@ex-grid/pivot 0.2.0-beta.3 → 0.2.0-rc.1
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.js +109 -1
- package/dist/index.js.map +2 -2
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/browser-locale.ts", "../src/create-pivot.ts", "../src/pivot-view.ts", "../src/details.ts", "../../data/src/decimal.ts", "../src/must.ts", "../src/parts.ts", "../src/chrome.ts", "../src/dom.ts", "../src/details-view.ts", "../src/entry-menu.ts", "../src/field-list.ts", "../src/field-list-slot.ts", "../src/item-filter.ts", "../src/items.ts", "../src/menu.ts", "../src/panels.ts", "../src/shipped-stylesheet.ts", "../src/report-grid.ts", "../src/report-find.ts", "../src/report-summary.ts", "../src/report-menu.ts", "../src/words.ts"],
|
|
4
|
-
"sourcesContent": ["// The locale a Framework Adapter hands the pivot when the Consumer gives none (ADR-0370 section 10): the\n// browser's own, as the browser ranks its languages. The pivot writes numbers only in the locales its engine\n// holds, so a language it does not hold is passed over for the next the browser lists. A language is never\n// stood in for by another, its region dropped: `es-419` written as `es` would group thousands with a point\n// for readers who read it as a decimal. A browser with none it holds is refused, naming them.\n\nimport { pivotLocales } from '@ex-grid/pivot-engine';\n\n/**\n * The first of `languages`, in the browser's order, that the pivot writes in, matched whole and without\n * regard to case. A list with none it holds throws a `RangeError` that says to pass `locale`.\n */\nexport function browserPivotLocale(languages: readonly string[]): string {\n const held = new Map(pivotLocales().map(name => [name.toLowerCase(), name]));\n for (const tag of languages) {\n const exact = held.get(tag.toLowerCase());\n if (exact !== undefined) return exact;\n }\n throw new RangeError(`None of the browser's languages (${languages.join(', ')}) is one the pivot writes numbers in: pass locale, a BCP 47 tag or 'invariant' (ADR-0370 section 10).`);\n}\n", "import { createGrid, type GridHandle, type GridOptions } from '@ex-grid/core';\nimport type { PivotShowDetailsEvent } from './details';\nimport { PivotView, type PivotViewOptions } from './pivot-view';\n\n/** An ExPivot drawn into an element, handed back by {@link createPivot}. */\nexport interface PivotHandle {\n /** Takes the options again, whole: what did not change asks nothing again. */\n update(options: PivotViewOptions): void;\n /** Opens the records of a Show Details event this pivot raised, as `detailsView` says: what a Consumer that\n * heard `onShowDetails` and does not take them hands back (ADR-0059). */\n openDetails(event: PivotShowDetailsEvent): void;\n /**\n * The grid that takes the inputs made at `element` (ADR-0240 section 6): a Show Details grid's, where `element`\n * stands in that grid's Input Root, else the report's; undefined while the report draws no grid. For a Framework\n * Adapter whose Chrome's contents arrive later than their slot, to hold that grid's inputs and Settled Mark until\n * they stand (ADR-0410 section 5).\n */\n gridAround(element: Element): GridHandle<unknown> | undefined;\n /** Holds the Settled Mark (ADR-0220) of the grid `element` stands in, as `gridAround` finds it, until the\n * function it answers is called. Where no grid stands there yet, the hold waits for the grid that comes to: the\n * report's next one while the report draws none, and a grid being made for a part it mounted before placing it,\n * which meanwhile holds every grid. */\n holdSettled(element: Element): () => void;\n /** Stops the pivot: it asks and hears nothing more, and empties its element. The source stays the\n * Consumer's. */\n destroy(): void;\n}\n\n/**\n * Draws an ExPivot into `element`, which becomes its root (ADR-0370 section 1): the report, drawn by ExGrid,\n * beside the Field List. The pivot owns everything inside it; a Framework Adapter renders the element and\n * hands the pivot its props, and nothing here assumes React's lifecycle or Blazor's.\n */\nexport function createPivot(element: HTMLElement, options: PivotViewOptions): PivotHandle {\n const grids = new PivotGrids(element);\n const view = new PivotView(element, options, (root, gridOptions) => grids.mount(root, gridOptions));\n return Object.freeze({\n update: (next: PivotViewOptions) => { view.update(next); },\n openDetails: (event: PivotShowDetailsEvent) => { view.openDetails(event); },\n gridAround: (within: Element) => grids.around(within),\n holdSettled: (within: Element) => grids.holdSettled(within),\n destroy: () => { view.destroy(); },\n });\n}\n\n/** A hold of the Settled Mark taken before the grid it holds stood: let go, or handed to that grid's once it stands. */\ninterface WaitingHold {\n readonly element: Element;\n readonly releases: (() => void)[];\n gone: boolean;\n}\n\n/** Draws a grid into an element: ExGrid's `createGrid`, or a layer-2 test's own. */\nexport type MakeGrid = <Row>(root: HTMLElement, options: GridOptions<Row>) => GridHandle<Row>;\n\n/** The grids a pivot draws, each by its root: the report's, and Show Details'. */\nexport class PivotGrids {\n readonly #pivot: HTMLElement;\n readonly #make: MakeGrid;\n readonly #grids = new Map<HTMLElement, GridHandle<unknown>>();\n readonly #waiting = new Set<WaitingHold>();\n\n constructor(pivot: HTMLElement, make: MakeGrid = createGrid) {\n this.#pivot = pivot;\n this.#make = make;\n }\n\n mount<Row>(root: HTMLElement, options: GridOptions<Row>): GridHandle<Row> {\n const grid = this.#make(root, options);\n // The grid's own members, its getters among them, with a destroy that forgets it first.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Object.create answers any; the members are the grid's\n const handle = Object.freeze(Object.create(grid, {\n destroy: { value: () => { this.#grids.delete(root); grid.destroy(); }, enumerable: true },\n })) as GridHandle<Row>;\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- kept to hold and order, which read no row\n this.#grids.set(root, handle as unknown as GridHandle<unknown>);\n // A hold taken before this grid stood holds it, once what it was taken for stands in the grid's Input Root:\n // the report's while the report drew no grid, and a part the grid mounted as it was made, before its first\n // paint placed it.\n const inputRoot = this.#inputRootOf(root);\n for (const waiting of this.#waiting) {\n if (this.#inputRootOf(waiting.element) !== inputRoot) continue;\n this.#waiting.delete(waiting);\n if (!waiting.gone) waiting.releases.push(handle.holdSettled());\n }\n return handle;\n }\n\n around(element: Element): GridHandle<unknown> | undefined {\n const inputRoot = this.#inputRootOf(element);\n const report = this.#gridIn(this.#pivot);\n if (inputRoot === this.#pivot || inputRoot === undefined) return report;\n return this.#gridIn(inputRoot) ?? report;\n }\n\n holdSettled(element: Element): () => void {\n const inputRoot = this.#inputRootOf(element);\n const grid = inputRoot === undefined ? undefined : this.#gridIn(inputRoot);\n if (grid !== undefined) return grid.holdSettled();\n // No grid stands where the element does yet. One not yet placed holds every grid now, as it may stand in any,\n // and each waits for the grid it comes to stand in.\n const waiting: WaitingHold = { element, releases: inputRoot === undefined ? [...this.#grids.values()].map(each => each.holdSettled()) : [], gone: false };\n this.#waiting.add(waiting);\n return () => {\n waiting.gone = true;\n this.#waiting.delete(waiting);\n for (const release of waiting.releases) release();\n };\n }\n\n // The grid whose Input Root is `inputRoot`.\n #gridIn(inputRoot: HTMLElement): GridHandle<unknown> | undefined {\n for (const [root, grid] of this.#grids) {\n if (this.#inputRootOf(root) === inputRoot) return grid;\n }\n return undefined;\n }\n\n // The Input Root an element stands in: the pivot's, or a Show Details grid's; undefined for one outside the pivot,\n // or not yet in the document.\n #inputRootOf(element: Element): HTMLElement | undefined {\n const around = element.parentElement?.closest<HTMLElement>('[data-ex-input-root]');\n return around === null || around === undefined || !this.#pivot.contains(around) ? undefined : around;\n }\n}\n", "// ExPivot's Script Core (ADR-0370 section 1): Excel's PivotTable, drawn by ExGrid as that grid's Consumer\n// (ADR-0059). It holds the Pivot Layout and asks its report source; ExGrid paints, selects, navigates and\n// copies. It owns the DOM inside its own root, writes the Razor component's DOM contract and reads ExPivot's\n// stylesheet unchanged (ADR-0350 section 4), and depends on no UI framework.\n//\n// Every move is a question, and only the newest question's answer is shown: a move made while a question is\n// out is taken against the layout that question asks for, and when that question is refused every move taken\n// against it is refused with it, and the pane goes back to the layout the report shows (ADR-0370 section 3,\n// spine rule 6). The one clock it waits on is the redraw interval (ADR-0067): the source's changes of data are\n// gathered, and asked for at most once per interval, which decides when the newest data reaches the screen, never\n// which data it is.\n\nimport {\n CellTextMetrics, GridPresentationDefaults, gridTextGeometry, type GridColumnWidthChange, type GridDensity, type GridHandle, type GridOptions,\n type GridSelection, type GridTextGeometry, type GridTextOptions,\n type CellPosition, type GridCommand, type GridContextMenuContext,\n type FetchingGridSource, type GridRefusal, type ViewportSize, type GridColumn, type GridCopyAnswer, type GridCopyRequest,\n type SelectionSummary, type SummaryFigure,\n assembleCopy, builtInCommandLabel, defaultChangeHighlightMs, defaultSummaryFigures, reloadNoticeLabelIds, summaryFigureOrder, systemClock,\n} from '@ex-grid/core';\nimport {\n FetchingPivotSource, LocalPivotReportSource, chooseLayout, defaultMaxLeaves, emptyPivotLayout, formatPivotCount, isLayoutChosen, isValuesPseudoField,\n layoutChoiceChanges, pivotLayoutChoices, pivotValueCaptions, placementOf, placementsIn, isItemCollapsed, pivotWord, pivotWordIdList, setCollapsed, setHiddenItems,\n itemKeysEqual, pivotItemKeyId, validateLayout, writePivotLayoutJson, type PivotDisplayRow, type PivotEntry, type PivotFieldPlacement, type PivotItemInfo, type PivotItemCounts, type PivotLabel, type PivotLayout, type PivotLayoutChoice,\n type PivotReportCopyCell, type PivotReportRefusal, type PivotReportSettings, type PivotSourceChanged, type PivotReportState, type PivotSlicing, type PivotSource, type PivotToggle,\n pivotReportDetailsQuery, PivotItemPage, itemsOfPage, PivotChangeTimes, type PivotFieldItem,\n} from '@ex-grid/pivot-engine';\nimport { detailsEvent, detailsProblemText, type PivotDetailItem, type PivotDetailsView, type PivotShowDetailsEvent } from './details';\nimport {\n checkedPivotChrome, StandingSlot, type PivotChrome, type PivotChromeSlot, type PivotReportFiltersSlotContext, type PivotReportFiltersView, type PivotStaleReportSlotContext,\n type PivotStaleReportView, type PivotToolbarSlotContext, type PivotToolbarView,\n} from './chrome';\nimport { DetailsSheets, type MountGrid } from './details-view';\nimport { entryMenuCommands, entryOfField, type EntryMenuCommand, type EntryPanel } from './entry-menu';\nimport { FieldListView, fieldOf, sameEntry, type FieldListEdit, type FieldListHandlers, type FieldListMove } from './field-list';\nimport { entryKey, SlottedFieldList } from './field-list-slot';\nimport { itemFilterPanel, itemsProblemText } from './item-filter';\nimport { ItemListings, pendingFirst, searchItems, type FieldItems, type ItemsUnder } from './items';\nimport { PivotMenuFrame, SlottedMenuFrame, type PivotMenu, type PivotMenuCommand } from './menu';\nimport { clearStyle, element, writeStyle } from './dom';\nimport { stylesheetName, stylesheetStamp } from './shipped-stylesheet';\nimport { defined, elementAt, unreachable } from './must';\nimport { fieldSettingsPanel, valueFieldSettingsPanel, type PivotPanel } from './panels';\nimport { checkedName, PartElements, swap, type PartRefs } from './parts';\nimport { cellItems, ReportColumns, reportMatch, reportRows, type PivotCellItems } from './report-grid';\nimport type { ReportFindGivenUp } from './report-find';\nimport { captionOfRemove, removeNamedFieldId, reportMenuCommands, valueFieldAt } from './report-menu';\nimport { layoutChoiceId, PivotScreenWords } from './words';\n\n/** A Pivot Layout the user made and the report now shows. */\nexport interface PivotLayoutChangedEvent {\n /** The layout the report shows. */\n readonly layout: PivotLayout;\n}\n\n/** The Field List shown or hidden by the user. */\nexport interface PivotFieldListShownEvent {\n /** Whether it now stands beside the report. */\n readonly shown: boolean;\n}\n\n/** A move the report could not take, said where the user sees it (ADR-0066, ADR-0370 section 3). */\nexport interface PivotRefusedEvent {\n /** The sentence the pivot shows. */\n readonly message: string;\n /** The fields the refusal names, in the order they were moved: every move taken against the refused\n * question, which went with it. Empty where it names none. */\n readonly fields: readonly string[];\n}\n\n/** The Pivot Source failed to answer the report's newest question (ADR-0067). */\nexport interface PivotFailedEvent {\n /** What the source threw. */\n readonly error: unknown;\n /** Whether the report on screen stays as a Stale Report, whose notice says the failure: such a failure is raised here\n * and thrown no further. Any other is said in the Pivot Toolbar, and thrown on after it is raised. */\n readonly stale: boolean;\n}\n\n/** The report's selection, as the grid raised it, and what its cells stand for. */\nexport interface PivotSelectionChangedEvent {\n /** The selection of the report grid. */\n readonly selection: GridSelection;\n /** Each selected cell's row and column Items, each cell once, in the order selected (ADR-0340); `undefined`\n * when the selection reaches a row the grid does not hold drawn now, which is read from no Items rather than\n * from some of them (spine rule 1), and when no report is shown. A selection dropped over a report is said with\n * an empty list. */\n readonly items: readonly PivotCellItems[] | undefined;\n}\n\n/** An ExPivot's options (ADR-0370 section 1): what the Consumer hands, whole, on every update. */\nexport interface PivotViewOptions {\n /** The Pivot Source the report is computed from: its fields are what the Field List offers. A new\n * instance is a refresh. */\n readonly source: PivotSource;\n /** The Pivot Layout, View State the Consumer holds (ADR-0059). A layout handed in replaces the one on\n * screen; one this pivot raised through `onLayoutChanged` and handed back, however late, is its own and asks\n * nothing, so an earlier layout is asked for again by handing in one of the Consumer's own making. Left out,\n * the pivot starts from nothing and keeps the user's changes itself. A layout naming a field the source\n * does not offer is refused by name. */\n readonly layout?: PivotLayout;\n /** Raised with the layout the report shows after each change the user made, once it is answered: never\n * for one a newer move superseded, nor for one refused. */\n readonly onLayoutChanged?: (event: PivotLayoutChangedEvent) => void;\n /** Raised when a move is refused, with the sentence the pivot shows. */\n readonly onRefused?: (event: PivotRefusedEvent) => void;\n /** Raised when the Pivot Source fails to answer the report's newest question, as the Razor component keeps\n * `LastError`: a live source whose transport is down is heard of here (ADR-0067). */\n readonly onFailed?: (event: PivotFailedEvent) => void;\n /** The locale numbers, dates and counts are written in and text Items ordered by: a BCP 47 tag, or\n * `invariant`, which the pivot reads unless given (ADR-0370 section 10). A React adapter passes the\n * browser's language. It changes no word. */\n readonly locale?: string;\n /** The Consumer's word for an id, or `undefined` to keep the English (ADR-0370 section 10).\n * `japanesePivotWords` gives Excel's Japanese edition's words in one line. */\n readonly label?: PivotLabel;\n /** Whether the Field List stands beside the report; true unless given. */\n readonly showFieldList?: boolean;\n /** Raised when the report's selection changes, with what its cells stand for: what a Board reads its links\n * by (ADR-0340). */\n readonly onSelectionChanged?: (event: PivotSelectionChangedEvent) => void;\n /** Raised when the user shows or hides the Field List. */\n readonly onShowFieldListChanged?: (event: PivotFieldListShownEvent) => void;\n /** The Field List's width in pixels; 300 unless given. */\n readonly fieldListWidth?: number;\n /** The report grid's height, header included: pixels, or `stretch` for the parent's; 400 unless given. */\n readonly viewportHeight?: ViewportSize;\n /** The report grid's width; `stretch` unless given, what the Field List leaves. */\n readonly viewportWidth?: ViewportSize;\n /** The most leaves a question may ask the source for (ADR-0066): 200,000 unless given. A layout past it is\n * refused by name, and the report stays on the layout before. */\n readonly maxLeaves?: number;\n /** The most rows a report may have (ADR-0066): Excel's 1,048,576 unless given. A layout past it is refused, and\n * newer data past it leaves a Stale Report. */\n readonly maxRows?: number;\n /** The most columns a report may have, its label columns included (ADR-0066): Excel's 16,384 unless given. A layout\n * past it is refused, and newer data past it leaves a Stale Report. */\n readonly maxColumns?: number;\n /** How long after a change of data reached the screen the next is asked for, in milliseconds: 250 unless given\n * (ADR-0067). The source's notices that come meanwhile are gathered and asked for once, so a source that changes\n * many times a second redraws the report at most once per interval; a notice after a quiet spell is asked for at\n * once. */\n readonly redrawInterval?: number;\n /** The report's row height, or the Density's. */\n readonly rowHeight?: number;\n /** The report's Density, beating a Wrapper's. */\n readonly density?: GridDensity;\n /** The widths the report's grids charge each glyph, beating a Wrapper's and the Density's (ADR-0016): whoever sets\n * the font the cells are drawn in hands its widths, so `####` and the label widths are judged by the face on\n * screen. */\n readonly cellMetrics?: CellTextMetrics;\n /** What a Wrapper hands the report's grids (ADR-0030): the widths of the font it sets, its Density, and its hover\n * band and Row Stripes. A value the pivot is given beats these. */\n readonly presentationDefaults?: GridPresentationDefaults;\n /** How long the Change Highlight marks a value that changed with the data, in milliseconds: one second unless\n * given (ADR-0068). The source's changes are marked when newer data is shown, and a Refresh marks what changed\n * too; a move of the user's marks nothing. Zero marks nothing, and a negative or endless one is refused. */\n readonly changeHighlightDuration?: number;\n /** How the report's work shares the thread: a slice of 30 ms between macrotasks unless given (PV-40). Read\n * once, when the pivot is made. */\n readonly slicing?: PivotSlicing;\n /** Hears Show Details (ADR-0059, ADR-0063): the records behind a value cell double clicked. A Consumer that\n * listens takes them, and the pivot shows nothing; otherwise they open as `detailsView` says. */\n readonly onShowDetails?: (event: PivotShowDetailsEvent) => void;\n /** Where the records open when nobody hears `onShowDetails`: a tab at the report's foot, which covers the report\n * while it is selected, or a dialog; `tab` unless given. */\n readonly detailsView?: PivotDetailsView;\n /** Whether the Selection Summary is shown under the report (ADR-0130): Excel's status-bar figures over the cells\n * selected, summed by the report source over the whole report, rows not drawn included. On unless given. */\n readonly showSelectionSummary?: boolean;\n /** The Selection Summary's figures, Excel's Average, Count and Sum unless given (ADR-0130). The report holds the\n * choice made in the figures menu from then on; figures handed in that differ from the ones last handed replace\n * it. */\n readonly summaryFigures?: readonly SummaryFigure[];\n /** Raised when the figures menu changes the figures shown (ADR-0130). */\n readonly onSummaryFiguresChanged?: (figures: readonly SummaryFigure[]) => void;\n /** Hears the Selection Summary as it now stands (ADR-0130), for an application that shows the figures elsewhere. */\n readonly onSelectionSummaryChanged?: (summary: SelectionSummary) => void;\n /** The parts a Wrapper's Chrome, or the Consumer's own, draws in place of the built-in markup (ADR-0061, ADR-0390),\n * its `grid` dressing the report's grid and Show Details' grids. A part standing keeps the slot it opened with. */\n readonly chrome?: PivotChrome;\n}\n\nexport type { MountGrid } from './details-view';\n\n/** Why a question was asked: a move of the user's, a layout the Consumer handed in, newer data a person or the Consumer\n * asked for (Refresh, Retry, a new source), or newer data the source told of, which is asked quietly, without the loading\n * indication, so a live report does not flicker (ADR-0067). */\ntype Cause = 'user' | 'consumer' | 'data' | 'live';\n\n/** Whether a question was asked for newer data: its answer marks what changed, and one it cannot show leaves a Stale\n * Report (ADR-0067). */\nfunction asksData(cause: Cause): boolean {\n return cause === 'data' || cause === 'live';\n}\n\n/** The redraw interval unless the Consumer gives one, in milliseconds: the Razor component's `DefaultRedrawInterval`\n * (ADR-0067). */\nconst defaultRedrawInterval = 250;\n\n/** Excel's own limits on a worksheet's rows and columns, the report's caps unless given (ADR-0066). */\nconst excelRows = 1_048_576;\nconst excelColumns = 16_384;\n\ninterface Question {\n readonly layout: PivotLayout;\n readonly generation: number;\n readonly controller: AbortController;\n /** Whether the layout is the user's, raised once shown: a move of the user's, or one asked again before its\n * answer came, under new settings or data, as the Razor component carries its pending raise. */\n readonly raise: boolean;\n /** Whether the answer marks what changed: new data, or the user's layout asked again under new data. */\n readonly markChanges: boolean;\n /** Whether the Pivot Source is asked again rather than answered from what the report source holds: while a Refresh\n * is owed. */\n readonly refreshData: boolean;\n /** The user's moves this question carries: its own, after those of the questions it superseded while they\n * were out, which were taken against them and go with it (ADR-0370 section 3). */\n readonly moves: readonly FieldListMove[];\n /** Whether it answers changes of data the source told of: those gathered when it was asked, and those the\n * question it superseded carried (ADR-0067). */\n readonly carries: boolean;\n /** Who asked it: the user's move, the Consumer's layout or settings, Refresh or Retry, or the source's notice. */\n readonly cause: Cause;\n /** What it is asked of and under: the rows of its answer are asked of the same, with the same. */\n readonly reportSource: LocalPivotReportSource;\n /** The Pivot Source its report source asks, which Show Details asks for the records behind a cell. */\n readonly source: PivotSource;\n readonly settings: PivotReportSettings;\n /** The locale its settings carry, which its counts and its report are written in. */\n readonly locale: string;\n readonly maxLeaves: number;\n /** The caps on the report's rows and columns it is shown under (ADR-0066). */\n readonly maxRows: number;\n readonly maxColumns: number;\n /** The Item a user's expand or collapse toggled, which keeps the Focus in the report this question brings. */\n readonly toggled: ToggledItem | undefined;\n}\n\ninterface Shown {\n readonly layout: PivotLayout;\n /** The answer the report was drawn from; none for a layout with nothing to show. */\n readonly answer: PivotReportState | undefined;\n /** The question it answered, whose locale the grid writes the report in. */\n readonly question: Question | undefined;\n}\n\n// Keys that change no Selection: a modifier pressed alone, and a key an IME or a dead key takes to compose text.\nconst inertKeys: ReadonlySet<string> = new Set(['Shift', 'Control', 'Alt', 'Meta', 'AltGraph', 'CapsLock', 'Process', 'Dead']);\n\n/** An Item expanded or collapsed on a row: the row Items down to it, the last of them the Item, which tell its place\n * from the same Item's under another parent; and how many gestures the user had made in the report's grid then. */\ninterface ToggledItem {\n readonly path: readonly PivotFieldItem[];\n readonly gestures: number;\n}\n\n// The label cell of the toggled Item among the rows held: the one that paints its button on the toggled row's path.\nfunction toggledCell(rows: readonly PivotDisplayRow[], start: number, { path }: ToggledItem): CellPosition | undefined {\n const toggled = elementAt(path, path.length - 1);\n for (const [i, row] of rows.entries()) {\n if (row.rowPath.length < path.length || path.some((step, level) => {\n const at = elementAt(row.rowPath, level);\n return at.field !== step.field || !itemKeysEqual(at.item, step.item);\n })) continue;\n const column = row.labels.findIndex(label => label.toggle !== undefined && label.toggle.field === toggled.field\n && itemKeysEqual(label.toggle.item, toggled.item));\n if (column >= 0) return Object.freeze({ row: start + i, column });\n }\n return undefined;\n}\n\n/** What a menu or a panel opened under a field's entry was opened on. */\ninterface AtEntry {\n readonly entry: PivotEntry;\n /** The field the entry stands for; none for \u03A3 Values. */\n readonly field: string | undefined;\n /** The pane's layout it was opened on, which it closes on leaving. */\n readonly against: PivotLayout;\n}\n\n/** What is open in the pivot (ADR-0061), one at a time: the Layout menu from the Pivot Toolbar, a placed field's menu\n * in the Field List, a panel that menu opened in its place, or Filter\u2026 under a report filter in the band. */\ntype OpenSurface =\n | { readonly kind: 'layout'; readonly popup: PivotMenu }\n | (AtEntry & { readonly kind: 'entry'; readonly popup: PivotMenu })\n | (AtEntry & { readonly kind: 'panel'; readonly popup: PivotPanel })\n | { readonly kind: 'band'; readonly field: string; readonly against: PivotLayout; readonly popup: PivotPanel };\n\ntype EntrySurface = Extract<OpenSurface, { readonly kind: 'entry' | 'panel' }>;\n\n/** A report filter in the band: its caption, and its button, which says what it shows and opens Filter\u2026 under it. */\ninterface BandFilter {\n readonly filter: HTMLElement;\n readonly caption: HTMLElement;\n readonly anchor: HTMLElement;\n readonly button: HTMLButtonElement;\n readonly summary: HTMLElement;\n}\n\n// Stops what a panel asked that is still on its way, as it leaves.\nfunction closed(open: OpenSurface): void {\n if (open.kind === 'panel' || open.kind === 'band') open.popup.close?.();\n else open.popup.close();\n}\n\n// The Layout menu's groups, each headed where it starts, in Excel's order (ADR-0061).\nconst layoutHeadings: ReadonlyMap<PivotLayoutChoice, string> = new Map([\n ['doNotShowSubtotals', 'subtotals'],\n ['grandTotalsOff', 'grand-totals'],\n ['compactForm', 'report-layout'],\n]);\n\n// The ids of the pivot's own words: a command of the grid's own is not one of them.\nconst pivotWordIds: ReadonlySet<string> = new Set(pivotWordIdList());\n\n// The rows a first answer brings: a screen's worth and more. The grid asks for the rest as it scrolls.\nconst firstWindowRows = 200;\n\n// Whether a layout shows nothing: no field in Rows, Columns or Values, so there is nothing to compute, whatever\n// stands in Filters (ADR-0059).\nfunction showsNothing(layout: PivotLayout): boolean {\n return layout.rows.length === 0 && layout.columns.length === 0 && layout.values.length === 0;\n}\n\n/** What the report's text is charged by, as its grids resolve it (ADR-0028). */\nfunction textOf(options: PivotViewOptions): GridTextOptions {\n return {\n ...(options.density === undefined ? {} : { density: options.density }),\n ...(options.cellMetrics === undefined ? {} : { cellMetrics: options.cellMetrics }),\n ...(options.presentationDefaults === undefined ? {} : { presentationDefaults: options.presentationDefaults }),\n };\n}\n\n/** Whether two Cell Metrics, either of them none, charge every glyph alike. */\nfunction sameCellMetrics(a: CellTextMetrics | undefined, b: CellTextMetrics | undefined): boolean {\n return a === b || (a !== undefined && b !== undefined && a.equals(b));\n}\n\n/** Whether two Wrappers' defaults, either of them none, hand the grids the same widths and words. */\nfunction sameDefaults(a: GridPresentationDefaults | undefined, b: GridPresentationDefaults | undefined): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n const read = ['wideWidthPx', 'digitWidthPx', 'narrowWidthPx', 'boldWideWidthPx', 'boldDigitWidthPx', 'boldNarrowWidthPx', 'otherWidthPx',\n 'boldOtherWidthPx', 'glyphWidths', 'fontSizePx', 'density', 'highlightHoverRow', 'stripeRows'] as const;\n return read.every(name => a[name] === b[name]);\n}\n\n/** Whether two geometries charge every glyph alike. */\nfunction sameGeometry(a: GridTextGeometry, b: GridTextGeometry): boolean {\n if (a === b) return true;\n const widths = ['wideWidthPx', 'digitWidthPx', 'narrowWidthPx', 'fullWidthPx', 'otherWidthPx', 'cellHorizontalPaddingPx'] as const;\n if (widths.some(name => a[name] !== b[name])) return false;\n const glyphs = Object.keys(a.glyphWidths);\n return glyphs.length === Object.keys(b.glyphWidths).length && glyphs.every(point => a.glyphWidths[Number(point)] === b.glyphWidths[Number(point)]);\n}\n\nfunction checkedOptions(options: PivotViewOptions): PivotViewOptions {\n // Checked as an untyped caller may hand them, where they arrive (CONVENTIONS.md).\n const given: Readonly<Record<string, unknown>> = { ...options };\n const source = given['source'];\n if (typeof source !== 'object' || source === null || !('fields' in source) || !('aggregate' in source)) {\n throw new TypeError('An ExPivot needs a Pivot Source (source) to compute its report from.');\n }\n const width = given['fieldListWidth'];\n if (width !== undefined && (typeof width !== 'number' || !Number.isFinite(width) || width <= 0 || width >= 10_000)) {\n throw new RangeError(`fieldListWidth is a width in pixels above zero, not ${JSON.stringify(width)}.`);\n }\n const redrawInterval = given['redrawInterval'];\n if (redrawInterval !== undefined && (typeof redrawInterval !== 'number' || !Number.isFinite(redrawInterval) || redrawInterval < 0)) {\n throw new RangeError(`redrawInterval is a time in milliseconds of zero or more, not ${JSON.stringify(redrawInterval)} (ADR-0067).`);\n }\n for (const name of ['maxLeaves', 'maxRows', 'maxColumns']) {\n const cap = given[name];\n if (cap !== undefined && (typeof cap !== 'number' || !Number.isSafeInteger(cap) || cap < 1)) {\n throw new RangeError(`${name} is a whole number of at least 1, not ${JSON.stringify(cap)} (ADR-0066).`);\n }\n }\n if (given['cellMetrics'] !== undefined && !(given['cellMetrics'] instanceof CellTextMetrics)) {\n throw new TypeError('cellMetrics is a CellTextMetrics: the widths the report\\'s grids charge each glyph (ADR-0016).');\n }\n if (given['presentationDefaults'] !== undefined && !(given['presentationDefaults'] instanceof GridPresentationDefaults)) {\n throw new TypeError('presentationDefaults is a GridPresentationDefaults, as a Wrapper makes one (ADR-0030).');\n }\n const highlight = given['changeHighlightDuration'];\n if (highlight !== undefined && (typeof highlight !== 'number' || !Number.isFinite(highlight) || highlight < 0)) {\n throw new RangeError(`changeHighlightDuration is a finite number of zero or more milliseconds, not ${typeof highlight === 'number' ? String(highlight) : typeof highlight} (ADR-0068).`);\n }\n const slicing = given['slicing'];\n if (slicing !== undefined && (typeof slicing !== 'object' || slicing === null)) throw new TypeError('slicing is an object.');\n const showSummary = given['showSelectionSummary'];\n if (showSummary !== undefined && typeof showSummary !== 'boolean') throw new TypeError('showSelectionSummary is true or false.');\n const figures: unknown = given['summaryFigures'];\n if (figures !== undefined && (!Array.isArray(figures) || !figures.every(figure => (summaryFigureOrder as readonly unknown[]).includes(figure)))) {\n throw new TypeError(`summaryFigures is a list of the figures ${summaryFigureOrder.join(', ')} (ADR-0130).`);\n }\n for (const name of ['onLayoutChanged', 'onRefused', 'onFailed', 'onShowFieldListChanged', 'onSelectionChanged', 'onShowDetails', 'label',\n 'onSummaryFiguresChanged', 'onSelectionSummaryChanged']) {\n const handler = given[name];\n if (handler !== undefined && typeof handler !== 'function') throw new TypeError(`${name} is a function.`);\n }\n const detailsView = given['detailsView'];\n if (detailsView !== undefined && detailsView !== 'tab' && detailsView !== 'dialog') {\n throw new TypeError(`detailsView is 'tab' or 'dialog', not ${JSON.stringify(detailsView)}.`);\n }\n checkedPivotChrome(given['chrome']);\n const locale = given['locale'];\n if (locale !== undefined && (typeof locale !== 'string' || locale === '')) {\n throw new TypeError('locale is a BCP 47 tag or \"invariant\", never an empty tag (ADR-0370 section 10).');\n }\n return options;\n}\n\n// The Consumer's words as the report source takes them, plain data that crosses to a Worker as it is.\nfunction wordsRecord(label: PivotLabel | undefined): Readonly<Record<string, string>> | undefined {\n if (label === undefined) return undefined;\n const words: Record<string, string> = {};\n for (const id of pivotWordIdList()) {\n const word = label(id);\n if (word !== undefined) words[id] = word;\n }\n return Object.freeze(words);\n}\n\n// Two lists of figures that name the same figures, whatever their order: the grid shows them in Excel's.\nfunction sameFigures(a: readonly SummaryFigure[] | undefined, b: readonly SummaryFigure[] | undefined): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n const named = new Set(b);\n return new Set(a).size === named.size && a.every(figure => named.has(figure));\n}\n\n// A copy refused, in the sentence the grid says.\nfunction refuse(sentence: string): GridCopyAnswer {\n return Object.freeze({ kind: 'refuse', sentence });\n}\n\n/** One ExPivot, drawn into its root. */\nexport class PivotView {\n readonly #root: HTMLElement;\n readonly #mountGrid: MountGrid;\n readonly #report: HTMLElement;\n readonly #notice: HTMLElement;\n // The Stale Report's live region under the Pivot Toolbar, always present, and the notice it holds while the report\n // is stale: the sentence, and Retry (ADR-0067).\n readonly #staleRegion: HTMLElement;\n readonly #staleNotice: HTMLElement;\n readonly #staleMessage: HTMLElement;\n readonly #retryButton: HTMLButtonElement;\n readonly #fieldListToggle: HTMLButtonElement;\n readonly #refreshButton: HTMLButtonElement;\n readonly #layoutAnchor: HTMLElement;\n readonly #toolbarStart: HTMLElement;\n // The built-in Pivot Toolbar, which a Chrome's toolbar stands in place of (ADR-0390).\n readonly #toolbar: HTMLElement;\n // The controls and anchors the toolbar, the band and the Stale Report's notice handed in, the built-in markup's or\n // a Chrome's: the keyboard goes to them, and the popups are placed in them, by name.\n readonly #parts: PartElements;\n readonly #toolbarSlot: StandingSlot<PivotToolbarView, PivotToolbarSlotContext>;\n readonly #bandSlot: StandingSlot<PivotReportFiltersView, PivotReportFiltersSlotContext>;\n readonly #staleSlot: StandingSlot<PivotStaleReportView, PivotStaleReportSlotContext>;\n // What a standing part's contents threw as they were mounted, thrown once the draw that mounted them is done.\n #slotErrors: Error[] = [];\n // Whether the draw is the Consumer's, making the pivot or updating it, which a Chrome that cannot be drawn is thrown\n // to.\n #consumerDraws = false;\n // The report filter band (ADR-0061): each report filter's elements, kept while it stands in Filters.\n readonly #band: HTMLElement;\n readonly #bandFilters = new Map<string, BandFilter>();\n readonly #layoutButton: HTMLButtonElement;\n readonly #layoutLabel: HTMLElement;\n readonly #backdrop: HTMLElement;\n readonly #sheet: HTMLElement;\n readonly #empty: HTMLElement;\n readonly #gridRoot: HTMLElement;\n readonly #dropRemove: HTMLElement;\n readonly #fieldListBox: HTMLElement;\n readonly #fieldListScroll: HTMLElement;\n readonly #builtInFieldList: FieldListView;\n // The Field List a Chrome draws (ADR-0390), in the built-in pane's place while it stands.\n readonly #slottedFieldList: SlottedFieldList;\n #fieldListSlotted = false;\n // Show Details' sheets, when the Consumer does not take the records: tabs at the report's foot, or a dialog.\n readonly #details: DetailsSheets;\n // The Show Details events this pivot handed a Consumer: the only ones it opens when they are handed back.\n readonly #detailsRaised = new WeakSet<PivotShowDetailsEvent>();\n readonly #userWidths = new Map<string, number>();\n // Read once, when the pivot is made: every report source it makes shares the thread the same way.\n readonly #slicing: PivotSlicing | undefined;\n #options: PivotViewOptions;\n #words: PivotScreenWords;\n // The Selection Summary's figures shown, and the ones last handed in (ADR-0130), as the Razor component's\n // `HeldSummaryFigures`: the figures menu's choice stands until the Consumer hands in different ones.\n #summaryFigures: readonly SummaryFigure[];\n #summaryFiguresHanded: readonly SummaryFigure[] | undefined;\n // The words of the grid's commands, made again when the Consumer's words change.\n #commandLabel: (id: string) => string | undefined;\n // The text geometry of the report grid's density: what its label widths are estimated under, and a level's indent.\n #geometry: GridTextGeometry;\n #columns: ReportColumns;\n #settings: PivotReportSettings;\n #reportSource: LocalPivotReportSource;\n // The report source the rows on screen read their Windows from: the one before a new source's answer lands.\n #shownReportSource: LocalPivotReportSource | undefined;\n // Every layout raised through onLayoutChanged, as the Razor component holds them: one handed back is the\n // Consumer binding the pivot's own layout back, never a layout it asks for, however late it comes. An earlier\n // layout is asked for again by handing in a layout of the Consumer's own making. Held weakly, so the user's\n // moves cost nothing once nobody holds them.\n readonly #raised = new WeakSet<PivotLayout>();\n // Unhooks the listeners on the root, which is the Consumer's element and outlives the pivot.\n readonly #listening = new AbortController();\n #layoutGiven: PivotLayout | undefined;\n #shown: Shown;\n #asked: Question | undefined;\n // While Defer Layout Update is ticked (ADR-0061): the layout the pane shows and builds, which Update applies, and\n // what the pane moved into it that the report on screen does not hold yet, which a refusal of that layout names.\n #deferred: Deferred | undefined;\n #generation = 0;\n #requests = 0;\n #refusal: string | undefined;\n // A Refresh pressed and not yet answered from the Pivot Source asked again.\n #refreshOwed = false;\n // A change of data no question asked since answers, and the Source Version the latest notice named, if it named\n // one (ADR-0067). When a change of data last reached the screen, from which the next waits the redraw interval;\n // the timer that waits; and how to stop hearing the report source's notices.\n #changed = false;\n #changedTo: string | undefined;\n // The Stale Report (ADR-0067): what happened while the newest data cannot be shown, and when the data the report\n // shows arrived, which the notice and a refused Copy say.\n #stale: string | undefined;\n // The Change Highlight (ADR-0068): when this pivot first showed each change the report source marks, one for the\n // pivot's life across sources; the grid's question about a cell, one function for the pivot's life, as the Razor\n // component holds its delegate, so that its identity says nothing changed (ADR-0003): a newly marked value is a\n // new row; and each value column's index by its name, which a row's marks are listed by.\n readonly #changeTimes = new PivotChangeTimes();\n readonly #cellChangedAt: NonNullable<GridOptions<PivotDisplayRow>['cellChangedAt']> = (row, column) => {\n const index = this.#valueColumnIndexes.get(column);\n return index === undefined ? undefined : this.#changeTimes.changedAt(row, index);\n };\n #valueColumnIndexes = new Map<string, number>();\n // Whether what left the report stale was a question that refreshed the Pivot Source, which Retry then asks again\n // rather than the report alone: asking a source that did not refresh would show its old data as the newest.\n #staleRetryRefreshes = false;\n #shownAt = Date.now();\n // The time of the data shown as last said, and what it was said for: the time, the locale and the day.\n #asOfSaid: { readonly key: string; readonly text: string } | undefined;\n #lastDataShown: number | undefined;\n #redrawTimer: ReturnType<typeof setTimeout> | undefined;\n #stopHearing: (() => void) | undefined;\n #fieldListShown: boolean;\n #counts: PivotItemCounts | undefined;\n #countsAsked: AbortController | undefined;\n #grid: GridHandle<PivotDisplayRow> | undefined;\n #rows: FetchingGridSource<PivotDisplayRow> | undefined;\n // The grid's columns as last drawn, whose names a copy asks the report source for.\n #gridColumns: readonly GridColumn<PivotDisplayRow>[] = [];\n #dropRemoveShown = false;\n #open: OpenSurface | undefined;\n // The Items Filter\u2026 lists, asked of the source under the report on screen (ADR-0066).\n readonly #items = new ItemListings(() => { this.#draw(); });\n // A field menu the pane left while it held the keyboard: the keyboard goes to its field's entry once drawn.\n #keyboardAfterDraw: OpenSurface | undefined;\n // Stops waiting for the first rows of the report a toggled Item keeps the Focus in.\n #placing: (() => void) | undefined;\n // The presses, wheels and keys the user has made in the report's grid, counted: a toggled Item keeps the Focus only\n // while none has come since the toggle (spine rule 6).\n #gestures = 0;\n #destroyed = false;\n // The stylesheets' notices at the top of the root, and what they were drawn from.\n #notices: readonly HTMLElement[] = [];\n #noticesDrawn = '';\n\n constructor(root: HTMLElement, options: PivotViewOptions, mountGrid: MountGrid) {\n this.#options = checkedOptions(options);\n this.#root = root;\n this.#mountGrid = mountGrid;\n this.#slicing = options.slicing;\n this.#words = new PivotScreenWords(options.label);\n this.#summaryFiguresHanded = options.summaryFigures;\n this.#summaryFigures = options.summaryFigures ?? defaultSummaryFigures;\n this.#commandLabel = this.#commandLabelOf(options.label);\n this.#geometry = gridTextGeometry(textOf(options));\n this.#columns = this.#columnsOf(options);\n this.#settings = this.#settingsOf(options);\n this.#fieldListShown = options.showFieldList !== false;\n this.#layoutGiven = options.layout;\n if (options.layout !== undefined) validateLayout(options.layout, this.#declared(options.source));\n this.#shown = { layout: emptyPivotLayout, answer: undefined, question: undefined };\n this.#reportSource = this.#reportSourceOf(options.source);\n\n const document = root.ownerDocument;\n const div = (className: string): HTMLDivElement => {\n const made = document.createElement('div');\n made.className = className;\n return made;\n };\n root.replaceChildren();\n root.classList.add('ex-pivot');\n // The pivot's box is its Input Root (ADR-0240 section 6): the report grid hears the whole pivot from here.\n root.setAttribute('data-ex-input-root', '');\n this.#report = div('ex-pivot-report');\n this.#parts = new PartElements(root);\n const toolbar = div('ex-pivot-toolbar');\n this.#toolbar = toolbar;\n const start = div('ex-pivot-toolbar-start');\n this.#toolbarStart = start;\n this.#band = div('ex-pivot-filters');\n this.#band.setAttribute('role', 'group');\n const end = div('ex-pivot-toolbar-end');\n // Refresh asks the Pivot Source again, offered only by a source that can be asked again (ADR-0066).\n this.#refreshButton = document.createElement('button');\n this.#refreshButton.type = 'button';\n this.#refreshButton.className = 'ex-pivot-toolbar-button ex-pivot-refresh-button';\n this.#refreshButton.setAttribute('data-ex-claims', 'click');\n this.#refreshButton.addEventListener('click', () => { this.#refresh(); });\n this.#fieldListToggle = document.createElement('button');\n this.#fieldListToggle.type = 'button';\n this.#fieldListToggle.className = 'ex-pivot-toolbar-button ex-pivot-field-list-toggle';\n this.#fieldListToggle.setAttribute('data-ex-claims', 'click');\n this.#fieldListToggle.addEventListener('click', () => { this.#setFieldListShown(!this.#fieldListShown); });\n // Layout \u25BE opens the Layout menu under it, over the report, at its right edge; its wrapper is positioned\n // so the menu needs no position the pivot would have to measure (ADR-0061).\n this.#layoutAnchor = document.createElement('span');\n this.#layoutAnchor.className = 'ex-pivot-toolbar-anchor';\n this.#layoutButton = document.createElement('button');\n this.#layoutButton.type = 'button';\n this.#layoutButton.className = 'ex-pivot-toolbar-button ex-pivot-layout-button';\n this.#layoutButton.setAttribute('data-ex-claims', 'click');\n this.#layoutButton.setAttribute('aria-haspopup', 'menu');\n this.#layoutLabel = document.createElement('span');\n const arrow = document.createElement('span');\n arrow.className = 'ex-pivot-entry-arrow';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n this.#layoutButton.append(this.#layoutLabel, arrow);\n this.#layoutButton.addEventListener('click', () => { this.#toggleLayoutMenu(); });\n this.#layoutAnchor.append(this.#layoutButton);\n end.append(this.#layoutAnchor, this.#fieldListToggle);\n // Under a menu opened from the Pivot Toolbar, a press anywhere else closes it.\n this.#backdrop = div('ex-pivot-backdrop');\n this.#backdrop.setAttribute('data-ex-claims', 'click');\n this.#backdrop.setAttribute('aria-hidden', 'true');\n this.#backdrop.addEventListener('click', () => { this.#close('opener'); });\n toolbar.append(start, end);\n this.#notice = div('ex-pivot-refusal-notice');\n this.#notice.setAttribute('role', 'alert');\n // A polite live region, always present, so a notice that appears in it is announced without interrupting the\n // reader as the Pivot Toolbar's refusal of their own change does. Empty, it takes no room.\n this.#staleRegion = div('ex-pivot-stale');\n this.#staleRegion.setAttribute('role', 'status');\n this.#staleNotice = div('ex-pivot-stale-notice');\n this.#staleMessage = document.createElement('span');\n this.#staleMessage.className = 'ex-pivot-stale-message';\n this.#retryButton = document.createElement('button');\n this.#retryButton.type = 'button';\n this.#retryButton.className = 'ex-pivot-retry';\n this.#retryButton.setAttribute('data-ex-claims', 'click');\n this.#retryButton.addEventListener('click', () => { this.#retry(); });\n this.#staleNotice.append(this.#staleMessage, this.#retryButton);\n this.#toolbarSlot = new StandingSlot('toolbar', document, Object.freeze({\n layoutMenu: Object.freeze({ label: '', open: false }), fieldList: Object.freeze({ label: '', shown: false }), reportFilters: false,\n }));\n this.#bandSlot = new StandingSlot('reportFilters', document, Object.freeze({ name: '', filters: Object.freeze([]) }));\n this.#staleSlot = new StandingSlot('staleReport', document, Object.freeze({\n message: '', asOfText: '', reason: '', retry: Object.freeze({ label: '', enabled: false }),\n }));\n this.#bandSlot.element.setAttribute('role', 'group');\n this.#sheet = div('ex-pivot-sheet');\n // Records covering the report take no drop meant for it.\n this.#sheet.addEventListener('dragover', event => {\n if (!this.#fieldList.removable || this.#details.covering) return;\n event.preventDefault();\n });\n this.#sheet.addEventListener('drop', event => {\n event.preventDefault();\n if (!this.#details.covering) this.#fieldList.dropOnReport();\n });\n this.#empty = div('ex-pivot-empty');\n this.#empty.setAttribute('role', 'status');\n this.#gridRoot = document.createElement('div');\n this.#dropRemove = div('ex-pivot-report-drop-remove');\n this.#dropRemove.setAttribute('aria-hidden', 'true');\n this.#dropRemove.append(document.createElement('span'));\n this.#report.append(toolbar, this.#notice, this.#staleRegion, this.#sheet);\n this.#fieldListBox = div('ex-pivot-field-list');\n this.#fieldListBox.setAttribute('role', 'region');\n const scroll = div('ex-pivot-field-list-scroll');\n this.#fieldListBox.append(scroll);\n this.#fieldListScroll = scroll;\n const fieldListHandlers: FieldListHandlers = {\n edit: edit => { this.#edited(edit); },\n close: () => { this.#setFieldListShown(false); },\n dragging: removable => { this.#paintDropRemove(removable); },\n menu: entry => { this.#toggleEntryMenu(entry); },\n defer: deferred => { this.#setDeferred(deferred); },\n update: () => { this.#applyPending(); },\n };\n this.#builtInFieldList = new FieldListView(scroll, fieldListHandlers);\n this.#slottedFieldList = new SlottedFieldList(document, fieldListHandlers, this.#parts);\n root.append(this.#report, this.#fieldListBox);\n this.#drawNotices();\n this.#details = new DetailsSheets({\n document,\n mountGrid,\n words: () => this.#words,\n look: () => ({\n rowHeight: this.#options.rowHeight, density: this.#options.density, cellMetrics: this.#options.cellMetrics,\n presentationDefaults: this.#options.presentationDefaults, commandLabel: this.#options.label, chrome: this.#chrome?.grid,\n }),\n problemText: problem => detailsProblemText(problem, this.#words),\n changed: () => { this.#draw(); },\n // The report's grid takes the keyboard back; a report with no grid has the Field List's toggle take it, so\n // the keyboard stays in the pivot.\n returnKeyboard: () => {\n if (this.#grid === undefined) this.#parts.focus('field-list');\n else this.#gridRoot.focus();\n },\n parts: this.#parts,\n chrome: () => this.#chrome,\n });\n // A drag that moves on from an Area, anywhere in the pivot, leaves it unmarked; and one that leaves the\n // pivot for an element the browser names. WebKit names none on leaving one element for another, so a\n // leave that names nothing is not taken as one.\n const listening = { signal: this.#listening.signal };\n const gestured = (): void => { this.#gestures++; };\n this.#gridRoot.addEventListener('pointerdown', gestured, { capture: true, ...listening });\n this.#gridRoot.addEventListener('wheel', gestured, { capture: true, passive: true, ...listening });\n this.#gridRoot.addEventListener('keydown', event => {\n if (!event.isComposing && !inertKeys.has(event.key)) gestured();\n }, { capture: true, ...listening });\n root.addEventListener('dragenter', event => { this.#fieldList.dragEntered(event.target); }, listening);\n root.addEventListener('dragleave', event => {\n const to = event.relatedTarget;\n if (to instanceof Node && !root.contains(to)) this.#fieldList.leaveTargets();\n }, listening);\n // A press, or focus coming in, anywhere in the pivot outside an open field menu and its entry dismisses the\n // menu, and leaves the keyboard where it went (ADR-0061). A panel keeps its draft until OK or Cancel.\n const outside = (event: Event): void => {\n const open = this.#open;\n if (open?.kind !== 'entry') return;\n if (event.target instanceof Node && this.#within(open, event.target)) return;\n this.#close('stay');\n };\n root.addEventListener('mousedown', outside, listening);\n root.addEventListener('focusin', outside, listening);\n\n this.#askCounts();\n // Heard once the pivot is whole: a construction that throws leaves no listener on the Consumer's source.\n this.#hear(this.#reportSource);\n if (options.layout !== undefined) this.#ask(options.layout, 'consumer', []);\n try {\n this.#consumerDraws = true;\n this.#draw();\n } catch (error) {\n // A pivot refused as it is made leaves nothing hearing the source.\n this.destroy();\n throw error;\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n #reportSourceOf(source: PivotSource): LocalPivotReportSource {\n const slicing = this.#slicing;\n return new LocalPivotReportSource(source, slicing === undefined ? undefined : { slicing });\n }\n\n // A report source is disposed once nothing asks it and no row on screen reads it.\n #release(reportSource: LocalPivotReportSource | undefined): void {\n if (reportSource !== undefined && reportSource !== this.#reportSource && reportSource !== this.#shownReportSource) reportSource.dispose();\n }\n\n /** Takes the options again, whole. Options refused leave the pivot as it was. A Chrome slot whose contents cannot\n * be drawn is thrown once the options are taken, with the built-in markup standing in its place (ADR-0390). */\n update(options: PivotViewOptions): void {\n if (this.#destroyed) throw new Error('This ExPivot was destroyed: make a new one.');\n checkedOptions(options);\n const before = this.#options;\n const sourceMoved = options.source !== before.source;\n // A layout handed in is a question, unless the pane holds it already or this pivot raised it.\n const layoutMoved = options.layout !== this.#layoutGiven;\n const consumerLayout = layoutMoved && options.layout !== undefined && options.layout !== this.#layoutAhead && !this.#raised.has(options.layout)\n ? options.layout\n : undefined;\n const asked = consumerLayout ?? (sourceMoved ? this.#layoutAhead : undefined);\n // Checked against the source it will be asked of before anything changes; a new source is always asked.\n if (asked !== undefined) validateLayout(asked, this.#declared(options.source));\n this.#options = options;\n if (layoutMoved) this.#layoutGiven = options.layout;\n // The Consumer's layout replaces the user's, a pending one too. A pending layout placing a field the new source\n // does not have goes back to the one asked of it, which is checked above: the rest of what a layout is checked\n // for does not depend on the source, and the pending one was made by the pane's own edits.\n const pending = this.#deferred?.layout;\n if (asked !== undefined && pending !== undefined && (consumerLayout !== undefined || !placesOnly(pending, this.#declared(options.source)))) {\n this.#deferred = Object.freeze({ layout: asked, moves: Object.freeze([]) });\n }\n // What the report's text is charged by: a label's width is estimated under it, so the report is asked again\n // when it charges otherwise, and not for equal widths handed again in a new object, as a framework's render may.\n const geometry = gridTextGeometry(textOf(options));\n const textMoved = options.density !== before.density || !sameGeometry(geometry, this.#geometry);\n // The grids are handed what they resolve their own metrics from when it charges or reads otherwise, not when\n // equal values come again in new objects.\n const metricsGiven = !sameCellMetrics(options.cellMetrics, before.cellMetrics) || !sameDefaults(options.presentationDefaults, before.presentationDefaults);\n const settingsMoved = options.locale !== before.locale || options.label !== before.label || textMoved;\n if (options.label !== before.label) {\n this.#words = new PivotScreenWords(options.label);\n this.#commandLabel = this.#commandLabelOf(options.label);\n }\n if (textMoved) this.#geometry = geometry;\n if (options.label !== before.label || textMoved) this.#columns = this.#columnsOf(options);\n // A highlight's length is the next question's to carry, which keeps what it compares that long; the report on\n // screen is not asked again for it, and the grid paints by it at once.\n const highlightMoved = highlightMsOf(options) !== highlightMsOf(before);\n if (settingsMoved || highlightMoved) this.#settings = this.#settingsOf(options);\n if (options.showFieldList !== before.showFieldList) this.#fieldListShown = options.showFieldList !== false;\n if (sourceMoved) {\n // A new source is asked from nothing: no Refresh is owed to it.\n this.#refreshOwed = false;\n // The rows on screen keep reading the report source that answered them until a new answer replaces them.\n const replaced = this.#reportSource;\n this.#reportSource = this.#reportSourceOf(options.source);\n this.#hear(this.#reportSource);\n this.#release(replaced);\n this.#counts = undefined;\n this.#askCounts();\n }\n if (options.redrawInterval !== before.redrawInterval) {\n // A redraw waiting on the interval before is timed again on the new one.\n this.#disarmRedraw();\n this.#scheduleRedraw();\n }\n if (asked !== undefined) {\n this.#ask(asked, consumerLayout !== undefined ? 'consumer' : 'data', []);\n } else if (settingsMoved || capsOf(options) !== capsOf(before)) {\n this.#ask(this.#layoutAhead, 'consumer', []);\n }\n const gridChromeMoved = options.chrome?.grid !== before.chrome?.grid;\n const summaryMoved = this.#adoptSummaryFigures(options.summaryFigures) || options.showSelectionSummary !== before.showSelectionSummary;\n if (summaryMoved || highlightMoved || options.rowHeight !== before.rowHeight || textMoved || metricsGiven || options.viewportHeight !== before.viewportHeight\n || options.viewportWidth !== before.viewportWidth || gridChromeMoved) {\n this.#drawGrid();\n }\n const detailsChromeMoved = options.chrome?.detailsTabs !== before.chrome?.detailsTabs || options.chrome?.detailsDialog !== before.chrome?.detailsDialog;\n this.#drawNotices();\n this.#consumerDraws = true;\n try {\n if (settingsMoved || metricsGiven || options.rowHeight !== before.rowHeight || gridChromeMoved || detailsChromeMoved) {\n this.#details.draw();\n this.#slotErrors.push(...this.#details.takeRefused());\n }\n this.#draw();\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n /** Opens the records of a Show Details event this pivot raised, as `detailsView` says, as when nobody hears\n * `onShowDetails`: a Consumer that heard it and does not take it hands it back. An event another pivot raised is\n * refused, rather than shown under this pivot's report; a stopped pivot opens nothing. */\n openDetails(event: PivotShowDetailsEvent): void {\n if (!this.#detailsRaised.has(event)) throw new Error('These records are another pivot\\'s: a pivot opens only the Show Details it raised.');\n if (this.#destroyed) return;\n this.#consumerDraws = true;\n try {\n this.#details.open(event, this.#options.detailsView ?? 'tab', this.#locale); // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0059: a tab at the report's foot unless the Consumer asks for the dialog, as the Razor component's DetailsView\n this.#slotErrors.push(...this.#details.takeRefused());\n this.#throwRefused();\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n /** Stops the pivot: it asks and hears nothing more, and empties its element. The source stays the\n * Consumer's. */\n destroy(): void {\n if (this.#destroyed) return;\n this.#destroyed = true;\n this.#listening.abort();\n this.#stopHearing?.();\n this.#stopHearing = undefined;\n this.#disarmRedraw();\n this.#takeDown();\n this.#toolbarSlot.hide();\n this.#bandSlot.hide();\n this.#staleSlot.hide();\n this.#slottedFieldList.hide();\n this.#parts.dispose();\n this.#items.dispose();\n this.#details.destroy();\n this.#generation++;\n this.#asked?.controller.abort();\n this.#asked = undefined;\n this.#countsAsked?.abort();\n this.#placing?.();\n this.#grid?.destroy();\n this.#grid = undefined;\n this.#rows?.dispose();\n this.#rows = undefined;\n const asked = this.#reportSource;\n const read = this.#shownReportSource;\n this.#shownReportSource = undefined;\n asked.dispose();\n if (read !== asked) read?.dispose();\n this.#root.replaceChildren();\n this.#root.classList.remove('ex-pivot');\n this.#root.removeAttribute('data-ex-input-root');\n clearStyle(this.#root);\n this.#root.removeAttribute('aria-busy');\n }\n\n /** The layout the report on screen was laid out under. */\n get shownLayout(): PivotLayout {\n return this.#shown.layout;\n }\n\n // Whether the report on screen is drawn as a grid: one was answered, and its layout shows something. A layout with\n // fields in Filters alone is answered, for their Items, and the box says how to start.\n get #reportDrawn(): boolean {\n return this.#shown.answer !== undefined && !showsNothing(this.#shown.layout);\n }\n\n // The layout the report is on, or on its way to: the one the newest question asks for, or the one it shows.\n get #layoutAhead(): PivotLayout {\n return this.#asked?.layout ?? this.#shown.layout;\n }\n\n // The pane's layout: the pending one while Defer Layout Update is ticked, otherwise the report's.\n get #paneLayout(): PivotLayout {\n return this.#deferred?.layout ?? this.#layoutAhead;\n }\n\n get #redrawInterval(): number {\n return this.#options.redrawInterval ?? defaultRedrawInterval;\n }\n\n get #maxLeaves(): number {\n return this.#options.maxLeaves ?? defaultMaxLeaves;\n }\n\n get #changeHighlightMs(): number {\n return highlightMsOf(this.#options);\n }\n\n get #maxRows(): number {\n return this.#options.maxRows ?? excelRows;\n }\n\n get #maxColumns(): number {\n return this.#options.maxColumns ?? excelColumns;\n }\n\n get #locale(): string {\n return this.#localeOf(this.#options);\n }\n\n // The Chrome's slots, read as each part opens (ADR-0390).\n get #chrome(): PivotChrome | undefined {\n return this.#options.chrome;\n }\n\n // The Field List standing now: a Chrome's, or the built-in pane.\n get #fieldList(): FieldListView | SlottedFieldList {\n return this.#fieldListSlotted ? this.#slottedFieldList : this.#builtInFieldList;\n }\n\n // The report source estimates the label widths under the grid's text geometry, as the Razor component tells it\n // the grid's Cell Metrics (ADR-0151).\n #settingsOf(options: PivotViewOptions): PivotReportSettings {\n const words = wordsRecord(options.label);\n // The report source keeps what a highlight compares for as long as it is marked (ADR-0153).\n return Object.freeze({\n locale: this.#localeOf(options), labelMetrics: this.#geometry, changeHighlightMs: highlightMsOf(options),\n ...(words === undefined ? {} : { words }),\n });\n }\n\n // A level's indent and a button's side: the em of the grid's font, rounded as .NET rounds it, which is what the\n // report source charges a level (ADR-0151).\n get #indentPx(): number {\n return roundHalfToEven(this.#geometry.fullWidthPx);\n }\n\n #columnsOf(options: PivotViewOptions): ReportColumns {\n const words = this.#words;\n return new ReportColumns(Object.freeze({\n indentPx: this.#indentPx,\n toggleName: (toggle: PivotToggle) => words.fill(toggle.isCollapsed ? 'expand-item' : 'collapse-item', toggle.itemLabel),\n toggled: (toggle: PivotToggle, row: PivotDisplayRow) => { this.#toggled(toggle, row); },\n }), textOf(options));\n }\n\n #localeOf(options: PivotViewOptions): string {\n return options.locale ?? 'invariant'; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0370 section 10: a Script Core given no locale reads as .NET's InvariantCulture does\n }\n\n #declared(source: PivotSource): ReadonlyMap<string, unknown> {\n return new Map(source.fields.map(field => [field.name, field]));\n }\n\n // ---- Asking ----------------------------------------------------------------------------------------\n\n #edited(edit: FieldListEdit): void {\n // A gesture taken against a layout that is no longer the pane's means nothing now: its indexes named the\n // entries of a layout that was replaced (ADR-0061, spine rule 6).\n if (edit.against !== this.#paneLayout) {\n this.#draw();\n return;\n }\n // While Defer Layout Update is ticked the pane builds the pending layout, and the report and the source are\n // left alone (ADR-0061).\n const deferred = this.#deferred;\n if (deferred !== undefined) {\n const { moved } = edit;\n // A field moved into an Area again replaces its earlier move into that Area, so the moves stay bounded.\n const moves = moved === undefined ? deferred.moves\n : [...deferred.moves.filter(move => move.field !== moved.field || move.area !== moved.area), moved];\n this.#deferred = Object.freeze({ layout: edit.layout, moves: Object.freeze(moves) });\n this.#refusal = undefined;\n this.#draw();\n return;\n }\n this.#move(edit.layout, edit.moved === undefined ? [] : [edit.moved]);\n }\n\n // A gesture on the report or the Pivot Toolbar, made to the layout the report is on. While Defer Layout Update\n // holds a pending layout, it reaches that one too, so Update does not take it back; where the pending layout does\n // not hold what the gesture was for, it stays as it is. A gesture that would change nothing now asks nothing.\n #reportEdit(edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: ToggledItem): void {\n const deferred = this.#deferred;\n if (deferred !== undefined) this.#deferred = Object.freeze({ ...deferred, layout: edit(deferred.layout) ?? deferred.layout });\n const now = this.#layoutAhead;\n const next = edit(now);\n if (next === undefined || next === now) this.#draw();\n else this.#move(next, [], toggled);\n }\n\n // Defer Layout Update ticked holds the pane's changes from here on; unticked, it applies them, as Excel does.\n #setDeferred(deferred: boolean): void {\n const held = this.#deferred;\n if (deferred === (held !== undefined)) return;\n if (deferred) {\n this.#deferred = Object.freeze({ layout: this.#layoutAhead, moves: Object.freeze([]) });\n this.#draw();\n return;\n }\n const unticked = defined(held, 'Defer Layout Update ticked');\n this.#deferred = undefined;\n if (this.#pendingApplies(unticked.layout)) this.#move(unticked.layout, unticked.moves);\n else this.#draw();\n }\n\n // Update applies the pending layout in one change, and Defer Layout Update stays ticked. The pending layout stays\n // the pane's, as the Razor component keeps it: refused, it is still the user's work, with the moves it names.\n #applyPending(): void {\n const held = this.#deferred;\n if (held !== undefined && this.#pendingApplies(held.layout)) this.#move(held.layout, held.moves);\n }\n\n // Whether a pending layout would change the report's: layouts are compared by what they say, since a gesture on\n // the report makes the pending layout and the report's anew, each its own.\n #pendingApplies(pending: PivotLayout): boolean {\n const now = this.#layoutAhead;\n return pending !== now && writePivotLayoutJson(pending) !== writePivotLayoutJson(now);\n }\n\n #move(layout: PivotLayout, moved: readonly FieldListMove[], toggled?: ToggledItem): void {\n // A move after a toggle asks for another report: the Item toggled is no longer the one to follow.\n this.#placing?.();\n this.#refusal = undefined;\n this.#ask(layout, 'user', moved, toggled);\n this.#draw();\n }\n\n #ask(layout: PivotLayout, asked: Cause, moved: readonly FieldListMove[], toggled?: ToggledItem): void {\n const superseded = this.#asked;\n superseded?.controller.abort();\n // A layout asked again before its answer came keeps what that question was owed: the user's raises once\n // shown and names its moves if refused, and new data's changes are marked.\n const again = superseded?.layout === layout;\n const raise = asked === 'user' || (again && superseded.raise);\n // A question asked while a Refresh is owed asks the Pivot Source again, and marks what changed, whatever asked it.\n const refreshData = this.#refreshOwed;\n const markChanges = asksData(asked) || refreshData || (again && superseded.markChanges);\n // An Item toggled into the layout keeps the Focus in its report, asked again or not.\n const focusOn = toggled ?? (again ? superseded.toggled : undefined);\n // A user's move made while a user's question was out was taken against it, and carries its moves on.\n const moves = [...(raise && superseded?.raise === true ? superseded.moves : []), ...moved];\n const generation = ++this.#generation;\n // Asked of the source as it stands now, a question answers every change of data told before it, and those the\n // question it superseded carried.\n const carries = this.#changed || superseded?.carries === true;\n this.#changed = false;\n this.#disarmRedraw();\n if (showsNothing(layout) && layout.filters.length === 0) {\n // Nothing to compute: the report is the empty box that says how to start. A layout with fields in Filters\n // alone is asked for still, as the Razor component asks every layout: Filter\u2026 lists their Items under its\n // Report Version (ADR-0066). Nothing on screen reads the data, so no change of data is owed to it: the next\n // layout's question is asked of the source as it stands then.\n this.#asked = undefined;\n this.#showLayout(layout, undefined, raise);\n return;\n }\n const question: Question = {\n layout, generation, controller: new AbortController(), raise, markChanges, refreshData, moves: Object.freeze(moves), carries, cause: asked,\n reportSource: this.#reportSource, source: this.#options.source, settings: this.#settings, locale: this.#locale, maxLeaves: this.#maxLeaves,\n maxRows: this.#maxRows, maxColumns: this.#maxColumns, toggled: focusOn,\n };\n this.#asked = question;\n void this.#run(question);\n }\n\n async #run(question: Question): Promise<void> {\n const current = (): boolean => question.generation === this.#generation && !this.#destroyed;\n let update;\n try {\n update = await question.reportSource.window(Object.freeze({\n requestId: this.#nextRequestId(),\n layout: question.layout,\n settings: question.settings,\n window: Object.freeze({ start: 0, count: firstWindowRows }),\n maxLeaves: question.maxLeaves,\n markChanges: question.markChanges,\n refreshData: question.refreshData,\n }), question.controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a superseded question's failure is nobody's; the newest one's is said where the user sees it and rethrown\n if (!current()) return;\n this.#asked = undefined;\n const stale = this.#staleFor(question);\n if (stale) this.#markStale(this.#words.staleFailed(error), question.refreshData);\n else this.#refusal = this.#words.failed(error);\n this.#draw();\n // A failure is said where the user sees it, and asked again only by the next notice, Refresh, Retry or move:\n // asking again on the clock would ask a failing source once per interval.\n this.#landed(question, undefined, false);\n this.#options.onFailed?.(Object.freeze({ error, stale }));\n // A failure the Stale Report says is raised and thrown no further, as the Razor component keeps it in\n // LastError: a live source whose transport is down would otherwise throw once for each notice. Any other is\n // rethrown.\n if (!stale) throw error;\n return;\n }\n // Late and superseded: a newer question was asked, and this answers a layout no longer wanted.\n if (!current()) return;\n this.#asked = undefined;\n if (update.refusal !== undefined) {\n if (this.#staleFor(question)) {\n this.#markStale(this.#staleRefusalOf(update.refusal, question), question.refreshData);\n this.#draw();\n } else {\n this.#refuse(update.refusal, question);\n }\n // The report on screen stays on its layout, and the changes the refused question carried are gathered again\n // for it: a refusal of the user's move is no reason to leave the totals before them on screen. A refusal of\n // the layout on screen itself is said, and asked again only by the next notice, Refresh or move.\n this.#landed(question, undefined, question.layout !== this.#shown.layout);\n return;\n }\n const broken = capBrokenBy(update.metadata, question);\n if (broken !== undefined) {\n // An answer past the report's caps is not shown (ADR-0066): newer data under the layout on screen leaves a\n // Stale Report, and a layout is refused, naming the moves it held. Either way the version is the one the\n // source told of, so it is not asked for again until the data moves on.\n const cap = formatPivotCount(broken.cap, question.locale);\n // The source answered, so a Refresh it carried is paid, and Retry asks the report again.\n if (question.refreshData) this.#refreshOwed = false;\n if (this.#staleFor(question)) {\n this.#markStale(this.#words.fill(broken.stale, cap), false);\n this.#draw();\n } else {\n this.#sayRefused(this.#words.fill(broken.refusal, cap), heldFields(heldMoves(question)));\n }\n this.#landed(question, update.metadata.sourceVersion, question.layout !== this.#shown.layout);\n return;\n }\n // The data on screen is the Pivot Source's as it is now: the Refresh is paid.\n if (question.refreshData) this.#refreshOwed = false;\n // Newer data, or data asked for again, ends a Stale Report; the time of the data shown moves with its version, and\n // with its source, whose versions are its own.\n const shown = this.#shown;\n const newer = shown.answer?.metadata.sourceVersion !== update.metadata.sourceVersion || shown.question?.reportSource !== question.reportSource;\n if (newer) this.#shownAt = Date.now();\n if (newer || asksData(question.cause)) {\n this.#stale = undefined;\n this.#staleRetryRefreshes = false;\n }\n // The changes this Window carries are shown from now, on the clock the grid paints by (createGrid's is the\n // system clock, ADR-0068). A cell keeps its mark after the source stops listing its change, until the\n // highlight stamped here ends.\n this.#changeTimes.adopt(update, systemClock.now(), this.#changeHighlightMs);\n this.#showLayout(question.layout, { answer: update, question }, question.raise);\n this.#landed(question, update.metadata.sourceVersion, false);\n }\n\n // ---- Changes of data (ADR-0067) --------------------------------------------------------------------\n\n // Whether a question that could not be shown leaves a Stale Report rather than a refusal: one the data asked, for the\n // layout of the report on screen. A move of the user's or the Consumer's is refused, and the pane goes back.\n #staleFor(question: Question): boolean {\n return asksData(question.cause) && this.#shown.answer !== undefined && question.layout === this.#shown.layout;\n }\n\n #markStale(sentence: string, retryRefreshes: boolean): void {\n this.#stale = sentence;\n this.#staleRetryRefreshes = retryRefreshes;\n }\n\n // What a refusal of newer data says, after the time of the data shown. A refusal the report source made itself, and\n // not the Pivot Source, is its failure to answer, as the Razor component says it.\n #staleRefusalOf(refusal: PivotReportRefusal, question: Question): string {\n const source = refusal.sourceRefusal;\n if (source === undefined) return this.#words.fill('stale-source-failed', refusal.message);\n if (source.kind === 'tooManyLeaves') return this.#words.fill('stale-too-many-cells', formatPivotCount(source.limit ?? question.maxLeaves, question.locale));\n return this.#words.fill('stale-source-refused', source.message);\n }\n\n // The Stale Report's Retry asks again what failed: Refresh, when that is what failed, otherwise the report's question\n // of the Pivot Source (ADR-0067). Either asks the Pivot Source itself, as the Razor component's Retry does: a report\n // source that kept its last answer would give back the data the report already shows, and the notice would go.\n #retry(): void {\n if (this.#staleRetryRefreshes) {\n this.#refresh();\n return;\n }\n this.#refreshOwed = true;\n this.#refusal = undefined;\n this.#ask(this.#layoutAhead, 'data', []);\n this.#draw();\n }\n\n // When the data the report shows arrived, in the report's locale: the time, and the date too when it is not today's,\n // since a time alone would say the report is fresher than it is.\n #asOf(): string {\n const at = new Date(this.#shownAt);\n const today = new Date().toDateString() === at.toDateString();\n const key = `${this.#shownAt} ${this.#locale} ${today ? 'today' : 'before'}`;\n if (this.#asOfSaid?.key !== key) {\n const text = new Intl.DateTimeFormat(this.#locale, today ? { timeStyle: 'medium' } : { dateStyle: 'short', timeStyle: 'medium' }).format(at);\n this.#asOfSaid = { key, text };\n }\n return this.#asOfSaid.text;\n }\n\n // Hears the report source's notices, and no longer the one before: a source handed over is asked from nothing, and\n // that question answers whatever was gathered.\n #hear(reportSource: LocalPivotReportSource): void {\n this.#stopHearing?.();\n this.#changed = false;\n this.#changedTo = undefined;\n this.#disarmRedraw();\n this.#stopHearing = reportSource.subscribe(changed => { this.#sourceChanged(reportSource, changed); });\n }\n\n // The source's data moved on: gathered, and asked for at once when the last change reached the screen more than\n // the redraw interval ago and nothing is out, otherwise when that time comes, or when the question out lands. A\n // notice of the very version on screen, with nothing out and nothing gathered before it, has nothing to bring.\n #sourceChanged(reportSource: LocalPivotReportSource, changed: PivotSourceChanged): void {\n if (this.#destroyed || reportSource !== this.#reportSource) return;\n const { answer, question } = this.#shown;\n if (!this.#changed && this.#asked === undefined && this.#stale === undefined && changed.sourceVersion !== undefined && question?.reportSource === reportSource\n && answer?.metadata.sourceVersion === changed.sourceVersion) {\n return;\n }\n this.#changed = true;\n this.#changedTo = changed.sourceVersion;\n this.#scheduleRedraw();\n }\n\n // Asks for the changes gathered no sooner than the redraw interval after the last change reached the screen: at\n // once when that time has passed, else when it comes. Nothing is asked while a question is out: its landing asks.\n #scheduleRedraw(): void {\n if (!this.#changed || this.#asked !== undefined || this.#destroyed) return;\n const ahead = this.#layoutAhead;\n if (showsNothing(ahead) && ahead.filters.length === 0) {\n // Nothing on screen reads the data: the next layout's question is asked of the source as it stands then.\n this.#changed = false;\n this.#disarmRedraw();\n return;\n }\n const now = performance.now();\n const due = this.#lastDataShown === undefined ? now : this.#lastDataShown + this.#redrawInterval;\n if (due <= now) {\n this.#ask(ahead, 'live', []);\n this.#draw();\n return;\n }\n if (this.#redrawTimer !== undefined) return;\n this.#redrawTimer = setTimeout(() => {\n this.#redrawTimer = undefined;\n this.#scheduleRedraw();\n }, due - now);\n }\n\n #disarmRedraw(): void {\n if (this.#redrawTimer === undefined) return;\n clearTimeout(this.#redrawTimer);\n this.#redrawTimer = undefined;\n }\n\n // A question landed \u2014 answered, refused or failed. One that carried changes of data brought them to the screen, or\n // found them unshowable, and the next waits the redraw interval from now; the changes gathered meanwhile are asked\n // for then, unless the answer is already of the version the latest notice named. `regather` gathers again the changes\n // a question carried and did not bring.\n #landed(question: Question, version: string | undefined, regather: boolean): void {\n if (question.carries) this.#lastDataShown = performance.now();\n if (regather && question.carries) this.#changed = true;\n if (this.#changed && this.#changedTo !== undefined && version === this.#changedTo) this.#changed = false;\n this.#scheduleRedraw();\n }\n\n #nextRequestId(): string {\n this.#requests++;\n return `ex-pivot-${this.#requests}`;\n }\n\n #showLayout(layout: PivotLayout, answered: { readonly answer: PivotReportState; readonly question: Question } | undefined, raise: boolean): void {\n const answer = answered?.answer;\n this.#shown = { layout, answer, question: answered?.question };\n // A pending move the report on screen now holds is news no more: a refusal of the pending layout names it no more.\n const deferred = this.#deferred;\n if (deferred !== undefined && deferred.moves.length > 0) {\n this.#deferred = Object.freeze({ layout: deferred.layout, moves: Object.freeze(deferred.moves.filter(move => !holdsMove(layout, move))) });\n }\n this.#showReport(answered);\n if (answer !== undefined && this.#counts !== undefined && this.#counts.sourceVersion !== answer.metadata.sourceVersion) {\n // Counted under another Source Version: asked again, so the marks follow the data (ADR-0370 section 3).\n this.#askCounts();\n }\n this.#draw();\n if (raise) {\n this.#raised.add(layout);\n this.#options.onLayoutChanged?.(Object.freeze({ layout }));\n }\n }\n\n // A refused question: the pane goes back to the layout the report shows, and the sentence says why. Every\n // move taken against the refused layout went with it, and is named (ADR-0370 section 3). A pending layout, while\n // Defer Layout Update is ticked, is the user's work in the pane, and stays, as the Razor component keeps it.\n #refuse(refusal: PivotReportRefusal, question: Question): void {\n const { message, fields } = this.#sentenceFor(refusal, question);\n this.#sayRefused(message, fields);\n }\n\n #sayRefused(message: string, fields: readonly string[]): void {\n this.#refusal = message;\n this.#draw();\n this.#options.onRefused?.(Object.freeze({ message, fields: Object.freeze(fields) }));\n }\n\n #sentenceFor(refusal: PivotReportRefusal, question: Question): { readonly message: string; readonly fields: readonly string[] } {\n const held = heldMoves(question);\n const named = heldFields(held);\n const source = refusal.sourceRefusal;\n if (source?.kind !== 'tooManyLeaves') return { message: refusal.message, fields: refusal.field === undefined ? named : [refusal.field] };\n // A source that names no limit stopped at the cap it was asked with (ADR-0066).\n const { locale } = question;\n const cap = formatPivotCount(source.limit ?? question.maxLeaves, locale);\n // Server data is refused naming each field moved into Rows or Columns, which make the combinations\n // (ADR-0370 section 3); data the pivot computes itself is refused by the cells the layout needs, as the\n // Razor component says it.\n const combining = held.filter(move => move.area === 'rows' || move.area === 'columns');\n if (!(this.#options.source instanceof FetchingPivotSource) || combining.length === 0) {\n return { message: this.#words.fill('refused-too-many-cells', cap), fields: named };\n }\n const sentences = combining.map(move => {\n const caption = this.#captionOf(move.field);\n const area = this.#words.area(move.area);\n const count = this.#counts?.countOf(move.field);\n const sentence = count === undefined\n ? this.#words.fill('refused-too-many-combinations', caption, area, cap)\n : this.#words.fill('refused-too-many-combinations-counted', caption, formatPivotCount(count, locale), area, cap);\n return `${sentence} ${this.#words.fill('refused-too-many-combinations-remedy', caption)}`;\n });\n return { message: sentences.join(' '), fields: named };\n }\n\n #captionOf(field: string): string {\n const found = this.#options.source.fields.find(f => f.name === field);\n if (found === undefined) throw new Error(`Internal: the field '${field}' is not the source's.`);\n return found.caption;\n }\n\n // Each field's count of Items, asked once when the source is opened and again under a new Source Version,\n // of a source that declares it counts them (ADR-0370 section 3). A source that does not gets no count.\n #askCounts(): void {\n this.#countsAsked?.abort();\n const source = this.#options.source;\n if (!source.features.countsItems || source.itemCounts === undefined) {\n this.#countsAsked = undefined;\n return;\n }\n const controller = new AbortController();\n this.#countsAsked = controller;\n void this.#countItems(source, controller);\n }\n\n async #countItems(source: PivotSource, controller: AbortController): Promise<void> {\n let counts;\n try {\n if (source.itemCounts === undefined) throw new Error('Internal: a source counted without counting Items.');\n counts = await source.itemCounts(controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a count superseded is nobody's; one that failed leaves the fields uncounted, said by rethrowing\n if (controller.signal.aborted || this.#destroyed) return;\n this.#countsAsked = undefined;\n throw error;\n }\n if (controller.signal.aborted || this.#destroyed || source !== this.#options.source) return;\n this.#countsAsked = undefined;\n this.#counts = counts;\n this.#draw();\n }\n\n // ---- The report ------------------------------------------------------------------------------------\n\n #showReport(answered: { readonly answer: PivotReportState; readonly question: Question } | undefined): void {\n this.#placing?.();\n this.#rows?.dispose();\n this.#rows = undefined;\n // The rows of the report before read a source that may since have been replaced.\n const before = this.#shownReportSource;\n this.#shownReportSource = answered?.question.reportSource;\n this.#release(before);\n if (answered === undefined || !this.#reportDrawn) {\n this.#grid?.destroy();\n this.#grid = undefined;\n return;\n }\n const { answer, question } = answered;\n this.#rows = reportRows({\n source: question.reportSource,\n layout: question.layout,\n settings: question.settings,\n maxLeaves: question.maxLeaves,\n answered: answer,\n nextRequestId: () => this.#nextRequestId(),\n moved: () => { this.#reportMoved(answer); },\n findGivenUp: why => { this.#findGivenUp(answer, why); },\n words: () => this.#words,\n });\n this.#drawGrid();\n if (question.toggled !== undefined) this.#placeToggled(question.toggled);\n }\n\n // The toggled Item keeps the Focus, as it does in Excel (ADR-0050 item 4): its label cell is selected among the\n // first rows the grid holds of the report it was toggled into, on the toggled row's path, as the Razor component\n // finds it among the rows drawn, and under the order those rows came in. A press, a key or a wheel the user turns\n // in the grid after the toggle, while its question is out or its rows are on their way, is newer than the toggle,\n // and the toggle places nothing over it (spine rule 6); a modifier pressed alone, or a key composing text, is no\n // such gesture. Nor does the toggle place anything after a later move, or once another report is shown. A placement the grid refuses leaves the Selection it dropped with the\n // old report, and the toggled Item is found in no other rows than those first ones: no place, rather than a\n // late one over what the user did since.\n #placeToggled(toggled: ToggledItem): void {\n const rows = this.#rows;\n const grid = this.#grid;\n if (rows === undefined || grid === undefined) return;\n const place = (): void => {\n if (this.#gestures !== toggled.gestures) {\n stop();\n return;\n }\n const state = rows.snapshot();\n if (state.window.length === 0) return;\n stop();\n const at = toggledCell(state.window, state.windowStart, toggled);\n if (at === undefined) return;\n grid.placeSelection(Object.freeze({ topRow: at.row, leftColumn: at.column, rowCount: 1, columnCount: 1 }), at, state.rowSequenceVersion);\n };\n const unsubscribe = rows.subscribe(place);\n const stop = (): void => {\n unsubscribe();\n if (this.#placing === stop) this.#placing = undefined;\n };\n this.#placing = stop;\n place();\n }\n\n // The source answered a Window from another report than the one shown: the data moved on under it, and the\n // report on screen is asked again under its layout, unless something newer is asked already.\n #reportMoved(answer: PivotReportState): void {\n // A Stale Report is not asked again for it: the newest data is what it could not show, and asking again would\n // break the same cap once per interval while the reader scrolls. Retry and the source's next notice ask.\n if (this.#destroyed || this.#shown.answer !== answer || this.#asked !== undefined || this.#stale !== undefined) return;\n // A change of data like any other: asked for no sooner than the redraw interval after the last one shown.\n this.#changed = true;\n this.#scheduleRedraw();\n }\n\n // Figures handed in replace the ones shown only when they differ from the ones handed before: an update that hands\n // the same again keeps the figures menu's choice. True when the figures shown moved.\n #adoptSummaryFigures(handed: readonly SummaryFigure[] | undefined): boolean {\n if (sameFigures(handed, this.#summaryFiguresHanded)) return false;\n this.#summaryFiguresHanded = handed;\n const shown = handed ?? defaultSummaryFigures;\n if (sameFigures(shown, this.#summaryFigures)) return false;\n this.#summaryFigures = shown;\n return true;\n }\n\n // The figures menu's choice, which the report holds and raises (ADR-0130). Held in a field: its identity reaches the\n // grid.\n readonly #summaryFiguresChosen = (figures: readonly SummaryFigure[]): void => {\n if (this.#destroyed) return;\n this.#summaryFigures = figures;\n this.#drawGrid();\n this.#options.onSummaryFiguresChanged?.(figures);\n };\n\n // The Selection Summary as it stands, raised to the Consumer's handler as the options now hold it. Held in a field,\n // so a handler that is a new function at each update does not draw the grid again.\n readonly #selectionSummaryChanged = (summary: SelectionSummary): void => {\n this.#options.onSelectionSummaryChanged?.(summary);\n };\n\n #drawGrid(): void {\n const answer = this.#shown.answer;\n const rows = this.#rows;\n const question = this.#shown.question;\n if (answer === undefined || rows === undefined || question === undefined) return;\n const { locale } = question;\n const { columns, headerGroups, pinnedColumnCount } = this.#columns.of(answer.metadata, this.#userWidths);\n this.#gridColumns = columns;\n this.#valueColumnIndexes = new Map(answer.metadata.valueColumns.map((column, index) => [column.name, index]));\n const { rowHeight, density, cellMetrics, presentationDefaults } = this.#options;\n const gridChrome = this.#chrome?.grid;\n const options: GridOptions<PivotDisplayRow> = {\n columns,\n headerGroups,\n pinnedColumnCount,\n source: rows,\n locale,\n viewportHeight: this.#options.viewportHeight ?? 400, // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report's declared default height, as the Razor component's\n viewportWidth: this.#options.viewportWidth ?? 'stretch', // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report takes what the Field List leaves unless told\n // Item order and Hidden Items are the Pivot Layout's, and a report is computed: no column menu, no\n // sort, no filter, and every write refused by the grid's own gate, since nobody hears one (ADR-0059).\n hideColumnMenu: true,\n onColumnWidthChanged: change => { this.#widthChanged(change); },\n onCellDoubleClick: cell => { this.#doubleClicked(cell); },\n onSelectionChanged: selection => { this.#selectionChanged(selection); },\n contextCommands: this.#contextCommands,\n // Find over the report as shown, and its painted matches marked by the rule it finds by (ADR-0332).\n findMatch: reportMatch,\n onRefused: this.#gridRefused,\n copyAnswerAsync: this.#copyReport,\n commandLabel: this.#commandLabel,\n cellChangedAt: this.#cellChangedAt,\n changeHighlightDuration: this.#changeHighlightMs,\n showSelectionSummary: this.#options.showSelectionSummary !== false,\n summaryFigures: this.#summaryFigures,\n onSummaryFiguresChanged: this.#summaryFiguresChosen,\n onSelectionSummaryChanged: this.#selectionSummaryChanged,\n ...(gridChrome === undefined ? {} : { chrome: gridChrome }),\n ...(rowHeight === undefined ? {} : { rowHeight }),\n ...(density === undefined ? {} : { density }),\n ...(cellMetrics === undefined ? {} : { cellMetrics }),\n ...(presentationDefaults === undefined ? {} : { presentationDefaults }),\n };\n if (this.#grid === undefined) {\n // Made standing in the sheet, inside the pivot's box: the grid reads its Input Root once, as it is made, and\n // on an element standing nowhere it would hear only itself, not the Field List, the toolbar or the popups\n // (ADR-0240 section 6). The draw that follows keeps it there, or puts the report's notice in its place.\n if (this.#gridRoot.parentNode !== this.#sheet) this.#sheet.prepend(this.#gridRoot);\n this.#grid = this.#mountGrid(this.#gridRoot, options);\n } else {\n this.#grid.update(options);\n }\n }\n\n // A Find step over the report that cannot go on is said on the Pivot Toolbar, while that report is the one shown:\n // a step over a report since replaced is the grid's to refuse, as its source is no longer the grid's (ADR-0332 \u00A71).\n #findGivenUp(answer: PivotReportState, why: ReportFindGivenUp): void {\n if (this.#destroyed || this.#shown.answer !== answer) return;\n switch (why.kind) {\n case 'notHeld': this.#refusal = this.#words.word('find-report-not-held'); break;\n case 'refused': this.#refusal = this.#words.fill('source-refused', why.refusal.message); break;\n case 'invalid': this.#refusal = this.#words.word('find-invalid-answer'); break;\n default: unreachable(why);\n }\n this.#draw();\n }\n\n // A copy is the report source's, of the report on screen, as the Razor component's is (ADR-0152): each cell's text\n // and its locale-free form, and a number column Item's header in full in the HTML flavour (ADR-0005's note of\n // 2026-10-13). Every refusal is said in ExPivot's words, a source's own inside one (ADR-0060). Held in a field: its\n // identity reaches the grid.\n readonly #copyReport = async (request: GridCopyRequest, signal: AbortSignal): Promise<GridCopyAnswer> => {\n // The whole question is captured before awaiting: a new Window never rebinds this gesture.\n const metadata = this.#shown.answer?.metadata;\n const source = this.#shownReportSource;\n const rows = this.#rows;\n if (metadata === undefined || source === undefined || rows === undefined || request.rowSequenceVersion !== rows.snapshot().rowSequenceVersion) {\n return refuse(this.#words.word('data-changed'));\n }\n // A Stale Report shows the data as of its time, and says so beside it; pasted elsewhere, the numbers would lose\n // that and look current. So Copy is refused, saying as of when, until Retry brings the newest (ADR-0067).\n if (this.#stale !== undefined) return refuse(this.#words.fill('copy-stale-report', this.#asOf()));\n const { plan } = request;\n const version = metadata.version;\n const answer = await source.copy(Object.freeze({\n version,\n columns: Object.freeze(this.#gridColumns.map(column => column.name)),\n ranges: Object.freeze(plan.segments.map(range => Object.freeze({\n top: range.topRow, left: range.leftColumn, bottom: range.topRow + range.rowCount - 1, right: range.leftColumn + range.columnCount - 1,\n }))),\n }), signal);\n if (answer.version !== version) return refuse(this.#words.word('copy-another-version'));\n if (answer.refusal !== undefined) return refuse(this.#words.fill('source-refused', answer.refusal.message));\n if (answer.blocks.length !== plan.segments.length) return refuse(this.#words.word('copy-missing-range'));\n const whole = plan.segments.every((range, i) => {\n const block = elementAt(answer.blocks, i);\n return block.rows.length === range.rowCount && block.headers.length === range.columnCount\n && (block.headerRaws === undefined || block.headerRaws.length === range.columnCount)\n && block.rows.every(cells => cells.length === range.columnCount);\n });\n if (!whole) return refuse(this.#words.word('copy-incomplete-range'));\n // The block a position lies in: the one the last position lay in, which assembly mostly asks again, or the one\n // found by halves along the plan's order, as the Razor component finds it.\n const vertical = plan.orientation === 'vertical';\n let hint = 0;\n const blockAt = (row: number, column: number): number => {\n const at = vertical ? row : column;\n const within = (index: number): number => {\n const range = elementAt(plan.segments, index);\n const start = vertical ? range.topRow : range.leftColumn;\n const end = start + (vertical ? range.rowCount : range.columnCount) - 1;\n return at < start ? -1 : at > end ? 1 : 0;\n };\n if (within(hint) === 0) return hint;\n let low = 0;\n let high = plan.segments.length - 1;\n while (low <= high) {\n const middle = low + Math.floor((high - low) / 2);\n const side = within(middle);\n if (side === 0) {\n hint = middle;\n return middle;\n }\n if (side < 0) high = middle - 1;\n else low = middle + 1;\n }\n throw new Error('The copied position is outside the approved plan.');\n };\n const cellAt = (row: number, column: number): PivotReportCopyCell => {\n const index = blockAt(row, column);\n const range = elementAt(plan.segments, index);\n return elementAt(elementAt(elementAt(answer.blocks, index).rows, row - range.topRow), column - range.leftColumn);\n };\n const headerBlock = (column: number): number => {\n const index = plan.segments.findIndex(range => column >= range.leftColumn && column < range.leftColumn + range.columnCount);\n if (index < 0) throw new Error('The copy header is outside the approved plan.');\n return index;\n };\n const flavours = assembleCopy(plan, {\n displayAt: (row, column) => cellAt(row, column).text,\n // A blank carries no raw form, and is written empty, as the Razor component writes it.\n // oxlint-disable-next-line ex-grid/no-stand-in-default -- ADR-0005: a blank cell's HTML flavour is empty\n rawAt: (row, column) => cellAt(row, column).raw ?? '',\n ...(request.withHeaders ? {\n headerAt: (column: number) => {\n const index = headerBlock(column);\n return elementAt(elementAt(answer.blocks, index).headers, column - elementAt(plan.segments, index).leftColumn);\n },\n headerRawAt: (column: number) => {\n const index = headerBlock(column);\n return elementAt(answer.blocks, index).headerRaws?.[column - elementAt(plan.segments, index).leftColumn];\n },\n } : {}),\n });\n return Object.freeze({ kind: 'write', text: flavours.text, html: flavours.html });\n };\n\n // The report grid's refusals: Ctrl+H on a report, which is not written, is said on the Pivot Toolbar in Excel's\n // words (ADR-0332 \u00A72). The refusals the find panel shows itself are left to it. Held in a field: its identity\n // reaches the grid.\n readonly #gridRefused = (refusal: GridRefusal<PivotDisplayRow>): void => {\n if (this.#destroyed || refusal.kind !== 'find' || refusal.reason !== 'replaceUnavailable') return;\n this.#refusal = this.#words.word('replace-unavailable');\n this.#draw();\n };\n\n // A width the user dragged a column to is the Consumer's to hand back (ADR-0016): the pivot keeps it, by the\n // column's name, for every report that has the column.\n #widthChanged(change: GridColumnWidthChange): void {\n this.#userWidths.set(change.column, change.widthPx);\n this.#drawGrid();\n }\n\n // The grid's selection, said with what its cells stand for, read from the rows the grid holds when it is\n // raised: each report is a new source, so a selection the grid keeps is over the same report's rows, and one\n // over another report is dropped and raised again (ADR-0011). The Items are read when first asked for, from\n // what was held then, so a selection dragged over thousands of cells costs nothing until a Consumer reads it.\n #selectionChanged(selection: GridSelection): void {\n const raise = this.#options.onSelectionChanged;\n if (raise === undefined || this.#destroyed) return;\n const answer = this.#shown.answer;\n const state = this.#rows?.snapshot();\n const metadata = answer?.metadata;\n let read = false;\n let items: readonly PivotCellItems[] | undefined;\n raise(Object.freeze({\n selection,\n get items(): readonly PivotCellItems[] | undefined {\n if (!read) {\n read = true;\n if (metadata !== undefined && state !== undefined) items = cellItems(selection, metadata, state.window, state.windowStart);\n }\n return items;\n },\n }));\n }\n\n // A double click on an outer Item's label expands or collapses it, as Excel's does (ADR-0063).\n #doubleClicked(cell: CellPosition): void {\n const { answer, question } = this.#shown;\n const rows = this.#rows;\n if (answer === undefined || question === undefined || rows === undefined) return;\n const state = rows.snapshot();\n const row = state.window[cell.row - state.windowStart];\n if (row === undefined) return;\n const labels = answer.metadata.labelColumns.length;\n if (cell.column >= labels) {\n this.#showDetails(answer, question, row, cell.column - labels);\n return;\n }\n // A double click on an outer Item's label expands or collapses it, as in Excel.\n const toggle = elementAt(row.labels, cell.column).toggle;\n if (toggle !== undefined) this.#toggled(toggle, row);\n }\n\n // Show Details (ADR-0059, ADR-0063): the records behind a value cell, asked of the Pivot Source the report came\n // from under its Source Version, so they add up to the cell. An empty cell has none. Resolved now, from the cell\n // the user acted on: the question names its Items and the Source Version, so a collapse or a sort that follows\n // leaves it the same question.\n #showDetails(answer: PivotReportState, question: Question, row: PivotDisplayRow, valueColumn: number): void {\n if (row.values[valueColumn] === undefined) return;\n const { metadata } = answer;\n const words = this.#words;\n const fields = question.source.fields;\n const options = { locale: question.locale, ...(words.label === undefined ? {} : { label: words.label }) };\n // Each Item with its field's caption and its label, by the engine's rule for its field (ADR-0060).\n const items = (path: readonly PivotFieldItem[]): readonly PivotDetailItem[] => Object.freeze(path.map(step => {\n const declared = fields.find(field => field.name === step.field);\n if (declared === undefined) throw new Error(`Internal: the report's field '${step.field}' is not its source's.`);\n const [info] = itemsOfPage(PivotItemPage.of(metadata.sourceVersion, [step.item], 1), metadata.layout, declared, options);\n if (info === undefined) throw new Error('Internal: an Item listed is labelled.');\n return Object.freeze({ field: declared.caption, item: info.label });\n }));\n const rowItems = items(row.rowPath);\n const column = elementAt(metadata.valueColumns, valueColumn);\n const columnItems = items(column.columnPath);\n const valueField = valueFieldAt(metadata, row, valueColumn);\n const path = [...rowItems, ...columnItems].map(item => item.item);\n const details = detailsEvent(question.source, pivotReportDetailsQuery(metadata, row, valueColumn), {\n title: words.fill('details-title', path.length === 0 ? words.word('grand-total') : path.join(' / ')),\n rowItems,\n columnItems,\n valueField: valueField < 0 ? undefined : elementAt(metadata.valueCaptions, valueField),\n });\n const heard = this.#options.onShowDetails;\n if (heard !== undefined) {\n this.#detailsRaised.add(details);\n heard(details);\n return;\n }\n this.#details.open(details, this.#options.detailsView ?? 'tab', question.locale); // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0059: a tab at the report's foot unless the Consumer asks for the dialog, as the Razor component's DetailsView\n this.#slotErrors.push(...this.#details.takeRefused());\n this.#throwRefused();\n }\n\n // The report's commands in the grid's Context Menu (ADR-0036, ADR-0059), for a row of the report on screen.\n readonly #contextCommands = (context: GridContextMenuContext<PivotDisplayRow>): readonly GridCommand[] => {\n const { answer, question } = this.#shown;\n const rows = this.#rows;\n if (this.#destroyed || answer === undefined || question === undefined || rows === undefined || !rows.snapshot().window.includes(context.row)) {\n return [];\n }\n return reportMenuCommands({\n metadata: answer.metadata,\n row: context.row,\n column: context.column,\n report: this.#layoutAhead,\n pane: this.#paneLayout,\n fieldListShown: this.#fieldListShown,\n captionOf: field => this.#captionOf(field),\n }, {\n edit: (edit, toggled) => { this.#reportEdit(edit, toggled === undefined ? undefined : this.#toggledItemOf(context.row, toggled)); },\n showDetails: valueColumn => { this.#showDetails(answer, question, context.row, valueColumn); },\n valueFieldSettings: (valueField, holds) => { this.#openFromReport(valueField, holds); },\n setFieldListShown: shown => { this.#setFieldListShown(shown); },\n });\n };\n\n // The words of the grid's commands (ADR-0036): the Consumer's, then the pivot's own for its commands; the grid's\n // own commands keep the grid's English where the Consumer gives none. Made again with the Consumer's words, so the\n // grid, which holds words by the function they came from, reads them again.\n #commandLabelOf(label: PivotLabel | undefined): (id: string) => string | undefined {\n return id => {\n const own = label?.(id);\n if (own !== undefined) return own;\n const caption = captionOfRemove(id);\n if (caption !== undefined) return this.#words.fill(removeNamedFieldId, caption);\n return pivotWordIds.has(id) ? pivotWord(id, undefined) : undefined;\n };\n }\n\n // The stylesheets' notices (ADR-0123, ERR-11), as the Razor component draws them: ExPivot's own, and beside it one\n // for each stylesheet the Chrome brings, each hidden until a stylesheet's rules decide. Every shipped stylesheet\n // shows a notice of its name and hides it for its own stamp, so another version's shows it, this version's hides\n // it, and none yet loaded shows nothing, with no script. The report grid draws ExGrid's own.\n #drawNotices(): void {\n const brought = this.#chrome?.stylesheets;\n const sheets = [{ name: stylesheetName, stamp: stylesheetStamp }, ...(brought === undefined ? [] : brought)];\n const id = reloadNoticeLabelIds.stylesheet;\n const words = this.#commandLabel(id) ?? builtInCommandLabel(id);\n const drawn = JSON.stringify([words, sheets.map(sheet => [sheet.name, sheet.stamp])]);\n if (drawn === this.#noticesDrawn) return;\n this.#noticesDrawn = drawn;\n for (const notice of this.#notices) notice.remove();\n this.#notices = sheets.map(sheet => {\n const notice = element(this.#root.ownerDocument, 'div');\n notice.setAttribute('data-ex-notice', 'stylesheet');\n notice.setAttribute('data-ex-stylesheet', sheet.name);\n notice.setAttribute('data-ex-stamp', sheet.stamp);\n notice.style.display = 'none';\n notice.textContent = words;\n return notice;\n });\n this.#root.prepend(...this.#notices);\n }\n\n // Value Field Settings\u2026 from the report opens in the pane, under the Value Field's entry, showing the Field List.\n // Opened only while the pane holds the Value Field the cell showed there.\n #openFromReport(valueField: number, holds: (pane: PivotLayout) => boolean): void {\n const pane = this.#paneLayout;\n const value = pane.values[valueField];\n if (value === undefined || !holds(pane)) return;\n this.#setFieldListShown(true);\n this.#openPanelAt({ entry: { area: 'values', index: valueField }, field: value.field, against: pane }, 'value-field-settings');\n }\n\n // An outer Item's button pressed, or its label double clicked: the Item is collapsed or expanded (ADR-0063).\n // The press does what the button it was taken on said, against the report's layout, the one the newest question\n // asks for; where that layout no longer holds the Item as the button painted it, a press already moved it, or\n // its field left the layout, and the press is refused rather than turned into its opposite (spine rule 6). Two\n // presses of one painted button collapse once, as the Razor component's do. A pending layout follows it.\n // An Item toggled on a row, as it keeps the Focus in the report the toggle brings.\n #toggledItemOf(row: PivotDisplayRow, toggled: PivotFieldItem): ToggledItem {\n const level = row.rowPath.findIndex(step => step.field === toggled.field && itemKeysEqual(step.item, toggled.item));\n if (level < 0) throw new Error(`Internal: the row toggled holds no '${toggled.field}' Item there.`);\n return Object.freeze({ path: Object.freeze(row.rowPath.slice(0, level + 1)), gestures: this.#gestures });\n }\n\n // The Item keeps the Focus in the report the press brings.\n #toggled(toggle: PivotToggle, row: PivotDisplayRow): void {\n if (this.#destroyed) return;\n const now = this.#layoutAhead;\n const placed = now.rows.find(placement => placement.field === toggle.field);\n if (placed === undefined || isItemCollapsed(placed, toggle.item) !== toggle.isCollapsed) return;\n this.#reportEdit(layout => (layout.rows.some(placement => placement.field === toggle.field)\n ? setCollapsed(layout, toggle.field, toggle.item, !toggle.isCollapsed)\n : undefined), this.#toggledItemOf(row, toggle));\n }\n\n // The report asked again of the Pivot Source, under the pane's layout. A move of the user's still out is asked again\n // with it, and stays the user's.\n #refresh(): void {\n // Owed until an answer from the Pivot Source asked again lands: a move made meanwhile, or a layout with nothing\n // to compute, does not answer it from the data before it.\n this.#refreshOwed = true;\n this.#refusal = undefined;\n this.#askCounts();\n this.#ask(this.#layoutAhead, 'data', []);\n this.#draw();\n }\n\n // ---- Menus and panels (ADR-0061) -------------------------------------------------------------------\n\n #toggleLayoutMenu(): void {\n if (this.#open?.kind === 'layout') {\n this.#close('opener');\n return;\n }\n this.#anchorFor('layout', 'chrome.toolbar hands in no anchor \\'layout\\': hand context.anchor(\\'layout\\') the element around Layout \u25BE');\n this.#openSurface({ kind: 'layout', popup: this.#menuFrame('toolbar-end') });\n }\n\n // A popup of the Pivot Toolbar's opens only in an anchor that stands: one that would stand nowhere, behind a\n // backdrop that takes every press, is refused, naming what the Chrome did not hand in (ADR-0390).\n #anchorFor(name: string, missing: string): void {\n if (!this.#parts.anchored(name)) throw new Error(`An ExPivot's ${missing} (ADR-0390).`);\n }\n\n // An entry's button opens its menu, and closes the menu standing under it.\n #toggleEntryMenu(entry: PivotEntry): void {\n // A panel open under the entry is dropped for the menu, as the Razor component's ToggleMenu does.\n const open = this.#open;\n if (open?.kind === 'entry' && sameEntry(open.entry, entry)) {\n this.#close('opener');\n return;\n }\n const pane = this.#paneLayout;\n const field = isValuesPseudoField(entry) ? undefined : fieldOf(pane, entry);\n if (this.#fieldListSlotted) {\n this.#anchorFor(entryKey(entry), `chrome.fieldList hands in no anchor for the entry '${entryKey(entry)}': hand context.anchor(entry.key) the element around its button`);\n }\n this.#openSurface({ kind: 'entry', entry, field, against: pane, popup: this.#menuFrame('field-list') });\n }\n\n #menuFrame(place: 'field-list' | 'toolbar-end'): PivotMenu {\n const escape = (): void => { this.#close('opener'); };\n const mount = this.#chrome?.menu;\n const frame = mount === undefined\n ? new PivotMenuFrame(this.#root.ownerDocument, place, escape)\n : new SlottedMenuFrame(this.#root.ownerDocument, place, mount, this.#words, escape);\n this.#closeOnLeaving(frame.element);\n return frame;\n }\n\n // The keyboard leaving what is open for another control \u2014 Tab past its last command \u2014 closes it, so the backdrop of\n // a surface opened from the Pivot Toolbar takes no press meant for that control, and a field menu does not stand\n // open over the pane once the keyboard left the pivot. A field menu's entry, which toggles it, is inside its bounds.\n #closeOnLeaving(frame: HTMLElement): void {\n frame.addEventListener('focusout', event => {\n const to = event.relatedTarget;\n const open = this.#open;\n // A popup of a Chrome's contents may stand outside the frame, and take the keyboard while it is open.\n if (open?.popup.element !== frame || !(to instanceof Node) || open.popup.innerPopupOpen?.() === true) return;\n if (!this.#within(open, to)) this.#close('stay');\n });\n }\n\n // Whether `node` is inside what is open. A field menu's bounds are its entry: the anchor around the frame, and the\n // entry's button, which a Chrome may draw beside the anchor rather than in it, as a design system draws a menu's\n // opener.\n #within(open: OpenSurface, node: Node): boolean {\n const frame = open.popup.element;\n if (open.kind !== 'entry') return frame.contains(node);\n const anchor = frame.parentNode;\n return (anchor !== null && anchor.contains(node)) || this.#parts.controlContains(entryKey(open.entry), node);\n }\n\n // A report filter's button opens Filter\u2026 under it, over the report, and closes the one standing under it.\n #toggleBand(field: string): void {\n const open = this.#open;\n if (open?.kind === 'band' && open.field === field) {\n this.#close('opener');\n return;\n }\n this.#anchorFor(bandName(field), `chrome.reportFilters hands in no anchor for '${field}': hand context.anchor('${field}') the element around its button`);\n const report = this.#layoutAhead;\n const handlers = {\n // OK's Hidden Items are the report's next, taken against the layout Filter\u2026 was opened on (spine rule 6),\n // and reach a pending layout that holds the field too.\n apply: (layout: PivotLayout) => {\n this.#finish(surface, () => {\n if (report === this.#layoutAhead) {\n const hidden = defined(layout.filters.find(placement => placement.field === field), `the report filter '${field}'`).hiddenItems;\n this.#reportEdit(now => (placementOf(now, field) === undefined ? undefined : setHiddenItems(now, field, hidden, []).layout));\n }\n return undefined;\n });\n },\n cancel: () => { if (this.#open === surface) this.#close('opener'); },\n items: () => this.#itemsOf(field),\n search: (search: string, signal: AbortSignal) =>\n Promise.resolve().then(() => searchItems(field, search, defined(this.#itemsUnder(field), 'a report to search the Items of'), signal)),\n };\n this.#items.retry(field);\n const popup = itemFilterPanel(this.#root.ownerDocument,\n { layout: report, field, caption: this.#captionOf(field), place: 'toolbar-start', locale: this.#locale, words: this.#words }, handlers,\n this.#chrome?.itemFilter);\n this.#closeOnLeaving(popup.element);\n const surface: OpenSurface = { kind: 'band', field, against: report, popup };\n this.#openSurface(surface);\n }\n\n // Opened, its first enabled command, or its panel's first control, takes the keyboard.\n #openSurface(open: OpenSurface): void {\n this.#takeDown();\n this.#open = open;\n this.#draw();\n open.popup.takeKeyboard();\n }\n\n // Closed by Escape, by its button, by the backdrop or by Cancel, the keyboard goes back to what opened it.\n // Dismissed by a press or focus elsewhere, it stays where that put it.\n #close(keyboard: 'opener' | 'stay'): void {\n const open = this.#takeDown();\n if (open === undefined) return;\n this.#draw();\n if (keyboard === 'opener') this.#returnKeyboard(open, this.#entryNow(open));\n }\n\n // Takes what is open off the page, without drawing.\n #takeDown(): OpenSurface | undefined {\n const open = this.#open;\n this.#open = undefined;\n if (open === undefined) return undefined;\n closed(open);\n this.#parts.unplace(open.popup.element);\n open.popup.element.remove();\n return open;\n }\n\n // The keyboard goes back to the button that opened the menu: Layout \u25BE, a report filter's button, or the entry `entry`\n // names, where the field the menu was for stands now; a field taken out of the Areas hands it to its tick box in\n // the list.\n #returnKeyboard(open: OpenSurface, entry: PivotEntry | undefined): void {\n if (open.kind === 'layout') this.#parts.focus('layout');\n else if (open.kind === 'band') this.#focusBand(open.field);\n else if (entry !== undefined) this.#fieldList.focusEntry(entry);\n else this.#fieldList.focusField(open.field);\n }\n\n // A report filter's button; once the field has left Filters, its tick box in the Field List, or the toggle that\n // shows the list.\n #focusBand(field: string): void {\n if (this.#layoutAhead.filters.some(placement => placement.field === field)) this.#parts.focus(bandName(field));\n else if (this.#fieldListShown) this.#fieldList.focusField(field);\n else this.#parts.focus('field-list');\n }\n\n // Where the field a menu or panel in the Field List was for stands in the pane's layout now; none for what opened\n // from the Pivot Toolbar.\n #entryNow(open: OpenSurface): PivotEntry | undefined {\n return open.kind === 'entry' || open.kind === 'panel' ? entryOfField(this.#paneLayout, open.field, open.entry) : undefined;\n }\n\n\n // Closes what is open, does what its command or its OK says, and hands the keyboard back once the pivot is drawn\n // after it. The popup leaves the page once the keyboard has gone back, so the Layout menu's never passes it\n // through the page's body (ADR-0061). Pressed once what it stood in has closed, it does nothing.\n #finish(open: OpenSurface, run: () => PivotEntry | undefined): void {\n if (this.#open !== open) return;\n this.#open = undefined;\n closed(open);\n this.#returnKeyboard(open, run());\n this.#parts.unplace(open.popup.element);\n open.popup.element.remove();\n }\n\n #command(open: OpenSurface, command: Omit<PivotMenuCommand, 'invoke'>, run: () => PivotEntry | undefined): PivotMenuCommand {\n return Object.freeze({ ...command, invoke: () => { this.#finish(open, run); } });\n }\n\n // The Layout menu (ADR-0061): Excel's Design tab choices, the current one of each group marked, and one that\n // would change nothing disabled, read from the report's layout. A choice is the report's, and reaches a pending\n // layout too.\n #layoutCommands(open: OpenSurface): readonly PivotMenuCommand[] {\n const report = this.#layoutAhead;\n const words = this.#words;\n return pivotLayoutChoices.map(choice => {\n const id = layoutChoiceId(choice);\n const heading = layoutHeadings.get(choice);\n return this.#command(open, {\n id,\n label: words.word(id),\n enabled: layoutChoiceChanges(report, choice),\n checked: isLayoutChosen(report, choice),\n ...(heading === undefined ? {} : { heading: words.word(heading) }),\n }, () => {\n this.#reportEdit(now => chooseLayout(now, choice));\n return undefined;\n });\n });\n }\n\n #entryCaption(entry: PivotEntry, valueCaptions: readonly string[] | undefined): string {\n if (isValuesPseudoField(entry)) return this.#words.word('values-pseudo-field');\n if (entry.area === 'values') return elementAt(defined(valueCaptions, 'the Value Fields\\' captions'), entry.index);\n return this.#captionOf(fieldOf(this.#paneLayout, entry));\n }\n\n // A field menu's command: a change of the layout, made as the menu closes, or a panel opened in its place.\n #entryCommand(open: EntrySurface, command: EntryMenuCommand): PivotMenuCommand {\n const { does, ...shown } = command;\n if ('edit' in does) {\n return this.#command(open, shown, () => {\n const made = does.edit();\n this.#edited(made);\n return made.entry;\n });\n }\n return Object.freeze({ ...shown, invoke: () => { this.#openPanel(open, does.panel); } });\n }\n\n #openPanel(open: EntrySurface, panel: EntryPanel): void {\n if (this.#open === open) this.#openPanelAt(open, panel);\n }\n\n // A panel opened under a field's entry in the pane: from its menu, or from the report's Context Menu.\n #openPanelAt(open: AtEntry, panel: EntryPanel): void {\n const document = this.#root.ownerDocument;\n const { entry, against } = open;\n // The panel's OK and Cancel are called once it stands, and act only while it does.\n const handlers = {\n // OK's layout is the pane's next, taken against the layout the panel was opened on (spine rule 6).\n apply: (layout: PivotLayout) => {\n this.#finish(surface, () => {\n this.#edited({ layout, against, moved: undefined });\n return this.#entryNow(surface);\n });\n },\n cancel: () => { if (this.#open === surface) this.#close('opener'); },\n };\n const words = this.#words;\n const fields = this.#options.source.fields;\n const captions = pivotValueCaptions(against, fields, { locale: this.#locale, ...(words.label === undefined ? {} : { label: words.label }) });\n let popup: PivotPanel;\n switch (panel) {\n case 'filter-items': {\n const field = fieldOf(against, entry);\n // Opened again on Items that could not be listed, it asks for them again.\n this.#items.retry(field);\n popup = itemFilterPanel(document, { layout: against, field, caption: this.#captionOf(field), place: 'field-list', locale: this.#locale, words }, {\n ...handlers,\n items: () => this.#itemsOf(field),\n // Asked from the panel's draw, it says a problem in a later turn, never in the middle of that draw.\n search: (search, signal) => Promise.resolve().then(() => searchItems(field, search, defined(this.#itemsUnder(field), 'a report to search the Items of'), signal)),\n }, this.#chrome?.itemFilter);\n break;\n }\n case 'field-settings':\n popup = fieldSettingsPanel(document, {\n layout: against,\n placement: elementAt(placementsIn(against, entry.area), entry.index),\n caption: this.#entryCaption(entry, captions),\n valueCaptions: captions,\n words,\n }, handlers, this.#chrome?.fieldSettings);\n break;\n case 'value-field-settings':\n popup = valueFieldSettingsPanel(document, {\n layout: against,\n index: entry.index,\n fieldCaption: this.#captionOf(fieldOf(against, entry)),\n caption: elementAt(captions, entry.index),\n fields,\n features: this.#options.source.features,\n locale: this.#locale,\n words,\n }, handlers, this.#chrome?.valueFieldSettings);\n break;\n default:\n unreachable(panel);\n }\n const surface: EntrySurface = { kind: 'panel', entry, field: open.field, against, popup };\n this.#openSurface(surface);\n }\n\n // Each draw draws the open menu again from the pane's layout. A field's menu or panel, or a report filter's Filter\u2026,\n // goes when the pane leaves the layout it was opened on, since its entry may now be another field's and its draft is\n // taken against that layout; one in the Field List goes too when the list is hidden. The keyboard it held goes to\n // the entry or the button its field stands at now.\n #drawMenu(valueCaptions: readonly string[] | undefined): void {\n const open = this.#open;\n const inList = open?.kind === 'entry' || open?.kind === 'panel';\n const holding = open?.kind === 'band' ? this.#layoutAhead : this.#paneLayout;\n if (open !== undefined && open.kind !== 'layout' && (open.against !== holding || (inList && !this.#fieldListShown))) {\n const held = open.popup.element.contains(this.#root.ownerDocument.activeElement);\n this.#takeDown();\n // Hidden with the Field List, the keyboard goes to the toggle that shows it again.\n if (held && (this.#fieldListShown || !inList)) this.#keyboardAfterDraw = open;\n else if (held) this.#parts.focus('field-list');\n }\n const shown = this.#open;\n this.#drawToolbar();\n if (shown?.kind === 'layout') {\n shown.popup.draw(this.#words.word('layout-menu'), this.#layoutCommands(shown));\n this.#parts.place('layout', shown.popup.element);\n }\n this.#drawBand();\n if (shown?.kind === 'band') this.#parts.place(bandName(shown.field), shown.popup.element);\n // Under what is open from the Pivot Toolbar, a press anywhere else closes it.\n if (shown?.kind === 'layout' || shown?.kind === 'band') {\n if (this.#backdrop.parentNode !== this.#root) this.#root.append(this.#backdrop);\n } else {\n this.#backdrop.remove();\n }\n if (shown?.kind === 'entry') {\n const { entry } = shown;\n const commands = entryMenuCommands({ layout: this.#paneLayout, fields: this.#options.source.fields, words: this.#words }, entry);\n shown.popup.draw(this.#words.fill('field-menu', this.#entryCaption(entry, valueCaptions)),\n commands.map(command => this.#entryCommand(shown, command)));\n }\n if (shown?.kind === 'panel' || shown?.kind === 'band') shown.popup.redraw?.();\n }\n\n // Shows a standing part's contents by `mount`; answers whether they stand. Contents that cannot be drawn leave the\n // built-in markup in their place, and are refused by name once the pivot has drawn.\n #showStanding<View, Context>(slot: StandingSlot<View, Context>, mount: PivotChromeSlot<Context>,\n context: (...made: [...Parameters<Parameters<StandingSlot<View, Context>['show']>[1]>, refs: PartRefs]) => Context): boolean {\n // Each mount hands its controls and anchors in by refs of its own.\n return this.#answered(slot.show(mount, (shared, input) => context(shared, input, this.#parts.refs()), id => this.#words.word(id)));\n }\n\n // Whether a standing part's contents stand, as `answer` says; an error it answers is the draw's to throw.\n #answered(answer: { readonly shown: boolean; readonly error?: Error }): boolean {\n if (answer.error !== undefined) this.#slotErrors.push(answer.error);\n return answer.shown;\n }\n\n // The Pivot Toolbar (ADR-0061): the built-in markup's, or a Chrome's in its place, drawn from the same view; the\n // refusal of the user's last change is the toolbar's to say. The built-in markup's controls are handed in again\n // each time it stands, as a Chrome's are when it draws them.\n #drawToolbar(): void {\n const words = this.#words;\n const view = this.#toolbarSlot.viewOf(Object.freeze({\n layoutMenu: Object.freeze({ label: words.word('layout-menu'), open: this.#open?.kind === 'layout' }),\n ...(this.#options.source.features.canRefresh ? { refresh: Object.freeze({ label: words.word('refresh') }) } : {}),\n fieldList: Object.freeze({ label: words.word('field-list-toggle'), shown: this.#fieldListShown }),\n reportFilters: this.#layoutAhead.filters.length > 0,\n ...(this.#refusal === undefined ? {} : { refusal: this.#refusal }),\n }));\n const mount = this.#chrome?.toolbar;\n // A control taken away while it holds the keyboard hands it to the Field List's toggle, so it stays in the pivot.\n const refreshHeld = view.refresh === undefined && this.#parts.holds('refresh');\n // The slot stands in the page as the contents mount, so plain script hands in controls already in it; contents\n // refused once leave the built-in toolbar standing, and the keyboard on it.\n if (mount !== undefined && !this.#toolbarSlot.refuses(mount)) swap(this.#toolbar, this.#toolbarSlot.element);\n const shown = mount !== undefined && this.#showStanding(this.#toolbarSlot, mount, (shared, input, refs) => ({\n ...shared,\n toggleLayoutMenu: input(() => { this.#toggleLayoutMenu(); }),\n refresh: input(() => { if (this.#options.source.features.canRefresh) this.#refresh(); }),\n toggleFieldList: input(() => { this.#setFieldListShown(!this.#fieldListShown); }),\n control: name => refs.control(checkedName(name, ['layout', 'refresh', 'field-list'], 'toolbar')),\n anchor: name => refs.anchor(checkedName(name, ['layout', 'report-filters'], 'toolbar')),\n }));\n if (shown) {\n this.#notice.remove();\n } else {\n this.#toolbarSlot.hide();\n swap(this.#toolbarSlot.element, this.#toolbar);\n for (const [name, control] of [['layout', this.#layoutButton], ['refresh', this.#refreshButton], ['field-list', this.#fieldListToggle]] as const) {\n this.#parts.handInControl(name, control);\n }\n this.#parts.handInAnchor('layout', this.#layoutAnchor);\n this.#parts.handInAnchor('report-filters', this.#toolbarStart);\n this.#layoutLabel.textContent = view.layoutMenu.label;\n this.#layoutButton.setAttribute('aria-expanded', view.layoutMenu.open ? 'true' : 'false');\n this.#fieldListToggle.textContent = view.fieldList.label;\n this.#fieldListToggle.setAttribute('aria-pressed', view.fieldList.shown ? 'true' : 'false');\n this.#refreshButton.textContent = words.word('refresh');\n if (view.refresh === undefined) this.#refreshButton.remove();\n else if (this.#refreshButton.parentNode === null) this.#fieldListToggle.before(this.#refreshButton);\n const refusal = view.refusal ?? ''; // oxlint-disable-line ex-grid/no-stand-in-default -- no refusal is an empty notice, which takes no room\n if (this.#notice.textContent !== refusal) this.#notice.textContent = refusal;\n this.#notice.hidden = view.refusal === undefined;\n if (this.#notice.parentNode !== this.#report) this.#toolbar.after(this.#notice);\n }\n if (refreshHeld) this.#parts.focus('field-list');\n }\n\n // The report filter band, on the Pivot Toolbar's left (ADR-0061): each field in Filters, its caption, and a button\n // that says what it shows and opens Filter\u2026 under it, over the report. It stands while Filters holds a field, in\n // the toolbar's anchor for it; the built-in markup's or a Chrome's, drawn from the same view.\n #drawBand(): void {\n const words = this.#words;\n const open = this.#open;\n const view = this.#bandSlot.viewOf(Object.freeze({\n name: words.word('report-filters'),\n filters: Object.freeze(this.#layoutAhead.filters.map(placement => {\n const caption = this.#captionOf(placement.field);\n return Object.freeze({\n field: placement.field,\n caption,\n summary: this.#bandSummary(placement),\n filtered: placement.hiddenItems.length > 0,\n open: open?.kind === 'band' && open.field === placement.field,\n buttonLabel: words.fill('filter-of', caption),\n });\n })),\n }));\n const mount = this.#chrome?.reportFilters;\n const shown = mount !== undefined && this.#showStanding(this.#bandSlot, mount, (shared, input, refs) => ({\n ...shared,\n toggle: input((field: string) => { if (this.#layoutAhead.filters.some(placement => placement.field === field)) this.#toggleBand(field); }),\n control: field => refs.control(bandName(checkedField(field))),\n anchor: field => refs.anchor(bandName(checkedField(field))),\n }));\n const band = shown ? this.#bandSlot.element : this.#band;\n if (shown) {\n this.#band.remove();\n for (const field of this.#bandFilters.keys()) this.#forgetBandFilter(field);\n this.#bandSlot.element.setAttribute('aria-label', view.name);\n } else {\n this.#bandSlot.hide();\n this.#bandSlot.element.remove();\n this.#drawBuiltInBand(view);\n }\n if (view.filters.length === 0) {\n band.remove();\n this.#parts.place('report-filters', undefined);\n } else {\n this.#parts.place('report-filters', band);\n }\n }\n\n #drawBuiltInBand(view: PivotReportFiltersView): void {\n const document = this.#root.ownerDocument;\n const drawn: HTMLElement[] = [];\n const kept = new Set<string>();\n for (const shown of view.filters) {\n const { field } = shown;\n let band = this.#bandFilters.get(field);\n if (band === undefined) {\n band = this.#bandFilter(document, field);\n this.#bandFilters.set(field, band);\n }\n this.#parts.handInControl(bandName(field), band.button);\n this.#parts.handInAnchor(bandName(field), band.anchor);\n kept.add(field);\n if (band.caption.textContent !== shown.caption) band.caption.textContent = shown.caption;\n if (band.summary.textContent !== shown.summary) band.summary.textContent = shown.summary;\n band.button.classList.toggle('ex-pivot-filter-active', shown.filtered);\n band.button.setAttribute('aria-expanded', shown.open ? 'true' : 'false');\n band.button.setAttribute('aria-label', shown.buttonLabel);\n drawn.push(band.filter);\n }\n for (const field of this.#bandFilters.keys()) {\n if (!kept.has(field)) this.#forgetBandFilter(field);\n }\n this.#band.setAttribute('aria-label', view.name);\n const children = this.#band.children;\n if (drawn.length !== children.length || drawn.some((filter, i) => children[i] !== filter)) this.#band.replaceChildren(...drawn);\n }\n\n // A built-in report filter that no longer stands: its elements are dropped, and taken back from the parts.\n #forgetBandFilter(field: string): void {\n const band = this.#bandFilters.get(field);\n if (band === undefined) return;\n this.#bandFilters.delete(field);\n this.#parts.forget(bandName(field), band.button);\n this.#parts.forget(bandName(field), band.anchor);\n }\n\n #bandFilter(document: Document, field: string): BandFilter {\n const filter = element(document, 'div', 'ex-pivot-filter');\n const caption = element(document, 'span', 'ex-pivot-filter-caption');\n const anchor = element(document, 'span', 'ex-pivot-filter-anchor');\n const button = element(document, 'button', 'ex-pivot-filter-button');\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.setAttribute('aria-haspopup', 'dialog');\n const summary = element(document, 'span', 'ex-pivot-filter-summary');\n const arrow = element(document, 'span', 'ex-pivot-entry-arrow');\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n button.append(summary, arrow);\n button.addEventListener('click', () => { this.#toggleBand(field); });\n anchor.append(button);\n filter.append(caption, anchor);\n return { filter, caption, anchor, button, summary };\n }\n\n // What a report filter shows, as Excel shows a page field: (All) while it hides nothing, the one Item shown, or\n // (Multiple Items), read from the field's Items, asked of the source; Loading\u2026 until a first listing lands, rather\n // than a guess, and why when they cannot be listed. While a new Source Version's Items are on their way, it is read\n // from the Items in view, the earlier version's (ADR-0066 refined).\n #bandSummary(placement: PivotFieldPlacement): string {\n const words = this.#words;\n if (placement.hiddenItems.length === 0) return words.word('all');\n const items = this.#itemsOf(placement.field);\n if (items.problem !== undefined) return itemsProblemText(items.problem, words);\n const page = items.listed;\n if (page === undefined) return words.word('loading');\n if (page.total > page.items.length) {\n // More Items than are held: provably several shown, or not known.\n return page.total - placement.hiddenItems.length > 1 ? words.word('multiple-items') : words.word('loading');\n }\n // One Item shown is named; past one, how many does not matter.\n const hidden = new Set(placement.hiddenItems.map(key => pivotItemKeyId(key)));\n let shown: PivotItemInfo | undefined;\n for (const item of page.items) {\n if (hidden.has(pivotItemKeyId(item.key))) continue;\n if (shown !== undefined) return words.word('multiple-items');\n shown = item;\n }\n // None shown (data that no longer holds the one Item shown) is said as the Razor component says it.\n return shown === undefined ? words.word('multiple-items') : shown.label;\n }\n\n // What a field's Items are listed under: the report on screen, and the field's order in it. None while no report\n // is shown.\n #itemsUnder(field: string): ItemsUnder | undefined {\n const { answer, question, layout } = this.#shown;\n if (answer === undefined || question === undefined) return undefined;\n const at = placementOf(layout, field);\n return Object.freeze({\n reportSource: question.reportSource,\n version: answer.metadata.version,\n sourceVersion: answer.metadata.sourceVersion,\n settings: question.settings,\n sort: at === undefined ? undefined : elementAt(placementsIn(layout, at.area), at.index).sort,\n });\n }\n\n // A field's Items as they stand for the report on screen; on their way while the first report is.\n #itemsOf(field: string): FieldItems {\n const under = this.#itemsUnder(field);\n return under === undefined ? pendingFirst : this.#items.of(field, under);\n }\n\n // ---- Drawing ---------------------------------------------------------------------------------------\n\n #setFieldListShown(shown: boolean): void {\n if (shown === this.#fieldListShown) return;\n this.#fieldListShown = shown;\n this.#draw();\n this.#options.onShowFieldListChanged?.(Object.freeze({ shown }));\n }\n\n #paintDropRemove(removable: boolean): void {\n // A drag takes the pane: a field menu open in it goes, as the Razor component's does, drawn below.\n this.#takeDown();\n this.#dropRemoveShown = removable;\n this.#draw();\n }\n\n // Whether a question is out under the loading indication: any but the quiet one a source's notice asked.\n #loading(): boolean {\n return this.#asked !== undefined && this.#asked.cause !== 'live';\n }\n\n // The Field List: a Chrome's in the pane's place while one is given and can be drawn, else the built-in pane.\n #placeFieldList(): void {\n const mount = this.#chrome?.fieldList;\n const slotted = mount !== undefined && this.#answered(this.#slottedFieldList.show(mount, id => this.#words.word(id)));\n if (!slotted) this.#slottedFieldList.hide();\n this.#fieldListSlotted = slotted;\n const pane = slotted ? this.#slottedFieldList.element : this.#builtInFieldList.element;\n if (pane.parentNode !== this.#fieldListScroll) this.#fieldListScroll.replaceChildren(pane);\n // A drag whose pane went with its contents ended with them: the report no longer offers to remove its field.\n if (!this.#fieldList.removable) this.#dropRemoveShown = false;\n }\n\n // The Stale Report's notice, and the class by which ExPivot's stylesheet mutes the report's numbers (ADR-0067). Retry\n // is not offered twice at once: while a question a person or the Consumer asked is out, it is the one Retry would\n // ask. A quiet one for the source's notice leaves Retry offered, or a ticking source would hardly ever let it be\n // pressed.\n #drawStale(words: PivotScreenWords): void {\n const stale = this.#stale !== undefined && this.#shown.answer !== undefined ? this.#stale : undefined;\n this.#report.classList.toggle('ex-pivot-report-stale', stale !== undefined);\n // Retry taken away or disabled while it holds the keyboard hands it to the Field List toggle, so the keyboard stays\n // in the pivot, on a button whose press asks nothing of the source.\n const held = this.#parts.holds('retry');\n const handOn = (): void => { if (held) this.#parts.focus('field-list'); };\n const mount = this.#chrome?.staleReport;\n if (stale === undefined) {\n this.#staleNotice.remove();\n this.#staleSlot.hide();\n this.#staleSlot.element.remove();\n handOn();\n return;\n }\n const asOf = this.#asOf();\n const view = this.#staleSlot.viewOf(Object.freeze({\n message: words.fill('stale-report', asOf, stale),\n asOfText: asOf,\n reason: stale,\n retry: Object.freeze({ label: words.word('retry'), enabled: !this.#loading() }),\n }));\n if (mount !== undefined && this.#staleSlot.element.parentNode !== this.#staleRegion) this.#staleRegion.append(this.#staleSlot.element);\n const shown = mount !== undefined && this.#showStanding(this.#staleSlot, mount, (shared, input, refs) => ({\n ...shared,\n // Asked only while Retry is offered: one pressed while what it would ask is out asks nothing twice.\n retry: input(() => { if (shared.view().retry.enabled) this.#retry(); }),\n control: name => refs.control(checkedName(name, ['retry'], 'staleReport')),\n }));\n if (shown) {\n this.#staleNotice.remove();\n } else {\n this.#staleSlot.hide();\n this.#staleSlot.element.remove();\n this.#parts.handInControl('retry', this.#retryButton);\n if (this.#staleMessage.textContent !== view.message) this.#staleMessage.textContent = view.message;\n if (this.#retryButton.textContent !== view.retry.label) this.#retryButton.textContent = view.retry.label;\n this.#retryButton.disabled = !view.retry.enabled;\n if (this.#staleNotice.parentNode !== this.#staleRegion) this.#staleRegion.append(this.#staleNotice);\n }\n if (!view.retry.enabled) handOn();\n }\n\n #draw(): void {\n if (this.#destroyed) return;\n const words = this.#words;\n const layout = this.#paneLayout;\n const fields = this.#options.source.fields;\n // The Value Fields' captions, which the Field List and a Values entry's menu say.\n const valueCaptions = this.#fieldListShown\n ? pivotValueCaptions(layout, fields, { locale: this.#locale, ...(words.label === undefined ? {} : { label: words.label }) })\n : undefined;\n this.#placeFieldList();\n this.#drawMenu(valueCaptions);\n const stretch = this.#options.viewportHeight === 'stretch';\n const width = this.#options.fieldListWidth ?? 300; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0061: the Field List's declared default width, as the Razor component's\n // The Geometry Tokens, inline on the root (ADR-0027): the Field List's width and a level's indent.\n writeStyle(this.#root, `--ex-pivot-field-list-width: ${width}px; --ex-pivot-indent: ${this.#indentPx}px${stretch ? '; height: 100%; flex: 1 1 auto; min-height: 0' : ''}`);\n // A question for the newer data the source told of is asked quietly, so a live report is not busy every interval.\n if (this.#loading()) this.#root.setAttribute('aria-busy', 'true');\n else this.#root.removeAttribute('aria-busy');\n this.#drawStale(words);\n writeStyle(this.#sheet, stretch ? 'display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0' : '');\n const answered = this.#reportDrawn;\n // The report or the box that says why there is none, and over the report, while a placed field is\n // dragged, the mark that a drop there removes it (ADR-0061). Elements come and go rather than hide, since\n // the stylesheet gives the box a display of its own.\n // While a details tab is selected its records cover the report, which stays laid out, with its state, and is\n // not painted: its own header would otherwise paint over the records', and a report nobody sees takes no\n // keyboard and is not read out (ADR-0059). Records covering it take no drop meant for it.\n const details = this.#details;\n const panel = details.panel;\n this.#sheet.className = panel === undefined ? 'ex-pivot-sheet' : 'ex-pivot-sheet ex-pivot-sheet-covered';\n const dropRemove = answered && this.#dropRemoveShown && panel === undefined && !details.dialogShown;\n elementAt([...this.#dropRemove.children], 0).textContent = words.word('remove-field');\n const shownInSheet = [answered ? this.#gridRoot : this.#empty, ...(dropRemove ? [this.#dropRemove] : []), ...(panel === undefined ? [] : [panel])];\n if (shownInSheet.length !== this.#sheet.children.length || shownInSheet.some((child, i) => this.#sheet.children[i] !== child)) {\n this.#sheet.replaceChildren(...shownInSheet);\n }\n // The tabs stand at the report's foot, where Excel's sheet tabs are, while a details tab stands.\n if (!details.tabsShown) details.tabList.remove();\n else if (details.tabList.parentNode !== this.#report) this.#report.append(details.tabList);\n // While the dialog stands, what it covers takes neither the keyboard nor the pointer: it is modal (ADR-0059).\n this.#report.inert = details.dialogShown;\n this.#fieldListBox.inert = details.dialogShown;\n for (const shown of details.dialogElements) {\n if (shown.parentNode !== this.#root) this.#root.append(shown);\n }\n if (!answered) {\n this.#empty.textContent = words.word(this.#asked !== undefined && !showsNothing(this.#layoutAhead) ? 'loading' : 'empty-report');\n const height = this.#options.viewportHeight ?? 400; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report's declared default height, as the Razor component's\n writeStyle(this.#empty, height === 'stretch' ? 'flex: 1 1 auto; min-height: 0' : `height: ${height}px`);\n }\n this.#fieldListBox.hidden = !this.#fieldListShown;\n this.#fieldListBox.setAttribute('aria-label', words.word('field-list'));\n if (valueCaptions !== undefined) {\n this.#fieldList.draw({\n layout,\n fields,\n valueCaptions,\n counts: this.#counts,\n maxLeaves: this.#maxLeaves,\n locale: this.#locale,\n words,\n deferred: this.#deferred !== undefined,\n canUpdate: this.#deferred !== undefined && this.#pendingApplies(this.#deferred.layout),\n popup: this.#open?.kind === 'entry' || this.#open?.kind === 'panel' ? { entry: this.#open.entry, frame: this.#open.popup.element } : undefined,\n });\n }\n const left = this.#keyboardAfterDraw;\n this.#keyboardAfterDraw = undefined;\n if (left !== undefined) this.#returnKeyboard(left, this.#entryNow(left));\n this.#throwRefused();\n }\n\n // Throws the first of the slots' contents that could not be drawn: to the Consumer, where it makes or updates the\n // pivot or opens records; otherwise on its own, as a listener's error is, so the source, the user's input or the\n // timer that drew goes on.\n #throwRefused(): void {\n const [refused] = this.#slotErrors;\n this.#slotErrors = [];\n if (refused === undefined) return;\n if (this.#consumerDraws) throw refused;\n queueMicrotask(() => { throw refused; });\n }\n}\n\n/** Defer Layout Update ticked: the layout the pane shows and builds, and the moves into it the report does not hold. */\ninterface Deferred {\n readonly layout: PivotLayout;\n readonly moves: readonly FieldListMove[];\n}\n\n// The moves a refused question's layout still holds: a field moved and then taken out again is not in it. A field may\n// stand in Values as well as in an axis, so a move is known by its field and its Area.\nfunction heldMoves(question: Question): readonly FieldListMove[] {\n return question.moves.filter((move, i, all) => all.findLastIndex(later => later.field === move.field && later.area === move.area) === i\n && holdsMove(question.layout, move));\n}\n\n// The fields a refusal names: those of the moves its layout still holds, each once.\nfunction heldFields(held: readonly FieldListMove[]): readonly string[] {\n return [...new Set(held.map(move => move.field))];\n}\n\n// How long a Change Highlight lasts under a pivot's options (ADR-0068).\nfunction highlightMsOf(options: PivotViewOptions): number {\n return options.changeHighlightDuration ?? defaultChangeHighlightMs;\n}\n\n// The caps a pivot's options set, each as it applies, so a cap given as its default asks nothing again.\nfunction capsOf(options: PivotViewOptions): string {\n return `${options.maxLeaves ?? defaultMaxLeaves} ${options.maxRows ?? excelRows} ${options.maxColumns ?? excelColumns}`;\n}\n\n// The cap a report breaks, or none (ADR-0066): its rows, or its columns with the label columns, past the question's \u2014\n// with the word that refuses a layout for it and the word that says newer data broke it.\nfunction capBrokenBy(metadata: PivotReportState['metadata'], question: Question): { readonly refusal: string; readonly stale: string; readonly cap: number } | undefined {\n if (metadata.rowCount > question.maxRows) return { refusal: 'refused-too-many-rows', stale: 'stale-too-many-rows', cap: question.maxRows };\n if (metadata.labelColumns.length + metadata.valueColumns.length > question.maxColumns) {\n return { refusal: 'refused-too-many-columns', stale: 'stale-too-many-columns', cap: question.maxColumns };\n }\n return undefined;\n}\n\n// Whether `layout` holds the field a move put in its Area.\nfunction holdsMove(layout: PivotLayout, move: FieldListMove): boolean {\n return move.area === 'values' ? layout.values.some(value => value.field === move.field) : placementOf(layout, move.field)?.area === move.area;\n}\n\n// Whether every field `layout` places is one of `declared`.\nfunction placesOnly(layout: PivotLayout, declared: ReadonlyMap<string, unknown>): boolean {\n return [...layout.filters, ...layout.rows, ...layout.columns, ...layout.values].every(placed => declared.has(placed.field));\n}\n\n// .NET's Math.Round, which sends a tie to the even number (CONVENTIONS.md).\nfunction roundHalfToEven(value: number): number {\n const floor = Math.floor(value);\n const diff = value - floor;\n if (diff < 0.5) return floor;\n if (diff > 0.5) return floor + 1;\n return floor % 2 === 0 ? floor : floor + 1;\n}\n\n// The name a report filter's button and the anchor around it are handed in by.\nfunction bandName(field: string): string {\n return `filter:${field}`;\n}\n\n// A report filter's field, as a script may hand it to the band's `control` or `anchor`: the field's name.\nfunction checkedField(field: string): string {\n const given: unknown = field;\n if (typeof given !== 'string') throw new TypeError('An ExPivot\\'s report filter band hands in a filter\\'s button and anchor by the field\\'s name (ADR-0390).');\n return given;\n}\n", "// Show Details (ADR-0059, ADR-0063): the records behind a value cell, asked of the report source the report came\n// from under its Source Version, so they add up to the cell. The Consumer takes them when it listens; otherwise they\n// open as a sheet, in a tab at the report's foot or in a dialog: an ExGrid of the source's fields, fetched in pages,\n// in the markup and under the classes the Razor component's PivotDetailsSheet and PivotDetailsGrid draw (ADR-0350\n// section 4).\n\nimport { FetchingGridSource, type ColumnType, type GridColumn, type GridPage, type GridQuery } from '@ex-grid/core';\nimport { decimalText } from '@ex-grid/data';\nimport {\n formatPivotDetailValue, pivotDetailsQuery, type PivotDetailPage, type PivotDetailRecord, type PivotDetailValue, type PivotDetailsQuery, type PivotField,\n type PivotSource, type PivotSourceRefusal,\n} from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** One Item of a cell's path: its field's caption and its label, as the report shows them. */\nexport interface PivotDetailItem {\n /** The caption of the Item's field. */\n readonly field: string;\n /** The Item's label. */\n readonly item: string;\n}\n\n/** The records behind a value cell, which Show Details opens (ADR-0059): handed to `onShowDetails` when the Consumer\n * listens, and otherwise shown by the pivot. */\nexport interface PivotShowDetailsEvent {\n /** What the cell stands for, as its sheet is titled: `Details: EU / Rates`. */\n readonly title: string;\n /** The Items of the cell's row, outermost first. */\n readonly rowItems: readonly PivotDetailItem[];\n /** The Items of the cell's column, outermost first. */\n readonly columnItems: readonly PivotDetailItem[];\n /** The caption of the cell's Value Field, or `undefined` where the cell is not one Value Field's. */\n readonly valueField: string | undefined;\n /** The question for the records, plain data a Consumer may send elsewhere, as the Razor component's\n * `PivotDetails.Query` (ADR-0151): the cell's Items, the Hidden Items and the Source Version it is answered under. */\n readonly query: PivotDetailsQuery;\n /** The Pivot Source the report was computed from, which the records are asked of. */\n readonly source: PivotSource;\n /** The source's fields, which each record holds a value of, in order. */\n readonly fields: readonly PivotField[];\n /** A page of the records, from `start`, at most `count` of them, under the Source Version the report was computed\n * from: a source that no longer holds it refuses, rather than answer records that do not add up. */\n readonly records: (start: number, count: number, signal?: AbortSignal) => Promise<PivotDetailPage>;\n}\n\n/** Where the pivot shows the records when the Consumer does not take them: a tab at the report's foot, or a dialog. */\nexport type PivotDetailsView = 'tab' | 'dialog';\n\n/** The records behind `query`'s cell, asked of the Pivot Source the report was computed from, which stays the\n * Consumer's however long the records are shown. */\nexport function detailsEvent(\n source: PivotSource, query: PivotDetailsQuery, described: Omit<PivotShowDetailsEvent, 'source' | 'query' | 'fields' | 'records'>,\n): PivotShowDetailsEvent {\n return Object.freeze({\n ...described,\n source,\n query,\n fields: source.fields,\n // Checked as the question is: a page from a negative or broken start is refused by name, never asked.\n records: (start: number, count: number, signal?: AbortSignal) => source.details(pivotDetailsQuery({ ...query, start, count }), signal),\n });\n}\n\n/** A record's value as the details grid holds it: the text it shows, and its own text, which the grid copies. */\nexport class DetailCellValue {\n readonly #value: PivotDetailValue;\n /** The text the cell shows. */\n readonly text: string;\n\n constructor(value: PivotDetailValue, text: string) {\n this.#value = value;\n this.text = text;\n }\n\n /** What the cell is painted and aligned as: a value not of its field's declared type keeps its own (ADR-0060). */\n get type(): ColumnType {\n const value = this.#value;\n if (typeof value === 'string') return 'text';\n if (typeof value === 'boolean') return 'boolean';\n if (typeof value === 'bigint') return 'date';\n return 'number';\n }\n\n /** The raw text the clipboard carries: an exact number's digits, a double's shortest text, and otherwise what\n * the cell shows (ADR-0005). */\n toString(): string {\n const value = this.#value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'object' && value !== null) return decimalText(value);\n return this.text;\n }\n}\n\n/** Why the records cannot be shown: the source refused (the data changed under the report's Source Version, for\n * one), or it failed. */\nexport type DetailsProblem = { readonly refusal: PivotSourceRefusal } | { readonly error: unknown };\n\n/** The sentence that says why the records cannot be shown. */\nexport function detailsProblemText(problem: DetailsProblem, words: PivotScreenWords): string {\n return 'error' in problem ? words.failed(problem.error) : words.sourceRefused(problem.refusal);\n}\n\nclass RefusedError extends Error {\n readonly refusal: PivotSourceRefusal;\n\n constructor(refusal: PivotSourceRefusal) {\n super(refusal.message);\n this.refusal = refusal;\n }\n}\n\nfunction columnTypeOf(field: PivotField): ColumnType {\n switch (field.type) {\n case 'number': return 'number';\n case 'date': return 'date';\n case 'boolean': return 'boolean';\n case 'text': return 'text';\n default: return unreachable(field.type);\n }\n}\n\nfunction cellOf(value: unknown): DetailCellValue | undefined {\n if (value === undefined) return undefined;\n if (!(value instanceof DetailCellValue)) throw new TypeError('Internal: a details cell holds a record\\'s value.');\n return value;\n}\n\n/** What a details cell is painted and aligned as: its value's own type, or its column's for a Blank. */\nexport function detailCellType(row: PivotDetailRecord, column: GridColumn<PivotDetailRecord>): ColumnType {\n // A Blank is painted as its column's type, as the Razor component's CellTypeOf does.\n return cellOf(column.value(row))?.type ?? column.type;\n}\n\n/**\n * One Show Details the pivot opened: the cell's records as a Grid Source of pages fetched from the report source,\n * under the Source Version the report was computed from, and one column per field of the source, headed by its\n * caption. It keeps that version for as long as it stands; a source that can no longer answer under it refuses, and\n * the sheet says the data has changed rather than show records that do not add up. It owns its source and releases\n * it when it closes.\n */\nexport class DetailsSheet {\n /** Unique in its pivot: its tab's id, and its panel's with `-panel`. */\n readonly id: string;\n readonly details: PivotShowDetailsEvent;\n /** The locale its records are written in: the pivot's when it opened, as its title's words are. */\n readonly locale: string;\n readonly columns: readonly GridColumn<PivotDetailRecord>[];\n readonly source: FetchingGridSource<PivotDetailRecord>;\n /** Why the records cannot be shown, or `undefined` while they can. */\n problem: DetailsProblem | undefined;\n readonly #closed = new AbortController();\n\n /** `changed` is called when the records can no longer be shown. */\n constructor(id: string, details: PivotShowDetailsEvent, locale: string, changed: () => void) {\n this.id = id;\n this.details = details;\n this.locale = locale;\n this.columns = Object.freeze(details.fields.map((field, index) => {\n const values = new WeakMap<PivotDetailRecord, DetailCellValue | undefined>();\n return Object.freeze({\n name: field.name,\n header: field.caption,\n type: columnTypeOf(field),\n queryable: false,\n value: (record: PivotDetailRecord) => {\n if (values.has(record)) return values.get(record);\n const value = record.values[index];\n const cell = value === undefined || value === null ? undefined : new DetailCellValue(value, formatPivotDetailValue(value, field.format, locale));\n values.set(record, cell);\n return cell;\n },\n format: (value: unknown) => cellOf(value)?.text ?? '', // oxlint-disable-line ex-grid/no-stand-in-default -- a Blank shows nothing\n });\n }));\n this.source = FetchingGridSource.fetch((query, signal) => this.#fetch(query, signal), {\n onFetchFailed: ({ error }) => {\n if (this.#closed.signal.aborted) return;\n this.problem = error instanceof RefusedError ? Object.freeze({ refusal: error.refusal }) : Object.freeze({ error });\n changed();\n },\n });\n }\n\n async #fetch(query: GridQuery, signal: AbortSignal): Promise<GridPage<PivotDetailRecord>> {\n // The records behind a cell are in the data's order, and none is left out: the details grid offers no sort\n // and no filter, and a question carrying one is not answered quietly in another order (ADR-0059).\n if (query.sorts.length > 0 || query.filter !== undefined) throw new Error('The records behind a cell are shown in the data\\'s order, unfiltered (ADR-0059).');\n const page = await this.details.records(query.range.start, query.range.count, signal);\n if (page.refusal !== undefined) throw new RefusedError(page.refusal);\n return Object.freeze({ rows: page.records, start: page.start, totalCount: page.total });\n }\n\n /** Releases its source: the sheet has closed. */\n dispose(): void {\n this.#closed.abort();\n this.source.dispose();\n }\n}\n", "// The Snapshot's Decimal (ADR-0064): C#'s decimal, a whole number of at most 96 bits and 0 to 28 decimal\n// places, held as its value and not as the places it was written with, so 1.5 and 1.50 are one value. The\n// shape is the Script Core's ExactDecimal's, so a value passes between the two packages as it is.\n\n/** A Decimal value, `mantissa` \u00D7 10^-`scale`: a whole number below 2^96 in magnitude, and 0 to 28 places.\n * A value a Snapshot hands out is canonical: no trailing zero after the point, and 0 is `0n` at scale 0. */\nexport interface SnapshotDecimal {\n /** The digits, as a whole number. */\n readonly mantissa: bigint;\n /** How many of them stand after the point, 0 to 28. */\n readonly scale: number;\n}\n\n/** The magnitude a Decimal's digits stay below: 2^96. */\nexport const decimalLimit = 1n << 96n;\n\n/** The most places a Decimal holds. */\nexport const maxDecimalScale = 28;\n\n/** The canonical Decimal \u00B1 `magnitude` \u00D7 10^-`scale` is, its trailing zeros taken off, frozen. The caller\n * has checked it is a Decimal. */\nexport function canonicalDecimal(mantissa: bigint, scale: number): SnapshotDecimal {\n let digits = mantissa;\n let places = scale;\n while (places > 0 && digits % 10n === 0n) {\n digits /= 10n;\n places -= 1;\n }\n return Object.freeze({ mantissa: digits, scale: digits === 0n ? 0 : places });\n}\n\n/** Whether `value` is a Decimal a Snapshot holds: a bigint below 2^96 in magnitude and a whole scale from\n * 0 to 28. A value of any other shape, which only an untyped caller can pass, is not one. */\nexport function isSnapshotDecimal(value: unknown): value is SnapshotDecimal {\n if (typeof value !== 'object' || value === null) return false;\n const mantissa: unknown = Reflect.get(value, 'mantissa');\n const scale: unknown = Reflect.get(value, 'scale');\n return typeof mantissa === 'bigint' && mantissa < decimalLimit && mantissa > -decimalLimit\n && typeof scale === 'number' && Number.isInteger(scale) && scale >= 0 && scale <= maxDecimalScale;\n}\n\n/**\n * The Decimal a text writes: an optional `-`, digits, and optionally a point and more digits, as\n * `\"-1234.5678\"`. Refused with a `TypeError` when the text is not one, and with a `RangeError` when no\n * Decimal holds it exactly: more than 28 places that are not trailing zeros, or digits past 2^96.\n */\nexport function decimalFromText(text: string): SnapshotDecimal {\n const match = /^(-?)(\\d+)(?:\\.(\\d+))?$/.exec(text);\n if (match === null) throw new TypeError(`'${text}' is not a decimal: a decimal is written as -1234.5678.`);\n // The point and the places after it are optional: a whole number has none.\n const [, sign = '', whole = '', fraction = ''] = match;\n const places = fraction.replace(/0+$/, '');\n if (places.length > maxDecimalScale) throw new RangeError(`'${text}' has more decimal places than the 28 a decimal holds.`);\n const magnitude = BigInt(whole + places);\n if (magnitude >= decimalLimit) throw new RangeError(`'${text}' lies beyond the range of a decimal.`);\n return canonicalDecimal(sign === '-' ? -magnitude : magnitude, places.length);\n}\n\n/** A Decimal's text, canonical: `-0.0001`, `1.5`, `79228162514264337593543950335`. */\nexport function decimalText(value: SnapshotDecimal): string {\n return unscaledText(value.mantissa.toString(), value.scale);\n}\n\n/** An unscaled whole number's digits with the point put in at `places`, which may be negative, as a\n * refusal shows a value read at its Arrow scale (`0.000\u2026015`, `999\u2026000`). */\nexport function unscaledText(unscaled: string, places: number): string {\n const negative = unscaled.startsWith('-');\n let digits = negative ? unscaled.slice(1) : unscaled;\n if (places > 0) {\n digits = digits.padStart(places + 1, '0');\n digits = `${digits.slice(0, -places)}.${digits.slice(-places)}`;\n } else if (places < 0) {\n digits += '0'.repeat(-places);\n }\n return negative ? `-${digits}` : digits;\n}\n", "// What the pivot's Script Core knows is there, as core/src/must.ts says it for ExGrid's: a miss is a defect,\n// said by throwing where a `!` would read on with `undefined` (CONVENTIONS.md, \"No quiet fallback\"). The\n// packages share no code, so each carries its own.\n\n/** The element at `index`, which the caller knows is there. A miss throws: it is a defect, never an answer. */\nexport function elementAt<T extends object | string | number | boolean | bigint | null>(list: readonly T[], index: number): T {\n const value = list[index];\n if (value === undefined) {\n throw new Error(`Internal: index ${index} is outside a list of ${list.length}.`);\n }\n return value;\n}\n\n/** The value, which the caller knows is there. `undefined` throws, naming what was missing. */\nexport function defined<T>(value: T | undefined, what: string): T {\n if (value === undefined) {\n throw new Error(`Internal: ${what} is missing.`);\n }\n return value;\n}\n\n/** The end of a switch that has taken every member of a union; a value from outside it throws here. */\nexport function unreachable(value: never): never {\n throw new Error(`Internal: ${String(value)} is not a value this switch takes.`);\n}\n", "// The controls and the anchors of the pivot's standing parts (ADR-0061, ADR-0390): the Pivot Toolbar's buttons, a\n// report filter's, Retry. The built-in markup and a Chrome's contents hand them in alike, each by its name, so the\n// pivot gives the keyboard to the control it means and places a popup's frame in the anchor it belongs in, the same\n// way whichever drew them. A part's contents are drawn by their framework when it gets to them: a control asked for\n// before it is handed in takes the keyboard once it is, unless the keyboard has moved on meanwhile.\n\nimport type { PivotPartRef } from './chrome';\n\n/** Whether DOM focus is inside `pivot`, or on nothing: the keyboard is still the pivot's (ADR-0204). */\nexport function keyboardIsThePivots(pivot: Element): boolean {\n const document = pivot.ownerDocument;\n const active = document.activeElement;\n return active === null || active === document.body || active === document.documentElement || pivot.contains(active);\n}\n\n/** The elements the pivot's standing parts handed in, by name. */\nexport class PartElements {\n readonly #root: HTMLElement;\n readonly #controls = new Map<string, HTMLElement>();\n readonly #anchors = new Map<string, HTMLElement>();\n // What each anchor is to hold: a popup's frame, or the report filter band, placed once the anchor is handed in.\n readonly #placed = new Map<string, HTMLElement>();\n // What hears an element placed land in its anchor, the first time it does.\n readonly #landing = new Map<HTMLElement, () => void>();\n // The control the keyboard is owed to, given once it is handed in; any focus moving or press meanwhile ends it,\n // since a press on nothing focusable moves the keyboard to the page without a focus event. A key does not: one\n // that moves the keyboard moves focus, and one typed while the control is on its way is held in the pivot's Input\n // Order on an adapter that holds (ADR-0410 section 5), to be taken where the control stands once it does.\n // The document is heard only while something is owed, and its listeners answer only that (ADR-0350 section 6's\n // note of 2026-11-01): a pivot owing nothing listens to nothing outside itself.\n #owed: string | undefined;\n #listening: AbortController | undefined;\n\n constructor(root: HTMLElement) {\n this.#root = root;\n }\n\n /** The pivot is gone: nothing is heard, and nothing owed is given. */\n dispose(): void {\n this.#settle();\n }\n\n // The keyboard is owed to `name` until it is given, or focus moves or a press lands anywhere meanwhile.\n #owe(name: string): void {\n this.#owed = name;\n if (this.#listening !== undefined) return;\n this.#listening = new AbortController();\n const settled = (): void => { this.#settle(); };\n for (const type of ['focusin', 'pointerdown']) {\n this.#root.ownerDocument.addEventListener(type, settled, { capture: true, signal: this.#listening.signal });\n }\n }\n\n // Nothing is owed any longer, and the document is no longer heard.\n #settle(): void {\n this.#owed = undefined;\n this.#listening?.abort();\n this.#listening = undefined;\n }\n\n /** The refs by which one mount of a Chrome's contents hands in its controls and anchors: the same function for a\n * name each time it is asked, and each taking back only what it handed in, so contents taken away late take nothing\n * the contents after them handed in under the same name. */\n refs(): PartRefs {\n const controls = new Map<string, PivotPartRef>();\n const anchors = new Map<string, PivotPartRef>();\n return {\n control: name => cachedRef(controls, name, () => elementRef(this.#controls, name, `An ExPivot part's '${name}'`, element => { this.#giveOwed(name, element); })),\n anchor: name => cachedRef(anchors, name, () => elementRef(this.#anchors, name, `An ExPivot part's '${name}'`, element => { this.#fill(name, element); })),\n };\n }\n\n /** The built-in markup's control named `name`, handed in as it stands: no Chrome's ref is involved, so a Chrome's\n * contents taken away later take nothing of it. */\n handInControl(name: string, element: HTMLElement): void {\n this.#controls.set(name, element);\n this.#giveOwed(name, element);\n }\n\n /** The built-in markup's anchor named `name`, handed in as it stands. */\n handInAnchor(name: string, element: HTMLElement): void {\n this.#anchors.set(name, element);\n this.#fill(name, element);\n }\n\n /** Takes back what was handed in as `name`, where it is still `element`: built-in markup that no longer stands. */\n forget(name: string, element: HTMLElement): void {\n if (this.#controls.get(name) === element) this.#controls.delete(name);\n if (this.#anchors.get(name) === element) this.#anchors.delete(name);\n }\n\n /** The anchor named `name` went with what held it: nothing is placed in it any longer, though its framework lets\n * go of it only later. */\n dropAnchor(name: string): void {\n this.#anchors.delete(name);\n }\n\n /** Whether an anchor named `name` stands: a popup opens only in one that does. */\n anchored(name: string): boolean {\n return this.#anchors.get(name)?.isConnected === true;\n }\n\n /** Whether the control named `name` is `node` or holds it. */\n controlContains(name: string, node: Node): boolean {\n return this.#controls.get(name)?.contains(node) === true;\n }\n\n /** Whether the control named `name` holds the keyboard. */\n holds(name: string): boolean {\n const control = this.#controls.get(name);\n const active = this.#root.ownerDocument.activeElement;\n return control !== undefined && active !== null && control.contains(active);\n }\n\n /** Gives the keyboard to the control named `name`; one not drawn yet takes it once it is, while the keyboard is\n * still the pivot's and nothing else took it meanwhile. */\n focus(name: string): void {\n const control = this.#controls.get(name);\n if (control?.isConnected === true) {\n this.#settle();\n control.focus();\n } else {\n this.#owe(name);\n }\n }\n\n /** Places `element` in the anchor named `name`, now or once it is handed in; `undefined` places nothing there any\n * longer, as the pivot takes what it placed away itself. `landed` hears the first time `element` stands in an\n * anchor. */\n place(name: string, element: HTMLElement | undefined, landed?: () => void): void {\n if (element === undefined) {\n const placed = this.#placed.get(name);\n if (placed !== undefined) this.#landing.delete(placed);\n this.#placed.delete(name);\n return;\n }\n this.#placed.set(name, element);\n if (landed !== undefined) this.#landing.set(element, landed);\n const anchor = this.#anchors.get(name);\n if (anchor !== undefined) this.#fill(name, anchor);\n }\n\n /** `element` is placed nowhere any longer: the pivot took it away. */\n unplace(element: HTMLElement): void {\n for (const [name, placed] of this.#placed) {\n if (placed === element) this.#placed.delete(name);\n }\n this.#landing.delete(element);\n }\n\n #fill(name: string, anchor: HTMLElement): void {\n const placed = this.#placed.get(name);\n if (placed === undefined || placed.parentNode === anchor) return;\n anchor.append(placed);\n const landed = this.#landing.get(placed);\n this.#landing.delete(placed);\n landed?.();\n }\n\n // The keyboard owed to `name`, given to `element` once it is in the page: a framework hands an element in once it\n // is drawn, plain script often just before.\n #giveOwed(name: string, element: HTMLElement): void {\n if (this.#owed !== name) return;\n const give = (): void => {\n if (this.#owed !== name || !element.isConnected || this.#controls.get(name) !== element) return;\n this.#settle();\n if (keyboardIsThePivots(this.#root)) element.focus();\n };\n if (element.isConnected) give();\n else queueMicrotask(give);\n }\n}\n\n/** One mount's refs, by name. */\nexport interface PartRefs {\n /** The ref for the control named `name`. */\n readonly control: (name: string) => PivotPartRef;\n /** The ref for the anchor named `name`. */\n readonly anchor: (name: string) => PivotPartRef;\n}\n\n/** The ref `refs` holds for `key`, made by `make` the first time it is asked, so a framework handed it again on each\n * render does not hand the element in again. */\nexport function cachedRef<Key>(refs: Map<Key, PivotPartRef>, key: Key, make: () => PivotPartRef): PivotPartRef {\n let ref = refs.get(key);\n if (ref === undefined) {\n ref = make();\n refs.set(key, ref);\n }\n return ref;\n}\n\n/** A ref handing in the element `elements` holds as `key`, which `what` names when anything else is handed in: an\n * element handed in replaces the one before, and `null` takes away only the element this ref handed in, since a\n * framework may hand in the next before it takes back the last, and the built-in markup may stand in its place by\n * then. `handedIn` hears each element handed in. */\nexport function elementRef<Key>(elements: Map<Key, HTMLElement>, key: Key, what: string, handedIn?: (element: HTMLElement) => void): PivotPartRef {\n let current: HTMLElement | undefined;\n return element => {\n if (element === null) {\n if (current !== undefined && elements.get(key) === current) elements.delete(key);\n current = undefined;\n return;\n }\n if (!(element instanceof HTMLElement)) throw new TypeError(`${what} is handed in as an element, or null once it is gone (ADR-0390).`);\n current = element;\n elements.set(key, element);\n handedIn?.(element);\n };\n}\n\n/** `name`, checked as a script may hand it to a part's `control` or `anchor`: one of `names`, which `slot` hands in. */\nexport function checkedName<Name extends string>(name: Name, names: readonly Name[], slot: string): Name {\n if (!names.includes(name)) throw new RangeError(`An ExPivot's ${slot} hands in ${names.join(', ')}, not '${name}' (ADR-0390).`);\n return name;\n}\n\n/** `standing` in the place of `leaving`, where that stands. */\nexport function swap(leaving: HTMLElement, standing: HTMLElement): void {\n if (leaving.parentNode !== null) leaving.replaceWith(standing);\n}\n", "// ExPivot's Chrome slots (ADR-0061, ADR-0390 section 3): the parts of the pivot a Wrapper draws in place of the\n// built-in markup, as the C# `IPivotChrome` lets a Chrome do. The pivot makes the slot, an element inside the frame\n// it places, and hands it to the slot's mount function with what the part shows and the callbacks it answers\n// through. What the part means is the pivot's: the commands and their order, which are enabled, what a draft holds\n// and what OK makes of it, where the frame stands and what closes it. The contents only draw, and call back. A slot\n// left unfilled is drawn by the built-in markup.\n//\n// A context is handed whole at each mount, as the grid's are (ADR-0390): what the part shows is its `view`, read\n// again at each change its `subscribe` tells, and a request for the keyboard mounts the contents again with the next\n// `focusRequest`, on the same slot, so a framework that keys its rendering by the slot keeps its component and that\n// component's state across the two. Once the part goes, nothing the contents call back reaches the pivot.\n\nimport type { GridChrome } from '@ex-grid/core';\nimport type { PivotAggregation, PivotArea, PivotEntry, PivotItemKey, PivotShowValuesAs } from '@ex-grid/pivot-engine';\nimport { keyboardIsThePivots } from './parts';\n\n/**\n * A Chrome slot's mount function (ADR-0350 section 9): it draws the part into `slot`, the element the pivot made for\n * it, from `context`, and answers the function that takes what it drew away. The pivot calls that cleanup before the\n * slot goes, and before it mounts again on the same slot with a new context.\n */\nexport type PivotChromeSlot<Context> = (slot: HTMLElement, context: Context) => () => void;\n\n/** One command of a menu the pivot decides (ADR-0061): what it is called, whether it is available, and what it does. */\nexport interface PivotMenuCommand {\n /** The command's id, which is also the id of its word, stable for an icon. */\n readonly id: string;\n /** What it is called, in the pivot's words. */\n readonly label: string;\n /** Whether it can be pressed: one that would change nothing is disabled. */\n readonly enabled: boolean;\n /** For a choice among others, the Layout menu's, whether it is the current one, which the menu marks; absent on a\n * plain command. */\n readonly checked?: boolean;\n /** The heading of the group of choices that starts at this command: the Layout menu's Subtotals, Grand Totals and\n * Report Layout; absent where it continues the group above. */\n readonly heading?: string;\n /** Runs it and closes the menu, or opens the panel it names in the menu's place. A disabled command runs nothing,\n * and so does one pressed once the menu has closed or been drawn again without it. */\n readonly invoke: () => void;\n}\n\n/** What a menu shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotMenuView {\n /** The menu's accessible name, which its frame carries. */\n readonly name: string;\n /** Excel's commands, in its order. */\n readonly commands: readonly PivotMenuCommand[];\n}\n\n/** What the slots of a part that takes the keyboard share: their words, and the keyboard's requests. */\nexport interface PivotPartSlotContext {\n /** One of the pivot's words by its id: the Consumer's `label`, else the built-in English. */\n readonly label: (id: string) => string;\n /** The count of the pivot's requests for the part to take the keyboard; zero asks nothing. Each request mounts the\n * contents again, and whenever the count differs from the one they last answered they give DOM focus, through\n * `takeFocus`, to the control the part's context names. */\n readonly focusRequest: number;\n /** Gives `control` DOM focus: wherever DOM focus stands while a request is owed, until the contents answer it or\n * the user makes an input in the part, and otherwise only while the keyboard is still the pivot's (ADR-0204). */\n readonly takeFocus: (control: HTMLElement) => void;\n}\n\n/**\n * What a menu's contents are handed (ADR-0061): a placed field's menu, under its entry in the Field List, or the\n * Layout menu, under Layout \u25BE. The slot stands inside the pivot's frame (`role=\"menu\"`, named by the pivot), which\n * Escape anywhere in it closes. The contents draw one item per command, in this order, a choice as a\n * `menuitemradio` marked while it is the current one and a group's heading where one starts. A request for the\n * keyboard is for the first enabled command; with none enabled the pivot gives the frame the keyboard itself.\n */\nexport interface PivotMenuSlotContext extends PivotPartSlotContext {\n /** What the menu shows now. */\n readonly view: () => PivotMenuView;\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** Closes the menu without running anything, for a dismissal of the contents' own; the keyboard goes back to what\n * opened it. */\n readonly close: () => void;\n}\n\n/** What the slots of a panel share (ADR-0061): its exits, and a popup of the contents' own. A panel holds a draft the\n * pivot keeps; OK says it as the next layout, and Cancel and Escape drop it. */\nexport interface PivotPanelSlotContext extends PivotPartSlotContext {\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** OK: the draft is applied and the panel closes. While the view says it cannot be, or the pivot refuses it, the\n * panel stands and says why. */\n readonly apply: () => void;\n /** Cancel: the draft is dropped, the panel closes, and the keyboard goes back to what opened it. */\n readonly cancel: () => void;\n /** The contents report a popup of their own (a select's list) opening (`true`) and closing (`false`): while one\n * is open, Escape is the popup's, and the next closes the panel (ADR-0039). */\n readonly innerPopupChanged: (open: boolean) => void;\n}\n\n/** What Field Settings\u2026 shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotFieldSettingsView {\n /** The field's caption, the panel's title. */\n readonly caption: string;\n /** The draft's subtotals: Automatic (`true`) or None. */\n readonly subtotals: boolean;\n /** The orders there are, each by its words: A to Z and Z to A by label, then each Value Field's two. */\n readonly sorts: readonly string[];\n /** The draft's order, by its index in `sorts`. */\n readonly sort: number;\n}\n\n/** What Field Settings\u2026' contents are handed (ADR-0061): a row or column field's subtotals and order. A request for\n * the keyboard is for the first control, the subtotals' choice. */\nexport interface PivotFieldSettingsSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotFieldSettingsView;\n /** Sets the draft's subtotals. */\n readonly setSubtotals: (automatic: boolean) => void;\n /** Sets the draft's order, by its index in the view's `sorts`. */\n readonly setSort: (index: number) => void;\n}\n\n/** A choice a panel offers: its value, its words, and whether it may be chosen. */\nexport interface PivotChoice<T> {\n /** The choice. */\n readonly value: T;\n /** What it is called. */\n readonly label: string;\n /** Whether it may be chosen: an Aggregation the Pivot Source does not answer is offered, and not available\n * (ADR-0066). */\n readonly enabled: boolean;\n /** Why it may not be chosen, in words; absent while it may. */\n readonly reason?: string;\n}\n\n/** What Value Field Settings\u2026 shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotValueFieldSettingsView {\n /** The Pivot Field's caption, the Source Name. */\n readonly sourceCaption: string;\n /** The draft's caption, as its field shows it: one the user has not written follows the Aggregation. */\n readonly caption: string;\n /** The draft's Aggregation. */\n readonly aggregation: PivotAggregation;\n /** Every Aggregation, with its name and whether the source answers it. */\n readonly aggregations: readonly PivotChoice<PivotAggregation>[];\n /** The draft's Show Values As. */\n readonly showValuesAs: PivotShowValuesAs;\n /** Every Show Values As, with its name. */\n readonly showValuesAsChoices: readonly PivotChoice<PivotShowValuesAs>[];\n /** The draft's number format, as typed; empty for General. */\n readonly numberFormat: string;\n /** What an empty number format means, the field's placeholder: General. */\n readonly numberFormatPlaceholder: string;\n /** A number shown in the draft's format, or the reason it cannot be. */\n readonly sample: string;\n /** Why OK last refused, in words: a caption taken or empty, a format that cannot be used; absent otherwise. */\n readonly refusal?: string;\n}\n\n/** What Value Field Settings\u2026' contents are handed (ADR-0061). A request for the keyboard is for the first control,\n * the caption's field. */\nexport interface PivotValueFieldSettingsSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotValueFieldSettingsView;\n /** The caption as typed. */\n readonly setCaption: (text: string) => void;\n /** Sets the draft's Aggregation: one the source does not answer is never chosen. */\n readonly setAggregation: (aggregation: PivotAggregation) => void;\n /** Sets the draft's Show Values As. */\n readonly setShowValuesAs: (showValuesAs: PivotShowValuesAs) => void;\n /** The number format as typed. */\n readonly setNumberFormat: (text: string) => void;\n}\n\n/** One Item as Filter\u2026 lists it. */\nexport interface PivotItemChoice {\n /** The Item. */\n readonly key: PivotItemKey;\n /** Its label. */\n readonly label: string;\n /** Whether it is shown in the draft. */\n readonly ticked: boolean;\n}\n\n/** What Filter\u2026 shows now (ADR-0061, ADR-0066): a new object at each change, and the same one otherwise. */\nexport interface PivotItemFilterView {\n /** The field's caption, which names the list. */\n readonly caption: string;\n /** The search as typed. */\n readonly search: string;\n /** The Items the search leaves, in the field's order, at most the most Filter\u2026 lists. */\n readonly items: readonly PivotItemChoice[];\n /** (Select All)'s state over `items`: `true` for every one, `false` for none (and over no Items), or `undefined` for\n * some. */\n readonly allTicked: boolean | undefined;\n /** Whether the Items, or the source's answer to the search, are on their way, with nothing yet to list. */\n readonly loading: boolean;\n /** Whether newer Items are on their way while what is shown stands: an earlier Source Version's Items, kept in\n * view (ADR-0066 refined), or why they could not be listed, while they are asked again. A Chrome may mark the list\n * as updating; it does not blank it, nor dim it. */\n readonly updating: boolean;\n /** Why the Items cannot be listed, in words, said in place of the list; absent while they can. */\n readonly unavailable?: string;\n /** A note under the Items: that more match than are listed, or that none matches the search; absent otherwise. */\n readonly note?: string;\n /** Whether OK may be pressed: not while every Item is unticked, nor while the Items are on their way. */\n readonly canApply: boolean;\n /** Why OK cannot apply, in words; absent while it can. */\n readonly refusal?: string;\n}\n\n/** What Filter\u2026' contents are handed (ADR-0061, ADR-0066): a field's Items, each ticked while shown, a search that\n * narrows them, and OK and Cancel. A request for the keyboard is for the search. */\nexport interface PivotItemFilterSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotItemFilterView;\n /** The search as typed. */\n readonly setSearch: (text: string) => void;\n /** Ticks or unticks one Item. */\n readonly setTicked: (key: PivotItemKey, ticked: boolean) => void;\n /** (Select All): ticks or unticks every Item the search lists. */\n readonly setAll: (ticked: boolean) => void;\n}\n\n/** Takes one of a standing part's elements, or `null` once it is gone, as a callback ref does: hand it the element\n * itself (a React `ref`, or a call with the element once it is drawn). */\nexport type PivotPartRef = (element: HTMLElement | null) => void;\n\n/** What the slots of the pivot's standing parts share (ADR-0390): the Pivot Toolbar, the report filter band and the\n * Stale Report's notice. Their contents are mounted once while the part stands, and draw its view again at each change.\n * They hand in their controls by name, through `control`, so the pivot gives the keyboard to the one it means, as it\n * does with the built-in markup's: after a menu closes, to the button that opened it. They hand in the anchors the\n * pivot places a popup's frame in, through `anchor`: an element around the button that opens it, positioned, so the\n * frame needs no position the pivot would have to measure (ADR-0061). */\nexport interface PivotStandingSlotContext<View> {\n /** What the part shows now: a new object at each change, and the same one otherwise. */\n readonly view: () => View;\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** One of the pivot's words by its id: the Consumer's `label`, else the built-in English. */\n readonly label: (id: string) => string;\n}\n\n/** What the Pivot Toolbar shows now (ADR-0061). */\nexport interface PivotToolbarView {\n /** Layout \u25BE: its words, and whether its menu is open. */\n readonly layoutMenu: { readonly label: string; readonly open: boolean };\n /** Refresh, while the source can be refreshed (ADR-0066); absent otherwise, and then there is no button. */\n readonly refresh?: { readonly label: string };\n /** The Field List's toggle: its words, and whether the list is shown. */\n readonly fieldList: { readonly label: string; readonly shown: boolean };\n /** Whether the report filter band stands, on the toolbar's left: the contents then hand in its anchor,\n * `anchor('report-filters')`, in which the pivot places the band. */\n readonly reportFilters: boolean;\n /** What the report could not do with the last change, in words \u2014 a layout refused by name, or the source's\n * failure \u2014 said where the user sees it, as an alert (`role=\"alert\"`); absent otherwise. Data that could not be\n * shown is the Stale Report's notice's to say, not this. */\n readonly refusal?: string;\n}\n\n/**\n * What the Pivot Toolbar's contents are handed (ADR-0061): the report filter band on its left, and on its right, in\n * this order, Layout \u25BE, Refresh where the source can be refreshed, and the Field List's toggle. The Layout menu opens\n * in the anchor around Layout \u25BE, over the report, with a backdrop that closes it.\n */\nexport interface PivotToolbarSlotContext extends PivotStandingSlotContext<PivotToolbarView> {\n /** Layout \u25BE pressed: opens the Layout menu, or closes it when it is open. */\n readonly toggleLayoutMenu: () => void;\n /** Refresh pressed: asks the source again. */\n readonly refresh: () => void;\n /** The Field List's toggle pressed: shows the list, or hides it. */\n readonly toggleFieldList: () => void;\n /** Hands in a button: `layout`, `refresh` or `field-list`. */\n readonly control: (name: 'layout' | 'refresh' | 'field-list') => PivotPartRef;\n /** Hands in an anchor: `layout`, around Layout \u25BE, and `report-filters`, where the band stands. */\n readonly anchor: (name: 'layout' | 'report-filters') => PivotPartRef;\n}\n\n/** One report filter (ADR-0061). */\nexport interface PivotReportFilterView {\n /** The field's name. */\n readonly field: string;\n /** Its caption. */\n readonly caption: string;\n /** What it shows: (All), the one Item shown, or (Multiple Items). */\n readonly summary: string;\n /** Whether it hides Items. */\n readonly filtered: boolean;\n /** Whether its Filter\u2026 is open. */\n readonly open: boolean;\n /** The button's accessible name: \"Filter Region\". */\n readonly buttonLabel: string;\n}\n\n/** What the report filter band shows now (ADR-0061). */\nexport interface PivotReportFiltersView {\n /** The band's accessible name, which a `role=\"group\"` around it carries. */\n readonly name: string;\n /** One per field in Filters, in their order. */\n readonly filters: readonly PivotReportFilterView[];\n}\n\n/** What the report filter band's contents are handed (ADR-0061): one entry per field in Filters, its caption and a\n * button that says what it shows and opens Filter\u2026 in the anchor around it, over the report. */\nexport interface PivotReportFiltersSlotContext extends PivotStandingSlotContext<PivotReportFiltersView> {\n /** A filter's button pressed: opens its Filter\u2026, or closes it when it is open. */\n readonly toggle: (field: string) => void;\n /** Hands in the button of the filter of `field`. */\n readonly control: (field: string) => PivotPartRef;\n /** Hands in the anchor around the button of the filter of `field`. */\n readonly anchor: (field: string) => PivotPartRef;\n}\n\n/** What the Stale Report's notice shows now (ADR-0067). */\nexport interface PivotStaleReportView {\n /** The whole sentence: \"Showing the data as of 14:32:05: the newest data needs more than 200,000 cells.\" */\n readonly message: string;\n /** When the data on screen arrived, as the sentence writes it. */\n readonly asOfText: string;\n /** What happened, as the sentence ends it. */\n readonly reason: string;\n /** Retry: its words, and whether it can be pressed \u2014 not while what it would ask is already out. */\n readonly retry: { readonly label: string; readonly enabled: boolean };\n}\n\n/** What the Stale Report's notice's contents are handed (ADR-0067), inside the pivot's polite live region under the\n * Pivot Toolbar, while the report is stale; the contents add no live region of their own. */\nexport interface PivotStaleReportSlotContext extends PivotStandingSlotContext<PivotStaleReportView> {\n /** Retry pressed: asks again what failed. */\n readonly retry: () => void;\n /** Hands in Retry. */\n readonly control: (name: 'retry') => PivotPartRef;\n}\n\n/** A declared field in the Field List (ADR-0061). */\nexport interface PivotFieldListFieldView {\n /** The field's name. */\n readonly name: string;\n /** What it is called. */\n readonly caption: string;\n /** The name its tick box is handed in by, through `control`. */\n readonly key: string;\n /** Whether it stands in any Area: its tick box. */\n readonly placed: boolean;\n /** Whether it hides Items now. */\n readonly filtered: boolean;\n /** Its count of Items, written in the pivot's locale, where the source counted them; absent otherwise. */\n readonly count?: string;\n /** The count as said: \"12 Items\"; absent with the count. */\n readonly countLabel?: string;\n /** Whether it is the one being dragged. */\n readonly dragging: boolean;\n}\n\n/** A placed entry of an Area (ADR-0061). */\nexport interface PivotFieldListEntryView {\n /** Which entry it is: its Area and index there, \u22121 for \u03A3 Values. */\n readonly entry: PivotEntry;\n /** The name its button and the anchor around it are handed in by, through `control` and `anchor`. */\n readonly key: string;\n /** What it is called: the field's caption, a Value Field's caption, \u03A3 Values. */\n readonly caption: string;\n /** The button's accessible name: \"Options for Region\". */\n readonly menuLabel: string;\n /** Whether its field hides Items now. */\n readonly filtered: boolean;\n /** Whether it is \u03A3 Values. */\n readonly values: boolean;\n /** Whether its menu, or a panel the menu opened, stands under it: the entry is then not draggable, so a press that\n * moves a little on the menu is the menu's. */\n readonly menuOpen: boolean;\n /** Whether it is the one being dragged. */\n readonly dragging: boolean;\n /** Whether a drop now would land before it. */\n readonly dropBefore: boolean;\n /** The index a `dragenter` on it hands `dragEnter`, and a `drop` on it hands `drop`: its own, or for \u03A3 Values,\n * which always stands last, its Area's `end`. */\n readonly dropIndex: number;\n}\n\n/** One Area of the Field List (ADR-0061). */\nexport interface PivotFieldListAreaView {\n /** Which Area. */\n readonly area: PivotArea;\n /** Its name: Filters, Columns, Rows, Values. */\n readonly title: string;\n /** What stands in it, \u03A3 Values last where it stands. */\n readonly entries: readonly PivotFieldListEntryView[];\n /** The index a `dragenter` or a `drop` on the Area's box itself hands on: past its last entry. */\n readonly end: number;\n /** Whether what is dragged is over it, and may be dropped there. */\n readonly dropTarget: boolean;\n /** While a drop there would pass the leaf cap, by the counts, the words that say so, in a `role=\"status\"`: a hint,\n * never a refusal (ADR-0370 section 3). Absent otherwise. */\n readonly overCap?: string;\n}\n\n/** What the Field List shows now (ADR-0061). */\nexport interface PivotFieldListView {\n /** The pane's name: \"PivotTable Fields\". */\n readonly title: string;\n /** The heading's close button's accessible name: \"Hide Field List\". */\n readonly hideLabel: string;\n /** The caption above the fields: \"Choose fields to add to report:\". */\n readonly chooseCaption: string;\n /** The search's accessible name and placeholder. */\n readonly searchLabel: string;\n /** The search as typed. */\n readonly search: string;\n /** The declared fields the search leaves, in declaration order. */\n readonly fields: readonly PivotFieldListFieldView[];\n /** The caption above the Areas: \"Drag fields between areas below:\". */\n readonly dragCaption: string;\n /** The four Areas, in Excel's order: Filters, Columns, Rows, Values. */\n readonly areas: readonly PivotFieldListAreaView[];\n /** Whether a drop on the list of fields, or on the report, removes what is dragged: a placed field's entry. */\n readonly dropRemoves: boolean;\n /** Defer Layout Update, at the pane's foot: its words, and whether it is ticked. */\n readonly defer: { readonly label: string; readonly ticked: boolean };\n /** Update: its words, and whether it would apply anything. */\n readonly update: { readonly label: string; readonly enabled: boolean };\n}\n\n/** What is dragged in the Field List: a declared field from the list of fields, or a placed entry of an Area. */\nexport type PivotDragSubject = { readonly field: string } | { readonly entry: PivotEntry };\n\n/**\n * What the Field List's contents are handed (ADR-0061): the fields with their tick boxes and search, and the four\n * Areas with their entries, each entry's open menu or panel placed by the pivot in the anchor around its button.\n * Drag and drop is the browser's own: a draggable element calls `startDrag` on `dragstart` and `endDrag` on `dragend`;\n * a drop target calls `dragOver` on `dragover` always \u2014 whether it may be dropped on is decided at the drop, never by a\n * render that may still be on its way \u2014 `dragEnter` on `dragenter` for the marks, and `drop` (or `dropOnList`) on\n * `drop`. Each Area's box is handed in by `area`, so a drag that leaves every Area is seen to.\n */\nexport interface PivotFieldListSlotContext extends PivotStandingSlotContext<PivotFieldListView> {\n /** The search as it is typed. */\n readonly setSearch: (text: string) => void;\n /** A field's tick box pressed: ticks it into the layout, or takes it out. */\n readonly toggle: (field: string) => void;\n /** An entry's button pressed: opens its menu, or closes the one standing under it. */\n readonly openMenu: (entry: PivotEntry) => void;\n /** The heading's close button pressed: hides the Field List, keeping the layout and any pending one. */\n readonly close: () => void;\n /** A `dragstart` on a field or an entry: the drag starts, against the layout the pane shows. */\n readonly startDrag: (event: DragEvent, subject: PivotDragSubject) => void;\n /** A `dragover` on any drop target: takes the drop while a drag of the pane's is on. */\n readonly dragOver: (event: DragEvent) => void;\n /** A `dragenter` on an Area (`index` its entries' count) or an entry (`index` its own): where a drop would land. */\n readonly dragEnter: (area: PivotArea, index: number) => void;\n /** A `drop` on an Area or an entry, at the index `dragEnter` takes. */\n readonly drop: (event: DragEvent, area: PivotArea, index: number) => void;\n /** A `drop` on the list of fields: an entry dragged back is taken out of the layout. */\n readonly dropOnList: (event: DragEvent) => void;\n /** A `dragend`, whether or not anything was dropped. */\n readonly endDrag: () => void;\n /** Defer Layout Update ticked or unticked; unticking applies the pending layout, as Excel does. */\n readonly setDeferred: (deferred: boolean) => void;\n /** Update pressed: applies the pending layout in one change. */\n readonly update: () => void;\n /** Hands in a control: `search`, a field's tick box by its `key`, or an entry's button by its `key`. */\n readonly control: (key: string) => PivotPartRef;\n /** Hands in the anchor around an entry's button, or beside it, by the entry's `key`: an element of no position of\n * its own, so the frame the pivot places in it takes the pane's width (ADR-0061). A press or focus on the entry's\n * button, handed in by `control`, is inside its open menu wherever the anchor stands. */\n readonly anchor: (key: string) => PivotPartRef;\n /** Hands in an Area's box. */\n readonly area: (area: PivotArea) => PivotPartRef;\n}\n\n/** A sheet's tab at the report's foot (ADR-0059): the report's own, first, or a Show Details sheet's. */\nexport interface PivotDetailsTabView {\n /** The name the tab's control is handed in by, and `select` and `close` are handed. */\n readonly key: string;\n /** What the tab reads: the report's own words, or the cell the records are behind. */\n readonly title: string;\n /** Whether it is the selected sheet: a details sheet's records then cover the report. */\n readonly selected: boolean;\n /** The id of the panel its records stand in, for the control's `aria-controls`; absent on the report's tab. */\n readonly panelId?: string;\n /** Its close button's words, said as \"Close \u2026\"; absent on the report's tab, which does not close. */\n readonly closeLabel?: string;\n}\n\n/** What the sheet tabs show now (ADR-0059). */\nexport interface PivotDetailsTabsView {\n /** The tab list's name. */\n readonly name: string;\n /** The report's tab, then each Show Details sheet's, in the order they opened. */\n readonly tabs: readonly PivotDetailsTabView[];\n}\n\n/** What the sheet tabs' contents are handed (ADR-0059), at the report's foot while a Show Details sheet stands. The\n * selected sheet's records are the pivot's, in a panel of its own over the report; the tab that opens takes the\n * keyboard, and so does the one selected once a tab holding it closes. */\nexport interface PivotDetailsTabsSlotContext extends PivotStandingSlotContext<PivotDetailsTabsView> {\n /** A tab pressed, by its `key`: its sheet is selected. */\n readonly select: (key: string) => void;\n /** A details tab's close pressed, by its `key`: Excel's next sheet is selected, or the report. */\n readonly close: (key: string) => void;\n /** Hands in the control of the tab of `key`. */\n readonly control: (key: string) => PivotPartRef;\n}\n\n/** What the Show Details dialog shows now (ADR-0059). */\nexport interface PivotDetailsDialogView {\n /** The cell the records are behind, which names the dialog. */\n readonly title: string;\n /** Close's words. */\n readonly closeLabel: string;\n}\n\n/** What the Show Details dialog's contents are handed (ADR-0059): its title, the anchor its records stand in and\n * Close, inside the pivot's modal frame, which keeps the backdrop and Escape. Close takes the keyboard as the dialog\n * opens, and the report's grid takes it back however it closes. */\nexport interface PivotDetailsDialogSlotContext extends PivotStandingSlotContext<PivotDetailsDialogView> {\n /** Close pressed. */\n readonly close: () => void;\n /** Hands in Close. */\n readonly control: (name: 'close') => PivotPartRef;\n /** Hands in the element the records stand in: their box takes the room the dialog gives it. */\n readonly anchor: (name: 'records') => PivotPartRef;\n}\n\n/** A stylesheet a Chrome brings (ADR-0123), as its notice names it: a Wrapper has no root of its own (ADR-0062), so\n * its Chrome declares the stylesheets it brings, and the pivot's root renders a notice for each beside its own. */\nexport interface PivotChromeStylesheet {\n /** The stylesheet's source file name, as the rules at the end of the shipped stylesheet name it: `mud-ex-pivot.css`. */\n readonly name: string;\n /** The SHA-256 of that source, as lower-case hex: the stamp the stylesheet the Chrome was built with hides its\n * notice for. */\n readonly stamp: string;\n}\n\n/**\n * The Chrome slots a pivot takes (ADR-0061, ADR-0390): the parts a Wrapper draws, each in place of the built-in\n * markup's. A slot not given is the built-in markup's. A slot is read when its part opens: a part standing keeps the\n * slot it opened with.\n */\nexport interface PivotChrome {\n /** The stylesheets this Chrome brings (ADR-0123): the pivot's root renders a notice for each beside its own, which\n * only another version's stylesheet shows. The report grid's Chrome declares its own. None where not given. */\n readonly stylesheets?: readonly PivotChromeStylesheet[];\n /** The report grid's Chrome, and Show Details' grids', so one Chrome dresses the pivot and the grids it draws. The\n * Context Menu's commands are worded by the pivot. */\n readonly grid?: GridChrome<unknown>;\n /** A placed field's menu and the Layout menu. */\n readonly menu?: PivotChromeSlot<PivotMenuSlotContext>;\n /** Filter\u2026, under a field's entry or a report filter's button. */\n readonly itemFilter?: PivotChromeSlot<PivotItemFilterSlotContext>;\n /** Field Settings\u2026 of a row or column field. */\n readonly fieldSettings?: PivotChromeSlot<PivotFieldSettingsSlotContext>;\n /** Value Field Settings\u2026. */\n readonly valueFieldSettings?: PivotChromeSlot<PivotValueFieldSettingsSlotContext>;\n /** The Pivot Toolbar above the report. */\n readonly toolbar?: PivotChromeSlot<PivotToolbarSlotContext>;\n /** The report filter band, on the Pivot Toolbar's left. */\n readonly reportFilters?: PivotChromeSlot<PivotReportFiltersSlotContext>;\n /** The Stale Report's notice, under the Pivot Toolbar. */\n readonly staleReport?: PivotChromeSlot<PivotStaleReportSlotContext>;\n /** The Field List: Excel's PivotTable Fields pane. Its slot draws no box of its own, so the contents fill the\n * Field List's height (`height: 100%`). */\n readonly fieldList?: PivotChromeSlot<PivotFieldListSlotContext>;\n /** The sheet tabs at the report's foot, while Show Details' records stand in a tab. */\n readonly detailsTabs?: PivotChromeSlot<PivotDetailsTabsSlotContext>;\n /** What the Show Details dialog draws inside its frame, a flex column; the slot draws no box of its own. */\n readonly detailsDialog?: PivotChromeSlot<PivotDetailsDialogSlotContext>;\n}\n\nconst slotNames: readonly Exclude<keyof PivotChrome, 'stylesheets'>[] = ['grid', 'menu', 'itemFilter', 'fieldSettings', 'valueFieldSettings', 'toolbar', 'reportFilters', 'staleReport', 'fieldList', 'detailsTabs',\n 'detailsDialog'];\n\n/** A pivot's `chrome`, checked as a script may hand it: an object whose slots are each a mount function, and whose\n * `grid` is an object the report grid checks. */\nexport function checkedPivotChrome(chrome: unknown): PivotChrome | undefined {\n if (chrome === undefined) return undefined;\n if (typeof chrome !== 'object' || chrome === null) {\n throw new TypeError('An ExPivot\\'s chrome is an object of Chrome slots, each a mount function (ADR-0390).');\n }\n for (const [name, slot] of Object.entries(chrome)) {\n if (name === 'stylesheets') {\n checkedStylesheets(slot);\n continue;\n }\n if (!(slotNames as readonly string[]).includes(name)) {\n throw new TypeError(`An ExPivot's chrome has no slot '${name}': its slots are ${slotNames.join(', ')} (ADR-0390).`);\n }\n if (name === 'grid') {\n if (slot !== undefined && (typeof slot !== 'object' || slot === null)) {\n throw new TypeError('An ExPivot\\'s chrome.grid is a grid\\'s chrome: an object of its Chrome slots (ADR-0390).');\n }\n } else if (slot !== undefined && typeof slot !== 'function') {\n throw new TypeError(`An ExPivot's chrome.${name} is a mount function, (slot, context) => cleanup (ADR-0350 section 9).`);\n }\n }\n return chrome;\n}\n\n/** A Chrome's `stylesheets`, checked as a script may hand them: each a name and a SHA-256 stamp the notice carries. */\nfunction checkedStylesheets(stylesheets: unknown): void {\n if (stylesheets === undefined) return;\n if (!Array.isArray(stylesheets)) throw new TypeError('An ExPivot\\'s chrome.stylesheets is an array of { name, stamp } (ADR-0123).');\n for (const stylesheet of stylesheets as readonly unknown[]) {\n const name: unknown = typeof stylesheet === 'object' && stylesheet !== null ? Reflect.get(stylesheet, 'name') : undefined;\n const stamp: unknown = typeof stylesheet === 'object' && stylesheet !== null ? Reflect.get(stylesheet, 'stamp') : undefined;\n // Any stamp is taken, as C#'s ChromeStylesheet takes it: one no shipped stylesheet carries leaves the notice\n // showing, which says so, not quietly.\n if (typeof name !== 'string' || name === '' || typeof stamp !== 'string' || stamp === '') {\n throw new TypeError('Each of an ExPivot\\'s chrome.stylesheets is { name, stamp }: the stylesheet\\'s file name, and the stamp its own rule hides the notice for (ADR-0123).');\n }\n }\n}\n\n/** Mounts `context` into `slot` by `mount`, and answers the cleanup it returned, checked. */\nfunction mounted<Context>(name: string, mount: PivotChromeSlot<Context>, slot: HTMLElement, context: Context): () => void {\n const cleanup: unknown = mount(slot, context);\n if (typeof cleanup !== 'function') {\n throw new TypeError(`An ExPivot's chrome.${name} answered ${typeof cleanup}: a mount function answers the function that takes its contents away.`);\n }\n return () => { Reflect.apply(cleanup, undefined, []); };\n}\n\n/** The listeners a slot's view is told each change through, by the context's `subscribe`. */\nexport class ViewListeners {\n readonly #listeners = new Set<() => void>();\n\n /** The context's `subscribe`: adds `listener`, and answers the function that removes it. */\n readonly subscribe = (listener: () => void): (() => void) => {\n if (typeof listener !== 'function') throw new TypeError('subscribe is handed the function that hears each change to the view.');\n this.#listeners.add(listener);\n return () => { this.#listeners.delete(listener); };\n };\n\n /** Tells every listener the view changed. */\n tell(): void {\n for (const listener of this.#listeners) listener();\n }\n\n /** The part is gone: nothing is told any more. */\n clear(): void {\n this.#listeners.clear();\n }\n}\n\n/**\n * A Chrome slot's contents while their part stands (ADR-0390): mounted with a context, mounted again with the next\n * one for each request for the keyboard, and taken away when the part goes, after which nothing they call back\n * reaches the pivot. The focus a request asks for is owed, the pivot's to give wherever DOM focus stands, until the\n * contents give it or the user makes an input in the part; any other focus they ask for is given only while the\n * keyboard is still the pivot's (ADR-0204), as ExGrid's own slots do.\n */\nexport class SlotMount<Context> {\n readonly #name: string;\n readonly #mount: PivotChromeSlot<Context>;\n /** The slot, which the pivot stands inside the part's frame. */\n readonly element: HTMLElement;\n readonly #context: (focusRequest: number) => Context;\n readonly #cancel: () => void;\n #cleanup: (() => void) | undefined;\n #focusRequest = 0;\n #owed = false;\n #live = true;\n /** Whether a popup of the contents' own is open: Escape is then the popup's (ADR-0039). */\n innerPopupOpen = false;\n\n /** `context` makes the context for a focus request's count; `cancel` closes the part. */\n constructor(name: string, mount: PivotChromeSlot<Context>, element: HTMLElement, context: (focusRequest: number) => Context, cancel: () => void) {\n this.#name = name;\n this.#mount = mount;\n this.element = element;\n this.#context = context;\n this.#cancel = cancel;\n element.setAttribute('data-ex-pivot-slot', name);\n }\n\n /** Whether the part stands. */\n get live(): boolean {\n return this.#live;\n }\n\n /** Mounts the contents, once. */\n mount(): void {\n if (this.#live && this.#cleanup === undefined) this.#draw();\n }\n\n /** A request for the keyboard: the contents are mounted again with the next count. */\n request(): void {\n if (!this.#live) return;\n this.#focusRequest += 1;\n this.#owed = true;\n this.#unmount();\n this.#draw();\n }\n\n /** `change` as an input the user made in the part: no focus is owed any longer, and nothing is made once the part\n * is gone. */\n input<Args extends unknown[]>(change: (...args: Args) => void): (...args: Args) => void {\n return (...args: Args): void => {\n if (!this.#live) return;\n this.#owed = false;\n change(...args);\n };\n }\n\n /** The part is going: its contents are taken away. */\n dispose(): void {\n if (!this.#live) return;\n this.#live = false;\n this.#unmount();\n }\n\n readonly innerPopupChanged = (open: boolean): void => {\n if (typeof open !== 'boolean') throw new TypeError('innerPopupChanged is handed whether the popup is open.');\n if (this.#live) this.innerPopupOpen = open;\n };\n\n readonly takeFocus = (control: HTMLElement): void => {\n if (!(control instanceof HTMLElement)) throw new TypeError('takeFocus is handed the element that takes the keyboard.');\n if (!this.#live || !control.isConnected) return;\n const owed = this.#owed;\n this.#owed = false;\n const pivot = this.element.closest('.ex-pivot');\n if (owed || (pivot !== null && keyboardIsThePivots(pivot))) control.focus();\n };\n\n // Contents that cannot be drawn close the part, rather than leave it standing empty.\n #draw(): void {\n try {\n this.#cleanup = mounted(this.#name, this.#mount, this.element, this.#context(this.#focusRequest));\n } catch (error) {\n this.#cancel();\n throw error;\n }\n }\n\n // The contents go, and a popup of theirs with them: they are not asked to say so.\n #unmount(): void {\n const cleanup = this.#cleanup;\n this.#cleanup = undefined;\n this.innerPopupOpen = false;\n cleanup?.();\n }\n}\n\n/**\n * A standing part's slot (ADR-0390): its contents are mounted once, with a context of their own, while the part\n * stands and the same mount function is given, and told each change to its view. Another mount function, the\n * Consumer having handed another `chrome`, mounts again; once the part goes, nothing the contents call back reaches\n * the pivot. The slot is an element of its own, which the pivot stands in the part's place. Contents that cannot be\n * drawn are refused by name once, and the part is the built-in markup's while that mount function is given.\n */\nexport class StandingSlot<View, Context> {\n readonly #name: string;\n /** The slot. */\n readonly element: HTMLElement;\n // Each mount's own, so contents a framework keeps across a mount subscribe again to the next one's.\n #listeners = new ViewListeners();\n #view: View;\n // What the view held says, so a draw that shows the same thing makes nothing new and tells nobody; worked out only\n // while contents stand to be told.\n #said: string | undefined;\n #mount: PivotChromeSlot<Context> | undefined;\n #cleanup: (() => void) | undefined;\n #failed: PivotChromeSlot<Context> | undefined;\n // Counts the mounts, so a callback handed to one reaches nothing once another stands.\n #mounts = 0;\n\n constructor(name: string, document: Document, view: View) {\n this.#name = name;\n this.element = document.createElement('div');\n this.element.setAttribute('data-ex-pivot-slot', name);\n this.#view = view;\n }\n\n /** The view the part shows: `next`, or the one held where it shows the same, so it stays the same object while\n * nothing it shows changed. */\n viewOf(next: View): View {\n if (this.#cleanup === undefined) {\n this.#view = next;\n this.#said = undefined;\n return next;\n }\n const said = JSON.stringify(next);\n const held = this.#said === undefined ? JSON.stringify(this.#view) : this.#said;\n this.#said = said;\n if (said === held) return this.#view;\n this.#view = next;\n this.#listeners.tell();\n return next;\n }\n\n /** Whether the contents `mount` draws stand. */\n stands(mount: PivotChromeSlot<Context>): boolean {\n return this.#cleanup !== undefined && this.#mount === mount;\n }\n\n /** Whether `mount` could not be drawn: it is not tried again. */\n refuses(mount: PivotChromeSlot<Context>): boolean {\n return this.#failed === mount;\n }\n\n /** Shows the view held by `mount`: the contents are mounted with the context `context` makes, unless `mount`\n * already stands. `context` is handed the shared parts and an `input` that keeps a callback from reaching the\n * pivot once these contents are gone. Answers whether the contents stand; a mount function that throws, or answers\n * no cleanup, is not tried again, and its error is answered for the pivot to throw once it has drawn. */\n show(mount: PivotChromeSlot<Context>,\n context: (shared: PivotStandingSlotContext<View>, input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void) => Context,\n label: (id: string) => string): { readonly shown: boolean; readonly error?: Error } {\n if (this.refuses(mount)) return { shown: false };\n if (this.stands(mount)) return { shown: true };\n this.hide();\n this.#mounts += 1;\n const made = this.#mounts;\n const input = <Args extends unknown[]>(change: (...args: Args) => void): ((...args: Args) => void) => (...args: Args): void => {\n if (this.#cleanup !== undefined && this.#mounts === made) change(...args);\n };\n this.#listeners = new ViewListeners();\n const shared: PivotStandingSlotContext<View> = { view: () => this.#view, subscribe: this.#listeners.subscribe, label };\n try {\n this.#cleanup = mounted(this.#name, mount, this.element, Object.freeze(context(shared, input)));\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- answered, and thrown by the pivot once it has drawn the built-in markup in its place\n this.#failed = mount;\n return { shown: false, error: error instanceof Error ? error : new Error(`An ExPivot's chrome.${this.#name} could not be drawn (ADR-0390).`, { cause: error }) };\n }\n this.#mount = mount;\n return { shown: true };\n }\n\n /** What the part shows now. */\n get view(): View {\n return this.#view;\n }\n\n /** The part shows none of the contents: they are taken away. */\n hide(): void {\n const cleanup = this.#cleanup;\n this.#cleanup = undefined;\n this.#mount = undefined;\n this.#listeners.clear();\n cleanup?.();\n }\n}\n", "// The pivot's own elements, made as every view of it makes them.\n\n/** A new element of `document`, with `className` when given. */\nexport function element<K extends keyof HTMLElementTagNameMap>(document: Document, tag: K, className?: string): HTMLElementTagNameMap[K] {\n const made = document.createElement(tag);\n if (className !== undefined) made.className = className;\n return made;\n}\n\n// The style each element was last written, by the pivot.\nconst written = new WeakMap<Element, string>();\n\n/** Writes `style` on `target` when it differs from what the pivot last wrote there, as a Razor render writes an\n * attribute only when its own value changed: a style the page set on the element since stays until the pivot's\n * own changes. */\nexport function writeStyle(target: Element, style: string): void {\n if (written.get(target) === style) return;\n written.set(target, style);\n target.setAttribute('style', style);\n}\n\n/** Takes away the style the pivot wrote on `target`, which it no longer draws. */\nexport function clearStyle(target: Element): void {\n written.delete(target);\n target.removeAttribute('style');\n}\n", "// Show Details' sheets as the pivot shows them when the Consumer does not take the records (ADR-0059): a tab at the\n// report's foot for each, where Excel's sheet tabs are, whose records cover the report while it is selected; or one\n// modal dialog over the pivot. The markup and classes are the Razor component's PivotDetailsTabsView,\n// PivotDialogFrame, PivotDetailsDialogView and PivotDetailsGrid (ADR-0350 section 4). Each sheet's records are an\n// ExGrid of their own, in an Input Root of their own (ADR-0240 section 6).\n\nimport type { CellTextMetrics, GridChrome, GridDensity, GridHandle, GridOptions, GridPresentationDefaults } from '@ex-grid/core';\nimport type { PivotDetailRecord } from '@ex-grid/pivot-engine';\nimport {\n StandingSlot, type PivotChrome, type PivotDetailsDialogSlotContext, type PivotDetailsDialogView, type PivotDetailsTabsSlotContext, type PivotDetailsTabsView,\n} from './chrome';\nimport { detailCellType, DetailsSheet, type DetailsProblem, type PivotDetailsView, type PivotShowDetailsEvent } from './details';\nimport { element } from './dom';\nimport { checkedName, keyboardIsThePivots, swap, type PartElements } from './parts';\nimport type { PivotScreenWords } from './words';\n\n/** Draws a grid into an element: ExGrid's `createGrid`, or a layer-2 test's own. */\nexport type MountGrid = <Row>(element: HTMLElement, options: GridOptions<Row>) => GridHandle<Row>;\n\n/** What the records' grids take from the pivot's options. */\nexport interface DetailsGridLook {\n readonly rowHeight: number | undefined;\n readonly density: GridDensity | undefined;\n readonly cellMetrics: CellTextMetrics | undefined;\n readonly presentationDefaults: GridPresentationDefaults | undefined;\n readonly commandLabel: ((id: string) => string | undefined) | undefined;\n /** The grid's Chrome a pivot's Chrome dresses its grids in (ADR-0390). */\n readonly chrome: GridChrome<PivotDetailRecord> | undefined;\n}\n\n/** What the sheets ask of the pivot. */\nexport interface DetailsHost {\n readonly document: Document;\n readonly mountGrid: MountGrid;\n readonly words: () => PivotScreenWords;\n readonly look: () => DetailsGridLook;\n /** Why the records cannot be shown, in the pivot's words. */\n readonly problemText: (problem: DetailsProblem) => string;\n /** The sheets changed what the pivot draws around them: which covers the report, whether a dialog stands. */\n readonly changed: () => void;\n /** The report's grid takes the keyboard back (ADR-0070). */\n readonly returnKeyboard: () => void;\n /** The controls and anchors the pivot's parts hand in, the sheets' among them. */\n readonly parts: PartElements;\n /** The pivot's Chrome slots for the sheets, read each time the sheets are drawn. */\n readonly chrome: () => Pick<PivotChrome, 'detailsTabs' | 'detailsDialog'> | undefined;\n}\n\n// One sheet's records: its grid in an Input Root of its own, or the sentence that says why there are none.\nclass Records {\n readonly sheet: DetailsSheet;\n /** What stands in the panel or the dialog. */\n readonly box: HTMLElement;\n readonly #host: DetailsHost;\n readonly #leave: (() => void) | undefined;\n readonly #keyboardHome: () => void;\n /** Whether the box stands where the records are shown: a Chrome's dialog hands in the anchor it stands in once\n * its contents are drawn. */\n standing = true;\n #grid: GridHandle<PivotDetailRecord> | undefined;\n #status: HTMLElement | undefined;\n\n /** `leave` is the dialog's way out; `keyboardHome` gives the keyboard on when the grid that held it goes. */\n constructor(host: DetailsHost, sheet: DetailsSheet, leave: (() => void) | undefined, keyboardHome: () => void) {\n this.#host = host;\n this.sheet = sheet;\n this.#leave = leave;\n this.#keyboardHome = keyboardHome;\n // The box draws nothing (`display: contents`); the records' grid keeps an order of its own, apart from the\n // report's, which hears the rest of the pivot.\n this.box = element(host.document, 'div');\n this.box.setAttribute('data-ex-input-root', '');\n this.box.setAttribute('style', 'display: contents');\n }\n\n /** Draws the records, once their box stands in the document. */\n draw(): void {\n if (!this.standing) return;\n const { problem } = this.sheet;\n if (problem !== undefined) {\n // The sentence replaces the grid, and the keyboard the grid held goes to the tab or to Close, so it stays\n // in the sheet.\n const held = this.box.contains(this.#host.document.activeElement);\n this.#grid?.destroy();\n this.#grid = undefined;\n const text = this.#host.problemText(problem);\n if (this.#status === undefined) {\n this.#status = element(this.#host.document, 'div', 'ex-pivot-details-status');\n this.#status.setAttribute('role', 'alert');\n this.box.replaceWith(this.#status);\n }\n if (this.#status.textContent !== text) this.#status.textContent = text;\n if (held) this.#keyboardHome();\n return;\n }\n const { rowHeight, density, cellMetrics, presentationDefaults, commandLabel, chrome } = this.#host.look();\n const options: GridOptions<PivotDetailRecord> = {\n columns: this.sheet.columns,\n source: this.sheet.source,\n // The locale its records' text was written in, so one grid never shows two cultures.\n locale: this.sheet.locale,\n viewportHeight: 'stretch',\n viewportWidth: 'stretch',\n // The records are in the data's order and none is left out: the header click selects, and there is no\n // column menu to sort or filter them by (ADR-0059).\n headerClickSelects: true,\n hideColumnMenu: true,\n cellType: detailCellType,\n ...(commandLabel === undefined ? {} : { commandLabel }),\n ...(chrome === undefined ? {} : { chrome }),\n ...(rowHeight === undefined ? {} : { rowHeight }),\n ...(density === undefined ? {} : { density }),\n ...(cellMetrics === undefined ? {} : { cellMetrics }),\n ...(presentationDefaults === undefined ? {} : { presentationDefaults }),\n // The dialog's way out: the Escape its grid has nothing left to dismiss closes it (ADR-0070). A tab's grid\n // has none; Escape does not close a sheet.\n ...(this.#leave === undefined ? {} : { onLeave: this.#leave }),\n };\n if (this.#grid === undefined) {\n const root = element(this.#host.document, 'div');\n this.box.replaceChildren(root);\n this.#grid = this.#host.mountGrid(root, options);\n } else {\n this.#grid.update(options);\n }\n }\n\n /** Takes the grid away while the records are not on screen: a tab not selected. Its source stays. */\n hide(): void {\n this.#grid?.destroy();\n this.#grid = undefined;\n }\n\n dispose(): void {\n this.hide();\n this.sheet.dispose();\n }\n}\n\n// A details tab: its tab at the report's foot, and its panel over the report.\ninterface Tab {\n /** The name its control is handed in by, the built-in button's id. */\n readonly key: string;\n readonly records: Records;\n readonly tab: HTMLElement;\n readonly button: HTMLButtonElement;\n readonly close: HTMLButtonElement;\n readonly panel: HTMLElement;\n}\n\n// The dialog's frame over its backdrop; what stands inside it, the built-in markup's or a Chrome's contents; and\n// the box its records stand in.\ninterface Dialog {\n readonly records: Records;\n readonly backdrop: HTMLElement;\n readonly frame: HTMLElement;\n /** The built-in markup's: the title, the records and Close. */\n readonly content: HTMLElement;\n readonly heading: HTMLElement;\n readonly recordsBox: HTMLElement;\n readonly close: HTMLButtonElement;\n /** Whether a Chrome's contents stand in the frame. */\n slotted: boolean;\n}\n\n/** The name the dialog's Close is handed in by. */\nconst dialogClose = 'details-close';\n/** The name of the anchor the dialog's records stand in. */\nconst dialogRecords = 'details-records';\n\n// The name a tab's control is handed in by.\nfunction tabName(key: string): string {\n return `tab:${key}`;\n}\n\n// Each pivot's ids are its own on the page (ADR-0018).\nlet pivots = 0;\n\n/** The pivot's details sheets: the tabs and the dialog. */\nexport class DetailsSheets {\n readonly #host: DetailsHost;\n readonly #idPrefix: string;\n readonly #builtInTabList: HTMLElement;\n readonly #tabsSlot: StandingSlot<PivotDetailsTabsView, PivotDetailsTabsSlotContext>;\n #tabsSlotted = false;\n // One for every dialog, so contents refused once are not tried again at the next.\n readonly #dialogSlot: StandingSlot<PivotDetailsDialogView, PivotDetailsDialogSlotContext>;\n // The slots' contents that could not be drawn, for the pivot to throw once the sheets have drawn.\n #refused: Error[] = [];\n readonly #reportTab: HTMLElement;\n readonly #reportButton: HTMLButtonElement;\n readonly #tabs: Tab[] = [];\n #selected: Tab | undefined;\n #dialog: Dialog | undefined;\n #sequence = 0;\n\n constructor(host: DetailsHost) {\n this.#host = host;\n this.#idPrefix = `ex-pivot-${++pivots}`;\n const { document } = host;\n this.#builtInTabList = element(document, 'div', 'ex-pivot-tabs');\n this.#builtInTabList.setAttribute('role', 'tablist');\n this.#tabsSlot = new StandingSlot('detailsTabs', document, Object.freeze({ name: '', tabs: Object.freeze([]) }));\n this.#dialogSlot = new StandingSlot('detailsDialog', document, Object.freeze({ title: '', closeLabel: '' }));\n // The slot draws nothing (`display: contents`): the contents lay themselves out in the dialog's frame.\n this.#dialogSlot.element.setAttribute('style', 'display: contents');\n // The report's own tab, first: selecting it uncovers the report.\n const { tab, button } = this.#tab(`${this.#idPrefix}-report`, () => { this.#select(undefined); });\n this.#reportTab = tab;\n this.#reportButton = button;\n }\n\n /** The tab list at the report's foot, the built-in markup's or a Chrome's, which the pivot places after the report\n * while a tab stands. */\n get tabList(): HTMLElement {\n return this.#tabsSlotted ? this.#tabsSlot.element : this.#builtInTabList;\n }\n\n /** The slots' contents that could not be drawn since this was last asked, the built-in markup standing in their\n * place. */\n takeRefused(): readonly Error[] {\n const refused = this.#refused;\n this.#refused = [];\n return refused;\n }\n\n /** Whether a details tab is selected, its records covering the report. */\n get covering(): boolean {\n return this.#selected !== undefined;\n }\n\n /** The selected tab's panel, which the pivot places in the report's sheet over the report. */\n get panel(): HTMLElement | undefined {\n return this.#selected?.panel;\n }\n\n /** Whether a tab stands at the report's foot. */\n get tabsShown(): boolean {\n return this.#tabs.length > 0;\n }\n\n /** Whether the dialog stands: what it covers takes neither the keyboard nor the pointer (ADR-0059). */\n get dialogShown(): boolean {\n return this.#dialog !== undefined;\n }\n\n /** The dialog's backdrop and frame, which the pivot places last in its root; none while no dialog stands. */\n get dialogElements(): readonly HTMLElement[] {\n const dialog = this.#dialog;\n return dialog === undefined ? [] : [dialog.backdrop, dialog.frame];\n }\n\n /** Opens the records behind a cell as a new tab, selected and holding the keyboard, or in the dialog, whose\n * Close holds it. */\n open(details: PivotShowDetailsEvent, view: PivotDetailsView, locale: string): void {\n const id = `${this.#idPrefix}-details-${++this.#sequence}`;\n // `changed` reaches whichever of the tab and the dialog shows the sheet once it is made.\n let shown: Records | undefined;\n const sheet = new DetailsSheet(id, details, locale, () => {\n if (shown !== undefined && this.#showing(shown)) {\n shown.draw();\n this.#host.changed();\n }\n });\n const { parts } = this.#host;\n if (view === 'dialog') {\n this.#closeDialogNow();\n const records = new Records(this.#host, sheet, () => { this.closeDialog(); }, () => { parts.focus(dialogClose); });\n shown = records;\n const dialog = this.#dialogOf(records);\n this.#dialog = dialog;\n // Its contents are drawn once its frame stands, so Close is there to take the keyboard. Until a Chrome's\n // Close is drawn, a round trip later on a circuit, the frame holds it: the report it covers is inert, and a\n // key typed meanwhile is then the pivot's, never the page's (ADR-0240 section 6, ADR-0410 section 5).\n this.#host.changed();\n this.#drawDialog(dialog);\n const root = dialog.frame.parentElement;\n if (root !== null && keyboardIsThePivots(root)) dialog.frame.focus();\n parts.focus(dialogClose);\n return;\n }\n const { tab, button } = this.#tab(id, () => {\n const pressed = standing();\n if (pressed !== undefined) this.#select(pressed);\n });\n const records = new Records(this.#host, sheet, undefined, () => { parts.focus(tabName(id)); });\n shown = records;\n const tabs = this.#tabs;\n // Pressed only while the tab stands: a closed tab leaves the page.\n const standing = (): Tab | undefined => tabs.find(t => t.records === records);\n const close = this.#closeButton(tab, () => {\n const closed = standing();\n if (closed !== undefined) this.#closeTab(closed);\n });\n button.textContent = details.title;\n button.setAttribute('aria-controls', `${id}-panel`);\n const panel = element(this.#host.document, 'div', 'ex-pivot-details-panel');\n panel.setAttribute('role', 'tabpanel');\n panel.id = `${id}-panel`;\n panel.setAttribute('aria-labelledby', id);\n panel.append(records.box);\n const made: Tab = { key: id, records, tab, button, close, panel };\n this.#tabs.push(made);\n this.#selected?.records.hide();\n this.#selected = made;\n this.#drawTabs();\n this.#host.changed();\n records.draw();\n // The records now cover the report, so the keyboard leaves it for the new tab: keys left in a report nobody\n // sees would move and copy what is not on screen.\n parts.focus(tabName(id));\n }\n\n /** Draws the words again and hands the records' grids the pivot's options again. */\n draw(): void {\n this.#drawTabs();\n this.#selected?.records.draw();\n const dialog = this.#dialog;\n if (dialog !== undefined) this.#drawDialog(dialog);\n }\n\n /** Closes the dialog: the report's grid takes the keyboard back (ADR-0070), however it closes. */\n closeDialog(): void {\n if (this.#dialog === undefined) return;\n this.#closeDialogNow();\n this.#host.changed();\n this.#host.returnKeyboard();\n }\n\n /** Closes every sheet: the pivot is gone. */\n destroy(): void {\n for (const tab of this.#tabs) tab.records.dispose();\n this.#tabs.length = 0;\n this.#selected = undefined;\n this.#tabsSlot.hide();\n this.#closeDialogNow();\n }\n\n // Whether the records are on screen: the dialog's, or the selected tab's.\n #showing(records: Records): boolean {\n return this.#dialog?.records === records || this.#selected?.records === records;\n }\n\n #tab(id: string, select: () => void): { readonly tab: HTMLElement; readonly button: HTMLButtonElement } {\n const { document } = this.#host;\n const tab = element(document, 'div', 'ex-pivot-tab');\n const button = element(document, 'button', 'ex-pivot-tab-button');\n button.type = 'button';\n button.id = id;\n button.setAttribute('role', 'tab');\n button.setAttribute('data-ex-claims', 'click');\n button.addEventListener('click', select);\n tab.append(button);\n return { tab, button };\n }\n\n // A details tab's \u00D7, after its button.\n #closeButton(tab: HTMLElement, close: () => void): HTMLButtonElement {\n const closing = element(this.#host.document, 'button', 'ex-pivot-tab-close');\n closing.type = 'button';\n closing.textContent = '\u00D7';\n closing.setAttribute('data-ex-claims', 'click');\n closing.addEventListener('click', close);\n tab.append(closing);\n return closing;\n }\n\n // The tab list: the built-in markup's, or a Chrome's in its place while a details tab stands, drawn from the same\n // view. The built-in markup's buttons are handed in again each time it stands, as a Chrome's are when it draws\n // them.\n #drawTabs(): void {\n const words = this.#host.words();\n const view = this.#tabsSlot.viewOf(Object.freeze({\n name: words.word('sheets'),\n tabs: Object.freeze([\n Object.freeze({ key: this.#reportButton.id, title: words.word('report-tab'), selected: this.#selected === undefined }),\n ...this.#tabs.map(tab => Object.freeze({\n key: tab.key,\n title: tab.records.sheet.details.title,\n selected: tab === this.#selected,\n panelId: tab.panel.id,\n closeLabel: words.fill('close-tab', tab.records.sheet.details.title),\n })),\n ]),\n }));\n const mount = this.#host.chrome()?.detailsTabs;\n const leaving = this.tabList;\n const held = leaving.contains(this.#host.document.activeElement);\n const slotted = mount !== undefined && this.#tabs.length > 0 && this.#answered(this.#tabsSlot.show(mount, (shared, input) => {\n const refs = this.#host.parts.refs();\n return {\n ...shared,\n select: input((key: string) => {\n if (key === this.#reportButton.id) {\n this.#select(undefined);\n return;\n }\n const pressed = this.#tabs.find(tab => tab.key === key);\n if (pressed !== undefined) this.#select(pressed);\n }),\n close: input((key: string) => {\n const closed = this.#tabs.find(tab => tab.key === key);\n if (closed !== undefined) this.#closeTab(closed);\n }),\n control: (key: string) => refs.control(tabName(checkedKey(key))),\n };\n }, id => words.word(id)));\n if (!slotted) this.#tabsSlot.hide();\n this.#tabsSlotted = slotted;\n if (leaving !== this.tabList) {\n swap(leaving, this.tabList);\n // The tab that held the keyboard went with the markup it stood in: the selected sheet's tab takes it.\n if (held) this.#host.parts.focus(tabName(this.#selected?.key ?? this.#reportButton.id));\n }\n // A Chrome's tab need not take the id the built-in one does, so the panel is named by its words.\n for (const tab of this.#tabs) {\n if (slotted) {\n tab.panel.removeAttribute('aria-labelledby');\n tab.panel.setAttribute('aria-label', tab.records.sheet.details.title);\n } else {\n tab.panel.removeAttribute('aria-label');\n tab.panel.setAttribute('aria-labelledby', tab.key);\n }\n }\n if (slotted) return;\n this.#builtInTabList.setAttribute('aria-label', view.name);\n this.#reportButton.textContent = words.word('report-tab');\n const all: readonly { readonly tab: HTMLElement; readonly button: HTMLButtonElement; readonly selected: boolean }[] = [\n { tab: this.#reportTab, button: this.#reportButton, selected: this.#selected === undefined },\n ...this.#tabs.map(tab => ({ tab: tab.tab, button: tab.button, selected: tab === this.#selected })),\n ];\n for (const { tab, button, selected } of all) {\n tab.className = selected ? 'ex-pivot-tab ex-pivot-tab-selected' : 'ex-pivot-tab';\n button.setAttribute('aria-selected', selected ? 'true' : 'false');\n this.#host.parts.handInControl(tabName(button.id), button);\n }\n for (const tab of this.#tabs) {\n const label = words.fill('close-tab', tab.records.sheet.details.title);\n tab.close.setAttribute('aria-label', label);\n tab.close.title = label;\n }\n const children = all.map(tab => tab.tab);\n const list = this.#builtInTabList;\n if (children.length !== list.children.length || children.some((child, i) => list.children[i] !== child)) {\n list.replaceChildren(...children);\n }\n }\n\n // Whether a slot's contents stand, as `answer` says; an error it answers is the pivot's to throw.\n #answered(answer: { readonly shown: boolean; readonly error?: Error }): boolean {\n if (answer.error !== undefined) this.#refused.push(answer.error);\n return answer.shown;\n }\n\n // A tab pressed: the report's (`undefined`), or a details tab that still stands.\n #select(tab: Tab | undefined): void {\n if (tab === this.#selected) return;\n this.#selected?.records.hide();\n this.#selected = tab;\n this.#drawTabs();\n this.#host.changed();\n tab?.records.draw();\n }\n\n #closeTab(tab: Tab): void {\n const at = this.#tabs.indexOf(tab);\n if (at < 0) return;\n this.#tabs.splice(at, 1);\n tab.records.dispose();\n this.#host.parts.forget(tabName(tab.key), tab.button);\n // Excel's next sheet: the one after the closed tab, or before it, or the report.\n const moved = this.#selected === tab;\n if (moved) this.#selected = this.#tabs[Math.min(at, this.#tabs.length - 1)];\n this.#drawTabs();\n this.#host.changed();\n const selected = this.#selected;\n // The close button that held the keyboard is gone: the selected tab takes it. The report's tab is its grid,\n // which takes the keyboard back (ADR-0070); there may be no tab left to hold it, the last one having closed.\n if (selected === undefined) {\n this.#host.returnKeyboard();\n return;\n }\n if (moved) selected.records.draw();\n this.#host.parts.focus(tabName(selected.key));\n }\n\n #dialogOf(records: Records): Dialog {\n const { document } = this.#host;\n const words = this.#host.words();\n const { title } = records.sheet.details;\n // Under the dialog, a press anywhere else closes it.\n const backdrop = element(document, 'div', 'ex-pivot-dialog-backdrop');\n backdrop.setAttribute('data-ex-claims', 'click');\n backdrop.setAttribute('aria-hidden', 'true');\n backdrop.addEventListener('click', () => { this.closeDialog(); });\n // A modal dialog named by the cell. It claims nothing, which makes it, holding the keyboard, the pivot's own\n // (ADR-0240 section 6). Escape closes it from anywhere inside it that hears the key: an Escape in the records'\n // grid never reaches it, the grid keeping every one, and the grid's way out closes it instead.\n const frame = element(document, 'div', 'ex-pivot-dialog');\n frame.setAttribute('role', 'dialog');\n frame.setAttribute('aria-modal', 'true');\n frame.setAttribute('aria-label', title);\n frame.tabIndex = -1;\n frame.setAttribute('data-ex-claims', '');\n frame.addEventListener('keydown', event => {\n if (event.key !== 'Escape' || event.defaultPrevented) return;\n event.preventDefault();\n this.closeDialog();\n });\n const content = element(document, 'div', 'ex-pivot-dialog-content');\n const heading = element(document, 'div', 'ex-pivot-dialog-title');\n heading.textContent = title;\n const recordsBox = element(document, 'div', 'ex-pivot-dialog-records');\n recordsBox.append(records.box);\n const actions = element(document, 'div', 'ex-pivot-panel-actions');\n const close = element(document, 'button', 'ex-pivot-close');\n close.type = 'button';\n close.textContent = words.word('close');\n close.setAttribute('data-ex-claims', 'click');\n close.addEventListener('click', () => { this.closeDialog(); });\n actions.append(close);\n content.append(heading, recordsBox, actions);\n return { records, backdrop, frame, content, heading, recordsBox, close, slotted: false };\n }\n\n // What stands inside the dialog's frame: a Chrome's contents while they are given and can be drawn, else the\n // built-in markup's. The records stand in the anchor the contents hand in, and are drawn once they land there;\n // Close takes the keyboard again where the markup that held it went.\n #drawDialog(dialog: Dialog): void {\n const words = this.#host.words();\n const { parts } = this.#host;\n const slot = this.#dialogSlot;\n const view = slot.viewOf(Object.freeze({ title: dialog.records.sheet.details.title, closeLabel: words.word('close') }));\n const mount = this.#host.chrome()?.detailsDialog;\n const { frame, content, recordsBox, records } = dialog;\n const held = frame.contains(this.#host.document.activeElement);\n // The slot stands in the frame as the contents mount, so plain script hands in Close already in the page.\n const trying = mount !== undefined && !slot.refuses(mount);\n if (trying && slot.element.parentNode !== frame) frame.replaceChildren(slot.element);\n const slotted = trying && this.#answered(slot.show(mount, (shared, input) => {\n const refs = parts.refs();\n return {\n ...shared,\n close: input(() => { this.closeDialog(); }),\n control: name => {\n checkedName(name, ['close'], 'detailsDialog');\n return refs.control(dialogClose);\n },\n anchor: name => {\n checkedName(name, ['records'], 'detailsDialog');\n return refs.anchor(dialogRecords);\n },\n };\n }, id => words.word(id)));\n const moved = slotted !== dialog.slotted;\n dialog.slotted = slotted;\n if (slotted) {\n if (moved) {\n parts.forget(dialogClose, dialog.close);\n records.standing = false;\n parts.place(dialogRecords, recordsBox, () => {\n records.standing = true;\n records.draw();\n });\n } else {\n records.draw();\n }\n } else {\n slot.hide();\n parts.place(dialogRecords, undefined);\n if (content.parentNode !== frame) frame.replaceChildren(content);\n if (recordsBox.parentNode !== content) dialog.heading.after(recordsBox);\n parts.handInControl(dialogClose, dialog.close);\n dialog.close.textContent = view.closeLabel;\n records.standing = true;\n records.draw();\n }\n if (moved && held) parts.focus(dialogClose);\n }\n\n #closeDialogNow(): void {\n const dialog = this.#dialog;\n if (dialog === undefined) return;\n this.#dialog = undefined;\n this.#dialogSlot.hide();\n this.#host.parts.unplace(dialog.recordsBox);\n // The anchor the records stood in goes with the contents, though their framework lets go of it only later.\n this.#host.parts.dropAnchor(dialogRecords);\n this.#host.parts.forget(dialogClose, dialog.close);\n dialog.records.dispose();\n dialog.backdrop.remove();\n dialog.frame.remove();\n }\n}\n\n// A tab's key, as a script may hand it to `control`.\nfunction checkedKey(key: string): string {\n const given: unknown = key;\n if (typeof given !== 'string' || given === '') throw new TypeError('An ExPivot\\'s sheet tabs hand in a tab\\'s control by the key its view gives it (ADR-0390).');\n return given;\n}\n", "// A placed field's menu (ADR-0061): the commands the Razor component's ExPivot.MenuFor builds, in its order and\n// under its ids, each enabled only where it would change something. Each says what it does as the next layout,\n// taken against the layout the menu was drawn from, as a gesture in the Field List does (spine rule 6), and where\n// the entry it was opened on stands in that layout, which the keyboard goes back to.\n//\n// Filter\u2026, Field Settings\u2026 and Value Field Settings\u2026 open a panel in the menu's place.\n\nimport {\n isValuesPseudoField, moveEntry, placementOf, placementsIn, removeEntry, setFieldCollapsed, setSort, valuesPseudoField, type PivotArea,\n type PivotEntry, type PivotField, type PivotLayout,\n} from '@ex-grid/pivot-engine';\nimport { fieldOf, type FieldListEdit } from './field-list';\nimport type { PivotMenuCommand } from './menu';\nimport { defined, elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** What a field's menu is drawn from. */\nexport interface EntryMenuModel {\n /** The pane's layout, which the menu's commands are taken against. */\n readonly layout: PivotLayout;\n /** The fields the source offers. */\n readonly fields: readonly PivotField[];\n /** The words. */\n readonly words: PivotScreenWords;\n}\n\n/** A command's change: the layout it makes, and where the entry its menu was opened on stands in that layout, or\n * `undefined` when its field left the Areas. */\nexport interface EntryMenuEdit extends FieldListEdit {\n readonly entry: PivotEntry | undefined;\n}\n\n/** A panel a field's menu opens. */\nexport type EntryPanel = 'filter-items' | 'field-settings' | 'value-field-settings';\n\n/** One command of a field's menu: what it is, and the change it makes when pressed, or the panel it opens. */\nexport interface EntryMenuCommand extends Omit<PivotMenuCommand, 'invoke'> {\n readonly does: { readonly edit: () => EntryMenuEdit } | { readonly panel: EntryPanel };\n}\n\n/** Where `field` stands in `layout`, for the keyboard to go back to: at `near`, the entry a menu was opened on, if it\n * still stands for the field, else in Values beside it, else in the axis or Filters Area it is placed in, else in\n * Values; \u03A3 Values (no field) on its axis while two Value Fields hold it there. `undefined` once it left the Areas. */\nexport function entryOfField(layout: PivotLayout, field: string | undefined, near: PivotEntry): PivotEntry | undefined {\n if (field === undefined) return layout.values.length >= 2 ? valuesPseudoField(layout.valuesAxis) : undefined;\n const inValues = layout.values.findIndex(value => value.field === field);\n if (near.area === 'values' && inValues >= 0) return layout.values[near.index]?.field === field ? near : { area: 'values', index: inValues };\n return placementOf(layout, field) ?? (inValues >= 0 ? { area: 'values', index: inValues } : undefined);\n}\n\n// Past an Area's last entry: a move there puts the entry last.\nconst end = Number.MAX_SAFE_INTEGER;\n\n/** The commands of the menu of `entry`. */\nexport function entryMenuCommands(model: EntryMenuModel, entry: PivotEntry): readonly EntryMenuCommand[] {\n const { layout, fields, words } = model;\n const commands: EntryMenuCommand[] = [];\n const add = (id: string, enabled: boolean, edit: () => EntryMenuEdit): void => {\n commands.push(Object.freeze({ id, label: words.word(id), enabled, does: Object.freeze({ edit }) }));\n };\n const opens = (panel: EntryPanel): void => {\n commands.push(Object.freeze({ id: panel, label: words.word(panel), enabled: true, does: Object.freeze({ panel }) }));\n };\n const edit = (next: PivotLayout, at: PivotEntry | undefined, moved?: { readonly field: string; readonly area: PivotArea }): EntryMenuEdit =>\n ({ layout: next, against: layout, moved, entry: at });\n\n if (isValuesPseudoField(entry)) {\n // \u03A3 Values moves between Rows and Columns only (ADR-0060).\n const onRows = layout.valuesAxis === 'rows';\n add('move-to-rows', !onRows, () => edit(moveEntry(layout, entry, 'rows', end, undefined), valuesPseudoField('rows')));\n add('move-to-columns', onRows, () => edit(moveEntry(layout, entry, 'columns', end, undefined), valuesPseudoField('columns')));\n return Object.freeze(commands);\n }\n\n const name = fieldOf(layout, entry);\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n const count = entry.area === 'values' ? layout.values.length : placementsIn(layout, entry.area).length;\n // Within its Area the entry lands where it was put; moved to another, it stands last there, where a field already\n // in that Area is moved to (moveEntry).\n const within = (index: number, at: number): EntryMenuEdit =>\n edit(moveEntry(layout, entry, entry.area, index, field), { area: entry.area, index: at }, { field: name, area: entry.area });\n const to = (area: PivotArea): EntryMenuEdit => {\n const next = moveEntry(layout, entry, area, end, field);\n const index = area === 'values' ? next.values.length - 1 : placementsIn(next, area).findIndex(placement => placement.field === name);\n return edit(next, { area, index }, { field: name, area });\n };\n add('move-up', entry.index > 0, () => within(entry.index - 1, entry.index - 1));\n add('move-down', entry.index < count - 1, () => within(entry.index + 2, entry.index + 1));\n add('move-to-beginning', entry.index > 0, () => within(0, 0));\n add('move-to-end', entry.index < count - 1, () => within(count, count - 1));\n add('move-to-filters', entry.area !== 'filters', () => to('filters'));\n add('move-to-rows', entry.area !== 'rows', () => to('rows'));\n add('move-to-columns', entry.area !== 'columns', () => to('columns'));\n add('move-to-values', entry.area !== 'values', () => to('values'));\n // Removed from one Area, a field may still stand in another: Values beside Rows.\n add('remove-field', true, () => {\n const next = removeEntry(layout, entry);\n return edit(next, entryOfField(next, name, entry));\n });\n if (entry.area === 'values') opens('value-field-settings');\n if (entry.area === 'filters') opens('filter-items');\n if (entry.area !== 'rows' && entry.area !== 'columns') return Object.freeze(commands);\n\n const placement = elementAt(placementsIn(layout, entry.area), entry.index);\n const bySort = (direction: 'ascending' | 'descending'): boolean => placement.sort.direction === direction && placement.sort.byValue === undefined;\n add('sort-ascending', !bySort('ascending'), () => edit(setSort(layout, name, { direction: 'ascending' }), entry));\n add('sort-descending', !bySort('descending'), () => edit(setSort(layout, name, { direction: 'descending' }), entry));\n opens('filter-items');\n // The innermost field has nothing under its Items to collapse (ADR-0060).\n const outer = entry.index < count - 1;\n const toggled = placement.toggledItems.length > 0;\n add('expand-field', outer && (placement.collapsed || toggled), () => edit(setFieldCollapsed(layout, name, false), entry));\n add('collapse-field', outer && (!placement.collapsed || toggled), () => edit(setFieldCollapsed(layout, name, true), entry));\n opens('field-settings');\n return Object.freeze(commands);\n}\n", "// The built-in Field List (ADR-0061): Excel's \"PivotTable Fields\" pane in plain markup, under the classes and\n// the Visual Tokens of ExPivot's stylesheet, which the Razor component draws too, so one stylesheet and one\n// layer 3 judge both (ADR-0350 section 4). It draws the layout it is handed and says what a gesture means as\n// the next layout, taken against the layout it was drawn from; whether that layout is still the pane's is\n// the pivot's to judge (spine rule 6).\n//\n// Beside each field it writes the field's count of Items where the source counted them, and while a field is\n// dragged it marks a target in Rows or Columns where the layout the drop would make passes the leaf cap\n// (ADR-0370 section 3). The mark is a hint from the counts, never a refusal: the drop is asked as any other.\n\nimport {\n formatPivotCount, isValuesPseudoField, moveEntry, pivotLeafBound, placeField, placementOf, placementsIn, placesField, removeEntry,\n tickField, untickField, valuesPseudoField, type PivotArea, type PivotEntry, type PivotField, type PivotItemCounts, type PivotLayout,\n} from '@ex-grid/pivot-engine';\nimport { element } from './dom';\nimport { defined, elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** The Areas in the order Excel's pane lays them out, two by two. */\nexport const areaOrder: readonly PivotArea[] = Object.freeze(['filters', 'columns', 'rows', 'values']);\n\n/** What a gesture in the pane moved into an Area, for the words of a refusal (ADR-0370 section 3). */\nexport interface FieldListMove {\n /** The field's name. */\n readonly field: string;\n /** The Area it was put in. */\n readonly area: PivotArea;\n}\n\n/** A gesture in the pane: the layout it makes, the layout it was taken against, and what it moved. */\nexport interface FieldListEdit {\n readonly layout: PivotLayout;\n readonly against: PivotLayout;\n readonly moved: FieldListMove | undefined;\n}\n\n/** What the pane draws. */\nexport interface FieldListModel {\n /** The pane's layout: the one last asked for, or the one the report shows. */\n readonly layout: PivotLayout;\n /** The fields the source offers. */\n readonly fields: readonly PivotField[];\n /** Each Value Field's caption under `layout`. */\n readonly valueCaptions: readonly string[];\n /** Each field's count of Items, where the source counted them. */\n readonly counts: PivotItemCounts | undefined;\n /** The most leaves a question may ask for. */\n readonly maxLeaves: number;\n /** The locale counts are written in. */\n readonly locale: string;\n /** The words. */\n readonly words: PivotScreenWords;\n /** Whether Defer Layout Update is ticked: the pane's changes build a pending layout, which Update applies. */\n readonly deferred: boolean;\n /** Whether Update would apply anything: the pending layout is not the report's. */\n readonly canUpdate: boolean;\n /** The field menu or panel open in the pane: the entry it was opened on, and its frame, which the pane places\n * under that entry. */\n readonly popup: { readonly entry: PivotEntry; readonly frame: HTMLElement } | undefined;\n}\n\n/** Whom the pane calls back. */\nexport interface FieldListHandlers {\n /** A gesture made a layout. */\n readonly edit: (edit: FieldListEdit) => void;\n /** The heading's close button was pressed. */\n readonly close: () => void;\n /** A drag started or ended: the report accepts a placed field dropped on it, which removes it. */\n readonly dragging: (removable: boolean) => void;\n /** An entry's button was pressed, which opens its menu or closes it (ADR-0061). */\n readonly menu: (entry: PivotEntry) => void;\n /** Defer Layout Update was ticked or unticked. */\n readonly defer: (deferred: boolean) => void;\n /** Update was pressed. */\n readonly update: () => void;\n}\n\n/** What is dragged: a field from the list, or an entry of an Area. */\nexport type DragSubject = { readonly kind: 'field'; readonly field: string } | { readonly kind: 'entry'; readonly entry: PivotEntry };\n\n/** A drag in the pane: what is dragged, and the layout it started on, which a drop is taken against. */\nexport interface Drag {\n readonly subject: DragSubject;\n readonly layout: PivotLayout;\n}\n\n/** Where a drop would land: an Area, and the index of the entry it goes before (the Area's count for its end). */\nexport interface DropAt {\n readonly area: PivotArea;\n readonly index: number;\n}\n\n// What a gesture in the pane means is decided here, once, for the built-in pane and a Chrome's alike (ADR-0390):\n// the layout a tick, a drop or a drag back to the list makes, which Area takes a drop, and when a drop's layout\n// passes the leaf cap.\n\n/** The edit a field's tick box makes: unticked out of the Areas, ticked into Rows, or a number into Values, as\n * Excel's does. */\nexport function tickEdit(layout: PivotLayout, field: PivotField): FieldListEdit {\n if (placesField(layout, field.name)) return { layout: untickField(layout, field.name), against: layout, moved: undefined };\n const next = tickField(layout, field);\n const at = placementOf(next, field.name);\n const inValues = next.values.some(value => value.field === field.name);\n const area = at !== undefined ? at.area : inValues ? 'values' : undefined;\n return { layout: next, against: layout, moved: area === undefined ? undefined : { field: field.name, area } };\n}\n\n/** Whether `area` takes a drop of `drag`: \u03A3 Values goes only to Rows or Columns. */\nexport function acceptsDrag(drag: Drag, area: PivotArea): boolean {\n return drag.subject.kind === 'field' || !isValuesPseudoField(drag.subject.entry) || area === 'rows' || area === 'columns';\n}\n\n/** Whether a drop of `drag` on the report or the list removes it: a placed field's entry. */\nexport function removesOnDrop(drag: Drag | undefined): boolean {\n return drag?.subject.kind === 'entry' && !isValuesPseudoField(drag.subject.entry);\n}\n\n/** The edit a drop of `drag` at `area` and `index` makes, and what it moved. */\nexport function dropEdit(drag: Drag, area: PivotArea, index: number, fields: readonly PivotField[]): FieldListEdit {\n const layout = drag.layout;\n if (drag.subject.kind === 'field') {\n const name = drag.subject.field;\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n return { layout: placeField(layout, field, area, index), against: layout, moved: { field: name, area } };\n }\n const { entry } = drag.subject;\n if (isValuesPseudoField(entry)) return { layout: moveEntry(layout, entry, area, index, undefined), against: layout, moved: undefined };\n const name = fieldOf(layout, entry);\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n return { layout: moveEntry(layout, entry, area, index, field), against: layout, moved: { field: name, area } };\n}\n\n/** The edit a drop of `drag` back on the list of fields makes: a placed field taken out; none for anything else. */\nexport function listDropEdit(drag: Drag | undefined): FieldListEdit | undefined {\n if (drag === undefined || !removesOnDrop(drag) || drag.subject.kind !== 'entry') return undefined;\n return { layout: removeEntry(drag.layout, drag.subject.entry), against: drag.layout, moved: undefined };\n}\n\n/** Whether a drop of `drag` at `at` makes a layout whose leaves the counts bound above the cap (ADR-0370 section 3):\n * a hint from the counts, never a refusal. */\nexport function dropOverCap(drag: Drag, at: DropAt, model: Pick<FieldListModel, 'counts' | 'maxLeaves' | 'fields'>): boolean {\n const { counts, maxLeaves } = model;\n if (counts === undefined || (at.area !== 'rows' && at.area !== 'columns') || !acceptsDrag(drag, at.area)) return false;\n const bound = pivotLeafBound(dropEdit(drag, at.area, at.index, model.fields).layout, counts);\n return bound !== undefined && bound > maxLeaves;\n}\n\n/** The data a drag carries for the browser: Firefox starts a drag only with data. The pivot reads what is dragged\n * from its own state, so a drop on another pivot carries nothing it takes (ADR-0061). */\nexport function startDragData(event: DragEvent, subject: DragSubject, layout: PivotLayout): void {\n if (event.dataTransfer === null) return;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', subject.kind === 'field' ? subject.field : fieldOrValues(layout, subject.entry));\n}\n\n/** The index past an Area's last entry: \u03A3 Values, which always stands last, is not counted. */\nexport function endOf(layout: PivotLayout, area: PivotArea): number {\n return area === 'values' ? layout.values.length : placementsIn(layout, area).length;\n}\n\n/** A field's item in the list, and the parts of it a redraw changes. */\ninterface FieldItem {\n readonly item: HTMLElement;\n readonly box: HTMLInputElement;\n readonly count: HTMLElement;\n readonly filtered: HTMLElement;\n}\n\n/** Text lowered for the search as the pivot's locale lowers it, never as the host's (ADR-0370 section 10). */\nexport function lowered(text: string, locale: string): string {\n return locale === 'invariant' ? text.toLowerCase() : text.toLocaleLowerCase(locale);\n}\n\ninterface AreaElements {\n readonly area: HTMLElement;\n readonly entries: HTMLElement;\n readonly cap: HTMLElement;\n}\n\n\n/** The field a placed entry stands for. */\nexport function fieldOf(layout: PivotLayout, entry: PivotEntry): string {\n return entry.area === 'values' ? elementAt(layout.values, entry.index).field : elementAt(placementsIn(layout, entry.area), entry.index).field;\n}\n\n/** Whether two entries name the same place: an Area and an index there, or \u03A3 Values on one axis. */\nexport function sameEntry(a: PivotEntry, b: PivotEntry): boolean {\n return a.area === b.area && a.index === b.index;\n}\n\n/** The Field List of one pivot, drawn into the element it is given. */\nexport class FieldListView {\n /** The pane, which stands in the element the view was given. */\n readonly element: HTMLElement;\n readonly #root: HTMLElement;\n readonly #handlers: FieldListHandlers;\n readonly #title: HTMLElement;\n readonly #close: HTMLButtonElement;\n readonly #chooseCaption: HTMLElement;\n readonly #search: HTMLInputElement;\n readonly #list: HTMLUListElement;\n readonly #dragCaption: HTMLElement;\n readonly #defer: HTMLInputElement;\n readonly #deferCaption: HTMLElement;\n readonly #update: HTMLButtonElement;\n readonly #areas = new Map<PivotArea, AreaElements>();\n readonly #areaBoxes = new Set<HTMLElement>();\n #model: FieldListModel | undefined;\n #searchText = '';\n #drag: Drag | undefined;\n #dropAt: DropAt | undefined;\n // The elements the drag paints, by what they stand for, so a drag repaints classes and never rebuilds the\n // element the browser is dragging.\n #fieldItems = new Map<string, FieldItem>();\n #fieldsDrawnFrom: readonly PivotField[] | undefined;\n #areasDrawnFrom: { readonly layout: PivotLayout; readonly words: PivotScreenWords; readonly captions: string; readonly fields: readonly PivotField[] } | undefined;\n #entryItems: { readonly entry: PivotEntry; readonly element: HTMLElement; readonly button: HTMLButtonElement; readonly index: number }[] = [];\n\n constructor(root: HTMLElement, handlers: FieldListHandlers) {\n this.#root = root;\n this.#handlers = handlers;\n const document = root.ownerDocument;\n const pane = element(document, 'div', 'ex-pivot-pane');\n const heading = element(document, 'div', 'ex-pivot-pane-heading');\n this.#title = element(document, 'div', 'ex-pivot-pane-title');\n this.#close = element(document, 'button', 'ex-pivot-pane-close');\n this.#close.type = 'button';\n const cross = element(document, 'span');\n cross.setAttribute('aria-hidden', 'true');\n cross.textContent = '\u00D7';\n this.#close.append(cross);\n this.#close.addEventListener('click', () => { this.#handlers.close(); });\n heading.append(this.#title, this.#close);\n const body = element(document, 'div', 'ex-pivot-pane-body');\n this.#chooseCaption = element(document, 'div', 'ex-pivot-pane-caption');\n this.#search = element(document, 'input', 'ex-pivot-search');\n this.#search.type = 'search';\n // The search only narrows the list: it claims nothing of the pivot's input (ADR-0240 section 6).\n this.#search.setAttribute('data-ex-claims', '');\n this.#search.addEventListener('input', () => {\n this.#searchText = this.#search.value;\n this.#drawFields();\n });\n this.#list = element(document, 'ul', 'ex-pivot-fields');\n this.#list.addEventListener('dragover', event => { this.#acceptDrop(event); });\n this.#list.addEventListener('drop', event => {\n event.preventDefault();\n this.#dropOnList();\n });\n this.#dragCaption = element(document, 'div', 'ex-pivot-pane-caption');\n const areas = element(document, 'div', 'ex-pivot-areas');\n for (const area of areaOrder) {\n const box = element(document, 'div', 'ex-pivot-area');\n box.setAttribute('data-ex-area', area);\n const title = element(document, 'div', 'ex-pivot-area-title');\n const cap = element(document, 'div', 'ex-pivot-area-cap');\n cap.setAttribute('role', 'status');\n const entries = element(document, 'div', 'ex-pivot-area-entries');\n entries.setAttribute('role', 'list');\n box.append(title, cap, entries);\n box.addEventListener('dragover', event => { this.#acceptDrop(event); });\n box.addEventListener('dragenter', () => { this.#dragOver(area, this.#endOf(area)); });\n box.addEventListener('drop', event => {\n event.preventDefault();\n this.#drop(area, this.#endOf(area));\n });\n this.#areas.set(area, { area: box, entries, cap });\n this.#areaBoxes.add(box);\n areas.append(box);\n }\n // Excel's Defer Layout Update at the pane's foot (ADR-0061): while it is ticked, the pane's changes build a\n // pending layout, and Update applies it in one change.\n const defer = element(document, 'div', 'ex-pivot-defer');\n const deferLabel = element(document, 'label', 'ex-pivot-defer-label');\n this.#defer = element(document, 'input');\n this.#defer.type = 'checkbox';\n this.#defer.setAttribute('data-ex-claims', 'click');\n this.#defer.addEventListener('change', () => { this.#handlers.defer(this.#defer.checked); });\n this.#deferCaption = element(document, 'span');\n deferLabel.append(this.#defer, this.#deferCaption);\n this.#update = element(document, 'button', 'ex-pivot-update');\n this.#update.type = 'button';\n this.#update.setAttribute('data-ex-claims', 'click');\n this.#update.addEventListener('click', () => { this.#handlers.update(); });\n defer.append(deferLabel, this.#update);\n body.append(this.#chooseCaption, this.#search, this.#list, this.#dragCaption, areas, defer);\n pane.append(heading, body);\n root.append(pane);\n this.element = pane;\n }\n\n /** Draws `model`. A drag in progress is dropped when the layout it started on is no longer the pane's. */\n draw(model: FieldListModel): void {\n this.#model = model;\n if (this.#drag !== undefined && this.#drag.layout !== model.layout) this.#endDrag();\n const { words } = model;\n const title = words.word('field-list');\n this.#title.textContent = title;\n this.#title.title = title;\n const hide = words.word('hide-field-list');\n this.#close.setAttribute('aria-label', hide);\n this.#close.title = hide;\n this.#chooseCaption.textContent = words.word('choose-fields');\n const search = words.word('search-fields');\n this.#search.placeholder = search;\n this.#search.setAttribute('aria-label', search);\n this.#list.setAttribute('aria-label', title);\n this.#dragCaption.textContent = words.word('drag-fields');\n this.#deferCaption.textContent = words.word('defer-layout-update');\n this.#defer.checked = model.deferred;\n this.#update.textContent = words.word('update');\n this.#update.disabled = !model.canUpdate;\n this.#drawFields();\n this.#drawAreas();\n this.#placeMenu();\n this.#paintDrag();\n }\n\n /** Gives the keyboard to the button of the entry drawn at `entry`. */\n focusEntry(entry: PivotEntry): void {\n const drawn = this.#entryItems.find(item => sameEntry(item.entry, entry));\n if (drawn === undefined) throw new Error(`Internal: no entry is drawn at ${entry.area} ${entry.index}.`);\n drawn.button.focus();\n }\n\n /** Gives the keyboard to the tick box of the field named `name`; to the search when the search hides that field,\n * or when no field is named. */\n focusField(name: string | undefined): void {\n const drawn = name === undefined ? undefined : this.#fieldItems.get(name);\n if (drawn?.item.isConnected === true) drawn.box.focus();\n else this.#search.focus();\n }\n\n /** Whether a placed field is being dragged, which a drop on the report removes. */\n get removable(): boolean {\n return removesOnDrop(this.#drag);\n }\n\n /** A drag entered `target`: unless it is in an Area, which hears its own entry first, no Area is the target. */\n dragEntered(target: EventTarget | null): void {\n // A drag over text enters the text itself in some browsers: its element is what it is in.\n const entered = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n const box = entered === null ? null : entered.closest('.ex-pivot-area');\n if (box instanceof HTMLElement && this.#areaBoxes.has(box)) return;\n this.leaveTargets();\n }\n\n /** The drag is over no Area of the pane now: none is marked as its target. */\n leaveTargets(): void {\n if (this.#dropAt === undefined) return;\n this.#dropAt = undefined;\n this.#paintDrag();\n }\n\n /** A drop on the report: a placed field dragged there is removed, as Excel removes it (ADR-0061). */\n dropOnReport(): void {\n this.#dropOnList();\n }\n\n get #current(): FieldListModel {\n return defined(this.#model, 'the Field List\\'s model');\n }\n\n #drawFields(): void {\n const model = this.#current;\n const search = lowered(this.#searchText, model.locale);\n if (this.#fieldsDrawnFrom !== model.fields) {\n this.#fieldItems = new Map();\n this.#fieldsDrawnFrom = model.fields;\n }\n const items = model.fields\n .filter(field => search === '' || lowered(field.caption, model.locale).includes(search))\n .map(field => {\n // Each field keeps its elements while the source's fields are the same, and a redraw changes what\n // they say in place: the item the browser is dragging stays in the page, and the tick box the\n // user just pressed keeps the keyboard.\n let drawn = this.#fieldItems.get(field.name);\n if (drawn === undefined) {\n drawn = this.#fieldItem(field);\n this.#fieldItems.set(field.name, drawn);\n }\n const { item, box, count, filtered } = drawn;\n box.checked = placesField(model.layout, field.name);\n const counted = model.counts?.countOf(field.name);\n if (counted === undefined) {\n count.remove();\n } else {\n const written = formatPivotCount(counted, model.locale);\n count.textContent = written;\n const said = model.words.fill('field-item-count', written);\n count.title = said;\n count.setAttribute('aria-label', said);\n if (count.parentNode !== item) item.insertBefore(count, filtered.parentNode === item ? filtered : null);\n }\n const at = placementOf(model.layout, field.name);\n if (at !== undefined && elementAt(placementsIn(model.layout, at.area), at.index).hiddenItems.length > 0) {\n const word = model.words.word('filtered');\n filtered.setAttribute('aria-label', word);\n filtered.title = word;\n if (filtered.parentNode !== item) item.append(filtered);\n } else {\n filtered.remove();\n }\n return item;\n });\n if (items.length !== this.#list.children.length || items.some((item, i) => this.#list.children[i] !== item)) {\n this.#list.replaceChildren(...items);\n }\n }\n\n #fieldItem(field: PivotField): FieldItem {\n const document = this.#root.ownerDocument;\n const item = element(document, 'li', 'ex-pivot-field');\n item.draggable = true;\n item.setAttribute('data-ex-field', field.name);\n const label = element(document, 'label', 'ex-pivot-field-label');\n const box = element(document, 'input');\n box.type = 'checkbox';\n box.setAttribute('data-ex-claims', 'click');\n box.addEventListener('change', () => { this.#tick(field); });\n const caption = element(document, 'span', 'ex-pivot-field-caption');\n caption.textContent = field.caption;\n label.append(box, caption);\n item.append(label);\n const filtered = element(document, 'span', 'ex-pivot-filtered-mark');\n filtered.setAttribute('role', 'img');\n item.addEventListener('dragstart', event => { this.#startDrag(event, { kind: 'field', field: field.name }); });\n item.addEventListener('dragend', () => { this.#endDrag(); });\n return { item, box, count: element(document, 'span', 'ex-pivot-field-count'), filtered };\n }\n\n #drawAreas(): void {\n const model = this.#current;\n const { layout, words } = model;\n // The entries are what the layout, the words and the captions make; drawn again only when one of them\n // changed, so a redraw while an entry is dragged keeps the element the browser is dragging.\n const drawnFrom = { layout, words, captions: model.valueCaptions.join('\\n'), fields: model.fields };\n const last = this.#areasDrawnFrom;\n if (last !== undefined && last.layout === layout && last.words === words && last.captions === drawnFrom.captions && last.fields === model.fields) return;\n this.#areasDrawnFrom = drawnFrom;\n const document = this.#root.ownerDocument;\n this.#entryItems = [];\n for (const area of areaOrder) {\n const { area: box, entries } = defined(this.#areas.get(area), 'an Area\\'s box');\n const title = words.area(area);\n elementAt([...box.children], 0).textContent = title;\n entries.setAttribute('aria-label', title);\n const drawn: HTMLElement[] = [];\n const end = this.#endOf(area);\n const add = (entry: PivotEntry, caption: string, filtered: boolean): void => {\n const index = isValuesPseudoField(entry) ? end : entry.index;\n const item = element(document, 'div', isValuesPseudoField(entry) ? 'ex-pivot-entry ex-pivot-entry-values' : 'ex-pivot-entry');\n item.setAttribute('role', 'listitem');\n item.draggable = true;\n const button = element(document, 'button', 'ex-pivot-entry-button');\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.setAttribute('aria-haspopup', 'menu');\n button.setAttribute('aria-label', words.fill('field-menu', caption));\n button.addEventListener('click', () => { this.#handlers.menu(entry); });\n const text = element(document, 'span', 'ex-pivot-entry-caption');\n text.textContent = caption;\n button.append(text);\n if (filtered) {\n const mark = element(document, 'span', 'ex-pivot-filtered-mark');\n mark.setAttribute('aria-hidden', 'true');\n button.append(mark);\n }\n const arrow = element(document, 'span', 'ex-pivot-entry-arrow');\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n button.append(arrow);\n item.append(button);\n item.addEventListener('dragstart', event => { this.#startDrag(event, { kind: 'entry', entry }); });\n item.addEventListener('dragend', () => { this.#endDrag(); });\n item.addEventListener('dragenter', event => {\n event.stopPropagation();\n this.#dragOver(area, index);\n });\n item.addEventListener('dragover', event => { this.#acceptDrop(event); });\n item.addEventListener('drop', event => {\n event.preventDefault();\n event.stopPropagation();\n this.#drop(area, index);\n });\n this.#entryItems.push({ entry, element: item, button, index });\n drawn.push(item);\n };\n if (area === 'values') {\n layout.values.forEach((_, i) => { add({ area, index: i }, elementAt(model.valueCaptions, i), false); });\n } else {\n placementsIn(layout, area).forEach((placement, i) => {\n const field = model.fields.find(f => f.name === placement.field);\n add({ area, index: i }, defined(field, `the field '${placement.field}'`).caption, placement.hiddenItems.length > 0);\n });\n if (layout.values.length >= 2 && area === (layout.valuesAxis === 'rows' ? 'rows' : 'columns')) {\n add(valuesPseudoField(layout.valuesAxis), words.word('values-pseudo-field'), false);\n }\n }\n entries.replaceChildren(...drawn);\n }\n }\n\n // The open field menu stands under its entry, in the flow, as wide as the pane (ADR-0061); every other entry's\n // button says its menu is closed.\n #placeMenu(): void {\n const { popup: menu } = this.#current;\n for (const { entry, element: item, button } of this.#entryItems) {\n const open = menu !== undefined && sameEntry(menu.entry, entry);\n button.setAttribute('aria-expanded', open ? 'true' : 'false');\n // While a menu or a panel stands under the entry, a press that moves a little on it is a command's, or\n // selects text in a field, never a drag of the entry.\n item.draggable = !open;\n if (open && menu.frame.parentNode !== item) {\n // The entries were drawn again under it: the command that held the keyboard keeps it.\n const held = item.ownerDocument.activeElement;\n item.append(menu.frame);\n if (held instanceof HTMLElement && menu.frame.contains(held) && held !== item.ownerDocument.activeElement) held.focus();\n }\n }\n }\n\n // The index past an Area's last entry: \u03A3 Values, which always stands last, is not counted.\n #endOf(area: PivotArea): number {\n return endOf(this.#current.layout, area);\n }\n\n #tick(field: PivotField): void {\n this.#handlers.edit(tickEdit(this.#current.layout, field));\n }\n\n #startDrag(event: DragEvent, subject: DragSubject): void {\n const layout = this.#current.layout;\n this.#drag = { subject, layout };\n this.#dropAt = undefined;\n startDragData(event, subject, layout);\n this.#paintDrag();\n this.#handlers.dragging(this.removable);\n }\n\n #endDrag(): void {\n if (this.#drag === undefined && this.#dropAt === undefined) return;\n this.#drag = undefined;\n this.#dropAt = undefined;\n this.#paintDrag();\n this.#handlers.dragging(false);\n }\n\n #accepts(area: PivotArea): boolean {\n return this.#drag !== undefined && acceptsDrag(this.#drag, area);\n }\n\n #acceptDrop(event: DragEvent): void {\n if (this.#drag === undefined) return;\n event.preventDefault();\n if (event.dataTransfer !== null) event.dataTransfer.dropEffect = 'move';\n }\n\n #dragOver(area: PivotArea, index: number): void {\n if (this.#drag === undefined) return;\n if (this.#dropAt?.area === area && this.#dropAt.index === index) return;\n this.#dropAt = { area, index };\n this.#paintDrag();\n }\n\n #drop(area: PivotArea, index: number): void {\n const drag = this.#drag;\n this.#endDrag();\n if (drag === undefined || !acceptsDrag(drag, area)) return;\n this.#handlers.edit(dropEdit(drag, area, index, this.#current.fields));\n }\n\n #dropOnList(): void {\n const drag = this.#drag;\n this.#endDrag();\n const edit = listDropEdit(drag);\n if (edit !== undefined) this.#handlers.edit(edit);\n }\n\n // The drag's marks, as classes on the elements drawn: never a rebuild, which would take away the element\n // the browser is dragging.\n #paintDrag(): void {\n const drag = this.#drag;\n const at = this.#dropAt;\n const model = this.#model;\n for (const [name, { item }] of this.#fieldItems) {\n item.classList.toggle('ex-pivot-dragging', drag?.subject.kind === 'field' && drag.subject.field === name);\n }\n for (const { entry, element: item, index } of this.#entryItems) {\n const dragged = drag?.subject.kind === 'entry' && sameEntry(drag.subject.entry, entry);\n item.classList.toggle('ex-pivot-dragging', dragged);\n item.classList.toggle('ex-pivot-drop-before', at !== undefined && this.#accepts(at.area) && at.area === entry.area && at.index === index);\n }\n const over = drag !== undefined && at !== undefined && model !== undefined && dropOverCap(drag, at, model);\n for (const [area, { area: box, cap }] of this.#areas) {\n const target = at !== undefined && at.area === area && this.#accepts(area);\n box.classList.toggle('ex-pivot-drop-target', target);\n box.classList.toggle('ex-pivot-drop-over-cap', target && over);\n const said = target && over ? model.words.fill('drop-over-cap', formatPivotCount(model.maxLeaves, model.locale)) : '';\n if (cap.textContent !== said) cap.textContent = said;\n }\n this.#list.classList.toggle('ex-pivot-drop-remove', this.removable);\n }\n}\n\nfunction fieldOrValues(layout: PivotLayout, entry: PivotEntry): string {\n return isValuesPseudoField(entry) ? 'values' : fieldOf(layout, entry);\n}\n", "// The Field List a Chrome's slot draws (ADR-0061, ADR-0390): Excel's PivotTable Fields pane, drawn from the view the\n// pivot makes of the layout it is handed. What each gesture means is the built-in pane's rules (`field-list.ts`),\n// so the layout a tick, a drop or a drag back makes is the same whichever draws the pane; whether that layout is\n// still the pane's is the pivot's to judge (spine rule 6). The contents hand in their controls, the anchors under\n// the entries and the Areas' boxes; the pivot places an entry's menu or panel in its anchor and gives the keyboard to\n// the control it means.\n\nimport { formatPivotCount, isValuesPseudoField, placementOf, placementsIn, placesField, valuesPseudoField, type PivotArea, type PivotEntry } from '@ex-grid/pivot-engine';\nimport type {\n PivotChromeSlot, PivotDragSubject, PivotFieldListAreaView, PivotFieldListEntryView, PivotFieldListFieldView, PivotFieldListSlotContext, PivotFieldListView,\n PivotPartRef, PivotStandingSlotContext,\n} from './chrome';\nimport { StandingSlot } from './chrome';\nimport {\n acceptsDrag, areaOrder, dropEdit, dropOverCap, endOf, listDropEdit, lowered, removesOnDrop, sameEntry, startDragData, tickEdit, type Drag, type DropAt,\n type FieldListHandlers, type FieldListModel,\n} from './field-list';\nimport { defined, elementAt } from './must';\nimport { cachedRef, elementRef, type PartElements } from './parts';\n\n/** The name an entry's button and the anchor around it are handed in by. */\nexport function entryKey(entry: PivotEntry): string {\n return `entry:${entry.area}:${entry.index}`;\n}\n\n/** The name a field's tick box is handed in by. */\nexport function fieldKey(field: string): string {\n return `field:${field}`;\n}\n\nconst emptyView: PivotFieldListView = Object.freeze({\n title: '', hideLabel: '', chooseCaption: '', searchLabel: '', search: '', fields: Object.freeze([]), dragCaption: '', areas: Object.freeze([]),\n dropRemoves: false, defer: Object.freeze({ label: '', ticked: false }), update: Object.freeze({ label: '', enabled: false }),\n});\n\n/** The Field List of one pivot, drawn by a Chrome's slot. */\nexport class SlottedFieldList {\n readonly #slot: StandingSlot<PivotFieldListView, PivotFieldListSlotContext>;\n readonly #handlers: FieldListHandlers;\n readonly #parts: PartElements;\n readonly #areaBoxes = new Map<PivotArea, HTMLElement>();\n #model: FieldListModel | undefined;\n #searchText = '';\n #drag: Drag | undefined;\n #dropAt: DropAt | undefined;\n\n constructor(document: Document, handlers: FieldListHandlers, parts: PartElements) {\n this.#slot = new StandingSlot('fieldList', document, emptyView);\n // The slot draws nothing (`display: contents`): the contents' pane takes the Field List's height as its own.\n this.#slot.element.setAttribute('style', 'display: contents');\n this.#handlers = handlers;\n this.#parts = parts;\n }\n\n /** The slot, which the pivot stands in the pane's place. */\n get element(): HTMLElement {\n return this.#slot.element;\n }\n\n /** Shows the pane by `mount`; answers as the slot does. */\n show(mount: PivotChromeSlot<PivotFieldListSlotContext>, label: (id: string) => string): { readonly shown: boolean; readonly error?: Error } {\n // A drag the contents before these started reaches nothing once they are gone: no dragend is heard from them.\n if (!this.#slot.stands(mount)) {\n this.#drag = undefined;\n this.#dropAt = undefined;\n }\n return this.#slot.show(mount, (shared, input) => this.#context(shared, input), label);\n }\n\n // The context of one mount of the contents, whose controls, anchors and Areas' boxes are handed in by refs of\n // its own.\n #context(shared: PivotStandingSlotContext<PivotFieldListView>, input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void): PivotFieldListSlotContext {\n const refs = this.#parts.refs();\n const areas = new Map<PivotArea, PivotPartRef>();\n return {\n ...shared,\n setSearch: input((text: string) => {\n if (typeof text !== 'string') throw new TypeError('An ExPivot\\'s Field List takes the search as typed, a string (ADR-0390).');\n this.#searchText = text;\n this.#tell();\n }),\n toggle: input((field: string) => {\n const model = this.#current;\n const declared = model.fields.find(f => f.name === field);\n if (declared === undefined) throw new RangeError(`The Field List has no field '${field}' to tick (ADR-0390).`);\n this.#handlers.edit(tickEdit(model.layout, declared));\n }),\n openMenu: input((entry: PivotEntry) => { if (this.#stands(entry)) this.#handlers.menu(entry); }),\n close: input(() => { this.#handlers.close(); }),\n startDrag: input((event: DragEvent, subject: PivotDragSubject) => { this.#startDrag(event, subject); }),\n dragOver: input((event: DragEvent) => {\n if (this.#drag === undefined) return;\n event.preventDefault();\n if (event.dataTransfer !== null) event.dataTransfer.dropEffect = 'move';\n }),\n dragEnter: input((area: PivotArea, index: number) => {\n if (this.#drag === undefined || (this.#dropAt?.area === area && this.#dropAt.index === index)) return;\n this.#dropAt = { area: checkedArea(area), index: checkedIndex(index) };\n this.#tell();\n }),\n drop: input((event: DragEvent, area: PivotArea, index: number) => {\n event.preventDefault();\n const drag = this.#drag;\n this.#endDrag();\n if (drag === undefined || !acceptsDrag(drag, checkedArea(area))) return;\n this.#handlers.edit(dropEdit(drag, area, checkedIndex(index), this.#current.fields));\n }),\n dropOnList: input((event: DragEvent) => {\n event.preventDefault();\n this.dropOnReport();\n }),\n endDrag: input(() => { this.#endDrag(); }),\n setDeferred: input((deferred: boolean) => {\n if (typeof deferred !== 'boolean') throw new TypeError('Defer Layout Update is handed whether it is ticked (ADR-0390).');\n this.#handlers.defer(deferred);\n }),\n update: input(() => { if (this.#slot.view.update.enabled) this.#handlers.update(); }),\n control: (key: string) => refs.control(checkedKey(key)),\n anchor: (key: string) => refs.anchor(checkedKey(key)),\n area: (area: PivotArea) => cachedRef(areas, checkedArea(area), () => elementRef(this.#areaBoxes, area, `An ExPivot's Field List's box of '${area}'`)),\n };\n }\n\n /** The pane is the built-in one's, or gone: the contents are taken away, and a drag they started with them. */\n hide(): void {\n this.#slot.hide();\n this.#drag = undefined;\n this.#dropAt = undefined;\n }\n\n /** Draws `model`. A drag in progress is dropped when the layout it started on is no longer the pane's. */\n draw(model: FieldListModel): void {\n this.#model = model;\n if (this.#drag !== undefined && this.#drag.layout !== model.layout) this.#endDrag();\n if (model.popup !== undefined) this.#parts.place(entryKey(model.popup.entry), model.popup.frame);\n this.#tell();\n }\n\n /** Gives the keyboard to the button of the entry drawn at `entry`. */\n focusEntry(entry: PivotEntry): void {\n this.#parts.focus(entryKey(entry));\n }\n\n /** Gives the keyboard to the tick box of the field named `name`; to the search when the search hides that field,\n * or when no field is named. */\n focusField(name: string | undefined): void {\n const shown = name !== undefined && this.#slot.view.fields.some(field => field.name === name);\n this.#parts.focus(shown ? fieldKey(name) : 'search');\n }\n\n /** Whether a placed field is being dragged, which a drop on the report removes. */\n get removable(): boolean {\n return removesOnDrop(this.#drag);\n }\n\n /** A drag entered `target`: unless it is in an Area, which hears its own entry first, no Area is the target. */\n dragEntered(target: EventTarget | null): void {\n const entered = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n for (const box of this.#areaBoxes.values()) {\n if (entered !== null && box.contains(entered)) return;\n }\n this.leaveTargets();\n }\n\n /** The drag is over no Area of the pane now: none is marked as its target. */\n leaveTargets(): void {\n if (this.#dropAt === undefined) return;\n this.#dropAt = undefined;\n this.#tell();\n }\n\n /** A drop on the report, or on the list of fields: a placed field dragged there is removed, as Excel removes it. */\n dropOnReport(): void {\n const drag = this.#drag;\n this.#endDrag();\n const edit = listDropEdit(drag);\n if (edit !== undefined) this.#handlers.edit(edit);\n }\n\n get #current(): FieldListModel {\n return defined(this.#model, 'the Field List\\'s model');\n }\n\n // Whether `entry` stands in the pane's layout now: a press on an entry the pane has since left asks nothing.\n #stands(entry: PivotEntry): boolean {\n const layout = this.#current.layout;\n if (isValuesPseudoField(entry)) return layout.values.length >= 2 && sameEntry(entry, valuesPseudoField(layout.valuesAxis));\n return entry.index >= 0 && entry.index < endOf(layout, entry.area);\n }\n\n #startDrag(event: DragEvent, subject: PivotDragSubject): void {\n const layout = this.#current.layout;\n const drag: Drag = 'field' in subject\n ? { subject: { kind: 'field', field: subject.field }, layout }\n : { subject: { kind: 'entry', entry: subject.entry }, layout };\n if (drag.subject.kind === 'entry' && !this.#stands(drag.subject.entry)) return;\n this.#drag = drag;\n this.#dropAt = undefined;\n startDragData(event, drag.subject, layout);\n this.#tell();\n this.#handlers.dragging(this.removable);\n }\n\n #endDrag(): void {\n if (this.#drag === undefined && this.#dropAt === undefined) return;\n this.#drag = undefined;\n this.#dropAt = undefined;\n this.#tell();\n this.#handlers.dragging(false);\n }\n\n #tell(): void {\n if (this.#model !== undefined) this.#slot.viewOf(this.#view(this.#model));\n }\n\n #view(model: FieldListModel): PivotFieldListView {\n const { layout, words, locale } = model;\n const drag = this.#drag;\n const at = this.#dropAt;\n const search = lowered(this.#searchText, locale);\n const fields = model.fields\n .filter(field => search === '' || lowered(field.caption, locale).includes(search))\n .map((field): PivotFieldListFieldView => {\n const counted = model.counts?.countOf(field.name);\n const written = counted === undefined ? undefined : formatPivotCount(counted, locale);\n const placed = placementOf(layout, field.name);\n return Object.freeze({\n name: field.name,\n caption: field.caption,\n key: fieldKey(field.name),\n placed: placesField(layout, field.name),\n filtered: placed !== undefined && elementAt(placementsIn(layout, placed.area), placed.index).hiddenItems.length > 0,\n ...(written === undefined ? {} : { count: written, countLabel: words.fill('field-item-count', written) }),\n dragging: drag?.subject.kind === 'field' && drag.subject.field === field.name,\n });\n });\n const over = drag !== undefined && at !== undefined && dropOverCap(drag, at, model);\n const areas = areaOrder.map((area): PivotFieldListAreaView => {\n const target = drag !== undefined && at !== undefined && at.area === area && acceptsDrag(drag, area);\n return Object.freeze({\n area,\n title: words.area(area),\n entries: Object.freeze(this.#entries(model, area)),\n end: endOf(layout, area),\n dropTarget: target,\n ...(target && over ? { overCap: words.fill('drop-over-cap', formatPivotCount(model.maxLeaves, locale)) } : {}),\n });\n });\n return Object.freeze({\n title: words.word('field-list'),\n hideLabel: words.word('hide-field-list'),\n chooseCaption: words.word('choose-fields'),\n searchLabel: words.word('search-fields'),\n search: this.#searchText,\n fields: Object.freeze(fields),\n dragCaption: words.word('drag-fields'),\n areas: Object.freeze(areas),\n dropRemoves: this.removable,\n defer: Object.freeze({ label: words.word('defer-layout-update'), ticked: model.deferred }),\n update: Object.freeze({ label: words.word('update'), enabled: model.canUpdate }),\n });\n }\n\n #entries(model: FieldListModel, area: PivotArea): PivotFieldListEntryView[] {\n const { layout, words, popup } = model;\n const drag = this.#drag;\n const at = this.#dropAt;\n const end = endOf(layout, area);\n const entry = (placed: PivotEntry, caption: string, filtered: boolean): PivotFieldListEntryView => {\n const index = isValuesPseudoField(placed) ? end : placed.index;\n return Object.freeze({\n entry: placed,\n key: entryKey(placed),\n caption,\n menuLabel: words.fill('field-menu', caption),\n filtered,\n values: isValuesPseudoField(placed),\n menuOpen: popup !== undefined && sameEntry(popup.entry, placed),\n dragging: drag?.subject.kind === 'entry' && sameEntry(drag.subject.entry, placed),\n dropBefore: drag !== undefined && at !== undefined && acceptsDrag(drag, at.area) && at.area === area && at.index === index,\n dropIndex: index,\n });\n };\n if (area === 'values') return layout.values.map((_, i) => entry({ area, index: i }, elementAt(model.valueCaptions, i), false));\n const entries = placementsIn(layout, area).map((placement, i) => {\n const field = defined(model.fields.find(f => f.name === placement.field), `the field '${placement.field}'`);\n return entry({ area, index: i }, field.caption, placement.hiddenItems.length > 0);\n });\n if (layout.values.length >= 2 && area === (layout.valuesAxis === 'rows' ? 'rows' : 'columns')) {\n entries.push(entry(valuesPseudoField(layout.valuesAxis), words.word('values-pseudo-field'), false));\n }\n return entries;\n }\n}\n\n// An Area, as a script may hand it.\nfunction checkedArea(area: PivotArea): PivotArea {\n if (!areaOrder.includes(area)) throw new RangeError(`An ExPivot's Field List has the Areas ${areaOrder.join(', ')}, not '${area}' (ADR-0390).`);\n return area;\n}\n\n// An index a drop lands before, as a script may hand it: a whole number, zero or more.\nfunction checkedIndex(index: number): number {\n if (!Number.isInteger(index) || index < 0) throw new RangeError(`A drop in an ExPivot's Field List lands before an entry's index, a whole number from 0, not ${index} (ADR-0390).`);\n return index;\n}\n\n// A name a control or an anchor is handed in by, as a script may hand it.\nfunction checkedKey(key: string): string {\n const given: unknown = key;\n if (typeof given !== 'string' || given === '') throw new TypeError('An ExPivot\\'s Field List hands in a control or an anchor by the name its view gives it (ADR-0390).');\n return given;\n}\n", "// Filter\u2026 (ADR-0061): a field's Items, each ticked while shown, (Select All), a search that narrows the list, and\n// OK / Cancel, in the markup and under the classes the Razor component's PivotItemFilterView draws, so one stylesheet\n// paints both (ADR-0350 section 4). The ticks are the panel's draft. The Items are the source's, listed under the\n// report's Source Version (ADR-0066); while a first listing is on its way the panel says so, and when the source\n// cannot list them it says why, never an empty list in its place. While a new version's Items are on their way, the\n// earlier version's stay listed and the list is marked busy: Hidden Items are keys, which name the same Items under\n// any version, so ticking and applying against them is safe (ADR-0066 refined).\n//\n// The search narrows the Items held, as the pivot's locale lowers text; past the Items Filter\u2026 holds, only the\n// source can answer it, and the answer to a search typed since is dropped.\n\nimport {\n formatPivotCount, pivotItemKeyId, placementOf, placementsIn, refusalWord, setHiddenItems, type PivotItemInfo, type PivotItemKey, type PivotLayout,\n type PivotReportItemsResult,\n} from '@ex-grid/pivot-engine';\nimport { lowered } from './field-list';\nimport { itemListCap, type FieldItems, type ItemsProblem } from './items';\nimport { ViewListeners, type PivotChromeSlot, type PivotItemFilterSlotContext, type PivotItemFilterView } from './chrome';\nimport { popupFrame, type PivotMenuPlace } from './menu';\nimport { defined, elementAt } from './must';\nimport { actions, element, slottedPanel, type PanelDraft, type PanelHandlers, type PivotPanel } from './panels';\nimport type { PivotScreenWords } from './words';\n\n/** What Filter\u2026 is opened on. */\nexport interface ItemFilterModel {\n /** The layout OK's change is taken against. */\n readonly layout: PivotLayout;\n readonly field: string;\n readonly caption: string;\n /** Where it stands: under the field's entry in the Field List, or under its button in the report filter band. */\n readonly place: PivotMenuPlace;\n /** The locale the search lowers text in, and the count in the note is written in. */\n readonly locale: string;\n readonly words: PivotScreenWords;\n}\n\n/** Whom Filter\u2026 calls back: OK and Cancel, the field's Items, and the source's search past the Items held. */\nexport interface ItemFilterHandlers extends PanelHandlers {\n /** The field's Items as they stand now: the same object while they have not changed. */\n readonly items: () => FieldItems;\n /** The Items matching `search`, asked of the source under the report on screen. */\n readonly search: (search: string, signal: AbortSignal) => Promise<PivotReportItemsResult>;\n}\n\n/** What the source answered for a search: the Items, why it could not, or nothing yet. */\ntype Found = { readonly listed: PivotReportItemsResult } | { readonly problem: ItemsProblem } | 'asked';\n\ninterface Search {\n readonly text: string;\n // The listing it searched past, so a newer listing searches again.\n readonly under: FieldItems['listed'];\n readonly controller: AbortController;\n found: Found;\n}\n\ninterface DrawnItem {\n readonly row: HTMLLabelElement;\n readonly box: HTMLInputElement;\n readonly text: HTMLSpanElement;\n}\n\n/** The sentence for a source's refusal or failure to list Items, as the Razor component's ProblemText says it. */\nexport function itemsProblemText(problem: ItemsProblem, words: PivotScreenWords): string {\n if ('error' in problem) return words.failed(problem.error);\n return words.reportRefused(problem.refusal);\n}\n\n/** Filter\u2026' draft: the ticks and the search, and the source's answer to a search past the Items held. It is drawn\n * again by the pivot as the field's Items land, and by the built-in markup and a Chrome's slot alike. */\nexport class ItemFilterDraft implements PanelDraft<PivotItemFilterView> {\n readonly listeners = new ViewListeners();\n readonly #model: ItemFilterModel;\n readonly #handlers: ItemFilterHandlers;\n // The draft: the Items unticked, by key id.\n readonly #hidden = new Map<string, PivotItemKey>();\n #text = '';\n #items: FieldItems;\n #search: Search | undefined;\n #refusal: string | undefined;\n #closed = false;\n // What a press of (Select All) or OK acts on: the Items listed now, and those held.\n #listed: readonly PivotItemInfo[] = [];\n #held: readonly PivotItemInfo[] = [];\n // Each Item's key id and lowered label, worked out once while its listing is in view: a draw on every key typed\n // and every tick reads them for every Item.\n readonly #ids = new WeakMap<PivotItemInfo, string>();\n readonly #labels = new WeakMap<PivotItemInfo, string>();\n #allHeld = true;\n #view: PivotItemFilterView;\n\n constructor(model: ItemFilterModel, handlers: ItemFilterHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n for (const key of placementHidden(model.layout, model.field)) this.#hidden.set(pivotItemKeyId(key), key);\n this.#items = handlers.items();\n this.#view = this.#compute();\n }\n\n get view(): PivotItemFilterView {\n return this.#view;\n }\n\n /** Each listed Item's key id, by its place in the view's `items`. */\n idAt(index: number): string {\n return this.#idOf(elementAt(this.#listed, index));\n }\n\n setSearch(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setSearch is handed the search as typed.');\n this.#text = text;\n this.#refusal = undefined;\n this.#render();\n }\n\n setTicked(key: PivotItemKey, ticked: boolean): void {\n if (typeof ticked !== 'boolean') throw new TypeError('setTicked is handed the Item and whether it is ticked.');\n const id = pivotItemKeyId(key);\n // Only an Item the panel lists now is ticked: a press on one a newer listing took away names nothing the user\n // sees, and changes nothing (spine rule 6).\n if (!this.#listed.some(item => this.#idOf(item) === id)) return;\n this.#tick(key, ticked);\n this.#refusal = undefined;\n this.#render();\n }\n\n setAll(ticked: boolean): void {\n if (typeof ticked !== 'boolean') throw new TypeError('setAll is handed whether every Item listed is ticked.');\n for (const item of this.#listed) this.#tick(item.key, ticked);\n this.#refusal = undefined;\n this.#render();\n }\n\n /** Draws the field's Items again, when they have changed. */\n redraw(): void {\n const items = this.#handlers.items();\n if (items === this.#items) return;\n this.#items = items;\n this.#render();\n }\n\n /** Stops a search on its way: the panel has closed. */\n close(): void {\n this.#closed = true;\n this.#search?.controller.abort();\n this.#search = undefined;\n this.listeners.clear();\n }\n\n apply(): void {\n if (!this.#view.canApply) return;\n const { layout, field, words } = this.#model;\n // With more Items than Filter\u2026 holds, that every one is unticked cannot be told, and nothing is refused for\n // it: the rule needs every Item (ADR-0060).\n const result = setHiddenItems(layout, field, this.#hidden.values(), this.#allHeld ? this.#held.map(item => item.key) : []);\n if (result.refusal !== undefined) {\n this.#refusal = words.word(refusalWord(result.refusal));\n this.#render();\n return;\n }\n const before = new Set(placementHidden(layout, field).map(key => pivotItemKeyId(key)));\n const after = placementHidden(result.layout, field).map(key => pivotItemKeyId(key));\n if (after.length === before.size && after.every(id => before.has(id))) {\n this.#handlers.cancel();\n return;\n }\n this.#handlers.apply(result.layout);\n }\n\n #idOf(item: PivotItemInfo): string {\n let id = this.#ids.get(item);\n if (id === undefined) {\n id = pivotItemKeyId(item.key);\n this.#ids.set(item, id);\n }\n return id;\n }\n\n #loweredLabel(item: PivotItemInfo): string {\n let label = this.#labels.get(item);\n if (label === undefined) {\n label = lowered(item.label, this.#model.locale);\n this.#labels.set(item, label);\n }\n return label;\n }\n\n #tick(key: PivotItemKey, tick: boolean): void {\n const id = pivotItemKeyId(key);\n if (tick) this.#hidden.delete(id);\n else this.#hidden.set(id, key);\n }\n\n // The source's answer for the search typed, past the Items held; asked again for a newer listing.\n #found(text: string, under: FieldItems['listed']): Found {\n const search = this.#search;\n if (search?.text === text && search.under === under) return search.found;\n search?.controller.abort();\n const asked: Search = { text, under, controller: new AbortController(), found: 'asked' };\n this.#search = asked;\n void this.#ask(asked);\n return asked.found;\n }\n\n async #ask(asked: Search): Promise<void> {\n let listed;\n try {\n listed = await this.#handlers.search(asked.text, asked.controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a search typed over, or of a panel closed, is nobody's; the current one's failure is said in the panel and rethrown\n if (this.#search !== asked) return;\n asked.found = Object.freeze({ problem: Object.freeze({ error }) });\n this.#render();\n throw error;\n }\n if (this.#search !== asked) return;\n asked.found = Object.freeze(listed.refusal === undefined ? { listed } : { problem: Object.freeze({ refusal: listed.refusal }) });\n this.#render();\n }\n\n #render(): void {\n if (this.#closed) return;\n this.#view = this.#compute();\n this.listeners.tell();\n }\n\n #compute(): PivotItemFilterView {\n const { words, locale } = this.#model;\n const items = this.#items;\n const text = this.#text;\n let loading = items.listed === undefined && items.problem === undefined;\n let problem = items.problem;\n let matches: readonly PivotItemInfo[] = [];\n let matchCount = 0;\n const page = items.listed;\n this.#allHeld = page === undefined || page.total <= page.items.length;\n if (page !== undefined && !this.#allHeld && text !== '') {\n // More Items than Filter\u2026 holds: the search is the source's to answer.\n const found = this.#found(text, page);\n if (found === 'asked') loading = true;\n else if ('problem' in found) problem = found.problem;\n else {\n matches = found.listed.items;\n matchCount = found.listed.total;\n }\n } else if (page !== undefined) {\n this.#search?.controller.abort();\n this.#search = undefined;\n const search = lowered(text, locale);\n matches = search === '' ? page.items : page.items.filter(item => this.#loweredLabel(item).includes(search));\n matchCount = search === '' ? page.total : matches.length;\n }\n const listed = matches.slice(0, itemListCap);\n this.#listed = listed;\n // The Items in view, an earlier version's while the report's are on their way (ADR-0066 refined).\n this.#held = page === undefined ? [] : page.items;\n const unavailable = problem === undefined ? undefined : itemsProblemText(problem, words);\n const canApply = !loading && unavailable === undefined\n && (!this.#allHeld || this.#held.length === 0 || this.#held.some(item => !this.#hidden.has(this.#idOf(item))));\n const shown = unavailable === undefined && !loading;\n const choices = shown\n ? listed.map(item => Object.freeze({ key: item.key, label: item.label, ticked: !this.#hidden.has(this.#idOf(item)) }))\n : [];\n const ticked = choices.filter(choice => choice.ticked).length;\n const note = !shown ? undefined\n : matchCount > listed.length ? words.fill('too-many-items', formatPivotCount(itemListCap, locale))\n : listed.length === 0 ? words.word('no-items-match')\n : undefined;\n const refusal = this.#refusal ?? (canApply || loading || unavailable !== undefined ? undefined : words.word('refused-hides-every-item'));\n return Object.freeze({\n caption: this.#model.caption,\n search: text,\n items: Object.freeze(choices),\n allTicked: ticked === 0 ? false : ticked === choices.length ? true : undefined,\n loading,\n updating: items.pending && !loading,\n canApply,\n ...(unavailable === undefined ? {} : { unavailable }),\n ...(note === undefined ? {} : { note }),\n ...(refusal === undefined ? {} : { refusal }),\n });\n }\n}\n\n/** Filter\u2026, drawn by `mount` where a Chrome gives one: drawn again by the pivot as the field's Items land. */\nexport function itemFilterPanel(document: Document, model: ItemFilterModel, handlers: ItemFilterHandlers,\n mount?: PivotChromeSlot<PivotItemFilterSlotContext>): PivotPanel {\n const draft = new ItemFilterDraft(model, handlers);\n const label = model.words.fill('filter-of', model.caption);\n if (mount === undefined) return new ItemFilterPanel(document, model, handlers, draft, label);\n return slottedPanel(document, label, model.place, 'itemFilter', mount, draft, handlers.cancel, model.words, input => ({\n setSearch: input((text: string) => { draft.setSearch(text); }),\n setTicked: input((key: PivotItemKey, ticked: boolean) => { draft.setTicked(key, ticked); }),\n setAll: input((ticked: boolean) => { draft.setAll(ticked); }),\n }), () => { draft.redraw(); }, () => { draft.close(); });\n}\n\n/** The built-in Filter\u2026, drawn from its draft. */\nclass ItemFilterPanel implements PivotPanel {\n /** Its frame, which the pivot places. */\n readonly element: HTMLDivElement;\n readonly #draft: ItemFilterDraft;\n readonly #searchBox: HTMLInputElement;\n readonly #list: HTMLDivElement;\n readonly #selectAll: DrawnItem;\n // The notes the list shows in place of Items, or under them; each made once, so drawing again moves nothing.\n readonly #unavailable: HTMLDivElement;\n readonly #loading: HTMLDivElement;\n readonly #note: HTMLDivElement;\n readonly #refusalBox: HTMLDivElement;\n readonly #ok: HTMLButtonElement;\n readonly #drawn = new Map<string, DrawnItem>();\n\n constructor(document: Document, model: ItemFilterModel, handlers: ItemFilterHandlers, draft: ItemFilterDraft, label: string) {\n this.#draft = draft;\n const { words } = model;\n this.element = popupFrame(document, model.place, 'dialog', handlers.cancel);\n this.element.setAttribute('aria-label', label);\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-item-filter');\n this.#searchBox = element(document, 'input', 'ex-pivot-search');\n this.#searchBox.type = 'search';\n this.#searchBox.placeholder = words.word('search-items');\n this.#searchBox.setAttribute('aria-label', words.word('search-items'));\n this.#searchBox.addEventListener('input', () => { draft.setSearch(this.#searchBox.value); });\n this.#list = element(document, 'div', 'ex-pivot-item-list');\n this.#list.setAttribute('role', 'group');\n this.#list.setAttribute('aria-label', model.caption);\n this.#selectAll = this.#item(document, 'ex-pivot-item ex-pivot-select-all', tick => { draft.setAll(tick); });\n this.#selectAll.text.textContent = words.word('select-all');\n this.#unavailable = element(document, 'div', 'ex-pivot-refusal ex-pivot-unavailable');\n this.#unavailable.setAttribute('role', 'alert');\n this.#loading = element(document, 'div', 'ex-pivot-note ex-pivot-loading');\n this.#loading.setAttribute('role', 'status');\n this.#loading.textContent = words.word('loading');\n this.#note = element(document, 'div', 'ex-pivot-note');\n this.#refusalBox = element(document, 'div', 'ex-pivot-refusal');\n this.#refusalBox.setAttribute('role', 'alert');\n const exits = actions(document, words, () => { draft.apply(); }, handlers.cancel);\n this.#ok = exits.ok;\n panel.append(this.#searchBox, this.#list, exits.box);\n this.element.append(panel);\n draft.listeners.subscribe(() => { this.#render(); });\n this.#render();\n }\n\n /** Draws the field's Items again, when they have changed. */\n redraw(): void {\n this.#draft.redraw();\n }\n\n /** Gives the keyboard to the search. */\n takeKeyboard(): void {\n this.#searchBox.focus();\n }\n\n /** Stops a search on its way: the panel has closed. */\n close(): void {\n this.#draft.close();\n }\n\n #item(document: Document, className: string, changed: (tick: boolean) => void): DrawnItem {\n const row = element(document, 'label', className);\n const box = element(document, 'input');\n box.type = 'checkbox';\n const text = element(document, 'span');\n row.append(box, text);\n box.addEventListener('change', () => { changed(box.checked); });\n return { row, box, text };\n }\n\n #render(): void {\n const view = this.#draft.view;\n if (view.loading || view.updating) this.#list.setAttribute('aria-busy', 'true');\n else this.#list.removeAttribute('aria-busy');\n const parts: HTMLElement[] = [];\n if (view.unavailable !== undefined) {\n this.#unavailable.textContent = view.unavailable;\n parts.push(this.#unavailable);\n } else if (view.loading) {\n parts.push(this.#loading);\n } else {\n const document = this.element.ownerDocument;\n if (view.items.length > 0) {\n this.#selectAll.box.checked = view.allTicked === true;\n parts.push(this.#selectAll.row);\n }\n // An Item keeps its row while it is listed, so the one with the keyboard keeps it.\n const kept = new Map<string, DrawnItem>();\n view.items.forEach((item, at) => {\n const id = this.#draft.idAt(at);\n const { key } = item;\n const drawn = this.#drawn.get(id) ?? this.#item(document, 'ex-pivot-item', tick => { this.#draft.setTicked(key, tick); });\n drawn.box.checked = item.ticked;\n if (drawn.text.textContent !== item.label) drawn.text.textContent = item.label;\n kept.set(id, drawn);\n parts.push(drawn.row);\n });\n this.#drawn.clear();\n for (const [id, drawn] of kept) this.#drawn.set(id, drawn);\n if (view.note !== undefined) {\n this.#note.textContent = view.note;\n parts.push(this.#note);\n }\n }\n const children = this.#list.children;\n if (parts.length !== children.length || parts.some((part, i) => children[i] !== part)) this.#list.replaceChildren(...parts);\n\n if (view.refusal === undefined) this.#refusalBox.remove();\n else {\n this.#refusalBox.textContent = view.refusal;\n if (this.#refusalBox.previousSibling !== this.#list) this.#list.after(this.#refusalBox);\n }\n this.#ok.disabled = !view.canApply;\n }\n}\n\n// The Hidden Items of `field` in `layout`, which Filter\u2026 is only opened on while the field is placed.\nfunction placementHidden(layout: PivotLayout, field: string): readonly PivotItemKey[] {\n const at = defined(placementOf(layout, field), `the placement of '${field}'`);\n return elementAt(placementsIn(layout, at.area), at.index).hiddenItems;\n}\n", "// A field's Items, asked of the report source (ADR-0066): what Filter\u2026 lists and the report filter band reads its\n// summary from. They are listed under the Source Version of the report on screen, in the field's order, and listed\n// again when the report moves to another Source Version, settings or order; meanwhile the earlier listing stays in\n// view, marked as updating, as the Razor component's does (ADR-0066 refined). A source that cannot list them says\n// why, never an empty list in its place.\n\nimport type {\n LocalPivotReportSource, PivotItemInfo, PivotReportItemsResult, PivotReportRefusal, PivotReportSettings, PivotSort,\n} from '@ex-grid/pivot-engine';\n\n/** The most Items Filter\u2026 lists (ADR-0061). */\nexport const itemListCap = 10_000;\n\n/** What a field's Items are now. */\nexport interface FieldItems {\n /** The Items listed, in the field's order, and how many there are; none while a first listing is on its way, or\n * when they cannot be listed. */\n readonly listed: { readonly items: readonly PivotItemInfo[]; readonly total: number } | undefined;\n /** Why they cannot be listed. */\n readonly problem: ItemsProblem | undefined;\n /** Whether a listing is on its way: a first one, or the report's while an earlier one is in view. */\n readonly pending: boolean;\n}\n\n/** Why a field's Items cannot be listed: the source's refusal, or an error it threw. */\nexport type ItemsProblem = { readonly refusal: PivotReportRefusal } | { readonly error: unknown };\n\n/** What a listing is asked under: the report on screen, and the field's order in it. */\nexport interface ItemsUnder {\n readonly reportSource: LocalPivotReportSource;\n /** The Report Version the Items are asked for. */\n readonly version: string;\n readonly sourceVersion: string;\n readonly settings: PivotReportSettings;\n /** The field's order, which the Items are listed in. */\n readonly sort: PivotSort | undefined;\n}\n\n/** The Items of `field` matching `search`, asked of the source under `under`: Filter\u2026's search past the Items\n * listed, which only the source can answer. */\nexport function searchItems(field: string, search: string, under: ItemsUnder, signal: AbortSignal): Promise<PivotReportItemsResult> {\n return under.reportSource.items(Object.freeze({ version: under.version, field, search, max: itemListCap }), signal);\n}\n\ninterface Load {\n readonly under: ItemsUnder;\n /** Stops it once a newer listing of its field is asked for, or its source is no longer the pivot's. */\n readonly controller: AbortController;\n /** What it shows: none while it is on its way. */\n shown: FieldItems | undefined;\n}\n\n// Whether two listings are of the same Items in the same order: the same source, Source Version, settings and order.\n// An order by a Value Field is the report's, which any change of the layout may change: such a listing is the report's\n// alone.\nfunction sameListing(a: ItemsUnder, b: ItemsUnder): boolean {\n return a.reportSource === b.reportSource && a.sourceVersion === b.sourceVersion && a.settings === b.settings\n && a.sort?.direction === b.sort?.direction && a.sort?.byValue === b.sort?.byValue\n && (a.sort?.byValue === undefined || a.version === b.version);\n}\n\n/** Nothing listed yet, and a first listing on its way. */\nexport const pendingFirst: FieldItems = Object.freeze({ listed: undefined, problem: undefined, pending: true });\n\n/** The Items of each field the pivot has asked about, under its report source now. */\nexport class ItemListings {\n readonly #listed: () => void;\n // The newest listing asked for each field, and the last one that listed Items, kept in view while a newer one is\n // out. Both hold only the listings of one report source: a new source's Items are listed from nothing.\n readonly #loads = new Map<string, Load>();\n readonly #answered = new Map<string, FieldItems>();\n #reportSource: LocalPivotReportSource | undefined;\n\n /** `listed` is called when a listing lands. */\n constructor(listed: () => void) {\n this.#listed = listed;\n }\n\n /** The Items of `field` as they stand under `under`, asked for if they are not listed under it nor on their way.\n * The same listing is answered with the same object, so a caller can tell nothing changed. */\n of(field: string, under: ItemsUnder): FieldItems {\n if (under.reportSource !== this.#reportSource) this.#forgetAll(under.reportSource);\n let load = this.#loads.get(field);\n if (load === undefined || !sameListing(load.under, under)) {\n // A listing asked over is stopped: its Items would be shown only until the newer one's land.\n if (load?.shown === undefined) load?.controller.abort();\n load = { under, controller: new AbortController(), shown: undefined };\n this.#loads.set(field, load);\n void this.#list(field, load);\n }\n if (load.shown !== undefined) return load.shown;\n // An earlier listing stays in view until this one lands; with none, the first listing is on its way.\n return this.#answered.get(field) ?? pendingFirst;\n }\n\n /** Asks for `field`'s Items again the next time they are read, when its listing failed: Filter\u2026 opened again\n * lists them anew rather than repeat a failure that may have passed. */\n retry(field: string): void {\n if (this.#loads.get(field)?.shown?.problem !== undefined) this.#loads.delete(field);\n }\n\n /** Stops every listing on its way and forgets every listing: the pivot is gone. */\n dispose(): void {\n this.#forgetAll(undefined);\n }\n\n #forgetAll(reportSource: LocalPivotReportSource | undefined): void {\n for (const load of this.#loads.values()) load.controller.abort();\n this.#loads.clear();\n this.#answered.clear();\n this.#reportSource = reportSource;\n }\n\n async #list(field: string, load: Load): Promise<void> {\n const { under, controller: { signal } } = load;\n let result;\n try {\n result = await under.reportSource.items(Object.freeze({ version: under.version, field, max: itemListCap }), signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a listing asked over, or of a source no longer the pivot's, is nobody's; the current one's failure is said where its Items are shown, and rethrown\n if (signal.aborted) return;\n this.#landed(field, load, Object.freeze({ listed: undefined, problem: Object.freeze({ error }), pending: false }));\n throw error;\n }\n if (signal.aborted) return;\n this.#landed(field, load, Object.freeze(result.refusal === undefined\n ? { listed: Object.freeze({ items: result.items, total: result.total }), problem: undefined, pending: false }\n : { listed: undefined, problem: Object.freeze({ refusal: result.refusal }), pending: false }));\n }\n\n // Its Items replace the ones kept in view while a newer listing is out; Items that could not be listed leave none\n // in view, as the Razor component's do.\n #landed(field: string, load: Load, shown: FieldItems): void {\n load.shown = shown;\n if (shown.listed === undefined) this.#answered.delete(field);\n else this.#answered.set(field, Object.freeze({ ...shown, pending: true }));\n this.#listed();\n }\n}\n", "// ExPivot's built-in menu in its frame (ADR-0061): a placed field's commands, or the Layout menu's choices, in\n// the markup and under the classes the Razor component's PivotPopupFrame and PivotMenuView draw, so one\n// stylesheet paints both (ADR-0350 section 4). Where the frame stands and what closes it are the pivot's; the\n// frame says only that Escape was pressed in it. A Chrome's menu slot draws the commands inside the same frame.\n\nimport { SlotMount, ViewListeners, type PivotChromeSlot, type PivotMenuCommand, type PivotMenuSlotContext, type PivotMenuView } from './chrome';\nimport type { PivotScreenWords } from './words';\n\nexport type { PivotMenuCommand } from './chrome';\n\n/** Where a frame stands: in the Field List under its entry, or from the Pivot Toolbar over the report, at its\n * button's left edge (the report filter band) or its right edge (Layout \u25BE). */\nexport type PivotMenuPlace = 'field-list' | 'toolbar-start' | 'toolbar-end';\n\n/**\n * ExPivot's frame around a menu or a panel (ADR-0061), as the Razor component's PivotPopupFrame draws it: where it\n * stands is its class, and Escape pressed anywhere in it calls `escape` and goes no further, so a dialog the\n * Consumer put the pivot in does not close on it too. It claims nothing of the pivot's input (ADR-0240 section 6).\n */\nexport function popupFrame(document: Document, place: PivotMenuPlace, role: 'menu' | 'dialog', escape: () => void,\n innerPopupOpen?: () => boolean): HTMLDivElement {\n const frame = document.createElement('div');\n frame.className = {\n 'field-list': 'ex-pivot-popup',\n 'toolbar-start': 'ex-pivot-popup ex-pivot-popup-overlay',\n 'toolbar-end': 'ex-pivot-popup ex-pivot-popup-overlay ex-pivot-popup-end',\n }[place];\n frame.setAttribute('role', role);\n // A press on its padding, its text or a disabled command gives the frame the keyboard, so Escape stays inside it\n // without another Tab stop (ADR-0061).\n frame.tabIndex = -1;\n frame.setAttribute('data-ex-claims', '');\n frame.addEventListener('keydown', event => {\n if (event.key !== 'Escape' || event.ctrlKey || event.altKey || event.metaKey) return;\n // While a popup of a Chrome's own is open in the frame, Escape is that popup's (ADR-0039).\n if (innerPopupOpen?.() === true) return;\n event.preventDefault();\n event.stopPropagation();\n escape();\n });\n return frame;\n}\n\ninterface DrawnCommand {\n readonly button: HTMLButtonElement;\n readonly mark: HTMLElement | undefined;\n}\n\nfunction sameShape(a: readonly PivotMenuCommand[], b: readonly PivotMenuCommand[]): boolean {\n return a.length === b.length\n && a.every((command, i) => {\n const other = b[i];\n return other !== undefined && other.id === command.id && other.heading === command.heading\n && (other.checked === undefined) === (command.checked === undefined);\n });\n}\n\n// Whether a Chrome's menu shows the same thing for `b` as for `a`.\nfunction sameCommands(a: readonly PivotMenuCommand[], b: readonly PivotMenuCommand[]): boolean {\n return a.length === b.length\n && a.every((command, i) => {\n const other = b[i];\n return other !== undefined && other.id === command.id && other.label === command.label && other.enabled === command.enabled\n && other.checked === command.checked && other.heading === command.heading;\n });\n}\n\n/** A menu in ExPivot's frame, the built-in one's or a Chrome's: the pivot places its element, draws it again on every\n * change, and takes it away. */\nexport interface PivotMenu {\n /** The frame, which the pivot places. */\n readonly element: HTMLElement;\n /** Draws `commands` under the accessible name `label`. */\n draw(label: string, commands: readonly PivotMenuCommand[]): void;\n /** Gives the keyboard to the first enabled command, or to the frame when every command is disabled. */\n takeKeyboard(): void;\n /** The menu is taken away. */\n close(): void;\n /** Whether a popup of a Chrome's contents is open, which may stand outside the frame and take the keyboard there. */\n innerPopupOpen?(): boolean;\n}\n\n/** A menu in ExPivot's frame. The pivot draws it again on every change, and a command pressed is the one drawn\n * last: a press never reaches a command built against a layout the pane has since left. */\nexport class PivotMenuFrame implements PivotMenu {\n /** The frame, which the pivot places. */\n readonly element: HTMLDivElement;\n readonly #menu: HTMLDivElement;\n #commands: readonly PivotMenuCommand[] = [];\n #drawn = new Map<string, DrawnCommand>();\n\n constructor(document: Document, place: PivotMenuPlace, escape: () => void) {\n this.element = popupFrame(document, place, 'menu', escape);\n this.#menu = document.createElement('div');\n this.#menu.className = 'ex-pivot-menu';\n this.#menu.setAttribute('role', 'none');\n this.element.append(this.#menu);\n }\n\n /** Draws `commands` under the accessible name `label`. A command keeps its button while the menu holds the\n * same commands, so the one with the keyboard keeps it. */\n draw(label: string, commands: readonly PivotMenuCommand[]): void {\n this.element.setAttribute('aria-label', label);\n if (!sameShape(this.#commands, commands)) this.#build(commands);\n this.#commands = commands;\n for (const command of commands) {\n const drawn = this.#drawn.get(command.id);\n if (drawn === undefined) throw new Error(`Internal: the command '${command.id}' was not drawn.`);\n drawn.button.disabled = !command.enabled;\n if (command.checked !== undefined) drawn.button.setAttribute('aria-checked', command.checked ? 'true' : 'false');\n if (drawn.mark !== undefined) drawn.mark.textContent = command.checked === true ? '\u2713' : '';\n const text = drawn.button.lastChild;\n if (text?.textContent !== command.label) {\n if (text instanceof Text) text.textContent = command.label;\n else drawn.button.append(command.label);\n }\n }\n }\n\n /** Gives the keyboard to the first enabled command, or to the frame when every command is disabled. */\n takeKeyboard(): void {\n const first = this.#commands.find(command => command.enabled);\n if (first === undefined) {\n this.element.focus();\n return;\n }\n const drawn = this.#drawn.get(first.id);\n if (drawn === undefined) throw new Error(`Internal: the command '${first.id}' was not drawn.`);\n drawn.button.focus();\n }\n\n /** Nothing of the built-in menu outlives its frame. */\n close(): void {\n // The frame's listeners go with it.\n }\n\n #build(commands: readonly PivotMenuCommand[]): void {\n const document = this.element.ownerDocument;\n const drawn = new Map<string, DrawnCommand>();\n const parts: HTMLElement[] = [];\n let group: HTMLElement | undefined;\n for (const command of commands) {\n if (command.heading !== undefined) {\n // A group of choices stands under its heading, as the Razor component's menu draws it.\n group = document.createElement('div');\n group.className = 'ex-pivot-menu-group';\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', command.heading);\n const heading = document.createElement('div');\n heading.className = 'ex-pivot-menu-heading';\n heading.setAttribute('aria-hidden', 'true');\n heading.textContent = command.heading;\n group.append(heading);\n parts.push(group);\n }\n const button = document.createElement('button');\n button.type = 'button';\n const choice = command.checked !== undefined;\n button.className = choice ? 'ex-pivot-menu-item ex-pivot-menu-choice' : 'ex-pivot-menu-item';\n button.setAttribute('role', choice ? 'menuitemradio' : 'menuitem');\n button.setAttribute('data-ex-claims', 'click');\n let mark: HTMLElement | undefined;\n if (choice) {\n mark = document.createElement('span');\n mark.className = 'ex-pivot-menu-mark';\n mark.setAttribute('aria-hidden', 'true');\n button.append(mark);\n }\n const { id } = command;\n button.addEventListener('click', () => {\n // The command drawn last under this id: the one built against the pane's layout now.\n const current = this.#commands.find(c => c.id === id);\n if (current?.enabled === true) current.invoke();\n });\n drawn.set(id, { button, mark });\n if (group === undefined) parts.push(button);\n else group.append(button);\n }\n if (drawn.size !== commands.length) throw new Error('Internal: two commands of one menu share an id.');\n this.#drawn = drawn;\n this.#menu.replaceChildren(...parts);\n }\n}\n\n/**\n * A menu whose commands a Chrome's slot draws (ADR-0390), inside the same frame: the commands, their order and what\n * each does are the pivot's, and a command pressed is the one drawn last under its id, as the built-in menu's is, so a\n * press never reaches a command built against a layout the pane has since left.\n */\nexport class SlottedMenuFrame implements PivotMenu {\n readonly element: HTMLDivElement;\n readonly #slot: SlotMount<PivotMenuSlotContext>;\n readonly #listeners = new ViewListeners();\n #view: PivotMenuView = Object.freeze({ name: '', commands: Object.freeze([]) });\n #commands: readonly PivotMenuCommand[] = [];\n\n constructor(document: Document, place: PivotMenuPlace, mount: PivotChromeSlot<PivotMenuSlotContext>, words: PivotScreenWords, escape: () => void) {\n this.element = popupFrame(document, place, 'menu', escape, () => this.#slot.innerPopupOpen);\n const body = document.createElement('div');\n body.setAttribute('role', 'none');\n this.element.append(body);\n const close = (): void => { escape(); };\n this.#slot = new SlotMount('menu', mount, body, focusRequest => Object.freeze({\n view: () => this.#view,\n subscribe: this.#listeners.subscribe,\n close: this.#slot.input(close),\n focusRequest,\n label: (id: string) => words.word(id),\n takeFocus: this.#slot.takeFocus,\n }), close);\n }\n\n draw(label: string, commands: readonly PivotMenuCommand[]): void {\n this.element.setAttribute('aria-label', label);\n this.#commands = commands;\n // The view is the same object while nothing it shows changed: a press reaches the commands drawn now anyway.\n if (this.#view.name === label && sameCommands(this.#view.commands, commands)) {\n this.#slot.mount();\n return;\n }\n this.#view = Object.freeze({\n name: label,\n commands: Object.freeze(commands.map(command => Object.freeze({ ...command, invoke: this.#slot.input(() => { this.#press(command.id); }) }))),\n });\n // Mounted once its first commands are known, and told of each change after.\n this.#slot.mount();\n this.#listeners.tell();\n }\n\n takeKeyboard(): void {\n if (this.#commands.some(command => command.enabled)) this.#slot.request();\n else this.element.focus();\n }\n\n innerPopupOpen(): boolean {\n return this.#slot.innerPopupOpen;\n }\n\n close(): void {\n this.#listeners.clear();\n this.#slot.dispose();\n }\n\n // The command drawn last under this id: the one built against the pane's layout now.\n #press(id: string): void {\n const current = this.#commands.find(command => command.id === id);\n if (current?.enabled === true) current.invoke();\n }\n}\n", "// ExPivot's built-in panels (ADR-0061): Field Settings\u2026 and Value Field Settings\u2026, in the markup and under the\n// classes the Razor component's PivotFieldSettingsView and PivotValueFieldSettingsView draw, so one stylesheet\n// paints both (ADR-0350 section 4). A panel holds a draft until OK, which says the change as the next layout; Cancel\n// and Escape drop it. Its controls are built once, when it opens, so nothing the pivot draws meanwhile writes over\n// what the user is typing.\n//\n// What a draft holds and what OK makes of it is the draft's, which the built-in markup and a Chrome's slot draw alike\n// (ADR-0390): swapping the Chrome changes no behaviour.\n\nimport {\n formatPivotNumber, pivotAggregationNameId, pivotAggregations, pivotCaptionId, pivotNumberFormatProblem, pivotShowValuesAsList,\n pivotShowValuesAsNameId, pivotSort, refusalWord, setSort, setSubtotals, setValueField, sortsEqual, type PivotAggregation, type PivotField,\n type PivotFieldPlacement, type PivotLayout, type PivotShowValuesAs, type PivotSort, type PivotSourceFeatures, type PivotValueFieldInput,\n} from '@ex-grid/pivot-engine';\nimport {\n SlotMount, ViewListeners, type PivotChoice, type PivotChromeSlot, type PivotFieldSettingsSlotContext, type PivotFieldSettingsView, type PivotPanelSlotContext,\n type PivotValueFieldSettingsSlotContext, type PivotValueFieldSettingsView,\n} from './chrome';\nimport { element as made } from './dom';\nimport { popupFrame, type PivotMenuPlace } from './menu';\nimport { elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** A panel open under a field's entry. */\nexport interface PivotPanel {\n /** Its frame, which the pivot places. */\n readonly element: HTMLElement;\n /** Gives the keyboard to its first control. */\n takeKeyboard(): void;\n /** Draws again what it shows of the pivot's state, which the pivot has drawn again. */\n redraw?(): void;\n /** Closed: stops what it has asked that is still on its way. */\n close?(): void;\n /** Whether a popup of a Chrome's contents is open, which may stand outside the frame and take the keyboard there. */\n innerPopupOpen?(): boolean;\n}\n\n/** Whom a panel calls back. */\nexport interface PanelHandlers {\n /** OK made `layout`, taken against the layout the panel was opened on. */\n readonly apply: (layout: PivotLayout) => void;\n /** Cancel or Escape, or OK with nothing changed. */\n readonly cancel: () => void;\n}\n\n// Each panel's radio group is named apart from every other's on the page (ADR-0018).\nlet groups = 0;\n\n/** A panel's element. */\nexport function element<K extends keyof HTMLElementTagNameMap>(document: Document, tag: K, className?: string): HTMLElementTagNameMap[K] {\n const control = made(document, tag, className);\n // A draft's control claims nothing of the pivot's input: holding the keyboard, it is the pivot's own (ADR-0240).\n if (tag === 'input' || tag === 'select') control.setAttribute('data-ex-claims', '');\n return control;\n}\n\nfunction labelled(document: Document, words: string, control: HTMLElement): HTMLLabelElement {\n const row = element(document, 'label', 'ex-pivot-row');\n const text = element(document, 'span');\n text.textContent = words;\n row.append(text, control);\n return row;\n}\n\n/** OK and Cancel, which claim their click. */\nexport function actions(document: Document, words: PivotScreenWords, ok: () => void, cancel: () => void): { readonly box: HTMLElement; readonly ok: HTMLButtonElement } {\n const box = element(document, 'div', 'ex-pivot-panel-actions');\n const make = (className: string, id: string, pressed: () => void): HTMLButtonElement => {\n const button = element(document, 'button', className);\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.textContent = words.word(id);\n button.addEventListener('click', pressed);\n return button;\n };\n const okButton = make('ex-pivot-ok', 'ok', ok);\n box.append(okButton, make('ex-pivot-cancel', 'cancel', cancel));\n return { box, ok: okButton };\n}\n\n/** A draft a panel draws: its view, told to its listeners at each change, and OK. */\nexport interface PanelDraft<View> {\n /** What the panel shows now: a new object at each change, and the same one otherwise. */\n readonly view: View;\n /** Hears each change to the view. */\n readonly listeners: ViewListeners;\n /** OK: the draft as the next layout, a refusal said in the view, or Cancel where nothing changed. */\n apply(): void;\n}\n\n/**\n * A panel whose contents a Chrome's slot draws (ADR-0390), inside the pivot's frame, from its draft: every choice is\n * the draft's, and OK and Cancel the panel's handlers'. A request for the keyboard mounts the contents again with the\n * next count; once the panel is closed, nothing they call back reaches the pivot.\n */\nexport function slottedPanel<View, Context extends PivotPanelSlotContext>(document: Document, frameLabel: string, place: PivotMenuPlace, name: string,\n mount: PivotChromeSlot<Context>, draft: PanelDraft<View>, cancel: () => void, words: PivotScreenWords,\n choices: (input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void) => Omit<Context, keyof PivotPanelSlotContext | 'view'>,\n redraw?: () => void, closing?: () => void): PivotPanel {\n // A popup of the contents' own takes Escape first.\n const frame = popupFrame(document, place, 'dialog', cancel, () => slot.innerPopupOpen);\n frame.setAttribute('aria-label', frameLabel);\n const body = document.createElement('div');\n frame.append(body);\n const slot: SlotMount<Context> = new SlotMount<Context>(name, mount, body, focusRequest => {\n const input = <Args extends unknown[]>(change: (...args: Args) => void): ((...args: Args) => void) => slot.input(change);\n const parts: PivotPanelSlotContext & { readonly view: () => View } = {\n label: (id: string) => words.word(id),\n focusRequest,\n takeFocus: slot.takeFocus,\n subscribe: draft.listeners.subscribe,\n view: () => draft.view,\n apply: input(() => { draft.apply(); }),\n cancel: input(cancel),\n innerPopupChanged: slot.innerPopupChanged,\n };\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the parts every panel's context shares, and the choices this panel's adds, make its context\n return Object.freeze({ ...parts, ...choices(input) }) as unknown as Context;\n }, cancel);\n // Mounted first by the request for the keyboard its opening makes, once the pivot holds the panel as open: contents\n // that cannot be drawn then close a panel that stands.\n return Object.freeze({\n element: frame,\n takeKeyboard: () => { slot.request(); },\n innerPopupOpen: () => slot.innerPopupOpen,\n ...(redraw === undefined ? {} : { redraw }),\n close: () => {\n closing?.();\n draft.listeners.clear();\n slot.dispose();\n },\n });\n}\n\n/** What Field Settings\u2026 is opened on. */\nexport interface FieldSettingsModel {\n readonly layout: PivotLayout;\n readonly placement: PivotFieldPlacement;\n readonly caption: string;\n /** The Value Fields' captions, which name the sorts by value. */\n readonly valueCaptions: readonly string[];\n readonly words: PivotScreenWords;\n}\n\n/** Field Settings\u2026' draft: the subtotals and the order, until OK. */\nexport class FieldSettingsDraft implements PanelDraft<PivotFieldSettingsView> {\n readonly listeners = new ViewListeners();\n readonly #model: FieldSettingsModel;\n readonly #handlers: PanelHandlers;\n readonly #sorts: readonly { readonly sort: PivotSort; readonly label: string }[];\n #view: PivotFieldSettingsView;\n\n constructor(model: FieldSettingsModel, handlers: PanelHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n const { placement, words } = model;\n // A to Z and Z to A by label, then each Value Field's two orders, as Excel's More Sort Options lists them.\n const sorts: { readonly sort: PivotSort; readonly label: string }[] = [\n { sort: pivotSort('ascending'), label: words.word('sort-label-ascending') },\n { sort: pivotSort('descending'), label: words.word('sort-label-descending') },\n ];\n model.valueCaptions.forEach((caption, i) => {\n sorts.push({ sort: pivotSort('ascending', i), label: words.fill('sort-value-ascending', caption) });\n sorts.push({ sort: pivotSort('descending', i), label: words.fill('sort-value-descending', caption) });\n });\n this.#sorts = sorts;\n const current = sorts.findIndex(({ sort }) => sortsEqual(sort, placement.sort));\n if (current < 0) throw new Error(`Internal: the field's order is none Field Settings\u2026 lists.`);\n this.#view = Object.freeze({\n caption: model.caption, subtotals: placement.subtotals, sorts: Object.freeze(sorts.map(({ label }) => label)), sort: current,\n });\n }\n\n get view(): PivotFieldSettingsView {\n return this.#view;\n }\n\n setSubtotals(automatic: boolean): void {\n if (typeof automatic !== 'boolean') throw new TypeError('setSubtotals is handed whether the subtotals are Automatic.');\n this.#change({ subtotals: automatic });\n }\n\n setSort(index: number): void {\n if (!Number.isSafeInteger(index) || index < 0 || index >= this.#sorts.length) {\n throw new RangeError(`setSort is handed the index of one of the panel's ${this.#sorts.length} orders, not ${index}.`);\n }\n this.#change({ sort: index });\n }\n\n apply(): void {\n const { layout, placement } = this.#model;\n const sort = elementAt(this.#sorts, this.#view.sort).sort;\n const { subtotals } = this.#view;\n if (subtotals === placement.subtotals && sortsEqual(sort, placement.sort)) {\n this.#handlers.cancel();\n return;\n }\n this.#handlers.apply(setSort(setSubtotals(layout, placement.field, subtotals), placement.field, sort));\n }\n\n #change(change: Partial<PivotFieldSettingsView>): void {\n this.#view = Object.freeze({ ...this.#view, ...change });\n this.listeners.tell();\n }\n}\n\n/** Field Settings\u2026 (ADR-0061): a row or column field's subtotals and order, drawn by `mount` where a Chrome gives one. */\nexport function fieldSettingsPanel(document: Document, model: FieldSettingsModel, handlers: PanelHandlers,\n mount?: PivotChromeSlot<PivotFieldSettingsSlotContext>): PivotPanel {\n const { words } = model;\n const draft = new FieldSettingsDraft(model, handlers);\n if (mount !== undefined) {\n return slottedPanel(document, words.word('field-settings'), 'field-list', 'fieldSettings', mount, draft, handlers.cancel, words, input => ({\n setSubtotals: input((automatic: boolean) => { draft.setSubtotals(automatic); }),\n setSort: input((index: number) => { draft.setSort(index); }),\n }));\n }\n const frame = popupFrame(document, 'field-list', 'dialog', handlers.cancel);\n frame.setAttribute('aria-label', words.word('field-settings'));\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-field-settings');\n const title = element(document, 'div', 'ex-pivot-panel-title');\n title.textContent = model.caption;\n\n const fieldset = element(document, 'fieldset', 'ex-pivot-fieldset');\n const legend = element(document, 'legend');\n legend.textContent = words.word('subtotals');\n groups++;\n const group = `ex-pivot-subtotals-${groups}`;\n const radio = (id: string, automatic: boolean): { readonly row: HTMLLabelElement; readonly input: HTMLInputElement } => {\n const row = element(document, 'label', 'ex-pivot-choice');\n const input = element(document, 'input');\n input.type = 'radio';\n input.name = group;\n input.checked = draft.view.subtotals === automatic;\n input.addEventListener('change', () => { if (input.checked) draft.setSubtotals(automatic); });\n const text = element(document, 'span');\n text.textContent = words.word(id);\n row.append(input, text);\n return { row, input };\n };\n const automatic = radio('subtotals-automatic', true);\n const none = radio('subtotals-none', false);\n fieldset.append(legend, automatic.row, none.row);\n\n const select = element(document, 'select', 'ex-pivot-select');\n draft.view.sorts.forEach((label, i) => {\n const option = element(document, 'option');\n option.value = String(i);\n option.textContent = label;\n select.append(option);\n });\n select.value = String(draft.view.sort);\n select.addEventListener('change', () => { draft.setSort(Number(select.value)); });\n\n panel.append(title, fieldset, labelled(document, words.word('sort-order'), select), actions(document, words, () => { draft.apply(); }, handlers.cancel).box);\n frame.append(panel);\n return Object.freeze({ element: frame, takeKeyboard: () => { automatic.input.focus(); } });\n}\n\n/** What Value Field Settings\u2026 is opened on. */\nexport interface ValueFieldSettingsModel {\n readonly layout: PivotLayout;\n readonly index: number;\n /** The field's caption. */\n readonly fieldCaption: string;\n /** The Value Field's caption as the report shows it. */\n readonly caption: string;\n readonly fields: readonly PivotField[];\n readonly features: PivotSourceFeatures;\n readonly locale: string;\n readonly words: PivotScreenWords;\n}\n\n/** Value Field Settings\u2026' draft: the caption, the Aggregation, Show Values As and the number format, until OK. */\nexport class ValueFieldSettingsDraft implements PanelDraft<PivotValueFieldSettingsView> {\n readonly listeners = new ViewListeners();\n readonly #model: ValueFieldSettingsModel;\n readonly #handlers: PanelHandlers;\n #captionTouched = false;\n #view: PivotValueFieldSettingsView;\n\n constructor(model: ValueFieldSettingsModel, handlers: PanelHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n const { layout, index, words, features } = model;\n const value = elementAt(layout.values, index);\n const aggregations = pivotAggregations.map(choice => {\n const name = words.word(pivotAggregationNameId(choice));\n return Object.freeze<PivotChoice<PivotAggregation>>(features.offers(choice)\n ? { value: choice, label: name, enabled: true }\n : { value: choice, label: name, enabled: false, reason: words.fill('aggregation-not-offered', name) });\n });\n const showValuesAsChoices = pivotShowValuesAsList.map(choice => Object.freeze<PivotChoice<PivotShowValuesAs>>({\n value: choice, label: words.word(pivotShowValuesAsNameId(choice)), enabled: true,\n }));\n const numberFormat = value.numberFormat ?? ''; // oxlint-disable-line ex-grid/no-stand-in-default -- no format of its own is General, which the field shows empty\n this.#view = Object.freeze({\n sourceCaption: model.fieldCaption,\n caption: model.caption,\n aggregation: value.aggregation,\n aggregations: Object.freeze(aggregations),\n showValuesAs: value.showValuesAs,\n showValuesAsChoices: Object.freeze(showValuesAsChoices),\n numberFormat,\n numberFormatPlaceholder: words.word('number-format-general'),\n sample: this.#sampleOf(value.showValuesAs, numberFormat),\n });\n }\n\n get view(): PivotValueFieldSettingsView {\n return this.#view;\n }\n\n setCaption(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setCaption is handed the caption as typed.');\n this.#captionTouched = true;\n this.#change({ caption: text });\n }\n\n setAggregation(aggregation: PivotAggregation): void {\n if (!pivotAggregations.includes(aggregation)) throw new RangeError(`'${aggregation}' is not an Aggregation.`);\n // An Aggregation the source does not answer is never chosen: it is never asked for (ADR-0066).\n if (!this.#model.features.offers(aggregation)) {\n this.listeners.tell();\n return;\n }\n const value = elementAt(this.#model.layout.values, this.#model.index);\n // A caption the user has not written follows the Aggregation, as Excel's Custom Name box does.\n this.#change({ aggregation, ...(!this.#captionTouched && value.caption === undefined ? { caption: this.#defaultCaption(aggregation) } : {}) });\n }\n\n setShowValuesAs(showValuesAs: PivotShowValuesAs): void {\n if (!pivotShowValuesAsList.includes(showValuesAs)) throw new RangeError(`'${showValuesAs}' is not a Show Values As.`);\n this.#change({ showValuesAs, sample: this.#sampleOf(showValuesAs, this.#view.numberFormat) });\n }\n\n setNumberFormat(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setNumberFormat is handed the number format as typed.');\n this.#change({ numberFormat: text, sample: this.#sampleOf(this.#view.showValuesAs, text) });\n }\n\n apply(): void {\n const { layout, index, words, features } = this.#model;\n const value = elementAt(layout.values, index);\n const { aggregation: chosen, showValuesAs: shown } = this.#view;\n // A Value Field the Consumer handed in with an Aggregation the source does not answer is refused here, never\n // asked for (ADR-0066).\n if (!features.offers(chosen)) {\n this.#refuse(words.fill('aggregation-not-offered', words.word(pivotAggregationNameId(chosen))));\n return;\n }\n const trimmed = this.#view.caption.trim();\n // A caption left as the pivot wrote it stays the pivot's, and follows the Aggregation and the words.\n const own = (!this.#captionTouched && value.caption === undefined) || trimmed === this.#defaultCaption(chosen) ? undefined : trimmed;\n const numberFormat = this.#view.numberFormat.trim();\n if (chosen === value.aggregation && shown === value.showValuesAs && own === value.caption && (numberFormat === '' ? undefined : numberFormat) === value.numberFormat) {\n this.#handlers.cancel();\n return;\n }\n const input: PivotValueFieldInput = {\n field: value.field,\n aggregation: chosen,\n showValuesAs: shown,\n ...(own === undefined ? {} : { caption: own }),\n ...(numberFormat === '' ? {} : { numberFormat }),\n };\n const result = setValueField(layout, index, input, this.#model.fields, { locale: this.#model.locale, ...(words.label === undefined ? {} : { label: words.label }) });\n if (result.refusal !== undefined) {\n this.#refuse(words.word(refusalWord(result.refusal)));\n return;\n }\n this.#handlers.apply(result.layout);\n }\n\n #defaultCaption(aggregation: PivotAggregation): string {\n return this.#model.words.fill(pivotCaptionId(aggregation), this.#model.fieldCaption);\n }\n\n // A number shown in the draft's format, or the reason it cannot be, so a format is seen before it is applied.\n #sampleOf(showValuesAs: PivotShowValuesAs, format: string): string {\n const { words, locale } = this.#model;\n const trimmed = format.trim();\n const percent = showValuesAs !== 'noCalculation';\n if (trimmed !== '' && pivotNumberFormatProblem(trimmed) !== undefined) return words.word('refused-number-format');\n return words.fill('sample', formatPivotNumber(percent ? 0.1234 : -1234.5678, trimmed === '' ? (percent ? '0.00%' : 'G15') : trimmed, locale));\n }\n\n #refuse(sentence: string): void {\n this.#view = Object.freeze({ ...this.#view, refusal: sentence });\n this.listeners.tell();\n }\n\n // Any change of the draft takes back a refusal said for the draft before it.\n #change(change: Partial<PivotValueFieldSettingsView>): void {\n const { refusal: _said, ...kept } = this.#view;\n this.#view = Object.freeze({ ...kept, ...change });\n this.listeners.tell();\n }\n}\n\n/** Value Field Settings\u2026 (ADR-0061): the caption, the Aggregation, Show Values As and the number format with a\n * sample, drawn by `mount` where a Chrome gives one. OK is refused, the sentence said in the panel, for a caption taken\n * or empty and for a format that cannot be used; an Aggregation the source does not answer is offered disabled, with\n * the reason (ADR-0066). */\nexport function valueFieldSettingsPanel(document: Document, model: ValueFieldSettingsModel, handlers: PanelHandlers,\n mount?: PivotChromeSlot<PivotValueFieldSettingsSlotContext>): PivotPanel {\n const { words } = model;\n const draft = new ValueFieldSettingsDraft(model, handlers);\n if (mount !== undefined) {\n return slottedPanel(document, words.word('value-field-settings'), 'field-list', 'valueFieldSettings', mount, draft, handlers.cancel, words, input => ({\n setCaption: input((text: string) => { draft.setCaption(text); }),\n setAggregation: input((aggregation: PivotAggregation) => { draft.setAggregation(aggregation); }),\n setShowValuesAs: input((showValuesAs: PivotShowValuesAs) => { draft.setShowValuesAs(showValuesAs); }),\n setNumberFormat: input((text: string) => { draft.setNumberFormat(text); }),\n }));\n }\n const view = (): PivotValueFieldSettingsView => draft.view;\n const frame = popupFrame(document, 'field-list', 'dialog', handlers.cancel);\n frame.setAttribute('aria-label', words.word('value-field-settings'));\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-value-settings');\n const title = element(document, 'div', 'ex-pivot-panel-title');\n title.textContent = words.word('value-field-settings');\n const source = element(document, 'div', 'ex-pivot-row ex-pivot-source');\n source.textContent = view().sourceCaption;\n\n const caption = element(document, 'input', 'ex-pivot-text');\n caption.type = 'text';\n caption.value = view().caption;\n\n const aggregation = element(document, 'select', 'ex-pivot-select');\n const notOffered: HTMLElement[] = [];\n for (const choice of view().aggregations) {\n const option = element(document, 'option');\n option.value = choice.value;\n option.textContent = choice.label;\n if (choice.reason !== undefined) {\n option.disabled = true;\n option.title = choice.reason;\n const note = element(document, 'div', 'ex-pivot-note ex-pivot-not-offered');\n note.textContent = choice.reason;\n notOffered.push(note);\n }\n aggregation.append(option);\n }\n aggregation.value = view().aggregation;\n\n const showAs = element(document, 'select', 'ex-pivot-select');\n for (const choice of view().showValuesAsChoices) {\n const option = element(document, 'option');\n option.value = choice.value;\n option.textContent = choice.label;\n showAs.append(option);\n }\n showAs.value = view().showValuesAs;\n\n const format = element(document, 'input', 'ex-pivot-text');\n format.type = 'text';\n format.placeholder = view().numberFormatPlaceholder;\n format.value = view().numberFormat;\n const sample = element(document, 'div', 'ex-pivot-sample');\n // The refusal is said under the sample while it stands, and is not on the page otherwise, as the Razor component's.\n const refusal = element(document, 'div', 'ex-pivot-refusal');\n refusal.setAttribute('role', 'alert');\n\n // Each control shows the draft: a text field is written only where the draft differs from what is typed in it, so\n // the caret stays where the user put it.\n const drawn = (): void => {\n const now = view();\n if (caption.value !== now.caption) caption.value = now.caption;\n aggregation.value = now.aggregation;\n showAs.value = now.showValuesAs;\n if (format.value !== now.numberFormat) format.value = now.numberFormat;\n sample.textContent = now.sample;\n if (now.refusal === undefined) {\n refusal.remove();\n } else {\n refusal.textContent = now.refusal;\n sample.after(refusal);\n }\n };\n draft.listeners.subscribe(drawn);\n caption.addEventListener('input', () => { draft.setCaption(caption.value); });\n aggregation.addEventListener('change', () => {\n const picked = pivotAggregations.find(a => a === aggregation.value);\n if (picked === undefined) throw new Error(`Internal: '${aggregation.value}' is not an Aggregation.`);\n draft.setAggregation(picked);\n });\n showAs.addEventListener('change', () => {\n const picked = pivotShowValuesAsList.find(s => s === showAs.value);\n if (picked === undefined) throw new Error(`Internal: '${showAs.value}' is not a Show Values As.`);\n draft.setShowValuesAs(picked);\n });\n format.addEventListener('input', () => { draft.setNumberFormat(format.value); });\n drawn();\n\n panel.append(\n title, source,\n labelled(document, words.word('custom-name'), caption),\n labelled(document, words.word('summarize-by'), aggregation),\n ...notOffered,\n labelled(document, words.word('show-values-as'), showAs),\n labelled(document, words.word('number-format'), format),\n sample,\n actions(document, words, () => { draft.apply(); }, handlers.cancel).box,\n );\n frame.append(panel);\n return Object.freeze({ element: frame, takeKeyboard: () => { caption.focus(); }, close: () => { draft.listeners.clear(); } });\n}\n", "// Written by tools/assets/minify.mjs (ADR-0123): do not edit. Edit dotnet/src/ExPivot/Assets/ and run it\n// again, and commit what it writes. test/shipped-stylesheet.test.ts checks it against the source.\n\n/** The name of the stylesheet the pivot draws against, by which its notice rules find the notice. */\nexport const stylesheetName = 'ex-pivot.css';\n\n/** The SHA-256 of that stylesheet's source: the stamp its own notice rule hides the notice for. */\nexport const stylesheetStamp = '1a2532223e2af8d3d27b7aa2e8919df9378c1554121b47e778ced6ff8ae89dd3';\n", "// The Pivot Report as ExGrid's Consumer draws it (ADR-0059, ADR-0063): its rows a Window the report source\n// answers, its label columns pinned and its value columns under Header Groups. Nothing is held here but what\n// one report's metadata says; the rows stay with the report source, asked for as the grid scrolls, so the\n// DOM and the memory grow with the rows on screen, not with the report (ADR-0151, ADR-0027 P1).\n\nimport {\n GridSource, findMatches, gridHeaderRequiredPx, type FetchingGridSource, type GridColumn, type GridColumnWidth, type GridHeaderGroup, type GridTextOptions,\n type GridFindPattern, type GridFindRequest, type GridFindResult, type GridPage, type GridQuery, type GridSelection, type GridTemplate,\n} from '@ex-grid/core';\nimport { decimalText } from '@ex-grid/data';\nimport {\n PivotRowKey, type PivotDisplayRow, type PivotFieldItem, type PivotLabelColumn, type PivotLayout, type PivotReportMetadata, type PivotReportSettings, type PivotReportSource,\n type PivotReportState, type PivotToggle, type PivotValue,\n} from '@ex-grid/pivot-engine';\nimport { elementAt } from './must';\nimport { findInReport, type ReportFindGivenUp } from './report-find';\nimport { summarizeReport } from './report-summary';\nimport type { PivotScreenWords } from './words';\n\n/**\n * A value cell's value as the grid holds it: the report's own text is what the cell paints, and the value's\n * own text, which the grid copies as the raw flavour and a spreadsheet reads back as the same number, is the\n * exact decimal's digits where there is one, the double's shortest text otherwise, and an error's text for an\n * error (ADR-0005, ADR-0060). The grid reads an object's text through `toString`, as C#'s reads `ToString`.\n */\nexport class ReportCellValue {\n readonly #value: PivotValue;\n\n constructor(value: PivotValue) {\n this.#value = value;\n }\n\n /** The text the report shows. */\n get text(): string {\n return this.#value.text;\n }\n\n /** The raw text the clipboard carries. */\n toString(): string {\n const { error, exact, number } = this.#value;\n if (error !== undefined) return error;\n return exact === undefined ? String(number) : decimalText(exact);\n }\n}\n\n/**\n * The Match Mark's rule over the report (ADR-0332 \u00A74): the reference rule over the text a cell shows, which is the\n * text its Copy reads and `findInReport` finds by, so the mark and the step agree. One function for every pivot:\n * its identity reaches the grid (ADR-0003).\n */\nexport function reportMatch(row: PivotDisplayRow, column: GridColumn<PivotDisplayRow>, pattern: GridFindPattern): boolean {\n const value = column.value(row);\n // A label with no text, or a cell with no value, shows nothing.\n if (value === undefined) return findMatches('', pattern);\n if (value instanceof ReportCellValue) return findMatches(value.text, pattern);\n if (typeof value === 'string') return findMatches(value, pattern);\n throw new TypeError(`Internal: the report column '${column.name}' holds neither a label nor a value.`);\n}\n\n/** A display row's identity across Windows and reports: its role, its Value Field and its Items. */\nexport function reportRowKey(row: PivotDisplayRow): string {\n return new PivotRowKey(row.role, row.valueField, row.items).toString();\n}\n\n/** What a label cell paints beside its text: a level's indent, and the expand / collapse button's name and press. */\nexport interface LabelPainter {\n /** A level's indent, in pixels: the em of the grid's font, as the report source charges it (ADR-0151). */\n readonly indentPx: number;\n /** The button's accessible name: \"Expand East\", \"Collapse East\". */\n readonly toggleName: (toggle: PivotToggle) => string;\n /** The button pressed on `row`: the Item is to be collapsed or expanded. */\n readonly toggled: (toggle: PivotToggle, row: PivotDisplayRow) => void;\n}\n\n/**\n * One label column's cells (ADR-0059), the Razor component's markup: the indent, the expand / collapse button\n * of an outer Item, and the label. The button is pressed, never reached by Tab, and takes the keyboard when\n * Space asks the cell to (ADR-0037); a press on it keeps the keyboard where it was, as the grid's own buttons\n * do, and a double click on it stops there, since its offsets are the button's (ADR-0063).\n */\nfunction labelTemplate(index: number, painter: LabelPainter): GridTemplate<PivotDisplayRow> {\n // A button pressed by Enter or Space asks the report again, and is painted anew: the grid takes back the\n // keyboard it held (ADR-0037).\n return (slot, cell) => {\n const label = elementAt(cell.row.labels, index);\n const document = slot.ownerDocument;\n const box = document.createElement('span');\n box.className = 'ex-pivot-label';\n if (label.indent > 0) box.style.paddingLeft = `${label.indent * painter.indentPx}px`;\n const listening = new AbortController();\n const { toggle } = label;\n let button: HTMLButtonElement | undefined;\n if (toggle !== undefined) {\n const made = document.createElement('button');\n made.type = 'button';\n made.className = toggle.isCollapsed ? 'ex-pivot-toggle ex-interactive ex-pivot-toggle-collapsed' : 'ex-pivot-toggle ex-interactive';\n made.tabIndex = -1;\n made.setAttribute('data-ex-claims', 'click');\n made.setAttribute('aria-expanded', toggle.isCollapsed ? 'false' : 'true');\n made.setAttribute('aria-label', painter.toggleName(toggle));\n made.textContent = toggle.isCollapsed ? '+' : '\\u2212';\n const { signal } = listening;\n made.addEventListener('mousedown', event => { event.preventDefault(); }, { signal });\n made.addEventListener('click', () => { painter.toggled(toggle, cell.row); }, { signal });\n made.addEventListener('dblclick', event => { event.stopPropagation(); }, { signal });\n box.append(made);\n button = made;\n }\n if (label.text !== undefined) {\n const text = document.createElement('span');\n text.className = 'ex-pivot-label-text';\n text.textContent = label.text;\n box.append(text);\n }\n slot.append(box);\n if (button !== undefined && cell.focusRequest !== 0) cell.takeKeyboard(button);\n return () => {\n listening.abort();\n box.remove();\n };\n };\n}\n\nfunction labelColumn(name: string, header: string, index: number, width: GridColumnWidth, painter: LabelPainter): GridColumn<PivotDisplayRow> {\n return Object.freeze({\n name,\n header,\n type: 'text',\n width,\n // A label is Text; an Item the report shows as a number is still a label, aligned as text (ADR-0059).\n align: 'left',\n queryable: false,\n value: (row: PivotDisplayRow) => elementAt(row.labels, index).text,\n template: labelTemplate(index, painter),\n });\n}\n\nfunction cellValueOf(value: unknown): string {\n if (!(value instanceof ReportCellValue)) throw new TypeError('Internal: a value cell holds a report value.');\n return value.text;\n}\n\nfunction valueColumn(name: string, header: string, index: number, width: GridColumnWidth | undefined): GridColumn<PivotDisplayRow> {\n const values = new WeakMap<PivotDisplayRow, ReportCellValue | undefined>();\n return Object.freeze({\n name,\n header,\n type: 'number',\n ...(width === undefined ? {} : { width }),\n queryable: false,\n value: (row: PivotDisplayRow) => {\n if (values.has(row)) return values.get(row);\n const shown = row.values[index];\n const cell = shown === undefined ? undefined : new ReportCellValue(shown);\n values.set(row, cell);\n return cell;\n },\n format: cellValueOf,\n });\n}\n\n/** What the grid is handed for one report: its columns, its Header Groups and how many columns are pinned. */\nexport interface ReportColumnSet {\n readonly columns: readonly GridColumn<PivotDisplayRow>[];\n readonly headerGroups: readonly GridHeaderGroup[];\n readonly pinnedColumnCount: number;\n}\n\n/** The narrowest and the widest a label column is laid out at when the user has not set its width (ADR-0059). */\nconst minLabelWidthPx = 60;\nconst maxLabelWidthPx = 480;\n\nfunction fixedWidth(px: number): GridColumnWidth {\n return Object.freeze({ px, minPx: Math.min(40, px), maxPx: Math.max(400, px) });\n}\n\n/**\n * The grid's columns for each report, made once for each name, header, place and width and held, so a report\n * that keeps a column hands the grid the same column, and its cells are not painted again (ADR-0003). Made\n * anew when what a label cell paints with changes.\n */\nexport class ReportColumns {\n readonly #painter: LabelPainter;\n readonly #text: GridTextOptions;\n readonly #made = new Map<string, GridColumn<PivotDisplayRow>>();\n\n constructor(painter: LabelPainter, text: GridTextOptions) {\n this.#painter = painter;\n this.#text = text;\n }\n\n /**\n * The grid's columns for a report: each label column, then each value column, with any width the user\n * dragged a column of that name to (ADR-0016), and the column Items as Header Groups over the value columns,\n * never over the pinned labels (ADR-0032). A label column the user has not sized is as wide as its header\n * or its widest label, which the report source estimated under the grid's text geometry, between 60 and 480\n * pixels, since its cells paint a template that no Auto width observes.\n */\n of(metadata: PivotReportMetadata, userWidths: ReadonlyMap<string, number>): ReportColumnSet {\n const columns: GridColumn<PivotDisplayRow>[] = [];\n metadata.labelColumns.forEach((label, index) => {\n const user = userWidths.get(label.name);\n const px = user ?? this.#labelWidth(label.header, metadata.labelWidths[index]);\n columns.push(this.#held(`l\\u001F${label.name}\\u001F${label.header}\\u001F${index}\\u001F${px}`,\n () => labelColumn(label.name, label.header, index, fixedWidth(px), this.#painter)));\n });\n metadata.valueColumns.forEach((value, index) => {\n const px = userWidths.get(value.name);\n columns.push(this.#held(`v\\u001F${value.name}\\u001F${value.header}\\u001F${index}\\u001F${px}`,\n () => valueColumn(value.name, value.header, index, px === undefined ? undefined : fixedWidth(px))));\n });\n // Columns no report has kept are let go once they outnumber the ones in use, as the Razor component's are.\n if (this.#made.size > (4 * columns.length) + 64) {\n const used = new Set(columns);\n for (const [key, column] of this.#made) if (!used.has(column)) this.#made.delete(key);\n }\n const names = metadata.valueColumns.map(column => column.name);\n const headerGroups = metadata.headerSpans.map(span => Object.freeze({\n label: span.label,\n columns: Object.freeze(names.slice(span.firstColumn, span.firstColumn + span.columnCount)),\n tier: span.tier,\n tierSpan: span.tierSpan,\n }));\n return Object.freeze({ columns: Object.freeze(columns), headerGroups: Object.freeze(headerGroups), pinnedColumnCount: metadata.labelColumns.length });\n }\n\n #labelWidth(header: string, label: number | undefined): number {\n const headerPx = gridHeaderRequiredPx(header, { ...this.#text, menuButton: false, sortable: false });\n // A report answered without label geometry has no estimate, and its header alone sizes it.\n const widest = label === undefined ? headerPx : Math.max(headerPx, label);\n return Math.min(maxLabelWidthPx, Math.max(minLabelWidthPx, Math.ceil(widest)));\n }\n\n #held(key: string, make: () => GridColumn<PivotDisplayRow>): GridColumn<PivotDisplayRow> {\n let column = this.#made.get(key);\n if (column === undefined) {\n column = make();\n this.#made.set(key, column);\n }\n return column;\n }\n}\n\n/** Thrown when a Window is answered from another report than the one the grid shows: the data moved on, and\n * the report is asked again rather than shown with rows of two reports (spine rule 6). */\nexport class ReportMovedError extends Error {\n constructor() {\n super('The report source answered a Window of another report than the one shown: the report is asked again.');\n this.name = 'ReportMovedError';\n }\n}\n\nfunction pageOf(state: PivotReportState): GridPage<PivotDisplayRow> {\n return Object.freeze({\n rows: state.rows,\n start: state.window.start,\n totalCount: state.metadata.rowCount,\n orderToken: state.metadata.rowSequenceVersion,\n });\n}\n\n/** What the rows of one report are asked under. */\nexport interface ReportRowsRequest {\n readonly source: PivotReportSource;\n readonly layout: PivotLayout;\n readonly settings: PivotReportSettings;\n readonly maxLeaves: number;\n /** The answer the report was shown from, whose rows are served without asking again. */\n readonly answered: PivotReportState;\n /** A request identity for each Window asked. */\n readonly nextRequestId: () => string;\n /** Told when a Window came from another report: the report is to be asked again. */\n readonly moved: () => void;\n /** Told when a Find step over the report cannot go on, before the step is given up (ADR-0332 \u00A71). */\n readonly findGivenUp: (why: ReportFindGivenUp) => void;\n /** The pivot's words as they stand when a Selection Summary is declined (ADR-0060). */\n readonly words: () => PivotScreenWords;\n}\n\n/**\n * The rows of one report as a Grid Source (ADR-0350 section 16): each range the grid asks for is a Window of\n * the same report, under the layout and settings it was answered under, named by its Report Version, and a\n * Window of any other report is refused rather than shown beside it.\n */\nexport function reportRows(request: ReportRowsRequest): FetchingGridSource<PivotDisplayRow> {\n const { answered } = request;\n const version = answered.metadata.version;\n const fetch = async (query: GridQuery, signal: AbortSignal): Promise<GridPage<PivotDisplayRow>> => {\n const { start, count } = query.range;\n const held = answered.window;\n // The rows the report has end at its row count: a range past it is held when what of it there is, is.\n const end = Math.min(start + count, answered.metadata.rowCount);\n if (start >= held.start && end <= held.start + answered.rows.length) return pageOf(answered);\n const update = await request.source.window(Object.freeze({\n requestId: request.nextRequestId(),\n layout: request.layout,\n settings: request.settings,\n window: Object.freeze({ start, count }),\n baseline: version,\n markChanges: false,\n maxLeaves: request.maxLeaves,\n }), signal);\n if (update.refusal !== undefined) throw new Error(update.refusal.message);\n if (update.metadata.version !== version) throw new ReportMovedError();\n return pageOf(update);\n };\n // A step that cannot go on is given up: nothing moves, and nothing claims \"no match\" for cells it could not read\n // (ADR-0025). The grid takes an AbortError as a step its Consumer gave up; the pivot says why while the report is\n // the one shown, and over one since replaced the grid says its source changed.\n const find = async (step: GridFindRequest, _query: unknown, signal: AbortSignal): Promise<GridFindResult> => {\n const read = await findInReport(request.source, answered.metadata, step, signal);\n if (read.kind === 'answered') return read.answer;\n request.findGivenUp(read);\n throw new DOMException('The Find step over the report was given up.', 'AbortError');\n };\n return GridSource.fetch(fetch, {\n rowKey: reportRowKey,\n readAheadRows: 60,\n find,\n // The Selection Summary is the report source's, over the report the selection was made on (ADR-0130).\n summarize: (summary, _query, signal) => summarizeReport(request.source, version, summary, request.words(), signal),\n // A Window of another report is never shown beside this one's rows: the pivot asks again, and the grid\n // stands on what it holds meanwhile. Any other failure is the grid's to say (ADR-0025).\n onFetchFailed: ({ error }) => {\n if (!(error instanceof ReportMovedError)) throw error;\n request.moved();\n },\n });\n}\n\n/** What one cell of the report stands for (ADR-0340): its row's Items and, for a value cell, its column's. */\nexport interface PivotCellItems {\n /** The Items its row's path names, outermost first. */\n readonly row: readonly PivotFieldItem[];\n /** The Items its column's path names, outermost first; none for a label cell. */\n readonly column: readonly PivotFieldItem[];\n}\n\n// A label column of its own field (outline and tabular forms) shows that field's Item, so its cell stands for the\n// path down to it; the compact form's one column shows the row's own.\nfunction labelPath(path: readonly PivotFieldItem[], column: PivotLabelColumn): readonly PivotFieldItem[] {\n const at = column.field === undefined ? -1 : path.findIndex(item => item.field === column.field);\n return at < 0 ? path : Object.freeze(path.slice(0, at + 1));\n}\n\nconst noItems: readonly PivotFieldItem[] = Object.freeze([]);\n\n/**\n * What each cell of a selection of the report grid stands for (ADR-0340, Q5), as the Razor component's `ItemsOf`\n * reads it: each cell once, in the order selected. `undefined` when the selection reaches a row the grid does not\n * hold drawn now, or a column past the report's, which is read from no Items rather than from some of them\n * (spine rule 1).\n */\nexport function cellItems(\n selection: GridSelection, metadata: PivotReportMetadata, rows: readonly PivotDisplayRow[], windowStart: number,\n): readonly PivotCellItems[] | undefined {\n const labels = metadata.labelColumns.length;\n // A cell two ranges both hold is said once; one range holds each of its cells once.\n const seen = selection.ranges.length > 1 ? new Set<string>() : undefined;\n const cells: PivotCellItems[] = [];\n for (const range of selection.ranges) {\n const bottom = range.topRow + range.rowCount - 1;\n const right = range.leftColumn + range.columnCount - 1;\n if (range.topRow < windowStart || bottom >= windowStart + rows.length || right >= labels + metadata.valueColumns.length) return undefined;\n for (let r = range.topRow; r <= bottom; r++) {\n const row = elementAt(rows, r - windowStart);\n for (let c = range.leftColumn; c <= right; c++) {\n if (seen !== undefined) {\n const key = `${r},${c}`;\n if (seen.has(key)) continue;\n seen.add(key);\n }\n cells.push(Object.freeze(c < labels\n ? { row: labelPath(row.rowPath, elementAt(metadata.labelColumns, c)), column: noItems }\n : { row: row.rowPath, column: elementAt(metadata.valueColumns, c - labels).columnPath }));\n }\n }\n }\n return Object.freeze(cells);\n}\n", "// Find over the report as shown (ADR-0332 \u00A71), the Razor component's FindInReportAsync: ExPivot answers each step\n// of its report grid's Find as that grid's Consumer (ADR-0055). What is searched is every cell the report lays\n// out, the row labels, values and totals, by its displayed text, the text the user reads. The column Items and the\n// value captions stand in the grid's headers and Header Groups, which the grid searches itself (ADR-0333). A\n// collapsed group is not searched inside, because its rows are not laid out, and nothing is expanded to show a\n// match: a search never changes the report's shape. The cells outside the Window are read from the report source\n// by the Report Version on screen, as Copy reads them, in blocks, so a step that finds early stops reading.\n\nimport { findMatches, type GridFindRequest, type GridFindResult } from '@ex-grid/core';\nimport type { PivotReportCopyBlock, PivotReportMetadata, PivotReportRefusal, PivotReportSource } from '@ex-grid/pivot-engine';\nimport { elementAt } from './must';\n\n// How many cells one read of the report asks for: a step that finds early stops reading, and a remote report is\n// asked in blocks rather than for the whole report at once.\nconst findBlockCells = 20_000;\n\n/** What one step over one Report Version came to: an answer, or why it cannot be given. */\nexport type ReportFindRead =\n | { readonly kind: 'answered'; readonly answer: GridFindResult }\n /** The source no longer holds the Report Version the step reads. */\n | { readonly kind: 'notHeld' }\n /** The source refused to be read. */\n | { readonly kind: 'refused'; readonly refusal: PivotReportRefusal }\n /** The source answered another version or range than it was asked. */\n | { readonly kind: 'invalid' };\n\n/** A step that cannot go on, and why. */\nexport type ReportFindGivenUp = Exclude<ReportFindRead, { readonly kind: 'answered' }>;\n\nconst notFound: ReportFindRead = Object.freeze({ kind: 'answered', answer: Object.freeze({ found: false }) });\nconst notHeld: ReportFindRead = Object.freeze({ kind: 'notHeld' });\nconst invalid: ReportFindRead = Object.freeze({ kind: 'invalid' });\n\n/**\n * One Find step over the report `metadata` describes, in ADR-0055's order: row by row, across a row in the\n * request's column order, from the cell after the Focus, wrapping, the Focus's own cell last; within the selection\n * when more than one cell is selected. A column of the request the report does not lay out is skipped.\n */\nexport async function findInReport(\n source: PivotReportSource, metadata: PivotReportMetadata, request: GridFindRequest, signal: AbortSignal,\n): Promise<ReportFindRead> {\n const rows = metadata.rowCount;\n const known = new Set([...metadata.labelColumns.map(column => column.name), ...metadata.valueColumns.map(column => column.name)]);\n // The request's columns the report lays out, by their position in the request.\n const read = request.columns.flatMap((name, position) => (known.has(name) ? [{ name, position }] : []));\n const columns = request.columns.length;\n if (request.text === '' || rows === 0 || read.length === 0) return notFound;\n\n // Where the walk starts: past the Focus, which is looked at last; without one, from the first cell (the last,\n // backward), as the reference step walks.\n const { backward, from, scope } = request;\n const [startRow, startColumn] = from !== undefined && from.row >= 0 && from.row < rows && from.column >= 0 && from.column < columns\n ? [from.row, from.column]\n : backward ? [0, 0] : [rows - 1, columns - 1];\n const step = backward ? -1 : 1;\n const names = Object.freeze(read.map(column => column.name));\n const blockRows = Math.max(1, Math.floor(findBlockCells / names.length));\n\n // The rows a block may hold: within the scope's rows when there is one, so no block reads past them.\n let first = scope === undefined ? 0 : rows - 1;\n let last = scope === undefined ? rows - 1 : 0;\n if (scope !== undefined) {\n for (const range of scope) {\n first = Math.min(first, Math.max(0, range.topRow));\n last = Math.max(last, Math.min(rows - 1, range.topRow + range.rowCount - 1));\n }\n }\n // The Focus's row is visited twice: first past the Focus, last up to it and on it.\n const visited = (visit: number, position: number): boolean => {\n if (visit === 0) return backward ? position < startColumn : position > startColumn;\n if (visit === rows) return backward ? position >= startColumn : position <= startColumn;\n return true;\n };\n\n let block: PivotReportCopyBlock | undefined;\n let blockTop = 0;\n for (let visit = 0; visit <= rows; visit++) {\n signal.throwIfAborted();\n const row = (((startRow + step * visit) % rows) + rows) % rows;\n if (scope !== undefined && !scope.some(range => row >= range.topRow && row < range.topRow + range.rowCount)) continue;\n // A row with no cell left to look at is not read: the Focus at the end of the last row, a step from the start.\n if (!read.some(({ position }) => visited(visit, position))) continue;\n if (block === undefined || row < blockTop || row >= blockTop + block.rows.length) {\n // Once the walk has wrapped, it ends on the Focus's row: a block reads no row past it, which was searched first.\n const wrapped = visit > 0 && (backward ? row >= startRow : row <= startRow);\n const top = backward ? Math.max(first, row - blockRows + 1, wrapped ? startRow : 0) : row;\n const bottom = backward ? row : Math.min(last, row + blockRows - 1, wrapped ? startRow : rows - 1);\n const answer = await source.copy(Object.freeze({\n version: metadata.version,\n columns: names,\n ranges: Object.freeze([Object.freeze({ top, left: 0, bottom, right: names.length - 1 })]),\n maxCells: (bottom - top + 1) * names.length,\n }), signal);\n signal.throwIfAborted();\n if (answer.refusal?.kind === 'reportVersionNotHeld') return notHeld;\n if (answer.refusal !== undefined) return Object.freeze({ kind: 'refused', refusal: answer.refusal });\n const got = answer.blocks[0];\n if (answer.version !== metadata.version || answer.blocks.length !== 1 || got === undefined || got.rows.length !== bottom - top + 1\n || got.rows.some(cells => cells.length !== names.length)) {\n return invalid;\n }\n block = got;\n blockTop = top;\n }\n const cells = elementAt(block.rows, row - blockTop);\n for (let k = 0; k < read.length; k++) {\n const index = backward ? read.length - 1 - k : k;\n const { name, position } = elementAt(read, index);\n if (!visited(visit, position)) continue;\n if (scope !== undefined && !scope.some(range => row >= range.topRow && row < range.topRow + range.rowCount\n && position >= range.leftColumn && position < range.leftColumn + range.columnCount)) continue;\n if (findMatches(elementAt(cells, index).text, request)) {\n return Object.freeze({ kind: 'answered', answer: Object.freeze({ found: true, row, column: name }) });\n }\n }\n }\n return notFound;\n}\n", "// The Selection Summary over the report (ADR-0130), the Razor component's `SummarizeReportAsync`: the report\n// source sums the cells it laid out, under the Report Version the selection was made on, and the figures are\n// read from its counts, sum and extremes as C#'s `GridSummaryCells` reads a server's parts. A figure that reads\n// numbers is written in the Focus value's number format, as the report shows that value.\n\nimport { answeredSummary, declinedSummary, summaryFigureOrder, type AggregateResult, type GridSummaryRequest, type GridSummaryResult, type SummaryFigure } from '@ex-grid/core';\nimport { formatPivotFigure, pivotNumberAverage, pivotNumberCanonical, pivotNumberValue, type PivotNumber, type PivotReportSource, type PivotReportSummaryResult } from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\nimport type { PivotScreenWords } from './words';\n\nconst empty: AggregateResult = Object.freeze({ kind: 'empty' });\n\n/** The figures `request` asks for over the report of `version`, or a decline in ExPivot's words (ADR-0060). */\nexport async function summarizeReport(\n source: PivotReportSource, version: string, request: GridSummaryRequest, words: PivotScreenWords, signal: AbortSignal,\n): Promise<GridSummaryResult> {\n const { focus } = request;\n const query = Object.freeze({\n version,\n columns: request.columns,\n ranges: Object.freeze(request.ranges.map(range => Object.freeze({\n top: range.topRow, left: range.leftColumn, bottom: range.topRow + range.rowCount - 1, right: range.leftColumn + range.columnCount - 1,\n }))),\n ...(focus === undefined ? {} : { focusRow: focus.row, focusColumn: focus.column }),\n });\n const answer = await source.summary(query, signal);\n if (answer.version !== version) return declinedSummary(words.word('summary-another-version'));\n if (answer.refusal !== undefined) return declinedSummary(words.reportRefused(answer.refusal));\n // An error is counted among the values: an answer that says one was selected and counts no value contradicts itself.\n if (answer.hasError && answer.values <= 0) return declinedSummary(words.word('summary-inconsistent-errors'));\n return figuresOf(answer, request.figures);\n}\n\n// Each figure asked for, in Excel's order, by the rules C#'s accumulator reads merged parts by: a figure that reads\n// numbers is empty where no cell holds one, an error among the values shows only the counts, a value that is no finite\n// number makes every figure that reads numbers #NUM!, and a figure that overflows is #NUM! alone.\nfunction figuresOf(answer: PivotReportSummaryResult, asked: readonly SummaryFigure[]): GridSummaryResult {\n const { values, numbers, min, max, hasError, numberFormat, locale } = answer;\n const figures: Partial<Record<SummaryFigure, AggregateResult>> = {};\n const texts: Partial<Record<SummaryFigure, string>> = {};\n // A value that is no finite number is one of the extremes; a sum of finite values may still overflow.\n const nonFinite = [min, max].some(number => number !== undefined && !finite(number));\n for (const figure of summaryFigureOrder) {\n if (!asked.includes(figure)) continue;\n const counts = figure === 'count' || figure === 'numericalCount';\n if (!counts && numbers === 0) figures[figure] = empty;\n else if (!counts && hasError) figures[figure] = Object.freeze({ kind: 'error', error: 'errorAmongValues' });\n else if (values === 0) figures[figure] = empty;\n else if (counts) figures[figure] = countOf(figure === 'count' ? values : numbers);\n else {\n const number = pivotNumberCanonical(numberOf(figure, answer));\n if (nonFinite || !finite(number)) {\n figures[figure] = Object.freeze({ kind: 'error', error: 'notANumber' });\n } else {\n figures[figure] = resultOf(number);\n if (numberFormat !== undefined) texts[figure] = formatPivotFigure(number, numberFormat, locale);\n }\n }\n }\n return answeredSummary(figures, texts);\n}\n\nfunction numberOf(figure: SummaryFigure, answer: PivotReportSummaryResult): PivotNumber {\n const { numbers, sum, min, max } = answer;\n switch (figure) {\n case 'sum': return held(sum, figure);\n case 'average': return pivotNumberAverage(held(sum, figure), numbers);\n case 'min': return held(min, figure);\n case 'max': return held(max, figure);\n case 'count':\n case 'numericalCount': throw new Error(`Internal: ${figure} is a count.`);\n default: return unreachable(figure);\n }\n}\n\n// The report source answers a sum and both extremes wherever it counted a number.\nfunction held(number: PivotNumber | undefined, figure: SummaryFigure): PivotNumber {\n if (number === undefined) throw new Error(`The report source counted numbers and answered no ${figure} of them (ADR-0130).`);\n return number;\n}\n\nfunction finite(number: PivotNumber): boolean {\n return Number.isFinite(pivotNumberValue(number));\n}\n\nfunction countOf(count: number): AggregateResult {\n return Object.freeze({ kind: 'number', number: count, exact: Object.freeze({ mantissa: BigInt(count), scale: 0 }) });\n}\n\nfunction resultOf(number: PivotNumber): AggregateResult {\n return Object.freeze(number.kind === 'exact'\n ? { kind: 'number', number: pivotNumberValue(number), exact: number.value }\n : { kind: 'number', number: number.value, exact: undefined });\n}\n", "// The report's own commands in the grid's Context Menu (ADR-0036, ADR-0059): the ones the Razor component's\n// ContextCommandsFor builds, in its order and under its ids, after the grid's clipboard commands. Each is enabled from\n// the report the menu was opened over, and runs against the report's layout when it is chosen: where that layout no\n// longer holds what it was for, it changes nothing (spine rule 6).\n\nimport type { GridCommand } from '@ex-grid/core';\nimport {\n isItemCollapsed, placementOf, removeEntry, setCollapsed, setFieldCollapsed, setSort, sortsEqual, valueFieldsEqual,\n type PivotDisplayRow, type PivotFieldItem, type PivotFieldPlacement, type PivotLayout, type PivotReportMetadata, type PivotSort,\n} from '@ex-grid/pivot-engine';\nimport { defined, elementAt } from './must';\n\n/** What the menu was opened over. */\nexport interface ReportMenuModel {\n readonly metadata: PivotReportMetadata;\n /** The row it was opened on, which the report on screen holds. */\n readonly row: PivotDisplayRow;\n /** The name of the column it was opened on. */\n readonly column: string;\n /** The report's layout now: the one it shows, or is on its way to, which its commands are run against. */\n readonly report: PivotLayout;\n /** The pane's layout now, which is the report's unless Defer Layout Update holds another: Value Field Settings\u2026\n * opens in the pane, under the entry it shows. */\n readonly pane: PivotLayout;\n readonly fieldListShown: boolean;\n /** A field's caption. */\n readonly captionOf: (field: string) => string;\n}\n\n/** What the commands do. */\nexport interface ReportMenuActions {\n /** A change of the report's layout, made from the layout when chosen; `undefined` changes nothing. An Item\n * expanded or collapsed is named, and keeps the Focus in the report the change brings. */\n readonly edit: (edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: PivotFieldItem) => void;\n /** Show Details on the row's value cell in `valueColumn`. */\n readonly showDetails: (valueColumn: number) => void;\n /** Value Field Settings\u2026 for the Value Field at `valueField`, in the pane, while `holds` says the pane holds the\n * one the cell showed there. */\n readonly valueFieldSettings: (valueField: number, holds: (pane: PivotLayout) => boolean) => void;\n readonly setFieldListShown: (shown: boolean) => void;\n}\n\n/** The id of \"Remove <field>\", which carries the field's caption after it. */\nexport const removeNamedFieldId = 'remove-named-field';\n\n/** The caption \"Remove <field>\" names, from its command's id; `undefined` for any other id. */\nexport function captionOfRemove(id: string): string | undefined {\n const prefix = `${removeNamedFieldId}:`;\n return id.startsWith(prefix) ? id.slice(prefix.length) : undefined;\n}\n\n// The outer Item a row's Expand and Collapse act on: the innermost of its row Items that has Items under it.\nfunction collapsibleItemOf(metadata: PivotReportMetadata, row: PivotDisplayRow): PivotFieldItem | undefined {\n const path = row.rowPath;\n for (let level = path.length - 1; level >= 0; level--) {\n if (level < metadata.layout.rows.length - 1) return elementAt(path, level);\n }\n return undefined;\n}\n\nfunction innermostFieldOf(row: PivotDisplayRow): string | undefined {\n return row.rowPath.at(-1)?.field;\n}\n\n// The Value Field a value cell shows: its row's, its column's, or the one Value Field.\nexport function valueFieldAt(metadata: PivotReportMetadata, row: PivotDisplayRow, valueColumn: number): number {\n if (row.valueField >= 0) return row.valueField;\n const column = elementAt(metadata.valueColumns, valueColumn);\n if (column.valueField >= 0) return column.valueField;\n return metadata.layout.values.length === 1 ? 0 : -1;\n}\n\nfunction inRows(layout: PivotLayout, field: string): boolean {\n return placementOf(layout, field)?.area === 'rows';\n}\n\n/** The report's commands for the cell the menu was opened on. Which Items and fields they stand for is read from the\n * report on screen; whether each would change something, from the report's layout, which it is run against. */\nexport function reportMenuCommands(model: ReportMenuModel, actions: ReportMenuActions): readonly GridCommand[] {\n const { metadata, row, column, report, pane, captionOf } = model;\n const labelColumn = metadata.labelColumns.findIndex(label => label.name === column);\n const valueColumn = labelColumn >= 0 ? -1 : metadata.valueColumns.findIndex(value => value.name === column);\n const commands: GridCommand[] = [];\n const add = (id: string, enabled: boolean, invoke: () => void): void => { commands.push(Object.freeze({ id, enabled, invoke })); };\n // A change of a field in Rows, made while the layout still holds it there.\n const editRows = (field: string, edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: PivotFieldItem): () => void =>\n () => { actions.edit(now => (inRows(now, field) ? edit(now) : undefined), toggled); };\n const inReport = (field: string): PivotFieldPlacement | undefined => report.rows.find(placement => placement.field === field);\n\n const item = collapsibleItemOf(metadata, row);\n if (item !== undefined) {\n const placement = inReport(item.field);\n const collapsed = placement !== undefined && isItemCollapsed(placement, item.item);\n const toggled = placement !== undefined && placement.toggledItems.length > 0;\n add('expand', collapsed, editRows(item.field, now => setCollapsed(now, item.field, item.item, false), item));\n add('collapse', placement !== undefined && !collapsed, editRows(item.field, now => setCollapsed(now, item.field, item.item, true), item));\n add('expand-field', placement !== undefined && (placement.collapsed || toggled), editRows(item.field, now => setFieldCollapsed(now, item.field, false)));\n add('collapse-field', placement !== undefined && (!placement.collapsed || toggled), editRows(item.field, now => setFieldCollapsed(now, item.field, true)));\n }\n\n const field = labelColumn >= 0\n ? elementAt(metadata.labelColumns, labelColumn).field ?? (row.valueField < 0 ? innermostFieldOf(row) : undefined)\n : innermostFieldOf(row);\n // A sort by a Value Field is by the one the cell shows, while the layout holds it at the same place.\n const sortBy = (sortField: string, sort: PivotSort, holds: (now: PivotLayout) => boolean): void => {\n const placement = inReport(sortField);\n add(sortCommandId(sort), placement !== undefined && holds(report) && !sortsEqual(placement.sort, sort),\n editRows(sortField, now => (holds(now) ? setSort(now, sortField, sort) : undefined)));\n };\n if (labelColumn >= 0 && field !== undefined) {\n sortBy(field, { direction: 'ascending' }, () => true);\n sortBy(field, { direction: 'descending' }, () => true);\n }\n if (valueColumn >= 0) {\n const valueField = valueFieldAt(metadata, row, valueColumn);\n const shown = metadata.layout.values[valueField];\n const holds = (now: PivotLayout): boolean => {\n const at = now.values[valueField];\n return shown !== undefined && at !== undefined && valueFieldsEqual(at, shown);\n };\n if (field !== undefined && shown !== undefined) {\n sortBy(field, { direction: 'ascending', byValue: valueField }, holds);\n sortBy(field, { direction: 'descending', byValue: valueField }, holds);\n }\n // Show Details is always offered: the tab, the dialog or the Consumer takes the records (ADR-0059). An empty\n // cell has none to show.\n add('show-details', row.values[valueColumn] !== undefined, () => { actions.showDetails(valueColumn); });\n // The panel opens in the pane, under the Value Field's entry: offered while the pane shows that Value Field\n // where the report does.\n if (shown !== undefined) add('value-field-settings', holds(pane), () => { actions.valueFieldSettings(valueField, holds); });\n }\n if (field !== undefined) {\n add(`${removeNamedFieldId}:${captionOf(field)}`, inReport(field) !== undefined, editRows(field, now => removeEntry(now, defined(placementOf(now, field), 'the field in Rows'))));\n }\n if (model.fieldListShown) add('hide-field-list', true, () => { actions.setFieldListShown(false); });\n else add('show-field-list', true, () => { actions.setFieldListShown(true); });\n return Object.freeze(commands);\n}\n\nfunction sortCommandId(sort: PivotSort): string {\n if (sort.byValue === undefined) return sort.direction === 'ascending' ? 'sort-ascending' : 'sort-descending';\n return sort.direction === 'ascending' ? 'sort-smallest-to-largest' : 'sort-largest-to-smallest';\n}\n\n", "// The words ExPivot's screen paints, by id (ADR-0370 section 10): the Consumer's label function first, then\n// the engine's English, and an id neither knows painted as itself, a missing word seen, never a blank. The\n// tables are the engine's, so a report's own words and the Field List's come from one place.\n\nimport { fillPivotWord, pivotWord, type PivotArea, type PivotLabel, type PivotLayoutChoice, type PivotReportRefusal, type PivotSourceRefusal } from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\n\n/** The words of one pivot, under the label function it was given. */\nexport class PivotScreenWords {\n readonly #label: PivotLabel | undefined;\n\n constructor(label: PivotLabel | undefined) {\n this.#label = label;\n }\n\n /** The label function the words were made with: the one the report is laid out with too. */\n get label(): PivotLabel | undefined {\n return this.#label;\n }\n\n /** The word for `id`. */\n word(id: string): string {\n return pivotWord(id, this.#label);\n }\n\n /** The template word for `id`, filled as .NET fills one. */\n fill(id: string, ...args: readonly string[]): string {\n return fillPivotWord(this.word(id), ...args);\n }\n\n /** What a source that threw says where the user sees it. */\n failed(error: unknown): string {\n return this.fill('source-failed', messageOf(error));\n }\n\n /** What a Stale Report says of a source that threw while asked for newer data (ADR-0067). */\n staleFailed(error: unknown): string {\n return this.fill('stale-source-failed', messageOf(error));\n }\n\n /** What a Pivot Source's refusal says where the user sees it: data that moved on under the report asks for a\n * refresh (ADR-0066), and any other refusal is said in the source's words. */\n sourceRefused(refusal: PivotSourceRefusal): string {\n return refusal.kind === 'sourceVersionNotHeld' ? this.word('data-changed') : this.fill('source-refused', refusal.message);\n }\n\n /** What a report source's refusal says where the user sees it: the Pivot Source's refusal it carries in that\n * source's words, a report the source no longer holds as data that moved on (ADR-0066), and any other in the\n * report source's words. */\n reportRefused(refusal: PivotReportRefusal): string {\n if (refusal.sourceRefusal !== undefined) return this.sourceRefused(refusal.sourceRefusal);\n return refusal.kind === 'reportVersionNotHeld' ? this.word('data-changed') : this.fill('source-refused', refusal.message);\n }\n\n /** An Area's title: `Filters`, `Columns`, `Rows`, `Values`. */\n area(area: PivotArea): string {\n return this.word(areaWordId(area));\n }\n}\n\n/** The id of an Area's title. */\nexport function areaWordId(area: PivotArea): string {\n switch (area) {\n case 'filters': return 'area-filters';\n case 'columns': return 'area-columns';\n case 'rows': return 'area-rows';\n case 'values': return 'area-values';\n default: return unreachable(area);\n }\n}\n\n/** The id of a Layout menu choice's command, which is also the id of its word, as the Razor component's\n * `PivotCommandIds.LayoutChoice` names it (ADR-0061). */\nexport function layoutChoiceId(choice: PivotLayoutChoice): string {\n switch (choice) {\n case 'doNotShowSubtotals': return 'subtotals-do-not-show';\n case 'showSubtotalsAtBottom': return 'subtotals-at-bottom';\n case 'showSubtotalsAtTop': return 'subtotals-at-top';\n case 'grandTotalsOff': return 'grand-totals-off';\n case 'grandTotalsOn': return 'grand-totals-on';\n case 'grandTotalsOnRowsOnly': return 'grand-totals-rows-only';\n case 'grandTotalsOnColumnsOnly': return 'grand-totals-columns-only';\n case 'compactForm': return 'form-compact';\n case 'outlineForm': return 'form-outline';\n case 'tabularForm': return 'form-tabular';\n case 'repeatItemLabels': return 'repeat-item-labels';\n case 'doNotRepeatItemLabels': return 'do-not-repeat-item-labels';\n default: return unreachable(choice);\n }\n}\n\n// What a thrown value says: an Error's message, and anything else as it prints.\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["// The locale a Framework Adapter hands the pivot when the Consumer gives none (ADR-0370 section 10): the\n// browser's own, as the browser ranks its languages. The pivot writes numbers only in the locales its engine\n// holds, so a language it does not hold is passed over for the next the browser lists. A language is never\n// stood in for by another, its region dropped: `es-419` written as `es` would group thousands with a point\n// for readers who read it as a decimal. A browser with none it holds is refused, naming them.\n\nimport { pivotLocales } from '@ex-grid/pivot-engine';\n\n/**\n * The first of `languages`, in the browser's order, that the pivot writes in, matched whole and without\n * regard to case. A list with none it holds throws a `RangeError` that says to pass `locale`.\n */\nexport function browserPivotLocale(languages: readonly string[]): string {\n const held = new Map(pivotLocales().map(name => [name.toLowerCase(), name]));\n for (const tag of languages) {\n const exact = held.get(tag.toLowerCase());\n if (exact !== undefined) return exact;\n }\n throw new RangeError(`None of the browser's languages (${languages.join(', ')}) is one the pivot writes numbers in: pass locale, a BCP 47 tag or 'invariant' (ADR-0370 section 10).`);\n}\n", "import { createGrid, type GridHandle, type GridOptions } from '@ex-grid/core';\nimport type { PivotShowDetailsEvent } from './details';\nimport { PivotView, type PivotViewOptions } from './pivot-view';\n\n/** An ExPivot drawn into an element, handed back by {@link createPivot}. */\nexport interface PivotHandle {\n /** Takes the options again, whole: what did not change asks nothing again. */\n update(options: PivotViewOptions): void;\n /** Opens the records of a Show Details event this pivot raised, as `detailsView` says: what a Consumer that\n * heard `onShowDetails` and does not take them hands back (ADR-0059). */\n openDetails(event: PivotShowDetailsEvent): void;\n /**\n * The grid that takes the inputs made at `element` (ADR-0240 section 6): a Show Details grid's, where `element`\n * stands in that grid's Input Root, else the report's; undefined while the report draws no grid. For a Framework\n * Adapter whose Chrome's contents arrive later than their slot, to hold that grid's inputs and Settled Mark until\n * they stand (ADR-0410 section 5).\n */\n gridAround(element: Element): GridHandle<unknown> | undefined;\n /** Holds the Settled Mark (ADR-0220) of the grid `element` stands in, as `gridAround` finds it, until the\n * function it answers is called. Where no grid stands there yet, the hold waits for the grid that comes to: the\n * report's next one while the report draws none, and a grid being made for a part it mounted before placing it,\n * which meanwhile holds every grid. */\n holdSettled(element: Element): () => void;\n /** Stops the pivot: it asks and hears nothing more, and empties its element. The source stays the\n * Consumer's. */\n destroy(): void;\n}\n\n/**\n * Draws an ExPivot into `element`, which becomes its root (ADR-0370 section 1): the report, drawn by ExGrid,\n * beside the Field List. The pivot owns everything inside it; a Framework Adapter renders the element and\n * hands the pivot its props, and nothing here assumes React's lifecycle or Blazor's.\n */\nexport function createPivot(element: HTMLElement, options: PivotViewOptions): PivotHandle {\n const grids = new PivotGrids(element);\n const view = new PivotView(element, options, (root, gridOptions) => grids.mount(root, gridOptions));\n return Object.freeze({\n update: (next: PivotViewOptions) => { view.update(next); },\n openDetails: (event: PivotShowDetailsEvent) => { view.openDetails(event); },\n gridAround: (within: Element) => grids.around(within),\n holdSettled: (within: Element) => grids.holdSettled(within),\n destroy: () => { view.destroy(); },\n });\n}\n\n/** A hold of the Settled Mark taken before the grid it holds stood: let go, or handed to that grid's once it stands. */\ninterface WaitingHold {\n readonly element: Element;\n readonly releases: (() => void)[];\n gone: boolean;\n}\n\n/** Draws a grid into an element: ExGrid's `createGrid`, or a layer-2 test's own. */\nexport type MakeGrid = <Row>(root: HTMLElement, options: GridOptions<Row>) => GridHandle<Row>;\n\n/** The grids a pivot draws, each by its root: the report's, and Show Details'. */\nexport class PivotGrids {\n readonly #pivot: HTMLElement;\n readonly #make: MakeGrid;\n readonly #grids = new Map<HTMLElement, GridHandle<unknown>>();\n readonly #waiting = new Set<WaitingHold>();\n\n constructor(pivot: HTMLElement, make: MakeGrid = createGrid) {\n this.#pivot = pivot;\n this.#make = make;\n }\n\n mount<Row>(root: HTMLElement, options: GridOptions<Row>): GridHandle<Row> {\n const grid = this.#make(root, options);\n // The grid's own members, its getters among them, with a destroy that forgets it first.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Object.create answers any; the members are the grid's\n const handle = Object.freeze(Object.create(grid, {\n destroy: { value: () => { this.#grids.delete(root); grid.destroy(); }, enumerable: true },\n })) as GridHandle<Row>;\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- kept to hold and order, which read no row\n this.#grids.set(root, handle as unknown as GridHandle<unknown>);\n // A hold taken before this grid stood holds it, once what it was taken for stands in the grid's Input Root:\n // the report's while the report drew no grid, and a part the grid mounted as it was made, before its first\n // paint placed it.\n const inputRoot = this.#inputRootOf(root);\n for (const waiting of this.#waiting) {\n if (this.#inputRootOf(waiting.element) !== inputRoot) continue;\n this.#waiting.delete(waiting);\n if (!waiting.gone) waiting.releases.push(handle.holdSettled());\n }\n return handle;\n }\n\n around(element: Element): GridHandle<unknown> | undefined {\n const inputRoot = this.#inputRootOf(element);\n const report = this.#gridIn(this.#pivot);\n if (inputRoot === this.#pivot || inputRoot === undefined) return report;\n return this.#gridIn(inputRoot) ?? report;\n }\n\n holdSettled(element: Element): () => void {\n const inputRoot = this.#inputRootOf(element);\n const grid = inputRoot === undefined ? undefined : this.#gridIn(inputRoot);\n if (grid !== undefined) return grid.holdSettled();\n // No grid stands where the element does yet. One not yet placed holds every grid now, as it may stand in any,\n // and each waits for the grid it comes to stand in.\n const waiting: WaitingHold = { element, releases: inputRoot === undefined ? [...this.#grids.values()].map(each => each.holdSettled()) : [], gone: false };\n this.#waiting.add(waiting);\n return () => {\n waiting.gone = true;\n this.#waiting.delete(waiting);\n for (const release of waiting.releases) release();\n };\n }\n\n // The grid whose Input Root is `inputRoot`.\n #gridIn(inputRoot: HTMLElement): GridHandle<unknown> | undefined {\n for (const [root, grid] of this.#grids) {\n if (this.#inputRootOf(root) === inputRoot) return grid;\n }\n return undefined;\n }\n\n // The Input Root an element stands in: the pivot's, or a Show Details grid's; undefined for one outside the pivot,\n // or not yet in the document.\n #inputRootOf(element: Element): HTMLElement | undefined {\n const around = element.parentElement?.closest<HTMLElement>('[data-ex-input-root]');\n return around === null || around === undefined || !this.#pivot.contains(around) ? undefined : around;\n }\n}\n", "// ExPivot's Script Core (ADR-0370 section 1): Excel's PivotTable, drawn by ExGrid as that grid's Consumer\n// (ADR-0059). It holds the Pivot Layout and asks its report source; ExGrid paints, selects, navigates and\n// copies. It owns the DOM inside its own root, writes the Razor component's DOM contract and reads ExPivot's\n// stylesheet unchanged (ADR-0350 section 4), and depends on no UI framework.\n//\n// Every move is a question, and only the newest question's answer is shown: a move made while a question is\n// out is taken against the layout that question asks for, and when that question is refused every move taken\n// against it is refused with it, and the pane goes back to the layout the report shows (ADR-0370 section 3,\n// spine rule 6). The one clock it waits on is the redraw interval (ADR-0067): the source's changes of data are\n// gathered, and asked for at most once per interval, which decides when the newest data reaches the screen, never\n// which data it is.\n\nimport {\n CellTextMetrics, GridPresentationDefaults, gridTextGeometry, type GridColumnWidthChange, type GridDensity, type GridHandle, type GridOptions,\n type GridSelection, type GridTextGeometry, type GridTextOptions,\n type CellPosition, type GridCommand, type GridContextMenuContext,\n type FetchingGridSource, type GridRefusal, type ViewportSize, type GridColumn, type GridCopyAnswer, type GridCopyRequest,\n type SelectionSummary, type SummaryFigure,\n assembleCopy, builtInCommandLabel, defaultChangeHighlightMs, defaultSummaryFigures, reloadNoticeLabelIds, summaryFigureOrder, systemClock,\n} from '@ex-grid/core';\nimport {\n FetchingPivotSource, LocalPivotReportSource, chooseLayout, defaultMaxLeaves, emptyPivotLayout, formatPivotCount, isLayoutChosen, isValuesPseudoField,\n layoutChoiceChanges, pivotLayoutChoices, pivotValueCaptions, placementOf, placementsIn, isItemCollapsed, pivotWord, pivotWordIdList, setCollapsed, setHiddenItems,\n itemKeysEqual, pivotItemKeyId, validateLayout, writePivotLayoutJson, type PivotDisplayRow, type PivotEntry, type PivotFieldPlacement, type PivotItemInfo, type PivotItemCounts, type PivotLabel, type PivotLayout, type PivotLayoutChoice,\n type PivotReportCopyCell, type PivotReportRefusal, type PivotReportSettings, type PivotSourceChanged, type PivotReportState, type PivotSlicing, type PivotSource, type PivotToggle,\n pivotReportDetailsQuery, PivotItemPage, itemsOfPage, PivotChangeTimes, type PivotFieldItem,\n} from '@ex-grid/pivot-engine';\nimport { detailsEvent, detailsProblemText, type PivotDetailItem, type PivotDetailsView, type PivotShowDetailsEvent } from './details';\nimport {\n checkedPivotChrome, StandingSlot, type PivotChrome, type PivotChromeSlot, type PivotReportFiltersSlotContext, type PivotReportFiltersView, type PivotStaleReportSlotContext,\n type PivotStaleReportView, type PivotToolbarSlotContext, type PivotToolbarView,\n} from './chrome';\nimport { DetailsSheets, type MountGrid } from './details-view';\nimport { entryMenuCommands, entryOfField, type EntryMenuCommand, type EntryPanel } from './entry-menu';\nimport { FieldListView, fieldOf, sameEntry, type FieldListEdit, type FieldListHandlers, type FieldListMove } from './field-list';\nimport { entryKey, SlottedFieldList } from './field-list-slot';\nimport { itemFilterPanel, itemsProblemText } from './item-filter';\nimport { ItemListings, pendingFirst, searchItems, type FieldItems, type ItemsUnder } from './items';\nimport { PivotMenuFrame, SlottedMenuFrame, type PivotMenu, type PivotMenuCommand } from './menu';\nimport { clearStyle, element, writeStyle } from './dom';\nimport { stylesheetName, stylesheetStamp } from './shipped-stylesheet';\nimport { defined, elementAt, unreachable } from './must';\nimport { fieldSettingsPanel, valueFieldSettingsPanel, type PivotPanel } from './panels';\nimport { checkedName, PartElements, swap, type PartRefs } from './parts';\nimport { cellItems, ReportColumns, reportMatch, reportRows, type PivotCellItems } from './report-grid';\nimport type { ReportFindGivenUp } from './report-find';\nimport { captionOfRemove, removeNamedFieldId, reportMenuCommands, valueFieldAt } from './report-menu';\nimport { layoutChoiceId, PivotScreenWords } from './words';\n\n/** A Pivot Layout the user made and the report now shows. */\nexport interface PivotLayoutChangedEvent {\n /** The layout the report shows. */\n readonly layout: PivotLayout;\n}\n\n/** The Field List shown or hidden by the user. */\nexport interface PivotFieldListShownEvent {\n /** Whether it now stands beside the report. */\n readonly shown: boolean;\n}\n\n/** A move the report could not take, said where the user sees it (ADR-0066, ADR-0370 section 3). */\nexport interface PivotRefusedEvent {\n /** The sentence the pivot shows. */\n readonly message: string;\n /** The fields the refusal names, in the order they were moved: every move taken against the refused\n * question, which went with it. Empty where it names none. */\n readonly fields: readonly string[];\n}\n\n/** The Pivot Source failed to answer the report's newest question (ADR-0067). */\nexport interface PivotFailedEvent {\n /** What the source threw. */\n readonly error: unknown;\n /** Whether the report on screen stays as a Stale Report, whose notice says the failure: such a failure is raised here\n * and thrown no further. Any other is said in the Pivot Toolbar, and thrown on after it is raised. */\n readonly stale: boolean;\n}\n\n/** The report's selection, as the grid raised it, and what its cells stand for. */\nexport interface PivotSelectionChangedEvent {\n /** The selection of the report grid. */\n readonly selection: GridSelection;\n /** Each selected cell's row and column Items, each cell once, in the order selected (ADR-0340); `undefined`\n * when the selection reaches a row the grid does not hold drawn now, which is read from no Items rather than\n * from some of them (spine rule 1), and when no report is shown. A selection dropped over a report is said with\n * an empty list. */\n readonly items: readonly PivotCellItems[] | undefined;\n}\n\n/** An ExPivot's options (ADR-0370 section 1): what the Consumer hands, whole, on every update. */\nexport interface PivotViewOptions {\n /** The Pivot Source the report is computed from: its fields are what the Field List offers. A new\n * instance is a refresh. */\n readonly source: PivotSource;\n /** The Pivot Layout, View State the Consumer holds (ADR-0059). A layout handed in replaces the one on\n * screen; one this pivot raised through `onLayoutChanged` and handed back, however late, is its own and asks\n * nothing, so an earlier layout is asked for again by handing in one of the Consumer's own making. Left out,\n * the pivot starts from nothing and keeps the user's changes itself. A layout naming a field the source\n * does not offer is refused by name. */\n readonly layout?: PivotLayout;\n /** Raised with the layout the report shows after each change the user made, once it is answered: never\n * for one a newer move superseded, nor for one refused. */\n readonly onLayoutChanged?: (event: PivotLayoutChangedEvent) => void;\n /** Raised when a move is refused, with the sentence the pivot shows. */\n readonly onRefused?: (event: PivotRefusedEvent) => void;\n /** Raised when the Pivot Source fails to answer the report's newest question, as the Razor component keeps\n * `LastError`: a live source whose transport is down is heard of here (ADR-0067). */\n readonly onFailed?: (event: PivotFailedEvent) => void;\n /** The locale numbers, dates and counts are written in and text Items ordered by: a BCP 47 tag, or\n * `invariant`, which the pivot reads unless given (ADR-0370 section 10). A React adapter passes the\n * browser's language. It changes no word. */\n readonly locale?: string;\n /** The Consumer's word for an id, or `undefined` to keep the English (ADR-0370 section 10).\n * `japanesePivotWords` gives Excel's Japanese edition's words in one line. */\n readonly label?: PivotLabel;\n /** Whether the Field List stands beside the report; true unless given. */\n readonly showFieldList?: boolean;\n /** Raised when the report's selection changes, with what its cells stand for: what a Board reads its links\n * by (ADR-0340). */\n readonly onSelectionChanged?: (event: PivotSelectionChangedEvent) => void;\n /** Raised when the user shows or hides the Field List. */\n readonly onShowFieldListChanged?: (event: PivotFieldListShownEvent) => void;\n /** The Field List's width in pixels; 300 unless given. */\n readonly fieldListWidth?: number;\n /** The report grid's height, header included: pixels, or `stretch` for the parent's; 400 unless given. */\n readonly viewportHeight?: ViewportSize;\n /** The report grid's width; `stretch` unless given, what the Field List leaves. */\n readonly viewportWidth?: ViewportSize;\n /** The most leaves a question may ask the source for (ADR-0066): 200,000 unless given. A layout past it is\n * refused by name, and the report stays on the layout before. */\n readonly maxLeaves?: number;\n /** The most rows a report may have (ADR-0066): Excel's 1,048,576 unless given. A layout past it is refused, and\n * newer data past it leaves a Stale Report. */\n readonly maxRows?: number;\n /** The most columns a report may have, its label columns included (ADR-0066): Excel's 16,384 unless given. A layout\n * past it is refused, and newer data past it leaves a Stale Report. */\n readonly maxColumns?: number;\n /** How long after a change of data reached the screen the next is asked for, in milliseconds: 250 unless given\n * (ADR-0067). The source's notices that come meanwhile are gathered and asked for once, so a source that changes\n * many times a second redraws the report at most once per interval; a notice after a quiet spell is asked for at\n * once. */\n readonly redrawInterval?: number;\n /** The report's row height, or the Density's. */\n readonly rowHeight?: number;\n /** The report's Density, beating a Wrapper's. */\n readonly density?: GridDensity;\n /** The widths the report's grids charge each glyph, beating a Wrapper's and the Density's (ADR-0016): whoever sets\n * the font the cells are drawn in hands its widths, so `####` and the label widths are judged by the face on\n * screen. */\n readonly cellMetrics?: CellTextMetrics;\n /** What a Wrapper hands the report's grids (ADR-0030): the widths of the font it sets, its Density, and its hover\n * band and Row Stripes. A value the pivot is given beats these. */\n readonly presentationDefaults?: GridPresentationDefaults;\n /** How long the Change Highlight marks a value that changed with the data, in milliseconds: one second unless\n * given (ADR-0068). The source's changes are marked when newer data is shown, and a Refresh marks what changed\n * too; a move of the user's marks nothing. Zero marks nothing, and a negative or endless one is refused. */\n readonly changeHighlightDuration?: number;\n /** How the report's work shares the thread: a slice of 30 ms between macrotasks unless given (PV-40). Read\n * once, when the pivot is made. */\n readonly slicing?: PivotSlicing;\n /** Hears Show Details (ADR-0059, ADR-0063): the records behind a value cell double clicked. A Consumer that\n * listens takes them, and the pivot shows nothing; otherwise they open as `detailsView` says. */\n readonly onShowDetails?: (event: PivotShowDetailsEvent) => void;\n /** Where the records open when nobody hears `onShowDetails`: a tab at the report's foot, which covers the report\n * while it is selected, or a dialog; `tab` unless given. */\n readonly detailsView?: PivotDetailsView;\n /** Whether the Selection Summary is shown under the report (ADR-0130): Excel's status-bar figures over the cells\n * selected, summed by the report source over the whole report, rows not drawn included. On unless given. */\n readonly showSelectionSummary?: boolean;\n /** The Selection Summary's figures, Excel's Average, Count and Sum unless given (ADR-0130). The report holds the\n * choice made in the figures menu from then on; figures handed in that differ from the ones last handed replace\n * it. */\n readonly summaryFigures?: readonly SummaryFigure[];\n /** Raised when the figures menu changes the figures shown (ADR-0130). */\n readonly onSummaryFiguresChanged?: (figures: readonly SummaryFigure[]) => void;\n /** Hears the Selection Summary as it now stands (ADR-0130), for an application that shows the figures elsewhere. */\n readonly onSelectionSummaryChanged?: (summary: SelectionSummary) => void;\n /** The parts a Wrapper's Chrome, or the Consumer's own, draws in place of the built-in markup (ADR-0061, ADR-0390),\n * its `grid` dressing the report's grid and Show Details' grids. A part standing keeps the slot it opened with. */\n readonly chrome?: PivotChrome;\n}\n\nexport type { MountGrid } from './details-view';\n\n/** Why a question was asked: a move of the user's, a layout the Consumer handed in, newer data a person or the Consumer\n * asked for (Refresh, Retry, a new source), or newer data the source told of, which is asked quietly, without the loading\n * indication, so a live report does not flicker (ADR-0067). */\ntype Cause = 'user' | 'consumer' | 'data' | 'live';\n\n/** Whether a question was asked for newer data: its answer marks what changed, and one it cannot show leaves a Stale\n * Report (ADR-0067). */\nfunction asksData(cause: Cause): boolean {\n return cause === 'data' || cause === 'live';\n}\n\n/** The redraw interval unless the Consumer gives one, in milliseconds: the Razor component's `DefaultRedrawInterval`\n * (ADR-0067). */\nconst defaultRedrawInterval = 250;\n\n/** Excel's own limits on a worksheet's rows and columns, the report's caps unless given (ADR-0066). */\nconst excelRows = 1_048_576;\nconst excelColumns = 16_384;\n\ninterface Question {\n readonly layout: PivotLayout;\n readonly generation: number;\n readonly controller: AbortController;\n /** Whether the layout is the user's, raised once shown: a move of the user's, or one asked again before its\n * answer came, under new settings or data, as the Razor component carries its pending raise. */\n readonly raise: boolean;\n /** Whether the answer marks what changed: new data, or the user's layout asked again under new data. */\n readonly markChanges: boolean;\n /** Whether the Pivot Source is asked again rather than answered from what the report source holds: while a Refresh\n * is owed. */\n readonly refreshData: boolean;\n /** The user's moves this question carries: its own, after those of the questions it superseded while they\n * were out, which were taken against them and go with it (ADR-0370 section 3). */\n readonly moves: readonly FieldListMove[];\n /** Whether it answers changes of data the source told of: those gathered when it was asked, and those the\n * question it superseded carried (ADR-0067). */\n readonly carries: boolean;\n /** Who asked it: the user's move, the Consumer's layout or settings, Refresh or Retry, or the source's notice. */\n readonly cause: Cause;\n /** What it is asked of and under: the rows of its answer are asked of the same, with the same. */\n readonly reportSource: LocalPivotReportSource;\n /** The Pivot Source its report source asks, which Show Details asks for the records behind a cell. */\n readonly source: PivotSource;\n readonly settings: PivotReportSettings;\n /** The locale its settings carry, which its counts and its report are written in. */\n readonly locale: string;\n readonly maxLeaves: number;\n /** The caps on the report's rows and columns it is shown under (ADR-0066). */\n readonly maxRows: number;\n readonly maxColumns: number;\n /** The Item a user's expand or collapse toggled, which keeps the Focus in the report this question brings. */\n readonly toggled: ToggledItem | undefined;\n}\n\ninterface Shown {\n readonly layout: PivotLayout;\n /** The answer the report was drawn from; none for a layout with nothing to show. */\n readonly answer: PivotReportState | undefined;\n /** The question it answered, whose locale the grid writes the report in. */\n readonly question: Question | undefined;\n}\n\n// Keys that change no Selection: a modifier pressed alone, and a key an IME or a dead key takes to compose text.\nconst inertKeys: ReadonlySet<string> = new Set(['Shift', 'Control', 'Alt', 'Meta', 'AltGraph', 'CapsLock', 'Process', 'Dead']);\n\n/** An Item expanded or collapsed on a row: the row Items down to it, the last of them the Item, which tell its place\n * from the same Item's under another parent; and how many gestures the user had made in the report's grid then. */\ninterface ToggledItem {\n readonly path: readonly PivotFieldItem[];\n readonly gestures: number;\n}\n\n// The label cell of the toggled Item among the rows held: the one that paints its button on the toggled row's path.\nfunction toggledCell(rows: readonly PivotDisplayRow[], start: number, { path }: ToggledItem): CellPosition | undefined {\n const toggled = elementAt(path, path.length - 1);\n for (const [i, row] of rows.entries()) {\n if (row.rowPath.length < path.length || path.some((step, level) => {\n const at = elementAt(row.rowPath, level);\n return at.field !== step.field || !itemKeysEqual(at.item, step.item);\n })) continue;\n const column = row.labels.findIndex(label => label.toggle !== undefined && label.toggle.field === toggled.field\n && itemKeysEqual(label.toggle.item, toggled.item));\n if (column >= 0) return Object.freeze({ row: start + i, column });\n }\n return undefined;\n}\n\n/** What a menu or a panel opened under a field's entry was opened on. */\ninterface AtEntry {\n readonly entry: PivotEntry;\n /** The field the entry stands for; none for \u03A3 Values. */\n readonly field: string | undefined;\n /** The pane's layout it was opened on, which it closes on leaving. */\n readonly against: PivotLayout;\n}\n\n/** What is open in the pivot (ADR-0061), one at a time: the Layout menu from the Pivot Toolbar, a placed field's menu\n * in the Field List, a panel that menu opened in its place, or Filter\u2026 under a report filter in the band. */\ntype OpenSurface =\n | { readonly kind: 'layout'; readonly popup: PivotMenu }\n | (AtEntry & { readonly kind: 'entry'; readonly popup: PivotMenu })\n | (AtEntry & { readonly kind: 'panel'; readonly popup: PivotPanel })\n | { readonly kind: 'band'; readonly field: string; readonly against: PivotLayout; readonly popup: PivotPanel };\n\ntype EntrySurface = Extract<OpenSurface, { readonly kind: 'entry' | 'panel' }>;\n\n/** A report filter in the band: its caption, and its button, which says what it shows and opens Filter\u2026 under it. */\ninterface BandFilter {\n readonly filter: HTMLElement;\n readonly caption: HTMLElement;\n readonly anchor: HTMLElement;\n readonly button: HTMLButtonElement;\n readonly summary: HTMLElement;\n}\n\n// Stops what a panel asked that is still on its way, as it leaves.\nfunction closed(open: OpenSurface): void {\n if (open.kind === 'panel' || open.kind === 'band') open.popup.close?.();\n else open.popup.close();\n}\n\n// The Layout menu's groups, each headed where it starts, in Excel's order (ADR-0061).\nconst layoutHeadings: ReadonlyMap<PivotLayoutChoice, string> = new Map([\n ['doNotShowSubtotals', 'subtotals'],\n ['grandTotalsOff', 'grand-totals'],\n ['compactForm', 'report-layout'],\n]);\n\n// The ids of the pivot's own words: a command of the grid's own is not one of them.\nconst pivotWordIds: ReadonlySet<string> = new Set(pivotWordIdList());\n\n// The rows a first answer brings: a screen's worth and more. The grid asks for the rest as it scrolls.\nconst firstWindowRows = 200;\n\n// Whether a layout shows nothing: no field in Rows, Columns or Values, so there is nothing to compute, whatever\n// stands in Filters (ADR-0059).\nfunction showsNothing(layout: PivotLayout): boolean {\n return layout.rows.length === 0 && layout.columns.length === 0 && layout.values.length === 0;\n}\n\n/** What the report's text is charged by, as its grids resolve it (ADR-0028). */\nfunction textOf(options: PivotViewOptions): GridTextOptions {\n return {\n ...(options.density === undefined ? {} : { density: options.density }),\n ...(options.cellMetrics === undefined ? {} : { cellMetrics: options.cellMetrics }),\n ...(options.presentationDefaults === undefined ? {} : { presentationDefaults: options.presentationDefaults }),\n };\n}\n\n/** Whether two Cell Metrics, either of them none, charge every glyph alike. */\nfunction sameCellMetrics(a: CellTextMetrics | undefined, b: CellTextMetrics | undefined): boolean {\n return a === b || (a !== undefined && b !== undefined && a.equals(b));\n}\n\n/** Whether two Wrappers' defaults, either of them none, hand the grids the same widths and words. */\nfunction sameDefaults(a: GridPresentationDefaults | undefined, b: GridPresentationDefaults | undefined): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n const read = ['wideWidthPx', 'digitWidthPx', 'narrowWidthPx', 'boldWideWidthPx', 'boldDigitWidthPx', 'boldNarrowWidthPx', 'otherWidthPx',\n 'boldOtherWidthPx', 'glyphWidths', 'fontSizePx', 'density', 'highlightHoverRow', 'stripeRows'] as const;\n return read.every(name => a[name] === b[name]);\n}\n\n/** Whether two geometries charge every glyph alike. */\nfunction sameGeometry(a: GridTextGeometry, b: GridTextGeometry): boolean {\n if (a === b) return true;\n const widths = ['wideWidthPx', 'digitWidthPx', 'narrowWidthPx', 'fullWidthPx', 'otherWidthPx', 'cellHorizontalPaddingPx'] as const;\n if (widths.some(name => a[name] !== b[name])) return false;\n const glyphs = Object.keys(a.glyphWidths);\n return glyphs.length === Object.keys(b.glyphWidths).length && glyphs.every(point => a.glyphWidths[Number(point)] === b.glyphWidths[Number(point)]);\n}\n\nfunction checkedOptions(options: PivotViewOptions): PivotViewOptions {\n // Checked as an untyped caller may hand them, where they arrive (CONVENTIONS.md).\n const given: Readonly<Record<string, unknown>> = { ...options };\n const source = given['source'];\n if (typeof source !== 'object' || source === null || !('fields' in source) || !('aggregate' in source)) {\n throw new TypeError('An ExPivot needs a Pivot Source (source) to compute its report from.');\n }\n const width = given['fieldListWidth'];\n if (width !== undefined && (typeof width !== 'number' || !Number.isFinite(width) || width <= 0 || width >= 10_000)) {\n throw new RangeError(`fieldListWidth is a width in pixels above zero, not ${JSON.stringify(width)}.`);\n }\n const redrawInterval = given['redrawInterval'];\n if (redrawInterval !== undefined && (typeof redrawInterval !== 'number' || !Number.isFinite(redrawInterval) || redrawInterval < 0)) {\n throw new RangeError(`redrawInterval is a time in milliseconds of zero or more, not ${JSON.stringify(redrawInterval)} (ADR-0067).`);\n }\n for (const name of ['maxLeaves', 'maxRows', 'maxColumns']) {\n const cap = given[name];\n if (cap !== undefined && (typeof cap !== 'number' || !Number.isSafeInteger(cap) || cap < 1)) {\n throw new RangeError(`${name} is a whole number of at least 1, not ${JSON.stringify(cap)} (ADR-0066).`);\n }\n }\n if (given['cellMetrics'] !== undefined && !(given['cellMetrics'] instanceof CellTextMetrics)) {\n throw new TypeError('cellMetrics is a CellTextMetrics: the widths the report\\'s grids charge each glyph (ADR-0016).');\n }\n if (given['presentationDefaults'] !== undefined && !(given['presentationDefaults'] instanceof GridPresentationDefaults)) {\n throw new TypeError('presentationDefaults is a GridPresentationDefaults, as a Wrapper makes one (ADR-0030).');\n }\n const highlight = given['changeHighlightDuration'];\n if (highlight !== undefined && (typeof highlight !== 'number' || !Number.isFinite(highlight) || highlight < 0)) {\n throw new RangeError(`changeHighlightDuration is a finite number of zero or more milliseconds, not ${typeof highlight === 'number' ? String(highlight) : typeof highlight} (ADR-0068).`);\n }\n const slicing = given['slicing'];\n if (slicing !== undefined && (typeof slicing !== 'object' || slicing === null)) throw new TypeError('slicing is an object.');\n const showSummary = given['showSelectionSummary'];\n if (showSummary !== undefined && typeof showSummary !== 'boolean') throw new TypeError('showSelectionSummary is true or false.');\n const figures: unknown = given['summaryFigures'];\n if (figures !== undefined && (!Array.isArray(figures) || !figures.every(figure => (summaryFigureOrder as readonly unknown[]).includes(figure)))) {\n throw new TypeError(`summaryFigures is a list of the figures ${summaryFigureOrder.join(', ')} (ADR-0130).`);\n }\n for (const name of ['onLayoutChanged', 'onRefused', 'onFailed', 'onShowFieldListChanged', 'onSelectionChanged', 'onShowDetails', 'label',\n 'onSummaryFiguresChanged', 'onSelectionSummaryChanged']) {\n const handler = given[name];\n if (handler !== undefined && typeof handler !== 'function') throw new TypeError(`${name} is a function.`);\n }\n const detailsView = given['detailsView'];\n if (detailsView !== undefined && detailsView !== 'tab' && detailsView !== 'dialog') {\n throw new TypeError(`detailsView is 'tab' or 'dialog', not ${JSON.stringify(detailsView)}.`);\n }\n checkedPivotChrome(given['chrome']);\n const locale = given['locale'];\n if (locale !== undefined && (typeof locale !== 'string' || locale === '')) {\n throw new TypeError('locale is a BCP 47 tag or \"invariant\", never an empty tag (ADR-0370 section 10).');\n }\n return options;\n}\n\n// The Consumer's words as the report source takes them, plain data that crosses to a Worker as it is.\nfunction wordsRecord(label: PivotLabel | undefined): Readonly<Record<string, string>> | undefined {\n if (label === undefined) return undefined;\n const words: Record<string, string> = {};\n for (const id of pivotWordIdList()) {\n const word = label(id);\n if (word !== undefined) words[id] = word;\n }\n return Object.freeze(words);\n}\n\n// Two lists of figures that name the same figures, whatever their order: the grid shows them in Excel's.\nfunction sameFigures(a: readonly SummaryFigure[] | undefined, b: readonly SummaryFigure[] | undefined): boolean {\n if (a === b) return true;\n if (a === undefined || b === undefined) return false;\n const named = new Set(b);\n return new Set(a).size === named.size && a.every(figure => named.has(figure));\n}\n\n// A copy refused, in the sentence the grid says.\nfunction refuse(sentence: string): GridCopyAnswer {\n return Object.freeze({ kind: 'refuse', sentence });\n}\n\n/** One ExPivot, drawn into its root. */\nexport class PivotView {\n readonly #root: HTMLElement;\n readonly #mountGrid: MountGrid;\n readonly #report: HTMLElement;\n readonly #notice: HTMLElement;\n // The Stale Report's live region under the Pivot Toolbar, always present, and the notice it holds while the report\n // is stale: the sentence, and Retry (ADR-0067).\n readonly #staleRegion: HTMLElement;\n readonly #staleNotice: HTMLElement;\n readonly #staleMessage: HTMLElement;\n readonly #retryButton: HTMLButtonElement;\n readonly #fieldListToggle: HTMLButtonElement;\n readonly #refreshButton: HTMLButtonElement;\n readonly #layoutAnchor: HTMLElement;\n readonly #toolbarStart: HTMLElement;\n // The built-in Pivot Toolbar, which a Chrome's toolbar stands in place of (ADR-0390).\n readonly #toolbar: HTMLElement;\n // The controls and anchors the toolbar, the band and the Stale Report's notice handed in, the built-in markup's or\n // a Chrome's: the keyboard goes to them, and the popups are placed in them, by name.\n readonly #parts: PartElements;\n readonly #toolbarSlot: StandingSlot<PivotToolbarView, PivotToolbarSlotContext>;\n readonly #bandSlot: StandingSlot<PivotReportFiltersView, PivotReportFiltersSlotContext>;\n readonly #staleSlot: StandingSlot<PivotStaleReportView, PivotStaleReportSlotContext>;\n // What a standing part's contents threw as they were mounted, thrown once the draw that mounted them is done.\n #slotErrors: Error[] = [];\n // Whether the draw is the Consumer's, making the pivot or updating it, which a Chrome that cannot be drawn is thrown\n // to.\n #consumerDraws = false;\n // The report filter band (ADR-0061): each report filter's elements, kept while it stands in Filters.\n readonly #band: HTMLElement;\n readonly #bandFilters = new Map<string, BandFilter>();\n readonly #layoutButton: HTMLButtonElement;\n readonly #layoutLabel: HTMLElement;\n readonly #backdrop: HTMLElement;\n readonly #sheet: HTMLElement;\n readonly #empty: HTMLElement;\n readonly #gridRoot: HTMLElement;\n readonly #dropRemove: HTMLElement;\n readonly #fieldListBox: HTMLElement;\n readonly #fieldListScroll: HTMLElement;\n readonly #builtInFieldList: FieldListView;\n // The Field List a Chrome draws (ADR-0390), in the built-in pane's place while it stands.\n readonly #slottedFieldList: SlottedFieldList;\n #fieldListSlotted = false;\n // Show Details' sheets, when the Consumer does not take the records: tabs at the report's foot, or a dialog.\n readonly #details: DetailsSheets;\n // The Show Details events this pivot handed a Consumer: the only ones it opens when they are handed back.\n readonly #detailsRaised = new WeakSet<PivotShowDetailsEvent>();\n readonly #userWidths = new Map<string, number>();\n // Read once, when the pivot is made: every report source it makes shares the thread the same way.\n readonly #slicing: PivotSlicing | undefined;\n #options: PivotViewOptions;\n #words: PivotScreenWords;\n // The Selection Summary's figures shown, and the ones last handed in (ADR-0130), as the Razor component's\n // `HeldSummaryFigures`: the figures menu's choice stands until the Consumer hands in different ones.\n #summaryFigures: readonly SummaryFigure[];\n #summaryFiguresHanded: readonly SummaryFigure[] | undefined;\n // The words of the grid's commands, made again when the Consumer's words change.\n #commandLabel: (id: string) => string | undefined;\n // The text geometry of the report grid's density: what its label widths are estimated under, and a level's indent.\n #geometry: GridTextGeometry;\n #columns: ReportColumns;\n #settings: PivotReportSettings;\n #reportSource: LocalPivotReportSource;\n // The report source the rows on screen read their Windows from: the one before a new source's answer lands.\n #shownReportSource: LocalPivotReportSource | undefined;\n // Every layout raised through onLayoutChanged, as the Razor component holds them: one handed back is the\n // Consumer binding the pivot's own layout back, never a layout it asks for, however late it comes. An earlier\n // layout is asked for again by handing in a layout of the Consumer's own making. Held weakly, so the user's\n // moves cost nothing once nobody holds them.\n readonly #raised = new WeakSet<PivotLayout>();\n // Unhooks the listeners on the root, which is the Consumer's element and outlives the pivot.\n readonly #listening = new AbortController();\n #layoutGiven: PivotLayout | undefined;\n #shown: Shown;\n #asked: Question | undefined;\n // While Defer Layout Update is ticked (ADR-0061): the layout the pane shows and builds, which Update applies, and\n // what the pane moved into it that the report on screen does not hold yet, which a refusal of that layout names.\n #deferred: Deferred | undefined;\n #generation = 0;\n #requests = 0;\n #refusal: string | undefined;\n // A Refresh pressed and not yet answered from the Pivot Source asked again.\n #refreshOwed = false;\n // A change of data no question asked since answers, and the Source Version the latest notice named, if it named\n // one (ADR-0067). When a change of data last reached the screen, from which the next waits the redraw interval;\n // the timer that waits; and how to stop hearing the report source's notices.\n #changed = false;\n #changedTo: string | undefined;\n // The Stale Report (ADR-0067): what happened while the newest data cannot be shown, and when the data the report\n // shows arrived, which the notice and a refused Copy say.\n #stale: string | undefined;\n // The Change Highlight (ADR-0068): when this pivot first showed each change the report source marks, one for the\n // pivot's life across sources; the grid's question about a cell, one function for the pivot's life, as the Razor\n // component holds its delegate, so that its identity says nothing changed (ADR-0003): a newly marked value is a\n // new row; and each value column's index by its name, which a row's marks are listed by.\n readonly #changeTimes = new PivotChangeTimes();\n readonly #cellChangedAt: NonNullable<GridOptions<PivotDisplayRow>['cellChangedAt']> = (row, column) => {\n const index = this.#valueColumnIndexes.get(column);\n return index === undefined ? undefined : this.#changeTimes.changedAt(row, index);\n };\n #valueColumnIndexes = new Map<string, number>();\n // Whether what left the report stale was a question that refreshed the Pivot Source, which Retry then asks again\n // rather than the report alone: asking a source that did not refresh would show its old data as the newest.\n #staleRetryRefreshes = false;\n #shownAt = Date.now();\n // The time of the data shown as last said, and what it was said for: the time, the locale and the day.\n #asOfSaid: { readonly key: string; readonly text: string } | undefined;\n #lastDataShown: number | undefined;\n #redrawTimer: ReturnType<typeof setTimeout> | undefined;\n #stopHearing: (() => void) | undefined;\n #fieldListShown: boolean;\n #counts: PivotItemCounts | undefined;\n #countsAsked: AbortController | undefined;\n #grid: GridHandle<PivotDisplayRow> | undefined;\n // The report grid's Settled Mark, held while a question under the loading indication is out (ADR-0220 section 1):\n // the report that question brings is the effect of the move, the Consumer's layout or the Refresh that asked it,\n // and a reading taken before it lands reads the report before. A quiet question a source's notice asked holds\n // nothing, as it shows no loading either: a live report would otherwise never settle.\n #loadingHold: { readonly grid: GridHandle<PivotDisplayRow>; readonly release: () => void } | undefined;\n #rows: FetchingGridSource<PivotDisplayRow> | undefined;\n // The grid's columns as last drawn, whose names a copy asks the report source for.\n #gridColumns: readonly GridColumn<PivotDisplayRow>[] = [];\n #dropRemoveShown = false;\n #open: OpenSurface | undefined;\n // The Items Filter\u2026 lists, asked of the source under the report on screen (ADR-0066).\n readonly #items = new ItemListings(() => { this.#draw(); });\n // A field menu the pane left while it held the keyboard: the keyboard goes to its field's entry once drawn.\n #keyboardAfterDraw: OpenSurface | undefined;\n // Stops waiting for the first rows of the report a toggled Item keeps the Focus in.\n #placing: (() => void) | undefined;\n // The presses, wheels and keys the user has made in the report's grid, counted: a toggled Item keeps the Focus only\n // while none has come since the toggle (spine rule 6).\n #gestures = 0;\n #destroyed = false;\n // The stylesheets' notices at the top of the root, and what they were drawn from.\n #notices: readonly HTMLElement[] = [];\n #noticesDrawn = '';\n\n constructor(root: HTMLElement, options: PivotViewOptions, mountGrid: MountGrid) {\n this.#options = checkedOptions(options);\n this.#root = root;\n this.#mountGrid = mountGrid;\n this.#slicing = options.slicing;\n this.#words = new PivotScreenWords(options.label);\n this.#summaryFiguresHanded = options.summaryFigures;\n this.#summaryFigures = options.summaryFigures ?? defaultSummaryFigures;\n this.#commandLabel = this.#commandLabelOf(options.label);\n this.#geometry = gridTextGeometry(textOf(options));\n this.#columns = this.#columnsOf(options);\n this.#settings = this.#settingsOf(options);\n this.#fieldListShown = options.showFieldList !== false;\n this.#layoutGiven = options.layout;\n if (options.layout !== undefined) validateLayout(options.layout, this.#declared(options.source));\n this.#shown = { layout: emptyPivotLayout, answer: undefined, question: undefined };\n this.#reportSource = this.#reportSourceOf(options.source);\n\n const document = root.ownerDocument;\n const div = (className: string): HTMLDivElement => {\n const made = document.createElement('div');\n made.className = className;\n return made;\n };\n root.replaceChildren();\n root.classList.add('ex-pivot');\n // The pivot's box is its Input Root (ADR-0240 section 6): the report grid hears the whole pivot from here.\n root.setAttribute('data-ex-input-root', '');\n this.#report = div('ex-pivot-report');\n this.#parts = new PartElements(root);\n const toolbar = div('ex-pivot-toolbar');\n this.#toolbar = toolbar;\n const start = div('ex-pivot-toolbar-start');\n this.#toolbarStart = start;\n this.#band = div('ex-pivot-filters');\n this.#band.setAttribute('role', 'group');\n const end = div('ex-pivot-toolbar-end');\n // Refresh asks the Pivot Source again, offered only by a source that can be asked again (ADR-0066).\n this.#refreshButton = document.createElement('button');\n this.#refreshButton.type = 'button';\n this.#refreshButton.className = 'ex-pivot-toolbar-button ex-pivot-refresh-button';\n this.#refreshButton.setAttribute('data-ex-claims', 'click');\n this.#refreshButton.addEventListener('click', () => { this.#refresh(); });\n this.#fieldListToggle = document.createElement('button');\n this.#fieldListToggle.type = 'button';\n this.#fieldListToggle.className = 'ex-pivot-toolbar-button ex-pivot-field-list-toggle';\n this.#fieldListToggle.setAttribute('data-ex-claims', 'click');\n this.#fieldListToggle.addEventListener('click', () => { this.#setFieldListShown(!this.#fieldListShown); });\n // Layout \u25BE opens the Layout menu under it, over the report, at its right edge; its wrapper is positioned\n // so the menu needs no position the pivot would have to measure (ADR-0061).\n this.#layoutAnchor = document.createElement('span');\n this.#layoutAnchor.className = 'ex-pivot-toolbar-anchor';\n this.#layoutButton = document.createElement('button');\n this.#layoutButton.type = 'button';\n this.#layoutButton.className = 'ex-pivot-toolbar-button ex-pivot-layout-button';\n this.#layoutButton.setAttribute('data-ex-claims', 'click');\n this.#layoutButton.setAttribute('aria-haspopup', 'menu');\n this.#layoutLabel = document.createElement('span');\n const arrow = document.createElement('span');\n arrow.className = 'ex-pivot-entry-arrow';\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n this.#layoutButton.append(this.#layoutLabel, arrow);\n this.#layoutButton.addEventListener('click', () => { this.#toggleLayoutMenu(); });\n this.#layoutAnchor.append(this.#layoutButton);\n end.append(this.#layoutAnchor, this.#fieldListToggle);\n // Under a menu opened from the Pivot Toolbar, a press anywhere else closes it.\n this.#backdrop = div('ex-pivot-backdrop');\n this.#backdrop.setAttribute('data-ex-claims', 'click');\n this.#backdrop.setAttribute('aria-hidden', 'true');\n this.#backdrop.addEventListener('click', () => { this.#close('opener'); });\n toolbar.append(start, end);\n this.#notice = div('ex-pivot-refusal-notice');\n this.#notice.setAttribute('role', 'alert');\n // A polite live region, always present, so a notice that appears in it is announced without interrupting the\n // reader as the Pivot Toolbar's refusal of their own change does. Empty, it takes no room.\n this.#staleRegion = div('ex-pivot-stale');\n this.#staleRegion.setAttribute('role', 'status');\n this.#staleNotice = div('ex-pivot-stale-notice');\n this.#staleMessage = document.createElement('span');\n this.#staleMessage.className = 'ex-pivot-stale-message';\n this.#retryButton = document.createElement('button');\n this.#retryButton.type = 'button';\n this.#retryButton.className = 'ex-pivot-retry';\n this.#retryButton.setAttribute('data-ex-claims', 'click');\n this.#retryButton.addEventListener('click', () => { this.#retry(); });\n this.#staleNotice.append(this.#staleMessage, this.#retryButton);\n this.#toolbarSlot = new StandingSlot('toolbar', document, Object.freeze({\n layoutMenu: Object.freeze({ label: '', open: false }), fieldList: Object.freeze({ label: '', shown: false }), reportFilters: false,\n }));\n this.#bandSlot = new StandingSlot('reportFilters', document, Object.freeze({ name: '', filters: Object.freeze([]) }));\n this.#staleSlot = new StandingSlot('staleReport', document, Object.freeze({\n message: '', asOfText: '', reason: '', retry: Object.freeze({ label: '', enabled: false }),\n }));\n this.#bandSlot.element.setAttribute('role', 'group');\n this.#sheet = div('ex-pivot-sheet');\n // Records covering the report take no drop meant for it.\n this.#sheet.addEventListener('dragover', event => {\n if (!this.#fieldList.removable || this.#details.covering) return;\n event.preventDefault();\n });\n this.#sheet.addEventListener('drop', event => {\n event.preventDefault();\n if (!this.#details.covering) this.#fieldList.dropOnReport();\n });\n this.#empty = div('ex-pivot-empty');\n this.#empty.setAttribute('role', 'status');\n this.#gridRoot = document.createElement('div');\n this.#dropRemove = div('ex-pivot-report-drop-remove');\n this.#dropRemove.setAttribute('aria-hidden', 'true');\n this.#dropRemove.append(document.createElement('span'));\n this.#report.append(toolbar, this.#notice, this.#staleRegion, this.#sheet);\n this.#fieldListBox = div('ex-pivot-field-list');\n this.#fieldListBox.setAttribute('role', 'region');\n const scroll = div('ex-pivot-field-list-scroll');\n this.#fieldListBox.append(scroll);\n this.#fieldListScroll = scroll;\n const fieldListHandlers: FieldListHandlers = {\n edit: edit => { this.#edited(edit); },\n close: () => { this.#setFieldListShown(false); },\n dragging: removable => { this.#paintDropRemove(removable); },\n menu: entry => { this.#toggleEntryMenu(entry); },\n defer: deferred => { this.#setDeferred(deferred); },\n update: () => { this.#applyPending(); },\n };\n this.#builtInFieldList = new FieldListView(scroll, fieldListHandlers);\n this.#slottedFieldList = new SlottedFieldList(document, fieldListHandlers, this.#parts);\n root.append(this.#report, this.#fieldListBox);\n this.#drawNotices();\n this.#details = new DetailsSheets({\n document,\n mountGrid,\n words: () => this.#words,\n look: () => ({\n rowHeight: this.#options.rowHeight, density: this.#options.density, cellMetrics: this.#options.cellMetrics,\n presentationDefaults: this.#options.presentationDefaults, commandLabel: this.#options.label, chrome: this.#chrome?.grid,\n }),\n problemText: problem => detailsProblemText(problem, this.#words),\n changed: () => { this.#draw(); },\n // The report's grid takes the keyboard back; a report with no grid has the Field List's toggle take it, so\n // the keyboard stays in the pivot.\n returnKeyboard: () => {\n if (this.#grid === undefined) this.#parts.focus('field-list');\n else this.#gridRoot.focus();\n },\n parts: this.#parts,\n chrome: () => this.#chrome,\n });\n // A drag that moves on from an Area, anywhere in the pivot, leaves it unmarked; and one that leaves the\n // pivot for an element the browser names. WebKit names none on leaving one element for another, so a\n // leave that names nothing is not taken as one.\n const listening = { signal: this.#listening.signal };\n const gestured = (): void => { this.#gestures++; };\n this.#gridRoot.addEventListener('pointerdown', gestured, { capture: true, ...listening });\n this.#gridRoot.addEventListener('wheel', gestured, { capture: true, passive: true, ...listening });\n this.#gridRoot.addEventListener('keydown', event => {\n if (!event.isComposing && !inertKeys.has(event.key)) gestured();\n }, { capture: true, ...listening });\n root.addEventListener('dragenter', event => { this.#fieldList.dragEntered(event.target); }, listening);\n root.addEventListener('dragleave', event => {\n const to = event.relatedTarget;\n if (to instanceof Node && !root.contains(to)) this.#fieldList.leaveTargets();\n }, listening);\n // A press, or focus coming in, anywhere in the pivot outside an open field menu and its entry dismisses the\n // menu, and leaves the keyboard where it went (ADR-0061). A panel keeps its draft until OK or Cancel.\n const outside = (event: Event): void => {\n const open = this.#open;\n if (open?.kind !== 'entry') return;\n if (event.target instanceof Node && this.#within(open, event.target)) return;\n this.#close('stay');\n };\n root.addEventListener('mousedown', outside, listening);\n root.addEventListener('focusin', outside, listening);\n\n this.#askCounts();\n // Heard once the pivot is whole: a construction that throws leaves no listener on the Consumer's source.\n this.#hear(this.#reportSource);\n if (options.layout !== undefined) this.#ask(options.layout, 'consumer', []);\n try {\n this.#consumerDraws = true;\n this.#draw();\n } catch (error) {\n // A pivot refused as it is made leaves nothing hearing the source.\n this.destroy();\n throw error;\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n #reportSourceOf(source: PivotSource): LocalPivotReportSource {\n const slicing = this.#slicing;\n return new LocalPivotReportSource(source, slicing === undefined ? undefined : { slicing });\n }\n\n // A report source is disposed once nothing asks it and no row on screen reads it.\n #release(reportSource: LocalPivotReportSource | undefined): void {\n if (reportSource !== undefined && reportSource !== this.#reportSource && reportSource !== this.#shownReportSource) reportSource.dispose();\n }\n\n /** Takes the options again, whole. Options refused leave the pivot as it was. A Chrome slot whose contents cannot\n * be drawn is thrown once the options are taken, with the built-in markup standing in its place (ADR-0390). */\n update(options: PivotViewOptions): void {\n if (this.#destroyed) throw new Error('This ExPivot was destroyed: make a new one.');\n checkedOptions(options);\n const before = this.#options;\n const sourceMoved = options.source !== before.source;\n // A layout handed in is a question, unless the pane holds it already or this pivot raised it.\n const layoutMoved = options.layout !== this.#layoutGiven;\n const consumerLayout = layoutMoved && options.layout !== undefined && options.layout !== this.#layoutAhead && !this.#raised.has(options.layout)\n ? options.layout\n : undefined;\n const asked = consumerLayout ?? (sourceMoved ? this.#layoutAhead : undefined);\n // Checked against the source it will be asked of before anything changes; a new source is always asked.\n if (asked !== undefined) validateLayout(asked, this.#declared(options.source));\n this.#options = options;\n if (layoutMoved) this.#layoutGiven = options.layout;\n // The Consumer's layout replaces the user's, a pending one too. A pending layout placing a field the new source\n // does not have goes back to the one asked of it, which is checked above: the rest of what a layout is checked\n // for does not depend on the source, and the pending one was made by the pane's own edits.\n const pending = this.#deferred?.layout;\n if (asked !== undefined && pending !== undefined && (consumerLayout !== undefined || !placesOnly(pending, this.#declared(options.source)))) {\n this.#deferred = Object.freeze({ layout: asked, moves: Object.freeze([]) });\n }\n // What the report's text is charged by: a label's width is estimated under it, so the report is asked again\n // when it charges otherwise, and not for equal widths handed again in a new object, as a framework's render may.\n const geometry = gridTextGeometry(textOf(options));\n const textMoved = options.density !== before.density || !sameGeometry(geometry, this.#geometry);\n // The grids are handed what they resolve their own metrics from when it charges or reads otherwise, not when\n // equal values come again in new objects.\n const metricsGiven = !sameCellMetrics(options.cellMetrics, before.cellMetrics) || !sameDefaults(options.presentationDefaults, before.presentationDefaults);\n const settingsMoved = options.locale !== before.locale || options.label !== before.label || textMoved;\n if (options.label !== before.label) {\n this.#words = new PivotScreenWords(options.label);\n this.#commandLabel = this.#commandLabelOf(options.label);\n }\n if (textMoved) this.#geometry = geometry;\n if (options.label !== before.label || textMoved) this.#columns = this.#columnsOf(options);\n // A highlight's length is the next question's to carry, which keeps what it compares that long; the report on\n // screen is not asked again for it, and the grid paints by it at once.\n const highlightMoved = highlightMsOf(options) !== highlightMsOf(before);\n if (settingsMoved || highlightMoved) this.#settings = this.#settingsOf(options);\n if (options.showFieldList !== before.showFieldList) this.#fieldListShown = options.showFieldList !== false;\n if (sourceMoved) {\n // A new source is asked from nothing: no Refresh is owed to it.\n this.#refreshOwed = false;\n // The rows on screen keep reading the report source that answered them until a new answer replaces them.\n const replaced = this.#reportSource;\n this.#reportSource = this.#reportSourceOf(options.source);\n this.#hear(this.#reportSource);\n this.#release(replaced);\n this.#counts = undefined;\n this.#askCounts();\n }\n if (options.redrawInterval !== before.redrawInterval) {\n // A redraw waiting on the interval before is timed again on the new one.\n this.#disarmRedraw();\n this.#scheduleRedraw();\n }\n if (asked !== undefined) {\n this.#ask(asked, consumerLayout !== undefined ? 'consumer' : 'data', []);\n } else if (settingsMoved || capsOf(options) !== capsOf(before)) {\n this.#ask(this.#layoutAhead, 'consumer', []);\n }\n const gridChromeMoved = options.chrome?.grid !== before.chrome?.grid;\n const summaryMoved = this.#adoptSummaryFigures(options.summaryFigures) || options.showSelectionSummary !== before.showSelectionSummary;\n if (summaryMoved || highlightMoved || options.rowHeight !== before.rowHeight || textMoved || metricsGiven || options.viewportHeight !== before.viewportHeight\n || options.viewportWidth !== before.viewportWidth || gridChromeMoved) {\n this.#drawGrid();\n }\n const detailsChromeMoved = options.chrome?.detailsTabs !== before.chrome?.detailsTabs || options.chrome?.detailsDialog !== before.chrome?.detailsDialog;\n this.#drawNotices();\n this.#consumerDraws = true;\n try {\n if (settingsMoved || metricsGiven || options.rowHeight !== before.rowHeight || gridChromeMoved || detailsChromeMoved) {\n this.#details.draw();\n this.#slotErrors.push(...this.#details.takeRefused());\n }\n this.#draw();\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n /** Opens the records of a Show Details event this pivot raised, as `detailsView` says, as when nobody hears\n * `onShowDetails`: a Consumer that heard it and does not take it hands it back. An event another pivot raised is\n * refused, rather than shown under this pivot's report; a stopped pivot opens nothing. */\n openDetails(event: PivotShowDetailsEvent): void {\n if (!this.#detailsRaised.has(event)) throw new Error('These records are another pivot\\'s: a pivot opens only the Show Details it raised.');\n if (this.#destroyed) return;\n this.#consumerDraws = true;\n try {\n this.#details.open(event, this.#options.detailsView ?? 'tab', this.#locale); // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0059: a tab at the report's foot unless the Consumer asks for the dialog, as the Razor component's DetailsView\n this.#slotErrors.push(...this.#details.takeRefused());\n this.#throwRefused();\n } finally {\n this.#consumerDraws = false;\n }\n }\n\n /** Stops the pivot: it asks and hears nothing more, and empties its element. The source stays the\n * Consumer's. */\n destroy(): void {\n if (this.#destroyed) return;\n this.#destroyed = true;\n this.#listening.abort();\n this.#stopHearing?.();\n this.#stopHearing = undefined;\n this.#disarmRedraw();\n this.#takeDown();\n this.#toolbarSlot.hide();\n this.#bandSlot.hide();\n this.#staleSlot.hide();\n this.#slottedFieldList.hide();\n this.#parts.dispose();\n this.#items.dispose();\n this.#details.destroy();\n this.#generation++;\n this.#asked?.controller.abort();\n this.#asked = undefined;\n this.#holdWhileLoading();\n this.#countsAsked?.abort();\n this.#placing?.();\n this.#grid?.destroy();\n this.#grid = undefined;\n this.#rows?.dispose();\n this.#rows = undefined;\n const asked = this.#reportSource;\n const read = this.#shownReportSource;\n this.#shownReportSource = undefined;\n asked.dispose();\n if (read !== asked) read?.dispose();\n this.#root.replaceChildren();\n this.#root.classList.remove('ex-pivot');\n this.#root.removeAttribute('data-ex-input-root');\n clearStyle(this.#root);\n this.#root.removeAttribute('aria-busy');\n }\n\n /** The layout the report on screen was laid out under. */\n get shownLayout(): PivotLayout {\n return this.#shown.layout;\n }\n\n // Whether the report on screen is drawn as a grid: one was answered, and its layout shows something. A layout with\n // fields in Filters alone is answered, for their Items, and the box says how to start.\n get #reportDrawn(): boolean {\n return this.#shown.answer !== undefined && !showsNothing(this.#shown.layout);\n }\n\n // The layout the report is on, or on its way to: the one the newest question asks for, or the one it shows.\n get #layoutAhead(): PivotLayout {\n return this.#asked?.layout ?? this.#shown.layout;\n }\n\n // The pane's layout: the pending one while Defer Layout Update is ticked, otherwise the report's.\n get #paneLayout(): PivotLayout {\n return this.#deferred?.layout ?? this.#layoutAhead;\n }\n\n get #redrawInterval(): number {\n return this.#options.redrawInterval ?? defaultRedrawInterval;\n }\n\n get #maxLeaves(): number {\n return this.#options.maxLeaves ?? defaultMaxLeaves;\n }\n\n get #changeHighlightMs(): number {\n return highlightMsOf(this.#options);\n }\n\n get #maxRows(): number {\n return this.#options.maxRows ?? excelRows;\n }\n\n get #maxColumns(): number {\n return this.#options.maxColumns ?? excelColumns;\n }\n\n get #locale(): string {\n return this.#localeOf(this.#options);\n }\n\n // The Chrome's slots, read as each part opens (ADR-0390).\n get #chrome(): PivotChrome | undefined {\n return this.#options.chrome;\n }\n\n // The Field List standing now: a Chrome's, or the built-in pane.\n get #fieldList(): FieldListView | SlottedFieldList {\n return this.#fieldListSlotted ? this.#slottedFieldList : this.#builtInFieldList;\n }\n\n // The report source estimates the label widths under the grid's text geometry, as the Razor component tells it\n // the grid's Cell Metrics (ADR-0151).\n #settingsOf(options: PivotViewOptions): PivotReportSettings {\n const words = wordsRecord(options.label);\n // The report source keeps what a highlight compares for as long as it is marked (ADR-0153).\n return Object.freeze({\n locale: this.#localeOf(options), labelMetrics: this.#geometry, changeHighlightMs: highlightMsOf(options),\n ...(words === undefined ? {} : { words }),\n });\n }\n\n // A level's indent and a button's side: the em of the grid's font, rounded as .NET rounds it, which is what the\n // report source charges a level (ADR-0151).\n get #indentPx(): number {\n return roundHalfToEven(this.#geometry.fullWidthPx);\n }\n\n #columnsOf(options: PivotViewOptions): ReportColumns {\n const words = this.#words;\n return new ReportColumns(Object.freeze({\n indentPx: this.#indentPx,\n toggleName: (toggle: PivotToggle) => words.fill(toggle.isCollapsed ? 'expand-item' : 'collapse-item', toggle.itemLabel),\n toggled: (toggle: PivotToggle, row: PivotDisplayRow) => { this.#toggled(toggle, row); },\n }), textOf(options));\n }\n\n #localeOf(options: PivotViewOptions): string {\n return options.locale ?? 'invariant'; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0370 section 10: a Script Core given no locale reads as .NET's InvariantCulture does\n }\n\n #declared(source: PivotSource): ReadonlyMap<string, unknown> {\n return new Map(source.fields.map(field => [field.name, field]));\n }\n\n // ---- Asking ----------------------------------------------------------------------------------------\n\n #edited(edit: FieldListEdit): void {\n // A gesture taken against a layout that is no longer the pane's means nothing now: its indexes named the\n // entries of a layout that was replaced (ADR-0061, spine rule 6).\n if (edit.against !== this.#paneLayout) {\n this.#draw();\n return;\n }\n // While Defer Layout Update is ticked the pane builds the pending layout, and the report and the source are\n // left alone (ADR-0061).\n const deferred = this.#deferred;\n if (deferred !== undefined) {\n const { moved } = edit;\n // A field moved into an Area again replaces its earlier move into that Area, so the moves stay bounded.\n const moves = moved === undefined ? deferred.moves\n : [...deferred.moves.filter(move => move.field !== moved.field || move.area !== moved.area), moved];\n this.#deferred = Object.freeze({ layout: edit.layout, moves: Object.freeze(moves) });\n this.#refusal = undefined;\n this.#draw();\n return;\n }\n this.#move(edit.layout, edit.moved === undefined ? [] : [edit.moved]);\n }\n\n // A gesture on the report or the Pivot Toolbar, made to the layout the report is on. While Defer Layout Update\n // holds a pending layout, it reaches that one too, so Update does not take it back; where the pending layout does\n // not hold what the gesture was for, it stays as it is. A gesture that would change nothing now asks nothing.\n #reportEdit(edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: ToggledItem): void {\n const deferred = this.#deferred;\n if (deferred !== undefined) this.#deferred = Object.freeze({ ...deferred, layout: edit(deferred.layout) ?? deferred.layout });\n const now = this.#layoutAhead;\n const next = edit(now);\n if (next === undefined || next === now) this.#draw();\n else this.#move(next, [], toggled);\n }\n\n // Defer Layout Update ticked holds the pane's changes from here on; unticked, it applies them, as Excel does.\n #setDeferred(deferred: boolean): void {\n const held = this.#deferred;\n if (deferred === (held !== undefined)) return;\n if (deferred) {\n this.#deferred = Object.freeze({ layout: this.#layoutAhead, moves: Object.freeze([]) });\n this.#draw();\n return;\n }\n const unticked = defined(held, 'Defer Layout Update ticked');\n this.#deferred = undefined;\n if (this.#pendingApplies(unticked.layout)) this.#move(unticked.layout, unticked.moves);\n else this.#draw();\n }\n\n // Update applies the pending layout in one change, and Defer Layout Update stays ticked. The pending layout stays\n // the pane's, as the Razor component keeps it: refused, it is still the user's work, with the moves it names.\n #applyPending(): void {\n const held = this.#deferred;\n if (held !== undefined && this.#pendingApplies(held.layout)) this.#move(held.layout, held.moves);\n }\n\n // Whether a pending layout would change the report's: layouts are compared by what they say, since a gesture on\n // the report makes the pending layout and the report's anew, each its own.\n #pendingApplies(pending: PivotLayout): boolean {\n const now = this.#layoutAhead;\n return pending !== now && writePivotLayoutJson(pending) !== writePivotLayoutJson(now);\n }\n\n #move(layout: PivotLayout, moved: readonly FieldListMove[], toggled?: ToggledItem): void {\n // A move after a toggle asks for another report: the Item toggled is no longer the one to follow.\n this.#placing?.();\n this.#refusal = undefined;\n this.#ask(layout, 'user', moved, toggled);\n this.#draw();\n }\n\n #ask(layout: PivotLayout, asked: Cause, moved: readonly FieldListMove[], toggled?: ToggledItem): void {\n const superseded = this.#asked;\n superseded?.controller.abort();\n // A layout asked again before its answer came keeps what that question was owed: the user's raises once\n // shown and names its moves if refused, and new data's changes are marked.\n const again = superseded?.layout === layout;\n const raise = asked === 'user' || (again && superseded.raise);\n // A question asked while a Refresh is owed asks the Pivot Source again, and marks what changed, whatever asked it.\n const refreshData = this.#refreshOwed;\n const markChanges = asksData(asked) || refreshData || (again && superseded.markChanges);\n // An Item toggled into the layout keeps the Focus in its report, asked again or not.\n const focusOn = toggled ?? (again ? superseded.toggled : undefined);\n // A user's move made while a user's question was out was taken against it, and carries its moves on.\n const moves = [...(raise && superseded?.raise === true ? superseded.moves : []), ...moved];\n const generation = ++this.#generation;\n // Asked of the source as it stands now, a question answers every change of data told before it, and those the\n // question it superseded carried.\n const carries = this.#changed || superseded?.carries === true;\n this.#changed = false;\n this.#disarmRedraw();\n if (showsNothing(layout) && layout.filters.length === 0) {\n // Nothing to compute: the report is the empty box that says how to start. A layout with fields in Filters\n // alone is asked for still, as the Razor component asks every layout: Filter\u2026 lists their Items under its\n // Report Version (ADR-0066). Nothing on screen reads the data, so no change of data is owed to it: the next\n // layout's question is asked of the source as it stands then.\n this.#asked = undefined;\n this.#showLayout(layout, undefined, raise);\n return;\n }\n const question: Question = {\n layout, generation, controller: new AbortController(), raise, markChanges, refreshData, moves: Object.freeze(moves), carries, cause: asked,\n reportSource: this.#reportSource, source: this.#options.source, settings: this.#settings, locale: this.#locale, maxLeaves: this.#maxLeaves,\n maxRows: this.#maxRows, maxColumns: this.#maxColumns, toggled: focusOn,\n };\n this.#asked = question;\n this.#holdWhileLoading();\n void this.#run(question);\n }\n\n // Holds the report grid's Settled Mark while a question under the loading indication is out, and lets it go once\n // none is: called wherever the question out or the grid changes, and by every draw, which follows each landing\n // after the grid has the report it brought.\n #holdWhileLoading(): void {\n const grid = this.#loading() ? this.#grid : undefined;\n if (this.#loadingHold?.grid === grid) return;\n this.#loadingHold?.release();\n this.#loadingHold = grid === undefined ? undefined : { grid, release: grid.holdSettled() };\n }\n\n async #run(question: Question): Promise<void> {\n const current = (): boolean => question.generation === this.#generation && !this.#destroyed;\n let update;\n try {\n update = await question.reportSource.window(Object.freeze({\n requestId: this.#nextRequestId(),\n layout: question.layout,\n settings: question.settings,\n window: Object.freeze({ start: 0, count: firstWindowRows }),\n maxLeaves: question.maxLeaves,\n markChanges: question.markChanges,\n refreshData: question.refreshData,\n }), question.controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a superseded question's failure is nobody's; the newest one's is said where the user sees it and rethrown\n if (!current()) return;\n this.#asked = undefined;\n const stale = this.#staleFor(question);\n if (stale) this.#markStale(this.#words.staleFailed(error), question.refreshData);\n else this.#refusal = this.#words.failed(error);\n this.#draw();\n // A failure is said where the user sees it, and asked again only by the next notice, Refresh, Retry or move:\n // asking again on the clock would ask a failing source once per interval.\n this.#landed(question, undefined, false);\n this.#options.onFailed?.(Object.freeze({ error, stale }));\n // A failure the Stale Report says is raised and thrown no further, as the Razor component keeps it in\n // LastError: a live source whose transport is down would otherwise throw once for each notice. Any other is\n // rethrown.\n if (!stale) throw error;\n return;\n }\n // Late and superseded: a newer question was asked, and this answers a layout no longer wanted.\n if (!current()) return;\n this.#asked = undefined;\n if (update.refusal !== undefined) {\n if (this.#staleFor(question)) {\n this.#markStale(this.#staleRefusalOf(update.refusal, question), question.refreshData);\n this.#draw();\n } else {\n this.#refuse(update.refusal, question);\n }\n // The report on screen stays on its layout, and the changes the refused question carried are gathered again\n // for it: a refusal of the user's move is no reason to leave the totals before them on screen. A refusal of\n // the layout on screen itself is said, and asked again only by the next notice, Refresh or move.\n this.#landed(question, undefined, question.layout !== this.#shown.layout);\n return;\n }\n const broken = capBrokenBy(update.metadata, question);\n if (broken !== undefined) {\n // An answer past the report's caps is not shown (ADR-0066): newer data under the layout on screen leaves a\n // Stale Report, and a layout is refused, naming the moves it held. Either way the version is the one the\n // source told of, so it is not asked for again until the data moves on.\n const cap = formatPivotCount(broken.cap, question.locale);\n // The source answered, so a Refresh it carried is paid, and Retry asks the report again.\n if (question.refreshData) this.#refreshOwed = false;\n if (this.#staleFor(question)) {\n this.#markStale(this.#words.fill(broken.stale, cap), false);\n this.#draw();\n } else {\n this.#sayRefused(this.#words.fill(broken.refusal, cap), heldFields(heldMoves(question)));\n }\n this.#landed(question, update.metadata.sourceVersion, question.layout !== this.#shown.layout);\n return;\n }\n // The data on screen is the Pivot Source's as it is now: the Refresh is paid.\n if (question.refreshData) this.#refreshOwed = false;\n // Newer data, or data asked for again, ends a Stale Report; the time of the data shown moves with its version, and\n // with its source, whose versions are its own.\n const shown = this.#shown;\n const newer = shown.answer?.metadata.sourceVersion !== update.metadata.sourceVersion || shown.question?.reportSource !== question.reportSource;\n if (newer) this.#shownAt = Date.now();\n if (newer || asksData(question.cause)) {\n this.#stale = undefined;\n this.#staleRetryRefreshes = false;\n }\n // The changes this Window carries are shown from now, on the clock the grid paints by (createGrid's is the\n // system clock, ADR-0068). A cell keeps its mark after the source stops listing its change, until the\n // highlight stamped here ends.\n this.#changeTimes.adopt(update, systemClock.now(), this.#changeHighlightMs);\n this.#showLayout(question.layout, { answer: update, question }, question.raise);\n this.#landed(question, update.metadata.sourceVersion, false);\n }\n\n // ---- Changes of data (ADR-0067) --------------------------------------------------------------------\n\n // Whether a question that could not be shown leaves a Stale Report rather than a refusal: one the data asked, for the\n // layout of the report on screen. A move of the user's or the Consumer's is refused, and the pane goes back.\n #staleFor(question: Question): boolean {\n return asksData(question.cause) && this.#shown.answer !== undefined && question.layout === this.#shown.layout;\n }\n\n #markStale(sentence: string, retryRefreshes: boolean): void {\n this.#stale = sentence;\n this.#staleRetryRefreshes = retryRefreshes;\n }\n\n // What a refusal of newer data says, after the time of the data shown. A refusal the report source made itself, and\n // not the Pivot Source, is its failure to answer, as the Razor component says it.\n #staleRefusalOf(refusal: PivotReportRefusal, question: Question): string {\n const source = refusal.sourceRefusal;\n if (source === undefined) return this.#words.fill('stale-source-failed', refusal.message);\n if (source.kind === 'tooManyLeaves') return this.#words.fill('stale-too-many-cells', formatPivotCount(source.limit ?? question.maxLeaves, question.locale));\n return this.#words.fill('stale-source-refused', source.message);\n }\n\n // The Stale Report's Retry asks again what failed: Refresh, when that is what failed, otherwise the report's question\n // of the Pivot Source (ADR-0067). Either asks the Pivot Source itself, as the Razor component's Retry does: a report\n // source that kept its last answer would give back the data the report already shows, and the notice would go.\n #retry(): void {\n if (this.#staleRetryRefreshes) {\n this.#refresh();\n return;\n }\n this.#refreshOwed = true;\n this.#refusal = undefined;\n this.#ask(this.#layoutAhead, 'data', []);\n this.#draw();\n }\n\n // When the data the report shows arrived, in the report's locale: the time, and the date too when it is not today's,\n // since a time alone would say the report is fresher than it is.\n #asOf(): string {\n const at = new Date(this.#shownAt);\n const today = new Date().toDateString() === at.toDateString();\n const key = `${this.#shownAt} ${this.#locale} ${today ? 'today' : 'before'}`;\n if (this.#asOfSaid?.key !== key) {\n const text = new Intl.DateTimeFormat(this.#locale, today ? { timeStyle: 'medium' } : { dateStyle: 'short', timeStyle: 'medium' }).format(at);\n this.#asOfSaid = { key, text };\n }\n return this.#asOfSaid.text;\n }\n\n // Hears the report source's notices, and no longer the one before: a source handed over is asked from nothing, and\n // that question answers whatever was gathered.\n #hear(reportSource: LocalPivotReportSource): void {\n this.#stopHearing?.();\n this.#changed = false;\n this.#changedTo = undefined;\n this.#disarmRedraw();\n this.#stopHearing = reportSource.subscribe(changed => { this.#sourceChanged(reportSource, changed); });\n }\n\n // The source's data moved on: gathered, and asked for at once when the last change reached the screen more than\n // the redraw interval ago and nothing is out, otherwise when that time comes, or when the question out lands. A\n // notice of the very version on screen, with nothing out and nothing gathered before it, has nothing to bring.\n #sourceChanged(reportSource: LocalPivotReportSource, changed: PivotSourceChanged): void {\n if (this.#destroyed || reportSource !== this.#reportSource) return;\n const { answer, question } = this.#shown;\n if (!this.#changed && this.#asked === undefined && this.#stale === undefined && changed.sourceVersion !== undefined && question?.reportSource === reportSource\n && answer?.metadata.sourceVersion === changed.sourceVersion) {\n return;\n }\n this.#changed = true;\n this.#changedTo = changed.sourceVersion;\n this.#scheduleRedraw();\n }\n\n // Asks for the changes gathered no sooner than the redraw interval after the last change reached the screen: at\n // once when that time has passed, else when it comes. Nothing is asked while a question is out: its landing asks.\n #scheduleRedraw(): void {\n if (!this.#changed || this.#asked !== undefined || this.#destroyed) return;\n const ahead = this.#layoutAhead;\n if (showsNothing(ahead) && ahead.filters.length === 0) {\n // Nothing on screen reads the data: the next layout's question is asked of the source as it stands then.\n this.#changed = false;\n this.#disarmRedraw();\n return;\n }\n const now = performance.now();\n const due = this.#lastDataShown === undefined ? now : this.#lastDataShown + this.#redrawInterval;\n if (due <= now) {\n this.#ask(ahead, 'live', []);\n this.#draw();\n return;\n }\n if (this.#redrawTimer !== undefined) return;\n this.#redrawTimer = setTimeout(() => {\n this.#redrawTimer = undefined;\n this.#scheduleRedraw();\n }, due - now);\n }\n\n #disarmRedraw(): void {\n if (this.#redrawTimer === undefined) return;\n clearTimeout(this.#redrawTimer);\n this.#redrawTimer = undefined;\n }\n\n // A question landed \u2014 answered, refused or failed. One that carried changes of data brought them to the screen, or\n // found them unshowable, and the next waits the redraw interval from now; the changes gathered meanwhile are asked\n // for then, unless the answer is already of the version the latest notice named. `regather` gathers again the changes\n // a question carried and did not bring.\n #landed(question: Question, version: string | undefined, regather: boolean): void {\n if (question.carries) this.#lastDataShown = performance.now();\n if (regather && question.carries) this.#changed = true;\n if (this.#changed && this.#changedTo !== undefined && version === this.#changedTo) this.#changed = false;\n this.#scheduleRedraw();\n }\n\n #nextRequestId(): string {\n this.#requests++;\n return `ex-pivot-${this.#requests}`;\n }\n\n #showLayout(layout: PivotLayout, answered: { readonly answer: PivotReportState; readonly question: Question } | undefined, raise: boolean): void {\n const answer = answered?.answer;\n this.#shown = { layout, answer, question: answered?.question };\n // A pending move the report on screen now holds is news no more: a refusal of the pending layout names it no more.\n const deferred = this.#deferred;\n if (deferred !== undefined && deferred.moves.length > 0) {\n this.#deferred = Object.freeze({ layout: deferred.layout, moves: Object.freeze(deferred.moves.filter(move => !holdsMove(layout, move))) });\n }\n this.#showReport(answered);\n if (answer !== undefined && this.#counts !== undefined && this.#counts.sourceVersion !== answer.metadata.sourceVersion) {\n // Counted under another Source Version: asked again, so the marks follow the data (ADR-0370 section 3).\n this.#askCounts();\n }\n this.#draw();\n if (raise) {\n this.#raised.add(layout);\n this.#options.onLayoutChanged?.(Object.freeze({ layout }));\n }\n }\n\n // A refused question: the pane goes back to the layout the report shows, and the sentence says why. Every\n // move taken against the refused layout went with it, and is named (ADR-0370 section 3). A pending layout, while\n // Defer Layout Update is ticked, is the user's work in the pane, and stays, as the Razor component keeps it.\n #refuse(refusal: PivotReportRefusal, question: Question): void {\n const { message, fields } = this.#sentenceFor(refusal, question);\n this.#sayRefused(message, fields);\n }\n\n #sayRefused(message: string, fields: readonly string[]): void {\n this.#refusal = message;\n this.#draw();\n this.#options.onRefused?.(Object.freeze({ message, fields: Object.freeze(fields) }));\n }\n\n #sentenceFor(refusal: PivotReportRefusal, question: Question): { readonly message: string; readonly fields: readonly string[] } {\n const held = heldMoves(question);\n const named = heldFields(held);\n const source = refusal.sourceRefusal;\n if (source?.kind !== 'tooManyLeaves') return { message: refusal.message, fields: refusal.field === undefined ? named : [refusal.field] };\n // A source that names no limit stopped at the cap it was asked with (ADR-0066).\n const { locale } = question;\n const cap = formatPivotCount(source.limit ?? question.maxLeaves, locale);\n // Server data is refused naming each field moved into Rows or Columns, which make the combinations\n // (ADR-0370 section 3); data the pivot computes itself is refused by the cells the layout needs, as the\n // Razor component says it.\n const combining = held.filter(move => move.area === 'rows' || move.area === 'columns');\n if (!(this.#options.source instanceof FetchingPivotSource) || combining.length === 0) {\n return { message: this.#words.fill('refused-too-many-cells', cap), fields: named };\n }\n const sentences = combining.map(move => {\n const caption = this.#captionOf(move.field);\n const area = this.#words.area(move.area);\n const count = this.#counts?.countOf(move.field);\n const sentence = count === undefined\n ? this.#words.fill('refused-too-many-combinations', caption, area, cap)\n : this.#words.fill('refused-too-many-combinations-counted', caption, formatPivotCount(count, locale), area, cap);\n return `${sentence} ${this.#words.fill('refused-too-many-combinations-remedy', caption)}`;\n });\n return { message: sentences.join(' '), fields: named };\n }\n\n #captionOf(field: string): string {\n const found = this.#options.source.fields.find(f => f.name === field);\n if (found === undefined) throw new Error(`Internal: the field '${field}' is not the source's.`);\n return found.caption;\n }\n\n // Each field's count of Items, asked once when the source is opened and again under a new Source Version,\n // of a source that declares it counts them (ADR-0370 section 3). A source that does not gets no count.\n #askCounts(): void {\n this.#countsAsked?.abort();\n const source = this.#options.source;\n if (!source.features.countsItems || source.itemCounts === undefined) {\n this.#countsAsked = undefined;\n return;\n }\n const controller = new AbortController();\n this.#countsAsked = controller;\n void this.#countItems(source, controller);\n }\n\n async #countItems(source: PivotSource, controller: AbortController): Promise<void> {\n let counts;\n try {\n if (source.itemCounts === undefined) throw new Error('Internal: a source counted without counting Items.');\n counts = await source.itemCounts(controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a count superseded is nobody's; one that failed leaves the fields uncounted, said by rethrowing\n if (controller.signal.aborted || this.#destroyed) return;\n this.#countsAsked = undefined;\n throw error;\n }\n if (controller.signal.aborted || this.#destroyed || source !== this.#options.source) return;\n this.#countsAsked = undefined;\n this.#counts = counts;\n this.#draw();\n }\n\n // ---- The report ------------------------------------------------------------------------------------\n\n #showReport(answered: { readonly answer: PivotReportState; readonly question: Question } | undefined): void {\n this.#placing?.();\n this.#rows?.dispose();\n this.#rows = undefined;\n // The rows of the report before read a source that may since have been replaced.\n const before = this.#shownReportSource;\n this.#shownReportSource = answered?.question.reportSource;\n this.#release(before);\n if (answered === undefined || !this.#reportDrawn) {\n this.#grid?.destroy();\n this.#grid = undefined;\n this.#holdWhileLoading();\n return;\n }\n const { answer, question } = answered;\n this.#rows = reportRows({\n source: question.reportSource,\n layout: question.layout,\n settings: question.settings,\n maxLeaves: question.maxLeaves,\n answered: answer,\n nextRequestId: () => this.#nextRequestId(),\n moved: () => { this.#reportMoved(answer); },\n findGivenUp: why => { this.#findGivenUp(answer, why); },\n words: () => this.#words,\n });\n this.#drawGrid();\n if (question.toggled !== undefined) this.#placeToggled(question.toggled);\n }\n\n // The toggled Item keeps the Focus, as it does in Excel (ADR-0050 item 4): its label cell is selected among the\n // first rows the grid holds of the report it was toggled into, on the toggled row's path, as the Razor component\n // finds it among the rows drawn, and under the order those rows came in. A press, a key or a wheel the user turns\n // in the grid after the toggle, while its question is out or its rows are on their way, is newer than the toggle,\n // and the toggle places nothing over it (spine rule 6); a modifier pressed alone, or a key composing text, is no\n // such gesture. Nor does the toggle place anything after a later move, or once another report is shown. A placement the grid refuses leaves the Selection it dropped with the\n // old report, and the toggled Item is found in no other rows than those first ones: no place, rather than a\n // late one over what the user did since.\n #placeToggled(toggled: ToggledItem): void {\n const rows = this.#rows;\n const grid = this.#grid;\n if (rows === undefined || grid === undefined) return;\n const place = (): void => {\n if (this.#gestures !== toggled.gestures) {\n stop();\n return;\n }\n const state = rows.snapshot();\n if (state.window.length === 0) return;\n stop();\n const at = toggledCell(state.window, state.windowStart, toggled);\n if (at === undefined) return;\n grid.placeSelection(Object.freeze({ topRow: at.row, leftColumn: at.column, rowCount: 1, columnCount: 1 }), at, state.rowSequenceVersion);\n };\n const unsubscribe = rows.subscribe(place);\n const stop = (): void => {\n unsubscribe();\n if (this.#placing === stop) this.#placing = undefined;\n };\n this.#placing = stop;\n place();\n }\n\n // The source answered a Window from another report than the one shown: the data moved on under it, and the\n // report on screen is asked again under its layout, unless something newer is asked already.\n #reportMoved(answer: PivotReportState): void {\n // A Stale Report is not asked again for it: the newest data is what it could not show, and asking again would\n // break the same cap once per interval while the reader scrolls. Retry and the source's next notice ask.\n if (this.#destroyed || this.#shown.answer !== answer || this.#asked !== undefined || this.#stale !== undefined) return;\n // A change of data like any other: asked for no sooner than the redraw interval after the last one shown.\n this.#changed = true;\n this.#scheduleRedraw();\n }\n\n // Figures handed in replace the ones shown only when they differ from the ones handed before: an update that hands\n // the same again keeps the figures menu's choice. True when the figures shown moved.\n #adoptSummaryFigures(handed: readonly SummaryFigure[] | undefined): boolean {\n if (sameFigures(handed, this.#summaryFiguresHanded)) return false;\n this.#summaryFiguresHanded = handed;\n const shown = handed ?? defaultSummaryFigures;\n if (sameFigures(shown, this.#summaryFigures)) return false;\n this.#summaryFigures = shown;\n return true;\n }\n\n // The figures menu's choice, which the report holds and raises (ADR-0130). Held in a field: its identity reaches the\n // grid.\n readonly #summaryFiguresChosen = (figures: readonly SummaryFigure[]): void => {\n if (this.#destroyed) return;\n this.#summaryFigures = figures;\n this.#drawGrid();\n this.#options.onSummaryFiguresChanged?.(figures);\n };\n\n // The Selection Summary as it stands, raised to the Consumer's handler as the options now hold it. Held in a field,\n // so a handler that is a new function at each update does not draw the grid again.\n readonly #selectionSummaryChanged = (summary: SelectionSummary): void => {\n this.#options.onSelectionSummaryChanged?.(summary);\n };\n\n #drawGrid(): void {\n const answer = this.#shown.answer;\n const rows = this.#rows;\n const question = this.#shown.question;\n if (answer === undefined || rows === undefined || question === undefined) return;\n const { locale } = question;\n const { columns, headerGroups, pinnedColumnCount } = this.#columns.of(answer.metadata, this.#userWidths);\n this.#gridColumns = columns;\n this.#valueColumnIndexes = new Map(answer.metadata.valueColumns.map((column, index) => [column.name, index]));\n const { rowHeight, density, cellMetrics, presentationDefaults } = this.#options;\n const gridChrome = this.#chrome?.grid;\n const options: GridOptions<PivotDisplayRow> = {\n columns,\n headerGroups,\n pinnedColumnCount,\n source: rows,\n locale,\n viewportHeight: this.#options.viewportHeight ?? 400, // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report's declared default height, as the Razor component's\n viewportWidth: this.#options.viewportWidth ?? 'stretch', // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report takes what the Field List leaves unless told\n // Item order and Hidden Items are the Pivot Layout's, and a report is computed: no column menu, no\n // sort, no filter, and every write refused by the grid's own gate, since nobody hears one (ADR-0059).\n hideColumnMenu: true,\n onColumnWidthChanged: change => { this.#widthChanged(change); },\n onCellDoubleClick: cell => { this.#doubleClicked(cell); },\n onSelectionChanged: selection => { this.#selectionChanged(selection); },\n contextCommands: this.#contextCommands,\n // Find over the report as shown, and its painted matches marked by the rule it finds by (ADR-0332).\n findMatch: reportMatch,\n onRefused: this.#gridRefused,\n copyAnswerAsync: this.#copyReport,\n commandLabel: this.#commandLabel,\n cellChangedAt: this.#cellChangedAt,\n changeHighlightDuration: this.#changeHighlightMs,\n showSelectionSummary: this.#options.showSelectionSummary !== false,\n summaryFigures: this.#summaryFigures,\n onSummaryFiguresChanged: this.#summaryFiguresChosen,\n onSelectionSummaryChanged: this.#selectionSummaryChanged,\n ...(gridChrome === undefined ? {} : { chrome: gridChrome }),\n ...(rowHeight === undefined ? {} : { rowHeight }),\n ...(density === undefined ? {} : { density }),\n ...(cellMetrics === undefined ? {} : { cellMetrics }),\n ...(presentationDefaults === undefined ? {} : { presentationDefaults }),\n };\n if (this.#grid === undefined) {\n // Made standing in the sheet, inside the pivot's box: the grid reads its Input Root once, as it is made, and\n // on an element standing nowhere it would hear only itself, not the Field List, the toolbar or the popups\n // (ADR-0240 section 6). The draw that follows keeps it there, or puts the report's notice in its place.\n if (this.#gridRoot.parentNode !== this.#sheet) this.#sheet.prepend(this.#gridRoot);\n this.#grid = this.#mountGrid(this.#gridRoot, options);\n // A grid made while a question is out is held from its first paint, as the one it replaced was.\n this.#holdWhileLoading();\n } else {\n this.#grid.update(options);\n }\n }\n\n // A Find step over the report that cannot go on is said on the Pivot Toolbar, while that report is the one shown:\n // a step over a report since replaced is the grid's to refuse, as its source is no longer the grid's (ADR-0332 \u00A71).\n #findGivenUp(answer: PivotReportState, why: ReportFindGivenUp): void {\n if (this.#destroyed || this.#shown.answer !== answer) return;\n switch (why.kind) {\n case 'notHeld': this.#refusal = this.#words.word('find-report-not-held'); break;\n case 'refused': this.#refusal = this.#words.fill('source-refused', why.refusal.message); break;\n case 'invalid': this.#refusal = this.#words.word('find-invalid-answer'); break;\n default: unreachable(why);\n }\n this.#draw();\n }\n\n // A copy is the report source's, of the report on screen, as the Razor component's is (ADR-0152): each cell's text\n // and its locale-free form, and a number column Item's header in full in the HTML flavour (ADR-0005's note of\n // 2026-10-13). Every refusal is said in ExPivot's words, a source's own inside one (ADR-0060). Held in a field: its\n // identity reaches the grid.\n readonly #copyReport = async (request: GridCopyRequest, signal: AbortSignal): Promise<GridCopyAnswer> => {\n // The whole question is captured before awaiting: a new Window never rebinds this gesture.\n const metadata = this.#shown.answer?.metadata;\n const source = this.#shownReportSource;\n const rows = this.#rows;\n if (metadata === undefined || source === undefined || rows === undefined || request.rowSequenceVersion !== rows.snapshot().rowSequenceVersion) {\n return refuse(this.#words.word('data-changed'));\n }\n // A Stale Report shows the data as of its time, and says so beside it; pasted elsewhere, the numbers would lose\n // that and look current. So Copy is refused, saying as of when, until Retry brings the newest (ADR-0067).\n if (this.#stale !== undefined) return refuse(this.#words.fill('copy-stale-report', this.#asOf()));\n const { plan } = request;\n const version = metadata.version;\n const answer = await source.copy(Object.freeze({\n version,\n columns: Object.freeze(this.#gridColumns.map(column => column.name)),\n ranges: Object.freeze(plan.segments.map(range => Object.freeze({\n top: range.topRow, left: range.leftColumn, bottom: range.topRow + range.rowCount - 1, right: range.leftColumn + range.columnCount - 1,\n }))),\n }), signal);\n if (answer.version !== version) return refuse(this.#words.word('copy-another-version'));\n if (answer.refusal !== undefined) return refuse(this.#words.fill('source-refused', answer.refusal.message));\n if (answer.blocks.length !== plan.segments.length) return refuse(this.#words.word('copy-missing-range'));\n const whole = plan.segments.every((range, i) => {\n const block = elementAt(answer.blocks, i);\n return block.rows.length === range.rowCount && block.headers.length === range.columnCount\n && (block.headerRaws === undefined || block.headerRaws.length === range.columnCount)\n && block.rows.every(cells => cells.length === range.columnCount);\n });\n if (!whole) return refuse(this.#words.word('copy-incomplete-range'));\n // The block a position lies in: the one the last position lay in, which assembly mostly asks again, or the one\n // found by halves along the plan's order, as the Razor component finds it.\n const vertical = plan.orientation === 'vertical';\n let hint = 0;\n const blockAt = (row: number, column: number): number => {\n const at = vertical ? row : column;\n const within = (index: number): number => {\n const range = elementAt(plan.segments, index);\n const start = vertical ? range.topRow : range.leftColumn;\n const end = start + (vertical ? range.rowCount : range.columnCount) - 1;\n return at < start ? -1 : at > end ? 1 : 0;\n };\n if (within(hint) === 0) return hint;\n let low = 0;\n let high = plan.segments.length - 1;\n while (low <= high) {\n const middle = low + Math.floor((high - low) / 2);\n const side = within(middle);\n if (side === 0) {\n hint = middle;\n return middle;\n }\n if (side < 0) high = middle - 1;\n else low = middle + 1;\n }\n throw new Error('The copied position is outside the approved plan.');\n };\n const cellAt = (row: number, column: number): PivotReportCopyCell => {\n const index = blockAt(row, column);\n const range = elementAt(plan.segments, index);\n return elementAt(elementAt(elementAt(answer.blocks, index).rows, row - range.topRow), column - range.leftColumn);\n };\n const headerBlock = (column: number): number => {\n const index = plan.segments.findIndex(range => column >= range.leftColumn && column < range.leftColumn + range.columnCount);\n if (index < 0) throw new Error('The copy header is outside the approved plan.');\n return index;\n };\n const flavours = assembleCopy(plan, {\n displayAt: (row, column) => cellAt(row, column).text,\n // A blank carries no raw form, and is written empty, as the Razor component writes it.\n // oxlint-disable-next-line ex-grid/no-stand-in-default -- ADR-0005: a blank cell's HTML flavour is empty\n rawAt: (row, column) => cellAt(row, column).raw ?? '',\n ...(request.withHeaders ? {\n headerAt: (column: number) => {\n const index = headerBlock(column);\n return elementAt(elementAt(answer.blocks, index).headers, column - elementAt(plan.segments, index).leftColumn);\n },\n headerRawAt: (column: number) => {\n const index = headerBlock(column);\n return elementAt(answer.blocks, index).headerRaws?.[column - elementAt(plan.segments, index).leftColumn];\n },\n } : {}),\n });\n return Object.freeze({ kind: 'write', text: flavours.text, html: flavours.html });\n };\n\n // The report grid's refusals: Ctrl+H on a report, which is not written, is said on the Pivot Toolbar in Excel's\n // words (ADR-0332 \u00A72). The refusals the find panel shows itself are left to it. Held in a field: its identity\n // reaches the grid.\n readonly #gridRefused = (refusal: GridRefusal<PivotDisplayRow>): void => {\n if (this.#destroyed || refusal.kind !== 'find' || refusal.reason !== 'replaceUnavailable') return;\n this.#refusal = this.#words.word('replace-unavailable');\n this.#draw();\n };\n\n // A width the user dragged a column to is the Consumer's to hand back (ADR-0016): the pivot keeps it, by the\n // column's name, for every report that has the column.\n #widthChanged(change: GridColumnWidthChange): void {\n this.#userWidths.set(change.column, change.widthPx);\n this.#drawGrid();\n }\n\n // The grid's selection, said with what its cells stand for, read from the rows the grid holds when it is\n // raised: each report is a new source, so a selection the grid keeps is over the same report's rows, and one\n // over another report is dropped and raised again (ADR-0011). The Items are read when first asked for, from\n // what was held then, so a selection dragged over thousands of cells costs nothing until a Consumer reads it.\n #selectionChanged(selection: GridSelection): void {\n const raise = this.#options.onSelectionChanged;\n if (raise === undefined || this.#destroyed) return;\n const answer = this.#shown.answer;\n const state = this.#rows?.snapshot();\n const metadata = answer?.metadata;\n let read = false;\n let items: readonly PivotCellItems[] | undefined;\n raise(Object.freeze({\n selection,\n get items(): readonly PivotCellItems[] | undefined {\n if (!read) {\n read = true;\n if (metadata !== undefined && state !== undefined) items = cellItems(selection, metadata, state.window, state.windowStart);\n }\n return items;\n },\n }));\n }\n\n // A double click on an outer Item's label expands or collapses it, as Excel's does (ADR-0063).\n #doubleClicked(cell: CellPosition): void {\n const { answer, question } = this.#shown;\n const rows = this.#rows;\n if (answer === undefined || question === undefined || rows === undefined) return;\n const state = rows.snapshot();\n const row = state.window[cell.row - state.windowStart];\n if (row === undefined) return;\n const labels = answer.metadata.labelColumns.length;\n if (cell.column >= labels) {\n this.#showDetails(answer, question, row, cell.column - labels);\n return;\n }\n // A double click on an outer Item's label expands or collapses it, as in Excel.\n const toggle = elementAt(row.labels, cell.column).toggle;\n if (toggle !== undefined) this.#toggled(toggle, row);\n }\n\n // Show Details (ADR-0059, ADR-0063): the records behind a value cell, asked of the Pivot Source the report came\n // from under its Source Version, so they add up to the cell. An empty cell has none. Resolved now, from the cell\n // the user acted on: the question names its Items and the Source Version, so a collapse or a sort that follows\n // leaves it the same question.\n #showDetails(answer: PivotReportState, question: Question, row: PivotDisplayRow, valueColumn: number): void {\n if (row.values[valueColumn] === undefined) return;\n const { metadata } = answer;\n const words = this.#words;\n const fields = question.source.fields;\n const options = { locale: question.locale, ...(words.label === undefined ? {} : { label: words.label }) };\n // Each Item with its field's caption and its label, by the engine's rule for its field (ADR-0060).\n const items = (path: readonly PivotFieldItem[]): readonly PivotDetailItem[] => Object.freeze(path.map(step => {\n const declared = fields.find(field => field.name === step.field);\n if (declared === undefined) throw new Error(`Internal: the report's field '${step.field}' is not its source's.`);\n const [info] = itemsOfPage(PivotItemPage.of(metadata.sourceVersion, [step.item], 1), metadata.layout, declared, options);\n if (info === undefined) throw new Error('Internal: an Item listed is labelled.');\n return Object.freeze({ field: declared.caption, item: info.label });\n }));\n const rowItems = items(row.rowPath);\n const column = elementAt(metadata.valueColumns, valueColumn);\n const columnItems = items(column.columnPath);\n const valueField = valueFieldAt(metadata, row, valueColumn);\n const path = [...rowItems, ...columnItems].map(item => item.item);\n const details = detailsEvent(question.source, pivotReportDetailsQuery(metadata, row, valueColumn), {\n title: words.fill('details-title', path.length === 0 ? words.word('grand-total') : path.join(' / ')),\n rowItems,\n columnItems,\n valueField: valueField < 0 ? undefined : elementAt(metadata.valueCaptions, valueField),\n });\n const heard = this.#options.onShowDetails;\n if (heard !== undefined) {\n this.#detailsRaised.add(details);\n heard(details);\n return;\n }\n this.#details.open(details, this.#options.detailsView ?? 'tab', question.locale); // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0059: a tab at the report's foot unless the Consumer asks for the dialog, as the Razor component's DetailsView\n this.#slotErrors.push(...this.#details.takeRefused());\n this.#throwRefused();\n }\n\n // The report's commands in the grid's Context Menu (ADR-0036, ADR-0059), for a row of the report on screen.\n readonly #contextCommands = (context: GridContextMenuContext<PivotDisplayRow>): readonly GridCommand[] => {\n const { answer, question } = this.#shown;\n const rows = this.#rows;\n if (this.#destroyed || answer === undefined || question === undefined || rows === undefined || !rows.snapshot().window.includes(context.row)) {\n return [];\n }\n return reportMenuCommands({\n metadata: answer.metadata,\n row: context.row,\n column: context.column,\n report: this.#layoutAhead,\n pane: this.#paneLayout,\n fieldListShown: this.#fieldListShown,\n captionOf: field => this.#captionOf(field),\n }, {\n edit: (edit, toggled) => { this.#reportEdit(edit, toggled === undefined ? undefined : this.#toggledItemOf(context.row, toggled)); },\n showDetails: valueColumn => { this.#showDetails(answer, question, context.row, valueColumn); },\n valueFieldSettings: (valueField, holds) => { this.#openFromReport(valueField, holds); },\n setFieldListShown: shown => { this.#setFieldListShown(shown); },\n });\n };\n\n // The words of the grid's commands (ADR-0036): the Consumer's, then the pivot's own for its commands; the grid's\n // own commands keep the grid's English where the Consumer gives none. Made again with the Consumer's words, so the\n // grid, which holds words by the function they came from, reads them again.\n #commandLabelOf(label: PivotLabel | undefined): (id: string) => string | undefined {\n return id => {\n const own = label?.(id);\n if (own !== undefined) return own;\n const caption = captionOfRemove(id);\n if (caption !== undefined) return this.#words.fill(removeNamedFieldId, caption);\n return pivotWordIds.has(id) ? pivotWord(id, undefined) : undefined;\n };\n }\n\n // The stylesheets' notices (ADR-0123, ERR-11), as the Razor component draws them: ExPivot's own, and beside it one\n // for each stylesheet the Chrome brings, each hidden until a stylesheet's rules decide. Every shipped stylesheet\n // shows a notice of its name and hides it for its own stamp, so another version's shows it, this version's hides\n // it, and none yet loaded shows nothing, with no script. The report grid draws ExGrid's own.\n #drawNotices(): void {\n const brought = this.#chrome?.stylesheets;\n const sheets = [{ name: stylesheetName, stamp: stylesheetStamp }, ...(brought === undefined ? [] : brought)];\n const id = reloadNoticeLabelIds.stylesheet;\n const words = this.#commandLabel(id) ?? builtInCommandLabel(id);\n const drawn = JSON.stringify([words, sheets.map(sheet => [sheet.name, sheet.stamp])]);\n if (drawn === this.#noticesDrawn) return;\n this.#noticesDrawn = drawn;\n for (const notice of this.#notices) notice.remove();\n this.#notices = sheets.map(sheet => {\n const notice = element(this.#root.ownerDocument, 'div');\n notice.setAttribute('data-ex-notice', 'stylesheet');\n notice.setAttribute('data-ex-stylesheet', sheet.name);\n notice.setAttribute('data-ex-stamp', sheet.stamp);\n notice.style.display = 'none';\n notice.textContent = words;\n return notice;\n });\n this.#root.prepend(...this.#notices);\n }\n\n // Value Field Settings\u2026 from the report opens in the pane, under the Value Field's entry, showing the Field List.\n // Opened only while the pane holds the Value Field the cell showed there.\n #openFromReport(valueField: number, holds: (pane: PivotLayout) => boolean): void {\n const pane = this.#paneLayout;\n const value = pane.values[valueField];\n if (value === undefined || !holds(pane)) return;\n this.#setFieldListShown(true);\n this.#openPanelAt({ entry: { area: 'values', index: valueField }, field: value.field, against: pane }, 'value-field-settings');\n }\n\n // An outer Item's button pressed, or its label double clicked: the Item is collapsed or expanded (ADR-0063).\n // The press does what the button it was taken on said, against the report's layout, the one the newest question\n // asks for; where that layout no longer holds the Item as the button painted it, a press already moved it, or\n // its field left the layout, and the press is refused rather than turned into its opposite (spine rule 6). Two\n // presses of one painted button collapse once, as the Razor component's do. A pending layout follows it.\n // An Item toggled on a row, as it keeps the Focus in the report the toggle brings.\n #toggledItemOf(row: PivotDisplayRow, toggled: PivotFieldItem): ToggledItem {\n const level = row.rowPath.findIndex(step => step.field === toggled.field && itemKeysEqual(step.item, toggled.item));\n if (level < 0) throw new Error(`Internal: the row toggled holds no '${toggled.field}' Item there.`);\n return Object.freeze({ path: Object.freeze(row.rowPath.slice(0, level + 1)), gestures: this.#gestures });\n }\n\n // The Item keeps the Focus in the report the press brings.\n #toggled(toggle: PivotToggle, row: PivotDisplayRow): void {\n if (this.#destroyed) return;\n const now = this.#layoutAhead;\n const placed = now.rows.find(placement => placement.field === toggle.field);\n if (placed === undefined || isItemCollapsed(placed, toggle.item) !== toggle.isCollapsed) return;\n this.#reportEdit(layout => (layout.rows.some(placement => placement.field === toggle.field)\n ? setCollapsed(layout, toggle.field, toggle.item, !toggle.isCollapsed)\n : undefined), this.#toggledItemOf(row, toggle));\n }\n\n // The report asked again of the Pivot Source, under the pane's layout. A move of the user's still out is asked again\n // with it, and stays the user's.\n #refresh(): void {\n // Owed until an answer from the Pivot Source asked again lands: a move made meanwhile, or a layout with nothing\n // to compute, does not answer it from the data before it.\n this.#refreshOwed = true;\n this.#refusal = undefined;\n this.#askCounts();\n this.#ask(this.#layoutAhead, 'data', []);\n this.#draw();\n }\n\n // ---- Menus and panels (ADR-0061) -------------------------------------------------------------------\n\n #toggleLayoutMenu(): void {\n if (this.#open?.kind === 'layout') {\n this.#close('opener');\n return;\n }\n this.#anchorFor('layout', 'chrome.toolbar hands in no anchor \\'layout\\': hand context.anchor(\\'layout\\') the element around Layout \u25BE');\n this.#openSurface({ kind: 'layout', popup: this.#menuFrame('toolbar-end') });\n }\n\n // A popup of the Pivot Toolbar's opens only in an anchor that stands: one that would stand nowhere, behind a\n // backdrop that takes every press, is refused, naming what the Chrome did not hand in (ADR-0390).\n #anchorFor(name: string, missing: string): void {\n if (!this.#parts.anchored(name)) throw new Error(`An ExPivot's ${missing} (ADR-0390).`);\n }\n\n // An entry's button opens its menu, and closes the menu standing under it.\n #toggleEntryMenu(entry: PivotEntry): void {\n // A panel open under the entry is dropped for the menu, as the Razor component's ToggleMenu does.\n const open = this.#open;\n if (open?.kind === 'entry' && sameEntry(open.entry, entry)) {\n this.#close('opener');\n return;\n }\n const pane = this.#paneLayout;\n const field = isValuesPseudoField(entry) ? undefined : fieldOf(pane, entry);\n if (this.#fieldListSlotted) {\n this.#anchorFor(entryKey(entry), `chrome.fieldList hands in no anchor for the entry '${entryKey(entry)}': hand context.anchor(entry.key) the element around its button`);\n }\n this.#openSurface({ kind: 'entry', entry, field, against: pane, popup: this.#menuFrame('field-list') });\n }\n\n #menuFrame(place: 'field-list' | 'toolbar-end'): PivotMenu {\n const escape = (): void => { this.#close('opener'); };\n const mount = this.#chrome?.menu;\n const frame = mount === undefined\n ? new PivotMenuFrame(this.#root.ownerDocument, place, escape)\n : new SlottedMenuFrame(this.#root.ownerDocument, place, mount, this.#words, escape);\n this.#closeOnLeaving(frame.element);\n return frame;\n }\n\n // The keyboard leaving what is open for another control \u2014 Tab past its last command \u2014 closes it, so the backdrop of\n // a surface opened from the Pivot Toolbar takes no press meant for that control, and a field menu does not stand\n // open over the pane once the keyboard left the pivot. A field menu's entry, which toggles it, is inside its bounds.\n #closeOnLeaving(frame: HTMLElement): void {\n frame.addEventListener('focusout', event => {\n const to = event.relatedTarget;\n const open = this.#open;\n // A popup of a Chrome's contents may stand outside the frame, and take the keyboard while it is open.\n if (open?.popup.element !== frame || !(to instanceof Node) || open.popup.innerPopupOpen?.() === true) return;\n if (!this.#within(open, to)) this.#close('stay');\n });\n }\n\n // Whether `node` is inside what is open. A field menu's bounds are its entry: the anchor around the frame, and the\n // entry's button, which a Chrome may draw beside the anchor rather than in it, as a design system draws a menu's\n // opener.\n #within(open: OpenSurface, node: Node): boolean {\n const frame = open.popup.element;\n if (open.kind !== 'entry') return frame.contains(node);\n const anchor = frame.parentNode;\n return (anchor !== null && anchor.contains(node)) || this.#parts.controlContains(entryKey(open.entry), node);\n }\n\n // A report filter's button opens Filter\u2026 under it, over the report, and closes the one standing under it.\n #toggleBand(field: string): void {\n const open = this.#open;\n if (open?.kind === 'band' && open.field === field) {\n this.#close('opener');\n return;\n }\n this.#anchorFor(bandName(field), `chrome.reportFilters hands in no anchor for '${field}': hand context.anchor('${field}') the element around its button`);\n const report = this.#layoutAhead;\n const handlers = {\n // OK's Hidden Items are the report's next, taken against the layout Filter\u2026 was opened on (spine rule 6),\n // and reach a pending layout that holds the field too.\n apply: (layout: PivotLayout) => {\n this.#finish(surface, () => {\n if (report === this.#layoutAhead) {\n const hidden = defined(layout.filters.find(placement => placement.field === field), `the report filter '${field}'`).hiddenItems;\n this.#reportEdit(now => (placementOf(now, field) === undefined ? undefined : setHiddenItems(now, field, hidden, []).layout));\n }\n return undefined;\n });\n },\n cancel: () => { if (this.#open === surface) this.#close('opener'); },\n items: () => this.#itemsOf(field),\n search: (search: string, signal: AbortSignal) =>\n Promise.resolve().then(() => searchItems(field, search, defined(this.#itemsUnder(field), 'a report to search the Items of'), signal)),\n };\n this.#items.retry(field);\n const popup = itemFilterPanel(this.#root.ownerDocument,\n { layout: report, field, caption: this.#captionOf(field), place: 'toolbar-start', locale: this.#locale, words: this.#words }, handlers,\n this.#chrome?.itemFilter);\n this.#closeOnLeaving(popup.element);\n const surface: OpenSurface = { kind: 'band', field, against: report, popup };\n this.#openSurface(surface);\n }\n\n // Opened, its first enabled command, or its panel's first control, takes the keyboard.\n #openSurface(open: OpenSurface): void {\n this.#takeDown();\n this.#open = open;\n this.#draw();\n open.popup.takeKeyboard();\n }\n\n // Closed by Escape, by its button, by the backdrop or by Cancel, the keyboard goes back to what opened it.\n // Dismissed by a press or focus elsewhere, it stays where that put it.\n #close(keyboard: 'opener' | 'stay'): void {\n const open = this.#takeDown();\n if (open === undefined) return;\n this.#draw();\n if (keyboard === 'opener') this.#returnKeyboard(open, this.#entryNow(open));\n }\n\n // Takes what is open off the page, without drawing.\n #takeDown(): OpenSurface | undefined {\n const open = this.#open;\n this.#open = undefined;\n if (open === undefined) return undefined;\n closed(open);\n this.#parts.unplace(open.popup.element);\n open.popup.element.remove();\n return open;\n }\n\n // The keyboard goes back to the button that opened the menu: Layout \u25BE, a report filter's button, or the entry `entry`\n // names, where the field the menu was for stands now; a field taken out of the Areas hands it to its tick box in\n // the list.\n #returnKeyboard(open: OpenSurface, entry: PivotEntry | undefined): void {\n if (open.kind === 'layout') this.#parts.focus('layout');\n else if (open.kind === 'band') this.#focusBand(open.field);\n else if (entry !== undefined) this.#fieldList.focusEntry(entry);\n else this.#fieldList.focusField(open.field);\n }\n\n // A report filter's button; once the field has left Filters, its tick box in the Field List, or the toggle that\n // shows the list.\n #focusBand(field: string): void {\n if (this.#layoutAhead.filters.some(placement => placement.field === field)) this.#parts.focus(bandName(field));\n else if (this.#fieldListShown) this.#fieldList.focusField(field);\n else this.#parts.focus('field-list');\n }\n\n // Where the field a menu or panel in the Field List was for stands in the pane's layout now; none for what opened\n // from the Pivot Toolbar.\n #entryNow(open: OpenSurface): PivotEntry | undefined {\n return open.kind === 'entry' || open.kind === 'panel' ? entryOfField(this.#paneLayout, open.field, open.entry) : undefined;\n }\n\n\n // Closes what is open, does what its command or its OK says, and hands the keyboard back once the pivot is drawn\n // after it. The popup leaves the page once the keyboard has gone back, so the Layout menu's never passes it\n // through the page's body (ADR-0061). Pressed once what it stood in has closed, it does nothing.\n #finish(open: OpenSurface, run: () => PivotEntry | undefined): void {\n if (this.#open !== open) return;\n this.#open = undefined;\n closed(open);\n this.#returnKeyboard(open, run());\n this.#parts.unplace(open.popup.element);\n open.popup.element.remove();\n }\n\n #command(open: OpenSurface, command: Omit<PivotMenuCommand, 'invoke'>, run: () => PivotEntry | undefined): PivotMenuCommand {\n return Object.freeze({ ...command, invoke: () => { this.#finish(open, run); } });\n }\n\n // The Layout menu (ADR-0061): Excel's Design tab choices, the current one of each group marked, and one that\n // would change nothing disabled, read from the report's layout. A choice is the report's, and reaches a pending\n // layout too.\n #layoutCommands(open: OpenSurface): readonly PivotMenuCommand[] {\n const report = this.#layoutAhead;\n const words = this.#words;\n return pivotLayoutChoices.map(choice => {\n const id = layoutChoiceId(choice);\n const heading = layoutHeadings.get(choice);\n return this.#command(open, {\n id,\n label: words.word(id),\n enabled: layoutChoiceChanges(report, choice),\n checked: isLayoutChosen(report, choice),\n ...(heading === undefined ? {} : { heading: words.word(heading) }),\n }, () => {\n this.#reportEdit(now => chooseLayout(now, choice));\n return undefined;\n });\n });\n }\n\n #entryCaption(entry: PivotEntry, valueCaptions: readonly string[] | undefined): string {\n if (isValuesPseudoField(entry)) return this.#words.word('values-pseudo-field');\n if (entry.area === 'values') return elementAt(defined(valueCaptions, 'the Value Fields\\' captions'), entry.index);\n return this.#captionOf(fieldOf(this.#paneLayout, entry));\n }\n\n // A field menu's command: a change of the layout, made as the menu closes, or a panel opened in its place.\n #entryCommand(open: EntrySurface, command: EntryMenuCommand): PivotMenuCommand {\n const { does, ...shown } = command;\n if ('edit' in does) {\n return this.#command(open, shown, () => {\n const made = does.edit();\n this.#edited(made);\n return made.entry;\n });\n }\n return Object.freeze({ ...shown, invoke: () => { this.#openPanel(open, does.panel); } });\n }\n\n #openPanel(open: EntrySurface, panel: EntryPanel): void {\n if (this.#open === open) this.#openPanelAt(open, panel);\n }\n\n // A panel opened under a field's entry in the pane: from its menu, or from the report's Context Menu.\n #openPanelAt(open: AtEntry, panel: EntryPanel): void {\n const document = this.#root.ownerDocument;\n const { entry, against } = open;\n // The panel's OK and Cancel are called once it stands, and act only while it does.\n const handlers = {\n // OK's layout is the pane's next, taken against the layout the panel was opened on (spine rule 6).\n apply: (layout: PivotLayout) => {\n this.#finish(surface, () => {\n this.#edited({ layout, against, moved: undefined });\n return this.#entryNow(surface);\n });\n },\n cancel: () => { if (this.#open === surface) this.#close('opener'); },\n };\n const words = this.#words;\n const fields = this.#options.source.fields;\n const captions = pivotValueCaptions(against, fields, { locale: this.#locale, ...(words.label === undefined ? {} : { label: words.label }) });\n let popup: PivotPanel;\n switch (panel) {\n case 'filter-items': {\n const field = fieldOf(against, entry);\n // Opened again on Items that could not be listed, it asks for them again.\n this.#items.retry(field);\n popup = itemFilterPanel(document, { layout: against, field, caption: this.#captionOf(field), place: 'field-list', locale: this.#locale, words }, {\n ...handlers,\n items: () => this.#itemsOf(field),\n // Asked from the panel's draw, it says a problem in a later turn, never in the middle of that draw.\n search: (search, signal) => Promise.resolve().then(() => searchItems(field, search, defined(this.#itemsUnder(field), 'a report to search the Items of'), signal)),\n }, this.#chrome?.itemFilter);\n break;\n }\n case 'field-settings':\n popup = fieldSettingsPanel(document, {\n layout: against,\n placement: elementAt(placementsIn(against, entry.area), entry.index),\n caption: this.#entryCaption(entry, captions),\n valueCaptions: captions,\n words,\n }, handlers, this.#chrome?.fieldSettings);\n break;\n case 'value-field-settings':\n popup = valueFieldSettingsPanel(document, {\n layout: against,\n index: entry.index,\n fieldCaption: this.#captionOf(fieldOf(against, entry)),\n caption: elementAt(captions, entry.index),\n fields,\n features: this.#options.source.features,\n locale: this.#locale,\n words,\n }, handlers, this.#chrome?.valueFieldSettings);\n break;\n default:\n unreachable(panel);\n }\n const surface: EntrySurface = { kind: 'panel', entry, field: open.field, against, popup };\n this.#openSurface(surface);\n }\n\n // Each draw draws the open menu again from the pane's layout. A field's menu or panel, or a report filter's Filter\u2026,\n // goes when the pane leaves the layout it was opened on, since its entry may now be another field's and its draft is\n // taken against that layout; one in the Field List goes too when the list is hidden. The keyboard it held goes to\n // the entry or the button its field stands at now.\n #drawMenu(valueCaptions: readonly string[] | undefined): void {\n const open = this.#open;\n const inList = open?.kind === 'entry' || open?.kind === 'panel';\n const holding = open?.kind === 'band' ? this.#layoutAhead : this.#paneLayout;\n if (open !== undefined && open.kind !== 'layout' && (open.against !== holding || (inList && !this.#fieldListShown))) {\n const held = open.popup.element.contains(this.#root.ownerDocument.activeElement);\n this.#takeDown();\n // Hidden with the Field List, the keyboard goes to the toggle that shows it again.\n if (held && (this.#fieldListShown || !inList)) this.#keyboardAfterDraw = open;\n else if (held) this.#parts.focus('field-list');\n }\n const shown = this.#open;\n this.#drawToolbar();\n if (shown?.kind === 'layout') {\n shown.popup.draw(this.#words.word('layout-menu'), this.#layoutCommands(shown));\n this.#parts.place('layout', shown.popup.element);\n }\n this.#drawBand();\n if (shown?.kind === 'band') this.#parts.place(bandName(shown.field), shown.popup.element);\n // Under what is open from the Pivot Toolbar, a press anywhere else closes it.\n if (shown?.kind === 'layout' || shown?.kind === 'band') {\n if (this.#backdrop.parentNode !== this.#root) this.#root.append(this.#backdrop);\n } else {\n this.#backdrop.remove();\n }\n if (shown?.kind === 'entry') {\n const { entry } = shown;\n const commands = entryMenuCommands({ layout: this.#paneLayout, fields: this.#options.source.fields, words: this.#words }, entry);\n shown.popup.draw(this.#words.fill('field-menu', this.#entryCaption(entry, valueCaptions)),\n commands.map(command => this.#entryCommand(shown, command)));\n }\n if (shown?.kind === 'panel' || shown?.kind === 'band') shown.popup.redraw?.();\n }\n\n // Shows a standing part's contents by `mount`; answers whether they stand. Contents that cannot be drawn leave the\n // built-in markup in their place, and are refused by name once the pivot has drawn.\n #showStanding<View, Context>(slot: StandingSlot<View, Context>, mount: PivotChromeSlot<Context>,\n context: (...made: [...Parameters<Parameters<StandingSlot<View, Context>['show']>[1]>, refs: PartRefs]) => Context): boolean {\n // Each mount hands its controls and anchors in by refs of its own.\n return this.#answered(slot.show(mount, (shared, input) => context(shared, input, this.#parts.refs()), id => this.#words.word(id)));\n }\n\n // Whether a standing part's contents stand, as `answer` says; an error it answers is the draw's to throw.\n #answered(answer: { readonly shown: boolean; readonly error?: Error }): boolean {\n if (answer.error !== undefined) this.#slotErrors.push(answer.error);\n return answer.shown;\n }\n\n // The Pivot Toolbar (ADR-0061): the built-in markup's, or a Chrome's in its place, drawn from the same view; the\n // refusal of the user's last change is the toolbar's to say. The built-in markup's controls are handed in again\n // each time it stands, as a Chrome's are when it draws them.\n #drawToolbar(): void {\n const words = this.#words;\n const view = this.#toolbarSlot.viewOf(Object.freeze({\n layoutMenu: Object.freeze({ label: words.word('layout-menu'), open: this.#open?.kind === 'layout' }),\n ...(this.#options.source.features.canRefresh ? { refresh: Object.freeze({ label: words.word('refresh') }) } : {}),\n fieldList: Object.freeze({ label: words.word('field-list-toggle'), shown: this.#fieldListShown }),\n reportFilters: this.#layoutAhead.filters.length > 0,\n ...(this.#refusal === undefined ? {} : { refusal: this.#refusal }),\n }));\n const mount = this.#chrome?.toolbar;\n // A control taken away while it holds the keyboard hands it to the Field List's toggle, so it stays in the pivot.\n const refreshHeld = view.refresh === undefined && this.#parts.holds('refresh');\n // The slot stands in the page as the contents mount, so plain script hands in controls already in it; contents\n // refused once leave the built-in toolbar standing, and the keyboard on it.\n if (mount !== undefined && !this.#toolbarSlot.refuses(mount)) swap(this.#toolbar, this.#toolbarSlot.element);\n const shown = mount !== undefined && this.#showStanding(this.#toolbarSlot, mount, (shared, input, refs) => ({\n ...shared,\n toggleLayoutMenu: input(() => { this.#toggleLayoutMenu(); }),\n refresh: input(() => { if (this.#options.source.features.canRefresh) this.#refresh(); }),\n toggleFieldList: input(() => { this.#setFieldListShown(!this.#fieldListShown); }),\n control: name => refs.control(checkedName(name, ['layout', 'refresh', 'field-list'], 'toolbar')),\n anchor: name => refs.anchor(checkedName(name, ['layout', 'report-filters'], 'toolbar')),\n }));\n if (shown) {\n this.#notice.remove();\n } else {\n this.#toolbarSlot.hide();\n swap(this.#toolbarSlot.element, this.#toolbar);\n for (const [name, control] of [['layout', this.#layoutButton], ['refresh', this.#refreshButton], ['field-list', this.#fieldListToggle]] as const) {\n this.#parts.handInControl(name, control);\n }\n this.#parts.handInAnchor('layout', this.#layoutAnchor);\n this.#parts.handInAnchor('report-filters', this.#toolbarStart);\n this.#layoutLabel.textContent = view.layoutMenu.label;\n this.#layoutButton.setAttribute('aria-expanded', view.layoutMenu.open ? 'true' : 'false');\n this.#fieldListToggle.textContent = view.fieldList.label;\n this.#fieldListToggle.setAttribute('aria-pressed', view.fieldList.shown ? 'true' : 'false');\n this.#refreshButton.textContent = words.word('refresh');\n if (view.refresh === undefined) this.#refreshButton.remove();\n else if (this.#refreshButton.parentNode === null) this.#fieldListToggle.before(this.#refreshButton);\n const refusal = view.refusal ?? ''; // oxlint-disable-line ex-grid/no-stand-in-default -- no refusal is an empty notice, which takes no room\n if (this.#notice.textContent !== refusal) this.#notice.textContent = refusal;\n this.#notice.hidden = view.refusal === undefined;\n if (this.#notice.parentNode !== this.#report) this.#toolbar.after(this.#notice);\n }\n if (refreshHeld) this.#parts.focus('field-list');\n }\n\n // The report filter band, on the Pivot Toolbar's left (ADR-0061): each field in Filters, its caption, and a button\n // that says what it shows and opens Filter\u2026 under it, over the report. It stands while Filters holds a field, in\n // the toolbar's anchor for it; the built-in markup's or a Chrome's, drawn from the same view.\n #drawBand(): void {\n const words = this.#words;\n const open = this.#open;\n const view = this.#bandSlot.viewOf(Object.freeze({\n name: words.word('report-filters'),\n filters: Object.freeze(this.#layoutAhead.filters.map(placement => {\n const caption = this.#captionOf(placement.field);\n return Object.freeze({\n field: placement.field,\n caption,\n summary: this.#bandSummary(placement),\n filtered: placement.hiddenItems.length > 0,\n open: open?.kind === 'band' && open.field === placement.field,\n buttonLabel: words.fill('filter-of', caption),\n });\n })),\n }));\n const mount = this.#chrome?.reportFilters;\n const shown = mount !== undefined && this.#showStanding(this.#bandSlot, mount, (shared, input, refs) => ({\n ...shared,\n toggle: input((field: string) => { if (this.#layoutAhead.filters.some(placement => placement.field === field)) this.#toggleBand(field); }),\n control: field => refs.control(bandName(checkedField(field))),\n anchor: field => refs.anchor(bandName(checkedField(field))),\n }));\n const band = shown ? this.#bandSlot.element : this.#band;\n if (shown) {\n this.#band.remove();\n for (const field of this.#bandFilters.keys()) this.#forgetBandFilter(field);\n this.#bandSlot.element.setAttribute('aria-label', view.name);\n } else {\n this.#bandSlot.hide();\n this.#bandSlot.element.remove();\n this.#drawBuiltInBand(view);\n }\n if (view.filters.length === 0) {\n band.remove();\n this.#parts.place('report-filters', undefined);\n } else {\n this.#parts.place('report-filters', band);\n }\n }\n\n #drawBuiltInBand(view: PivotReportFiltersView): void {\n const document = this.#root.ownerDocument;\n const drawn: HTMLElement[] = [];\n const kept = new Set<string>();\n for (const shown of view.filters) {\n const { field } = shown;\n let band = this.#bandFilters.get(field);\n if (band === undefined) {\n band = this.#bandFilter(document, field);\n this.#bandFilters.set(field, band);\n }\n this.#parts.handInControl(bandName(field), band.button);\n this.#parts.handInAnchor(bandName(field), band.anchor);\n kept.add(field);\n if (band.caption.textContent !== shown.caption) band.caption.textContent = shown.caption;\n if (band.summary.textContent !== shown.summary) band.summary.textContent = shown.summary;\n band.button.classList.toggle('ex-pivot-filter-active', shown.filtered);\n band.button.setAttribute('aria-expanded', shown.open ? 'true' : 'false');\n band.button.setAttribute('aria-label', shown.buttonLabel);\n drawn.push(band.filter);\n }\n for (const field of this.#bandFilters.keys()) {\n if (!kept.has(field)) this.#forgetBandFilter(field);\n }\n this.#band.setAttribute('aria-label', view.name);\n const children = this.#band.children;\n if (drawn.length !== children.length || drawn.some((filter, i) => children[i] !== filter)) this.#band.replaceChildren(...drawn);\n }\n\n // A built-in report filter that no longer stands: its elements are dropped, and taken back from the parts.\n #forgetBandFilter(field: string): void {\n const band = this.#bandFilters.get(field);\n if (band === undefined) return;\n this.#bandFilters.delete(field);\n this.#parts.forget(bandName(field), band.button);\n this.#parts.forget(bandName(field), band.anchor);\n }\n\n #bandFilter(document: Document, field: string): BandFilter {\n const filter = element(document, 'div', 'ex-pivot-filter');\n const caption = element(document, 'span', 'ex-pivot-filter-caption');\n const anchor = element(document, 'span', 'ex-pivot-filter-anchor');\n const button = element(document, 'button', 'ex-pivot-filter-button');\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.setAttribute('aria-haspopup', 'dialog');\n const summary = element(document, 'span', 'ex-pivot-filter-summary');\n const arrow = element(document, 'span', 'ex-pivot-entry-arrow');\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n button.append(summary, arrow);\n button.addEventListener('click', () => { this.#toggleBand(field); });\n anchor.append(button);\n filter.append(caption, anchor);\n return { filter, caption, anchor, button, summary };\n }\n\n // What a report filter shows, as Excel shows a page field: (All) while it hides nothing, the one Item shown, or\n // (Multiple Items), read from the field's Items, asked of the source; Loading\u2026 until a first listing lands, rather\n // than a guess, and why when they cannot be listed. While a new Source Version's Items are on their way, it is read\n // from the Items in view, the earlier version's (ADR-0066 refined).\n #bandSummary(placement: PivotFieldPlacement): string {\n const words = this.#words;\n if (placement.hiddenItems.length === 0) return words.word('all');\n const items = this.#itemsOf(placement.field);\n if (items.problem !== undefined) return itemsProblemText(items.problem, words);\n const page = items.listed;\n if (page === undefined) return words.word('loading');\n if (page.total > page.items.length) {\n // More Items than are held: provably several shown, or not known.\n return page.total - placement.hiddenItems.length > 1 ? words.word('multiple-items') : words.word('loading');\n }\n // One Item shown is named; past one, how many does not matter.\n const hidden = new Set(placement.hiddenItems.map(key => pivotItemKeyId(key)));\n let shown: PivotItemInfo | undefined;\n for (const item of page.items) {\n if (hidden.has(pivotItemKeyId(item.key))) continue;\n if (shown !== undefined) return words.word('multiple-items');\n shown = item;\n }\n // None shown (data that no longer holds the one Item shown) is said as the Razor component says it.\n return shown === undefined ? words.word('multiple-items') : shown.label;\n }\n\n // What a field's Items are listed under: the report on screen, and the field's order in it. None while no report\n // is shown.\n #itemsUnder(field: string): ItemsUnder | undefined {\n const { answer, question, layout } = this.#shown;\n if (answer === undefined || question === undefined) return undefined;\n const at = placementOf(layout, field);\n return Object.freeze({\n reportSource: question.reportSource,\n version: answer.metadata.version,\n sourceVersion: answer.metadata.sourceVersion,\n settings: question.settings,\n sort: at === undefined ? undefined : elementAt(placementsIn(layout, at.area), at.index).sort,\n });\n }\n\n // A field's Items as they stand for the report on screen; on their way while the first report is.\n #itemsOf(field: string): FieldItems {\n const under = this.#itemsUnder(field);\n return under === undefined ? pendingFirst : this.#items.of(field, under);\n }\n\n // ---- Drawing ---------------------------------------------------------------------------------------\n\n #setFieldListShown(shown: boolean): void {\n if (shown === this.#fieldListShown) return;\n this.#fieldListShown = shown;\n this.#draw();\n this.#options.onShowFieldListChanged?.(Object.freeze({ shown }));\n }\n\n #paintDropRemove(removable: boolean): void {\n // A drag takes the pane: a field menu open in it goes, as the Razor component's does, drawn below.\n this.#takeDown();\n this.#dropRemoveShown = removable;\n this.#draw();\n }\n\n // Whether a question is out under the loading indication: any but the quiet one a source's notice asked.\n #loading(): boolean {\n return this.#asked !== undefined && this.#asked.cause !== 'live';\n }\n\n // The Field List: a Chrome's in the pane's place while one is given and can be drawn, else the built-in pane.\n #placeFieldList(): void {\n const mount = this.#chrome?.fieldList;\n const slotted = mount !== undefined && this.#answered(this.#slottedFieldList.show(mount, id => this.#words.word(id)));\n if (!slotted) this.#slottedFieldList.hide();\n this.#fieldListSlotted = slotted;\n const pane = slotted ? this.#slottedFieldList.element : this.#builtInFieldList.element;\n if (pane.parentNode !== this.#fieldListScroll) this.#fieldListScroll.replaceChildren(pane);\n // A drag whose pane went with its contents ended with them: the report no longer offers to remove its field.\n if (!this.#fieldList.removable) this.#dropRemoveShown = false;\n }\n\n // The Stale Report's notice, and the class by which ExPivot's stylesheet mutes the report's numbers (ADR-0067). Retry\n // is not offered twice at once: while a question a person or the Consumer asked is out, it is the one Retry would\n // ask. A quiet one for the source's notice leaves Retry offered, or a ticking source would hardly ever let it be\n // pressed.\n #drawStale(words: PivotScreenWords): void {\n const stale = this.#stale !== undefined && this.#shown.answer !== undefined ? this.#stale : undefined;\n this.#report.classList.toggle('ex-pivot-report-stale', stale !== undefined);\n // Retry taken away or disabled while it holds the keyboard hands it to the Field List toggle, so the keyboard stays\n // in the pivot, on a button whose press asks nothing of the source.\n const held = this.#parts.holds('retry');\n const handOn = (): void => { if (held) this.#parts.focus('field-list'); };\n const mount = this.#chrome?.staleReport;\n if (stale === undefined) {\n this.#staleNotice.remove();\n this.#staleSlot.hide();\n this.#staleSlot.element.remove();\n handOn();\n return;\n }\n const asOf = this.#asOf();\n const view = this.#staleSlot.viewOf(Object.freeze({\n message: words.fill('stale-report', asOf, stale),\n asOfText: asOf,\n reason: stale,\n retry: Object.freeze({ label: words.word('retry'), enabled: !this.#loading() }),\n }));\n if (mount !== undefined && this.#staleSlot.element.parentNode !== this.#staleRegion) this.#staleRegion.append(this.#staleSlot.element);\n const shown = mount !== undefined && this.#showStanding(this.#staleSlot, mount, (shared, input, refs) => ({\n ...shared,\n // Asked only while Retry is offered: one pressed while what it would ask is out asks nothing twice.\n retry: input(() => { if (shared.view().retry.enabled) this.#retry(); }),\n control: name => refs.control(checkedName(name, ['retry'], 'staleReport')),\n }));\n if (shown) {\n this.#staleNotice.remove();\n } else {\n this.#staleSlot.hide();\n this.#staleSlot.element.remove();\n this.#parts.handInControl('retry', this.#retryButton);\n if (this.#staleMessage.textContent !== view.message) this.#staleMessage.textContent = view.message;\n if (this.#retryButton.textContent !== view.retry.label) this.#retryButton.textContent = view.retry.label;\n this.#retryButton.disabled = !view.retry.enabled;\n if (this.#staleNotice.parentNode !== this.#staleRegion) this.#staleRegion.append(this.#staleNotice);\n }\n if (!view.retry.enabled) handOn();\n }\n\n #draw(): void {\n if (this.#destroyed) return;\n this.#holdWhileLoading();\n const words = this.#words;\n const layout = this.#paneLayout;\n const fields = this.#options.source.fields;\n // The Value Fields' captions, which the Field List and a Values entry's menu say.\n const valueCaptions = this.#fieldListShown\n ? pivotValueCaptions(layout, fields, { locale: this.#locale, ...(words.label === undefined ? {} : { label: words.label }) })\n : undefined;\n this.#placeFieldList();\n this.#drawMenu(valueCaptions);\n const stretch = this.#options.viewportHeight === 'stretch';\n const width = this.#options.fieldListWidth ?? 300; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0061: the Field List's declared default width, as the Razor component's\n // The Geometry Tokens, inline on the root (ADR-0027): the Field List's width and a level's indent.\n writeStyle(this.#root, `--ex-pivot-field-list-width: ${width}px; --ex-pivot-indent: ${this.#indentPx}px${stretch ? '; height: 100%; flex: 1 1 auto; min-height: 0' : ''}`);\n // A question for the newer data the source told of is asked quietly, so a live report is not busy every interval.\n if (this.#loading()) this.#root.setAttribute('aria-busy', 'true');\n else this.#root.removeAttribute('aria-busy');\n this.#drawStale(words);\n writeStyle(this.#sheet, stretch ? 'display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0' : '');\n const answered = this.#reportDrawn;\n // The report or the box that says why there is none, and over the report, while a placed field is\n // dragged, the mark that a drop there removes it (ADR-0061). Elements come and go rather than hide, since\n // the stylesheet gives the box a display of its own.\n // While a details tab is selected its records cover the report, which stays laid out, with its state, and is\n // not painted: its own header would otherwise paint over the records', and a report nobody sees takes no\n // keyboard and is not read out (ADR-0059). Records covering it take no drop meant for it.\n const details = this.#details;\n const panel = details.panel;\n this.#sheet.className = panel === undefined ? 'ex-pivot-sheet' : 'ex-pivot-sheet ex-pivot-sheet-covered';\n const dropRemove = answered && this.#dropRemoveShown && panel === undefined && !details.dialogShown;\n elementAt([...this.#dropRemove.children], 0).textContent = words.word('remove-field');\n const shownInSheet = [answered ? this.#gridRoot : this.#empty, ...(dropRemove ? [this.#dropRemove] : []), ...(panel === undefined ? [] : [panel])];\n if (shownInSheet.length !== this.#sheet.children.length || shownInSheet.some((child, i) => this.#sheet.children[i] !== child)) {\n this.#sheet.replaceChildren(...shownInSheet);\n }\n // The tabs stand at the report's foot, where Excel's sheet tabs are, while a details tab stands.\n if (!details.tabsShown) details.tabList.remove();\n else if (details.tabList.parentNode !== this.#report) this.#report.append(details.tabList);\n // While the dialog stands, what it covers takes neither the keyboard nor the pointer: it is modal (ADR-0059).\n this.#report.inert = details.dialogShown;\n this.#fieldListBox.inert = details.dialogShown;\n for (const shown of details.dialogElements) {\n if (shown.parentNode !== this.#root) this.#root.append(shown);\n }\n if (!answered) {\n this.#empty.textContent = words.word(this.#asked !== undefined && !showsNothing(this.#layoutAhead) ? 'loading' : 'empty-report');\n const height = this.#options.viewportHeight ?? 400; // oxlint-disable-line ex-grid/no-stand-in-default -- ADR-0028: the report's declared default height, as the Razor component's\n writeStyle(this.#empty, height === 'stretch' ? 'flex: 1 1 auto; min-height: 0' : `height: ${height}px`);\n }\n this.#fieldListBox.hidden = !this.#fieldListShown;\n this.#fieldListBox.setAttribute('aria-label', words.word('field-list'));\n if (valueCaptions !== undefined) {\n this.#fieldList.draw({\n layout,\n fields,\n valueCaptions,\n counts: this.#counts,\n maxLeaves: this.#maxLeaves,\n locale: this.#locale,\n words,\n deferred: this.#deferred !== undefined,\n canUpdate: this.#deferred !== undefined && this.#pendingApplies(this.#deferred.layout),\n popup: this.#open?.kind === 'entry' || this.#open?.kind === 'panel' ? { entry: this.#open.entry, frame: this.#open.popup.element } : undefined,\n });\n }\n const left = this.#keyboardAfterDraw;\n this.#keyboardAfterDraw = undefined;\n if (left !== undefined) this.#returnKeyboard(left, this.#entryNow(left));\n this.#throwRefused();\n }\n\n // Throws the first of the slots' contents that could not be drawn: to the Consumer, where it makes or updates the\n // pivot or opens records; otherwise on its own, as a listener's error is, so the source, the user's input or the\n // timer that drew goes on.\n #throwRefused(): void {\n const [refused] = this.#slotErrors;\n this.#slotErrors = [];\n if (refused === undefined) return;\n if (this.#consumerDraws) throw refused;\n queueMicrotask(() => { throw refused; });\n }\n}\n\n/** Defer Layout Update ticked: the layout the pane shows and builds, and the moves into it the report does not hold. */\ninterface Deferred {\n readonly layout: PivotLayout;\n readonly moves: readonly FieldListMove[];\n}\n\n// The moves a refused question's layout still holds: a field moved and then taken out again is not in it. A field may\n// stand in Values as well as in an axis, so a move is known by its field and its Area.\nfunction heldMoves(question: Question): readonly FieldListMove[] {\n return question.moves.filter((move, i, all) => all.findLastIndex(later => later.field === move.field && later.area === move.area) === i\n && holdsMove(question.layout, move));\n}\n\n// The fields a refusal names: those of the moves its layout still holds, each once.\nfunction heldFields(held: readonly FieldListMove[]): readonly string[] {\n return [...new Set(held.map(move => move.field))];\n}\n\n// How long a Change Highlight lasts under a pivot's options (ADR-0068).\nfunction highlightMsOf(options: PivotViewOptions): number {\n return options.changeHighlightDuration ?? defaultChangeHighlightMs;\n}\n\n// The caps a pivot's options set, each as it applies, so a cap given as its default asks nothing again.\nfunction capsOf(options: PivotViewOptions): string {\n return `${options.maxLeaves ?? defaultMaxLeaves} ${options.maxRows ?? excelRows} ${options.maxColumns ?? excelColumns}`;\n}\n\n// The cap a report breaks, or none (ADR-0066): its rows, or its columns with the label columns, past the question's \u2014\n// with the word that refuses a layout for it and the word that says newer data broke it.\nfunction capBrokenBy(metadata: PivotReportState['metadata'], question: Question): { readonly refusal: string; readonly stale: string; readonly cap: number } | undefined {\n if (metadata.rowCount > question.maxRows) return { refusal: 'refused-too-many-rows', stale: 'stale-too-many-rows', cap: question.maxRows };\n if (metadata.labelColumns.length + metadata.valueColumns.length > question.maxColumns) {\n return { refusal: 'refused-too-many-columns', stale: 'stale-too-many-columns', cap: question.maxColumns };\n }\n return undefined;\n}\n\n// Whether `layout` holds the field a move put in its Area.\nfunction holdsMove(layout: PivotLayout, move: FieldListMove): boolean {\n return move.area === 'values' ? layout.values.some(value => value.field === move.field) : placementOf(layout, move.field)?.area === move.area;\n}\n\n// Whether every field `layout` places is one of `declared`.\nfunction placesOnly(layout: PivotLayout, declared: ReadonlyMap<string, unknown>): boolean {\n return [...layout.filters, ...layout.rows, ...layout.columns, ...layout.values].every(placed => declared.has(placed.field));\n}\n\n// .NET's Math.Round, which sends a tie to the even number (CONVENTIONS.md).\nfunction roundHalfToEven(value: number): number {\n const floor = Math.floor(value);\n const diff = value - floor;\n if (diff < 0.5) return floor;\n if (diff > 0.5) return floor + 1;\n return floor % 2 === 0 ? floor : floor + 1;\n}\n\n// The name a report filter's button and the anchor around it are handed in by.\nfunction bandName(field: string): string {\n return `filter:${field}`;\n}\n\n// A report filter's field, as a script may hand it to the band's `control` or `anchor`: the field's name.\nfunction checkedField(field: string): string {\n const given: unknown = field;\n if (typeof given !== 'string') throw new TypeError('An ExPivot\\'s report filter band hands in a filter\\'s button and anchor by the field\\'s name (ADR-0390).');\n return given;\n}\n", "// Show Details (ADR-0059, ADR-0063): the records behind a value cell, asked of the report source the report came\n// from under its Source Version, so they add up to the cell. The Consumer takes them when it listens; otherwise they\n// open as a sheet, in a tab at the report's foot or in a dialog: an ExGrid of the source's fields, fetched in pages,\n// in the markup and under the classes the Razor component's PivotDetailsSheet and PivotDetailsGrid draw (ADR-0350\n// section 4).\n\nimport { FetchingGridSource, type ColumnType, type GridColumn, type GridPage, type GridQuery } from '@ex-grid/core';\nimport { decimalText } from '@ex-grid/data';\nimport {\n formatPivotDetailValue, pivotDetailsQuery, type PivotDetailPage, type PivotDetailRecord, type PivotDetailValue, type PivotDetailsQuery, type PivotField,\n type PivotSource, type PivotSourceRefusal,\n} from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** One Item of a cell's path: its field's caption and its label, as the report shows them. */\nexport interface PivotDetailItem {\n /** The caption of the Item's field. */\n readonly field: string;\n /** The Item's label. */\n readonly item: string;\n}\n\n/** The records behind a value cell, which Show Details opens (ADR-0059): handed to `onShowDetails` when the Consumer\n * listens, and otherwise shown by the pivot. */\nexport interface PivotShowDetailsEvent {\n /** What the cell stands for, as its sheet is titled: `Details: EU / Rates`. */\n readonly title: string;\n /** The Items of the cell's row, outermost first. */\n readonly rowItems: readonly PivotDetailItem[];\n /** The Items of the cell's column, outermost first. */\n readonly columnItems: readonly PivotDetailItem[];\n /** The caption of the cell's Value Field, or `undefined` where the cell is not one Value Field's. */\n readonly valueField: string | undefined;\n /** The question for the records, plain data a Consumer may send elsewhere, as the Razor component's\n * `PivotDetails.Query` (ADR-0151): the cell's Items, the Hidden Items and the Source Version it is answered under. */\n readonly query: PivotDetailsQuery;\n /** The Pivot Source the report was computed from, which the records are asked of. */\n readonly source: PivotSource;\n /** The source's fields, which each record holds a value of, in order. */\n readonly fields: readonly PivotField[];\n /** A page of the records, from `start`, at most `count` of them, under the Source Version the report was computed\n * from: a source that no longer holds it refuses, rather than answer records that do not add up. */\n readonly records: (start: number, count: number, signal?: AbortSignal) => Promise<PivotDetailPage>;\n}\n\n/** Where the pivot shows the records when the Consumer does not take them: a tab at the report's foot, or a dialog. */\nexport type PivotDetailsView = 'tab' | 'dialog';\n\n/** The records behind `query`'s cell, asked of the Pivot Source the report was computed from, which stays the\n * Consumer's however long the records are shown. */\nexport function detailsEvent(\n source: PivotSource, query: PivotDetailsQuery, described: Omit<PivotShowDetailsEvent, 'source' | 'query' | 'fields' | 'records'>,\n): PivotShowDetailsEvent {\n return Object.freeze({\n ...described,\n source,\n query,\n fields: source.fields,\n // Checked as the question is: a page from a negative or broken start is refused by name, never asked.\n records: (start: number, count: number, signal?: AbortSignal) => source.details(pivotDetailsQuery({ ...query, start, count }), signal),\n });\n}\n\n/** A record's value as the details grid holds it: the text it shows, and its own text, which the grid copies. */\nexport class DetailCellValue {\n readonly #value: PivotDetailValue;\n /** The text the cell shows. */\n readonly text: string;\n\n constructor(value: PivotDetailValue, text: string) {\n this.#value = value;\n this.text = text;\n }\n\n /** What the cell is painted and aligned as: a value not of its field's declared type keeps its own (ADR-0060). */\n get type(): ColumnType {\n const value = this.#value;\n if (typeof value === 'string') return 'text';\n if (typeof value === 'boolean') return 'boolean';\n if (typeof value === 'bigint') return 'date';\n return 'number';\n }\n\n /** The raw text the clipboard carries: an exact number's digits, a double's shortest text, and otherwise what\n * the cell shows (ADR-0005). */\n toString(): string {\n const value = this.#value;\n if (typeof value === 'number' && Number.isFinite(value)) return String(value);\n if (typeof value === 'object' && value !== null) return decimalText(value);\n return this.text;\n }\n}\n\n/** Why the records cannot be shown: the source refused (the data changed under the report's Source Version, for\n * one), or it failed. */\nexport type DetailsProblem = { readonly refusal: PivotSourceRefusal } | { readonly error: unknown };\n\n/** The sentence that says why the records cannot be shown. */\nexport function detailsProblemText(problem: DetailsProblem, words: PivotScreenWords): string {\n return 'error' in problem ? words.failed(problem.error) : words.sourceRefused(problem.refusal);\n}\n\nclass RefusedError extends Error {\n readonly refusal: PivotSourceRefusal;\n\n constructor(refusal: PivotSourceRefusal) {\n super(refusal.message);\n this.refusal = refusal;\n }\n}\n\nfunction columnTypeOf(field: PivotField): ColumnType {\n switch (field.type) {\n case 'number': return 'number';\n case 'date': return 'date';\n case 'boolean': return 'boolean';\n case 'text': return 'text';\n default: return unreachable(field.type);\n }\n}\n\nfunction cellOf(value: unknown): DetailCellValue | undefined {\n if (value === undefined) return undefined;\n if (!(value instanceof DetailCellValue)) throw new TypeError('Internal: a details cell holds a record\\'s value.');\n return value;\n}\n\n/** What a details cell is painted and aligned as: its value's own type, or its column's for a Blank. */\nexport function detailCellType(row: PivotDetailRecord, column: GridColumn<PivotDetailRecord>): ColumnType {\n // A Blank is painted as its column's type, as the Razor component's CellTypeOf does.\n return cellOf(column.value(row))?.type ?? column.type;\n}\n\n/**\n * One Show Details the pivot opened: the cell's records as a Grid Source of pages fetched from the report source,\n * under the Source Version the report was computed from, and one column per field of the source, headed by its\n * caption. It keeps that version for as long as it stands; a source that can no longer answer under it refuses, and\n * the sheet says the data has changed rather than show records that do not add up. It owns its source and releases\n * it when it closes.\n */\nexport class DetailsSheet {\n /** Unique in its pivot: its tab's id, and its panel's with `-panel`. */\n readonly id: string;\n readonly details: PivotShowDetailsEvent;\n /** The locale its records are written in: the pivot's when it opened, as its title's words are. */\n readonly locale: string;\n readonly columns: readonly GridColumn<PivotDetailRecord>[];\n readonly source: FetchingGridSource<PivotDetailRecord>;\n /** Why the records cannot be shown, or `undefined` while they can. */\n problem: DetailsProblem | undefined;\n readonly #closed = new AbortController();\n\n /** `changed` is called when the records can no longer be shown. */\n constructor(id: string, details: PivotShowDetailsEvent, locale: string, changed: () => void) {\n this.id = id;\n this.details = details;\n this.locale = locale;\n this.columns = Object.freeze(details.fields.map((field, index) => {\n const values = new WeakMap<PivotDetailRecord, DetailCellValue | undefined>();\n return Object.freeze({\n name: field.name,\n header: field.caption,\n type: columnTypeOf(field),\n queryable: false,\n value: (record: PivotDetailRecord) => {\n if (values.has(record)) return values.get(record);\n const value = record.values[index];\n const cell = value === undefined || value === null ? undefined : new DetailCellValue(value, formatPivotDetailValue(value, field.format, locale));\n values.set(record, cell);\n return cell;\n },\n format: (value: unknown) => cellOf(value)?.text ?? '', // oxlint-disable-line ex-grid/no-stand-in-default -- a Blank shows nothing\n });\n }));\n this.source = FetchingGridSource.fetch((query, signal) => this.#fetch(query, signal), {\n onFetchFailed: ({ error }) => {\n if (this.#closed.signal.aborted) return;\n this.problem = error instanceof RefusedError ? Object.freeze({ refusal: error.refusal }) : Object.freeze({ error });\n changed();\n },\n });\n }\n\n async #fetch(query: GridQuery, signal: AbortSignal): Promise<GridPage<PivotDetailRecord>> {\n // The records behind a cell are in the data's order, and none is left out: the details grid offers no sort\n // and no filter, and a question carrying one is not answered quietly in another order (ADR-0059).\n if (query.sorts.length > 0 || query.filter !== undefined) throw new Error('The records behind a cell are shown in the data\\'s order, unfiltered (ADR-0059).');\n const page = await this.details.records(query.range.start, query.range.count, signal);\n if (page.refusal !== undefined) throw new RefusedError(page.refusal);\n return Object.freeze({ rows: page.records, start: page.start, totalCount: page.total });\n }\n\n /** Releases its source: the sheet has closed. */\n dispose(): void {\n this.#closed.abort();\n this.source.dispose();\n }\n}\n", "// The Snapshot's Decimal (ADR-0064): C#'s decimal, a whole number of at most 96 bits and 0 to 28 decimal\n// places, held as its value and not as the places it was written with, so 1.5 and 1.50 are one value. The\n// shape is the Script Core's ExactDecimal's, so a value passes between the two packages as it is.\n\n/** A Decimal value, `mantissa` \u00D7 10^-`scale`: a whole number below 2^96 in magnitude, and 0 to 28 places.\n * A value a Snapshot hands out is canonical: no trailing zero after the point, and 0 is `0n` at scale 0. */\nexport interface SnapshotDecimal {\n /** The digits, as a whole number. */\n readonly mantissa: bigint;\n /** How many of them stand after the point, 0 to 28. */\n readonly scale: number;\n}\n\n/** The magnitude a Decimal's digits stay below: 2^96. */\nexport const decimalLimit = 1n << 96n;\n\n/** The most places a Decimal holds. */\nexport const maxDecimalScale = 28;\n\n/** The canonical Decimal \u00B1 `magnitude` \u00D7 10^-`scale` is, its trailing zeros taken off, frozen. The caller\n * has checked it is a Decimal. */\nexport function canonicalDecimal(mantissa: bigint, scale: number): SnapshotDecimal {\n let digits = mantissa;\n let places = scale;\n while (places > 0 && digits % 10n === 0n) {\n digits /= 10n;\n places -= 1;\n }\n return Object.freeze({ mantissa: digits, scale: digits === 0n ? 0 : places });\n}\n\n/** Whether `value` is a Decimal a Snapshot holds: a bigint below 2^96 in magnitude and a whole scale from\n * 0 to 28. A value of any other shape, which only an untyped caller can pass, is not one. */\nexport function isSnapshotDecimal(value: unknown): value is SnapshotDecimal {\n if (typeof value !== 'object' || value === null) return false;\n const mantissa: unknown = Reflect.get(value, 'mantissa');\n const scale: unknown = Reflect.get(value, 'scale');\n return typeof mantissa === 'bigint' && mantissa < decimalLimit && mantissa > -decimalLimit\n && typeof scale === 'number' && Number.isInteger(scale) && scale >= 0 && scale <= maxDecimalScale;\n}\n\n/**\n * The Decimal a text writes: an optional `-`, digits, and optionally a point and more digits, as\n * `\"-1234.5678\"`. Refused with a `TypeError` when the text is not one, and with a `RangeError` when no\n * Decimal holds it exactly: more than 28 places that are not trailing zeros, or digits past 2^96.\n */\nexport function decimalFromText(text: string): SnapshotDecimal {\n const match = /^(-?)(\\d+)(?:\\.(\\d+))?$/.exec(text);\n if (match === null) throw new TypeError(`'${text}' is not a decimal: a decimal is written as -1234.5678.`);\n // The point and the places after it are optional: a whole number has none.\n const [, sign = '', whole = '', fraction = ''] = match;\n const places = fraction.replace(/0+$/, '');\n if (places.length > maxDecimalScale) throw new RangeError(`'${text}' has more decimal places than the 28 a decimal holds.`);\n const magnitude = BigInt(whole + places);\n if (magnitude >= decimalLimit) throw new RangeError(`'${text}' lies beyond the range of a decimal.`);\n return canonicalDecimal(sign === '-' ? -magnitude : magnitude, places.length);\n}\n\n/** A Decimal's text, canonical: `-0.0001`, `1.5`, `79228162514264337593543950335`. */\nexport function decimalText(value: SnapshotDecimal): string {\n return unscaledText(value.mantissa.toString(), value.scale);\n}\n\n/** An unscaled whole number's digits with the point put in at `places`, which may be negative, as a\n * refusal shows a value read at its Arrow scale (`0.000\u2026015`, `999\u2026000`). */\nexport function unscaledText(unscaled: string, places: number): string {\n const negative = unscaled.startsWith('-');\n let digits = negative ? unscaled.slice(1) : unscaled;\n if (places > 0) {\n digits = digits.padStart(places + 1, '0');\n digits = `${digits.slice(0, -places)}.${digits.slice(-places)}`;\n } else if (places < 0) {\n digits += '0'.repeat(-places);\n }\n return negative ? `-${digits}` : digits;\n}\n", "// What the pivot's Script Core knows is there, as core/src/must.ts says it for ExGrid's: a miss is a defect,\n// said by throwing where a `!` would read on with `undefined` (CONVENTIONS.md, \"No quiet fallback\"). The\n// packages share no code, so each carries its own.\n\n/** The element at `index`, which the caller knows is there. A miss throws: it is a defect, never an answer. */\nexport function elementAt<T extends object | string | number | boolean | bigint | null>(list: readonly T[], index: number): T {\n const value = list[index];\n if (value === undefined) {\n throw new Error(`Internal: index ${index} is outside a list of ${list.length}.`);\n }\n return value;\n}\n\n/** The value, which the caller knows is there. `undefined` throws, naming what was missing. */\nexport function defined<T>(value: T | undefined, what: string): T {\n if (value === undefined) {\n throw new Error(`Internal: ${what} is missing.`);\n }\n return value;\n}\n\n/** The end of a switch that has taken every member of a union; a value from outside it throws here. */\nexport function unreachable(value: never): never {\n throw new Error(`Internal: ${String(value)} is not a value this switch takes.`);\n}\n", "// The controls and the anchors of the pivot's standing parts (ADR-0061, ADR-0390): the Pivot Toolbar's buttons, a\n// report filter's, Retry. The built-in markup and a Chrome's contents hand them in alike, each by its name, so the\n// pivot gives the keyboard to the control it means and places a popup's frame in the anchor it belongs in, the same\n// way whichever drew them. A part's contents are drawn by their framework when it gets to them: a control asked for\n// before it is handed in takes the keyboard once it is, unless the keyboard has moved on meanwhile.\n\nimport type { PivotPartRef } from './chrome';\n\n/** Whether DOM focus is inside `pivot`, or on nothing: the keyboard is still the pivot's (ADR-0204). */\nexport function keyboardIsThePivots(pivot: Element): boolean {\n const document = pivot.ownerDocument;\n const active = document.activeElement;\n return active === null || active === document.body || active === document.documentElement || pivot.contains(active);\n}\n\n/** The elements the pivot's standing parts handed in, by name. */\nexport class PartElements {\n readonly #root: HTMLElement;\n readonly #controls = new Map<string, HTMLElement>();\n readonly #anchors = new Map<string, HTMLElement>();\n // What each anchor is to hold: a popup's frame, or the report filter band, placed once the anchor is handed in.\n readonly #placed = new Map<string, HTMLElement>();\n // What hears an element placed land in its anchor, the first time it does.\n readonly #landing = new Map<HTMLElement, () => void>();\n // The control the keyboard is owed to, given once it is handed in; any focus moving or press meanwhile ends it,\n // since a press on nothing focusable moves the keyboard to the page without a focus event. A key does not: one\n // that moves the keyboard moves focus, and one typed while the control is on its way is held in the pivot's Input\n // Order on an adapter that holds (ADR-0410 section 5), to be taken where the control stands once it does.\n // The document is heard only while something is owed, and its listeners answer only that (ADR-0350 section 6's\n // note of 2026-11-01): a pivot owing nothing listens to nothing outside itself.\n #owed: string | undefined;\n #listening: AbortController | undefined;\n\n constructor(root: HTMLElement) {\n this.#root = root;\n }\n\n /** The pivot is gone: nothing is heard, and nothing owed is given. */\n dispose(): void {\n this.#settle();\n }\n\n // The keyboard is owed to `name` until it is given, or focus moves or a press lands anywhere meanwhile.\n #owe(name: string): void {\n this.#owed = name;\n if (this.#listening !== undefined) return;\n this.#listening = new AbortController();\n const settled = (): void => { this.#settle(); };\n for (const type of ['focusin', 'pointerdown']) {\n this.#root.ownerDocument.addEventListener(type, settled, { capture: true, signal: this.#listening.signal });\n }\n }\n\n // Nothing is owed any longer, and the document is no longer heard.\n #settle(): void {\n this.#owed = undefined;\n this.#listening?.abort();\n this.#listening = undefined;\n }\n\n /** The refs by which one mount of a Chrome's contents hands in its controls and anchors: the same function for a\n * name each time it is asked, and each taking back only what it handed in, so contents taken away late take nothing\n * the contents after them handed in under the same name. */\n refs(): PartRefs {\n const controls = new Map<string, PivotPartRef>();\n const anchors = new Map<string, PivotPartRef>();\n return {\n control: name => cachedRef(controls, name, () => elementRef(this.#controls, name, `An ExPivot part's '${name}'`, element => { this.#giveOwed(name, element); })),\n anchor: name => cachedRef(anchors, name, () => elementRef(this.#anchors, name, `An ExPivot part's '${name}'`, element => { this.#fill(name, element); })),\n };\n }\n\n /** The built-in markup's control named `name`, handed in as it stands: no Chrome's ref is involved, so a Chrome's\n * contents taken away later take nothing of it. */\n handInControl(name: string, element: HTMLElement): void {\n this.#controls.set(name, element);\n this.#giveOwed(name, element);\n }\n\n /** The built-in markup's anchor named `name`, handed in as it stands. */\n handInAnchor(name: string, element: HTMLElement): void {\n this.#anchors.set(name, element);\n this.#fill(name, element);\n }\n\n /** Takes back what was handed in as `name`, where it is still `element`: built-in markup that no longer stands. */\n forget(name: string, element: HTMLElement): void {\n if (this.#controls.get(name) === element) this.#controls.delete(name);\n if (this.#anchors.get(name) === element) this.#anchors.delete(name);\n }\n\n /** The anchor named `name` went with what held it: nothing is placed in it any longer, though its framework lets\n * go of it only later. */\n dropAnchor(name: string): void {\n this.#anchors.delete(name);\n }\n\n /** Whether an anchor named `name` stands: a popup opens only in one that does. */\n anchored(name: string): boolean {\n return this.#anchors.get(name)?.isConnected === true;\n }\n\n /** Whether the control named `name` is `node` or holds it. */\n controlContains(name: string, node: Node): boolean {\n return this.#controls.get(name)?.contains(node) === true;\n }\n\n /** Whether the control named `name` holds the keyboard. */\n holds(name: string): boolean {\n const control = this.#controls.get(name);\n const active = this.#root.ownerDocument.activeElement;\n return control !== undefined && active !== null && control.contains(active);\n }\n\n /** Gives the keyboard to the control named `name`; one not drawn yet takes it once it is, while the keyboard is\n * still the pivot's and nothing else took it meanwhile. */\n focus(name: string): void {\n const control = this.#controls.get(name);\n if (control?.isConnected === true) {\n this.#settle();\n control.focus();\n } else {\n this.#owe(name);\n }\n }\n\n /** Places `element` in the anchor named `name`, now or once it is handed in; `undefined` places nothing there any\n * longer, as the pivot takes what it placed away itself. `landed` hears the first time `element` stands in an\n * anchor. */\n place(name: string, element: HTMLElement | undefined, landed?: () => void): void {\n if (element === undefined) {\n const placed = this.#placed.get(name);\n if (placed !== undefined) this.#landing.delete(placed);\n this.#placed.delete(name);\n return;\n }\n this.#placed.set(name, element);\n if (landed !== undefined) this.#landing.set(element, landed);\n const anchor = this.#anchors.get(name);\n if (anchor !== undefined) this.#fill(name, anchor);\n }\n\n /** `element` is placed nowhere any longer: the pivot took it away. */\n unplace(element: HTMLElement): void {\n for (const [name, placed] of this.#placed) {\n if (placed === element) this.#placed.delete(name);\n }\n this.#landing.delete(element);\n }\n\n #fill(name: string, anchor: HTMLElement): void {\n const placed = this.#placed.get(name);\n if (placed === undefined || placed.parentNode === anchor) return;\n anchor.append(placed);\n const landed = this.#landing.get(placed);\n this.#landing.delete(placed);\n landed?.();\n }\n\n // The keyboard owed to `name`, given to `element` once it is in the page: a framework hands an element in once it\n // is drawn, plain script often just before.\n #giveOwed(name: string, element: HTMLElement): void {\n if (this.#owed !== name) return;\n const give = (): void => {\n if (this.#owed !== name || !element.isConnected || this.#controls.get(name) !== element) return;\n this.#settle();\n if (keyboardIsThePivots(this.#root)) element.focus();\n };\n if (element.isConnected) give();\n else queueMicrotask(give);\n }\n}\n\n/** One mount's refs, by name. */\nexport interface PartRefs {\n /** The ref for the control named `name`. */\n readonly control: (name: string) => PivotPartRef;\n /** The ref for the anchor named `name`. */\n readonly anchor: (name: string) => PivotPartRef;\n}\n\n/** The ref `refs` holds for `key`, made by `make` the first time it is asked, so a framework handed it again on each\n * render does not hand the element in again. */\nexport function cachedRef<Key>(refs: Map<Key, PivotPartRef>, key: Key, make: () => PivotPartRef): PivotPartRef {\n let ref = refs.get(key);\n if (ref === undefined) {\n ref = make();\n refs.set(key, ref);\n }\n return ref;\n}\n\n/** A ref handing in the element `elements` holds as `key`, which `what` names when anything else is handed in: an\n * element handed in replaces the one before, and `null` takes away only the element this ref handed in, since a\n * framework may hand in the next before it takes back the last, and the built-in markup may stand in its place by\n * then. `handedIn` hears each element handed in. */\nexport function elementRef<Key>(elements: Map<Key, HTMLElement>, key: Key, what: string, handedIn?: (element: HTMLElement) => void): PivotPartRef {\n let current: HTMLElement | undefined;\n return element => {\n if (element === null) {\n if (current !== undefined && elements.get(key) === current) elements.delete(key);\n current = undefined;\n return;\n }\n if (!(element instanceof HTMLElement)) throw new TypeError(`${what} is handed in as an element, or null once it is gone (ADR-0390).`);\n current = element;\n elements.set(key, element);\n handedIn?.(element);\n };\n}\n\n/** `name`, checked as a script may hand it to a part's `control` or `anchor`: one of `names`, which `slot` hands in. */\nexport function checkedName<Name extends string>(name: Name, names: readonly Name[], slot: string): Name {\n if (!names.includes(name)) throw new RangeError(`An ExPivot's ${slot} hands in ${names.join(', ')}, not '${name}' (ADR-0390).`);\n return name;\n}\n\n/** `standing` in the place of `leaving`, where that stands. */\nexport function swap(leaving: HTMLElement, standing: HTMLElement): void {\n if (leaving.parentNode !== null) leaving.replaceWith(standing);\n}\n", "// ExPivot's Chrome slots (ADR-0061, ADR-0390 section 3): the parts of the pivot a Wrapper draws in place of the\n// built-in markup, as the C# `IPivotChrome` lets a Chrome do. The pivot makes the slot, an element inside the frame\n// it places, and hands it to the slot's mount function with what the part shows and the callbacks it answers\n// through. What the part means is the pivot's: the commands and their order, which are enabled, what a draft holds\n// and what OK makes of it, where the frame stands and what closes it. The contents only draw, and call back. A slot\n// left unfilled is drawn by the built-in markup.\n//\n// A context is handed whole at each mount, as the grid's are (ADR-0390): what the part shows is its `view`, read\n// again at each change its `subscribe` tells, and a request for the keyboard mounts the contents again with the next\n// `focusRequest`, on the same slot, so a framework that keys its rendering by the slot keeps its component and that\n// component's state across the two. Once the part goes, nothing the contents call back reaches the pivot.\n\nimport type { GridChrome } from '@ex-grid/core';\nimport type { PivotAggregation, PivotArea, PivotEntry, PivotItemKey, PivotShowValuesAs } from '@ex-grid/pivot-engine';\nimport { keyboardIsThePivots } from './parts';\n\n/**\n * A Chrome slot's mount function (ADR-0350 section 9): it draws the part into `slot`, the element the pivot made for\n * it, from `context`, and answers the function that takes what it drew away. The pivot calls that cleanup before the\n * slot goes, and before it mounts again on the same slot with a new context.\n */\nexport type PivotChromeSlot<Context> = (slot: HTMLElement, context: Context) => () => void;\n\n/** One command of a menu the pivot decides (ADR-0061): what it is called, whether it is available, and what it does. */\nexport interface PivotMenuCommand {\n /** The command's id, which is also the id of its word, stable for an icon. */\n readonly id: string;\n /** What it is called, in the pivot's words. */\n readonly label: string;\n /** Whether it can be pressed: one that would change nothing is disabled. */\n readonly enabled: boolean;\n /** For a choice among others, the Layout menu's, whether it is the current one, which the menu marks; absent on a\n * plain command. */\n readonly checked?: boolean;\n /** The heading of the group of choices that starts at this command: the Layout menu's Subtotals, Grand Totals and\n * Report Layout; absent where it continues the group above. */\n readonly heading?: string;\n /** Runs it and closes the menu, or opens the panel it names in the menu's place. A disabled command runs nothing,\n * and so does one pressed once the menu has closed or been drawn again without it. */\n readonly invoke: () => void;\n}\n\n/** What a menu shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotMenuView {\n /** The menu's accessible name, which its frame carries. */\n readonly name: string;\n /** Excel's commands, in its order. */\n readonly commands: readonly PivotMenuCommand[];\n}\n\n/** What the slots of a part that takes the keyboard share: their words, and the keyboard's requests. */\nexport interface PivotPartSlotContext {\n /** One of the pivot's words by its id: the Consumer's `label`, else the built-in English. */\n readonly label: (id: string) => string;\n /** The count of the pivot's requests for the part to take the keyboard; zero asks nothing. Each request mounts the\n * contents again, and whenever the count differs from the one they last answered they give DOM focus, through\n * `takeFocus`, to the control the part's context names. */\n readonly focusRequest: number;\n /** Gives `control` DOM focus: wherever DOM focus stands while a request is owed, until the contents answer it or\n * the user makes an input in the part, and otherwise only while the keyboard is still the pivot's (ADR-0204). */\n readonly takeFocus: (control: HTMLElement) => void;\n}\n\n/**\n * What a menu's contents are handed (ADR-0061): a placed field's menu, under its entry in the Field List, or the\n * Layout menu, under Layout \u25BE. The slot stands inside the pivot's frame (`role=\"menu\"`, named by the pivot), which\n * Escape anywhere in it closes. The contents draw one item per command, in this order, a choice as a\n * `menuitemradio` marked while it is the current one and a group's heading where one starts. A request for the\n * keyboard is for the first enabled command; with none enabled the pivot gives the frame the keyboard itself.\n */\nexport interface PivotMenuSlotContext extends PivotPartSlotContext {\n /** What the menu shows now. */\n readonly view: () => PivotMenuView;\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** Closes the menu without running anything, for a dismissal of the contents' own; the keyboard goes back to what\n * opened it. */\n readonly close: () => void;\n}\n\n/** What the slots of a panel share (ADR-0061): its exits, and a popup of the contents' own. A panel holds a draft the\n * pivot keeps; OK says it as the next layout, and Cancel and Escape drop it. */\nexport interface PivotPanelSlotContext extends PivotPartSlotContext {\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** OK: the draft is applied and the panel closes. While the view says it cannot be, or the pivot refuses it, the\n * panel stands and says why. */\n readonly apply: () => void;\n /** Cancel: the draft is dropped, the panel closes, and the keyboard goes back to what opened it. */\n readonly cancel: () => void;\n /** The contents report a popup of their own (a select's list) opening (`true`) and closing (`false`): while one\n * is open, Escape is the popup's, and the next closes the panel (ADR-0039). */\n readonly innerPopupChanged: (open: boolean) => void;\n}\n\n/** What Field Settings\u2026 shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotFieldSettingsView {\n /** The field's caption, the panel's title. */\n readonly caption: string;\n /** The draft's subtotals: Automatic (`true`) or None. */\n readonly subtotals: boolean;\n /** The orders there are, each by its words: A to Z and Z to A by label, then each Value Field's two. */\n readonly sorts: readonly string[];\n /** The draft's order, by its index in `sorts`. */\n readonly sort: number;\n}\n\n/** What Field Settings\u2026' contents are handed (ADR-0061): a row or column field's subtotals and order. A request for\n * the keyboard is for the first control, the subtotals' choice. */\nexport interface PivotFieldSettingsSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotFieldSettingsView;\n /** Sets the draft's subtotals. */\n readonly setSubtotals: (automatic: boolean) => void;\n /** Sets the draft's order, by its index in the view's `sorts`. */\n readonly setSort: (index: number) => void;\n}\n\n/** A choice a panel offers: its value, its words, and whether it may be chosen. */\nexport interface PivotChoice<T> {\n /** The choice. */\n readonly value: T;\n /** What it is called. */\n readonly label: string;\n /** Whether it may be chosen: an Aggregation the Pivot Source does not answer is offered, and not available\n * (ADR-0066). */\n readonly enabled: boolean;\n /** Why it may not be chosen, in words; absent while it may. */\n readonly reason?: string;\n}\n\n/** What Value Field Settings\u2026 shows now (ADR-0061): a new object at each change, and the same one otherwise. */\nexport interface PivotValueFieldSettingsView {\n /** The Pivot Field's caption, the Source Name. */\n readonly sourceCaption: string;\n /** The draft's caption, as its field shows it: one the user has not written follows the Aggregation. */\n readonly caption: string;\n /** The draft's Aggregation. */\n readonly aggregation: PivotAggregation;\n /** Every Aggregation, with its name and whether the source answers it. */\n readonly aggregations: readonly PivotChoice<PivotAggregation>[];\n /** The draft's Show Values As. */\n readonly showValuesAs: PivotShowValuesAs;\n /** Every Show Values As, with its name. */\n readonly showValuesAsChoices: readonly PivotChoice<PivotShowValuesAs>[];\n /** The draft's number format, as typed; empty for General. */\n readonly numberFormat: string;\n /** What an empty number format means, the field's placeholder: General. */\n readonly numberFormatPlaceholder: string;\n /** A number shown in the draft's format, or the reason it cannot be. */\n readonly sample: string;\n /** Why OK last refused, in words: a caption taken or empty, a format that cannot be used; absent otherwise. */\n readonly refusal?: string;\n}\n\n/** What Value Field Settings\u2026' contents are handed (ADR-0061). A request for the keyboard is for the first control,\n * the caption's field. */\nexport interface PivotValueFieldSettingsSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotValueFieldSettingsView;\n /** The caption as typed. */\n readonly setCaption: (text: string) => void;\n /** Sets the draft's Aggregation: one the source does not answer is never chosen. */\n readonly setAggregation: (aggregation: PivotAggregation) => void;\n /** Sets the draft's Show Values As. */\n readonly setShowValuesAs: (showValuesAs: PivotShowValuesAs) => void;\n /** The number format as typed. */\n readonly setNumberFormat: (text: string) => void;\n}\n\n/** One Item as Filter\u2026 lists it. */\nexport interface PivotItemChoice {\n /** The Item. */\n readonly key: PivotItemKey;\n /** Its label. */\n readonly label: string;\n /** Whether it is shown in the draft. */\n readonly ticked: boolean;\n}\n\n/** What Filter\u2026 shows now (ADR-0061, ADR-0066): a new object at each change, and the same one otherwise. */\nexport interface PivotItemFilterView {\n /** The field's caption, which names the list. */\n readonly caption: string;\n /** The search as typed. */\n readonly search: string;\n /** The Items the search leaves, in the field's order, at most the most Filter\u2026 lists. */\n readonly items: readonly PivotItemChoice[];\n /** (Select All)'s state over `items`: `true` for every one, `false` for none (and over no Items), or `undefined` for\n * some. */\n readonly allTicked: boolean | undefined;\n /** Whether the Items, or the source's answer to the search, are on their way, with nothing yet to list. */\n readonly loading: boolean;\n /** Whether newer Items are on their way while what is shown stands: an earlier Source Version's Items, kept in\n * view (ADR-0066 refined), or why they could not be listed, while they are asked again. A Chrome may mark the list\n * as updating; it does not blank it, nor dim it. */\n readonly updating: boolean;\n /** Why the Items cannot be listed, in words, said in place of the list; absent while they can. */\n readonly unavailable?: string;\n /** A note under the Items: that more match than are listed, or that none matches the search; absent otherwise. */\n readonly note?: string;\n /** Whether OK may be pressed: not while every Item is unticked, nor while the Items are on their way. */\n readonly canApply: boolean;\n /** Why OK cannot apply, in words; absent while it can. */\n readonly refusal?: string;\n}\n\n/** What Filter\u2026' contents are handed (ADR-0061, ADR-0066): a field's Items, each ticked while shown, a search that\n * narrows them, and OK and Cancel. A request for the keyboard is for the search. */\nexport interface PivotItemFilterSlotContext extends PivotPanelSlotContext {\n /** What the panel shows now. */\n readonly view: () => PivotItemFilterView;\n /** The search as typed. */\n readonly setSearch: (text: string) => void;\n /** Ticks or unticks one Item. */\n readonly setTicked: (key: PivotItemKey, ticked: boolean) => void;\n /** (Select All): ticks or unticks every Item the search lists. */\n readonly setAll: (ticked: boolean) => void;\n}\n\n/** Takes one of a standing part's elements, or `null` once it is gone, as a callback ref does: hand it the element\n * itself (a React `ref`, or a call with the element once it is drawn). */\nexport type PivotPartRef = (element: HTMLElement | null) => void;\n\n/** What the slots of the pivot's standing parts share (ADR-0390): the Pivot Toolbar, the report filter band and the\n * Stale Report's notice. Their contents are mounted once while the part stands, and draw its view again at each change.\n * They hand in their controls by name, through `control`, so the pivot gives the keyboard to the one it means, as it\n * does with the built-in markup's: after a menu closes, to the button that opened it. They hand in the anchors the\n * pivot places a popup's frame in, through `anchor`: an element around the button that opens it, positioned, so the\n * frame needs no position the pivot would have to measure (ADR-0061). */\nexport interface PivotStandingSlotContext<View> {\n /** What the part shows now: a new object at each change, and the same one otherwise. */\n readonly view: () => View;\n /** Hears each change to the view; answers the function that stops it. */\n readonly subscribe: (listener: () => void) => () => void;\n /** One of the pivot's words by its id: the Consumer's `label`, else the built-in English. */\n readonly label: (id: string) => string;\n}\n\n/** What the Pivot Toolbar shows now (ADR-0061). */\nexport interface PivotToolbarView {\n /** Layout \u25BE: its words, and whether its menu is open. */\n readonly layoutMenu: { readonly label: string; readonly open: boolean };\n /** Refresh, while the source can be refreshed (ADR-0066); absent otherwise, and then there is no button. */\n readonly refresh?: { readonly label: string };\n /** The Field List's toggle: its words, and whether the list is shown. */\n readonly fieldList: { readonly label: string; readonly shown: boolean };\n /** Whether the report filter band stands, on the toolbar's left: the contents then hand in its anchor,\n * `anchor('report-filters')`, in which the pivot places the band. */\n readonly reportFilters: boolean;\n /** What the report could not do with the last change, in words \u2014 a layout refused by name, or the source's\n * failure \u2014 said where the user sees it, as an alert (`role=\"alert\"`); absent otherwise. Data that could not be\n * shown is the Stale Report's notice's to say, not this. */\n readonly refusal?: string;\n}\n\n/**\n * What the Pivot Toolbar's contents are handed (ADR-0061): the report filter band on its left, and on its right, in\n * this order, Layout \u25BE, Refresh where the source can be refreshed, and the Field List's toggle. The Layout menu opens\n * in the anchor around Layout \u25BE, over the report, with a backdrop that closes it.\n */\nexport interface PivotToolbarSlotContext extends PivotStandingSlotContext<PivotToolbarView> {\n /** Layout \u25BE pressed: opens the Layout menu, or closes it when it is open. */\n readonly toggleLayoutMenu: () => void;\n /** Refresh pressed: asks the source again. */\n readonly refresh: () => void;\n /** The Field List's toggle pressed: shows the list, or hides it. */\n readonly toggleFieldList: () => void;\n /** Hands in a button: `layout`, `refresh` or `field-list`. */\n readonly control: (name: 'layout' | 'refresh' | 'field-list') => PivotPartRef;\n /** Hands in an anchor: `layout`, around Layout \u25BE, and `report-filters`, where the band stands. */\n readonly anchor: (name: 'layout' | 'report-filters') => PivotPartRef;\n}\n\n/** One report filter (ADR-0061). */\nexport interface PivotReportFilterView {\n /** The field's name. */\n readonly field: string;\n /** Its caption. */\n readonly caption: string;\n /** What it shows: (All), the one Item shown, or (Multiple Items). */\n readonly summary: string;\n /** Whether it hides Items. */\n readonly filtered: boolean;\n /** Whether its Filter\u2026 is open. */\n readonly open: boolean;\n /** The button's accessible name: \"Filter Region\". */\n readonly buttonLabel: string;\n}\n\n/** What the report filter band shows now (ADR-0061). */\nexport interface PivotReportFiltersView {\n /** The band's accessible name, which a `role=\"group\"` around it carries. */\n readonly name: string;\n /** One per field in Filters, in their order. */\n readonly filters: readonly PivotReportFilterView[];\n}\n\n/** What the report filter band's contents are handed (ADR-0061): one entry per field in Filters, its caption and a\n * button that says what it shows and opens Filter\u2026 in the anchor around it, over the report. */\nexport interface PivotReportFiltersSlotContext extends PivotStandingSlotContext<PivotReportFiltersView> {\n /** A filter's button pressed: opens its Filter\u2026, or closes it when it is open. */\n readonly toggle: (field: string) => void;\n /** Hands in the button of the filter of `field`. */\n readonly control: (field: string) => PivotPartRef;\n /** Hands in the anchor around the button of the filter of `field`. */\n readonly anchor: (field: string) => PivotPartRef;\n}\n\n/** What the Stale Report's notice shows now (ADR-0067). */\nexport interface PivotStaleReportView {\n /** The whole sentence: \"Showing the data as of 14:32:05: the newest data needs more than 200,000 cells.\" */\n readonly message: string;\n /** When the data on screen arrived, as the sentence writes it. */\n readonly asOfText: string;\n /** What happened, as the sentence ends it. */\n readonly reason: string;\n /** Retry: its words, and whether it can be pressed \u2014 not while what it would ask is already out. */\n readonly retry: { readonly label: string; readonly enabled: boolean };\n}\n\n/** What the Stale Report's notice's contents are handed (ADR-0067), inside the pivot's polite live region under the\n * Pivot Toolbar, while the report is stale; the contents add no live region of their own. */\nexport interface PivotStaleReportSlotContext extends PivotStandingSlotContext<PivotStaleReportView> {\n /** Retry pressed: asks again what failed. */\n readonly retry: () => void;\n /** Hands in Retry. */\n readonly control: (name: 'retry') => PivotPartRef;\n}\n\n/** A declared field in the Field List (ADR-0061). */\nexport interface PivotFieldListFieldView {\n /** The field's name. */\n readonly name: string;\n /** What it is called. */\n readonly caption: string;\n /** The name its tick box is handed in by, through `control`. */\n readonly key: string;\n /** Whether it stands in any Area: its tick box. */\n readonly placed: boolean;\n /** Whether it hides Items now. */\n readonly filtered: boolean;\n /** Its count of Items, written in the pivot's locale, where the source counted them; absent otherwise. */\n readonly count?: string;\n /** The count as said: \"12 Items\"; absent with the count. */\n readonly countLabel?: string;\n /** Whether it is the one being dragged. */\n readonly dragging: boolean;\n}\n\n/** A placed entry of an Area (ADR-0061). */\nexport interface PivotFieldListEntryView {\n /** Which entry it is: its Area and index there, \u22121 for \u03A3 Values. */\n readonly entry: PivotEntry;\n /** The name its button and the anchor around it are handed in by, through `control` and `anchor`. */\n readonly key: string;\n /** What it is called: the field's caption, a Value Field's caption, \u03A3 Values. */\n readonly caption: string;\n /** The button's accessible name: \"Options for Region\". */\n readonly menuLabel: string;\n /** Whether its field hides Items now. */\n readonly filtered: boolean;\n /** Whether it is \u03A3 Values. */\n readonly values: boolean;\n /** Whether its menu, or a panel the menu opened, stands under it: the entry is then not draggable, so a press that\n * moves a little on the menu is the menu's. */\n readonly menuOpen: boolean;\n /** Whether it is the one being dragged. */\n readonly dragging: boolean;\n /** Whether a drop now would land before it. */\n readonly dropBefore: boolean;\n /** The index a `dragenter` on it hands `dragEnter`, and a `drop` on it hands `drop`: its own, or for \u03A3 Values,\n * which always stands last, its Area's `end`. */\n readonly dropIndex: number;\n}\n\n/** One Area of the Field List (ADR-0061). */\nexport interface PivotFieldListAreaView {\n /** Which Area. */\n readonly area: PivotArea;\n /** Its name: Filters, Columns, Rows, Values. */\n readonly title: string;\n /** What stands in it, \u03A3 Values last where it stands. */\n readonly entries: readonly PivotFieldListEntryView[];\n /** The index a `dragenter` or a `drop` on the Area's box itself hands on: past its last entry. */\n readonly end: number;\n /** Whether what is dragged is over it, and may be dropped there. */\n readonly dropTarget: boolean;\n /** While a drop there would pass the leaf cap, by the counts, the words that say so, in a `role=\"status\"`: a hint,\n * never a refusal (ADR-0370 section 3). Absent otherwise. */\n readonly overCap?: string;\n}\n\n/** What the Field List shows now (ADR-0061). */\nexport interface PivotFieldListView {\n /** The pane's name: \"PivotTable Fields\". */\n readonly title: string;\n /** The heading's close button's accessible name: \"Hide Field List\". */\n readonly hideLabel: string;\n /** The caption above the fields: \"Choose fields to add to report:\". */\n readonly chooseCaption: string;\n /** The search's accessible name and placeholder. */\n readonly searchLabel: string;\n /** The search as typed. */\n readonly search: string;\n /** The declared fields the search leaves, in declaration order. */\n readonly fields: readonly PivotFieldListFieldView[];\n /** The caption above the Areas: \"Drag fields between areas below:\". */\n readonly dragCaption: string;\n /** The four Areas, in Excel's order: Filters, Columns, Rows, Values. */\n readonly areas: readonly PivotFieldListAreaView[];\n /** Whether a drop on the list of fields, or on the report, removes what is dragged: a placed field's entry. */\n readonly dropRemoves: boolean;\n /** Defer Layout Update, at the pane's foot: its words, and whether it is ticked. */\n readonly defer: { readonly label: string; readonly ticked: boolean };\n /** Update: its words, and whether it would apply anything. */\n readonly update: { readonly label: string; readonly enabled: boolean };\n}\n\n/** What is dragged in the Field List: a declared field from the list of fields, or a placed entry of an Area. */\nexport type PivotDragSubject = { readonly field: string } | { readonly entry: PivotEntry };\n\n/**\n * What the Field List's contents are handed (ADR-0061): the fields with their tick boxes and search, and the four\n * Areas with their entries, each entry's open menu or panel placed by the pivot in the anchor around its button.\n * Drag and drop is the browser's own: a draggable element calls `startDrag` on `dragstart` and `endDrag` on `dragend`;\n * a drop target calls `dragOver` on `dragover` always \u2014 whether it may be dropped on is decided at the drop, never by a\n * render that may still be on its way \u2014 `dragEnter` on `dragenter` for the marks, and `drop` (or `dropOnList`) on\n * `drop`. Each Area's box is handed in by `area`, so a drag that leaves every Area is seen to.\n */\nexport interface PivotFieldListSlotContext extends PivotStandingSlotContext<PivotFieldListView> {\n /** The search as it is typed. */\n readonly setSearch: (text: string) => void;\n /** A field's tick box pressed: ticks it into the layout, or takes it out. */\n readonly toggle: (field: string) => void;\n /** An entry's button pressed: opens its menu, or closes the one standing under it. */\n readonly openMenu: (entry: PivotEntry) => void;\n /** The heading's close button pressed: hides the Field List, keeping the layout and any pending one. */\n readonly close: () => void;\n /** A `dragstart` on a field or an entry: the drag starts, against the layout the pane shows. */\n readonly startDrag: (event: DragEvent, subject: PivotDragSubject) => void;\n /** A `dragover` on any drop target: takes the drop while a drag of the pane's is on. */\n readonly dragOver: (event: DragEvent) => void;\n /** A `dragenter` on an Area (`index` its entries' count) or an entry (`index` its own): where a drop would land. */\n readonly dragEnter: (area: PivotArea, index: number) => void;\n /** A `drop` on an Area or an entry, at the index `dragEnter` takes. */\n readonly drop: (event: DragEvent, area: PivotArea, index: number) => void;\n /** A `drop` on the list of fields: an entry dragged back is taken out of the layout. */\n readonly dropOnList: (event: DragEvent) => void;\n /** A `dragend`, whether or not anything was dropped. */\n readonly endDrag: () => void;\n /** Defer Layout Update ticked or unticked; unticking applies the pending layout, as Excel does. */\n readonly setDeferred: (deferred: boolean) => void;\n /** Update pressed: applies the pending layout in one change. */\n readonly update: () => void;\n /** Hands in a control: `search`, a field's tick box by its `key`, or an entry's button by its `key`. */\n readonly control: (key: string) => PivotPartRef;\n /** Hands in the anchor around an entry's button, or beside it, by the entry's `key`: an element of no position of\n * its own, so the frame the pivot places in it takes the pane's width (ADR-0061). A press or focus on the entry's\n * button, handed in by `control`, is inside its open menu wherever the anchor stands. */\n readonly anchor: (key: string) => PivotPartRef;\n /** Hands in an Area's box. */\n readonly area: (area: PivotArea) => PivotPartRef;\n}\n\n/** A sheet's tab at the report's foot (ADR-0059): the report's own, first, or a Show Details sheet's. */\nexport interface PivotDetailsTabView {\n /** The name the tab's control is handed in by, and `select` and `close` are handed. */\n readonly key: string;\n /** What the tab reads: the report's own words, or the cell the records are behind. */\n readonly title: string;\n /** Whether it is the selected sheet: a details sheet's records then cover the report. */\n readonly selected: boolean;\n /** The id of the panel its records stand in, for the control's `aria-controls`; absent on the report's tab. */\n readonly panelId?: string;\n /** Its close button's words, said as \"Close \u2026\"; absent on the report's tab, which does not close. */\n readonly closeLabel?: string;\n}\n\n/** What the sheet tabs show now (ADR-0059). */\nexport interface PivotDetailsTabsView {\n /** The tab list's name. */\n readonly name: string;\n /** The report's tab, then each Show Details sheet's, in the order they opened. */\n readonly tabs: readonly PivotDetailsTabView[];\n}\n\n/** What the sheet tabs' contents are handed (ADR-0059), at the report's foot while a Show Details sheet stands. The\n * selected sheet's records are the pivot's, in a panel of its own over the report; the tab that opens takes the\n * keyboard, and so does the one selected once a tab holding it closes. */\nexport interface PivotDetailsTabsSlotContext extends PivotStandingSlotContext<PivotDetailsTabsView> {\n /** A tab pressed, by its `key`: its sheet is selected. */\n readonly select: (key: string) => void;\n /** A details tab's close pressed, by its `key`: Excel's next sheet is selected, or the report. */\n readonly close: (key: string) => void;\n /** Hands in the control of the tab of `key`. */\n readonly control: (key: string) => PivotPartRef;\n}\n\n/** What the Show Details dialog shows now (ADR-0059). */\nexport interface PivotDetailsDialogView {\n /** The cell the records are behind, which names the dialog. */\n readonly title: string;\n /** Close's words. */\n readonly closeLabel: string;\n}\n\n/** What the Show Details dialog's contents are handed (ADR-0059): its title, the anchor its records stand in and\n * Close, inside the pivot's modal frame, which keeps the backdrop and Escape. Close takes the keyboard as the dialog\n * opens, and the report's grid takes it back however it closes. */\nexport interface PivotDetailsDialogSlotContext extends PivotStandingSlotContext<PivotDetailsDialogView> {\n /** Close pressed. */\n readonly close: () => void;\n /** Hands in Close. */\n readonly control: (name: 'close') => PivotPartRef;\n /** Hands in the element the records stand in: their box takes the room the dialog gives it. */\n readonly anchor: (name: 'records') => PivotPartRef;\n}\n\n/** A stylesheet a Chrome brings (ADR-0123), as its notice names it: a Wrapper has no root of its own (ADR-0062), so\n * its Chrome declares the stylesheets it brings, and the pivot's root renders a notice for each beside its own. */\nexport interface PivotChromeStylesheet {\n /** The stylesheet's source file name, as the rules at the end of the shipped stylesheet name it: `mud-ex-pivot.css`. */\n readonly name: string;\n /** The SHA-256 of that source, as lower-case hex: the stamp the stylesheet the Chrome was built with hides its\n * notice for. */\n readonly stamp: string;\n}\n\n/**\n * The Chrome slots a pivot takes (ADR-0061, ADR-0390): the parts a Wrapper draws, each in place of the built-in\n * markup's. A slot not given is the built-in markup's. A slot is read when its part opens: a part standing keeps the\n * slot it opened with.\n */\nexport interface PivotChrome {\n /** The stylesheets this Chrome brings (ADR-0123): the pivot's root renders a notice for each beside its own, which\n * only another version's stylesheet shows. The report grid's Chrome declares its own. None where not given. */\n readonly stylesheets?: readonly PivotChromeStylesheet[];\n /** The report grid's Chrome, and Show Details' grids', so one Chrome dresses the pivot and the grids it draws. The\n * Context Menu's commands are worded by the pivot. */\n readonly grid?: GridChrome<unknown>;\n /** A placed field's menu and the Layout menu. */\n readonly menu?: PivotChromeSlot<PivotMenuSlotContext>;\n /** Filter\u2026, under a field's entry or a report filter's button. */\n readonly itemFilter?: PivotChromeSlot<PivotItemFilterSlotContext>;\n /** Field Settings\u2026 of a row or column field. */\n readonly fieldSettings?: PivotChromeSlot<PivotFieldSettingsSlotContext>;\n /** Value Field Settings\u2026. */\n readonly valueFieldSettings?: PivotChromeSlot<PivotValueFieldSettingsSlotContext>;\n /** The Pivot Toolbar above the report. */\n readonly toolbar?: PivotChromeSlot<PivotToolbarSlotContext>;\n /** The report filter band, on the Pivot Toolbar's left. */\n readonly reportFilters?: PivotChromeSlot<PivotReportFiltersSlotContext>;\n /** The Stale Report's notice, under the Pivot Toolbar. */\n readonly staleReport?: PivotChromeSlot<PivotStaleReportSlotContext>;\n /** The Field List: Excel's PivotTable Fields pane. Its slot draws no box of its own, so the contents fill the\n * Field List's height (`height: 100%`). */\n readonly fieldList?: PivotChromeSlot<PivotFieldListSlotContext>;\n /** The sheet tabs at the report's foot, while Show Details' records stand in a tab. */\n readonly detailsTabs?: PivotChromeSlot<PivotDetailsTabsSlotContext>;\n /** What the Show Details dialog draws inside its frame, a flex column; the slot draws no box of its own. */\n readonly detailsDialog?: PivotChromeSlot<PivotDetailsDialogSlotContext>;\n}\n\nconst slotNames: readonly Exclude<keyof PivotChrome, 'stylesheets'>[] = ['grid', 'menu', 'itemFilter', 'fieldSettings', 'valueFieldSettings', 'toolbar', 'reportFilters', 'staleReport', 'fieldList', 'detailsTabs',\n 'detailsDialog'];\n\n/** A pivot's `chrome`, checked as a script may hand it: an object whose slots are each a mount function, and whose\n * `grid` is an object the report grid checks. */\nexport function checkedPivotChrome(chrome: unknown): PivotChrome | undefined {\n if (chrome === undefined) return undefined;\n if (typeof chrome !== 'object' || chrome === null) {\n throw new TypeError('An ExPivot\\'s chrome is an object of Chrome slots, each a mount function (ADR-0390).');\n }\n for (const [name, slot] of Object.entries(chrome)) {\n if (name === 'stylesheets') {\n checkedStylesheets(slot);\n continue;\n }\n if (!(slotNames as readonly string[]).includes(name)) {\n throw new TypeError(`An ExPivot's chrome has no slot '${name}': its slots are ${slotNames.join(', ')} (ADR-0390).`);\n }\n if (name === 'grid') {\n if (slot !== undefined && (typeof slot !== 'object' || slot === null)) {\n throw new TypeError('An ExPivot\\'s chrome.grid is a grid\\'s chrome: an object of its Chrome slots (ADR-0390).');\n }\n } else if (slot !== undefined && typeof slot !== 'function') {\n throw new TypeError(`An ExPivot's chrome.${name} is a mount function, (slot, context) => cleanup (ADR-0350 section 9).`);\n }\n }\n return chrome;\n}\n\n/** A Chrome's `stylesheets`, checked as a script may hand them: each a name and a SHA-256 stamp the notice carries. */\nfunction checkedStylesheets(stylesheets: unknown): void {\n if (stylesheets === undefined) return;\n if (!Array.isArray(stylesheets)) throw new TypeError('An ExPivot\\'s chrome.stylesheets is an array of { name, stamp } (ADR-0123).');\n for (const stylesheet of stylesheets as readonly unknown[]) {\n const name: unknown = typeof stylesheet === 'object' && stylesheet !== null ? Reflect.get(stylesheet, 'name') : undefined;\n const stamp: unknown = typeof stylesheet === 'object' && stylesheet !== null ? Reflect.get(stylesheet, 'stamp') : undefined;\n // Any stamp is taken, as C#'s ChromeStylesheet takes it: one no shipped stylesheet carries leaves the notice\n // showing, which says so, not quietly.\n if (typeof name !== 'string' || name === '' || typeof stamp !== 'string' || stamp === '') {\n throw new TypeError('Each of an ExPivot\\'s chrome.stylesheets is { name, stamp }: the stylesheet\\'s file name, and the stamp its own rule hides the notice for (ADR-0123).');\n }\n }\n}\n\n/** Mounts `context` into `slot` by `mount`, and answers the cleanup it returned, checked. */\nfunction mounted<Context>(name: string, mount: PivotChromeSlot<Context>, slot: HTMLElement, context: Context): () => void {\n const cleanup: unknown = mount(slot, context);\n if (typeof cleanup !== 'function') {\n throw new TypeError(`An ExPivot's chrome.${name} answered ${typeof cleanup}: a mount function answers the function that takes its contents away.`);\n }\n return () => { Reflect.apply(cleanup, undefined, []); };\n}\n\n/** The listeners a slot's view is told each change through, by the context's `subscribe`. */\nexport class ViewListeners {\n readonly #listeners = new Set<() => void>();\n\n /** The context's `subscribe`: adds `listener`, and answers the function that removes it. */\n readonly subscribe = (listener: () => void): (() => void) => {\n if (typeof listener !== 'function') throw new TypeError('subscribe is handed the function that hears each change to the view.');\n this.#listeners.add(listener);\n return () => { this.#listeners.delete(listener); };\n };\n\n /** Tells every listener the view changed. */\n tell(): void {\n for (const listener of this.#listeners) listener();\n }\n\n /** The part is gone: nothing is told any more. */\n clear(): void {\n this.#listeners.clear();\n }\n}\n\n/**\n * A Chrome slot's contents while their part stands (ADR-0390): mounted with a context, mounted again with the next\n * one for each request for the keyboard, and taken away when the part goes, after which nothing they call back\n * reaches the pivot. The focus a request asks for is owed, the pivot's to give wherever DOM focus stands, until the\n * contents give it or the user makes an input in the part; any other focus they ask for is given only while the\n * keyboard is still the pivot's (ADR-0204), as ExGrid's own slots do.\n */\nexport class SlotMount<Context> {\n readonly #name: string;\n readonly #mount: PivotChromeSlot<Context>;\n /** The slot, which the pivot stands inside the part's frame. */\n readonly element: HTMLElement;\n readonly #context: (focusRequest: number) => Context;\n readonly #cancel: () => void;\n #cleanup: (() => void) | undefined;\n #focusRequest = 0;\n #owed = false;\n #live = true;\n /** Whether a popup of the contents' own is open: Escape is then the popup's (ADR-0039). */\n innerPopupOpen = false;\n\n /** `context` makes the context for a focus request's count; `cancel` closes the part. */\n constructor(name: string, mount: PivotChromeSlot<Context>, element: HTMLElement, context: (focusRequest: number) => Context, cancel: () => void) {\n this.#name = name;\n this.#mount = mount;\n this.element = element;\n this.#context = context;\n this.#cancel = cancel;\n element.setAttribute('data-ex-pivot-slot', name);\n }\n\n /** Whether the part stands. */\n get live(): boolean {\n return this.#live;\n }\n\n /** Mounts the contents, once. */\n mount(): void {\n if (this.#live && this.#cleanup === undefined) this.#draw();\n }\n\n /** A request for the keyboard: the contents are mounted again with the next count. */\n request(): void {\n if (!this.#live) return;\n this.#focusRequest += 1;\n this.#owed = true;\n this.#unmount();\n this.#draw();\n }\n\n /** `change` as an input the user made in the part: no focus is owed any longer, and nothing is made once the part\n * is gone. */\n input<Args extends unknown[]>(change: (...args: Args) => void): (...args: Args) => void {\n return (...args: Args): void => {\n if (!this.#live) return;\n this.#owed = false;\n change(...args);\n };\n }\n\n /** The part is going: its contents are taken away. */\n dispose(): void {\n if (!this.#live) return;\n this.#live = false;\n this.#unmount();\n }\n\n readonly innerPopupChanged = (open: boolean): void => {\n if (typeof open !== 'boolean') throw new TypeError('innerPopupChanged is handed whether the popup is open.');\n if (this.#live) this.innerPopupOpen = open;\n };\n\n readonly takeFocus = (control: HTMLElement): void => {\n if (!(control instanceof HTMLElement)) throw new TypeError('takeFocus is handed the element that takes the keyboard.');\n if (!this.#live || !control.isConnected) return;\n const owed = this.#owed;\n this.#owed = false;\n const pivot = this.element.closest('.ex-pivot');\n if (owed || (pivot !== null && keyboardIsThePivots(pivot))) control.focus();\n };\n\n // Contents that cannot be drawn close the part, rather than leave it standing empty.\n #draw(): void {\n try {\n this.#cleanup = mounted(this.#name, this.#mount, this.element, this.#context(this.#focusRequest));\n } catch (error) {\n this.#cancel();\n throw error;\n }\n }\n\n // The contents go, and a popup of theirs with them: they are not asked to say so.\n #unmount(): void {\n const cleanup = this.#cleanup;\n this.#cleanup = undefined;\n this.innerPopupOpen = false;\n cleanup?.();\n }\n}\n\n/**\n * A standing part's slot (ADR-0390): its contents are mounted once, with a context of their own, while the part\n * stands and the same mount function is given, and told each change to its view. Another mount function, the\n * Consumer having handed another `chrome`, mounts again; once the part goes, nothing the contents call back reaches\n * the pivot. The slot is an element of its own, which the pivot stands in the part's place. Contents that cannot be\n * drawn are refused by name once, and the part is the built-in markup's while that mount function is given.\n */\nexport class StandingSlot<View, Context> {\n readonly #name: string;\n /** The slot. */\n readonly element: HTMLElement;\n // Each mount's own, so contents a framework keeps across a mount subscribe again to the next one's.\n #listeners = new ViewListeners();\n #view: View;\n // What the view held says, so a draw that shows the same thing makes nothing new and tells nobody; worked out only\n // while contents stand to be told.\n #said: string | undefined;\n #mount: PivotChromeSlot<Context> | undefined;\n #cleanup: (() => void) | undefined;\n #failed: PivotChromeSlot<Context> | undefined;\n // Counts the mounts, so a callback handed to one reaches nothing once another stands.\n #mounts = 0;\n\n constructor(name: string, document: Document, view: View) {\n this.#name = name;\n this.element = document.createElement('div');\n this.element.setAttribute('data-ex-pivot-slot', name);\n this.#view = view;\n }\n\n /** The view the part shows: `next`, or the one held where it shows the same, so it stays the same object while\n * nothing it shows changed. */\n viewOf(next: View): View {\n if (this.#cleanup === undefined) {\n this.#view = next;\n this.#said = undefined;\n return next;\n }\n const said = JSON.stringify(next);\n const held = this.#said === undefined ? JSON.stringify(this.#view) : this.#said;\n this.#said = said;\n if (said === held) return this.#view;\n this.#view = next;\n this.#listeners.tell();\n return next;\n }\n\n /** Whether the contents `mount` draws stand. */\n stands(mount: PivotChromeSlot<Context>): boolean {\n return this.#cleanup !== undefined && this.#mount === mount;\n }\n\n /** Whether `mount` could not be drawn: it is not tried again. */\n refuses(mount: PivotChromeSlot<Context>): boolean {\n return this.#failed === mount;\n }\n\n /** Shows the view held by `mount`: the contents are mounted with the context `context` makes, unless `mount`\n * already stands. `context` is handed the shared parts and an `input` that keeps a callback from reaching the\n * pivot once these contents are gone. Answers whether the contents stand; a mount function that throws, or answers\n * no cleanup, is not tried again, and its error is answered for the pivot to throw once it has drawn. */\n show(mount: PivotChromeSlot<Context>,\n context: (shared: PivotStandingSlotContext<View>, input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void) => Context,\n label: (id: string) => string): { readonly shown: boolean; readonly error?: Error } {\n if (this.refuses(mount)) return { shown: false };\n if (this.stands(mount)) return { shown: true };\n this.hide();\n this.#mounts += 1;\n const made = this.#mounts;\n const input = <Args extends unknown[]>(change: (...args: Args) => void): ((...args: Args) => void) => (...args: Args): void => {\n if (this.#cleanup !== undefined && this.#mounts === made) change(...args);\n };\n this.#listeners = new ViewListeners();\n const shared: PivotStandingSlotContext<View> = { view: () => this.#view, subscribe: this.#listeners.subscribe, label };\n try {\n this.#cleanup = mounted(this.#name, mount, this.element, Object.freeze(context(shared, input)));\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- answered, and thrown by the pivot once it has drawn the built-in markup in its place\n this.#failed = mount;\n return { shown: false, error: error instanceof Error ? error : new Error(`An ExPivot's chrome.${this.#name} could not be drawn (ADR-0390).`, { cause: error }) };\n }\n this.#mount = mount;\n return { shown: true };\n }\n\n /** What the part shows now. */\n get view(): View {\n return this.#view;\n }\n\n /** The part shows none of the contents: they are taken away. */\n hide(): void {\n const cleanup = this.#cleanup;\n this.#cleanup = undefined;\n this.#mount = undefined;\n this.#listeners.clear();\n cleanup?.();\n }\n}\n", "// The pivot's own elements, made as every view of it makes them.\n\n/** A new element of `document`, with `className` when given. */\nexport function element<K extends keyof HTMLElementTagNameMap>(document: Document, tag: K, className?: string): HTMLElementTagNameMap[K] {\n const made = document.createElement(tag);\n if (className !== undefined) made.className = className;\n return made;\n}\n\n// The style each element was last written, by the pivot.\nconst written = new WeakMap<Element, string>();\n\n/** Writes `style` on `target` when it differs from what the pivot last wrote there, as a Razor render writes an\n * attribute only when its own value changed: a style the page set on the element since stays until the pivot's\n * own changes. */\nexport function writeStyle(target: Element, style: string): void {\n if (written.get(target) === style) return;\n written.set(target, style);\n target.setAttribute('style', style);\n}\n\n/** Takes away the style the pivot wrote on `target`, which it no longer draws. */\nexport function clearStyle(target: Element): void {\n written.delete(target);\n target.removeAttribute('style');\n}\n", "// Show Details' sheets as the pivot shows them when the Consumer does not take the records (ADR-0059): a tab at the\n// report's foot for each, where Excel's sheet tabs are, whose records cover the report while it is selected; or one\n// modal dialog over the pivot. The markup and classes are the Razor component's PivotDetailsTabsView,\n// PivotDialogFrame, PivotDetailsDialogView and PivotDetailsGrid (ADR-0350 section 4). Each sheet's records are an\n// ExGrid of their own, in an Input Root of their own (ADR-0240 section 6).\n\nimport type { CellTextMetrics, GridChrome, GridDensity, GridHandle, GridOptions, GridPresentationDefaults } from '@ex-grid/core';\nimport type { PivotDetailRecord } from '@ex-grid/pivot-engine';\nimport {\n StandingSlot, type PivotChrome, type PivotDetailsDialogSlotContext, type PivotDetailsDialogView, type PivotDetailsTabsSlotContext, type PivotDetailsTabsView,\n} from './chrome';\nimport { detailCellType, DetailsSheet, type DetailsProblem, type PivotDetailsView, type PivotShowDetailsEvent } from './details';\nimport { element } from './dom';\nimport { checkedName, keyboardIsThePivots, swap, type PartElements } from './parts';\nimport type { PivotScreenWords } from './words';\n\n/** Draws a grid into an element: ExGrid's `createGrid`, or a layer-2 test's own. */\nexport type MountGrid = <Row>(element: HTMLElement, options: GridOptions<Row>) => GridHandle<Row>;\n\n/** What the records' grids take from the pivot's options. */\nexport interface DetailsGridLook {\n readonly rowHeight: number | undefined;\n readonly density: GridDensity | undefined;\n readonly cellMetrics: CellTextMetrics | undefined;\n readonly presentationDefaults: GridPresentationDefaults | undefined;\n readonly commandLabel: ((id: string) => string | undefined) | undefined;\n /** The grid's Chrome a pivot's Chrome dresses its grids in (ADR-0390). */\n readonly chrome: GridChrome<PivotDetailRecord> | undefined;\n}\n\n/** What the sheets ask of the pivot. */\nexport interface DetailsHost {\n readonly document: Document;\n readonly mountGrid: MountGrid;\n readonly words: () => PivotScreenWords;\n readonly look: () => DetailsGridLook;\n /** Why the records cannot be shown, in the pivot's words. */\n readonly problemText: (problem: DetailsProblem) => string;\n /** The sheets changed what the pivot draws around them: which covers the report, whether a dialog stands. */\n readonly changed: () => void;\n /** The report's grid takes the keyboard back (ADR-0070). */\n readonly returnKeyboard: () => void;\n /** The controls and anchors the pivot's parts hand in, the sheets' among them. */\n readonly parts: PartElements;\n /** The pivot's Chrome slots for the sheets, read each time the sheets are drawn. */\n readonly chrome: () => Pick<PivotChrome, 'detailsTabs' | 'detailsDialog'> | undefined;\n}\n\n// One sheet's records: its grid in an Input Root of its own, or the sentence that says why there are none.\nclass Records {\n readonly sheet: DetailsSheet;\n /** What stands in the panel or the dialog. */\n readonly box: HTMLElement;\n readonly #host: DetailsHost;\n readonly #leave: (() => void) | undefined;\n readonly #keyboardHome: () => void;\n /** Whether the box stands where the records are shown: a Chrome's dialog hands in the anchor it stands in once\n * its contents are drawn. */\n standing = true;\n #grid: GridHandle<PivotDetailRecord> | undefined;\n #status: HTMLElement | undefined;\n\n /** `leave` is the dialog's way out; `keyboardHome` gives the keyboard on when the grid that held it goes. */\n constructor(host: DetailsHost, sheet: DetailsSheet, leave: (() => void) | undefined, keyboardHome: () => void) {\n this.#host = host;\n this.sheet = sheet;\n this.#leave = leave;\n this.#keyboardHome = keyboardHome;\n // The box draws nothing (`display: contents`); the records' grid keeps an order of its own, apart from the\n // report's, which hears the rest of the pivot.\n this.box = element(host.document, 'div');\n this.box.setAttribute('data-ex-input-root', '');\n this.box.setAttribute('style', 'display: contents');\n }\n\n /** Draws the records, once their box stands in the document. */\n draw(): void {\n if (!this.standing) return;\n const { problem } = this.sheet;\n if (problem !== undefined) {\n // The sentence replaces the grid, and the keyboard the grid held goes to the tab or to Close, so it stays\n // in the sheet.\n const held = this.box.contains(this.#host.document.activeElement);\n this.#grid?.destroy();\n this.#grid = undefined;\n const text = this.#host.problemText(problem);\n if (this.#status === undefined) {\n this.#status = element(this.#host.document, 'div', 'ex-pivot-details-status');\n this.#status.setAttribute('role', 'alert');\n this.box.replaceWith(this.#status);\n }\n if (this.#status.textContent !== text) this.#status.textContent = text;\n if (held) this.#keyboardHome();\n return;\n }\n const { rowHeight, density, cellMetrics, presentationDefaults, commandLabel, chrome } = this.#host.look();\n const options: GridOptions<PivotDetailRecord> = {\n columns: this.sheet.columns,\n source: this.sheet.source,\n // The locale its records' text was written in, so one grid never shows two cultures.\n locale: this.sheet.locale,\n viewportHeight: 'stretch',\n viewportWidth: 'stretch',\n // The records are in the data's order and none is left out: the header click selects, and there is no\n // column menu to sort or filter them by (ADR-0059).\n headerClickSelects: true,\n hideColumnMenu: true,\n cellType: detailCellType,\n ...(commandLabel === undefined ? {} : { commandLabel }),\n ...(chrome === undefined ? {} : { chrome }),\n ...(rowHeight === undefined ? {} : { rowHeight }),\n ...(density === undefined ? {} : { density }),\n ...(cellMetrics === undefined ? {} : { cellMetrics }),\n ...(presentationDefaults === undefined ? {} : { presentationDefaults }),\n // The dialog's way out: the Escape its grid has nothing left to dismiss closes it (ADR-0070). A tab's grid\n // has none; Escape does not close a sheet.\n ...(this.#leave === undefined ? {} : { onLeave: this.#leave }),\n };\n if (this.#grid === undefined) {\n const root = element(this.#host.document, 'div');\n this.box.replaceChildren(root);\n this.#grid = this.#host.mountGrid(root, options);\n } else {\n this.#grid.update(options);\n }\n }\n\n /** Takes the grid away while the records are not on screen: a tab not selected. Its source stays. */\n hide(): void {\n this.#grid?.destroy();\n this.#grid = undefined;\n }\n\n dispose(): void {\n this.hide();\n this.sheet.dispose();\n }\n}\n\n// A details tab: its tab at the report's foot, and its panel over the report.\ninterface Tab {\n /** The name its control is handed in by, the built-in button's id. */\n readonly key: string;\n readonly records: Records;\n readonly tab: HTMLElement;\n readonly button: HTMLButtonElement;\n readonly close: HTMLButtonElement;\n readonly panel: HTMLElement;\n}\n\n// The dialog's frame over its backdrop; what stands inside it, the built-in markup's or a Chrome's contents; and\n// the box its records stand in.\ninterface Dialog {\n readonly records: Records;\n readonly backdrop: HTMLElement;\n readonly frame: HTMLElement;\n /** The built-in markup's: the title, the records and Close. */\n readonly content: HTMLElement;\n readonly heading: HTMLElement;\n readonly recordsBox: HTMLElement;\n readonly close: HTMLButtonElement;\n /** Whether a Chrome's contents stand in the frame. */\n slotted: boolean;\n}\n\n/** The name the dialog's Close is handed in by. */\nconst dialogClose = 'details-close';\n/** The name of the anchor the dialog's records stand in. */\nconst dialogRecords = 'details-records';\n\n// The name a tab's control is handed in by.\nfunction tabName(key: string): string {\n return `tab:${key}`;\n}\n\n// Each pivot's ids are its own on the page (ADR-0018).\nlet pivots = 0;\n\n/** The pivot's details sheets: the tabs and the dialog. */\nexport class DetailsSheets {\n readonly #host: DetailsHost;\n readonly #idPrefix: string;\n readonly #builtInTabList: HTMLElement;\n readonly #tabsSlot: StandingSlot<PivotDetailsTabsView, PivotDetailsTabsSlotContext>;\n #tabsSlotted = false;\n // One for every dialog, so contents refused once are not tried again at the next.\n readonly #dialogSlot: StandingSlot<PivotDetailsDialogView, PivotDetailsDialogSlotContext>;\n // The slots' contents that could not be drawn, for the pivot to throw once the sheets have drawn.\n #refused: Error[] = [];\n readonly #reportTab: HTMLElement;\n readonly #reportButton: HTMLButtonElement;\n readonly #tabs: Tab[] = [];\n #selected: Tab | undefined;\n #dialog: Dialog | undefined;\n #sequence = 0;\n\n constructor(host: DetailsHost) {\n this.#host = host;\n this.#idPrefix = `ex-pivot-${++pivots}`;\n const { document } = host;\n this.#builtInTabList = element(document, 'div', 'ex-pivot-tabs');\n this.#builtInTabList.setAttribute('role', 'tablist');\n this.#tabsSlot = new StandingSlot('detailsTabs', document, Object.freeze({ name: '', tabs: Object.freeze([]) }));\n this.#dialogSlot = new StandingSlot('detailsDialog', document, Object.freeze({ title: '', closeLabel: '' }));\n // The slot draws nothing (`display: contents`): the contents lay themselves out in the dialog's frame.\n this.#dialogSlot.element.setAttribute('style', 'display: contents');\n // The report's own tab, first: selecting it uncovers the report.\n const { tab, button } = this.#tab(`${this.#idPrefix}-report`, () => { this.#select(undefined); });\n this.#reportTab = tab;\n this.#reportButton = button;\n }\n\n /** The tab list at the report's foot, the built-in markup's or a Chrome's, which the pivot places after the report\n * while a tab stands. */\n get tabList(): HTMLElement {\n return this.#tabsSlotted ? this.#tabsSlot.element : this.#builtInTabList;\n }\n\n /** The slots' contents that could not be drawn since this was last asked, the built-in markup standing in their\n * place. */\n takeRefused(): readonly Error[] {\n const refused = this.#refused;\n this.#refused = [];\n return refused;\n }\n\n /** Whether a details tab is selected, its records covering the report. */\n get covering(): boolean {\n return this.#selected !== undefined;\n }\n\n /** The selected tab's panel, which the pivot places in the report's sheet over the report. */\n get panel(): HTMLElement | undefined {\n return this.#selected?.panel;\n }\n\n /** Whether a tab stands at the report's foot. */\n get tabsShown(): boolean {\n return this.#tabs.length > 0;\n }\n\n /** Whether the dialog stands: what it covers takes neither the keyboard nor the pointer (ADR-0059). */\n get dialogShown(): boolean {\n return this.#dialog !== undefined;\n }\n\n /** The dialog's backdrop and frame, which the pivot places last in its root; none while no dialog stands. */\n get dialogElements(): readonly HTMLElement[] {\n const dialog = this.#dialog;\n return dialog === undefined ? [] : [dialog.backdrop, dialog.frame];\n }\n\n /** Opens the records behind a cell as a new tab, selected and holding the keyboard, or in the dialog, whose\n * Close holds it. */\n open(details: PivotShowDetailsEvent, view: PivotDetailsView, locale: string): void {\n const id = `${this.#idPrefix}-details-${++this.#sequence}`;\n // `changed` reaches whichever of the tab and the dialog shows the sheet once it is made.\n let shown: Records | undefined;\n const sheet = new DetailsSheet(id, details, locale, () => {\n if (shown !== undefined && this.#showing(shown)) {\n shown.draw();\n this.#host.changed();\n }\n });\n const { parts } = this.#host;\n if (view === 'dialog') {\n this.#closeDialogNow();\n const records = new Records(this.#host, sheet, () => { this.closeDialog(); }, () => { parts.focus(dialogClose); });\n shown = records;\n const dialog = this.#dialogOf(records);\n this.#dialog = dialog;\n // Its contents are drawn once its frame stands, so Close is there to take the keyboard. Until a Chrome's\n // Close is drawn, a round trip later on a circuit, the frame holds it: the report it covers is inert, and a\n // key typed meanwhile is then the pivot's, never the page's (ADR-0240 section 6, ADR-0410 section 5).\n this.#host.changed();\n this.#drawDialog(dialog);\n const root = dialog.frame.parentElement;\n if (root !== null && keyboardIsThePivots(root)) dialog.frame.focus();\n parts.focus(dialogClose);\n return;\n }\n const { tab, button } = this.#tab(id, () => {\n const pressed = standing();\n if (pressed !== undefined) this.#select(pressed);\n });\n const records = new Records(this.#host, sheet, undefined, () => { parts.focus(tabName(id)); });\n shown = records;\n const tabs = this.#tabs;\n // Pressed only while the tab stands: a closed tab leaves the page.\n const standing = (): Tab | undefined => tabs.find(t => t.records === records);\n const close = this.#closeButton(tab, () => {\n const closed = standing();\n if (closed !== undefined) this.#closeTab(closed);\n });\n button.textContent = details.title;\n button.setAttribute('aria-controls', `${id}-panel`);\n const panel = element(this.#host.document, 'div', 'ex-pivot-details-panel');\n panel.setAttribute('role', 'tabpanel');\n panel.id = `${id}-panel`;\n panel.setAttribute('aria-labelledby', id);\n panel.append(records.box);\n const made: Tab = { key: id, records, tab, button, close, panel };\n this.#tabs.push(made);\n this.#selected?.records.hide();\n this.#selected = made;\n this.#drawTabs();\n this.#host.changed();\n records.draw();\n // The records now cover the report, so the keyboard leaves it for the new tab: keys left in a report nobody\n // sees would move and copy what is not on screen.\n parts.focus(tabName(id));\n }\n\n /** Draws the words again and hands the records' grids the pivot's options again. */\n draw(): void {\n this.#drawTabs();\n this.#selected?.records.draw();\n const dialog = this.#dialog;\n if (dialog !== undefined) this.#drawDialog(dialog);\n }\n\n /** Closes the dialog: the report's grid takes the keyboard back (ADR-0070), however it closes. */\n closeDialog(): void {\n if (this.#dialog === undefined) return;\n this.#closeDialogNow();\n this.#host.changed();\n this.#host.returnKeyboard();\n }\n\n /** Closes every sheet: the pivot is gone. */\n destroy(): void {\n for (const tab of this.#tabs) tab.records.dispose();\n this.#tabs.length = 0;\n this.#selected = undefined;\n this.#tabsSlot.hide();\n this.#closeDialogNow();\n }\n\n // Whether the records are on screen: the dialog's, or the selected tab's.\n #showing(records: Records): boolean {\n return this.#dialog?.records === records || this.#selected?.records === records;\n }\n\n #tab(id: string, select: () => void): { readonly tab: HTMLElement; readonly button: HTMLButtonElement } {\n const { document } = this.#host;\n const tab = element(document, 'div', 'ex-pivot-tab');\n const button = element(document, 'button', 'ex-pivot-tab-button');\n button.type = 'button';\n button.id = id;\n button.setAttribute('role', 'tab');\n button.setAttribute('data-ex-claims', 'click');\n button.addEventListener('click', select);\n tab.append(button);\n return { tab, button };\n }\n\n // A details tab's \u00D7, after its button.\n #closeButton(tab: HTMLElement, close: () => void): HTMLButtonElement {\n const closing = element(this.#host.document, 'button', 'ex-pivot-tab-close');\n closing.type = 'button';\n closing.textContent = '\u00D7';\n closing.setAttribute('data-ex-claims', 'click');\n closing.addEventListener('click', close);\n tab.append(closing);\n return closing;\n }\n\n // The tab list: the built-in markup's, or a Chrome's in its place while a details tab stands, drawn from the same\n // view. The built-in markup's buttons are handed in again each time it stands, as a Chrome's are when it draws\n // them.\n #drawTabs(): void {\n const words = this.#host.words();\n const view = this.#tabsSlot.viewOf(Object.freeze({\n name: words.word('sheets'),\n tabs: Object.freeze([\n Object.freeze({ key: this.#reportButton.id, title: words.word('report-tab'), selected: this.#selected === undefined }),\n ...this.#tabs.map(tab => Object.freeze({\n key: tab.key,\n title: tab.records.sheet.details.title,\n selected: tab === this.#selected,\n panelId: tab.panel.id,\n closeLabel: words.fill('close-tab', tab.records.sheet.details.title),\n })),\n ]),\n }));\n const mount = this.#host.chrome()?.detailsTabs;\n const leaving = this.tabList;\n const held = leaving.contains(this.#host.document.activeElement);\n const slotted = mount !== undefined && this.#tabs.length > 0 && this.#answered(this.#tabsSlot.show(mount, (shared, input) => {\n const refs = this.#host.parts.refs();\n return {\n ...shared,\n select: input((key: string) => {\n if (key === this.#reportButton.id) {\n this.#select(undefined);\n return;\n }\n const pressed = this.#tabs.find(tab => tab.key === key);\n if (pressed !== undefined) this.#select(pressed);\n }),\n close: input((key: string) => {\n const closed = this.#tabs.find(tab => tab.key === key);\n if (closed !== undefined) this.#closeTab(closed);\n }),\n control: (key: string) => refs.control(tabName(checkedKey(key))),\n };\n }, id => words.word(id)));\n if (!slotted) this.#tabsSlot.hide();\n this.#tabsSlotted = slotted;\n if (leaving !== this.tabList) {\n swap(leaving, this.tabList);\n // The tab that held the keyboard went with the markup it stood in: the selected sheet's tab takes it.\n if (held) this.#host.parts.focus(tabName(this.#selected?.key ?? this.#reportButton.id));\n }\n // A Chrome's tab need not take the id the built-in one does, so the panel is named by its words.\n for (const tab of this.#tabs) {\n if (slotted) {\n tab.panel.removeAttribute('aria-labelledby');\n tab.panel.setAttribute('aria-label', tab.records.sheet.details.title);\n } else {\n tab.panel.removeAttribute('aria-label');\n tab.panel.setAttribute('aria-labelledby', tab.key);\n }\n }\n if (slotted) return;\n this.#builtInTabList.setAttribute('aria-label', view.name);\n this.#reportButton.textContent = words.word('report-tab');\n const all: readonly { readonly tab: HTMLElement; readonly button: HTMLButtonElement; readonly selected: boolean }[] = [\n { tab: this.#reportTab, button: this.#reportButton, selected: this.#selected === undefined },\n ...this.#tabs.map(tab => ({ tab: tab.tab, button: tab.button, selected: tab === this.#selected })),\n ];\n for (const { tab, button, selected } of all) {\n tab.className = selected ? 'ex-pivot-tab ex-pivot-tab-selected' : 'ex-pivot-tab';\n button.setAttribute('aria-selected', selected ? 'true' : 'false');\n this.#host.parts.handInControl(tabName(button.id), button);\n }\n for (const tab of this.#tabs) {\n const label = words.fill('close-tab', tab.records.sheet.details.title);\n tab.close.setAttribute('aria-label', label);\n tab.close.title = label;\n }\n const children = all.map(tab => tab.tab);\n const list = this.#builtInTabList;\n if (children.length !== list.children.length || children.some((child, i) => list.children[i] !== child)) {\n list.replaceChildren(...children);\n }\n }\n\n // Whether a slot's contents stand, as `answer` says; an error it answers is the pivot's to throw.\n #answered(answer: { readonly shown: boolean; readonly error?: Error }): boolean {\n if (answer.error !== undefined) this.#refused.push(answer.error);\n return answer.shown;\n }\n\n // A tab pressed: the report's (`undefined`), or a details tab that still stands.\n #select(tab: Tab | undefined): void {\n if (tab === this.#selected) return;\n this.#selected?.records.hide();\n this.#selected = tab;\n this.#drawTabs();\n this.#host.changed();\n tab?.records.draw();\n }\n\n #closeTab(tab: Tab): void {\n const at = this.#tabs.indexOf(tab);\n if (at < 0) return;\n this.#tabs.splice(at, 1);\n tab.records.dispose();\n this.#host.parts.forget(tabName(tab.key), tab.button);\n // Excel's next sheet: the one after the closed tab, or before it, or the report.\n const moved = this.#selected === tab;\n if (moved) this.#selected = this.#tabs[Math.min(at, this.#tabs.length - 1)];\n this.#drawTabs();\n this.#host.changed();\n const selected = this.#selected;\n // The close button that held the keyboard is gone: the selected tab takes it. The report's tab is its grid,\n // which takes the keyboard back (ADR-0070); there may be no tab left to hold it, the last one having closed.\n if (selected === undefined) {\n this.#host.returnKeyboard();\n return;\n }\n if (moved) selected.records.draw();\n this.#host.parts.focus(tabName(selected.key));\n }\n\n #dialogOf(records: Records): Dialog {\n const { document } = this.#host;\n const words = this.#host.words();\n const { title } = records.sheet.details;\n // Under the dialog, a press anywhere else closes it.\n const backdrop = element(document, 'div', 'ex-pivot-dialog-backdrop');\n backdrop.setAttribute('data-ex-claims', 'click');\n backdrop.setAttribute('aria-hidden', 'true');\n backdrop.addEventListener('click', () => { this.closeDialog(); });\n // A modal dialog named by the cell. It claims nothing, which makes it, holding the keyboard, the pivot's own\n // (ADR-0240 section 6). Escape closes it from anywhere inside it that hears the key: an Escape in the records'\n // grid never reaches it, the grid keeping every one, and the grid's way out closes it instead.\n const frame = element(document, 'div', 'ex-pivot-dialog');\n frame.setAttribute('role', 'dialog');\n frame.setAttribute('aria-modal', 'true');\n frame.setAttribute('aria-label', title);\n frame.tabIndex = -1;\n frame.setAttribute('data-ex-claims', '');\n frame.addEventListener('keydown', event => {\n if (event.key !== 'Escape' || event.defaultPrevented) return;\n event.preventDefault();\n this.closeDialog();\n });\n const content = element(document, 'div', 'ex-pivot-dialog-content');\n const heading = element(document, 'div', 'ex-pivot-dialog-title');\n heading.textContent = title;\n const recordsBox = element(document, 'div', 'ex-pivot-dialog-records');\n recordsBox.append(records.box);\n const actions = element(document, 'div', 'ex-pivot-panel-actions');\n const close = element(document, 'button', 'ex-pivot-close');\n close.type = 'button';\n close.textContent = words.word('close');\n close.setAttribute('data-ex-claims', 'click');\n close.addEventListener('click', () => { this.closeDialog(); });\n actions.append(close);\n content.append(heading, recordsBox, actions);\n return { records, backdrop, frame, content, heading, recordsBox, close, slotted: false };\n }\n\n // What stands inside the dialog's frame: a Chrome's contents while they are given and can be drawn, else the\n // built-in markup's. The records stand in the anchor the contents hand in, and are drawn once they land there;\n // Close takes the keyboard again where the markup that held it went.\n #drawDialog(dialog: Dialog): void {\n const words = this.#host.words();\n const { parts } = this.#host;\n const slot = this.#dialogSlot;\n const view = slot.viewOf(Object.freeze({ title: dialog.records.sheet.details.title, closeLabel: words.word('close') }));\n const mount = this.#host.chrome()?.detailsDialog;\n const { frame, content, recordsBox, records } = dialog;\n const held = frame.contains(this.#host.document.activeElement);\n // The slot stands in the frame as the contents mount, so plain script hands in Close already in the page.\n const trying = mount !== undefined && !slot.refuses(mount);\n if (trying && slot.element.parentNode !== frame) frame.replaceChildren(slot.element);\n const slotted = trying && this.#answered(slot.show(mount, (shared, input) => {\n const refs = parts.refs();\n return {\n ...shared,\n close: input(() => { this.closeDialog(); }),\n control: name => {\n checkedName(name, ['close'], 'detailsDialog');\n return refs.control(dialogClose);\n },\n anchor: name => {\n checkedName(name, ['records'], 'detailsDialog');\n return refs.anchor(dialogRecords);\n },\n };\n }, id => words.word(id)));\n const moved = slotted !== dialog.slotted;\n dialog.slotted = slotted;\n if (slotted) {\n if (moved) {\n parts.forget(dialogClose, dialog.close);\n records.standing = false;\n parts.place(dialogRecords, recordsBox, () => {\n records.standing = true;\n records.draw();\n });\n } else {\n records.draw();\n }\n } else {\n slot.hide();\n parts.place(dialogRecords, undefined);\n if (content.parentNode !== frame) frame.replaceChildren(content);\n if (recordsBox.parentNode !== content) dialog.heading.after(recordsBox);\n parts.handInControl(dialogClose, dialog.close);\n dialog.close.textContent = view.closeLabel;\n records.standing = true;\n records.draw();\n }\n if (moved && held) parts.focus(dialogClose);\n }\n\n #closeDialogNow(): void {\n const dialog = this.#dialog;\n if (dialog === undefined) return;\n this.#dialog = undefined;\n this.#dialogSlot.hide();\n this.#host.parts.unplace(dialog.recordsBox);\n // The anchor the records stood in goes with the contents, though their framework lets go of it only later.\n this.#host.parts.dropAnchor(dialogRecords);\n this.#host.parts.forget(dialogClose, dialog.close);\n dialog.records.dispose();\n dialog.backdrop.remove();\n dialog.frame.remove();\n }\n}\n\n// A tab's key, as a script may hand it to `control`.\nfunction checkedKey(key: string): string {\n const given: unknown = key;\n if (typeof given !== 'string' || given === '') throw new TypeError('An ExPivot\\'s sheet tabs hand in a tab\\'s control by the key its view gives it (ADR-0390).');\n return given;\n}\n", "// A placed field's menu (ADR-0061): the commands the Razor component's ExPivot.MenuFor builds, in its order and\n// under its ids, each enabled only where it would change something. Each says what it does as the next layout,\n// taken against the layout the menu was drawn from, as a gesture in the Field List does (spine rule 6), and where\n// the entry it was opened on stands in that layout, which the keyboard goes back to.\n//\n// Filter\u2026, Field Settings\u2026 and Value Field Settings\u2026 open a panel in the menu's place.\n\nimport {\n isValuesPseudoField, moveEntry, placementOf, placementsIn, removeEntry, setFieldCollapsed, setSort, valuesPseudoField, type PivotArea,\n type PivotEntry, type PivotField, type PivotLayout,\n} from '@ex-grid/pivot-engine';\nimport { fieldOf, type FieldListEdit } from './field-list';\nimport type { PivotMenuCommand } from './menu';\nimport { defined, elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** What a field's menu is drawn from. */\nexport interface EntryMenuModel {\n /** The pane's layout, which the menu's commands are taken against. */\n readonly layout: PivotLayout;\n /** The fields the source offers. */\n readonly fields: readonly PivotField[];\n /** The words. */\n readonly words: PivotScreenWords;\n}\n\n/** A command's change: the layout it makes, and where the entry its menu was opened on stands in that layout, or\n * `undefined` when its field left the Areas. */\nexport interface EntryMenuEdit extends FieldListEdit {\n readonly entry: PivotEntry | undefined;\n}\n\n/** A panel a field's menu opens. */\nexport type EntryPanel = 'filter-items' | 'field-settings' | 'value-field-settings';\n\n/** One command of a field's menu: what it is, and the change it makes when pressed, or the panel it opens. */\nexport interface EntryMenuCommand extends Omit<PivotMenuCommand, 'invoke'> {\n readonly does: { readonly edit: () => EntryMenuEdit } | { readonly panel: EntryPanel };\n}\n\n/** Where `field` stands in `layout`, for the keyboard to go back to: at `near`, the entry a menu was opened on, if it\n * still stands for the field, else in Values beside it, else in the axis or Filters Area it is placed in, else in\n * Values; \u03A3 Values (no field) on its axis while two Value Fields hold it there. `undefined` once it left the Areas. */\nexport function entryOfField(layout: PivotLayout, field: string | undefined, near: PivotEntry): PivotEntry | undefined {\n if (field === undefined) return layout.values.length >= 2 ? valuesPseudoField(layout.valuesAxis) : undefined;\n const inValues = layout.values.findIndex(value => value.field === field);\n if (near.area === 'values' && inValues >= 0) return layout.values[near.index]?.field === field ? near : { area: 'values', index: inValues };\n return placementOf(layout, field) ?? (inValues >= 0 ? { area: 'values', index: inValues } : undefined);\n}\n\n// Past an Area's last entry: a move there puts the entry last.\nconst end = Number.MAX_SAFE_INTEGER;\n\n/** The commands of the menu of `entry`. */\nexport function entryMenuCommands(model: EntryMenuModel, entry: PivotEntry): readonly EntryMenuCommand[] {\n const { layout, fields, words } = model;\n const commands: EntryMenuCommand[] = [];\n const add = (id: string, enabled: boolean, edit: () => EntryMenuEdit): void => {\n commands.push(Object.freeze({ id, label: words.word(id), enabled, does: Object.freeze({ edit }) }));\n };\n const opens = (panel: EntryPanel): void => {\n commands.push(Object.freeze({ id: panel, label: words.word(panel), enabled: true, does: Object.freeze({ panel }) }));\n };\n const edit = (next: PivotLayout, at: PivotEntry | undefined, moved?: { readonly field: string; readonly area: PivotArea }): EntryMenuEdit =>\n ({ layout: next, against: layout, moved, entry: at });\n\n if (isValuesPseudoField(entry)) {\n // \u03A3 Values moves between Rows and Columns only (ADR-0060).\n const onRows = layout.valuesAxis === 'rows';\n add('move-to-rows', !onRows, () => edit(moveEntry(layout, entry, 'rows', end, undefined), valuesPseudoField('rows')));\n add('move-to-columns', onRows, () => edit(moveEntry(layout, entry, 'columns', end, undefined), valuesPseudoField('columns')));\n return Object.freeze(commands);\n }\n\n const name = fieldOf(layout, entry);\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n const count = entry.area === 'values' ? layout.values.length : placementsIn(layout, entry.area).length;\n // Within its Area the entry lands where it was put; moved to another, it stands last there, where a field already\n // in that Area is moved to (moveEntry).\n const within = (index: number, at: number): EntryMenuEdit =>\n edit(moveEntry(layout, entry, entry.area, index, field), { area: entry.area, index: at }, { field: name, area: entry.area });\n const to = (area: PivotArea): EntryMenuEdit => {\n const next = moveEntry(layout, entry, area, end, field);\n const index = area === 'values' ? next.values.length - 1 : placementsIn(next, area).findIndex(placement => placement.field === name);\n return edit(next, { area, index }, { field: name, area });\n };\n add('move-up', entry.index > 0, () => within(entry.index - 1, entry.index - 1));\n add('move-down', entry.index < count - 1, () => within(entry.index + 2, entry.index + 1));\n add('move-to-beginning', entry.index > 0, () => within(0, 0));\n add('move-to-end', entry.index < count - 1, () => within(count, count - 1));\n add('move-to-filters', entry.area !== 'filters', () => to('filters'));\n add('move-to-rows', entry.area !== 'rows', () => to('rows'));\n add('move-to-columns', entry.area !== 'columns', () => to('columns'));\n add('move-to-values', entry.area !== 'values', () => to('values'));\n // Removed from one Area, a field may still stand in another: Values beside Rows.\n add('remove-field', true, () => {\n const next = removeEntry(layout, entry);\n return edit(next, entryOfField(next, name, entry));\n });\n if (entry.area === 'values') opens('value-field-settings');\n if (entry.area === 'filters') opens('filter-items');\n if (entry.area !== 'rows' && entry.area !== 'columns') return Object.freeze(commands);\n\n const placement = elementAt(placementsIn(layout, entry.area), entry.index);\n const bySort = (direction: 'ascending' | 'descending'): boolean => placement.sort.direction === direction && placement.sort.byValue === undefined;\n add('sort-ascending', !bySort('ascending'), () => edit(setSort(layout, name, { direction: 'ascending' }), entry));\n add('sort-descending', !bySort('descending'), () => edit(setSort(layout, name, { direction: 'descending' }), entry));\n opens('filter-items');\n // The innermost field has nothing under its Items to collapse (ADR-0060).\n const outer = entry.index < count - 1;\n const toggled = placement.toggledItems.length > 0;\n add('expand-field', outer && (placement.collapsed || toggled), () => edit(setFieldCollapsed(layout, name, false), entry));\n add('collapse-field', outer && (!placement.collapsed || toggled), () => edit(setFieldCollapsed(layout, name, true), entry));\n opens('field-settings');\n return Object.freeze(commands);\n}\n", "// The built-in Field List (ADR-0061): Excel's \"PivotTable Fields\" pane in plain markup, under the classes and\n// the Visual Tokens of ExPivot's stylesheet, which the Razor component draws too, so one stylesheet and one\n// layer 3 judge both (ADR-0350 section 4). It draws the layout it is handed and says what a gesture means as\n// the next layout, taken against the layout it was drawn from; whether that layout is still the pane's is\n// the pivot's to judge (spine rule 6).\n//\n// Beside each field it writes the field's count of Items where the source counted them, and while a field is\n// dragged it marks a target in Rows or Columns where the layout the drop would make passes the leaf cap\n// (ADR-0370 section 3). The mark is a hint from the counts, never a refusal: the drop is asked as any other.\n\nimport {\n formatPivotCount, isValuesPseudoField, moveEntry, pivotLeafBound, placeField, placementOf, placementsIn, placesField, removeEntry,\n tickField, untickField, valuesPseudoField, type PivotArea, type PivotEntry, type PivotField, type PivotItemCounts, type PivotLayout,\n} from '@ex-grid/pivot-engine';\nimport { element } from './dom';\nimport { defined, elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** The Areas in the order Excel's pane lays them out, two by two. */\nexport const areaOrder: readonly PivotArea[] = Object.freeze(['filters', 'columns', 'rows', 'values']);\n\n/** What a gesture in the pane moved into an Area, for the words of a refusal (ADR-0370 section 3). */\nexport interface FieldListMove {\n /** The field's name. */\n readonly field: string;\n /** The Area it was put in. */\n readonly area: PivotArea;\n}\n\n/** A gesture in the pane: the layout it makes, the layout it was taken against, and what it moved. */\nexport interface FieldListEdit {\n readonly layout: PivotLayout;\n readonly against: PivotLayout;\n readonly moved: FieldListMove | undefined;\n}\n\n/** What the pane draws. */\nexport interface FieldListModel {\n /** The pane's layout: the one last asked for, or the one the report shows. */\n readonly layout: PivotLayout;\n /** The fields the source offers. */\n readonly fields: readonly PivotField[];\n /** Each Value Field's caption under `layout`. */\n readonly valueCaptions: readonly string[];\n /** Each field's count of Items, where the source counted them. */\n readonly counts: PivotItemCounts | undefined;\n /** The most leaves a question may ask for. */\n readonly maxLeaves: number;\n /** The locale counts are written in. */\n readonly locale: string;\n /** The words. */\n readonly words: PivotScreenWords;\n /** Whether Defer Layout Update is ticked: the pane's changes build a pending layout, which Update applies. */\n readonly deferred: boolean;\n /** Whether Update would apply anything: the pending layout is not the report's. */\n readonly canUpdate: boolean;\n /** The field menu or panel open in the pane: the entry it was opened on, and its frame, which the pane places\n * under that entry. */\n readonly popup: { readonly entry: PivotEntry; readonly frame: HTMLElement } | undefined;\n}\n\n/** Whom the pane calls back. */\nexport interface FieldListHandlers {\n /** A gesture made a layout. */\n readonly edit: (edit: FieldListEdit) => void;\n /** The heading's close button was pressed. */\n readonly close: () => void;\n /** A drag started or ended: the report accepts a placed field dropped on it, which removes it. */\n readonly dragging: (removable: boolean) => void;\n /** An entry's button was pressed, which opens its menu or closes it (ADR-0061). */\n readonly menu: (entry: PivotEntry) => void;\n /** Defer Layout Update was ticked or unticked. */\n readonly defer: (deferred: boolean) => void;\n /** Update was pressed. */\n readonly update: () => void;\n}\n\n/** What is dragged: a field from the list, or an entry of an Area. */\nexport type DragSubject = { readonly kind: 'field'; readonly field: string } | { readonly kind: 'entry'; readonly entry: PivotEntry };\n\n/** A drag in the pane: what is dragged, and the layout it started on, which a drop is taken against. */\nexport interface Drag {\n readonly subject: DragSubject;\n readonly layout: PivotLayout;\n}\n\n/** Where a drop would land: an Area, and the index of the entry it goes before (the Area's count for its end). */\nexport interface DropAt {\n readonly area: PivotArea;\n readonly index: number;\n}\n\n// What a gesture in the pane means is decided here, once, for the built-in pane and a Chrome's alike (ADR-0390):\n// the layout a tick, a drop or a drag back to the list makes, which Area takes a drop, and when a drop's layout\n// passes the leaf cap.\n\n/** The edit a field's tick box makes: unticked out of the Areas, ticked into Rows, or a number into Values, as\n * Excel's does. */\nexport function tickEdit(layout: PivotLayout, field: PivotField): FieldListEdit {\n if (placesField(layout, field.name)) return { layout: untickField(layout, field.name), against: layout, moved: undefined };\n const next = tickField(layout, field);\n const at = placementOf(next, field.name);\n const inValues = next.values.some(value => value.field === field.name);\n const area = at !== undefined ? at.area : inValues ? 'values' : undefined;\n return { layout: next, against: layout, moved: area === undefined ? undefined : { field: field.name, area } };\n}\n\n/** Whether `area` takes a drop of `drag`: \u03A3 Values goes only to Rows or Columns. */\nexport function acceptsDrag(drag: Drag, area: PivotArea): boolean {\n return drag.subject.kind === 'field' || !isValuesPseudoField(drag.subject.entry) || area === 'rows' || area === 'columns';\n}\n\n/** Whether a drop of `drag` on the report or the list removes it: a placed field's entry. */\nexport function removesOnDrop(drag: Drag | undefined): boolean {\n return drag?.subject.kind === 'entry' && !isValuesPseudoField(drag.subject.entry);\n}\n\n/** The edit a drop of `drag` at `area` and `index` makes, and what it moved. */\nexport function dropEdit(drag: Drag, area: PivotArea, index: number, fields: readonly PivotField[]): FieldListEdit {\n const layout = drag.layout;\n if (drag.subject.kind === 'field') {\n const name = drag.subject.field;\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n return { layout: placeField(layout, field, area, index), against: layout, moved: { field: name, area } };\n }\n const { entry } = drag.subject;\n if (isValuesPseudoField(entry)) return { layout: moveEntry(layout, entry, area, index, undefined), against: layout, moved: undefined };\n const name = fieldOf(layout, entry);\n const field = defined(fields.find(f => f.name === name), `the field '${name}'`);\n return { layout: moveEntry(layout, entry, area, index, field), against: layout, moved: { field: name, area } };\n}\n\n/** The edit a drop of `drag` back on the list of fields makes: a placed field taken out; none for anything else. */\nexport function listDropEdit(drag: Drag | undefined): FieldListEdit | undefined {\n if (drag === undefined || !removesOnDrop(drag) || drag.subject.kind !== 'entry') return undefined;\n return { layout: removeEntry(drag.layout, drag.subject.entry), against: drag.layout, moved: undefined };\n}\n\n/** Whether a drop of `drag` at `at` makes a layout whose leaves the counts bound above the cap (ADR-0370 section 3):\n * a hint from the counts, never a refusal. */\nexport function dropOverCap(drag: Drag, at: DropAt, model: Pick<FieldListModel, 'counts' | 'maxLeaves' | 'fields'>): boolean {\n const { counts, maxLeaves } = model;\n if (counts === undefined || (at.area !== 'rows' && at.area !== 'columns') || !acceptsDrag(drag, at.area)) return false;\n const bound = pivotLeafBound(dropEdit(drag, at.area, at.index, model.fields).layout, counts);\n return bound !== undefined && bound > maxLeaves;\n}\n\n/** The data a drag carries for the browser: Firefox starts a drag only with data. The pivot reads what is dragged\n * from its own state, so a drop on another pivot carries nothing it takes (ADR-0061). */\nexport function startDragData(event: DragEvent, subject: DragSubject, layout: PivotLayout): void {\n if (event.dataTransfer === null) return;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', subject.kind === 'field' ? subject.field : fieldOrValues(layout, subject.entry));\n}\n\n/** The index past an Area's last entry: \u03A3 Values, which always stands last, is not counted. */\nexport function endOf(layout: PivotLayout, area: PivotArea): number {\n return area === 'values' ? layout.values.length : placementsIn(layout, area).length;\n}\n\n/** A field's item in the list, and the parts of it a redraw changes. */\ninterface FieldItem {\n readonly item: HTMLElement;\n readonly box: HTMLInputElement;\n readonly count: HTMLElement;\n readonly filtered: HTMLElement;\n}\n\n/** Text lowered for the search as the pivot's locale lowers it, never as the host's (ADR-0370 section 10). */\nexport function lowered(text: string, locale: string): string {\n return locale === 'invariant' ? text.toLowerCase() : text.toLocaleLowerCase(locale);\n}\n\ninterface AreaElements {\n readonly area: HTMLElement;\n readonly entries: HTMLElement;\n readonly cap: HTMLElement;\n}\n\n\n/** The field a placed entry stands for. */\nexport function fieldOf(layout: PivotLayout, entry: PivotEntry): string {\n return entry.area === 'values' ? elementAt(layout.values, entry.index).field : elementAt(placementsIn(layout, entry.area), entry.index).field;\n}\n\n/** Whether two entries name the same place: an Area and an index there, or \u03A3 Values on one axis. */\nexport function sameEntry(a: PivotEntry, b: PivotEntry): boolean {\n return a.area === b.area && a.index === b.index;\n}\n\n/** The Field List of one pivot, drawn into the element it is given. */\nexport class FieldListView {\n /** The pane, which stands in the element the view was given. */\n readonly element: HTMLElement;\n readonly #root: HTMLElement;\n readonly #handlers: FieldListHandlers;\n readonly #title: HTMLElement;\n readonly #close: HTMLButtonElement;\n readonly #chooseCaption: HTMLElement;\n readonly #search: HTMLInputElement;\n readonly #list: HTMLUListElement;\n readonly #dragCaption: HTMLElement;\n readonly #defer: HTMLInputElement;\n readonly #deferCaption: HTMLElement;\n readonly #update: HTMLButtonElement;\n readonly #areas = new Map<PivotArea, AreaElements>();\n readonly #areaBoxes = new Set<HTMLElement>();\n #model: FieldListModel | undefined;\n #searchText = '';\n #drag: Drag | undefined;\n #dropAt: DropAt | undefined;\n // The elements the drag paints, by what they stand for, so a drag repaints classes and never rebuilds the\n // element the browser is dragging.\n #fieldItems = new Map<string, FieldItem>();\n #fieldsDrawnFrom: readonly PivotField[] | undefined;\n #areasDrawnFrom: { readonly layout: PivotLayout; readonly words: PivotScreenWords; readonly captions: string; readonly fields: readonly PivotField[] } | undefined;\n #entryItems: { readonly entry: PivotEntry; readonly element: HTMLElement; readonly button: HTMLButtonElement; readonly index: number }[] = [];\n\n constructor(root: HTMLElement, handlers: FieldListHandlers) {\n this.#root = root;\n this.#handlers = handlers;\n const document = root.ownerDocument;\n const pane = element(document, 'div', 'ex-pivot-pane');\n const heading = element(document, 'div', 'ex-pivot-pane-heading');\n this.#title = element(document, 'div', 'ex-pivot-pane-title');\n this.#close = element(document, 'button', 'ex-pivot-pane-close');\n this.#close.type = 'button';\n const cross = element(document, 'span');\n cross.setAttribute('aria-hidden', 'true');\n cross.textContent = '\u00D7';\n this.#close.append(cross);\n this.#close.addEventListener('click', () => { this.#handlers.close(); });\n heading.append(this.#title, this.#close);\n const body = element(document, 'div', 'ex-pivot-pane-body');\n this.#chooseCaption = element(document, 'div', 'ex-pivot-pane-caption');\n this.#search = element(document, 'input', 'ex-pivot-search');\n this.#search.type = 'search';\n // The search only narrows the list: it claims nothing of the pivot's input (ADR-0240 section 6).\n this.#search.setAttribute('data-ex-claims', '');\n this.#search.addEventListener('input', () => {\n this.#searchText = this.#search.value;\n this.#drawFields();\n });\n this.#list = element(document, 'ul', 'ex-pivot-fields');\n this.#list.addEventListener('dragover', event => { this.#acceptDrop(event); });\n this.#list.addEventListener('drop', event => {\n event.preventDefault();\n this.#dropOnList();\n });\n this.#dragCaption = element(document, 'div', 'ex-pivot-pane-caption');\n const areas = element(document, 'div', 'ex-pivot-areas');\n for (const area of areaOrder) {\n const box = element(document, 'div', 'ex-pivot-area');\n box.setAttribute('data-ex-area', area);\n const title = element(document, 'div', 'ex-pivot-area-title');\n const cap = element(document, 'div', 'ex-pivot-area-cap');\n cap.setAttribute('role', 'status');\n const entries = element(document, 'div', 'ex-pivot-area-entries');\n entries.setAttribute('role', 'list');\n box.append(title, cap, entries);\n box.addEventListener('dragover', event => { this.#acceptDrop(event); });\n box.addEventListener('dragenter', () => { this.#dragOver(area, this.#endOf(area)); });\n box.addEventListener('drop', event => {\n event.preventDefault();\n this.#drop(area, this.#endOf(area));\n });\n this.#areas.set(area, { area: box, entries, cap });\n this.#areaBoxes.add(box);\n areas.append(box);\n }\n // Excel's Defer Layout Update at the pane's foot (ADR-0061): while it is ticked, the pane's changes build a\n // pending layout, and Update applies it in one change.\n const defer = element(document, 'div', 'ex-pivot-defer');\n const deferLabel = element(document, 'label', 'ex-pivot-defer-label');\n this.#defer = element(document, 'input');\n this.#defer.type = 'checkbox';\n this.#defer.setAttribute('data-ex-claims', 'click');\n this.#defer.addEventListener('change', () => { this.#handlers.defer(this.#defer.checked); });\n this.#deferCaption = element(document, 'span');\n deferLabel.append(this.#defer, this.#deferCaption);\n this.#update = element(document, 'button', 'ex-pivot-update');\n this.#update.type = 'button';\n this.#update.setAttribute('data-ex-claims', 'click');\n this.#update.addEventListener('click', () => { this.#handlers.update(); });\n defer.append(deferLabel, this.#update);\n body.append(this.#chooseCaption, this.#search, this.#list, this.#dragCaption, areas, defer);\n pane.append(heading, body);\n root.append(pane);\n this.element = pane;\n }\n\n /** Draws `model`. A drag in progress is dropped when the layout it started on is no longer the pane's. */\n draw(model: FieldListModel): void {\n this.#model = model;\n if (this.#drag !== undefined && this.#drag.layout !== model.layout) this.#endDrag();\n const { words } = model;\n const title = words.word('field-list');\n this.#title.textContent = title;\n this.#title.title = title;\n const hide = words.word('hide-field-list');\n this.#close.setAttribute('aria-label', hide);\n this.#close.title = hide;\n this.#chooseCaption.textContent = words.word('choose-fields');\n const search = words.word('search-fields');\n this.#search.placeholder = search;\n this.#search.setAttribute('aria-label', search);\n this.#list.setAttribute('aria-label', title);\n this.#dragCaption.textContent = words.word('drag-fields');\n this.#deferCaption.textContent = words.word('defer-layout-update');\n this.#defer.checked = model.deferred;\n this.#update.textContent = words.word('update');\n this.#update.disabled = !model.canUpdate;\n this.#drawFields();\n this.#drawAreas();\n this.#placeMenu();\n this.#paintDrag();\n }\n\n /** Gives the keyboard to the button of the entry drawn at `entry`. */\n focusEntry(entry: PivotEntry): void {\n const drawn = this.#entryItems.find(item => sameEntry(item.entry, entry));\n if (drawn === undefined) throw new Error(`Internal: no entry is drawn at ${entry.area} ${entry.index}.`);\n drawn.button.focus();\n }\n\n /** Gives the keyboard to the tick box of the field named `name`; to the search when the search hides that field,\n * or when no field is named. */\n focusField(name: string | undefined): void {\n const drawn = name === undefined ? undefined : this.#fieldItems.get(name);\n if (drawn?.item.isConnected === true) drawn.box.focus();\n else this.#search.focus();\n }\n\n /** Whether a placed field is being dragged, which a drop on the report removes. */\n get removable(): boolean {\n return removesOnDrop(this.#drag);\n }\n\n /** A drag entered `target`: unless it is in an Area, which hears its own entry first, no Area is the target. */\n dragEntered(target: EventTarget | null): void {\n // A drag over text enters the text itself in some browsers: its element is what it is in.\n const entered = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n const box = entered === null ? null : entered.closest('.ex-pivot-area');\n if (box instanceof HTMLElement && this.#areaBoxes.has(box)) return;\n this.leaveTargets();\n }\n\n /** The drag is over no Area of the pane now: none is marked as its target. */\n leaveTargets(): void {\n if (this.#dropAt === undefined) return;\n this.#dropAt = undefined;\n this.#paintDrag();\n }\n\n /** A drop on the report: a placed field dragged there is removed, as Excel removes it (ADR-0061). */\n dropOnReport(): void {\n this.#dropOnList();\n }\n\n get #current(): FieldListModel {\n return defined(this.#model, 'the Field List\\'s model');\n }\n\n #drawFields(): void {\n const model = this.#current;\n const search = lowered(this.#searchText, model.locale);\n if (this.#fieldsDrawnFrom !== model.fields) {\n this.#fieldItems = new Map();\n this.#fieldsDrawnFrom = model.fields;\n }\n const items = model.fields\n .filter(field => search === '' || lowered(field.caption, model.locale).includes(search))\n .map(field => {\n // Each field keeps its elements while the source's fields are the same, and a redraw changes what\n // they say in place: the item the browser is dragging stays in the page, and the tick box the\n // user just pressed keeps the keyboard.\n let drawn = this.#fieldItems.get(field.name);\n if (drawn === undefined) {\n drawn = this.#fieldItem(field);\n this.#fieldItems.set(field.name, drawn);\n }\n const { item, box, count, filtered } = drawn;\n box.checked = placesField(model.layout, field.name);\n const counted = model.counts?.countOf(field.name);\n if (counted === undefined) {\n count.remove();\n } else {\n const written = formatPivotCount(counted, model.locale);\n count.textContent = written;\n const said = model.words.fill('field-item-count', written);\n count.title = said;\n count.setAttribute('aria-label', said);\n if (count.parentNode !== item) item.insertBefore(count, filtered.parentNode === item ? filtered : null);\n }\n const at = placementOf(model.layout, field.name);\n if (at !== undefined && elementAt(placementsIn(model.layout, at.area), at.index).hiddenItems.length > 0) {\n const word = model.words.word('filtered');\n filtered.setAttribute('aria-label', word);\n filtered.title = word;\n if (filtered.parentNode !== item) item.append(filtered);\n } else {\n filtered.remove();\n }\n return item;\n });\n if (items.length !== this.#list.children.length || items.some((item, i) => this.#list.children[i] !== item)) {\n this.#list.replaceChildren(...items);\n }\n }\n\n #fieldItem(field: PivotField): FieldItem {\n const document = this.#root.ownerDocument;\n const item = element(document, 'li', 'ex-pivot-field');\n item.draggable = true;\n item.setAttribute('data-ex-field', field.name);\n const label = element(document, 'label', 'ex-pivot-field-label');\n const box = element(document, 'input');\n box.type = 'checkbox';\n box.setAttribute('data-ex-claims', 'click');\n box.addEventListener('change', () => { this.#tick(field); });\n const caption = element(document, 'span', 'ex-pivot-field-caption');\n caption.textContent = field.caption;\n label.append(box, caption);\n item.append(label);\n const filtered = element(document, 'span', 'ex-pivot-filtered-mark');\n filtered.setAttribute('role', 'img');\n item.addEventListener('dragstart', event => { this.#startDrag(event, { kind: 'field', field: field.name }); });\n item.addEventListener('dragend', () => { this.#endDrag(); });\n return { item, box, count: element(document, 'span', 'ex-pivot-field-count'), filtered };\n }\n\n #drawAreas(): void {\n const model = this.#current;\n const { layout, words } = model;\n // The entries are what the layout, the words and the captions make; drawn again only when one of them\n // changed, so a redraw while an entry is dragged keeps the element the browser is dragging.\n const drawnFrom = { layout, words, captions: model.valueCaptions.join('\\n'), fields: model.fields };\n const last = this.#areasDrawnFrom;\n if (last !== undefined && last.layout === layout && last.words === words && last.captions === drawnFrom.captions && last.fields === model.fields) return;\n this.#areasDrawnFrom = drawnFrom;\n const document = this.#root.ownerDocument;\n this.#entryItems = [];\n for (const area of areaOrder) {\n const { area: box, entries } = defined(this.#areas.get(area), 'an Area\\'s box');\n const title = words.area(area);\n elementAt([...box.children], 0).textContent = title;\n entries.setAttribute('aria-label', title);\n const drawn: HTMLElement[] = [];\n const end = this.#endOf(area);\n const add = (entry: PivotEntry, caption: string, filtered: boolean): void => {\n const index = isValuesPseudoField(entry) ? end : entry.index;\n const item = element(document, 'div', isValuesPseudoField(entry) ? 'ex-pivot-entry ex-pivot-entry-values' : 'ex-pivot-entry');\n item.setAttribute('role', 'listitem');\n item.draggable = true;\n const button = element(document, 'button', 'ex-pivot-entry-button');\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.setAttribute('aria-haspopup', 'menu');\n button.setAttribute('aria-label', words.fill('field-menu', caption));\n button.addEventListener('click', () => { this.#handlers.menu(entry); });\n const text = element(document, 'span', 'ex-pivot-entry-caption');\n text.textContent = caption;\n button.append(text);\n if (filtered) {\n const mark = element(document, 'span', 'ex-pivot-filtered-mark');\n mark.setAttribute('aria-hidden', 'true');\n button.append(mark);\n }\n const arrow = element(document, 'span', 'ex-pivot-entry-arrow');\n arrow.setAttribute('aria-hidden', 'true');\n arrow.textContent = '\u25BE';\n button.append(arrow);\n item.append(button);\n item.addEventListener('dragstart', event => { this.#startDrag(event, { kind: 'entry', entry }); });\n item.addEventListener('dragend', () => { this.#endDrag(); });\n item.addEventListener('dragenter', event => {\n event.stopPropagation();\n this.#dragOver(area, index);\n });\n item.addEventListener('dragover', event => { this.#acceptDrop(event); });\n item.addEventListener('drop', event => {\n event.preventDefault();\n event.stopPropagation();\n this.#drop(area, index);\n });\n this.#entryItems.push({ entry, element: item, button, index });\n drawn.push(item);\n };\n if (area === 'values') {\n layout.values.forEach((_, i) => { add({ area, index: i }, elementAt(model.valueCaptions, i), false); });\n } else {\n placementsIn(layout, area).forEach((placement, i) => {\n const field = model.fields.find(f => f.name === placement.field);\n add({ area, index: i }, defined(field, `the field '${placement.field}'`).caption, placement.hiddenItems.length > 0);\n });\n if (layout.values.length >= 2 && area === (layout.valuesAxis === 'rows' ? 'rows' : 'columns')) {\n add(valuesPseudoField(layout.valuesAxis), words.word('values-pseudo-field'), false);\n }\n }\n entries.replaceChildren(...drawn);\n }\n }\n\n // The open field menu stands under its entry, in the flow, as wide as the pane (ADR-0061); every other entry's\n // button says its menu is closed.\n #placeMenu(): void {\n const { popup: menu } = this.#current;\n for (const { entry, element: item, button } of this.#entryItems) {\n const open = menu !== undefined && sameEntry(menu.entry, entry);\n button.setAttribute('aria-expanded', open ? 'true' : 'false');\n // While a menu or a panel stands under the entry, a press that moves a little on it is a command's, or\n // selects text in a field, never a drag of the entry.\n item.draggable = !open;\n if (open && menu.frame.parentNode !== item) {\n // The entries were drawn again under it: the command that held the keyboard keeps it.\n const held = item.ownerDocument.activeElement;\n item.append(menu.frame);\n if (held instanceof HTMLElement && menu.frame.contains(held) && held !== item.ownerDocument.activeElement) held.focus();\n }\n }\n }\n\n // The index past an Area's last entry: \u03A3 Values, which always stands last, is not counted.\n #endOf(area: PivotArea): number {\n return endOf(this.#current.layout, area);\n }\n\n #tick(field: PivotField): void {\n this.#handlers.edit(tickEdit(this.#current.layout, field));\n }\n\n #startDrag(event: DragEvent, subject: DragSubject): void {\n const layout = this.#current.layout;\n this.#drag = { subject, layout };\n this.#dropAt = undefined;\n startDragData(event, subject, layout);\n this.#paintDrag();\n this.#handlers.dragging(this.removable);\n }\n\n #endDrag(): void {\n if (this.#drag === undefined && this.#dropAt === undefined) return;\n this.#drag = undefined;\n this.#dropAt = undefined;\n this.#paintDrag();\n this.#handlers.dragging(false);\n }\n\n #accepts(area: PivotArea): boolean {\n return this.#drag !== undefined && acceptsDrag(this.#drag, area);\n }\n\n #acceptDrop(event: DragEvent): void {\n if (this.#drag === undefined) return;\n event.preventDefault();\n if (event.dataTransfer !== null) event.dataTransfer.dropEffect = 'move';\n }\n\n #dragOver(area: PivotArea, index: number): void {\n if (this.#drag === undefined) return;\n if (this.#dropAt?.area === area && this.#dropAt.index === index) return;\n this.#dropAt = { area, index };\n this.#paintDrag();\n }\n\n #drop(area: PivotArea, index: number): void {\n const drag = this.#drag;\n this.#endDrag();\n if (drag === undefined || !acceptsDrag(drag, area)) return;\n this.#handlers.edit(dropEdit(drag, area, index, this.#current.fields));\n }\n\n #dropOnList(): void {\n const drag = this.#drag;\n this.#endDrag();\n const edit = listDropEdit(drag);\n if (edit !== undefined) this.#handlers.edit(edit);\n }\n\n // The drag's marks, as classes on the elements drawn: never a rebuild, which would take away the element\n // the browser is dragging.\n #paintDrag(): void {\n const drag = this.#drag;\n const at = this.#dropAt;\n const model = this.#model;\n for (const [name, { item }] of this.#fieldItems) {\n item.classList.toggle('ex-pivot-dragging', drag?.subject.kind === 'field' && drag.subject.field === name);\n }\n for (const { entry, element: item, index } of this.#entryItems) {\n const dragged = drag?.subject.kind === 'entry' && sameEntry(drag.subject.entry, entry);\n item.classList.toggle('ex-pivot-dragging', dragged);\n item.classList.toggle('ex-pivot-drop-before', at !== undefined && this.#accepts(at.area) && at.area === entry.area && at.index === index);\n }\n const over = drag !== undefined && at !== undefined && model !== undefined && dropOverCap(drag, at, model);\n for (const [area, { area: box, cap }] of this.#areas) {\n const target = at !== undefined && at.area === area && this.#accepts(area);\n box.classList.toggle('ex-pivot-drop-target', target);\n box.classList.toggle('ex-pivot-drop-over-cap', target && over);\n const said = target && over ? model.words.fill('drop-over-cap', formatPivotCount(model.maxLeaves, model.locale)) : '';\n if (cap.textContent !== said) cap.textContent = said;\n }\n this.#list.classList.toggle('ex-pivot-drop-remove', this.removable);\n }\n}\n\nfunction fieldOrValues(layout: PivotLayout, entry: PivotEntry): string {\n return isValuesPseudoField(entry) ? 'values' : fieldOf(layout, entry);\n}\n", "// The Field List a Chrome's slot draws (ADR-0061, ADR-0390): Excel's PivotTable Fields pane, drawn from the view the\n// pivot makes of the layout it is handed. What each gesture means is the built-in pane's rules (`field-list.ts`),\n// so the layout a tick, a drop or a drag back makes is the same whichever draws the pane; whether that layout is\n// still the pane's is the pivot's to judge (spine rule 6). The contents hand in their controls, the anchors under\n// the entries and the Areas' boxes; the pivot places an entry's menu or panel in its anchor and gives the keyboard to\n// the control it means.\n\nimport { formatPivotCount, isValuesPseudoField, placementOf, placementsIn, placesField, valuesPseudoField, type PivotArea, type PivotEntry } from '@ex-grid/pivot-engine';\nimport type {\n PivotChromeSlot, PivotDragSubject, PivotFieldListAreaView, PivotFieldListEntryView, PivotFieldListFieldView, PivotFieldListSlotContext, PivotFieldListView,\n PivotPartRef, PivotStandingSlotContext,\n} from './chrome';\nimport { StandingSlot } from './chrome';\nimport {\n acceptsDrag, areaOrder, dropEdit, dropOverCap, endOf, listDropEdit, lowered, removesOnDrop, sameEntry, startDragData, tickEdit, type Drag, type DropAt,\n type FieldListHandlers, type FieldListModel,\n} from './field-list';\nimport { defined, elementAt } from './must';\nimport { cachedRef, elementRef, type PartElements } from './parts';\n\n/** The name an entry's button and the anchor around it are handed in by. */\nexport function entryKey(entry: PivotEntry): string {\n return `entry:${entry.area}:${entry.index}`;\n}\n\n/** The name a field's tick box is handed in by. */\nexport function fieldKey(field: string): string {\n return `field:${field}`;\n}\n\nconst emptyView: PivotFieldListView = Object.freeze({\n title: '', hideLabel: '', chooseCaption: '', searchLabel: '', search: '', fields: Object.freeze([]), dragCaption: '', areas: Object.freeze([]),\n dropRemoves: false, defer: Object.freeze({ label: '', ticked: false }), update: Object.freeze({ label: '', enabled: false }),\n});\n\n/** The Field List of one pivot, drawn by a Chrome's slot. */\nexport class SlottedFieldList {\n readonly #slot: StandingSlot<PivotFieldListView, PivotFieldListSlotContext>;\n readonly #handlers: FieldListHandlers;\n readonly #parts: PartElements;\n readonly #areaBoxes = new Map<PivotArea, HTMLElement>();\n #model: FieldListModel | undefined;\n #searchText = '';\n #drag: Drag | undefined;\n #dropAt: DropAt | undefined;\n\n constructor(document: Document, handlers: FieldListHandlers, parts: PartElements) {\n this.#slot = new StandingSlot('fieldList', document, emptyView);\n // The slot draws nothing (`display: contents`): the contents' pane takes the Field List's height as its own.\n this.#slot.element.setAttribute('style', 'display: contents');\n this.#handlers = handlers;\n this.#parts = parts;\n }\n\n /** The slot, which the pivot stands in the pane's place. */\n get element(): HTMLElement {\n return this.#slot.element;\n }\n\n /** Shows the pane by `mount`; answers as the slot does. */\n show(mount: PivotChromeSlot<PivotFieldListSlotContext>, label: (id: string) => string): { readonly shown: boolean; readonly error?: Error } {\n // A drag the contents before these started reaches nothing once they are gone: no dragend is heard from them.\n if (!this.#slot.stands(mount)) {\n this.#drag = undefined;\n this.#dropAt = undefined;\n }\n return this.#slot.show(mount, (shared, input) => this.#context(shared, input), label);\n }\n\n // The context of one mount of the contents, whose controls, anchors and Areas' boxes are handed in by refs of\n // its own.\n #context(shared: PivotStandingSlotContext<PivotFieldListView>, input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void): PivotFieldListSlotContext {\n const refs = this.#parts.refs();\n const areas = new Map<PivotArea, PivotPartRef>();\n return {\n ...shared,\n setSearch: input((text: string) => {\n if (typeof text !== 'string') throw new TypeError('An ExPivot\\'s Field List takes the search as typed, a string (ADR-0390).');\n this.#searchText = text;\n this.#tell();\n }),\n toggle: input((field: string) => {\n const model = this.#current;\n const declared = model.fields.find(f => f.name === field);\n if (declared === undefined) throw new RangeError(`The Field List has no field '${field}' to tick (ADR-0390).`);\n this.#handlers.edit(tickEdit(model.layout, declared));\n }),\n openMenu: input((entry: PivotEntry) => { if (this.#stands(entry)) this.#handlers.menu(entry); }),\n close: input(() => { this.#handlers.close(); }),\n startDrag: input((event: DragEvent, subject: PivotDragSubject) => { this.#startDrag(event, subject); }),\n dragOver: input((event: DragEvent) => {\n if (this.#drag === undefined) return;\n event.preventDefault();\n if (event.dataTransfer !== null) event.dataTransfer.dropEffect = 'move';\n }),\n dragEnter: input((area: PivotArea, index: number) => {\n if (this.#drag === undefined || (this.#dropAt?.area === area && this.#dropAt.index === index)) return;\n this.#dropAt = { area: checkedArea(area), index: checkedIndex(index) };\n this.#tell();\n }),\n drop: input((event: DragEvent, area: PivotArea, index: number) => {\n event.preventDefault();\n const drag = this.#drag;\n this.#endDrag();\n if (drag === undefined || !acceptsDrag(drag, checkedArea(area))) return;\n this.#handlers.edit(dropEdit(drag, area, checkedIndex(index), this.#current.fields));\n }),\n dropOnList: input((event: DragEvent) => {\n event.preventDefault();\n this.dropOnReport();\n }),\n endDrag: input(() => { this.#endDrag(); }),\n setDeferred: input((deferred: boolean) => {\n if (typeof deferred !== 'boolean') throw new TypeError('Defer Layout Update is handed whether it is ticked (ADR-0390).');\n this.#handlers.defer(deferred);\n }),\n update: input(() => { if (this.#slot.view.update.enabled) this.#handlers.update(); }),\n control: (key: string) => refs.control(checkedKey(key)),\n anchor: (key: string) => refs.anchor(checkedKey(key)),\n area: (area: PivotArea) => cachedRef(areas, checkedArea(area), () => elementRef(this.#areaBoxes, area, `An ExPivot's Field List's box of '${area}'`)),\n };\n }\n\n /** The pane is the built-in one's, or gone: the contents are taken away, and a drag they started with them. */\n hide(): void {\n this.#slot.hide();\n this.#drag = undefined;\n this.#dropAt = undefined;\n }\n\n /** Draws `model`. A drag in progress is dropped when the layout it started on is no longer the pane's. */\n draw(model: FieldListModel): void {\n this.#model = model;\n if (this.#drag !== undefined && this.#drag.layout !== model.layout) this.#endDrag();\n if (model.popup !== undefined) this.#parts.place(entryKey(model.popup.entry), model.popup.frame);\n this.#tell();\n }\n\n /** Gives the keyboard to the button of the entry drawn at `entry`. */\n focusEntry(entry: PivotEntry): void {\n this.#parts.focus(entryKey(entry));\n }\n\n /** Gives the keyboard to the tick box of the field named `name`; to the search when the search hides that field,\n * or when no field is named. */\n focusField(name: string | undefined): void {\n const shown = name !== undefined && this.#slot.view.fields.some(field => field.name === name);\n this.#parts.focus(shown ? fieldKey(name) : 'search');\n }\n\n /** Whether a placed field is being dragged, which a drop on the report removes. */\n get removable(): boolean {\n return removesOnDrop(this.#drag);\n }\n\n /** A drag entered `target`: unless it is in an Area, which hears its own entry first, no Area is the target. */\n dragEntered(target: EventTarget | null): void {\n const entered = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n for (const box of this.#areaBoxes.values()) {\n if (entered !== null && box.contains(entered)) return;\n }\n this.leaveTargets();\n }\n\n /** The drag is over no Area of the pane now: none is marked as its target. */\n leaveTargets(): void {\n if (this.#dropAt === undefined) return;\n this.#dropAt = undefined;\n this.#tell();\n }\n\n /** A drop on the report, or on the list of fields: a placed field dragged there is removed, as Excel removes it. */\n dropOnReport(): void {\n const drag = this.#drag;\n this.#endDrag();\n const edit = listDropEdit(drag);\n if (edit !== undefined) this.#handlers.edit(edit);\n }\n\n get #current(): FieldListModel {\n return defined(this.#model, 'the Field List\\'s model');\n }\n\n // Whether `entry` stands in the pane's layout now: a press on an entry the pane has since left asks nothing.\n #stands(entry: PivotEntry): boolean {\n const layout = this.#current.layout;\n if (isValuesPseudoField(entry)) return layout.values.length >= 2 && sameEntry(entry, valuesPseudoField(layout.valuesAxis));\n return entry.index >= 0 && entry.index < endOf(layout, entry.area);\n }\n\n #startDrag(event: DragEvent, subject: PivotDragSubject): void {\n const layout = this.#current.layout;\n const drag: Drag = 'field' in subject\n ? { subject: { kind: 'field', field: subject.field }, layout }\n : { subject: { kind: 'entry', entry: subject.entry }, layout };\n if (drag.subject.kind === 'entry' && !this.#stands(drag.subject.entry)) return;\n this.#drag = drag;\n this.#dropAt = undefined;\n startDragData(event, drag.subject, layout);\n this.#tell();\n this.#handlers.dragging(this.removable);\n }\n\n #endDrag(): void {\n if (this.#drag === undefined && this.#dropAt === undefined) return;\n this.#drag = undefined;\n this.#dropAt = undefined;\n this.#tell();\n this.#handlers.dragging(false);\n }\n\n #tell(): void {\n if (this.#model !== undefined) this.#slot.viewOf(this.#view(this.#model));\n }\n\n #view(model: FieldListModel): PivotFieldListView {\n const { layout, words, locale } = model;\n const drag = this.#drag;\n const at = this.#dropAt;\n const search = lowered(this.#searchText, locale);\n const fields = model.fields\n .filter(field => search === '' || lowered(field.caption, locale).includes(search))\n .map((field): PivotFieldListFieldView => {\n const counted = model.counts?.countOf(field.name);\n const written = counted === undefined ? undefined : formatPivotCount(counted, locale);\n const placed = placementOf(layout, field.name);\n return Object.freeze({\n name: field.name,\n caption: field.caption,\n key: fieldKey(field.name),\n placed: placesField(layout, field.name),\n filtered: placed !== undefined && elementAt(placementsIn(layout, placed.area), placed.index).hiddenItems.length > 0,\n ...(written === undefined ? {} : { count: written, countLabel: words.fill('field-item-count', written) }),\n dragging: drag?.subject.kind === 'field' && drag.subject.field === field.name,\n });\n });\n const over = drag !== undefined && at !== undefined && dropOverCap(drag, at, model);\n const areas = areaOrder.map((area): PivotFieldListAreaView => {\n const target = drag !== undefined && at !== undefined && at.area === area && acceptsDrag(drag, area);\n return Object.freeze({\n area,\n title: words.area(area),\n entries: Object.freeze(this.#entries(model, area)),\n end: endOf(layout, area),\n dropTarget: target,\n ...(target && over ? { overCap: words.fill('drop-over-cap', formatPivotCount(model.maxLeaves, locale)) } : {}),\n });\n });\n return Object.freeze({\n title: words.word('field-list'),\n hideLabel: words.word('hide-field-list'),\n chooseCaption: words.word('choose-fields'),\n searchLabel: words.word('search-fields'),\n search: this.#searchText,\n fields: Object.freeze(fields),\n dragCaption: words.word('drag-fields'),\n areas: Object.freeze(areas),\n dropRemoves: this.removable,\n defer: Object.freeze({ label: words.word('defer-layout-update'), ticked: model.deferred }),\n update: Object.freeze({ label: words.word('update'), enabled: model.canUpdate }),\n });\n }\n\n #entries(model: FieldListModel, area: PivotArea): PivotFieldListEntryView[] {\n const { layout, words, popup } = model;\n const drag = this.#drag;\n const at = this.#dropAt;\n const end = endOf(layout, area);\n const entry = (placed: PivotEntry, caption: string, filtered: boolean): PivotFieldListEntryView => {\n const index = isValuesPseudoField(placed) ? end : placed.index;\n return Object.freeze({\n entry: placed,\n key: entryKey(placed),\n caption,\n menuLabel: words.fill('field-menu', caption),\n filtered,\n values: isValuesPseudoField(placed),\n menuOpen: popup !== undefined && sameEntry(popup.entry, placed),\n dragging: drag?.subject.kind === 'entry' && sameEntry(drag.subject.entry, placed),\n dropBefore: drag !== undefined && at !== undefined && acceptsDrag(drag, at.area) && at.area === area && at.index === index,\n dropIndex: index,\n });\n };\n if (area === 'values') return layout.values.map((_, i) => entry({ area, index: i }, elementAt(model.valueCaptions, i), false));\n const entries = placementsIn(layout, area).map((placement, i) => {\n const field = defined(model.fields.find(f => f.name === placement.field), `the field '${placement.field}'`);\n return entry({ area, index: i }, field.caption, placement.hiddenItems.length > 0);\n });\n if (layout.values.length >= 2 && area === (layout.valuesAxis === 'rows' ? 'rows' : 'columns')) {\n entries.push(entry(valuesPseudoField(layout.valuesAxis), words.word('values-pseudo-field'), false));\n }\n return entries;\n }\n}\n\n// An Area, as a script may hand it.\nfunction checkedArea(area: PivotArea): PivotArea {\n if (!areaOrder.includes(area)) throw new RangeError(`An ExPivot's Field List has the Areas ${areaOrder.join(', ')}, not '${area}' (ADR-0390).`);\n return area;\n}\n\n// An index a drop lands before, as a script may hand it: a whole number, zero or more.\nfunction checkedIndex(index: number): number {\n if (!Number.isInteger(index) || index < 0) throw new RangeError(`A drop in an ExPivot's Field List lands before an entry's index, a whole number from 0, not ${index} (ADR-0390).`);\n return index;\n}\n\n// A name a control or an anchor is handed in by, as a script may hand it.\nfunction checkedKey(key: string): string {\n const given: unknown = key;\n if (typeof given !== 'string' || given === '') throw new TypeError('An ExPivot\\'s Field List hands in a control or an anchor by the name its view gives it (ADR-0390).');\n return given;\n}\n", "// Filter\u2026 (ADR-0061): a field's Items, each ticked while shown, (Select All), a search that narrows the list, and\n// OK / Cancel, in the markup and under the classes the Razor component's PivotItemFilterView draws, so one stylesheet\n// paints both (ADR-0350 section 4). The ticks are the panel's draft. The Items are the source's, listed under the\n// report's Source Version (ADR-0066); while a first listing is on its way the panel says so, and when the source\n// cannot list them it says why, never an empty list in its place. While a new version's Items are on their way, the\n// earlier version's stay listed and the list is marked busy: Hidden Items are keys, which name the same Items under\n// any version, so ticking and applying against them is safe (ADR-0066 refined).\n//\n// The search narrows the Items held, as the pivot's locale lowers text; past the Items Filter\u2026 holds, only the\n// source can answer it, and the answer to a search typed since is dropped.\n\nimport {\n formatPivotCount, pivotItemKeyId, placementOf, placementsIn, refusalWord, setHiddenItems, type PivotItemInfo, type PivotItemKey, type PivotLayout,\n type PivotReportItemsResult,\n} from '@ex-grid/pivot-engine';\nimport { lowered } from './field-list';\nimport { itemListCap, type FieldItems, type ItemsProblem } from './items';\nimport { ViewListeners, type PivotChromeSlot, type PivotItemFilterSlotContext, type PivotItemFilterView } from './chrome';\nimport { popupFrame, type PivotMenuPlace } from './menu';\nimport { defined, elementAt } from './must';\nimport { actions, element, slottedPanel, type PanelDraft, type PanelHandlers, type PivotPanel } from './panels';\nimport type { PivotScreenWords } from './words';\n\n/** What Filter\u2026 is opened on. */\nexport interface ItemFilterModel {\n /** The layout OK's change is taken against. */\n readonly layout: PivotLayout;\n readonly field: string;\n readonly caption: string;\n /** Where it stands: under the field's entry in the Field List, or under its button in the report filter band. */\n readonly place: PivotMenuPlace;\n /** The locale the search lowers text in, and the count in the note is written in. */\n readonly locale: string;\n readonly words: PivotScreenWords;\n}\n\n/** Whom Filter\u2026 calls back: OK and Cancel, the field's Items, and the source's search past the Items held. */\nexport interface ItemFilterHandlers extends PanelHandlers {\n /** The field's Items as they stand now: the same object while they have not changed. */\n readonly items: () => FieldItems;\n /** The Items matching `search`, asked of the source under the report on screen. */\n readonly search: (search: string, signal: AbortSignal) => Promise<PivotReportItemsResult>;\n}\n\n/** What the source answered for a search: the Items, why it could not, or nothing yet. */\ntype Found = { readonly listed: PivotReportItemsResult } | { readonly problem: ItemsProblem } | 'asked';\n\ninterface Search {\n readonly text: string;\n // The listing it searched past, so a newer listing searches again.\n readonly under: FieldItems['listed'];\n readonly controller: AbortController;\n found: Found;\n}\n\ninterface DrawnItem {\n readonly row: HTMLLabelElement;\n readonly box: HTMLInputElement;\n readonly text: HTMLSpanElement;\n}\n\n/** The sentence for a source's refusal or failure to list Items, as the Razor component's ProblemText says it. */\nexport function itemsProblemText(problem: ItemsProblem, words: PivotScreenWords): string {\n if ('error' in problem) return words.failed(problem.error);\n return words.reportRefused(problem.refusal);\n}\n\n/** Filter\u2026' draft: the ticks and the search, and the source's answer to a search past the Items held. It is drawn\n * again by the pivot as the field's Items land, and by the built-in markup and a Chrome's slot alike. */\nexport class ItemFilterDraft implements PanelDraft<PivotItemFilterView> {\n readonly listeners = new ViewListeners();\n readonly #model: ItemFilterModel;\n readonly #handlers: ItemFilterHandlers;\n // The draft: the Items unticked, by key id.\n readonly #hidden = new Map<string, PivotItemKey>();\n #text = '';\n #items: FieldItems;\n #search: Search | undefined;\n #refusal: string | undefined;\n #closed = false;\n // What a press of (Select All) or OK acts on: the Items listed now, and those held.\n #listed: readonly PivotItemInfo[] = [];\n #held: readonly PivotItemInfo[] = [];\n // Each Item's key id and lowered label, worked out once while its listing is in view: a draw on every key typed\n // and every tick reads them for every Item.\n readonly #ids = new WeakMap<PivotItemInfo, string>();\n readonly #labels = new WeakMap<PivotItemInfo, string>();\n #allHeld = true;\n #view: PivotItemFilterView;\n\n constructor(model: ItemFilterModel, handlers: ItemFilterHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n for (const key of placementHidden(model.layout, model.field)) this.#hidden.set(pivotItemKeyId(key), key);\n this.#items = handlers.items();\n this.#view = this.#compute();\n }\n\n get view(): PivotItemFilterView {\n return this.#view;\n }\n\n /** Each listed Item's key id, by its place in the view's `items`. */\n idAt(index: number): string {\n return this.#idOf(elementAt(this.#listed, index));\n }\n\n setSearch(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setSearch is handed the search as typed.');\n this.#text = text;\n this.#refusal = undefined;\n this.#render();\n }\n\n setTicked(key: PivotItemKey, ticked: boolean): void {\n if (typeof ticked !== 'boolean') throw new TypeError('setTicked is handed the Item and whether it is ticked.');\n const id = pivotItemKeyId(key);\n // Only an Item the panel lists now is ticked: a press on one a newer listing took away names nothing the user\n // sees, and changes nothing (spine rule 6).\n if (!this.#listed.some(item => this.#idOf(item) === id)) return;\n this.#tick(key, ticked);\n this.#refusal = undefined;\n this.#render();\n }\n\n setAll(ticked: boolean): void {\n if (typeof ticked !== 'boolean') throw new TypeError('setAll is handed whether every Item listed is ticked.');\n for (const item of this.#listed) this.#tick(item.key, ticked);\n this.#refusal = undefined;\n this.#render();\n }\n\n /** Draws the field's Items again, when they have changed. */\n redraw(): void {\n const items = this.#handlers.items();\n if (items === this.#items) return;\n this.#items = items;\n this.#render();\n }\n\n /** Stops a search on its way: the panel has closed. */\n close(): void {\n this.#closed = true;\n this.#search?.controller.abort();\n this.#search = undefined;\n this.listeners.clear();\n }\n\n apply(): void {\n if (!this.#view.canApply) return;\n const { layout, field, words } = this.#model;\n // With more Items than Filter\u2026 holds, that every one is unticked cannot be told, and nothing is refused for\n // it: the rule needs every Item (ADR-0060).\n const result = setHiddenItems(layout, field, this.#hidden.values(), this.#allHeld ? this.#held.map(item => item.key) : []);\n if (result.refusal !== undefined) {\n this.#refusal = words.word(refusalWord(result.refusal));\n this.#render();\n return;\n }\n const before = new Set(placementHidden(layout, field).map(key => pivotItemKeyId(key)));\n const after = placementHidden(result.layout, field).map(key => pivotItemKeyId(key));\n if (after.length === before.size && after.every(id => before.has(id))) {\n this.#handlers.cancel();\n return;\n }\n this.#handlers.apply(result.layout);\n }\n\n #idOf(item: PivotItemInfo): string {\n let id = this.#ids.get(item);\n if (id === undefined) {\n id = pivotItemKeyId(item.key);\n this.#ids.set(item, id);\n }\n return id;\n }\n\n #loweredLabel(item: PivotItemInfo): string {\n let label = this.#labels.get(item);\n if (label === undefined) {\n label = lowered(item.label, this.#model.locale);\n this.#labels.set(item, label);\n }\n return label;\n }\n\n #tick(key: PivotItemKey, tick: boolean): void {\n const id = pivotItemKeyId(key);\n if (tick) this.#hidden.delete(id);\n else this.#hidden.set(id, key);\n }\n\n // The source's answer for the search typed, past the Items held; asked again for a newer listing.\n #found(text: string, under: FieldItems['listed']): Found {\n const search = this.#search;\n if (search?.text === text && search.under === under) return search.found;\n search?.controller.abort();\n const asked: Search = { text, under, controller: new AbortController(), found: 'asked' };\n this.#search = asked;\n void this.#ask(asked);\n return asked.found;\n }\n\n async #ask(asked: Search): Promise<void> {\n let listed;\n try {\n listed = await this.#handlers.search(asked.text, asked.controller.signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a search typed over, or of a panel closed, is nobody's; the current one's failure is said in the panel and rethrown\n if (this.#search !== asked) return;\n asked.found = Object.freeze({ problem: Object.freeze({ error }) });\n this.#render();\n throw error;\n }\n if (this.#search !== asked) return;\n asked.found = Object.freeze(listed.refusal === undefined ? { listed } : { problem: Object.freeze({ refusal: listed.refusal }) });\n this.#render();\n }\n\n #render(): void {\n if (this.#closed) return;\n this.#view = this.#compute();\n this.listeners.tell();\n }\n\n #compute(): PivotItemFilterView {\n const { words, locale } = this.#model;\n const items = this.#items;\n const text = this.#text;\n let loading = items.listed === undefined && items.problem === undefined;\n let problem = items.problem;\n let matches: readonly PivotItemInfo[] = [];\n let matchCount = 0;\n const page = items.listed;\n this.#allHeld = page === undefined || page.total <= page.items.length;\n if (page !== undefined && !this.#allHeld && text !== '') {\n // More Items than Filter\u2026 holds: the search is the source's to answer.\n const found = this.#found(text, page);\n if (found === 'asked') loading = true;\n else if ('problem' in found) problem = found.problem;\n else {\n matches = found.listed.items;\n matchCount = found.listed.total;\n }\n } else if (page !== undefined) {\n this.#search?.controller.abort();\n this.#search = undefined;\n const search = lowered(text, locale);\n matches = search === '' ? page.items : page.items.filter(item => this.#loweredLabel(item).includes(search));\n matchCount = search === '' ? page.total : matches.length;\n }\n const listed = matches.slice(0, itemListCap);\n this.#listed = listed;\n // The Items in view, an earlier version's while the report's are on their way (ADR-0066 refined).\n this.#held = page === undefined ? [] : page.items;\n const unavailable = problem === undefined ? undefined : itemsProblemText(problem, words);\n const canApply = !loading && unavailable === undefined\n && (!this.#allHeld || this.#held.length === 0 || this.#held.some(item => !this.#hidden.has(this.#idOf(item))));\n const shown = unavailable === undefined && !loading;\n const choices = shown\n ? listed.map(item => Object.freeze({ key: item.key, label: item.label, ticked: !this.#hidden.has(this.#idOf(item)) }))\n : [];\n const ticked = choices.filter(choice => choice.ticked).length;\n const note = !shown ? undefined\n : matchCount > listed.length ? words.fill('too-many-items', formatPivotCount(itemListCap, locale))\n : listed.length === 0 ? words.word('no-items-match')\n : undefined;\n const refusal = this.#refusal ?? (canApply || loading || unavailable !== undefined ? undefined : words.word('refused-hides-every-item'));\n return Object.freeze({\n caption: this.#model.caption,\n search: text,\n items: Object.freeze(choices),\n allTicked: ticked === 0 ? false : ticked === choices.length ? true : undefined,\n loading,\n updating: items.pending && !loading,\n canApply,\n ...(unavailable === undefined ? {} : { unavailable }),\n ...(note === undefined ? {} : { note }),\n ...(refusal === undefined ? {} : { refusal }),\n });\n }\n}\n\n/** Filter\u2026, drawn by `mount` where a Chrome gives one: drawn again by the pivot as the field's Items land. */\nexport function itemFilterPanel(document: Document, model: ItemFilterModel, handlers: ItemFilterHandlers,\n mount?: PivotChromeSlot<PivotItemFilterSlotContext>): PivotPanel {\n const draft = new ItemFilterDraft(model, handlers);\n const label = model.words.fill('filter-of', model.caption);\n if (mount === undefined) return new ItemFilterPanel(document, model, handlers, draft, label);\n return slottedPanel(document, label, model.place, 'itemFilter', mount, draft, handlers.cancel, model.words, input => ({\n setSearch: input((text: string) => { draft.setSearch(text); }),\n setTicked: input((key: PivotItemKey, ticked: boolean) => { draft.setTicked(key, ticked); }),\n setAll: input((ticked: boolean) => { draft.setAll(ticked); }),\n }), () => { draft.redraw(); }, () => { draft.close(); });\n}\n\n/** The built-in Filter\u2026, drawn from its draft. */\nclass ItemFilterPanel implements PivotPanel {\n /** Its frame, which the pivot places. */\n readonly element: HTMLDivElement;\n readonly #draft: ItemFilterDraft;\n readonly #searchBox: HTMLInputElement;\n readonly #list: HTMLDivElement;\n readonly #selectAll: DrawnItem;\n // The notes the list shows in place of Items, or under them; each made once, so drawing again moves nothing.\n readonly #unavailable: HTMLDivElement;\n readonly #loading: HTMLDivElement;\n readonly #note: HTMLDivElement;\n readonly #refusalBox: HTMLDivElement;\n readonly #ok: HTMLButtonElement;\n readonly #drawn = new Map<string, DrawnItem>();\n\n constructor(document: Document, model: ItemFilterModel, handlers: ItemFilterHandlers, draft: ItemFilterDraft, label: string) {\n this.#draft = draft;\n const { words } = model;\n this.element = popupFrame(document, model.place, 'dialog', handlers.cancel);\n this.element.setAttribute('aria-label', label);\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-item-filter');\n this.#searchBox = element(document, 'input', 'ex-pivot-search');\n this.#searchBox.type = 'search';\n this.#searchBox.placeholder = words.word('search-items');\n this.#searchBox.setAttribute('aria-label', words.word('search-items'));\n this.#searchBox.addEventListener('input', () => { draft.setSearch(this.#searchBox.value); });\n this.#list = element(document, 'div', 'ex-pivot-item-list');\n this.#list.setAttribute('role', 'group');\n this.#list.setAttribute('aria-label', model.caption);\n this.#selectAll = this.#item(document, 'ex-pivot-item ex-pivot-select-all', tick => { draft.setAll(tick); });\n this.#selectAll.text.textContent = words.word('select-all');\n this.#unavailable = element(document, 'div', 'ex-pivot-refusal ex-pivot-unavailable');\n this.#unavailable.setAttribute('role', 'alert');\n this.#loading = element(document, 'div', 'ex-pivot-note ex-pivot-loading');\n this.#loading.setAttribute('role', 'status');\n this.#loading.textContent = words.word('loading');\n this.#note = element(document, 'div', 'ex-pivot-note');\n this.#refusalBox = element(document, 'div', 'ex-pivot-refusal');\n this.#refusalBox.setAttribute('role', 'alert');\n const exits = actions(document, words, () => { draft.apply(); }, handlers.cancel);\n this.#ok = exits.ok;\n panel.append(this.#searchBox, this.#list, exits.box);\n this.element.append(panel);\n draft.listeners.subscribe(() => { this.#render(); });\n this.#render();\n }\n\n /** Draws the field's Items again, when they have changed. */\n redraw(): void {\n this.#draft.redraw();\n }\n\n /** Gives the keyboard to the search. */\n takeKeyboard(): void {\n this.#searchBox.focus();\n }\n\n /** Stops a search on its way: the panel has closed. */\n close(): void {\n this.#draft.close();\n }\n\n #item(document: Document, className: string, changed: (tick: boolean) => void): DrawnItem {\n const row = element(document, 'label', className);\n const box = element(document, 'input');\n box.type = 'checkbox';\n const text = element(document, 'span');\n row.append(box, text);\n box.addEventListener('change', () => { changed(box.checked); });\n return { row, box, text };\n }\n\n #render(): void {\n const view = this.#draft.view;\n if (view.loading || view.updating) this.#list.setAttribute('aria-busy', 'true');\n else this.#list.removeAttribute('aria-busy');\n const parts: HTMLElement[] = [];\n if (view.unavailable !== undefined) {\n this.#unavailable.textContent = view.unavailable;\n parts.push(this.#unavailable);\n } else if (view.loading) {\n parts.push(this.#loading);\n } else {\n const document = this.element.ownerDocument;\n if (view.items.length > 0) {\n this.#selectAll.box.checked = view.allTicked === true;\n parts.push(this.#selectAll.row);\n }\n // An Item keeps its row while it is listed, so the one with the keyboard keeps it.\n const kept = new Map<string, DrawnItem>();\n view.items.forEach((item, at) => {\n const id = this.#draft.idAt(at);\n const { key } = item;\n const drawn = this.#drawn.get(id) ?? this.#item(document, 'ex-pivot-item', tick => { this.#draft.setTicked(key, tick); });\n drawn.box.checked = item.ticked;\n if (drawn.text.textContent !== item.label) drawn.text.textContent = item.label;\n kept.set(id, drawn);\n parts.push(drawn.row);\n });\n this.#drawn.clear();\n for (const [id, drawn] of kept) this.#drawn.set(id, drawn);\n if (view.note !== undefined) {\n this.#note.textContent = view.note;\n parts.push(this.#note);\n }\n }\n const children = this.#list.children;\n if (parts.length !== children.length || parts.some((part, i) => children[i] !== part)) this.#list.replaceChildren(...parts);\n\n if (view.refusal === undefined) this.#refusalBox.remove();\n else {\n this.#refusalBox.textContent = view.refusal;\n if (this.#refusalBox.previousSibling !== this.#list) this.#list.after(this.#refusalBox);\n }\n this.#ok.disabled = !view.canApply;\n }\n}\n\n// The Hidden Items of `field` in `layout`, which Filter\u2026 is only opened on while the field is placed.\nfunction placementHidden(layout: PivotLayout, field: string): readonly PivotItemKey[] {\n const at = defined(placementOf(layout, field), `the placement of '${field}'`);\n return elementAt(placementsIn(layout, at.area), at.index).hiddenItems;\n}\n", "// A field's Items, asked of the report source (ADR-0066): what Filter\u2026 lists and the report filter band reads its\n// summary from. They are listed under the Source Version of the report on screen, in the field's order, and listed\n// again when the report moves to another Source Version, settings or order; meanwhile the earlier listing stays in\n// view, marked as updating, as the Razor component's does (ADR-0066 refined). A source that cannot list them says\n// why, never an empty list in its place.\n\nimport type {\n LocalPivotReportSource, PivotItemInfo, PivotReportItemsResult, PivotReportRefusal, PivotReportSettings, PivotSort,\n} from '@ex-grid/pivot-engine';\n\n/** The most Items Filter\u2026 lists (ADR-0061). */\nexport const itemListCap = 10_000;\n\n/** What a field's Items are now. */\nexport interface FieldItems {\n /** The Items listed, in the field's order, and how many there are; none while a first listing is on its way, or\n * when they cannot be listed. */\n readonly listed: { readonly items: readonly PivotItemInfo[]; readonly total: number } | undefined;\n /** Why they cannot be listed. */\n readonly problem: ItemsProblem | undefined;\n /** Whether a listing is on its way: a first one, or the report's while an earlier one is in view. */\n readonly pending: boolean;\n}\n\n/** Why a field's Items cannot be listed: the source's refusal, or an error it threw. */\nexport type ItemsProblem = { readonly refusal: PivotReportRefusal } | { readonly error: unknown };\n\n/** What a listing is asked under: the report on screen, and the field's order in it. */\nexport interface ItemsUnder {\n readonly reportSource: LocalPivotReportSource;\n /** The Report Version the Items are asked for. */\n readonly version: string;\n readonly sourceVersion: string;\n readonly settings: PivotReportSettings;\n /** The field's order, which the Items are listed in. */\n readonly sort: PivotSort | undefined;\n}\n\n/** The Items of `field` matching `search`, asked of the source under `under`: Filter\u2026's search past the Items\n * listed, which only the source can answer. */\nexport function searchItems(field: string, search: string, under: ItemsUnder, signal: AbortSignal): Promise<PivotReportItemsResult> {\n return under.reportSource.items(Object.freeze({ version: under.version, field, search, max: itemListCap }), signal);\n}\n\ninterface Load {\n readonly under: ItemsUnder;\n /** Stops it once a newer listing of its field is asked for, or its source is no longer the pivot's. */\n readonly controller: AbortController;\n /** What it shows: none while it is on its way. */\n shown: FieldItems | undefined;\n}\n\n// Whether two listings are of the same Items in the same order: the same source, Source Version, settings and order.\n// An order by a Value Field is the report's, which any change of the layout may change: such a listing is the report's\n// alone.\nfunction sameListing(a: ItemsUnder, b: ItemsUnder): boolean {\n return a.reportSource === b.reportSource && a.sourceVersion === b.sourceVersion && a.settings === b.settings\n && a.sort?.direction === b.sort?.direction && a.sort?.byValue === b.sort?.byValue\n && (a.sort?.byValue === undefined || a.version === b.version);\n}\n\n/** Nothing listed yet, and a first listing on its way. */\nexport const pendingFirst: FieldItems = Object.freeze({ listed: undefined, problem: undefined, pending: true });\n\n/** The Items of each field the pivot has asked about, under its report source now. */\nexport class ItemListings {\n readonly #listed: () => void;\n // The newest listing asked for each field, and the last one that listed Items, kept in view while a newer one is\n // out. Both hold only the listings of one report source: a new source's Items are listed from nothing.\n readonly #loads = new Map<string, Load>();\n readonly #answered = new Map<string, FieldItems>();\n #reportSource: LocalPivotReportSource | undefined;\n\n /** `listed` is called when a listing lands. */\n constructor(listed: () => void) {\n this.#listed = listed;\n }\n\n /** The Items of `field` as they stand under `under`, asked for if they are not listed under it nor on their way.\n * The same listing is answered with the same object, so a caller can tell nothing changed. */\n of(field: string, under: ItemsUnder): FieldItems {\n if (under.reportSource !== this.#reportSource) this.#forgetAll(under.reportSource);\n let load = this.#loads.get(field);\n if (load === undefined || !sameListing(load.under, under)) {\n // A listing asked over is stopped: its Items would be shown only until the newer one's land.\n if (load?.shown === undefined) load?.controller.abort();\n load = { under, controller: new AbortController(), shown: undefined };\n this.#loads.set(field, load);\n void this.#list(field, load);\n }\n if (load.shown !== undefined) return load.shown;\n // An earlier listing stays in view until this one lands; with none, the first listing is on its way.\n return this.#answered.get(field) ?? pendingFirst;\n }\n\n /** Asks for `field`'s Items again the next time they are read, when its listing failed: Filter\u2026 opened again\n * lists them anew rather than repeat a failure that may have passed. */\n retry(field: string): void {\n if (this.#loads.get(field)?.shown?.problem !== undefined) this.#loads.delete(field);\n }\n\n /** Stops every listing on its way and forgets every listing: the pivot is gone. */\n dispose(): void {\n this.#forgetAll(undefined);\n }\n\n #forgetAll(reportSource: LocalPivotReportSource | undefined): void {\n for (const load of this.#loads.values()) load.controller.abort();\n this.#loads.clear();\n this.#answered.clear();\n this.#reportSource = reportSource;\n }\n\n async #list(field: string, load: Load): Promise<void> {\n const { under, controller: { signal } } = load;\n let result;\n try {\n result = await under.reportSource.items(Object.freeze({ version: under.version, field, max: itemListCap }), signal);\n } catch (error) { // oxlint-disable-line ex-grid/no-catch -- a listing asked over, or of a source no longer the pivot's, is nobody's; the current one's failure is said where its Items are shown, and rethrown\n if (signal.aborted) return;\n this.#landed(field, load, Object.freeze({ listed: undefined, problem: Object.freeze({ error }), pending: false }));\n throw error;\n }\n if (signal.aborted) return;\n this.#landed(field, load, Object.freeze(result.refusal === undefined\n ? { listed: Object.freeze({ items: result.items, total: result.total }), problem: undefined, pending: false }\n : { listed: undefined, problem: Object.freeze({ refusal: result.refusal }), pending: false }));\n }\n\n // Its Items replace the ones kept in view while a newer listing is out; Items that could not be listed leave none\n // in view, as the Razor component's do.\n #landed(field: string, load: Load, shown: FieldItems): void {\n load.shown = shown;\n if (shown.listed === undefined) this.#answered.delete(field);\n else this.#answered.set(field, Object.freeze({ ...shown, pending: true }));\n this.#listed();\n }\n}\n", "// ExPivot's built-in menu in its frame (ADR-0061): a placed field's commands, or the Layout menu's choices, in\n// the markup and under the classes the Razor component's PivotPopupFrame and PivotMenuView draw, so one\n// stylesheet paints both (ADR-0350 section 4). Where the frame stands and what closes it are the pivot's; the\n// frame says only that Escape was pressed in it. A Chrome's menu slot draws the commands inside the same frame.\n\nimport { SlotMount, ViewListeners, type PivotChromeSlot, type PivotMenuCommand, type PivotMenuSlotContext, type PivotMenuView } from './chrome';\nimport type { PivotScreenWords } from './words';\n\nexport type { PivotMenuCommand } from './chrome';\n\n/** Where a frame stands: in the Field List under its entry, or from the Pivot Toolbar over the report, at its\n * button's left edge (the report filter band) or its right edge (Layout \u25BE). */\nexport type PivotMenuPlace = 'field-list' | 'toolbar-start' | 'toolbar-end';\n\n/**\n * ExPivot's frame around a menu or a panel (ADR-0061), as the Razor component's PivotPopupFrame draws it: where it\n * stands is its class, and Escape pressed anywhere in it calls `escape` and goes no further, so a dialog the\n * Consumer put the pivot in does not close on it too. It claims nothing of the pivot's input (ADR-0240 section 6).\n */\nexport function popupFrame(document: Document, place: PivotMenuPlace, role: 'menu' | 'dialog', escape: () => void,\n innerPopupOpen?: () => boolean): HTMLDivElement {\n const frame = document.createElement('div');\n frame.className = {\n 'field-list': 'ex-pivot-popup',\n 'toolbar-start': 'ex-pivot-popup ex-pivot-popup-overlay',\n 'toolbar-end': 'ex-pivot-popup ex-pivot-popup-overlay ex-pivot-popup-end',\n }[place];\n frame.setAttribute('role', role);\n // A press on its padding, its text or a disabled command gives the frame the keyboard, so Escape stays inside it\n // without another Tab stop (ADR-0061).\n frame.tabIndex = -1;\n frame.setAttribute('data-ex-claims', '');\n frame.addEventListener('keydown', event => {\n if (event.key !== 'Escape' || event.ctrlKey || event.altKey || event.metaKey) return;\n // While a popup of a Chrome's own is open in the frame, Escape is that popup's (ADR-0039).\n if (innerPopupOpen?.() === true) return;\n event.preventDefault();\n event.stopPropagation();\n escape();\n });\n return frame;\n}\n\ninterface DrawnCommand {\n readonly button: HTMLButtonElement;\n readonly mark: HTMLElement | undefined;\n}\n\nfunction sameShape(a: readonly PivotMenuCommand[], b: readonly PivotMenuCommand[]): boolean {\n return a.length === b.length\n && a.every((command, i) => {\n const other = b[i];\n return other !== undefined && other.id === command.id && other.heading === command.heading\n && (other.checked === undefined) === (command.checked === undefined);\n });\n}\n\n// Whether a Chrome's menu shows the same thing for `b` as for `a`.\nfunction sameCommands(a: readonly PivotMenuCommand[], b: readonly PivotMenuCommand[]): boolean {\n return a.length === b.length\n && a.every((command, i) => {\n const other = b[i];\n return other !== undefined && other.id === command.id && other.label === command.label && other.enabled === command.enabled\n && other.checked === command.checked && other.heading === command.heading;\n });\n}\n\n/** A menu in ExPivot's frame, the built-in one's or a Chrome's: the pivot places its element, draws it again on every\n * change, and takes it away. */\nexport interface PivotMenu {\n /** The frame, which the pivot places. */\n readonly element: HTMLElement;\n /** Draws `commands` under the accessible name `label`. */\n draw(label: string, commands: readonly PivotMenuCommand[]): void;\n /** Gives the keyboard to the first enabled command, or to the frame when every command is disabled. */\n takeKeyboard(): void;\n /** The menu is taken away. */\n close(): void;\n /** Whether a popup of a Chrome's contents is open, which may stand outside the frame and take the keyboard there. */\n innerPopupOpen?(): boolean;\n}\n\n/** A menu in ExPivot's frame. The pivot draws it again on every change, and a command pressed is the one drawn\n * last: a press never reaches a command built against a layout the pane has since left. */\nexport class PivotMenuFrame implements PivotMenu {\n /** The frame, which the pivot places. */\n readonly element: HTMLDivElement;\n readonly #menu: HTMLDivElement;\n #commands: readonly PivotMenuCommand[] = [];\n #drawn = new Map<string, DrawnCommand>();\n\n constructor(document: Document, place: PivotMenuPlace, escape: () => void) {\n this.element = popupFrame(document, place, 'menu', escape);\n this.#menu = document.createElement('div');\n this.#menu.className = 'ex-pivot-menu';\n this.#menu.setAttribute('role', 'none');\n this.element.append(this.#menu);\n }\n\n /** Draws `commands` under the accessible name `label`. A command keeps its button while the menu holds the\n * same commands, so the one with the keyboard keeps it. */\n draw(label: string, commands: readonly PivotMenuCommand[]): void {\n this.element.setAttribute('aria-label', label);\n if (!sameShape(this.#commands, commands)) this.#build(commands);\n this.#commands = commands;\n for (const command of commands) {\n const drawn = this.#drawn.get(command.id);\n if (drawn === undefined) throw new Error(`Internal: the command '${command.id}' was not drawn.`);\n drawn.button.disabled = !command.enabled;\n if (command.checked !== undefined) drawn.button.setAttribute('aria-checked', command.checked ? 'true' : 'false');\n if (drawn.mark !== undefined) drawn.mark.textContent = command.checked === true ? '\u2713' : '';\n const text = drawn.button.lastChild;\n if (text?.textContent !== command.label) {\n if (text instanceof Text) text.textContent = command.label;\n else drawn.button.append(command.label);\n }\n }\n }\n\n /** Gives the keyboard to the first enabled command, or to the frame when every command is disabled. */\n takeKeyboard(): void {\n const first = this.#commands.find(command => command.enabled);\n if (first === undefined) {\n this.element.focus();\n return;\n }\n const drawn = this.#drawn.get(first.id);\n if (drawn === undefined) throw new Error(`Internal: the command '${first.id}' was not drawn.`);\n drawn.button.focus();\n }\n\n /** Nothing of the built-in menu outlives its frame. */\n close(): void {\n // The frame's listeners go with it.\n }\n\n #build(commands: readonly PivotMenuCommand[]): void {\n const document = this.element.ownerDocument;\n const drawn = new Map<string, DrawnCommand>();\n const parts: HTMLElement[] = [];\n let group: HTMLElement | undefined;\n for (const command of commands) {\n if (command.heading !== undefined) {\n // A group of choices stands under its heading, as the Razor component's menu draws it.\n group = document.createElement('div');\n group.className = 'ex-pivot-menu-group';\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', command.heading);\n const heading = document.createElement('div');\n heading.className = 'ex-pivot-menu-heading';\n heading.setAttribute('aria-hidden', 'true');\n heading.textContent = command.heading;\n group.append(heading);\n parts.push(group);\n }\n const button = document.createElement('button');\n button.type = 'button';\n const choice = command.checked !== undefined;\n button.className = choice ? 'ex-pivot-menu-item ex-pivot-menu-choice' : 'ex-pivot-menu-item';\n button.setAttribute('role', choice ? 'menuitemradio' : 'menuitem');\n button.setAttribute('data-ex-claims', 'click');\n let mark: HTMLElement | undefined;\n if (choice) {\n mark = document.createElement('span');\n mark.className = 'ex-pivot-menu-mark';\n mark.setAttribute('aria-hidden', 'true');\n button.append(mark);\n }\n const { id } = command;\n button.addEventListener('click', () => {\n // The command drawn last under this id: the one built against the pane's layout now.\n const current = this.#commands.find(c => c.id === id);\n if (current?.enabled === true) current.invoke();\n });\n drawn.set(id, { button, mark });\n if (group === undefined) parts.push(button);\n else group.append(button);\n }\n if (drawn.size !== commands.length) throw new Error('Internal: two commands of one menu share an id.');\n this.#drawn = drawn;\n this.#menu.replaceChildren(...parts);\n }\n}\n\n/**\n * A menu whose commands a Chrome's slot draws (ADR-0390), inside the same frame: the commands, their order and what\n * each does are the pivot's, and a command pressed is the one drawn last under its id, as the built-in menu's is, so a\n * press never reaches a command built against a layout the pane has since left.\n */\nexport class SlottedMenuFrame implements PivotMenu {\n readonly element: HTMLDivElement;\n readonly #slot: SlotMount<PivotMenuSlotContext>;\n readonly #listeners = new ViewListeners();\n #view: PivotMenuView = Object.freeze({ name: '', commands: Object.freeze([]) });\n #commands: readonly PivotMenuCommand[] = [];\n\n constructor(document: Document, place: PivotMenuPlace, mount: PivotChromeSlot<PivotMenuSlotContext>, words: PivotScreenWords, escape: () => void) {\n this.element = popupFrame(document, place, 'menu', escape, () => this.#slot.innerPopupOpen);\n const body = document.createElement('div');\n body.setAttribute('role', 'none');\n this.element.append(body);\n const close = (): void => { escape(); };\n this.#slot = new SlotMount('menu', mount, body, focusRequest => Object.freeze({\n view: () => this.#view,\n subscribe: this.#listeners.subscribe,\n close: this.#slot.input(close),\n focusRequest,\n label: (id: string) => words.word(id),\n takeFocus: this.#slot.takeFocus,\n }), close);\n }\n\n draw(label: string, commands: readonly PivotMenuCommand[]): void {\n this.element.setAttribute('aria-label', label);\n this.#commands = commands;\n // The view is the same object while nothing it shows changed: a press reaches the commands drawn now anyway.\n if (this.#view.name === label && sameCommands(this.#view.commands, commands)) {\n this.#slot.mount();\n return;\n }\n this.#view = Object.freeze({\n name: label,\n commands: Object.freeze(commands.map(command => Object.freeze({ ...command, invoke: this.#slot.input(() => { this.#press(command.id); }) }))),\n });\n // Mounted once its first commands are known, and told of each change after.\n this.#slot.mount();\n this.#listeners.tell();\n }\n\n takeKeyboard(): void {\n if (this.#commands.some(command => command.enabled)) this.#slot.request();\n else this.element.focus();\n }\n\n innerPopupOpen(): boolean {\n return this.#slot.innerPopupOpen;\n }\n\n close(): void {\n this.#listeners.clear();\n this.#slot.dispose();\n }\n\n // The command drawn last under this id: the one built against the pane's layout now.\n #press(id: string): void {\n const current = this.#commands.find(command => command.id === id);\n if (current?.enabled === true) current.invoke();\n }\n}\n", "// ExPivot's built-in panels (ADR-0061): Field Settings\u2026 and Value Field Settings\u2026, in the markup and under the\n// classes the Razor component's PivotFieldSettingsView and PivotValueFieldSettingsView draw, so one stylesheet\n// paints both (ADR-0350 section 4). A panel holds a draft until OK, which says the change as the next layout; Cancel\n// and Escape drop it. Its controls are built once, when it opens, so nothing the pivot draws meanwhile writes over\n// what the user is typing.\n//\n// What a draft holds and what OK makes of it is the draft's, which the built-in markup and a Chrome's slot draw alike\n// (ADR-0390): swapping the Chrome changes no behaviour.\n\nimport {\n formatPivotNumber, pivotAggregationNameId, pivotAggregations, pivotCaptionId, pivotNumberFormatProblem, pivotShowValuesAsList,\n pivotShowValuesAsNameId, pivotSort, refusalWord, setSort, setSubtotals, setValueField, sortsEqual, type PivotAggregation, type PivotField,\n type PivotFieldPlacement, type PivotLayout, type PivotShowValuesAs, type PivotSort, type PivotSourceFeatures, type PivotValueFieldInput,\n} from '@ex-grid/pivot-engine';\nimport {\n SlotMount, ViewListeners, type PivotChoice, type PivotChromeSlot, type PivotFieldSettingsSlotContext, type PivotFieldSettingsView, type PivotPanelSlotContext,\n type PivotValueFieldSettingsSlotContext, type PivotValueFieldSettingsView,\n} from './chrome';\nimport { element as made } from './dom';\nimport { popupFrame, type PivotMenuPlace } from './menu';\nimport { elementAt } from './must';\nimport type { PivotScreenWords } from './words';\n\n/** A panel open under a field's entry. */\nexport interface PivotPanel {\n /** Its frame, which the pivot places. */\n readonly element: HTMLElement;\n /** Gives the keyboard to its first control. */\n takeKeyboard(): void;\n /** Draws again what it shows of the pivot's state, which the pivot has drawn again. */\n redraw?(): void;\n /** Closed: stops what it has asked that is still on its way. */\n close?(): void;\n /** Whether a popup of a Chrome's contents is open, which may stand outside the frame and take the keyboard there. */\n innerPopupOpen?(): boolean;\n}\n\n/** Whom a panel calls back. */\nexport interface PanelHandlers {\n /** OK made `layout`, taken against the layout the panel was opened on. */\n readonly apply: (layout: PivotLayout) => void;\n /** Cancel or Escape, or OK with nothing changed. */\n readonly cancel: () => void;\n}\n\n// Each panel's radio group is named apart from every other's on the page (ADR-0018).\nlet groups = 0;\n\n/** A panel's element. */\nexport function element<K extends keyof HTMLElementTagNameMap>(document: Document, tag: K, className?: string): HTMLElementTagNameMap[K] {\n const control = made(document, tag, className);\n // A draft's control claims nothing of the pivot's input: holding the keyboard, it is the pivot's own (ADR-0240).\n if (tag === 'input' || tag === 'select') control.setAttribute('data-ex-claims', '');\n return control;\n}\n\nfunction labelled(document: Document, words: string, control: HTMLElement): HTMLLabelElement {\n const row = element(document, 'label', 'ex-pivot-row');\n const text = element(document, 'span');\n text.textContent = words;\n row.append(text, control);\n return row;\n}\n\n/** OK and Cancel, which claim their click. */\nexport function actions(document: Document, words: PivotScreenWords, ok: () => void, cancel: () => void): { readonly box: HTMLElement; readonly ok: HTMLButtonElement } {\n const box = element(document, 'div', 'ex-pivot-panel-actions');\n const make = (className: string, id: string, pressed: () => void): HTMLButtonElement => {\n const button = element(document, 'button', className);\n button.type = 'button';\n button.setAttribute('data-ex-claims', 'click');\n button.textContent = words.word(id);\n button.addEventListener('click', pressed);\n return button;\n };\n const okButton = make('ex-pivot-ok', 'ok', ok);\n box.append(okButton, make('ex-pivot-cancel', 'cancel', cancel));\n return { box, ok: okButton };\n}\n\n/** A draft a panel draws: its view, told to its listeners at each change, and OK. */\nexport interface PanelDraft<View> {\n /** What the panel shows now: a new object at each change, and the same one otherwise. */\n readonly view: View;\n /** Hears each change to the view. */\n readonly listeners: ViewListeners;\n /** OK: the draft as the next layout, a refusal said in the view, or Cancel where nothing changed. */\n apply(): void;\n}\n\n/**\n * A panel whose contents a Chrome's slot draws (ADR-0390), inside the pivot's frame, from its draft: every choice is\n * the draft's, and OK and Cancel the panel's handlers'. A request for the keyboard mounts the contents again with the\n * next count; once the panel is closed, nothing they call back reaches the pivot.\n */\nexport function slottedPanel<View, Context extends PivotPanelSlotContext>(document: Document, frameLabel: string, place: PivotMenuPlace, name: string,\n mount: PivotChromeSlot<Context>, draft: PanelDraft<View>, cancel: () => void, words: PivotScreenWords,\n choices: (input: <Args extends unknown[]>(change: (...args: Args) => void) => (...args: Args) => void) => Omit<Context, keyof PivotPanelSlotContext | 'view'>,\n redraw?: () => void, closing?: () => void): PivotPanel {\n // A popup of the contents' own takes Escape first.\n const frame = popupFrame(document, place, 'dialog', cancel, () => slot.innerPopupOpen);\n frame.setAttribute('aria-label', frameLabel);\n const body = document.createElement('div');\n frame.append(body);\n const slot: SlotMount<Context> = new SlotMount<Context>(name, mount, body, focusRequest => {\n const input = <Args extends unknown[]>(change: (...args: Args) => void): ((...args: Args) => void) => slot.input(change);\n const parts: PivotPanelSlotContext & { readonly view: () => View } = {\n label: (id: string) => words.word(id),\n focusRequest,\n takeFocus: slot.takeFocus,\n subscribe: draft.listeners.subscribe,\n view: () => draft.view,\n apply: input(() => { draft.apply(); }),\n cancel: input(cancel),\n innerPopupChanged: slot.innerPopupChanged,\n };\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the parts every panel's context shares, and the choices this panel's adds, make its context\n return Object.freeze({ ...parts, ...choices(input) }) as unknown as Context;\n }, cancel);\n // Mounted first by the request for the keyboard its opening makes, once the pivot holds the panel as open: contents\n // that cannot be drawn then close a panel that stands.\n return Object.freeze({\n element: frame,\n takeKeyboard: () => { slot.request(); },\n innerPopupOpen: () => slot.innerPopupOpen,\n ...(redraw === undefined ? {} : { redraw }),\n close: () => {\n closing?.();\n draft.listeners.clear();\n slot.dispose();\n },\n });\n}\n\n/** What Field Settings\u2026 is opened on. */\nexport interface FieldSettingsModel {\n readonly layout: PivotLayout;\n readonly placement: PivotFieldPlacement;\n readonly caption: string;\n /** The Value Fields' captions, which name the sorts by value. */\n readonly valueCaptions: readonly string[];\n readonly words: PivotScreenWords;\n}\n\n/** Field Settings\u2026' draft: the subtotals and the order, until OK. */\nexport class FieldSettingsDraft implements PanelDraft<PivotFieldSettingsView> {\n readonly listeners = new ViewListeners();\n readonly #model: FieldSettingsModel;\n readonly #handlers: PanelHandlers;\n readonly #sorts: readonly { readonly sort: PivotSort; readonly label: string }[];\n #view: PivotFieldSettingsView;\n\n constructor(model: FieldSettingsModel, handlers: PanelHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n const { placement, words } = model;\n // A to Z and Z to A by label, then each Value Field's two orders, as Excel's More Sort Options lists them.\n const sorts: { readonly sort: PivotSort; readonly label: string }[] = [\n { sort: pivotSort('ascending'), label: words.word('sort-label-ascending') },\n { sort: pivotSort('descending'), label: words.word('sort-label-descending') },\n ];\n model.valueCaptions.forEach((caption, i) => {\n sorts.push({ sort: pivotSort('ascending', i), label: words.fill('sort-value-ascending', caption) });\n sorts.push({ sort: pivotSort('descending', i), label: words.fill('sort-value-descending', caption) });\n });\n this.#sorts = sorts;\n const current = sorts.findIndex(({ sort }) => sortsEqual(sort, placement.sort));\n if (current < 0) throw new Error(`Internal: the field's order is none Field Settings\u2026 lists.`);\n this.#view = Object.freeze({\n caption: model.caption, subtotals: placement.subtotals, sorts: Object.freeze(sorts.map(({ label }) => label)), sort: current,\n });\n }\n\n get view(): PivotFieldSettingsView {\n return this.#view;\n }\n\n setSubtotals(automatic: boolean): void {\n if (typeof automatic !== 'boolean') throw new TypeError('setSubtotals is handed whether the subtotals are Automatic.');\n this.#change({ subtotals: automatic });\n }\n\n setSort(index: number): void {\n if (!Number.isSafeInteger(index) || index < 0 || index >= this.#sorts.length) {\n throw new RangeError(`setSort is handed the index of one of the panel's ${this.#sorts.length} orders, not ${index}.`);\n }\n this.#change({ sort: index });\n }\n\n apply(): void {\n const { layout, placement } = this.#model;\n const sort = elementAt(this.#sorts, this.#view.sort).sort;\n const { subtotals } = this.#view;\n if (subtotals === placement.subtotals && sortsEqual(sort, placement.sort)) {\n this.#handlers.cancel();\n return;\n }\n this.#handlers.apply(setSort(setSubtotals(layout, placement.field, subtotals), placement.field, sort));\n }\n\n #change(change: Partial<PivotFieldSettingsView>): void {\n this.#view = Object.freeze({ ...this.#view, ...change });\n this.listeners.tell();\n }\n}\n\n/** Field Settings\u2026 (ADR-0061): a row or column field's subtotals and order, drawn by `mount` where a Chrome gives one. */\nexport function fieldSettingsPanel(document: Document, model: FieldSettingsModel, handlers: PanelHandlers,\n mount?: PivotChromeSlot<PivotFieldSettingsSlotContext>): PivotPanel {\n const { words } = model;\n const draft = new FieldSettingsDraft(model, handlers);\n if (mount !== undefined) {\n return slottedPanel(document, words.word('field-settings'), 'field-list', 'fieldSettings', mount, draft, handlers.cancel, words, input => ({\n setSubtotals: input((automatic: boolean) => { draft.setSubtotals(automatic); }),\n setSort: input((index: number) => { draft.setSort(index); }),\n }));\n }\n const frame = popupFrame(document, 'field-list', 'dialog', handlers.cancel);\n frame.setAttribute('aria-label', words.word('field-settings'));\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-field-settings');\n const title = element(document, 'div', 'ex-pivot-panel-title');\n title.textContent = model.caption;\n\n const fieldset = element(document, 'fieldset', 'ex-pivot-fieldset');\n const legend = element(document, 'legend');\n legend.textContent = words.word('subtotals');\n groups++;\n const group = `ex-pivot-subtotals-${groups}`;\n const radio = (id: string, automatic: boolean): { readonly row: HTMLLabelElement; readonly input: HTMLInputElement } => {\n const row = element(document, 'label', 'ex-pivot-choice');\n const input = element(document, 'input');\n input.type = 'radio';\n input.name = group;\n input.checked = draft.view.subtotals === automatic;\n input.addEventListener('change', () => { if (input.checked) draft.setSubtotals(automatic); });\n const text = element(document, 'span');\n text.textContent = words.word(id);\n row.append(input, text);\n return { row, input };\n };\n const automatic = radio('subtotals-automatic', true);\n const none = radio('subtotals-none', false);\n fieldset.append(legend, automatic.row, none.row);\n\n const select = element(document, 'select', 'ex-pivot-select');\n draft.view.sorts.forEach((label, i) => {\n const option = element(document, 'option');\n option.value = String(i);\n option.textContent = label;\n select.append(option);\n });\n select.value = String(draft.view.sort);\n select.addEventListener('change', () => { draft.setSort(Number(select.value)); });\n\n panel.append(title, fieldset, labelled(document, words.word('sort-order'), select), actions(document, words, () => { draft.apply(); }, handlers.cancel).box);\n frame.append(panel);\n return Object.freeze({ element: frame, takeKeyboard: () => { automatic.input.focus(); } });\n}\n\n/** What Value Field Settings\u2026 is opened on. */\nexport interface ValueFieldSettingsModel {\n readonly layout: PivotLayout;\n readonly index: number;\n /** The field's caption. */\n readonly fieldCaption: string;\n /** The Value Field's caption as the report shows it. */\n readonly caption: string;\n readonly fields: readonly PivotField[];\n readonly features: PivotSourceFeatures;\n readonly locale: string;\n readonly words: PivotScreenWords;\n}\n\n/** Value Field Settings\u2026' draft: the caption, the Aggregation, Show Values As and the number format, until OK. */\nexport class ValueFieldSettingsDraft implements PanelDraft<PivotValueFieldSettingsView> {\n readonly listeners = new ViewListeners();\n readonly #model: ValueFieldSettingsModel;\n readonly #handlers: PanelHandlers;\n #captionTouched = false;\n #view: PivotValueFieldSettingsView;\n\n constructor(model: ValueFieldSettingsModel, handlers: PanelHandlers) {\n this.#model = model;\n this.#handlers = handlers;\n const { layout, index, words, features } = model;\n const value = elementAt(layout.values, index);\n const aggregations = pivotAggregations.map(choice => {\n const name = words.word(pivotAggregationNameId(choice));\n return Object.freeze<PivotChoice<PivotAggregation>>(features.offers(choice)\n ? { value: choice, label: name, enabled: true }\n : { value: choice, label: name, enabled: false, reason: words.fill('aggregation-not-offered', name) });\n });\n const showValuesAsChoices = pivotShowValuesAsList.map(choice => Object.freeze<PivotChoice<PivotShowValuesAs>>({\n value: choice, label: words.word(pivotShowValuesAsNameId(choice)), enabled: true,\n }));\n const numberFormat = value.numberFormat ?? ''; // oxlint-disable-line ex-grid/no-stand-in-default -- no format of its own is General, which the field shows empty\n this.#view = Object.freeze({\n sourceCaption: model.fieldCaption,\n caption: model.caption,\n aggregation: value.aggregation,\n aggregations: Object.freeze(aggregations),\n showValuesAs: value.showValuesAs,\n showValuesAsChoices: Object.freeze(showValuesAsChoices),\n numberFormat,\n numberFormatPlaceholder: words.word('number-format-general'),\n sample: this.#sampleOf(value.showValuesAs, numberFormat),\n });\n }\n\n get view(): PivotValueFieldSettingsView {\n return this.#view;\n }\n\n setCaption(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setCaption is handed the caption as typed.');\n this.#captionTouched = true;\n this.#change({ caption: text });\n }\n\n setAggregation(aggregation: PivotAggregation): void {\n if (!pivotAggregations.includes(aggregation)) throw new RangeError(`'${aggregation}' is not an Aggregation.`);\n // An Aggregation the source does not answer is never chosen: it is never asked for (ADR-0066).\n if (!this.#model.features.offers(aggregation)) {\n this.listeners.tell();\n return;\n }\n const value = elementAt(this.#model.layout.values, this.#model.index);\n // A caption the user has not written follows the Aggregation, as Excel's Custom Name box does.\n this.#change({ aggregation, ...(!this.#captionTouched && value.caption === undefined ? { caption: this.#defaultCaption(aggregation) } : {}) });\n }\n\n setShowValuesAs(showValuesAs: PivotShowValuesAs): void {\n if (!pivotShowValuesAsList.includes(showValuesAs)) throw new RangeError(`'${showValuesAs}' is not a Show Values As.`);\n this.#change({ showValuesAs, sample: this.#sampleOf(showValuesAs, this.#view.numberFormat) });\n }\n\n setNumberFormat(text: string): void {\n if (typeof text !== 'string') throw new TypeError('setNumberFormat is handed the number format as typed.');\n this.#change({ numberFormat: text, sample: this.#sampleOf(this.#view.showValuesAs, text) });\n }\n\n apply(): void {\n const { layout, index, words, features } = this.#model;\n const value = elementAt(layout.values, index);\n const { aggregation: chosen, showValuesAs: shown } = this.#view;\n // A Value Field the Consumer handed in with an Aggregation the source does not answer is refused here, never\n // asked for (ADR-0066).\n if (!features.offers(chosen)) {\n this.#refuse(words.fill('aggregation-not-offered', words.word(pivotAggregationNameId(chosen))));\n return;\n }\n const trimmed = this.#view.caption.trim();\n // A caption left as the pivot wrote it stays the pivot's, and follows the Aggregation and the words.\n const own = (!this.#captionTouched && value.caption === undefined) || trimmed === this.#defaultCaption(chosen) ? undefined : trimmed;\n const numberFormat = this.#view.numberFormat.trim();\n if (chosen === value.aggregation && shown === value.showValuesAs && own === value.caption && (numberFormat === '' ? undefined : numberFormat) === value.numberFormat) {\n this.#handlers.cancel();\n return;\n }\n const input: PivotValueFieldInput = {\n field: value.field,\n aggregation: chosen,\n showValuesAs: shown,\n ...(own === undefined ? {} : { caption: own }),\n ...(numberFormat === '' ? {} : { numberFormat }),\n };\n const result = setValueField(layout, index, input, this.#model.fields, { locale: this.#model.locale, ...(words.label === undefined ? {} : { label: words.label }) });\n if (result.refusal !== undefined) {\n this.#refuse(words.word(refusalWord(result.refusal)));\n return;\n }\n this.#handlers.apply(result.layout);\n }\n\n #defaultCaption(aggregation: PivotAggregation): string {\n return this.#model.words.fill(pivotCaptionId(aggregation), this.#model.fieldCaption);\n }\n\n // A number shown in the draft's format, or the reason it cannot be, so a format is seen before it is applied.\n #sampleOf(showValuesAs: PivotShowValuesAs, format: string): string {\n const { words, locale } = this.#model;\n const trimmed = format.trim();\n const percent = showValuesAs !== 'noCalculation';\n if (trimmed !== '' && pivotNumberFormatProblem(trimmed) !== undefined) return words.word('refused-number-format');\n return words.fill('sample', formatPivotNumber(percent ? 0.1234 : -1234.5678, trimmed === '' ? (percent ? '0.00%' : 'G15') : trimmed, locale));\n }\n\n #refuse(sentence: string): void {\n this.#view = Object.freeze({ ...this.#view, refusal: sentence });\n this.listeners.tell();\n }\n\n // Any change of the draft takes back a refusal said for the draft before it.\n #change(change: Partial<PivotValueFieldSettingsView>): void {\n const { refusal: _said, ...kept } = this.#view;\n this.#view = Object.freeze({ ...kept, ...change });\n this.listeners.tell();\n }\n}\n\n/** Value Field Settings\u2026 (ADR-0061): the caption, the Aggregation, Show Values As and the number format with a\n * sample, drawn by `mount` where a Chrome gives one. OK is refused, the sentence said in the panel, for a caption taken\n * or empty and for a format that cannot be used; an Aggregation the source does not answer is offered disabled, with\n * the reason (ADR-0066). */\nexport function valueFieldSettingsPanel(document: Document, model: ValueFieldSettingsModel, handlers: PanelHandlers,\n mount?: PivotChromeSlot<PivotValueFieldSettingsSlotContext>): PivotPanel {\n const { words } = model;\n const draft = new ValueFieldSettingsDraft(model, handlers);\n if (mount !== undefined) {\n return slottedPanel(document, words.word('value-field-settings'), 'field-list', 'valueFieldSettings', mount, draft, handlers.cancel, words, input => ({\n setCaption: input((text: string) => { draft.setCaption(text); }),\n setAggregation: input((aggregation: PivotAggregation) => { draft.setAggregation(aggregation); }),\n setShowValuesAs: input((showValuesAs: PivotShowValuesAs) => { draft.setShowValuesAs(showValuesAs); }),\n setNumberFormat: input((text: string) => { draft.setNumberFormat(text); }),\n }));\n }\n const view = (): PivotValueFieldSettingsView => draft.view;\n const frame = popupFrame(document, 'field-list', 'dialog', handlers.cancel);\n frame.setAttribute('aria-label', words.word('value-field-settings'));\n const panel = element(document, 'div', 'ex-pivot-panel ex-pivot-value-settings');\n const title = element(document, 'div', 'ex-pivot-panel-title');\n title.textContent = words.word('value-field-settings');\n const source = element(document, 'div', 'ex-pivot-row ex-pivot-source');\n source.textContent = view().sourceCaption;\n\n const caption = element(document, 'input', 'ex-pivot-text');\n caption.type = 'text';\n caption.value = view().caption;\n\n const aggregation = element(document, 'select', 'ex-pivot-select');\n const notOffered: HTMLElement[] = [];\n for (const choice of view().aggregations) {\n const option = element(document, 'option');\n option.value = choice.value;\n option.textContent = choice.label;\n if (choice.reason !== undefined) {\n option.disabled = true;\n option.title = choice.reason;\n const note = element(document, 'div', 'ex-pivot-note ex-pivot-not-offered');\n note.textContent = choice.reason;\n notOffered.push(note);\n }\n aggregation.append(option);\n }\n aggregation.value = view().aggregation;\n\n const showAs = element(document, 'select', 'ex-pivot-select');\n for (const choice of view().showValuesAsChoices) {\n const option = element(document, 'option');\n option.value = choice.value;\n option.textContent = choice.label;\n showAs.append(option);\n }\n showAs.value = view().showValuesAs;\n\n const format = element(document, 'input', 'ex-pivot-text');\n format.type = 'text';\n format.placeholder = view().numberFormatPlaceholder;\n format.value = view().numberFormat;\n const sample = element(document, 'div', 'ex-pivot-sample');\n // The refusal is said under the sample while it stands, and is not on the page otherwise, as the Razor component's.\n const refusal = element(document, 'div', 'ex-pivot-refusal');\n refusal.setAttribute('role', 'alert');\n\n // Each control shows the draft: a text field is written only where the draft differs from what is typed in it, so\n // the caret stays where the user put it.\n const drawn = (): void => {\n const now = view();\n if (caption.value !== now.caption) caption.value = now.caption;\n aggregation.value = now.aggregation;\n showAs.value = now.showValuesAs;\n if (format.value !== now.numberFormat) format.value = now.numberFormat;\n sample.textContent = now.sample;\n if (now.refusal === undefined) {\n refusal.remove();\n } else {\n refusal.textContent = now.refusal;\n sample.after(refusal);\n }\n };\n draft.listeners.subscribe(drawn);\n caption.addEventListener('input', () => { draft.setCaption(caption.value); });\n aggregation.addEventListener('change', () => {\n const picked = pivotAggregations.find(a => a === aggregation.value);\n if (picked === undefined) throw new Error(`Internal: '${aggregation.value}' is not an Aggregation.`);\n draft.setAggregation(picked);\n });\n showAs.addEventListener('change', () => {\n const picked = pivotShowValuesAsList.find(s => s === showAs.value);\n if (picked === undefined) throw new Error(`Internal: '${showAs.value}' is not a Show Values As.`);\n draft.setShowValuesAs(picked);\n });\n format.addEventListener('input', () => { draft.setNumberFormat(format.value); });\n drawn();\n\n panel.append(\n title, source,\n labelled(document, words.word('custom-name'), caption),\n labelled(document, words.word('summarize-by'), aggregation),\n ...notOffered,\n labelled(document, words.word('show-values-as'), showAs),\n labelled(document, words.word('number-format'), format),\n sample,\n actions(document, words, () => { draft.apply(); }, handlers.cancel).box,\n );\n frame.append(panel);\n return Object.freeze({ element: frame, takeKeyboard: () => { caption.focus(); }, close: () => { draft.listeners.clear(); } });\n}\n", "// Written by tools/assets/minify.mjs (ADR-0123): do not edit. Edit dotnet/src/ExPivot/Assets/ and run it\n// again, and commit what it writes. test/shipped-stylesheet.test.ts checks it against the source.\n\n/** The name of the stylesheet the pivot draws against, by which its notice rules find the notice. */\nexport const stylesheetName = 'ex-pivot.css';\n\n/** The SHA-256 of that stylesheet's source: the stamp its own notice rule hides the notice for. */\nexport const stylesheetStamp = '1a2532223e2af8d3d27b7aa2e8919df9378c1554121b47e778ced6ff8ae89dd3';\n", "// The Pivot Report as ExGrid's Consumer draws it (ADR-0059, ADR-0063): its rows a Window the report source\n// answers, its label columns pinned and its value columns under Header Groups. Nothing is held here but what\n// one report's metadata says; the rows stay with the report source, asked for as the grid scrolls, so the\n// DOM and the memory grow with the rows on screen, not with the report (ADR-0151, ADR-0027 P1).\n\nimport {\n GridSource, findMatches, gridHeaderRequiredPx, type FetchingGridSource, type GridColumn, type GridColumnWidth, type GridHeaderGroup, type GridTextOptions,\n type GridFindAllPage, type GridFindAllRequest, type GridFindPattern, type GridFindRequest, type GridFindResult, type GridPage, type GridQuery, type GridSelection, type GridTemplate,\n} from '@ex-grid/core';\nimport { decimalText } from '@ex-grid/data';\nimport {\n PivotRowKey, type PivotDisplayRow, type PivotFieldItem, type PivotLabelColumn, type PivotLayout, type PivotReportMetadata, type PivotReportSettings, type PivotReportSource,\n type PivotReportState, type PivotToggle, type PivotValue,\n} from '@ex-grid/pivot-engine';\nimport { elementAt } from './must';\nimport { findAllInReport, findInReport, type ReportFindAllMatches, type ReportFindGivenUp } from './report-find';\nimport { summarizeReport } from './report-summary';\nimport type { PivotScreenWords } from './words';\n\n/**\n * A value cell's value as the grid holds it: the report's own text is what the cell paints, and the value's\n * own text, which the grid copies as the raw flavour and a spreadsheet reads back as the same number, is the\n * exact decimal's digits where there is one, the double's shortest text otherwise, and an error's text for an\n * error (ADR-0005, ADR-0060). The grid reads an object's text through `toString`, as C#'s reads `ToString`.\n */\nexport class ReportCellValue {\n readonly #value: PivotValue;\n\n constructor(value: PivotValue) {\n this.#value = value;\n }\n\n /** The text the report shows. */\n get text(): string {\n return this.#value.text;\n }\n\n /** The raw text the clipboard carries. */\n toString(): string {\n const { error, exact, number } = this.#value;\n if (error !== undefined) return error;\n return exact === undefined ? String(number) : decimalText(exact);\n }\n}\n\n/**\n * The Match Mark's rule over the report (ADR-0332 \u00A74): the reference rule over the text a cell shows, which is the\n * text its Copy reads and `findInReport` finds by, so the mark and the step agree. One function for every pivot:\n * its identity reaches the grid (ADR-0003).\n */\nexport function reportMatch(row: PivotDisplayRow, column: GridColumn<PivotDisplayRow>, pattern: GridFindPattern): boolean {\n const value = column.value(row);\n // A label with no text, or a cell with no value, shows nothing.\n if (value === undefined) return findMatches('', pattern);\n if (value instanceof ReportCellValue) return findMatches(value.text, pattern);\n if (typeof value === 'string') return findMatches(value, pattern);\n throw new TypeError(`Internal: the report column '${column.name}' holds neither a label nor a value.`);\n}\n\n/** A display row's identity across Windows and reports: its role, its Value Field and its Items. */\nexport function reportRowKey(row: PivotDisplayRow): string {\n return new PivotRowKey(row.role, row.valueField, row.items).toString();\n}\n\n/** What a label cell paints beside its text: a level's indent, and the expand / collapse button's name and press. */\nexport interface LabelPainter {\n /** A level's indent, in pixels: the em of the grid's font, as the report source charges it (ADR-0151). */\n readonly indentPx: number;\n /** The button's accessible name: \"Expand East\", \"Collapse East\". */\n readonly toggleName: (toggle: PivotToggle) => string;\n /** The button pressed on `row`: the Item is to be collapsed or expanded. */\n readonly toggled: (toggle: PivotToggle, row: PivotDisplayRow) => void;\n}\n\n/**\n * One label column's cells (ADR-0059), the Razor component's markup: the indent, the expand / collapse button\n * of an outer Item, and the label. The button is pressed, never reached by Tab, and takes the keyboard when\n * Space asks the cell to (ADR-0037); a press on it keeps the keyboard where it was, as the grid's own buttons\n * do, and a double click on it stops there, since its offsets are the button's (ADR-0063).\n */\nfunction labelTemplate(index: number, painter: LabelPainter): GridTemplate<PivotDisplayRow> {\n // A button pressed by Enter or Space asks the report again, and is painted anew: the grid takes back the\n // keyboard it held (ADR-0037).\n return (slot, cell) => {\n const label = elementAt(cell.row.labels, index);\n const document = slot.ownerDocument;\n const box = document.createElement('span');\n box.className = 'ex-pivot-label';\n if (label.indent > 0) box.style.paddingLeft = `${label.indent * painter.indentPx}px`;\n const listening = new AbortController();\n const { toggle } = label;\n let button: HTMLButtonElement | undefined;\n if (toggle !== undefined) {\n const made = document.createElement('button');\n made.type = 'button';\n made.className = toggle.isCollapsed ? 'ex-pivot-toggle ex-interactive ex-pivot-toggle-collapsed' : 'ex-pivot-toggle ex-interactive';\n made.tabIndex = -1;\n made.setAttribute('data-ex-claims', 'click');\n made.setAttribute('aria-expanded', toggle.isCollapsed ? 'false' : 'true');\n made.setAttribute('aria-label', painter.toggleName(toggle));\n made.textContent = toggle.isCollapsed ? '+' : '\\u2212';\n const { signal } = listening;\n made.addEventListener('mousedown', event => { event.preventDefault(); }, { signal });\n made.addEventListener('click', () => { painter.toggled(toggle, cell.row); }, { signal });\n made.addEventListener('dblclick', event => { event.stopPropagation(); }, { signal });\n box.append(made);\n button = made;\n }\n if (label.text !== undefined) {\n const text = document.createElement('span');\n text.className = 'ex-pivot-label-text';\n text.textContent = label.text;\n box.append(text);\n }\n slot.append(box);\n if (button !== undefined && cell.focusRequest !== 0) cell.takeKeyboard(button);\n return () => {\n listening.abort();\n box.remove();\n };\n };\n}\n\nfunction labelColumn(name: string, header: string, index: number, width: GridColumnWidth, painter: LabelPainter): GridColumn<PivotDisplayRow> {\n return Object.freeze({\n name,\n header,\n type: 'text',\n width,\n // A label is Text; an Item the report shows as a number is still a label, aligned as text (ADR-0059).\n align: 'left',\n queryable: false,\n value: (row: PivotDisplayRow) => elementAt(row.labels, index).text,\n template: labelTemplate(index, painter),\n });\n}\n\nfunction cellValueOf(value: unknown): string {\n if (!(value instanceof ReportCellValue)) throw new TypeError('Internal: a value cell holds a report value.');\n return value.text;\n}\n\nfunction valueColumn(name: string, header: string, index: number, width: GridColumnWidth | undefined): GridColumn<PivotDisplayRow> {\n const values = new WeakMap<PivotDisplayRow, ReportCellValue | undefined>();\n return Object.freeze({\n name,\n header,\n type: 'number',\n ...(width === undefined ? {} : { width }),\n queryable: false,\n value: (row: PivotDisplayRow) => {\n if (values.has(row)) return values.get(row);\n const shown = row.values[index];\n const cell = shown === undefined ? undefined : new ReportCellValue(shown);\n values.set(row, cell);\n return cell;\n },\n format: cellValueOf,\n });\n}\n\n/** What the grid is handed for one report: its columns, its Header Groups and how many columns are pinned. */\nexport interface ReportColumnSet {\n readonly columns: readonly GridColumn<PivotDisplayRow>[];\n readonly headerGroups: readonly GridHeaderGroup[];\n readonly pinnedColumnCount: number;\n}\n\n/** The narrowest and the widest a label column is laid out at when the user has not set its width (ADR-0059). */\nconst minLabelWidthPx = 60;\nconst maxLabelWidthPx = 480;\n\nfunction fixedWidth(px: number): GridColumnWidth {\n return Object.freeze({ px, minPx: Math.min(40, px), maxPx: Math.max(400, px) });\n}\n\n/**\n * The grid's columns for each report, made once for each name, header, place and width and held, so a report\n * that keeps a column hands the grid the same column, and its cells are not painted again (ADR-0003). Made\n * anew when what a label cell paints with changes.\n */\nexport class ReportColumns {\n readonly #painter: LabelPainter;\n readonly #text: GridTextOptions;\n readonly #made = new Map<string, GridColumn<PivotDisplayRow>>();\n\n constructor(painter: LabelPainter, text: GridTextOptions) {\n this.#painter = painter;\n this.#text = text;\n }\n\n /**\n * The grid's columns for a report: each label column, then each value column, with any width the user\n * dragged a column of that name to (ADR-0016), and the column Items as Header Groups over the value columns,\n * never over the pinned labels (ADR-0032). A label column the user has not sized is as wide as its header\n * or its widest label, which the report source estimated under the grid's text geometry, between 60 and 480\n * pixels, since its cells paint a template that no Auto width observes.\n */\n of(metadata: PivotReportMetadata, userWidths: ReadonlyMap<string, number>): ReportColumnSet {\n const columns: GridColumn<PivotDisplayRow>[] = [];\n metadata.labelColumns.forEach((label, index) => {\n const user = userWidths.get(label.name);\n const px = user ?? this.#labelWidth(label.header, metadata.labelWidths[index]);\n columns.push(this.#held(`l\\u001F${label.name}\\u001F${label.header}\\u001F${index}\\u001F${px}`,\n () => labelColumn(label.name, label.header, index, fixedWidth(px), this.#painter)));\n });\n metadata.valueColumns.forEach((value, index) => {\n const px = userWidths.get(value.name);\n columns.push(this.#held(`v\\u001F${value.name}\\u001F${value.header}\\u001F${index}\\u001F${px}`,\n () => valueColumn(value.name, value.header, index, px === undefined ? undefined : fixedWidth(px))));\n });\n // Columns no report has kept are let go once they outnumber the ones in use, as the Razor component's are.\n if (this.#made.size > (4 * columns.length) + 64) {\n const used = new Set(columns);\n for (const [key, column] of this.#made) if (!used.has(column)) this.#made.delete(key);\n }\n const names = metadata.valueColumns.map(column => column.name);\n const headerGroups = metadata.headerSpans.map(span => Object.freeze({\n label: span.label,\n columns: Object.freeze(names.slice(span.firstColumn, span.firstColumn + span.columnCount)),\n tier: span.tier,\n tierSpan: span.tierSpan,\n }));\n return Object.freeze({ columns: Object.freeze(columns), headerGroups: Object.freeze(headerGroups), pinnedColumnCount: metadata.labelColumns.length });\n }\n\n #labelWidth(header: string, label: number | undefined): number {\n const headerPx = gridHeaderRequiredPx(header, { ...this.#text, menuButton: false, sortable: false });\n // A report answered without label geometry has no estimate, and its header alone sizes it.\n const widest = label === undefined ? headerPx : Math.max(headerPx, label);\n return Math.min(maxLabelWidthPx, Math.max(minLabelWidthPx, Math.ceil(widest)));\n }\n\n #held(key: string, make: () => GridColumn<PivotDisplayRow>): GridColumn<PivotDisplayRow> {\n let column = this.#made.get(key);\n if (column === undefined) {\n column = make();\n this.#made.set(key, column);\n }\n return column;\n }\n}\n\n/** Thrown when a Window is answered from another report than the one the grid shows: the data moved on, and\n * the report is asked again rather than shown with rows of two reports (spine rule 6). */\nexport class ReportMovedError extends Error {\n constructor() {\n super('The report source answered a Window of another report than the one shown: the report is asked again.');\n this.name = 'ReportMovedError';\n }\n}\n\nfunction pageOf(state: PivotReportState): GridPage<PivotDisplayRow> {\n return Object.freeze({\n rows: state.rows,\n start: state.window.start,\n totalCount: state.metadata.rowCount,\n orderToken: state.metadata.rowSequenceVersion,\n });\n}\n\n/** What the rows of one report are asked under. */\nexport interface ReportRowsRequest {\n readonly source: PivotReportSource;\n readonly layout: PivotLayout;\n readonly settings: PivotReportSettings;\n readonly maxLeaves: number;\n /** The answer the report was shown from, whose rows are served without asking again. */\n readonly answered: PivotReportState;\n /** A request identity for each Window asked. */\n readonly nextRequestId: () => string;\n /** Told when a Window came from another report: the report is to be asked again. */\n readonly moved: () => void;\n /** Told when a Find step over the report cannot go on, before the step is given up (ADR-0332 \u00A71). */\n readonly findGivenUp: (why: ReportFindGivenUp) => void;\n /** The pivot's words as they stand when a Selection Summary is declined (ADR-0060). */\n readonly words: () => PivotScreenWords;\n}\n\n/**\n * The rows of one report as a Grid Source (ADR-0350 section 16): each range the grid asks for is a Window of\n * the same report, under the layout and settings it was answered under, named by its Report Version, and a\n * Window of any other report is refused rather than shown beside it.\n */\nexport function reportRows(request: ReportRowsRequest): FetchingGridSource<PivotDisplayRow> {\n const { answered } = request;\n const version = answered.metadata.version;\n const fetch = async (query: GridQuery, signal: AbortSignal): Promise<GridPage<PivotDisplayRow>> => {\n const { start, count } = query.range;\n const held = answered.window;\n // The rows the report has end at its row count: a range past it is held when what of it there is, is.\n const end = Math.min(start + count, answered.metadata.rowCount);\n if (start >= held.start && end <= held.start + answered.rows.length) return pageOf(answered);\n const update = await request.source.window(Object.freeze({\n requestId: request.nextRequestId(),\n layout: request.layout,\n settings: request.settings,\n window: Object.freeze({ start, count }),\n baseline: version,\n markChanges: false,\n maxLeaves: request.maxLeaves,\n }), signal);\n if (update.refusal !== undefined) throw new Error(update.refusal.message);\n if (update.metadata.version !== version) throw new ReportMovedError();\n return pageOf(update);\n };\n // A step that cannot go on is given up: nothing moves, and nothing claims \"no match\" for cells it could not read\n // (ADR-0025). The grid takes an AbortError as a step its Consumer gave up; the pivot says why while the report is\n // the one shown, and over one since replaced the grid says its source changed.\n const find = async (step: GridFindRequest, _query: unknown, signal: AbortSignal): Promise<GridFindResult> => {\n const read = await findInReport(request.source, answered.metadata, step, signal);\n if (read.kind === 'answered') return read.answer;\n request.findGivenUp(read);\n throw new DOMException('The Find step over the report was given up.', 'AbortError');\n };\n // Find All over the report as shown (ADR-0470 \u00A77): the report is read to its end once for a question, and its\n // pages are read from what was found while the question stands. A report that moves is another source.\n let listed: { readonly key: string; readonly matches: ReportFindAllMatches } | undefined;\n const findAll = async (asked: GridFindAllRequest, _query: unknown, signal: AbortSignal): Promise<GridFindAllPage> => {\n const key = JSON.stringify([asked.text, asked.matchCase, asked.wholeCell, asked.scope, asked.columns]);\n if (listed?.key !== key) {\n const read = await findAllInReport(request.source, answered.metadata, asked, signal);\n if (read.kind !== 'answered') {\n request.findGivenUp(read);\n throw new DOMException('The Find All over the report was given up.', 'AbortError');\n }\n listed = { key, matches: read.matches };\n }\n return listed.matches.page(asked.start, asked.count, asked.rowSequenceVersion);\n };\n return GridSource.fetch(fetch, {\n rowKey: reportRowKey,\n readAheadRows: 60,\n find,\n findAll,\n // The Selection Summary is the report source's, over the report the selection was made on (ADR-0130).\n summarize: (summary, _query, signal) => summarizeReport(request.source, version, summary, request.words(), signal),\n // A Window of another report is never shown beside this one's rows: the pivot asks again, and the grid\n // stands on what it holds meanwhile. Any other failure is the grid's to say (ADR-0025).\n onFetchFailed: ({ error }) => {\n if (!(error instanceof ReportMovedError)) throw error;\n request.moved();\n },\n });\n}\n\n/** What one cell of the report stands for (ADR-0340): its row's Items and, for a value cell, its column's. */\nexport interface PivotCellItems {\n /** The Items its row's path names, outermost first. */\n readonly row: readonly PivotFieldItem[];\n /** The Items its column's path names, outermost first; none for a label cell. */\n readonly column: readonly PivotFieldItem[];\n}\n\n// A label column of its own field (outline and tabular forms) shows that field's Item, so its cell stands for the\n// path down to it; the compact form's one column shows the row's own.\nfunction labelPath(path: readonly PivotFieldItem[], column: PivotLabelColumn): readonly PivotFieldItem[] {\n const at = column.field === undefined ? -1 : path.findIndex(item => item.field === column.field);\n return at < 0 ? path : Object.freeze(path.slice(0, at + 1));\n}\n\nconst noItems: readonly PivotFieldItem[] = Object.freeze([]);\n\n/**\n * What each cell of a selection of the report grid stands for (ADR-0340, Q5), as the Razor component's `ItemsOf`\n * reads it: each cell once, in the order selected. `undefined` when the selection reaches a row the grid does not\n * hold drawn now, or a column past the report's, which is read from no Items rather than from some of them\n * (spine rule 1).\n */\nexport function cellItems(\n selection: GridSelection, metadata: PivotReportMetadata, rows: readonly PivotDisplayRow[], windowStart: number,\n): readonly PivotCellItems[] | undefined {\n const labels = metadata.labelColumns.length;\n // A cell two ranges both hold is said once; one range holds each of its cells once.\n const seen = selection.ranges.length > 1 ? new Set<string>() : undefined;\n const cells: PivotCellItems[] = [];\n for (const range of selection.ranges) {\n const bottom = range.topRow + range.rowCount - 1;\n const right = range.leftColumn + range.columnCount - 1;\n if (range.topRow < windowStart || bottom >= windowStart + rows.length || right >= labels + metadata.valueColumns.length) return undefined;\n for (let r = range.topRow; r <= bottom; r++) {\n const row = elementAt(rows, r - windowStart);\n for (let c = range.leftColumn; c <= right; c++) {\n if (seen !== undefined) {\n const key = `${r},${c}`;\n if (seen.has(key)) continue;\n seen.add(key);\n }\n cells.push(Object.freeze(c < labels\n ? { row: labelPath(row.rowPath, elementAt(metadata.labelColumns, c)), column: noItems }\n : { row: row.rowPath, column: elementAt(metadata.valueColumns, c - labels).columnPath }));\n }\n }\n }\n return Object.freeze(cells);\n}\n", "// Find over the report as shown (ADR-0332 \u00A71), the Razor component's FindInReportAsync: ExPivot answers each step\n// of its report grid's Find as that grid's Consumer (ADR-0055). What is searched is every cell the report lays\n// out, the row labels, values and totals, by its displayed text, the text the user reads. The column Items and the\n// value captions stand in the grid's headers and Header Groups, which the grid searches itself (ADR-0333). A\n// collapsed group is not searched inside, because its rows are not laid out, and nothing is expanded to show a\n// match: a search never changes the report's shape. The cells outside the Window are read from the report source\n// by the Report Version on screen, as Copy reads them, in blocks, so a step that finds early stops reading.\n\nimport { findAllPage, findMatches, type GridFindAllPage, type GridFindAllRequest, type GridFindRequest, type GridFindResult } from '@ex-grid/core';\nimport type { PivotReportCopyBlock, PivotReportMetadata, PivotReportRefusal, PivotReportSource } from '@ex-grid/pivot-engine';\nimport { elementAt } from './must';\n\n// How many cells one read of the report asks for: a step that finds early stops reading, and a remote report is\n// asked in blocks rather than for the whole report at once.\nconst findBlockCells = 20_000;\n\n/** What one step over one Report Version came to: an answer, or why it cannot be given. */\nexport type ReportFindRead =\n | { readonly kind: 'answered'; readonly answer: GridFindResult }\n /** The source no longer holds the Report Version the step reads. */\n | { readonly kind: 'notHeld' }\n /** The source refused to be read. */\n | { readonly kind: 'refused'; readonly refusal: PivotReportRefusal }\n /** The source answered another version or range than it was asked. */\n | { readonly kind: 'invalid' };\n\n/** A step that cannot go on, and why. */\nexport type ReportFindGivenUp = Exclude<ReportFindRead, { readonly kind: 'answered' }>;\n\nconst notFound: ReportFindRead = Object.freeze({ kind: 'answered', answer: Object.freeze({ found: false }) });\nconst notHeld: ReportFindGivenUp = Object.freeze({ kind: 'notHeld' });\nconst invalid: ReportFindGivenUp = Object.freeze({ kind: 'invalid' });\n\n/**\n * One Find step over the report `metadata` describes, in ADR-0055's order: row by row, across a row in the\n * request's column order, from the cell after the Focus, wrapping, the Focus's own cell last; within the selection\n * when more than one cell is selected. A column of the request the report does not lay out is skipped.\n */\nexport async function findInReport(\n source: PivotReportSource, metadata: PivotReportMetadata, request: GridFindRequest, signal: AbortSignal,\n): Promise<ReportFindRead> {\n const rows = metadata.rowCount;\n const known = new Set([...metadata.labelColumns.map(column => column.name), ...metadata.valueColumns.map(column => column.name)]);\n // The request's columns the report lays out, by their position in the request.\n const read = request.columns.flatMap((name, position) => (known.has(name) ? [{ name, position }] : []));\n const columns = request.columns.length;\n if (request.text === '' || rows === 0 || read.length === 0) return notFound;\n\n // Where the walk starts: past the Focus, which is looked at last; without one, from the first cell (the last,\n // backward), as the reference step walks.\n const { backward, from, scope } = request;\n const [startRow, startColumn] = from !== undefined && from.row >= 0 && from.row < rows && from.column >= 0 && from.column < columns\n ? [from.row, from.column]\n : backward ? [0, 0] : [rows - 1, columns - 1];\n const step = backward ? -1 : 1;\n const names = Object.freeze(read.map(column => column.name));\n const blockRows = Math.max(1, Math.floor(findBlockCells / names.length));\n\n // The rows a block may hold: within the scope's rows when there is one, so no block reads past them.\n let first = scope === undefined ? 0 : rows - 1;\n let last = scope === undefined ? rows - 1 : 0;\n if (scope !== undefined) {\n for (const range of scope) {\n first = Math.min(first, Math.max(0, range.topRow));\n last = Math.max(last, Math.min(rows - 1, range.topRow + range.rowCount - 1));\n }\n }\n // The Focus's row is visited twice: first past the Focus, last up to it and on it.\n const visited = (visit: number, position: number): boolean => {\n if (visit === 0) return backward ? position < startColumn : position > startColumn;\n if (visit === rows) return backward ? position >= startColumn : position <= startColumn;\n return true;\n };\n\n let block: PivotReportCopyBlock | undefined;\n let blockTop = 0;\n for (let visit = 0; visit <= rows; visit++) {\n signal.throwIfAborted();\n const row = (((startRow + step * visit) % rows) + rows) % rows;\n if (scope !== undefined && !scope.some(range => row >= range.topRow && row < range.topRow + range.rowCount)) continue;\n // A row with no cell left to look at is not read: the Focus at the end of the last row, a step from the start.\n if (!read.some(({ position }) => visited(visit, position))) continue;\n if (block === undefined || row < blockTop || row >= blockTop + block.rows.length) {\n // Once the walk has wrapped, it ends on the Focus's row: a block reads no row past it, which was searched first.\n const wrapped = visit > 0 && (backward ? row >= startRow : row <= startRow);\n const top = backward ? Math.max(first, row - blockRows + 1, wrapped ? startRow : 0) : row;\n const bottom = backward ? row : Math.min(last, row + blockRows - 1, wrapped ? startRow : rows - 1);\n const answer = await source.copy(Object.freeze({\n version: metadata.version,\n columns: names,\n ranges: Object.freeze([Object.freeze({ top, left: 0, bottom, right: names.length - 1 })]),\n maxCells: (bottom - top + 1) * names.length,\n }), signal);\n signal.throwIfAborted();\n if (answer.refusal?.kind === 'reportVersionNotHeld') return notHeld;\n if (answer.refusal !== undefined) return Object.freeze({ kind: 'refused', refusal: answer.refusal });\n const got = answer.blocks[0];\n if (answer.version !== metadata.version || answer.blocks.length !== 1 || got === undefined || got.rows.length !== bottom - top + 1\n || got.rows.some(cells => cells.length !== names.length)) {\n return invalid;\n }\n block = got;\n blockTop = top;\n }\n const cells = elementAt(block.rows, row - blockTop);\n for (let k = 0; k < read.length; k++) {\n const index = backward ? read.length - 1 - k : k;\n const { name, position } = elementAt(read, index);\n if (!visited(visit, position)) continue;\n if (scope !== undefined && !scope.some(range => row >= range.topRow && row < range.topRow + range.rowCount\n && position >= range.leftColumn && position < range.leftColumn + range.columnCount)) continue;\n if (findMatches(elementAt(cells, index).text, request)) {\n return Object.freeze({ kind: 'answered', answer: Object.freeze({ found: true, row, column: name }) });\n }\n }\n }\n return notFound;\n}\n\n/** Every match of one Find All over one Report Version (ADR-0470 \u00A77): each cell's ordinal in row-major order among the\n * request's columns, and the text it is shown with, found once and read a page at a time. */\nexport class ReportFindAllMatches {\n readonly #columns: readonly string[];\n readonly #ordinals: readonly number[];\n readonly #texts: readonly string[];\n\n constructor(columns: readonly string[], ordinals: readonly number[], texts: readonly string[]) {\n this.#columns = columns;\n this.#ordinals = ordinals;\n this.#texts = texts;\n }\n\n /** How many cells match. */\n get total(): number {\n return this.#ordinals.length;\n }\n\n /** The entries from `start`, `count` of them or every one left, under `rowSequenceVersion`. */\n page(start: number, count: number, rowSequenceVersion: number): GridFindAllPage {\n if (!Number.isInteger(start) || start < 0) throw new RangeError(`A Find All page starts at an entry at or after 0, not ${String(start)}.`);\n if (!Number.isInteger(count) || count < 1) throw new RangeError(`A Find All page asks for 1 entry or more, not ${String(count)}.`);\n const columns = this.#columns.length;\n const matches = this.#ordinals.slice(start, start + count).map((ordinal, i) => ({\n row: Math.floor(ordinal / columns),\n column: elementAt(this.#columns, ordinal % columns),\n text: elementAt(this.#texts, start + i),\n }));\n return findAllPage(this.total, matches, rowSequenceVersion);\n }\n}\n\n/** What one Find All over one Report Version came to: its matches, or why it cannot be given. */\nexport type ReportFindAllRead = { readonly kind: 'answered'; readonly matches: ReportFindAllMatches } | ReportFindGivenUp;\n\n/**\n * Every cell a Find step over the report would stop on (ADR-0470 \u00A77), in a forward walk's order from the first cell:\n * row by row, across a row in the request's column order, within the scope when there is one. The report is read from\n * its source in blocks by the Report Version on screen, as a step reads it, but to its end: the count is exact.\n */\nexport async function findAllInReport(\n source: PivotReportSource, metadata: PivotReportMetadata, request: Omit<GridFindAllRequest, 'start' | 'count'>, signal: AbortSignal,\n): Promise<ReportFindAllRead> {\n const rows = metadata.rowCount;\n const known = new Set([...metadata.labelColumns.map(column => column.name), ...metadata.valueColumns.map(column => column.name)]);\n const read = request.columns.flatMap((name, position) => (known.has(name) ? [{ name, position }] : []));\n const columns = request.columns.length;\n const ordinals: number[] = [];\n const texts: string[] = [];\n const done = (): ReportFindAllRead => Object.freeze({ kind: 'answered', matches: new ReportFindAllMatches(Object.freeze([...request.columns]), ordinals, texts) });\n if (request.text === '' || rows === 0 || read.length === 0) return done();\n const { scope } = request;\n const names = Object.freeze(read.map(column => column.name));\n const blockRows = Math.max(1, Math.floor(findBlockCells / names.length));\n let first = scope === undefined ? 0 : rows - 1;\n let last = scope === undefined ? rows - 1 : 0;\n if (scope !== undefined) {\n for (const range of scope) {\n first = Math.min(first, Math.max(0, range.topRow));\n last = Math.max(last, Math.min(rows - 1, range.topRow + range.rowCount - 1));\n }\n }\n for (let top = first; top <= last; top += blockRows) {\n signal.throwIfAborted();\n const bottom = Math.min(last, top + blockRows - 1);\n const answer = await source.copy(Object.freeze({\n version: metadata.version,\n columns: names,\n ranges: Object.freeze([Object.freeze({ top, left: 0, bottom, right: names.length - 1 })]),\n maxCells: (bottom - top + 1) * names.length,\n }), signal);\n signal.throwIfAborted();\n if (answer.refusal?.kind === 'reportVersionNotHeld') return notHeld;\n if (answer.refusal !== undefined) return Object.freeze({ kind: 'refused', refusal: answer.refusal });\n const block = answer.blocks[0];\n if (answer.version !== metadata.version || answer.blocks.length !== 1 || block === undefined || block.rows.length !== bottom - top + 1\n || block.rows.some(cells => cells.length !== names.length)) {\n return invalid;\n }\n for (let row = top; row <= bottom; row++) {\n const cells = elementAt(block.rows, row - top);\n read.forEach(({ position }, index) => {\n if (scope !== undefined && !scope.some(range => row >= range.topRow && row < range.topRow + range.rowCount\n && position >= range.leftColumn && position < range.leftColumn + range.columnCount)) return;\n const { text } = elementAt(cells, index);\n if (!findMatches(text, request)) return;\n ordinals.push((row * columns) + position);\n texts.push(text);\n });\n }\n }\n return done();\n}\n", "// The Selection Summary over the report (ADR-0130), the Razor component's `SummarizeReportAsync`: the report\n// source sums the cells it laid out, under the Report Version the selection was made on, and the figures are\n// read from its counts, sum and extremes as C#'s `GridSummaryCells` reads a server's parts. A figure that reads\n// numbers is written in the Focus value's number format, as the report shows that value.\n\nimport { answeredSummary, declinedSummary, summaryFigureOrder, type AggregateResult, type GridSummaryRequest, type GridSummaryResult, type SummaryFigure } from '@ex-grid/core';\nimport { formatPivotFigure, pivotNumberAverage, pivotNumberCanonical, pivotNumberValue, type PivotNumber, type PivotReportSource, type PivotReportSummaryResult } from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\nimport type { PivotScreenWords } from './words';\n\nconst empty: AggregateResult = Object.freeze({ kind: 'empty' });\n\n/** The figures `request` asks for over the report of `version`, or a decline in ExPivot's words (ADR-0060). */\nexport async function summarizeReport(\n source: PivotReportSource, version: string, request: GridSummaryRequest, words: PivotScreenWords, signal: AbortSignal,\n): Promise<GridSummaryResult> {\n const { focus } = request;\n const query = Object.freeze({\n version,\n columns: request.columns,\n ranges: Object.freeze(request.ranges.map(range => Object.freeze({\n top: range.topRow, left: range.leftColumn, bottom: range.topRow + range.rowCount - 1, right: range.leftColumn + range.columnCount - 1,\n }))),\n ...(focus === undefined ? {} : { focusRow: focus.row, focusColumn: focus.column }),\n });\n const answer = await source.summary(query, signal);\n if (answer.version !== version) return declinedSummary(words.word('summary-another-version'));\n if (answer.refusal !== undefined) return declinedSummary(words.reportRefused(answer.refusal));\n // An error is counted among the values: an answer that says one was selected and counts no value contradicts itself.\n if (answer.hasError && answer.values <= 0) return declinedSummary(words.word('summary-inconsistent-errors'));\n return figuresOf(answer, request.figures);\n}\n\n// Each figure asked for, in Excel's order, by the rules C#'s accumulator reads merged parts by: a figure that reads\n// numbers is empty where no cell holds one, an error among the values shows only the counts, a value that is no finite\n// number makes every figure that reads numbers #NUM!, and a figure that overflows is #NUM! alone.\nfunction figuresOf(answer: PivotReportSummaryResult, asked: readonly SummaryFigure[]): GridSummaryResult {\n const { values, numbers, min, max, hasError, numberFormat, locale } = answer;\n const figures: Partial<Record<SummaryFigure, AggregateResult>> = {};\n const texts: Partial<Record<SummaryFigure, string>> = {};\n // A value that is no finite number is one of the extremes; a sum of finite values may still overflow.\n const nonFinite = [min, max].some(number => number !== undefined && !finite(number));\n for (const figure of summaryFigureOrder) {\n if (!asked.includes(figure)) continue;\n const counts = figure === 'count' || figure === 'numericalCount';\n if (!counts && numbers === 0) figures[figure] = empty;\n else if (!counts && hasError) figures[figure] = Object.freeze({ kind: 'error', error: 'errorAmongValues' });\n else if (values === 0) figures[figure] = empty;\n else if (counts) figures[figure] = countOf(figure === 'count' ? values : numbers);\n else {\n const number = pivotNumberCanonical(numberOf(figure, answer));\n if (nonFinite || !finite(number)) {\n figures[figure] = Object.freeze({ kind: 'error', error: 'notANumber' });\n } else {\n figures[figure] = resultOf(number);\n if (numberFormat !== undefined) texts[figure] = formatPivotFigure(number, numberFormat, locale);\n }\n }\n }\n return answeredSummary(figures, texts);\n}\n\nfunction numberOf(figure: SummaryFigure, answer: PivotReportSummaryResult): PivotNumber {\n const { numbers, sum, min, max } = answer;\n switch (figure) {\n case 'sum': return held(sum, figure);\n case 'average': return pivotNumberAverage(held(sum, figure), numbers);\n case 'min': return held(min, figure);\n case 'max': return held(max, figure);\n case 'count':\n case 'numericalCount': throw new Error(`Internal: ${figure} is a count.`);\n default: return unreachable(figure);\n }\n}\n\n// The report source answers a sum and both extremes wherever it counted a number.\nfunction held(number: PivotNumber | undefined, figure: SummaryFigure): PivotNumber {\n if (number === undefined) throw new Error(`The report source counted numbers and answered no ${figure} of them (ADR-0130).`);\n return number;\n}\n\nfunction finite(number: PivotNumber): boolean {\n return Number.isFinite(pivotNumberValue(number));\n}\n\nfunction countOf(count: number): AggregateResult {\n return Object.freeze({ kind: 'number', number: count, exact: Object.freeze({ mantissa: BigInt(count), scale: 0 }) });\n}\n\nfunction resultOf(number: PivotNumber): AggregateResult {\n return Object.freeze(number.kind === 'exact'\n ? { kind: 'number', number: pivotNumberValue(number), exact: number.value }\n : { kind: 'number', number: number.value, exact: undefined });\n}\n", "// The report's own commands in the grid's Context Menu (ADR-0036, ADR-0059): the ones the Razor component's\n// ContextCommandsFor builds, in its order and under its ids, after the grid's clipboard commands. Each is enabled from\n// the report the menu was opened over, and runs against the report's layout when it is chosen: where that layout no\n// longer holds what it was for, it changes nothing (spine rule 6).\n\nimport type { GridCommand } from '@ex-grid/core';\nimport {\n isItemCollapsed, placementOf, removeEntry, setCollapsed, setFieldCollapsed, setSort, sortsEqual, valueFieldsEqual,\n type PivotDisplayRow, type PivotFieldItem, type PivotFieldPlacement, type PivotLayout, type PivotReportMetadata, type PivotSort,\n} from '@ex-grid/pivot-engine';\nimport { defined, elementAt } from './must';\n\n/** What the menu was opened over. */\nexport interface ReportMenuModel {\n readonly metadata: PivotReportMetadata;\n /** The row it was opened on, which the report on screen holds. */\n readonly row: PivotDisplayRow;\n /** The name of the column it was opened on. */\n readonly column: string;\n /** The report's layout now: the one it shows, or is on its way to, which its commands are run against. */\n readonly report: PivotLayout;\n /** The pane's layout now, which is the report's unless Defer Layout Update holds another: Value Field Settings\u2026\n * opens in the pane, under the entry it shows. */\n readonly pane: PivotLayout;\n readonly fieldListShown: boolean;\n /** A field's caption. */\n readonly captionOf: (field: string) => string;\n}\n\n/** What the commands do. */\nexport interface ReportMenuActions {\n /** A change of the report's layout, made from the layout when chosen; `undefined` changes nothing. An Item\n * expanded or collapsed is named, and keeps the Focus in the report the change brings. */\n readonly edit: (edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: PivotFieldItem) => void;\n /** Show Details on the row's value cell in `valueColumn`. */\n readonly showDetails: (valueColumn: number) => void;\n /** Value Field Settings\u2026 for the Value Field at `valueField`, in the pane, while `holds` says the pane holds the\n * one the cell showed there. */\n readonly valueFieldSettings: (valueField: number, holds: (pane: PivotLayout) => boolean) => void;\n readonly setFieldListShown: (shown: boolean) => void;\n}\n\n/** The id of \"Remove <field>\", which carries the field's caption after it. */\nexport const removeNamedFieldId = 'remove-named-field';\n\n/** The caption \"Remove <field>\" names, from its command's id; `undefined` for any other id. */\nexport function captionOfRemove(id: string): string | undefined {\n const prefix = `${removeNamedFieldId}:`;\n return id.startsWith(prefix) ? id.slice(prefix.length) : undefined;\n}\n\n// The outer Item a row's Expand and Collapse act on: the innermost of its row Items that has Items under it.\nfunction collapsibleItemOf(metadata: PivotReportMetadata, row: PivotDisplayRow): PivotFieldItem | undefined {\n const path = row.rowPath;\n for (let level = path.length - 1; level >= 0; level--) {\n if (level < metadata.layout.rows.length - 1) return elementAt(path, level);\n }\n return undefined;\n}\n\nfunction innermostFieldOf(row: PivotDisplayRow): string | undefined {\n return row.rowPath.at(-1)?.field;\n}\n\n// The Value Field a value cell shows: its row's, its column's, or the one Value Field.\nexport function valueFieldAt(metadata: PivotReportMetadata, row: PivotDisplayRow, valueColumn: number): number {\n if (row.valueField >= 0) return row.valueField;\n const column = elementAt(metadata.valueColumns, valueColumn);\n if (column.valueField >= 0) return column.valueField;\n return metadata.layout.values.length === 1 ? 0 : -1;\n}\n\nfunction inRows(layout: PivotLayout, field: string): boolean {\n return placementOf(layout, field)?.area === 'rows';\n}\n\n/** The report's commands for the cell the menu was opened on. Which Items and fields they stand for is read from the\n * report on screen; whether each would change something, from the report's layout, which it is run against. */\nexport function reportMenuCommands(model: ReportMenuModel, actions: ReportMenuActions): readonly GridCommand[] {\n const { metadata, row, column, report, pane, captionOf } = model;\n const labelColumn = metadata.labelColumns.findIndex(label => label.name === column);\n const valueColumn = labelColumn >= 0 ? -1 : metadata.valueColumns.findIndex(value => value.name === column);\n const commands: GridCommand[] = [];\n const add = (id: string, enabled: boolean, invoke: () => void): void => { commands.push(Object.freeze({ id, enabled, invoke })); };\n // A change of a field in Rows, made while the layout still holds it there.\n const editRows = (field: string, edit: (layout: PivotLayout) => PivotLayout | undefined, toggled?: PivotFieldItem): () => void =>\n () => { actions.edit(now => (inRows(now, field) ? edit(now) : undefined), toggled); };\n const inReport = (field: string): PivotFieldPlacement | undefined => report.rows.find(placement => placement.field === field);\n\n const item = collapsibleItemOf(metadata, row);\n if (item !== undefined) {\n const placement = inReport(item.field);\n const collapsed = placement !== undefined && isItemCollapsed(placement, item.item);\n const toggled = placement !== undefined && placement.toggledItems.length > 0;\n add('expand', collapsed, editRows(item.field, now => setCollapsed(now, item.field, item.item, false), item));\n add('collapse', placement !== undefined && !collapsed, editRows(item.field, now => setCollapsed(now, item.field, item.item, true), item));\n add('expand-field', placement !== undefined && (placement.collapsed || toggled), editRows(item.field, now => setFieldCollapsed(now, item.field, false)));\n add('collapse-field', placement !== undefined && (!placement.collapsed || toggled), editRows(item.field, now => setFieldCollapsed(now, item.field, true)));\n }\n\n const field = labelColumn >= 0\n ? elementAt(metadata.labelColumns, labelColumn).field ?? (row.valueField < 0 ? innermostFieldOf(row) : undefined)\n : innermostFieldOf(row);\n // A sort by a Value Field is by the one the cell shows, while the layout holds it at the same place.\n const sortBy = (sortField: string, sort: PivotSort, holds: (now: PivotLayout) => boolean): void => {\n const placement = inReport(sortField);\n add(sortCommandId(sort), placement !== undefined && holds(report) && !sortsEqual(placement.sort, sort),\n editRows(sortField, now => (holds(now) ? setSort(now, sortField, sort) : undefined)));\n };\n if (labelColumn >= 0 && field !== undefined) {\n sortBy(field, { direction: 'ascending' }, () => true);\n sortBy(field, { direction: 'descending' }, () => true);\n }\n if (valueColumn >= 0) {\n const valueField = valueFieldAt(metadata, row, valueColumn);\n const shown = metadata.layout.values[valueField];\n const holds = (now: PivotLayout): boolean => {\n const at = now.values[valueField];\n return shown !== undefined && at !== undefined && valueFieldsEqual(at, shown);\n };\n if (field !== undefined && shown !== undefined) {\n sortBy(field, { direction: 'ascending', byValue: valueField }, holds);\n sortBy(field, { direction: 'descending', byValue: valueField }, holds);\n }\n // Show Details is always offered: the tab, the dialog or the Consumer takes the records (ADR-0059). An empty\n // cell has none to show.\n add('show-details', row.values[valueColumn] !== undefined, () => { actions.showDetails(valueColumn); });\n // The panel opens in the pane, under the Value Field's entry: offered while the pane shows that Value Field\n // where the report does.\n if (shown !== undefined) add('value-field-settings', holds(pane), () => { actions.valueFieldSettings(valueField, holds); });\n }\n if (field !== undefined) {\n add(`${removeNamedFieldId}:${captionOf(field)}`, inReport(field) !== undefined, editRows(field, now => removeEntry(now, defined(placementOf(now, field), 'the field in Rows'))));\n }\n if (model.fieldListShown) add('hide-field-list', true, () => { actions.setFieldListShown(false); });\n else add('show-field-list', true, () => { actions.setFieldListShown(true); });\n return Object.freeze(commands);\n}\n\nfunction sortCommandId(sort: PivotSort): string {\n if (sort.byValue === undefined) return sort.direction === 'ascending' ? 'sort-ascending' : 'sort-descending';\n return sort.direction === 'ascending' ? 'sort-smallest-to-largest' : 'sort-largest-to-smallest';\n}\n\n", "// The words ExPivot's screen paints, by id (ADR-0370 section 10): the Consumer's label function first, then\n// the engine's English, and an id neither knows painted as itself, a missing word seen, never a blank. The\n// tables are the engine's, so a report's own words and the Field List's come from one place.\n\nimport { fillPivotWord, pivotWord, type PivotArea, type PivotLabel, type PivotLayoutChoice, type PivotReportRefusal, type PivotSourceRefusal } from '@ex-grid/pivot-engine';\nimport { unreachable } from './must';\n\n/** The words of one pivot, under the label function it was given. */\nexport class PivotScreenWords {\n readonly #label: PivotLabel | undefined;\n\n constructor(label: PivotLabel | undefined) {\n this.#label = label;\n }\n\n /** The label function the words were made with: the one the report is laid out with too. */\n get label(): PivotLabel | undefined {\n return this.#label;\n }\n\n /** The word for `id`. */\n word(id: string): string {\n return pivotWord(id, this.#label);\n }\n\n /** The template word for `id`, filled as .NET fills one. */\n fill(id: string, ...args: readonly string[]): string {\n return fillPivotWord(this.word(id), ...args);\n }\n\n /** What a source that threw says where the user sees it. */\n failed(error: unknown): string {\n return this.fill('source-failed', messageOf(error));\n }\n\n /** What a Stale Report says of a source that threw while asked for newer data (ADR-0067). */\n staleFailed(error: unknown): string {\n return this.fill('stale-source-failed', messageOf(error));\n }\n\n /** What a Pivot Source's refusal says where the user sees it: data that moved on under the report asks for a\n * refresh (ADR-0066), and any other refusal is said in the source's words. */\n sourceRefused(refusal: PivotSourceRefusal): string {\n return refusal.kind === 'sourceVersionNotHeld' ? this.word('data-changed') : this.fill('source-refused', refusal.message);\n }\n\n /** What a report source's refusal says where the user sees it: the Pivot Source's refusal it carries in that\n * source's words, a report the source no longer holds as data that moved on (ADR-0066), and any other in the\n * report source's words. */\n reportRefused(refusal: PivotReportRefusal): string {\n if (refusal.sourceRefusal !== undefined) return this.sourceRefused(refusal.sourceRefusal);\n return refusal.kind === 'reportVersionNotHeld' ? this.word('data-changed') : this.fill('source-refused', refusal.message);\n }\n\n /** An Area's title: `Filters`, `Columns`, `Rows`, `Values`. */\n area(area: PivotArea): string {\n return this.word(areaWordId(area));\n }\n}\n\n/** The id of an Area's title. */\nexport function areaWordId(area: PivotArea): string {\n switch (area) {\n case 'filters': return 'area-filters';\n case 'columns': return 'area-columns';\n case 'rows': return 'area-rows';\n case 'values': return 'area-values';\n default: return unreachable(area);\n }\n}\n\n/** The id of a Layout menu choice's command, which is also the id of its word, as the Razor component's\n * `PivotCommandIds.LayoutChoice` names it (ADR-0061). */\nexport function layoutChoiceId(choice: PivotLayoutChoice): string {\n switch (choice) {\n case 'doNotShowSubtotals': return 'subtotals-do-not-show';\n case 'showSubtotalsAtBottom': return 'subtotals-at-bottom';\n case 'showSubtotalsAtTop': return 'subtotals-at-top';\n case 'grandTotalsOff': return 'grand-totals-off';\n case 'grandTotalsOn': return 'grand-totals-on';\n case 'grandTotalsOnRowsOnly': return 'grand-totals-rows-only';\n case 'grandTotalsOnColumnsOnly': return 'grand-totals-columns-only';\n case 'compactForm': return 'form-compact';\n case 'outlineForm': return 'form-outline';\n case 'tabularForm': return 'form-tabular';\n case 'repeatItemLabels': return 'repeat-item-labels';\n case 'doNotRepeatItemLabels': return 'do-not-repeat-item-labels';\n default: return unreachable(choice);\n }\n}\n\n// What a thrown value says: an Error's message, and anything else as it prints.\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["held", "summaryFigureOrder", "formatPivotCount", "isValuesPseudoField", "placementOf", "placementsIn", "isItemCollapsed", "pivotWord", "setCollapsed", "setHiddenItems", "pivotItemKeyId", "element", "element", "held", "held", "records", "closed", "actions", "isValuesPseudoField", "moveEntry", "placementOf", "placementsIn", "removeEntry", "valuesPseudoField", "name", "field", "written", "end", "held", "valuesPseudoField", "placementOf", "edit", "isValuesPseudoField", "moveEntry", "placementsIn", "placement", "removeEntry", "formatPivotCount", "isValuesPseudoField", "placementOf", "placementsIn", "placesField", "valuesPseudoField", "checkedKey", "isValuesPseudoField", "valuesPseudoField", "written", "formatPivotCount", "placementOf", "placesField", "placementsIn", "end", "formatPivotCount", "placementOf", "placementsIn", "refusalWord", "setSort", "element", "setSort", "automatic", "aggregation", "refusalWord", "formatPivotCount", "element", "placementOf", "placementsIn", "findMatches", "cells", "findMatches", "held", "end", "placementOf", "removeEntry", "setFieldCollapsed", "setSort", "sortsEqual", "valueColumn", "placementOf", "actions", "labelColumn", "field", "setFieldCollapsed", "sortsEqual", "setSort", "removeEntry", "summaryFigureOrder", "end", "held", "formatPivotCount", "valueColumn", "path", "pivotWord", "isItemCollapsed", "setCollapsed", "isValuesPseudoField", "placementOf", "setHiddenItems", "placementsIn", "pivotItemKeyId", "element"]
|
|
7
7
|
}
|