@pythia-software/query-table-core 0.9.5 → 0.9.7

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cellDisplay.ts","../src/properties.ts","../src/schema.ts","../src/itemPage.ts","../src/metricNormalize.ts","../src/query.ts","../src/relativeTime.ts","../src/ops.ts","../src/agg.ts","../src/encode.ts","../src/setFilter.ts","../src/queryLinks.ts","../src/computed.ts","../src/formula.ts","../src/groupKeys.ts","../src/grouping.ts","../src/execution.ts","../src/metricPrecision.ts","../src/metricDistributions.ts","../src/metricDates.ts","../src/metrics.ts","../src/apply.ts","../src/adapters.ts","../src/propertyStorage.ts","../src/source.ts","../src/queryPatch.ts","../src/groupLinks.ts","../src/queryV3.ts","../src/drilldown.ts"],"sourcesContent":["/** Presentation hints only: field types still determine query/filter semantics. */\nexport interface JsonCellDisplay {\n kind: \"json\";\n /** auto accepts objects, JSON text and repeatedly encoded/escaped JSON text.\n * value keeps a native string literal; json parses text once; escaped unwraps it. */\n encoding?: \"auto\" | \"value\" | \"json\" | \"escaped\";\n /** Maximum string-unwrapping passes, 1–8. Default 4. */\n maxDecodeDepth?: number;\n /** Inline preview length, 20–500 characters. Default 80. */\n previewLength?: number;\n /** Override initially expanded container levels, 0–8.\n * The root starts open. By default, nested containers with up to 3 entries\n * open; larger nested containers collapse. */\n expandDepth?: number;\n}\n\ntype CalendarDisplay = {\n style?: \"human\" | \"iso\" | \"custom\";\n pattern?: string;\n /** UTC by default; an IANA timezone or local may be selected explicitly. */\n timeZone?: string;\n locale?: string;\n};\n\nexport type CellDisplay =\n | JsonCellDisplay\n | ({ kind: \"date\" | \"datetime\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" } & CalendarDisplay)\n | ({ kind: \"time\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" | \"secondsOfDay\" | \"millisecondsOfDay\" } & CalendarDisplay)\n | { kind: \"duration\"; sourceUnit?: \"milliseconds\" | \"seconds\" | \"minutes\" | \"hours\" | \"days\"; style?: \"human\" | \"long\" | \"clock\" | \"custom\"; pattern?: string; decimals?: number }\n | { kind: \"number\" | \"percent\"; decimals?: number; locale?: string }\n | { kind: \"chip\"; labels?: Record<string, string>; tones?: Record<string, \"neutral\" | \"success\" | \"warning\" | \"danger\"> }\n /** `truncate` keeps one line with an ellipsis. `lines` (1–20) wraps the text\n * and clamps it to that many lines with an ellipsis; it takes precedence. */\n | { kind: \"text\"; truncate?: boolean; lines?: number };\n\nconst calendarOptions = {\n style: [\"human\", \"iso\", \"custom\"], pattern: \"string\", timeZone: \"string\", locale: \"string\",\n} as const;\nconst numberOptions = { decimals: [0, 20], locale: \"string\" } as const;\nconst calendarUnits = [\"iso\", \"epochSeconds\", \"epochMilliseconds\"];\nconst options: Record<string, Record<string, readonly string[] | readonly number[] | string>> = {\n json: { encoding: [\"auto\", \"value\", \"json\", \"escaped\"], maxDecodeDepth: [1, 8], previewLength: [20, 500], expandDepth: [0, 8] },\n date: { ...calendarOptions, sourceUnit: calendarUnits },\n datetime: { ...calendarOptions, sourceUnit: calendarUnits },\n time: { ...calendarOptions, sourceUnit: [...calendarUnits, \"secondsOfDay\", \"millisecondsOfDay\"] },\n duration: { sourceUnit: [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\"], style: [\"human\", \"long\", \"clock\", \"custom\"], pattern: \"string\", decimals: [0, 20] },\n number: numberOptions, percent: numberOptions,\n chip: { labels: \"labels\", tones: \"tones\" },\n text: { truncate: \"boolean\", lines: [1, 20] },\n};\n\n/** Validate the serializable contract at schema loading, before rendering cells. */\nexport function parseCellDisplay(raw: unknown, context = \"cell display\"): CellDisplay {\n const fail = (reason: string): never => { throw Error(`${context}: ${reason}`); };\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return fail(\"expected an object\");\n const record = raw as Record<string, unknown>;\n if (typeof record.kind !== \"string\" || !Object.prototype.hasOwnProperty.call(options, record.kind)) return fail(\"unsupported kind\");\n const allowed = options[record.kind]!;\n for (const [key, value] of Object.entries(record)) {\n if (key === \"kind\") continue;\n const rule = Object.prototype.hasOwnProperty.call(allowed, key) ? allowed[key] : undefined;\n if (!rule) return fail(`unsupported option ${key}`);\n if (Array.isArray(rule)) {\n if (typeof rule[0] === \"number\") {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value < Number(rule[0]) || value > Number(rule[1])) return fail(`${key} must be an integer from ${rule[0]} to ${rule[1]}`);\n } else if (!rule.includes(value as never)) return fail(`unsupported ${key}`);\n } else if (rule === \"labels\" || rule === \"tones\") {\n if (!value || typeof value !== \"object\" || Array.isArray(value) || !Object.values(value).every((item) => typeof item === \"string\" && (rule === \"labels\" || [\"neutral\", \"success\", \"warning\", \"danger\"].includes(item)))) return fail(`invalid ${key} map`);\n } else if (typeof value !== rule) return fail(`${key} must be ${rule}`);\n if (key === \"pattern\" && (value as string).length > 160) return fail(\"pattern must be at most 160 characters\");\n }\n return { ...record,\n ...(record.labels ? { labels: { ...record.labels as Record<string, string> } } : {}),\n ...(record.tones ? { tones: { ...record.tones as Record<string, string> } } : {}),\n } as CellDisplay;\n}\n","import type { MetricValueFormat } from \"./metricTypes\";\nimport type { FieldDef, FieldSchema } from \"./schema\";\nimport { readFieldValue } from \"./schema\";\nimport type { RowId } from \"./query\";\nimport { parseCellDisplay, type CellDisplay, type JsonCellDisplay } from \"./cellDisplay\";\n\n/** Formats change presentation only; values retain their original types/units. */\nexport type PropertyFormat =\n | MetricValueFormat\n | { kind: \"text\" | \"code\" | \"boolean\" | \"chips\" }\n | JsonCellDisplay\n | Extract<CellDisplay, { kind: \"chip\" }>\n | {\n kind: \"relative\";\n sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\";\n }\n | { kind: \"currency\"; currency: string; decimals?: number };\n\nexport interface PropertyFieldConfig {\n enabled?: boolean;\n default?: boolean;\n /** Detail-specific renderer. Table renderers remain unchanged. */\n render?: string;\n format?: PropertyFormat;\n}\n\nexport interface PropertySelection {\n /** Instance identity allows the same field to appear with different formats. */\n id: string;\n field: string;\n label?: string;\n render?: string;\n format?: PropertyFormat;\n}\n\n/** Independent of object identity and collection QueryState. [] shows no fields. */\nexport interface PropertyViewState {\n version: 1;\n properties: PropertySelection[];\n /** Property label column width as a percentage, shared with the saved view. */\n labelWidth?: number;\n}\n\nexport const MAX_PROPERTIES = 200;\nconst string = (value: unknown, max = 256): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= max;\nconst record = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nexport function normalizePropertyFormat(\n input: unknown,\n): PropertyFormat | undefined {\n if (!record(input)) return;\n const kind = input.kind;\n if (kind === \"json\" || kind === \"chip\") {\n try { return parseCellDisplay(input) as PropertyFormat; }\n catch { return; }\n }\n if (\n input.decimals !== undefined &&\n !(\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n )\n return;\n if ([\"text\", \"code\", \"boolean\", \"chips\"].includes(String(kind)))\n return { kind } as PropertyFormat;\n if (kind === \"relative\") {\n if (\n input.sourceUnit !== undefined &&\n ![\"iso\", \"epochSeconds\", \"epochMilliseconds\"].includes(\n String(input.sourceUnit),\n )\n )\n return;\n return {\n kind,\n ...(input.sourceUnit ? { sourceUnit: input.sourceUnit } : {}),\n } as PropertyFormat;\n }\n if (kind === \"currency\") {\n if (\n typeof input.currency !== \"string\" ||\n !/^[A-Z]{3}$/.test(input.currency)\n )\n return;\n return {\n kind,\n currency: input.currency,\n ...(typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n ? { decimals: input.decimals }\n : {}),\n };\n }\n if (\n ![\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"].includes(\n String(kind),\n )\n )\n return;\n if (\n input.sourceUnit !== undefined &&\n ![\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n return;\n if (\n input.style !== undefined &&\n ![\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style))\n )\n return;\n if (input.pattern !== undefined && !string(input.pattern, 1000)) return;\n if (input.timeZone !== undefined && !string(input.timeZone)) return;\n const out: Record<string, unknown> = { kind };\n if (\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n out.decimals = input.decimals;\n if (\n [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n out.sourceUnit = input.sourceUnit;\n if ([\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style)))\n out.style = input.style;\n if (string(input.pattern, 1000)) out.pattern = input.pattern;\n if (string(input.timeZone)) out.timeZone = input.timeZone;\n return out as unknown as PropertyFormat;\n}\n\n/** Strict envelope/version checks prevent interpreting future saved views as empty. */\nexport function normalizePropertyView(input: unknown): PropertyViewState {\n if (!record(input) || input.version !== 1 || !Array.isArray(input.properties))\n throw new Error(\n \"Unsupported or invalid property view (expected version 1).\",\n );\n if (input.properties.length > MAX_PROPERTIES)\n throw new Error(`At most ${MAX_PROPERTIES} properties are allowed.`);\n const ids = new Set<string>();\n const properties = input.properties.map((item): PropertySelection => {\n if (\n !record(item) ||\n !string(item.id) ||\n !string(item.field) ||\n ids.has(item.id)\n )\n throw new Error(\"Property fields and unique instance IDs are required.\");\n ids.add(item.id);\n const property: PropertySelection = { id: item.id, field: item.field };\n if (string(item.label, 1000)) property.label = item.label;\n if (string(item.render)) property.render = item.render;\n if (item.format !== undefined) {\n const format = normalizePropertyFormat(item.format);\n if (!format) throw new Error(`Invalid format for property ${item.id}.`);\n property.format = format;\n }\n return property;\n });\n const labelWidth = typeof input.labelWidth === \"number\" && Number.isFinite(input.labelWidth)\n ? Math.max(15, Math.min(75, Math.round(input.labelWidth))) : undefined;\n return { version: 1, properties, ...(labelWidth !== undefined ? { labelWidth } : {}) };\n}\n\nexport function createPropertyView<Row>(\n schema: FieldSchema<Row>,\n names?: string[],\n): PropertyViewState {\n const enabled = schema.fields.filter((f) => f.property?.enabled !== false);\n const hasPropertyDefaults = enabled.some(\n (f) => f.property?.default !== undefined,\n );\n const defaults = hasPropertyDefaults\n ? enabled.filter((f) => f.property?.default).map((f) => f.name)\n : (schema.defaultSelect?.map((column) => column.field) ??\n enabled.filter((f) => f.select?.default).map((f) => f.name));\n const fields =\n names ??\n (hasPropertyDefaults || defaults.length\n ? defaults.filter((name) => enabled.some((field) => field.name === name))\n : enabled.map((f) => f.name));\n return normalizePropertyView({\n version: 1,\n properties: fields.map((field, i) => ({ id: `property-${i}`, field })),\n });\n}\n\nexport interface FieldOrigin {\n table: string;\n column: string;\n}\n/** Backend discovery groups composite key columns in constraint order. */\nexport interface ForeignKey {\n sourceTable: string;\n sourceColumns: string[];\n targetTable: string;\n targetColumns: string[];\n}\nexport interface ObjectTypeDefinition {\n name: string;\n table: string;\n keyFields: string[];\n}\nexport interface FieldRelationship {\n objectType: string;\n /** Target key field -> local catalogue field, including composite keys. */\n key: Record<string, string>;\n}\nexport interface ObjectReference {\n objectType: string;\n key: Record<string, RowId>;\n}\nexport interface ResolvedObjectReference {\n reference: ObjectReference;\n label?: string;\n href?: string;\n}\n/** Hosts resolve a batch through their authorized APIs, and own application routes. */\nexport interface RelationshipAdapter {\n resolve(\n references: ObjectReference[],\n signal?: AbortSignal,\n ): Promise<ResolvedObjectReference[]>;\n}\nexport function objectReferenceKey(reference: ObjectReference): string {\n return JSON.stringify([\n reference.objectType,\n Object.entries(reference.key).sort(([a], [b]) => a.localeCompare(b)),\n ]);\n}\nexport function readObjectReference<Row>(\n field: FieldDef<Row>,\n fields: FieldDef<Row>[],\n row: Row,\n): ObjectReference | null {\n const relationship = field.relationship;\n if (!relationship) return null;\n const key: Record<string, RowId> = Object.create(null);\n for (const [target, local] of Object.entries(relationship.key)) {\n const source = fields.find((f) => f.name === local);\n if (!source) return null;\n const value = readFieldValue(source, row);\n if (\n !(\n (typeof value === \"string\" && value !== \"\") ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n )\n return null;\n key[target] = value as RowId;\n }\n return Object.keys(key).length\n ? { objectType: relationship.objectType, key }\n : null;\n}\n\n/** Only unambiguous, fully mapped constraints become links. Explicit metadata wins. */\nexport function discoverFieldRelationships<Row>(\n fields: FieldDef<Row>[],\n keys: ForeignKey[],\n types: ObjectTypeDefinition[],\n): FieldDef<Row>[] {\n return fields.map((field) => {\n if (field.relationship || !field.origin) return field;\n const candidates: FieldRelationship[] = [];\n for (const fk of keys) {\n if (\n fk.sourceTable !== field.origin.table ||\n !fk.sourceColumns.includes(field.origin.column) ||\n fk.sourceColumns.length === 0 ||\n fk.sourceColumns.length !== fk.targetColumns.length\n )\n continue;\n const targets = types.filter(\n (type) =>\n type.table === fk.targetTable &&\n type.keyFields.length === fk.targetColumns.length &&\n type.keyFields.every((k) => fk.targetColumns.includes(k)),\n );\n if (targets.length !== 1) continue;\n const key: Record<string, string> = Object.create(null);\n let complete = true;\n fk.sourceColumns.forEach((column, i) => {\n const local = fields.filter(\n (f) =>\n f.origin?.table === fk.sourceTable && f.origin.column === column,\n );\n if (local.length !== 1) complete = false;\n else key[fk.targetColumns[i]!] = local[0]!.name;\n });\n if (complete) candidates.push({ objectType: targets[0]!.name, key });\n }\n return candidates.length === 1\n ? { ...field, relationship: candidates[0]! }\n : field;\n });\n}\n","// schema.ts — the field schema: the contract that binds frontend and backend.\n//\n// A `FieldSchema` is the runtime, frontend-facing projection of a JSON schema\n// document (schema/query-table.schema.json). The same document is projected on\n// the backend into a Go `Schema` of SQL bindings. Codegen keeps the two in sync.\n//\n// `FieldDef` is organized to make two things obvious (per design feedback):\n//\n// 1. WHAT KIND of field it is — the `source` discriminated union. A `backend`\n// field is a column the server returns and can filter/sort; a `derived`\n// field is computed on the client (or render-only) and is never pushed to\n// the server. Each kind uses its own property subset, so you can't, say,\n// mark a client-only column as server-filterable.\n//\n// 2. CONFIG vs CODE. Everything except `source.accessor` and `render` is\n// declarative, serializable config grouped by capability (`filter`, `sort`,\n// `select`, `display`). The only code-bearing members are the derived\n// `accessor` and the `render` function — kept apart from the config.\n\nimport type { AggOp, FilterOp, OrderByClause, SelectColumn } from \"./query\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { parseCellDisplay } from \"./cellDisplay\";\nimport { normalizePropertyFormat, type PropertyFieldConfig, type FieldOrigin, type FieldRelationship } from \"./properties\";\n\nexport type FieldType =\n | \"text\"\n | \"number\"\n | \"enum\"\n | \"datetime\"\n | \"bool\"\n | \"textarray\"; // array-of-text; supports `includes`, and null-as-empty semantics\n\nexport type Align = \"left\" | \"right\" | \"center\";\n\n/** A cell renderer is resolved by name against a `RenderRegistry` (in\n * @pythia-software/query-table-ui) or supplied inline. The type lives in core so FieldDef can\n * reference it, but core never imports React — `unknown` stands in for the node\n * and @pythia-software/query-table-ui narrows it to `React.ReactNode`. */\nexport type CellRenderer<Row = any, V = unknown> = (ctx: {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n}) => unknown;\n\n// ---- source: WHAT KIND of field (discriminated union) ---------------------\n\n/** A column the backend returns and can filter/sort. Its SQL expression lives in\n * the JSON schema doc's `bindings` (and the Go Schema), never on the frontend. */\nexport interface BackendField {\n kind: \"backend\";\n /** Dotted path into the API row when it differs from `name` (e.g. \"enqueued_at.Time\"). */\n path?: string;\n /** Computed SQL with no backing column (e.g. is_starred). Documentation hint\n * surfaced to the picker; the actual expression is server-side. */\n synthetic?: boolean;\n}\n\n/** A value computed on the client, or a purely render-driven column. Never\n * pushed to the server; client-side filtering/sorting (if any) reads `accessor`. */\nexport interface DerivedField<Row = any, V = unknown> {\n kind: \"derived\";\n /** Backend inputs required for accessors and computed formulas. */\n dependencies?: string[];\n /** Reusable computed column ID; always select-only. */\n computedId?: string;\n /** Compute the value from the row for client filter/sort. Omit for render-only\n * columns (the renderer reads the whole row from CellContext instead). */\n accessor?: (row: Row) => V;\n}\n\nexport type FieldSource<Row = any, V = unknown> = BackendField | DerivedField<Row, V>;\n\n// ---- capability config (declarative; serializable; shared with backend) ----\n\n/** How filter-value candidates are offered. Autocomplete is the DEFAULT for\n * every field (design feedback): the value input is a combobox backed by\n * Transport.fetchDistinctValues, which takes a search string so large domains\n * refine per keystroke on the backend. `static` is for closed domains you don't\n * want a round-trip for; `freeform` opts out of suggestions entirely. */\nexport type FilterValues =\n | { source: \"autocomplete\" }\n | { source: \"static\"; options: Array<string | { value: string; label: string }> }\n | { source: \"freeform\" };\n\nexport interface FilterConfig {\n /** Opt into the native multi-value editor: ANY/ALL/NONE/EMPTY for textarray\n * fields; ANY/NONE for enum fields and text fields with static options. */\n editor?: \"set\";\n /** Preserve case when matching textarray values. Default false. */\n arrayCaseSensitive?: boolean;\n /** Whether this field is filterable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Evaluate on the backend (predicate pushdown)? Default: backend ⇒ true.\n * false ⇒ the clause is stripped from the server request and applied locally\n * by applyQuery (the \"serverFilter:false\" derived/JSONB-less columns). */\n pushdown?: boolean;\n /** Override the default operator set for the field's type. */\n ops?: FilterOp[];\n /** Value-suggestion strategy. Default { source: \"autocomplete\" }. */\n values?: FilterValues;\n}\n\nexport interface SortConfig {\n /** Whether this field is sortable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Server field to ORDER BY when it differs from the display field\n * (e.g. a \"★\" column whose server sort key is `is_starred`). */\n field?: string;\n}\n\nexport interface SelectConfig {\n /** Can this appear as a visible column? Default true. false ⇒ filter-only field. */\n enabled?: boolean;\n /** Shown by default when QueryState.select is empty. */\n default?: boolean;\n /** Default column width (px); a per-column override rides in QueryState.select. */\n width?: number;\n align?: Align;\n}\n\nexport interface AggregateConfig {\n /** Can this field be a metric's MEASURE (sum/avg/min/max/count_distinct)?\n * Default: backend ⇒ true, derived ⇒ false. */\n measure?: boolean;\n /** Can this field be a GROUP BY key? Default: enum/text/bool ⇒ true. */\n groupable?: boolean;\n /** Override the default aggregate-op set for the field's type. */\n ops?: AggOp[];\n}\n\n// ---- the field ------------------------------------------------------------\n\nexport interface FieldDef<Row = any, V = unknown> {\n // identity\n name: string; // canonical id; matches the backend binding key + Where/OrderBy `field`\n label: string;\n type: FieldType;\n\n // WHAT KIND of field (value origin + server capability)\n source: FieldSource<Row, V>;\n\n // capabilities (declarative config; omit for sensible per-source defaults)\n filter?: FilterConfig;\n sort?: SortConfig;\n select?: SelectConfig;\n aggregate?: AggregateConfig;\n\n // discovery (picker UX, declarative)\n group?: string; // grouping bucket\n alias?: string; // single alternative search term\n aliases?: string[]; // extra search terms\n\n /** Declarative built-in presentation, independent of the query's field type.\n * An explicit render function or registered render key takes precedence. */\n display?: CellDisplay;\n // custom presentation: registry key or inline fn\n render?: string | CellRenderer<Row, V>;\n property?: PropertyFieldConfig;\n /** Structured provenance for relationship discovery; never SQL text. */\n origin?: FieldOrigin;\n relationship?: FieldRelationship;\n}\n\n/** The frontend's loaded schema for one dataset. */\nexport interface FieldSchema<Row = any> {\n /** Dataset id, also the StorageAdapter namespace for saved queries. */\n name: string;\n /** Field that yields a row's stable id for selection / per-row refresh. */\n idField: string;\n fields: FieldDef<Row>[];\n /** Sort applied when QueryState.orderBy is empty. */\n defaultSort?: OrderByClause[];\n /** Columns shown when QueryState.select is empty. */\n defaultSelect?: SelectColumn[];\n /** Page size for a fresh query. */\n defaultLimit?: number;\n}\n\n// ---- derived capability helpers (the per-source defaults, in one place) ----\n\nexport function isFilterable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return false;\n return f.filter?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isPushdownFilter(f: FieldDef): boolean {\n return isFilterable(f) && (f.filter?.pushdown ?? f.source.kind === \"backend\");\n}\nexport function isSortable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return f.sort?.enabled === true;\n return f.sort?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isSelectable(f: FieldDef): boolean {\n return f.select?.enabled ?? true;\n}\nexport function filterValues(f: FieldDef): FilterValues {\n return f.filter?.values ?? { source: \"autocomplete\" };\n}\n\n// ---- schema operations ----------------------------------------------------\n\n/** Index fields by name for O(1) lookup. */\nexport function indexFields<Row>(schema: FieldSchema<Row>): Map<string, FieldDef<Row>> {\n return new Map(schema.fields.map((f) => [f.name, f]));\n}\n\n/** Resolve the ordered, selectable FieldDefs for a query, falling back to schema\n * defaults, then to every `select.default` field. Unknown/duplicate/unselectable\n * names in `select` are dropped. */\nexport function selectedFields<Row>(\n schema: FieldSchema<Row>,\n q: { select: SelectColumn[] },\n): FieldDef<Row>[] {\n const order =\n q.select.length > 0\n ? q.select.map((c) => c.field)\n : (schema.defaultSelect ?? schema.fields.filter((f) => f.select?.default).map((f) => ({ field: f.name }))).map(\n (c) => c.field,\n );\n const seen = new Set<string>();\n const out: FieldDef<Row>[] = [];\n for (const name of order) {\n if (seen.has(name)) continue;\n const f = resolveField(schema, name);\n if (!f || !isSelectable(f)) continue;\n seen.add(name);\n seen.add(f.name);\n out.push(f);\n }\n return out;\n}\n\n/** Resolve a field token to a concrete field by canonical name, case-insensitive\n * name match, or alias match. */\nexport function resolveField<Row>(schema: FieldSchema<Row>, field: string): FieldDef<Row> | undefined {\n const token = field.trim();\n if (!token) return undefined;\n\n const byName = indexFields(schema);\n const byExactName = byName.get(token);\n if (byExactName) return byExactName;\n\n const needle = token.toLowerCase();\n for (const f of schema.fields) {\n if (f.name.toLowerCase() === needle) return f;\n if (aliasMatches(f, needle)) return f;\n }\n return undefined;\n}\n\n/** Return the canonical name for a query token, or undefined when unresolved. */\nexport function resolveFieldName<Row>(schema: FieldSchema<Row>, field: string): string | undefined {\n return resolveField(schema, field)?.name;\n}\n\n/** All configured aliases for a field (deduped, preserving display shape). */\nexport function aliasTermsFor<Row>(field: FieldDef<Row>): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(value);\n };\n\n add(field.alias);\n if (field.aliases) {\n for (const alias of field.aliases) add(alias);\n }\n\n return out;\n}\n\nfunction aliasMatches(field: FieldDef, needle: string): boolean {\n for (const alias of aliasTermsFor(field)) {\n if (alias.toLowerCase() === needle) return true;\n }\n return false;\n}\n\n/** Read a field's value from a row: derived `accessor` if present, else the\n * backend `path` (dotted) / `name`. Returns null when any path segment is missing. */\nexport function readFieldValue<Row, V = unknown>(field: FieldDef<Row, V>, row: Row): V | null {\n if (row == null) return null;\n if (field.source.kind === \"derived\" && field.source.accessor) {\n return field.source.accessor(row);\n }\n const path = (field.source.kind === \"backend\" && field.source.path) || field.name;\n const r = row as Record<string, unknown>;\n if (path in r) return (r[path] ?? null) as V | null;\n let cur: unknown = row;\n for (const part of path.split(\".\")) {\n if (cur == null || typeof cur !== \"object\") return null;\n cur = (cur as Record<string, unknown>)[part];\n }\n return (cur ?? null) as V | null;\n}\n\n/** Parse + validate a raw JSON schema document into a FieldSchema. The doc is the\n * same one the Go backend loads; here we drop backend `bindings` (the frontend\n * never sees SQL) and leave `render` as a string key the consumer maps to a\n * renderer at runtime. Throws with a readable message on a malformed document. */\nexport function loadSchema<Row = any>(doc: unknown): FieldSchema<Row> {\n const d = doc as Record<string, any>;\n if (!d || typeof d !== \"object\") throw new Error(\"schema: document is not an object\");\n if (typeof d.name !== \"string\") throw new Error(\"schema: missing `name`\");\n if (typeof d.idField !== \"string\") throw new Error(\"schema: missing `idField`\");\n if (!Array.isArray(d.fields) || d.fields.length === 0) throw new Error(\"schema: `fields` must be a non-empty array\");\n\n const fields: FieldDef<Row>[] = d.fields.map((raw: any, i: number) => projectField<Row>(raw, i));\n return {\n name: d.name,\n idField: d.idField,\n fields,\n defaultSort: d.defaultSort,\n defaultSelect: d.defaultSelect,\n defaultLimit: d.defaultLimit,\n };\n}\n\nfunction projectField<Row>(raw: any, i: number): FieldDef<Row> {\n if (!raw || typeof raw.name !== \"string\") throw new Error(`schema: field[${i}] missing \\`name\\``);\n if (typeof raw.label !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`label\\``);\n if (typeof raw.type !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`type\\``);\n if (raw.property !== undefined) {\n const property = raw.property;\n if (!property || typeof property !== \"object\" || Array.isArray(property)\n || (property.enabled !== undefined && typeof property.enabled !== \"boolean\")\n || (property.default !== undefined && typeof property.default !== \"boolean\")\n || (property.render !== undefined && (typeof property.render !== \"string\" || !property.render))) {\n throw new Error(`schema: field ${raw.name} has invalid property metadata`);\n }\n if (property.format !== undefined && !normalizePropertyFormat(property.format)) {\n throw new Error(`schema: field ${raw.name} has an invalid property format`);\n }\n }\n if (raw.origin !== undefined && (!raw.origin\n || typeof raw.origin.table !== \"string\" || !raw.origin.table\n || typeof raw.origin.column !== \"string\" || !raw.origin.column)) {\n throw new Error(`schema: field ${raw.name} has an invalid origin`);\n }\n if (raw.relationship !== undefined && (!raw.relationship\n || typeof raw.relationship.objectType !== \"string\" || !raw.relationship.objectType\n || !raw.relationship.key || typeof raw.relationship.key !== \"object\"\n || Array.isArray(raw.relationship.key) || Object.keys(raw.relationship.key).length === 0\n || Object.entries(raw.relationship.key).some(([key, value]) => !key || typeof value !== \"string\" || !value))) {\n throw new Error(`schema: field ${raw.name} has an invalid relationship`);\n }\n\n // `source` accepts a string shorthand (\"backend\"|\"derived\") or an object.\n const rs = raw.source ?? (raw.bindings ? \"backend\" : \"derived\");\n let source: FieldSource<Row>;\n if (typeof rs === \"string\") {\n source = rs === \"derived\" ? { kind: \"derived\" } : { kind: \"backend\" };\n } else if (rs.kind === \"derived\") {\n source = { kind: \"derived\" }; // accessor is code → attached at runtime, never from JSON\n } else {\n source = { kind: \"backend\", path: rs.path, synthetic: rs.synthetic };\n }\n\n return {\n name: raw.name,\n label: raw.label,\n type: raw.type,\n source,\n filter: raw.filter,\n sort: raw.sort,\n select: raw.select,\n aggregate: raw.aggregate,\n group: raw.group,\n alias: raw.alias,\n aliases: normalizeAliases(raw.aliases, raw.alias),\n ...(raw.display === undefined ? {} : { display: parseCellDisplay(raw.display, `schema: field ${raw.name} display`) }),\n render: raw.render, // string key from JSON; consumer may override with a fn\n property: raw.property ? { ...raw.property, format: raw.property.format === undefined ? undefined : normalizePropertyFormat(raw.property.format) } : undefined,\n origin: raw.origin,\n relationship: raw.relationship,\n };\n}\n\nfunction normalizeAliases(rawAliases: unknown, rawAlias: unknown): string[] {\n const aliases: string[] = [];\n const seen = new Set<string>();\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n aliases.push(value);\n };\n\n add(rawAlias);\n if (Array.isArray(rawAliases)) {\n for (const item of rawAliases) add(item);\n }\n return aliases;\n}\n","import { readFieldValue, type FieldSchema } from \"./schema\";\nimport type { RowId } from \"./query\";\n\n// Literal URL templates, shared by item pages and group link columns.\n// Substitution never evaluates code or nested paths: each placeholder is a bare\n// token or {field:name}, and every substituted value is percent-encoded.\n\nconst MAX_TEMPLATE_LENGTH = 8000;\nconst BASE = \"https://query-table.invalid/\";\nconst ITEM_PAGE_TOKENS = [\"id\", \"query\"] as const;\n\nfunction placeholders(tokens: readonly string[]): RegExp {\n return new RegExp(`\\\\{(${[...tokens, \"field:[^{}]+\"].join(\"|\")})\\\\}`, \"g\");\n}\n\nfunction httpOrRelative(href: string): boolean {\n try {\n return [\"http:\", \"https:\"].includes(new URL(href, BASE).protocol);\n } catch {\n return false;\n }\n}\n\n/** The distinct `{field:name}` references in a template. */\nexport function templateFields(template: string): string[] {\n return [...new Set(Array.from(template.matchAll(/\\{field:([^{}]+)\\}/g), match => match[1]!))];\n}\n\n/** Why a URL template is invalid, or null. An empty template is valid here;\n * callers that require a URL check for it. `tokens` are the bare placeholders\n * allowed besides `{field:name}`; `hasField` decides which names exist. */\nexport function urlTemplateProblem(template: string, tokens: readonly string[], hasField: (name: string) => boolean): string | null {\n if (template.length > MAX_TEMPLATE_LENGTH) return \"Use a URL template of at most 8,000 characters.\";\n if (!template.trim()) return null;\n const remainder = template.replace(placeholders(tokens), \"value\");\n if (/[{}]/.test(remainder)) {\n const names = [...tokens.map(token => `{${token}}`), \"{field:field_name}\"];\n const list = names.length > 1 ? `${names.slice(0, -1).join(\", \")}${names.length > 2 ? \",\" : \"\"} or ${names.at(-1)}` : names[0];\n return `Use ${list} placeholders.`;\n }\n for (const name of templateFields(template)) {\n if (!hasField(name)) return `Unknown URL field: ${name}.`;\n }\n try {\n if (![\"http:\", \"https:\"].includes(new URL(remainder, BASE).protocol))\n return \"Use an HTTP, HTTPS, or relative page URL.\";\n } catch { return \"Enter a valid page URL.\"; }\n return null;\n}\n\n/** Substitute a validated template. `read` returns each token's value (bare\n * tokens by name, fields as `field:name`); only strings, numbers and booleans\n * substitute. Returns null when a value is missing or the result would not be\n * an HTTP(S) or relative URL. */\nexport function fillUrlTemplate(template: string, tokens: readonly string[], read: (token: string) => unknown): string | null {\n let missing = false;\n const href = template.replace(placeholders(tokens), (_match, token: string) => {\n const value = read(token);\n if (value == null || ![\"string\", \"number\", \"boolean\"].includes(typeof value)) { missing = true; return \"\"; }\n return encodeURIComponent(String(value));\n });\n // Validate again after substitution: a placeholder cannot introduce a scheme.\n return missing || !httpOrRelative(href) ? null : href;\n}\n\nexport function itemPageFields(template: string): string[] {\n return templateFields(template);\n}\nexport function validateItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>): string | null {\n return urlTemplateProblem(template, ITEM_PAGE_TOKENS, name => schema.fields.some(field => field.name === name));\n}\nexport function renderItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>, row: Row, id: RowId | null, query: string): string | null {\n if (!template.trim() || validateItemPageTemplate(template, schema)) return null;\n return fillUrlTemplate(template, ITEM_PAGE_TOKENS, token => token === \"id\" ? id : token === \"query\" ? query\n : readFieldValue(schema.fields.find(field => field.name === token.slice(6))!, row));\n}\n","import type { AggregationClause } from \"./query\";\n/** Whitelist every nested property: URL/storage objects never become executable plans. */\nexport function normalizeMetricOptions(\n raw: Record<string, unknown>,\n): Partial<AggregationClause> {\n const out: Record<string, unknown> = {},\n diagnostics: string[] = [];\n const record = (x: unknown): x is Record<string, unknown> =>\n !!x && typeof x === \"object\" && !Array.isArray(x);\n const copy = (\n input: Record<string, unknown>,\n specs: Record<\n string,\n readonly string[] | \"string\" | \"boolean\" | \"integer\" | \"positiveInteger\" | \"number\"\n >,\n ): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, spec] of Object.entries(specs)) {\n const v = input[key];\n if (v === undefined) continue;\n if (\n spec === \"string\"\n ? typeof v === \"string\" && v.length <= 10000\n : spec === \"number\"\n ? typeof v === \"number\" && Number.isFinite(v)\n : spec === \"boolean\"\n ? typeof v === \"boolean\"\n : spec === \"integer\" || spec === \"positiveInteger\"\n ? typeof v === \"number\" &&\n Number.isSafeInteger(v) &&\n v >= (spec === \"positiveInteger\" ? 1 : 0) &&\n v <= 1000000\n : typeof v === \"string\" && spec.includes(v)\n )\n result[key] = v;\n else diagnostics.push(`Invalid metric ${key}.`);\n }\n return result;\n };\n Object.assign(\n out,\n copy(raw, {\n expression: \"string\",\n expressionY: \"string\",\n scope: [\"allMatching\", \"shownRows\"],\n groupLimit: \"integer\",\n minCount: \"positiveInteger\",\n }),\n );\n if (raw.dateGrouping !== undefined) {\n if (record(raw.dateGrouping)) {\n const d = copy(raw.dateGrouping, {\n field: \"string\",\n interval: [\"hour\", \"day\", \"week\", \"month\", \"year\"],\n timeZone: \"string\",\n includeEmpty: \"boolean\",\n range: [\"query\", \"observed\", \"custom\"],\n start: \"string\",\n end: \"string\",\n });\n if (\n typeof d.field !== \"string\" ||\n !d.field ||\n d.field.length > 256 ||\n !d.interval ||\n typeof d.includeEmpty !== \"boolean\" ||\n !d.range\n )\n diagnostics.push(\"Invalid metric date grouping.\");\n out.dateGrouping = d;\n } else diagnostics.push(\"Invalid metric date grouping.\");\n }\n if (raw.display !== undefined) {\n if (record(raw.display)) {\n if (typeof raw.display.kind !== \"string\")\n diagnostics.push(\"Invalid metric display kind.\");\n const d = copy(raw.display, {\n kind: [\n \"auto\",\n \"value\",\n \"table\",\n \"list\",\n \"bar-horizontal\",\n \"bar-vertical\",\n \"line\",\n \"pie\",\n \"donut\",\n \"scatter\",\n \"box\",\n \"histogram\",\n ],\n valueLabel: \"string\",\n xLabel: \"string\",\n yLabel: \"string\",\n legendPosition: [\"left\", \"right\", \"top\", \"bottom\", \"none\"],\n maxGroups: \"positiveInteger\",\n showOther: \"boolean\",\n boxMean: \"boolean\",\n });\n for (const k of [\"xScale\", \"yScale\"]) {\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], {\n mode: [\"linear\", \"log\"],\n min: \"number\",\n max: \"number\",\n });\n else if (raw.display[k] !== undefined)\n diagnostics.push(`Invalid metric ${k}.`);\n }\n for (const k of [\"format\", \"xFormat\", \"yFormat\"])\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], {\n kind: [\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"],\n decimals: \"integer\",\n sourceUnit: [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ],\n style: [\"human\", \"long\", \"clock\", \"custom\", \"iso\"],\n pattern: \"string\",\n timeZone: \"string\",\n });\n if (record(raw.display.list))\n d.list = copy(raw.display.list, {\n showBars: \"boolean\",\n useGroupColors: \"boolean\",\n showValues: \"boolean\",\n barPosition: [\"inline\", \"below\"],\n maxLabelLines: \"positiveInteger\",\n });\n if (record(raw.display.pivot))\n d.pivot = copy(raw.display.pivot, {\n swap: \"boolean\",\n rowDir: [\"asc\", \"desc\"],\n columnDir: [\"asc\", \"desc\"],\n });\n out.display = { kind: \"auto\", ...d };\n } else diagnostics.push(\"Invalid metric display.\");\n }\n if (raw.distribution !== undefined) {\n if (record(raw.distribution))\n out.distribution = copy(raw.distribution, {\n kind: [\"box\", \"histogram\"],\n input: \"string\",\n whiskers: [\"minmax\", \"tukey\"],\n bins: \"integer\",\n });\n else diagnostics.push(\"Invalid metric distribution.\");\n }\n if (record(raw.layout)) {\n const l = copy(raw.layout, {\n widthRem: \"integer\",\n heightRem: \"integer\",\n minWidthRem: \"integer\",\n minHeightRem: \"integer\",\n });\n for (const k of [\"widthRem\", \"heightRem\", \"minWidthRem\", \"minHeightRem\"])\n l[k] = Math.max(1, Math.min(1000, Number(l[k] ?? 1)));\n l.widthRem = Math.max(Number(l.widthRem), Number(l.minWidthRem));\n l.heightRem = Math.max(Number(l.heightRem), Number(l.minHeightRem));\n out.layout = l;\n }\n if (raw.sort !== undefined && !Array.isArray(raw.sort))\n diagnostics.push(\"Invalid metric sort.\");\n if (Array.isArray(raw.sort))\n out.sort = raw.sort.slice(0, 20).flatMap((s) => {\n if (\n !record(s) ||\n typeof s.key !== \"string\" ||\n !/^(value|y|count|samples|group(?:0|[1-9][0-9]?))$/.test(s.key) ||\n ![\"asc\", \"desc\"].includes(String(s.dir))\n ) {\n diagnostics.push(\"Invalid metric sort.\");\n return [];\n }\n return [\n copy(s, {\n key: [s.key],\n dir: [\"asc\", \"desc\"],\n nulls: [\"first\", \"last\"],\n }),\n ];\n });\n if (Array.isArray(raw.diagnostics))\n diagnostics.push(\n ...raw.diagnostics\n .filter((s): s is string => typeof s === \"string\" && s.length <= 1000)\n .slice(0, 20),\n );\n if (diagnostics.length) out.diagnostics = [...new Set(diagnostics)];\n return out as Partial<AggregationClause>;\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\nimport type { MetricDisplay, MetricLayout, MetricDistribution, MetricSort, MetricScope, MetricDateGrouping } from \"./metricTypes\";\nimport { normalizeMetricOptions } from \"./metricNormalize\";\nimport type { GroupingState, SummaryColumn, RepresentativeOrder, LinkSpec, LinkDestination } from \"./grouping\";\nimport type { QueryFacet, QueryPatch } from \"./queryPatch\";\nimport { parseCellDisplay, type CellDisplay } from \"./cellDisplay\";\n// query.ts — the canonical query state shape.\n//\n// We lean into SQL vocabulary at every layer (per design feedback): a QueryState\n// reads top-to-bottom like the statement it compiles to —\n//\n// SELECT <select> WHERE <where> ORDER BY <orderBy> LIMIT <limit> OFFSET <offset>\n//\n// Both \"what data\" (where/orderBy/limit/offset) and \"how viewed\" (select +\n// per-column width) can be serialized together when a consumer explicitly opts\n// into URL synchronization.\n\n/** All filter operators across both source projects, unioned. Every value can\n * be NULL, so `is_null`/`is_not_null` are valid for every field type. */\nexport type FilterOp =\n // comparison — number / datetime (and =,!= for any scalar)\n | \"=\"\n | \"!=\"\n | \">\"\n | \">=\"\n | \"<\"\n | \"<=\"\n // text matching\n | \"contains\"\n | \"starts_with\"\n | \"ends_with\"\n | \"matches_regex\"\n | \"not_matches_regex\"\n | \"length_gt\"\n | \"length_lt\"\n | \"length_eq\"\n // array (textarray) containment\n | \"includes\"\n // nullity — valid for EVERY type; for arrays, \"empty\" vs \"non-empty\"\n | \"is_null\"\n | \"is_not_null\";\n\n/** A single filter predicate (a \"literal\" in CNF terms). `value` is always the\n * raw string the UI captured; coercion to number/bool/date happens at\n * apply/compile time based on the field's declared type (never on the value's\n * runtime shape). Datetime comparisons also accept signed duration offsets\n * such as \"-1h\" or \"+8d2h10m\", resolved relative to execution time.\n * Unused for the nullary ops (`is_null`/`is_not_null`).\n *\n * `negated` wraps the predicate in a logical NOT. It is only ever set for ops\n * that have no complementary operator (`contains`/`starts_with`/`ends_with`/\n * `includes`); ops with a complement negate by flipping the op itself (`>=`→`<`,\n * `=`→`!=`, `is_null`→`is_not_null`, `matches_regex`→`not_matches_regex`) — see\n * `negateClause` in ops.ts. NOT is null-exclusive: a NULL/empty value satisfies\n * neither the predicate nor its negation, matching `not_matches_regex`. */\nexport interface WhereClause {\n field: string; // FieldDef.name\n op: FilterOp;\n value: string;\n negated?: boolean;\n setFilter?: SetFilterMetadata;\n}\n\nexport type SetFilterMode = \"any\" | \"all\" | \"none\" | \"empty\";\n\n/** Presentation-only identity; execution always uses the accompanying predicates. */\nexport interface SetFilterMetadata {\n id: string;\n mode: SetFilterMode;\n values: string[];\n}\n\n/** A disjunction of predicates — the inner OR of conjunctive normal form. Every\n * member is a plain literal; nesting is intentionally not allowed yet (CNF\n * only), but the object shape leaves room to grow. */\nexport interface OrGroup {\n any: WhereClause[];\n setFilter?: SetFilterMetadata;\n}\n\n/** One conjunct of the WHERE clause: either a single predicate or an OR group.\n * `QueryState.where` is the AND of these terms, so the whole WHERE is\n * conjunctive normal form — `(a) AND (b OR c) AND (d)`. A bare literal is\n * equivalent to a one-element OR group; normalization flattens singleton groups\n * back to a literal so equality/encoding stay canonical. */\nexport type WhereTerm = WhereClause | OrGroup;\n\n/** Narrow a term to an OR group. A literal always carries `field`; a group never\n * does and always carries an `any` array. */\nexport function isOrGroup(term: WhereTerm): term is OrGroup {\n return Array.isArray((term as OrGroup).any);\n}\n\n/** The predicate literals a term contributes, in order: the term itself for a\n * literal, or its members for a group. Handy for anything that must visit every\n * predicate regardless of grouping (field allowlisting, SELECT projection). */\nexport function predicatesOf(term: WhereTerm): WhereClause[] {\n return isOrGroup(term) ? term.any : [term];\n}\n\n/** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */\nexport interface OrderByClause {\n field: string; // FieldDef.name (server may sort a different expr via FieldDef.sort.field)\n dir: \"asc\" | \"desc\";\n /** NULL placement. Omitted = \"last\" (the historical default both projects used,\n * preserved so old `?q=` links round-trip identically). */\n nulls?: \"first\" | \"last\";\n /** Sort by the first capture group of a regex match (or by the whole match\n * when the pattern has no capture group). A non-match produces NULL. Regex\n * syntax is interpreted by the executor (JavaScript locally, PostgreSQL on\n * the bundled Go backend), so portable patterns should use their common\n * syntax subset. */\n extract?: { regex: string };\n}\n\n/** One column in the SELECT list, plus the view state that travels with it.\n * Order in `QueryState.select` is the left-to-right display order. */\nexport interface SelectColumn {\n field: string; // FieldDef.name, or @computed/<id> (source lives in ComputedColumnStore)\n /** Pixel width override. Omitted = FieldDef.select.width, else the type default. */\n width?: number;\n /** Table-cell presentation for this column in this layout, e.g.\n * `{ kind: \"text\", lines: 3 }`. Takes precedence over the field's `render`\n * and `display`; other surfaces (details, menus, metrics) keep the field's. */\n display?: CellDisplay;\n}\n\n/** A single aggregate operation. `count` is the only op that needs no measure\n * column (it counts rows); the rest reduce one column's values. The server-side\n * matrix (backends/go aggOpAllowed + the TS AGG_OPS_BY_TYPE) decides which ops a\n * field's type permits. */\nexport type AggOp = \"count\" | \"count_distinct\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\n/** One optional \"metric\" pinned above the table: a single aggregate over a single\n * measure column, optionally broken down by one or more group columns.\n *\n * Scope is deliberately the *whole filtered set* — the same WHERE as the table,\n * but NOT its ORDER BY / LIMIT / OFFSET. It is always evaluated on the server\n * (a real GROUP BY), so it reflects every matching row, not just the visible\n * page. Lives inside QueryState so it round-trips through `?q=`, saved queries,\n * and undo/redo for free — a saved query is a saved dashboard. */\nexport interface AggregationClause {\n dateGrouping?: MetricDateGrouping;\n expression?: string;\n expressionY?: string;\n scope?: MetricScope;\n sort?: MetricSort[];\n groupLimit?: number;\n display?: MetricDisplay;\n layout?: MetricLayout;\n distribution?: MetricDistribution;\n diagnostics?: string[];\n /** Preserved source operation when this client does not implement it. */\n unsupportedOp?: string;\n /** Stable id; keys the metric panel and survives a `?q=` round-trip. */\n id: string;\n op: AggOp;\n /** Measure column (FieldDef.name). Omit only for `count` (⇒ COUNT(*)). */\n field?: string;\n /** Group-by columns, in axis order. `[]` = a single grand-total value.\n * One ⇒ a list/bar breakdown; two ⇒ an x/y pivot; three+ ⇒ a flat table. */\n groupBy: string[];\n /** Panel header override; defaults to a derived label like \"avg total\". */\n label?: string;\n /** This metric's own row predicate (CNF, like `QueryState.where`), ANDed with\n * the table WHERE before grouping. The table rows are unchanged. In grouped\n * mode it refers to grouped-result fields. Shown-row metrics apply it inside\n * the shown page. */\n where?: WhereTerm[];\n /** Drop groups with fewer than this many rows (counted after `where`) before\n * sorting, `groupLimit` and Other. Requires at least one grouping field;\n * integer 1–1,000,000. Removed groups are reported as `hiddenGroups`. */\n minCount?: number;\n}\n\n/** Detail affordances are presentation state, never backend SELECT fields. */\nexport type ItemPropertyMode = \"hover\" | \"modal\" | \"expand\";\nexport type ItemDetailMode = ItemPropertyMode | \"page\";\nexport interface ItemPageOptions {\n /** Empty uses the current page with the item modal and query state. */\n urlTemplate: string;\n target: \"_blank\" | \"_self\";\n}\n/** Reserved presentation column; never sent to a data source. */\nexport const ITEM_DETAILS_COLUMN = \"__qt_item_details__\";\nexport interface ItemDetailsState {\n modes: ItemDetailMode[];\n /** A self-contained view travels with shared links; saved-view IDs are device-local. */\n view?: PropertyViewState;\n /** Independent layouts for each modality. Legacy view is the fallback. */\n views?: Partial<Record<ItemPropertyMode, PropertyViewState>>;\n page?: ItemPageOptions;\n active?: { id: RowId; mode: \"modal\" | \"expand\" };\n}\n\nexport interface QueryState {\n /** Optional row-producing stage. `grouping.source` is the original record\n * query (its WHERE runs first). This query selects/filters/sorts the groups;\n * its `where` therefore represents HAVING. Only one stage is supported. */\n grouping?: GroupingState;\n itemDetails?: ItemDetailsState;\n /** Ordered SELECT list + per-column widths. Empty = the schema's default columns. */\n select: SelectColumn[];\n /** Refit columns to each viewer's table viewport after loading. Manual width\n * changes clear this view preference; omitted/false uses stored widths. */\n fitToScreen?: boolean;\n /** WHERE in conjunctive normal form: the AND of these terms, each a single\n * predicate or an OR group. A flat list of literals (no groups) is the common\n * case and the legacy shape, decoded unchanged. */\n where: WhereTerm[];\n /** Multi-sort terms in priority order. Empty = the schema's default sort. */\n orderBy: OrderByClause[];\n /** Page size. */\n limit: number;\n /** Page offset (rows). */\n offset: number;\n /** Optional aggregate metrics shown above the table. Omitted/empty = none.\n * Each runs as its own server GROUP BY over the WHERE-filtered set (no paging). */\n aggregations?: AggregationClause[];\n}\n\n/** A row's stable identity, used for selection and per-row refresh. */\nexport type RowId = string | number;\n\n/** The query a fresh table starts from before schema defaults are layered on.\n * Empty `select`/`orderBy`/`where` mean \"defer to the schema\", which also keeps\n * encoded `?q=` tokens short (defaults are omitted). */\nexport const EMPTY_QUERY: QueryState = {\n select: [],\n where: [],\n orderBy: [],\n limit: 100,\n offset: 0,\n};\n\n/** Structural limits applied whenever query state crosses a trust boundary\n * (URL, storage, an imperative setQuery call, or a server projection). Row\n * limits may use the full safe-integer range; consumers and their backends own\n * any smaller operational cap appropriate for their dataset. */\nexport const MAX_QUERY_LIMIT = Number.MAX_SAFE_INTEGER;\nexport const MAX_QUERY_OFFSET = 1_000_000;\nexport const MAX_SELECT_COLUMNS = 200;\nexport const MAX_WHERE_CLAUSES = 100;\nexport const MAX_ORDER_BY_TERMS = 20;\nexport const MAX_AGGREGATIONS = 20;\nexport const MAX_GROUP_BY_FIELDS = 20;\nexport const MAX_QUERY_TOKEN_LENGTH = 2 * 1024 * 1024;\n\nconst MAX_FIELD_NAME_LENGTH = 256;\nconst MAX_FILTER_VALUE_LENGTH = 10_000;\nconst MAX_LABEL_LENGTH = 1_000;\nconst MIN_COLUMN_WIDTH = 24;\nconst MAX_COLUMN_WIDTH = 2_000;\n\nconst FILTER_OPS: ReadonlySet<string> = new Set([\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n \"includes\",\n \"is_null\",\n \"is_not_null\",\n]);\n\nconst AGG_OPS: ReadonlySet<string> = new Set([\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction boundedString(value: unknown, maxLength: number): string | null {\n return typeof value === \"string\" && value.length > 0 && value.length <= maxLength ? value : null;\n}\n\nfunction boundedInteger(value: unknown, fallback: number, min: number, max: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.min(max, Math.round(value)));\n}\n\n/** Validate one raw predicate into a bounded WhereClause, or null if malformed.\n * Shared by top-level literals and the members of an OR group. */\nfunction normalizeWhereClause(item: unknown): WhereClause | null {\n if (!isRecord(item)) return null;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const value = typeof item.value === \"string\" && item.value.length <= MAX_FILTER_VALUE_LENGTH ? item.value : null;\n if (!field || typeof item.op !== \"string\" || !FILTER_OPS.has(item.op) || value == null) {\n return null;\n }\n const clause: WhereClause = { field, op: item.op as FilterOp, value };\n if (item.negated === true) clause.negated = true;\n return clause;\n}\n\n/** Deep-clone one WHERE term (literal or group) so a normalized/fallback state\n * never aliases the caller's arrays. */\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy = isOrGroup(term) ? { ...term, any: term.any.map((c) => ({ ...c })) } : { ...term };\n if (term.setFilter) copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction normalizeSetFilter(item: unknown): SetFilterMetadata | undefined {\n if (!isRecord(item)) return undefined;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id || ![\"any\", \"all\", \"none\", \"empty\"].includes(String(item.mode)) || !Array.isArray(item.values)) return undefined;\n if (item.values.length > MAX_WHERE_CLAUSES || !item.values.every((value) => typeof value === \"string\" && value.length <= MAX_FILTER_VALUE_LENGTH)) return undefined;\n return { id, mode: item.mode as SetFilterMode, values: [...item.values] as string[] };\n}\n\nfunction normalizeWhereTerms(input: readonly unknown[]): WhereTerm[] {\n const where: WhereTerm[] = [];\n let literalBudget = MAX_WHERE_CLAUSES;\n for (const item of input) {\n if (literalBudget <= 0) break;\n const start = where.length;\n if (isRecord(item) && Array.isArray((item as { any?: unknown }).any)) {\n const members: WhereClause[] = [];\n for (const inner of (item as { any: unknown[] }).any) {\n if (literalBudget <= 0) break;\n const clause = normalizeWhereClause(inner);\n if (clause) {\n members.push(clause);\n literalBudget--;\n }\n }\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n // 0 members → drop the term entirely\n } else {\n const clause = normalizeWhereClause(item);\n if (clause) {\n where.push(clause);\n literalBudget--;\n }\n }\n if (where.length > start && isRecord(item)) {\n const metadata = normalizeSetFilter(item.setFilter);\n if (metadata) where[start]!.setFilter = metadata;\n }\n }\n return where;\n}\n\n/** A metric WHERE narrows its population. Dropping a malformed predicate would\n * silently widen it, so any loss is retained as a clause diagnostic instead. */\nfunction normalizeMetricWhere(value: unknown): { where?: WhereTerm[]; invalid: boolean } {\n if (value === undefined) return { invalid: false };\n if (!Array.isArray(value)) return { invalid: true };\n const where = normalizeWhereTerms(value);\n const supplied = value.reduce((count: number, term: unknown) =>\n count + (isRecord(term) && Array.isArray(term.any) ? term.any.length : 1), 0);\n const kept = where.reduce((count, term) => count + predicatesOf(term).length, 0);\n return { ...(where.length ? { where } : {}), invalid: supplied !== kept };\n}\n\n/** Convert unknown input into a bounded, structurally valid QueryState.\n * Invalid members are dropped; invalid scalar paging values use the supplied\n * fallback. This function is intentionally schema-agnostic—field allowlisting\n * still happens in toServerQuery and in the backend compiler. */\nexport function normalizeQueryState(input: unknown, fallback: QueryState = EMPTY_QUERY): QueryState {\n return normalizeQuery(input, fallback, true);\n}\n\n/** `links` is false inside a link's patch, which bounds nesting at one level. */\nfunction normalizeQuery(input: unknown, fallback: QueryState, links: boolean): QueryState {\n const raw = isRecord(input) ? input : {};\n\n const select: SelectColumn[] = [];\n if (Array.isArray(raw.select)) {\n for (const item of raw.select.slice(0, MAX_SELECT_COLUMNS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field) continue;\n const column: SelectColumn = { field };\n if (typeof item.width === \"number\" && Number.isFinite(item.width)) {\n column.width = boundedInteger(item.width, MIN_COLUMN_WIDTH, MIN_COLUMN_WIDTH, MAX_COLUMN_WIDTH);\n }\n if (item.display !== undefined) {\n // A malformed presentation hint never hides the column; it falls back\n // to the field's own presentation.\n try { column.display = parseCellDisplay(item.display, `column ${field} display`); } catch { /* dropped */ }\n }\n select.push(column);\n }\n } else {\n select.push(...fallback.select.map((column) => ({ ...column, ...(column.display ? { display: JSON.parse(JSON.stringify(column.display)) as CellDisplay } : {}) })));\n }\n\n // WHERE is CNF: an array of terms, each a literal or an `{ any: [...] }` OR\n // group. MAX_WHERE_CLAUSES bounds the TOTAL predicate count across all terms\n // (legacy flat lists are all literals, so the cap is unchanged for them).\n // Singleton/empty groups are canonicalized (flattened / dropped).\n const where: WhereTerm[] = Array.isArray(raw.where)\n ? normalizeWhereTerms(raw.where)\n : fallback.where.map(cloneWhereTerm);\n\n const orderBy: OrderByClause[] = [];\n if (Array.isArray(raw.orderBy)) {\n for (const item of raw.orderBy.slice(0, MAX_ORDER_BY_TERMS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field || (item.dir !== \"asc\" && item.dir !== \"desc\")) continue;\n const term: OrderByClause = { field, dir: item.dir };\n if (item.nulls === \"first\" || item.nulls === \"last\") term.nulls = item.nulls;\n if (\n isRecord(item.extract) &&\n typeof item.extract.regex === \"string\" &&\n item.extract.regex.length <= MAX_FILTER_VALUE_LENGTH\n ) {\n term.extract = { regex: item.extract.regex };\n }\n orderBy.push(term);\n }\n } else {\n orderBy.push(\n ...fallback.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n );\n }\n\n const out: QueryState = {\n select,\n where,\n orderBy,\n limit: boundedInteger(raw.limit, fallback.limit, 1, MAX_QUERY_LIMIT),\n offset: boundedInteger(raw.offset, fallback.offset, 0, MAX_QUERY_OFFSET),\n };\n\n if (raw.fitToScreen === true) out.fitToScreen = true;\n\n if (raw.grouping != null) out.grouping = normalizeGroupingState(raw.grouping, links);\n\n if (Array.isArray(raw.aggregations)) {\n const aggregations: AggregationClause[] = [];\n for (const item of raw.aggregations.slice(0, MAX_AGGREGATIONS)) {\n if (!isRecord(item)) continue;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id) continue;\n const validOp = typeof item.op === \"string\" && AGG_OPS.has(item.op);\n const rawGroups: unknown[] = Array.isArray(item.groupBy) ? item.groupBy : [];\n const groupBy = rawGroups\n .slice(0, MAX_GROUP_BY_FIELDS)\n .map((field) => boundedString(field, MAX_FIELD_NAME_LENGTH))\n .filter((field): field is string => field != null);\n const aggregation: AggregationClause = { id, op: validOp ? item.op as AggOp : \"count\", groupBy };\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const label = boundedString(item.label, MAX_LABEL_LENGTH);\n if (field) aggregation.field = field;\n if (label) aggregation.label = label;\n Object.assign(aggregation, normalizeMetricOptions(item));\n const metricWhere = normalizeMetricWhere(item.where);\n if (metricWhere.where) aggregation.where = metricWhere.where;\n if (metricWhere.invalid) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric filter.\"];\n if (!Array.isArray(item.groupBy) || rawGroups.length > MAX_GROUP_BY_FIELDS || groupBy.length !== rawGroups.length) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric grouping fields or grouping budget exceeded.\"];\n const unsupportedOp = boundedString(item.unsupportedOp ?? (!validOp ? item.op : undefined), MAX_FIELD_NAME_LENGTH);\n if (unsupportedOp) aggregation.unsupportedOp = unsupportedOp;\n if (item.field !== undefined && !field) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric measure field.\"];\n if (!validOp && typeof item.expression !== \"string\") aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Unsupported aggregate operation.\"];\n aggregations.push(aggregation);\n }\n if (aggregations.length > 0) out.aggregations = aggregations;\n } else if (fallback.aggregations?.length) {\n out.aggregations = normalizeQueryState({ aggregations: fallback.aggregations }).aggregations!;\n }\n\n if (isRecord(raw.itemDetails) && Array.isArray(raw.itemDetails.modes)) {\n const modes = [...new Set(raw.itemDetails.modes.filter(\n (mode): mode is ItemDetailMode => typeof mode === \"string\" && [\"hover\", \"modal\", \"expand\", \"page\"].includes(mode),\n ))];\n const details: ItemDetailsState = { modes };\n if (isRecord(raw.itemDetails.page) && typeof raw.itemDetails.page.urlTemplate === \"string\"\n && raw.itemDetails.page.urlTemplate.length <= 8000) {\n details.page = { urlTemplate: raw.itemDetails.page.urlTemplate,\n target: raw.itemDetails.page.target === \"_self\" ? \"_self\" : \"_blank\" };\n }\n if (raw.itemDetails.view !== undefined) {\n try { details.view = normalizePropertyView(raw.itemDetails.view); } catch { /* Ignore malformed view snapshots. */ }\n }\n if (isRecord(raw.itemDetails.views)) {\n const views: NonNullable<ItemDetailsState[\"views\"]> = {};\n for (const mode of [\"hover\", \"modal\", \"expand\"] as const) {\n try {\n if (raw.itemDetails.views[mode] !== undefined) views[mode] = normalizePropertyView(raw.itemDetails.views[mode]);\n } catch { /* Ignore malformed modality snapshots. */ }\n }\n if (Object.keys(views).length) details.views = views;\n }\n const active = raw.itemDetails.active;\n if (isRecord(active) && (active.mode === \"modal\" || active.mode === \"expand\") && modes.includes(active.mode)\n && ((typeof active.id === \"string\" && active.id.length > 0 && active.id.length <= 1000)\n || (typeof active.id === \"number\" && Number.isFinite(active.id)))) {\n details.active = { id: active.id as RowId, mode: active.mode };\n }\n out.itemDetails = details;\n }\n\n return out;\n}\n\n/** Retain an invalid stage as a diagnostic rather than silently executing an\n * ungrouped query. Strip nesting before normalizing the source snapshot. */\nfunction normalizeGroupingState(value: unknown, links: boolean): GroupingState {\n const raw = isRecord(value) ? value : {};\n const diagnostics: string[] = [];\n // Each problem gets its own message; the stage still refuses to execute.\n const fail = (message: string) => { diagnostics.push(`Invalid grouping: ${message}`); };\n const keys = Array.isArray(raw.keys) ? raw.keys.slice(0, MAX_GROUP_BY_FIELDS).filter((key): key is string => !!boundedString(key, MAX_FIELD_NAME_LENGTH)) : [];\n if (!Array.isArray(raw.keys) || !keys.length || keys.length !== raw.keys.length || new Set(keys).size !== keys.length)\n fail(`keys must list 1–${MAX_GROUP_BY_FIELDS} distinct field names.`);\n const summaries: SummaryColumn[] = [];\n if (!Array.isArray(raw.summaries) || raw.summaries.length > 64) fail(\"summaries must be a list of at most 64 columns.\");\n const summaryIds = new Set<string>();\n for (const [index, item] of (Array.isArray(raw.summaries) ? raw.summaries.slice(0, 64) : []).entries()) {\n const name = isRecord(item) && boundedString(item.id, MAX_FIELD_NAME_LENGTH) ? `summary \"${item.id as string}\"` : `summary ${index + 1}`;\n if (!isRecord(item) || !boundedString(item.id, MAX_FIELD_NAME_LENGTH)) { fail(`${name} needs an id of 1–${MAX_FIELD_NAME_LENGTH} characters.`); continue; }\n if (typeof item.op !== \"string\" || (!AGG_OPS.has(item.op) && item.op !== \"row\" && item.op !== \"formula\" && (item.op !== \"link\" || !links))) {\n fail(item.op === \"link\"\n ? `${name} is a link column; a link's patch cannot contain link columns.`\n : `${name} has unsupported op ${JSON.stringify(String(item.op).slice(0, 40))}; use count, count_distinct, sum, avg, min, max, row, formula, or link${String(item.op).toLowerCase() === \"median\" ? ' (for a median, use op \"formula\" with expression \"MEDIAN([field])\")' : \"\"}.`);\n continue;\n }\n const column: SummaryColumn = { id: item.id as string, op: item.op as SummaryColumn[\"op\"] };\n // Collisions with source fields need the schema and are reported by\n // createGroupingModel().validate(); keys and duplicates are visible here.\n if (summaryIds.has(column.id)) fail(`${name} uses the same id as another summary column.`);\n else if (keys.includes(column.id)) fail(`${name} uses the same id as group key \"${column.id}\"; summary ids must differ from source field names.`);\n summaryIds.add(column.id);\n if (item.op === \"link\") {\n // A malformed spec is isolated to its column (see linkDiagnostics).\n const link = normalizeLinkSpec(item.link);\n if (link) column.link = link;\n if (item.label !== undefined) {\n if (typeof item.label !== \"string\" || item.label.length > MAX_LABEL_LENGTH) fail(`${name} label must be text of at most ${MAX_LABEL_LENGTH.toLocaleString(\"en-US\")} characters.`);\n else column.label = item.label;\n }\n summaries.push(column);\n continue;\n }\n if (item.field !== undefined) {\n if (!boundedString(item.field, MAX_FIELD_NAME_LENGTH)) fail(`${name} has an invalid field name.`);\n else column.field = item.field as string;\n }\n if (item.op === \"formula\") {\n if (typeof item.expression !== \"string\" || item.expression.length > 10_000) fail(`${name} needs an expression of at most 10,000 characters.`);\n else column.expression = item.expression;\n }\n if (item.label !== undefined) {\n if (typeof item.label !== \"string\" || item.label.length > MAX_LABEL_LENGTH) fail(`${name} label must be text of at most ${MAX_LABEL_LENGTH.toLocaleString(\"en-US\")} characters.`);\n else column.label = item.label;\n }\n if (item.display !== undefined) {\n try { column.display = parseCellDisplay(item.display, `${name} display`); }\n catch (error) { fail(`${error instanceof Error ? error.message : String(error)}.`); }\n }\n summaries.push(column);\n }\n let representative: GroupingState[\"representative\"] = null;\n if (raw.representative != null) {\n const ordering = isRecord(raw.representative) ? raw.representative.orderBy : undefined;\n const orderBy: RepresentativeOrder[] = [];\n if (!Array.isArray(ordering) || !ordering.length || ordering.length > 8) fail(\"representative ordering must list 1–8 fields.\");\n for (const term of Array.isArray(ordering) ? ordering.slice(0, 8) : []) {\n if (!isRecord(term) || !boundedString(term.field, MAX_FIELD_NAME_LENGTH) || ![\"asc\", \"desc\"].includes(String(term.dir)) || (term.nulls !== undefined && ![\"first\", \"last\"].includes(String(term.nulls)))) {\n fail('each representative ordering term needs a field, dir \"asc\" or \"desc\", and optional nulls \"first\" or \"last\".');\n continue;\n }\n orderBy.push({ field: term.field as string, dir: term.dir as \"asc\" | \"desc\", nulls: term.nulls === \"first\" ? \"first\" : \"last\" });\n }\n representative = { orderBy };\n }\n if (!isRecord(raw.source)) fail(\"source must be the record query that is grouped.\");\n else if (raw.source.grouping != null) fail(\"only one grouping stage is supported; the source query cannot itself be grouped.\");\n const { grouping: _nested, ...source } = isRecord(raw.source) ? raw.source : {};\n // Retain earlier diagnostics (bounded) instead of collapsing them.\n if (Array.isArray(raw.diagnostics))\n for (const message of raw.diagnostics.slice(0, 20))\n diagnostics.push(typeof message === \"string\" && message ? message.slice(0, MAX_LABEL_LENGTH) : \"Invalid grouping definition.\");\n const normalizedSource = normalizeQueryState(source);\n if (Array.isArray(source.where)) {\n const supplied = source.where.reduce((count: number, term: unknown) => count + (isRecord(term) && Array.isArray(term.any) ? term.any.length : 1), 0);\n if (supplied !== normalizedSource.where.reduce((count, term) => count + predicatesOf(term).length, 0)) fail(\"source filters contain malformed predicates or exceed the predicate budget.\");\n }\n return { keys, summaries, representative, source: normalizedSource, ...(diagnostics.length ? { diagnostics: [...new Set(diagnostics)] } : {}) };\n}\n\nconst QUERY_FACETS: ReadonlySet<string> = new Set([\"filters\", \"columns\", \"order\", \"grouping\", \"metrics\", \"limit\"]);\nconst PATCH_QUERY_KEYS = [\"select\", \"where\", \"orderBy\", \"limit\", \"aggregations\", \"grouping\", \"fitToScreen\"] as const;\nconst MAX_LINK_PARAMS = 50;\n\n/** A link spec, or undefined when any part is malformed. Never partially kept:\n * dropping a key filter or patch term would silently widen the destination. */\nfunction normalizeLinkSpec(value: unknown): LinkSpec | undefined {\n if (!isRecord(value) || !isRecord(value.to)) return undefined;\n let label: LinkSpec[\"label\"];\n if (typeof value.label === \"string\" && value.label.length <= MAX_LABEL_LENGTH) label = value.label;\n else if (isRecord(value.label) && boundedString(value.label.column, MAX_FIELD_NAME_LENGTH)) label = { column: value.label.column as string };\n else return undefined;\n const to = value.to;\n if (to.kind === \"template\") {\n if (typeof to.template !== \"string\" || to.template.length > 8000) return undefined;\n return { label, to: { kind: \"template\", template: to.template } };\n }\n if (to.kind !== \"query\" || !boundedString(to.target, MAX_FIELD_NAME_LENGTH)) return undefined;\n const destination: Extract<LinkDestination, { kind: \"query\" }> = { kind: \"query\", target: to.target as string };\n if (to.base !== undefined) {\n if (to.base !== \"source\" && to.base !== \"empty\") return undefined;\n destination.base = to.base;\n }\n if (to.keyFilters !== undefined) {\n if (typeof to.keyFilters !== \"boolean\") return undefined;\n destination.keyFilters = to.keyFilters;\n }\n if (to.patch !== undefined) {\n const patch = normalizeLinkPatch(to.patch);\n if (!patch) return undefined;\n destination.patch = patch;\n }\n if (to.params !== undefined) {\n if (!isRecord(to.params)) return undefined;\n const entries = Object.entries(to.params);\n if (entries.length > MAX_LINK_PARAMS || entries.some(([key, item]) => !boundedString(key, MAX_FIELD_NAME_LENGTH) || typeof item !== \"string\" || item.length > MAX_FILTER_VALUE_LENGTH))\n return undefined;\n destination.params = Object.fromEntries(entries) as Record<string, string>;\n }\n return { label, to: destination };\n}\n\n/** True when normalization kept every supplied WHERE term. An OR group counts\n * as its members (an empty group as one), so dropping any literal, a whole\n * group or anything past the predicate budget is detected. */\nfunction keptEveryTerm(supplied: unknown, kept: readonly WhereTerm[]): boolean {\n if (!Array.isArray(supplied)) return false;\n const count = supplied.reduce((total: number, term: unknown) =>\n total + (isRecord(term) && Array.isArray(term.any) ? Math.max(1, term.any.length) : 1), 0);\n return count === kept.reduce((total, term) => total + predicatesOf(term).length, 0);\n}\n\n/** Keep only the facets the patch supplies, each normalized like any query.\n * Ordinary normalization drops malformed filter terms, which here would\n * silently widen the destination, so any loss rejects the whole patch. */\nfunction normalizeLinkPatch(value: unknown): QueryPatch | undefined {\n if (!isRecord(value) || !boundedString(value.id, MAX_FIELD_NAME_LENGTH) || !Array.isArray(value.owns) || !isRecord(value.query)) return undefined;\n if (value.owns.length > QUERY_FACETS.size || value.owns.some((facet) => typeof facet !== \"string\" || !QUERY_FACETS.has(facet))) return undefined;\n const raw = value.query;\n const normalized = normalizeQuery(raw, EMPTY_QUERY, false);\n if (normalized.grouping?.diagnostics) return undefined;\n if (raw.where !== undefined && !keptEveryTerm(raw.where, normalized.where)) return undefined;\n if (raw.aggregations !== undefined && (!Array.isArray(raw.aggregations) ||\n raw.aggregations.length !== (normalized.aggregations?.length ?? 0) ||\n normalized.aggregations?.some((clause) => clause.diagnostics?.length))) return undefined;\n const query: Partial<QueryState> = {};\n for (const key of PATCH_QUERY_KEYS) {\n if (raw[key] !== undefined && normalized[key] !== undefined) (query as Record<string, unknown>)[key] = normalized[key];\n }\n return { id: value.id as string, owns: [...new Set(value.owns as QueryFacet[])], query };\n}\n\n/** Structural equality on two queries — used to decide whether a `?q=` write or a\n * refetch is actually needed (avoids history spam / redundant fetches). */\nexport function queriesEqual(a: QueryState, b: QueryState): boolean {\n if (a === b) return true;\n if (a.limit !== b.limit || a.offset !== b.offset) return false;\n if ((a.fitToScreen === true) !== (b.fitToScreen === true)) return false;\n if (!sameArray(a.where, b.where)) return false;\n if (!sameArray(a.orderBy, b.orderBy)) return false;\n if (!sameArray(a.select, b.select)) return false;\n if (!sameArray(a.aggregations ?? [], b.aggregations ?? [])) return false;\n if (JSON.stringify(a.itemDetails) !== JSON.stringify(b.itemDetails)) return false;\n if (JSON.stringify(a.grouping) !== JSON.stringify(b.grouping)) return false;\n return true;\n}\n\nfunction sameArray<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n // Members are records of primitives (WHERE terms may nest one `any` array of\n // them) — a structural JSON compare is correct and cheap here.\n if (JSON.stringify(a[i]) !== JSON.stringify(b[i])) return false;\n }\n return true;\n}\n","const UNIT_MS: Record<string, number> = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000 };\n/** Portable datetime/offset bound in milliseconds (also below MAX_SAFE_INTEGER). */\nexport const MAX_RELATIVE_TIME_MS = 8_640_000_000_000_000;\n\n/** A signed elapsed offset, e.g. -1h or +8d2h10m. The sign applies to the\n * complete sum. Returns null for absolute values or invalid duration syntax.\n * Units are lowercase; amounts are whole integers. No whitespace, calendar\n * arithmetic, locale, or Date.parse heuristics are used. */\nexport function parseRelativeDuration(value: string): number | null {\n const valid = /^[+-](?:[0-9]+(?:ms|s|m|h|d|w))+$/.exec(value);\n if (!valid || valid[0] !== value) return null;\n const body = value.slice(1);\n const components = /([0-9]+)(ms|s|m|h|d|w)/g;\n let total = 0;\n for (const match of body.matchAll(components)) {\n const amount = Number(match[1]);\n const unit = UNIT_MS[match[2]!]!;\n if (!Number.isSafeInteger(amount) || amount > Math.floor((MAX_RELATIVE_TIME_MS - total) / unit)) return null;\n total += amount * unit;\n }\n return value[0] === \"-\" && total !== 0 ? -total : total;\n}\n\n/** Local execution only. The server independently owns its execution clock. */\nexport interface QueryEvaluationOptions { now?: number }\n\nexport function evaluationTime(options: QueryEvaluationOptions): number {\n const now = options.now ?? Date.now();\n if (!Number.isSafeInteger(now) || Math.abs(now) > MAX_RELATIVE_TIME_MS) throw new Error(\"Invalid query evaluation time\");\n return now;\n}\n\nexport function relativeTimestamp(now: number, offsetMs: number): number {\n const result = now + offsetMs;\n if (!Number.isSafeInteger(result) || Math.abs(result) > MAX_RELATIVE_TIME_MS) throw new Error(\"Relative time exceeds datetime limits\");\n return result;\n}\n","// ops.ts — which operators a field type allows, and value coercion.\n//\n// Single source of truth for \"what filters can I build on this field\", shared by\n// the QueryBuilder UI, the CellMenu quick-filters, and client-side applyQuery.\n// The backend (backends/go) enforces the same matrix independently — never trust\n// the client.\n//\n// Every value can be NULL, so `is_null`/`is_not_null` are available on EVERY\n// type, including bool (design feedback).\n\nimport { parseRelativeDuration, relativeTimestamp } from \"./relativeTime\";\nimport type { FilterOp, FieldType, FieldDef, WhereClause } from \"./index\";\n\nconst NULLITY: FilterOp[] = [\"is_null\", \"is_not_null\"];\n\n/** Operators that are each other's logical complement. Negating one of these is\n * a clean op flip (no NULL surprises the two ops don't already share), so the\n * UI can render `≥ 10`'s negation as `< 10` rather than `NOT (≥ 10)`. Ops absent\n * here (`contains`/`starts_with`/`ends_with`/`includes`) have no single-op\n * complement and negate via the `WhereClause.negated` flag instead. */\nconst COMPLEMENT_OP: Partial<Record<FilterOp, FilterOp>> = {\n \"=\": \"!=\",\n \"!=\": \"=\",\n \">\": \"<=\",\n \"<=\": \">\",\n \">=\": \"<\",\n \"<\": \">=\",\n is_null: \"is_not_null\",\n is_not_null: \"is_null\",\n matches_regex: \"not_matches_regex\",\n not_matches_regex: \"matches_regex\",\n};\n\n/** The logical negation of a predicate. Prefers flipping to the complementary\n * operator (nicer to read, and the server's op allowlist already covers it);\n * falls back to toggling the `negated` flag when the op has no complement, or\n * when the complement is not in `allowedOps` (a field's `filter.ops` override\n * could disable it, and the server would reject a disabled op). `allowedOps`,\n * when given, is the field's effective operator set from `opsForField`. */\nexport function negateClause(clause: WhereClause, allowedOps?: readonly FilterOp[]): WhereClause {\n if (clause.value === \"0\" && !clause.negated) {\n const zeroComplement = clause.op === \"length_gt\" ? \"length_eq\" : clause.op === \"length_eq\" ? \"length_gt\" : null;\n if (zeroComplement && (!allowedOps || allowedOps.includes(zeroComplement))) {\n return { field: clause.field, op: zeroComplement, value: \"0\" };\n }\n }\n const complement = COMPLEMENT_OP[clause.op];\n if (complement && (!allowedOps || allowedOps.includes(complement))) {\n const next: WhereClause = { field: clause.field, op: complement, value: clause.value };\n return next; // a complement fully expresses the negation; drop any stale flag\n }\n const next: WhereClause = { field: clause.field, op: clause.op, value: clause.value };\n if (!clause.negated) next.negated = true;\n return next;\n}\n\n/** Whether a predicate is negative — either an op that reads as a negation\n * (`!=`, `not_matches_regex`, `is_not_null`) or one carrying the `negated`\n * flag. Used to sort candidate filters into the CellMenu's two columns. */\nexport function isNegativePredicate(clause: Pick<WhereClause, \"op\" | \"negated\">): boolean {\n return Boolean(clause.negated) || clause.op === \"!=\" || clause.op === \"not_matches_regex\" || clause.op === \"is_not_null\";\n}\n\n/** A specific operator + negation state, e.g. `{ op: \"<\", negated: false }` or\n * `{ op: \"contains\", negated: true }`. */\nexport interface OpChoice {\n op: FilterOp;\n negated: boolean;\n}\n\n/** A positive operator (\"keep\") and its logical negation (\"exclude\") — the row\n * shape rendered by both the CellMenu quick-filters and the WHERE operator\n * picker, so the two read identically. */\nexport interface OpPair {\n keep: OpChoice;\n exclude: OpChoice;\n}\n\n/** Positive operators surfaced in the \"keep\" column, in display order. Each\n * one's negation lands opposite via `negateClause`, so the pair covers\n * `<`/`<=`/`!=`/`not_matches_regex` without listing them separately. */\nconst POSITIVE_OP_ORDER: FilterOp[] = [\"=\", \">\", \">=\", \"contains\", \"starts_with\", \"ends_with\", \"length_gt\", \"length_lt\", \"length_eq\", \"matches_regex\", \"includes\"];\n\n/** The keep/exclude operator pairs offered for a field: each positive op with\n * its negation opposite, then a nullity row (`is null`/`is not null`) when the\n * field allows it. Derived from the field's effective op set and `negateClause`,\n * so a `filter.ops` override narrows the offered pairs too. */\nexport function opPairsForField(field: Pick<FieldDef, \"type\" | \"filter\">): OpPair[] {\n const ops = opsForField(field);\n const allow = new Set(ops);\n const pairs: OpPair[] = [];\n for (const op of POSITIVE_OP_ORDER) {\n if (!allow.has(op)) continue;\n const neg = negateClause({ field: \"\", op, value: \"\" }, ops);\n pairs.push({ keep: { op, negated: false }, exclude: { op: neg.op, negated: Boolean(neg.negated) } });\n }\n if (allow.has(\"is_null\") || allow.has(\"is_not_null\")) {\n pairs.push({ keep: { op: \"is_null\", negated: false }, exclude: { op: \"is_not_null\", negated: false } });\n }\n return pairs;\n}\n\n/** Default operator set per type. A FieldDef.filter.ops overrides this. */\nexport const OPS_BY_TYPE: Record<FieldType, FilterOp[]> = {\n text: [\n \"=\",\n \"!=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n ...NULLITY,\n ],\n enum: [\"=\", \"!=\", ...NULLITY],\n number: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n datetime: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n bool: [\"=\", \"!=\", ...NULLITY],\n textarray: [\"includes\", ...NULLITY],\n};\n\n/** Operators that take no value (the value input is hidden). */\nexport const NULLARY_OPS: ReadonlySet<FilterOp> = new Set<FilterOp>(NULLITY);\n\n/** Effective operators for a field (its override, else the type default). */\nexport function opsForField(field: Pick<FieldDef, \"type\" | \"filter\">): FilterOp[] {\n return field.filter?.ops ?? OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (server mirror lives\n * in Go opAllowed; keep them in lockstep). */\nexport function opAllowedForType(type: FieldType, op: FilterOp): boolean {\n return OPS_BY_TYPE[type].includes(op);\n}\n\n/** Coerce a raw string value to the type the field expects, for client-side\n * comparison. Throws on invalid input (e.g. a non-numeric value on a number\n * field) so callers can surface it rather than silently mis-filtering. */\nexport function coerceValue(type: FieldType, raw: string, now?: number): string | number | boolean {\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n if (raw.trim() === \"\" || Number.isNaN(n)) throw new Error(`not a number: ${JSON.stringify(raw)}`);\n return n;\n }\n case \"bool\": {\n const v = raw.toLowerCase();\n if (v === \"true\" || v === \"1\" || v === \"t\") return true;\n if (v === \"false\" || v === \"0\" || v === \"f\") return false;\n throw new Error(`not a bool: ${JSON.stringify(raw)}`);\n }\n case \"datetime\": {\n if (raw.startsWith(\"+\") || raw.startsWith(\"-\")) {\n const offset = parseRelativeDuration(raw);\n if (offset === null) throw new Error(`not a signed duration: ${JSON.stringify(raw)}`);\n return relativeTimestamp(now ?? Date.now(), offset);\n }\n const ms = Date.parse(raw);\n if (Number.isNaN(ms)) throw new Error(`not a datetime: ${JSON.stringify(raw)}`);\n return ms;\n }\n default:\n return raw;\n }\n}\n","// agg.ts — which aggregate ops a field type allows, and which fields can be a\n// measure or a group-by key. The single source of truth shared by the\n// QueryBuilder's metric editor, the client-side applyAggregations, and (mirrored\n// independently in backends/go) the SQL compiler. Never trust the client: the Go\n// `aggOpAllowed` enforces the same matrix before any GROUP BY is built.\n\nimport type { AggOp } from \"./query\";\nimport type { FieldType, FieldDef } from \"./schema\";\n\n/** Default aggregate ops per field type. A FieldDef.aggregate.ops overrides this.\n * `count`/`count_distinct` work on anything countable; sum/avg are numeric-only;\n * min/max need an ordered domain (numbers, datetimes, and lexical text/enum). */\nexport const AGG_OPS_BY_TYPE: Record<FieldType, AggOp[]> = {\n number: [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"],\n datetime: [\"count\", \"count_distinct\", \"min\", \"max\"],\n enum: [\"count\", \"count_distinct\", \"min\", \"max\"],\n text: [\"count\", \"count_distinct\", \"min\", \"max\"],\n bool: [\"count\", \"count_distinct\"],\n textarray: [\"count\"],\n};\n\n/** Ops that reduce a measure column. `count` is the only op that may omit a\n * field (counting rows), so it's the only one absent here. */\nexport const AGG_OPS_NEEDING_FIELD: ReadonlySet<AggOp> = new Set<AggOp>([\n \"count_distinct\",\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n]);\n\n/** Whether an op requires a measure column. */\nexport function aggOpNeedsField(op: AggOp): boolean {\n return AGG_OPS_NEEDING_FIELD.has(op);\n}\n\n/** Effective aggregate ops for a field (its override, else the type default). */\nexport function aggOpsForField(field: Pick<FieldDef, \"type\" | \"aggregate\">): AggOp[] {\n return field.aggregate?.ops ?? AGG_OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (Go aggOpAllowed is\n * the server mirror; keep them in lockstep). */\nexport function aggOpAllowedForType(type: FieldType, op: AggOp): boolean {\n return AGG_OPS_BY_TYPE[type].includes(op);\n}\n\n/** Can this field be the MEASURE of a metric? Only backend fields (they have SQL\n * to aggregate); derived/render-only columns are never pushed to the server. An\n * explicit `aggregate.measure` wins over the type default. */\nexport function isMeasurable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.measure === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.measure != null) return field.aggregate.measure;\n return aggOpsForField(field).length > 0;\n}\n\n/** Can this field be a GROUP BY key? Backend fields only. Default: low-cardinality\n * types (enum/text/bool); numbers/datetimes need bucketing (out of scope) so they\n * default off, but `aggregate.groupable: true` opts any backend field in. */\nexport function isGroupable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.groupable === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.groupable != null) return field.aggregate.groupable;\n return field.type === \"enum\" || field.type === \"text\" || field.type === \"bool\";\n}\n","import type { MetricKey, MetricValue, MetricScope, MetricDistributionResult, MetricDiagnostic, MetricHistogramBin } from \"./metricTypes\";\nimport { deflateSync, Inflate } from \"fflate\";\nimport { createSetFilter, readSetFilter } from \"./setFilter\";\n// encode.ts — URL serialization + the server-bound query subset.\n//\n// Two distinct serializations, deliberately kept apart:\n//\n// 1. encodeQuery / decodeQuery — the *whole* QueryState (incl. view state:\n// select columns + widths) ⇄ a base64url `?q=` token. This is what makes\n// reload, back/forward, bookmarks, and \"send a coworker your view\" all work\n// (decisions #4 + #5). Defaults are omitted to keep the token short.\n//\n// 2. toServerQuery — the subset the backend acts on: pushdown\n// WHERE clauses, server-sortable ORDER BY (remapped through sort.field), the\n// page window, and the field names to SELECT (so the backend evaluates the\n// computed/synthetic columns the view needs — requested ∪ always-needed,\n// design decision #2). Per-column widths never leave the client.\n//\n// Back-compat: decodeQuery accepts legacy compact shapes: `o` as a single\n// object (pre-multi-sort) and `c`/`s` as a string[] (pre-width).\n\nimport { EMPTY_QUERY, MAX_QUERY_TOKEN_LENGTH, normalizeQueryState, predicatesOf } from \"./query\";\nimport { stripSetFilter } from \"./setFilter\";\nimport type { QueryState, WhereTerm, OrderByClause, SelectColumn, AggregationClause, SetFilterMode } from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { indexFields, isFilterable, isPushdownFilter, isSortable, resolveFieldName, selectedFields } from \"./schema\";\n\n// ---- base64url (browser + node) -------------------------------------------\n\nfunction toBase64Url(json: string): string {\n let b64: string;\n if (typeof Buffer !== \"undefined\") {\n b64 = Buffer.from(json, \"utf8\").toString(\"base64\");\n } else {\n const bytes = new TextEncoder().encode(json);\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n b64 = btoa(bin);\n }\n return b64.replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction fromBase64Url(s: string): string {\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4);\n if (typeof Buffer !== \"undefined\") return Buffer.from(b64, \"base64\").toString(\"utf8\");\n const bin = atob(b64);\n const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n// ---- compact wire form ----------------------------------------------------\n// Keys are short to keep `?q=` small; any field at its default is omitted.\n// s = select (as [field], [field, width] or [field, width | null, display]\n// tuples; older decoders read the first two members and ignore display)\n// w = where, o = orderBy, l = limit, f = offset\n// fs = fit to the viewer's screen\n\ntype CompactColumn = [string] | [string, number] | [string, number | null, CellDisplay];\n\ninterface CompactQuery {\n s?: CompactColumn[] | string[]; // string[] = legacy\n w?: WhereTerm[];\n o?: OrderByClause[] | OrderByClause; // object accepted for legacy decode\n l?: number;\n f?: number;\n g?: AggregationClause[]; // aggregation metrics (omitted when none)\n d?: QueryState[\"itemDetails\"];\n c?: string[]; // legacy alias for select column names\n fs?: boolean;\n b?: QueryState[\"grouping\"];\n}\n\n/** Canonical query projected into the URL wire form. */\nfunction compactQuery(q: QueryState): CompactQuery {\n q = normalizeQueryState(q);\n const c: CompactQuery = {};\n if (q.select.length)\n c.s = q.select.map((col): CompactColumn =>\n col.display ? [col.field, col.width ?? null, col.display]\n : col.width != null ? [col.field, col.width] : [col.field]);\n if (q.where.length) c.w = q.where;\n if (q.orderBy.length) c.o = q.orderBy;\n c.l = q.limit;\n if (q.offset) c.f = q.offset;\n if (q.aggregations?.length) c.g = q.aggregations;\n if (q.itemDetails) c.d = q.itemDetails;\n if (q.fitToScreen) c.fs = true;\n if (q.grouping) c.b = q.grouping;\n return c;\n}\n\nexport const MAX_QUERY_STATE_BYTES = 4 * 1024 * 1024;\nexport class QueryDecodeError extends Error {\n constructor(public readonly code: \"invalid\" | \"too_large\" | \"unsupported_version\", message: string) {\n super(message); this.name = \"QueryDecodeError\";\n }\n}\n\n// v2 keeps execution state unchanged, but represents intact set editors once.\n// Equal property layouts share one entry rather than repeating every modality.\nfunction packQuery(c: CompactQuery): Record<string, unknown> {\n const packed: Record<string, unknown> = { ...c };\n if (c.l === EMPTY_QUERY.limit) delete packed.l;\n if (c.w) {\n const terms: unknown[] = [];\n for (let i = 0; i < c.w.length; i++) {\n const set = readSetFilter(c.w, i);\n // Scalar sets stay as plain marked terms: the packed tuple always means\n // array membership, so older decoders must not rebuild them as includes.\n if (set?.target === \"array\") {\n terms.push([\"set\", set.field, set.metadata.mode, set.metadata.values, set.metadata.id]);\n i += set.count - 1;\n } else terms.push(c.w[i]);\n }\n packed.w = terms;\n }\n if (c.d?.views) {\n const pool: unknown[] = [];\n const refs: Record<string, number> = {};\n for (const [mode, view] of Object.entries(c.d.views)) {\n let index = pool.findIndex(v => JSON.stringify(v) === JSON.stringify(view));\n if (index < 0) { index = pool.length; pool.push(view); }\n refs[mode] = index;\n }\n packed.d = { ...c.d, views: { pool, refs } };\n }\n return packed;\n}\n\nfunction unpackQuery(c: Record<string, unknown>): CompactQuery {\n if (Array.isArray(c.w)) c.w = c.w.flatMap((term: unknown) => {\n if (!Array.isArray(term)) return [term];\n if (term.length !== 5 || term[0] !== \"set\" || typeof term[1] !== \"string\" ||\n typeof term[2] !== \"string\" || ![\"any\", \"all\", \"none\", \"empty\"].includes(term[2]) || !Array.isArray(term[3]) ||\n term[3].length > 100 || !term[3].every((v: unknown) => typeof v === \"string\" && v.length <= 10000) || typeof term[4] !== \"string\")\n throw new QueryDecodeError(\"invalid\", \"Invalid set filter in query link.\");\n return createSetFilter(term[1], term[2] as SetFilterMode, term[3] as string[], term[4]);\n });\n const details = c.d;\n const views = details && typeof details === \"object\" && \"views\" in details ? details.views : undefined;\n if (details && typeof details === \"object\" && views && typeof views === \"object\" && \"pool\" in views) {\n const pool = views.pool;\n const refs = \"refs\" in views ? views.refs : undefined;\n if (!Array.isArray(pool) || pool.length > 3 || !refs || typeof refs !== \"object\" || Array.isArray(refs))\n throw new QueryDecodeError(\"invalid\", \"Invalid property views in query link.\");\n c.d = { ...details, views: Object.fromEntries(Object.entries(refs).map(([mode, index]) => {\n if (![\"hover\", \"modal\", \"expand\"].includes(mode) || !Number.isInteger(index) || (index as number) < 0 || (index as number) >= pool.length)\n throw new QueryDecodeError(\"invalid\", \"Invalid property view reference.\");\n return [mode, pool[index as number]];\n })) };\n }\n return c as CompactQuery;\n}\n\n/** v2 JSON or raw-DEFLATE UTF-8, whichever produces the shorter URL token. */\nexport function encodeQuery(q: QueryState): string {\n const json = JSON.stringify(packQuery(compactQuery(q)));\n const bytes = new TextEncoder().encode(json);\n if (bytes.length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const plain = \"2j.\" + toBase64Url(json);\n const compressed = \"2d.\" + bytesToBase64(deflateSync(bytes));\n const token = compressed.length < plain.length ? compressed : plain;\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Encoded query state exceeds the storage limit.\");\n return token;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") return Buffer.from(bytes).toString(\"base64\").replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n let bin = \"\";\n for (const byte of bytes) bin += String.fromCharCode(byte);\n return btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction inflateToken(token: string): string {\n const bin = atob(token.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const input = Uint8Array.from(bin, c => c.charCodeAt(0));\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n const stream = new Inflate((chunk, final) => {\n size += chunk.length;\n if (size > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Expanded query state exceeds the storage limit.\");\n chunks.push(chunk); complete = final;\n });\n // Small input chunks bound allocations before the expanded-size check.\n for (let i = 0; i < input.length; i += 256) stream.push(input.subarray(i, i + 256), i + 256 >= input.length);\n if (!complete) throw new QueryDecodeError(\"invalid\", \"Incomplete compressed query link.\");\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n}\n\n/** base64url token → QueryState. Tolerant: bad input and legacy shapes both\n * normalize to a valid QueryState (never throws). */\nexport function decodeQuery(token: string): QueryState {\n try { return decodeToken(token, false); } catch { return { ...EMPTY_QUERY }; }\n}\n\n/** Navigation uses this decoder so corrupt links cannot silently run defaults. */\nexport function decodeQueryStrict(token: string): QueryState {\n return decodeToken(token, true);\n}\nfunction decodeToken(token: string, strict: boolean): QueryState {\n if (!token) return { ...EMPTY_QUERY };\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Query link exceeds the storage limit.\");\n try {\n const versioned = token.includes(\".\");\n if (versioned && !token.startsWith(\"2j.\") && !token.startsWith(\"2d.\"))\n throw new QueryDecodeError(\"unsupported_version\", \"Unsupported query link version.\");\n const payload = versioned ? token.slice(3) : token;\n if (!/^[A-Za-z0-9_-]+$/.test(payload) || payload.length % 4 === 1) throw new QueryDecodeError(\"invalid\", \"Invalid query link encoding.\");\n const json = token.startsWith(\"2d.\") ? inflateToken(payload) : fromBase64Url(payload);\n if (new TextEncoder().encode(json).length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const raw = JSON.parse(json);\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw) || [\"w\", \"g\"].some(k => raw[k] !== undefined && !Array.isArray(raw[k])))\n throw new QueryDecodeError(\"invalid\", \"Invalid query link state.\");\n const c = versioned ? unpackQuery(raw) : raw as CompactQuery;\n if (strict && c.w) {\n if (c.w.some((term: WhereTerm) => !term || typeof term !== \"object\")) throw new QueryDecodeError(\"invalid\", \"Invalid query predicates.\");\n const count = c.w.reduce((n: number, term: WhereTerm) => n + predicatesOf(term).length, 0);\n const normalized = normalizeQueryState({ where: c.w });\n const normalizedCount = normalized.where.reduce((n, term) => n + predicatesOf(term).length, 0);\n if (count > 100 || count !== normalizedCount || c.w.some((term: WhereTerm) => predicatesOf(term).some(clause =>\n !clause || typeof clause !== \"object\" || (clause.negated !== undefined && typeof clause.negated !== \"boolean\"))))\n throw new QueryDecodeError(\"invalid\", \"Invalid query predicates or predicate budget exceeded.\");\n }\n const out = normalizeQueryState({\n select: normalizeSelect(c.s ?? c.c),\n where: Array.isArray(c.w) ? c.w : [],\n orderBy: normalizeOrderBy(c.o),\n limit: c.l,\n offset: c.f,\n aggregations: c.g,\n itemDetails: c.d,\n fitToScreen: c.fs,\n grouping: c.b,\n });\n if (strict && c.g && out.aggregations?.length !== c.g.length) throw new QueryDecodeError(\"invalid\", \"Invalid query metrics.\");\n return out;\n } catch (error) {\n if (error instanceof QueryDecodeError) throw error;\n throw new QueryDecodeError(\"invalid\", \"Invalid or incomplete query link.\");\n }\n}\n\nfunction normalizeSelect(s: CompactQuery[\"s\"] | CompactQuery[\"c\"]): SelectColumn[] {\n if (!Array.isArray(s)) return [];\n return s\n .map((item): SelectColumn | null => {\n if (typeof item === \"string\") return { field: item }; // legacy string[]\n if (Array.isArray(item) && typeof item[0] === \"string\") {\n const column: SelectColumn = { field: item[0] };\n if (typeof item[1] === \"number\") column.width = item[1];\n // normalizeQueryState validates the display and drops a malformed one.\n if (item[2] !== undefined) column.display = item[2] as CellDisplay;\n return column;\n }\n return null;\n })\n .filter((x): x is SelectColumn => x != null);\n}\n\nfunction normalizeOrderBy(o: CompactQuery[\"o\"]): OrderByClause[] {\n if (!o) return [];\n if (Array.isArray(o)) return o;\n return [o]; // legacy single-object form → one-element array\n}\n\n// ---- server-bound subset --------------------------------------------------\n\n/** The backend request derived from a QueryState + its schema. Mirrors the Go\n * `WireQuery`. View-only state (column widths) is intentionally absent. */\nexport interface ServerQuery {\n /** field names to return — visible columns ∪ fields referenced by where/orderBy. */\n select: string[];\n /** only terms whose every predicate is on a pushdown-filterable field. */\n where: WhereTerm[];\n /** only terms on server-sortable fields, with `field` already remapped to the\n * field's server sort key (FieldDef.sort.field) when set. */\n orderBy: OrderByClause[];\n limit: number;\n offset: number;\n}\n\n/** Project a QueryState into the server request, dropping client-only filters,\n * client-only sorts, and remapping sort fields through `sort.field`. */\nexport function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): ServerQuery {\n if (q.grouping) throw new Error(\"This transport does not support grouped queries. Enable the v3 query executor.\");\n q = normalizeQueryState(q);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const orderBy: OrderByClause[] = [];\n for (const term of q.orderBy) {\n const field = resolveField(term.field);\n const f = byName.get(field);\n if (!f || !isSortable(f) || f.source.kind !== \"backend\") continue;\n orderBy.push({ ...term, field: f.sort?.field ?? f.name });\n }\n\n // SELECT = the BACKEND columns the response rows must carry: visible backend\n // columns, the id (for selection/refresh), and any backend column a\n // CLIENT-SIDE filter reads. Derived/render-only columns are computed on the\n // client and have no SQL to select; pushdown filters/sorts run in SQL and need\n // not be returned (design decision #2: requested ∪ always-needed).\n const select = new Set<string>(\n selectedFields(schema, q)\n .filter((f) => f.source.kind === \"backend\")\n .map((f) => f.name),\n );\n for (const field of selectedFields(schema, q)) {\n if (field.source.kind === \"derived\") {\n for (const name of field.source.dependencies ?? []) {\n if (byName.get(name)?.source.kind === \"backend\") select.add(name);\n }\n }\n }\n select.add(schema.idField);\n for (const term of q.where) {\n for (const cl of predicatesOf(term)) {\n const field = resolveField(cl.field);\n const f = byName.get(field);\n if (f && isFilterable(f) && !isPushdownFilter(f) && f.source.kind === \"backend\") select.add(field);\n }\n }\n\n return { select: [...select].sort(), where, orderBy, limit: q.limit, offset: q.offset };\n}\n\n/** A term can push down only if EVERY predicate it contains is on a\n * pushdown-filterable field. An OR group is all-or-nothing: dropping one\n * disjunct would change the set the group matches, so a group with any\n * non-pushdown member stays client-side in full. */\nfunction termIsPushdown<Row>(\n term: WhereTerm,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (name: string) => string,\n): boolean {\n return predicatesOf(term).every((cl) => {\n const f = byName.get(resolveField(cl.field));\n return f != null && isPushdownFilter(f);\n });\n}\n\n// ---- aggregation server subset --------------------------------------------\n\n/** The backend request for the metric panel. Scope is the whole filtered set:\n * the SAME pushdown WHERE as the rows query, but NO ORDER BY / LIMIT / OFFSET —\n * metrics describe every matching row, not the visible page. Mirrors the Go\n * AggSpec list. */\nexport interface AggregationRequest {\n diagnostics?: MetricDiagnostic[];\n where: WhereTerm[];\n aggregations: AggregationClause[];\n}\n\n/** One group's result. `keys` has one entry per AggregationClause.groupBy field,\n * in axis order (`[]` for a grand total); a null key is the NULL/empty bucket. */\nexport interface AggregationBucket {\n keys: MetricKey[];\n error?: string;\n y?: MetricValue;\n yError?: string;\n components?: {expression:string; value:MetricValue}[];\n nullCount?: number;\n inputErrorCount?: number;\n distribution?: MetricDistributionResult;\n /** Client-side only: set by the metric UI when one histogram bin of this\n * cohort is inspected (`count`/`value` are then the bin's count). Never part\n * of a transport result. */\n bin?: MetricHistogramBin;\n /** The metric: a number for count/sum/avg, or the column's value for min/max\n * (which may be a string for text/datetime). null when undefined (e.g. avg of\n * an all-null column). */\n value: MetricValue;\n /** COUNT(*) of rows in the group — always present, even when `value` isn't a\n * count, so the panel can show group sizes / shares. */\n count: number;\n}\n\nexport interface AggregationResultEntry {\n /** Exact omitted additive quantity; unavailable for ratios/averages/distinct. */\n other?: AggregationBucket;\n error?: string;\n scope?: MetricScope;\n processedRows?: number;\n groupCount?: number;\n coverage?: \"exact\" | \"partial\";\n /** Groups removed by AggregationClause.minCount (present whenever it is set).\n * They are not part of `groupCount`, `buckets` or `other`. */\n hiddenGroups?: number;\n /** Echoes AggregationClause.id. */\n id: string;\n buckets: AggregationBucket[];\n}\n\nexport interface AggregationResult {\n /** One entry per requested aggregation, in request order. */\n metrics: AggregationResultEntry[];\n}\n\n/** Project a QueryState into the metric request: the pushdown WHERE subset (same\n * rule as toServerQuery) plus the aggregations whose measure + group fields are\n * all server-capable backend columns. Aggregations referencing a derived /\n * unknown field are dropped — the server has no SQL for them. */\nexport function toAggregationQuery<Row>(q: QueryState, schema: FieldSchema<Row>): AggregationRequest {\n if (q.grouping) throw new Error(\"Metrics over grouped rows require grouped-query execution.\");\n const suppliedPredicateCount = q.where.reduce((n,t)=>n+predicatesOf(t).length,0);\n q = normalizeQueryState(q);\n if (q.aggregations?.some(a => a.dateGrouping)) throw new Error(\"Date grouping currently requires local metric execution.\");\n if (q.aggregations?.some(a => a.diagnostics?.length || a.expression !== undefined || a.expressionY !== undefined || a.distribution || a.scope === \"shownRows\" || a.sort?.length || a.groupLimit || a.where?.length || a.minCount !== undefined)) throw new Error(\"Metric definition requires the version 2 metric transport.\");\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const isBackend = (name: string | undefined): boolean => {\n if (name == null) return true; // omitted measure (count(*)) is fine\n const field = resolveField(name);\n const f = byName.get(field);\n return f != null && f.source.kind === \"backend\";\n };\n\n const aggregations = (q.aggregations ?? []).filter(\n (a) => isBackend(a.field) && a.groupBy.every((g) => isBackend(g)),\n );\n\n const diagnostics: MetricDiagnostic[] = [];\n for (const c of q.aggregations ?? []) if (!aggregations.includes(c)) diagnostics.push({ metricId: c.id, code: \"unsupported_metric\", message: \"Metric requires unavailable backend fields.\", from: 0, to: 1 });\n if (where.length !== q.where.length || suppliedPredicateCount !== q.where.reduce((n,t)=>n+predicatesOf(t).length,0)) diagnostics.push({ code: \"residual_filter\", message: \"All-matching metrics are unavailable with residual client-only filters.\", from: 0, to: 1 });\n return { where, aggregations, ...(diagnostics.length ? { diagnostics } : {}) };\n}\n","import { isOrGroup, predicatesOf, type SetFilterMetadata, type SetFilterMode, type WhereTerm } from \"./query\";\nimport { filterValues, type FieldDef } from \"./schema\";\n\n/** What a set editor compiles to: array membership (`includes`) for textarray\n * fields, or scalar equality (`=` / `!=`) for enum and static-option text fields. */\nexport type SetFilterTarget = \"array\" | \"scalar\";\n\n/** The set editor a field opted into with `filter.editor: \"set\"`, or null.\n * Text fields qualify only with static `filter.values.options`. */\nexport function setFilterTarget(field: FieldDef): SetFilterTarget | null {\n if (field.filter?.editor !== \"set\") return null;\n if (field.type === \"textarray\") return \"array\";\n if (field.type === \"enum\" || (field.type === \"text\" && filterValues(field).source === \"static\")) return \"scalar\";\n return null;\n}\n\n/** Modes a target supports. ALL and EMPTY describe arrays; a scalar holds one value. */\nexport function setFilterModes(target: SetFilterTarget): SetFilterMode[] {\n return target === \"array\" ? [\"any\", \"all\", \"none\", \"empty\"] : [\"any\", \"none\"];\n}\n\n/** Compile an explicitly identified editor into existing CNF predicates.\n * Scalar NONE keeps NULL rows: one `(is_null OR != v)` group per value, because\n * a bare `!=` is null-exclusive. */\nexport function createSetFilter(field: string, mode: SetFilterMode, values: string[], id: string, target: SetFilterTarget = \"array\"): WhereTerm[] {\n if (!setFilterModes(target).includes(mode)) throw new Error(`${mode.toUpperCase()} set filters require a textarray field.`);\n const keys = [...new Set(values)];\n if (mode !== \"empty\" && keys.length === 0) return [];\n const members = keys.map((value) => ({ field, op: target === \"array\" ? \"includes\" as const : \"=\" as const, value }));\n const isNull = { field, op: \"is_null\" as const, value: \"\" };\n let terms: WhereTerm[];\n if (mode === \"empty\") terms = [isNull];\n else if (mode === \"any\") terms = members.length === 1 ? members : [{ any: members }];\n else if (mode === \"all\") terms = members;\n else terms = members.map((clause) => ({ any: [isNull, target === \"array\" ? { ...clause, negated: true } : { ...clause, op: \"!=\" as const }] }));\n return terms.map((term) => ({ ...term, setFilter: { id, mode, values: mode === \"empty\" ? [] : [...keys] } }));\n}\n\n/** Remove presentation metadata at transport boundaries, including inner literals. */\nexport function stripSetFilter(term: WhereTerm): WhereTerm {\n const strip = ({ setFilter: _metadata, ...clause }: ReturnType<typeof predicatesOf>[number]) => clause;\n return isOrGroup(term) ? { any: term.any.map(strip) } : strip(term);\n}\n\n/** Only collapse explicitly marked, intact editor output. Never infer from predicates. */\nexport function readSetFilter(where: WhereTerm[], index: number): { field: string; metadata: SetFilterMetadata; count: number; target: SetFilterTarget } | null {\n const term = where[index];\n const metadata = term?.setFilter;\n if (!term || !metadata || where[index - 1]?.setFilter?.id === metadata.id) return null;\n const field = predicatesOf(term)[0]?.field;\n if (!field) return null;\n // The compiled operator distinguishes the two shapes; the exact comparison\n // below still rejects anything the compiler would not have produced.\n const target: SetFilterTarget = predicatesOf(term).some((clause) => clause.op === \"includes\") || !setFilterModes(\"scalar\").includes(metadata.mode) ? \"array\" : \"scalar\";\n const expected = createSetFilter(field, metadata.mode, metadata.values, metadata.id, target);\n if (expected.length === 0) return null;\n for (let offset = 0; offset < expected.length; offset++) {\n const actual = where[index + offset];\n if (!actual || JSON.stringify(actual.setFilter) !== JSON.stringify(expected[offset]!.setFilter) || JSON.stringify(stripSetFilter(actual)) !== JSON.stringify(stripSetFilter(expected[offset]!))) return null;\n }\n if (where[index + expected.length]?.setFilter?.id === metadata.id) return null;\n return { field, metadata, count: expected.length, target };\n}\n\n/** Canonicalize consumer-owned value aliases without disconnecting editor metadata. */\nexport function mapSetFilterValues(where: WhereTerm[], canonicalize: (field: string, value: string) => string): WhereTerm[] {\n const result: WhereTerm[] = [];\n for (let index = 0; index < where.length; index++) {\n const set = readSetFilter(where, index);\n if (!set) { result.push(where[index]!); continue; }\n result.push(...createSetFilter(set.field, set.metadata.mode, set.metadata.values.map((value) => canonicalize(set.field, value)), set.metadata.id, set.target));\n index += set.count - 1;\n }\n return result;\n}\n","import { decodeQueryStrict, encodeQuery } from \"./encode\";\nimport { MAX_QUERY_TOKEN_LENGTH, type QueryState } from \"./query\";\n\nexport interface QuerySnapshot {\n version: 1;\n code: string;\n token: string;\n createdAt: number;\n}\n/** The host owns authenticated, durable storage. Save is immutable/idempotent\n * by code: an existing code may never be assigned a different token. */\nexport interface QuerySnapshotStore {\n save(key: string, snapshot: QuerySnapshot, signal?: AbortSignal): Promise<QuerySnapshot>;\n resolve(key: string, code: string, signal?: AbortSignal): Promise<QuerySnapshot | null>;\n}\nexport interface QuerySnapshotCache {\n get(key: string, code: string): QuerySnapshot | null;\n find(key: string, token: string): QuerySnapshot | null;\n put(key: string, snapshot: QuerySnapshot): void;\n isDurable?(key: string, code: string): boolean;\n markDurable?(key: string, code: string): void;\n}\nexport interface QueryLink {\n url: string;\n kind: \"inline\" | \"local\" | \"durable\";\n bytes: number;\n snapshotCode?: string;\n}\nexport interface QueryLinkOptions {\n /** Complete URL budget, including host parameters and fragment. Default 2000. */\n maxUrlBytes?: number;\n cache?: QuerySnapshotCache;\n}\nconst codePattern = /^[A-Za-z0-9_-]{22}$/;\nexport function validateQuerySnapshot(input: unknown): QuerySnapshot {\n const s = input as QuerySnapshot;\n if (!s || s.version !== 1 || !codePattern.test(s.code) || typeof s.token !== \"string\" ||\n s.token.length > MAX_QUERY_TOKEN_LENGTH || !Number.isFinite(s.createdAt)) throw Error(\"Invalid query snapshot.\");\n decodeQueryStrict(s.token);\n return { version: 1, code: s.code, token: s.token, createdAt: s.createdAt };\n}\nfunction newSnapshot(token: string): QuerySnapshot {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return { version: 1, code: btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\"), token, createdAt: Date.now() };\n}\n\n/** FIFO entries are scoped by dataset. One bounded envelope makes each write\n * atomic; the new entry is protected from eviction and stored before URL use.\n * Browser profiles, origins, and devices do not share these entries. */\nexport function localQuerySnapshotCache(options: {\n storage?: Pick<Storage, \"getItem\" | \"setItem\">;\n storageKey?: string;\n maxEntries?: number;\n maxBytes?: number;\n} = {}): QuerySnapshotCache {\n const storageKey = options.storageKey ?? \"query-table:link-cache:v1\";\n const maxEntries = options.maxEntries ?? 100;\n const maxBytes = options.maxBytes ?? 2 * 1024 * 1024;\n if (!Number.isInteger(maxEntries) || maxEntries < 1 || !Number.isFinite(maxBytes) || maxBytes < 1) throw Error(\"Invalid query link cache limits.\");\n type Entry = { key: string; snapshot: QuerySnapshot; durable?: boolean };\n const storage = () => options.storage ?? globalThis.localStorage;\n function read(): Entry[] {\n const text = storage().getItem(storageKey);\n if (!text) return [];\n let raw: unknown;\n try { raw = JSON.parse(text); } catch { return []; }\n if (!Array.isArray(raw)) return [];\n const entries: Entry[] = raw.filter(e => e && typeof e.key === \"string\" && e.snapshot &&\n e.snapshot.version === 1 && codePattern.test(e.snapshot.code) && typeof e.snapshot.token === \"string\" &&\n e.snapshot.token.length <= MAX_QUERY_TOKEN_LENGTH && Number.isFinite(e.snapshot.createdAt)).slice(-maxEntries);\n // A lowered host limit trims the oldest entries instead of poisoning the\n // cache. The next successful write replaces malformed/outdated envelopes.\n while (entries.length && JSON.stringify(entries).length * 2 > maxBytes) entries.shift();\n return entries;\n }\n return {\n isDurable(key, code) { return read().some(e => e.key === key && e.snapshot.code === code && e.durable); },\n markDurable(key, code) {\n const entries = read(); const entry = entries.find(e => e.key === key && e.snapshot.code === code);\n if (entry) {\n entry.durable = true;\n let text = JSON.stringify(entries);\n while (text.length * 2 > maxBytes && entries.length > 1) {\n entries.splice(entries[0] === entry ? 1 : 0, 1); text = JSON.stringify(entries);\n }\n if (text.length * 2 <= maxBytes) storage().setItem(storageKey, text);\n }\n },\n get(key, code) { return read().find(e => e.key === key && e.snapshot.code === code)?.snapshot ?? null; },\n find(key, token) { return read().find(e => e.key === key && e.snapshot.token === token)?.snapshot ?? null; },\n put(key, snapshot) {\n const entries = read();\n const old = entries.find(e => e.key === key && e.snapshot.code === snapshot.code);\n if (old) {\n if (old.snapshot.token !== snapshot.token) throw Error(\"A query link code cannot be overwritten.\");\n const text = JSON.stringify(entries);\n if (storage().getItem(storageKey) !== text) storage().setItem(storageKey, text);\n return;\n }\n entries.push({ key, snapshot: validateQuerySnapshot(snapshot) });\n while (entries.length > maxEntries) entries.shift();\n let text = JSON.stringify(entries);\n // Web Storage stores UTF-16 strings; charge both bytes of each code unit.\n while (text.length * 2 > maxBytes && entries.length > 1) { entries.shift(); text = JSON.stringify(entries); }\n if (text.length * 2 > maxBytes) throw Error(\"This query is too large for the local link cache.\");\n storage().setItem(storageKey, text); // Throws on quota/access failure; caller keeps the previous URL.\n },\n };\n}\n\nexport function memoryQuerySnapshotCache(): QuerySnapshotCache {\n let text: string | null = null;\n return localQuerySnapshotCache({ storage: { getItem: () => text, setItem: (_key, value) => { text = value; } } });\n}\n\nexport type QuerySnapshotHttpErrorCode = \"quota\" | \"forbidden\" | \"conflict\" | \"unavailable\" | \"storage\" | \"http\";\n\n/** HTTP failures retain structured information for host error formatting. The\n * message is plain text suitable for displaying in the Save/Share UI. */\nexport class QuerySnapshotHttpError extends Error {\n readonly name = \"QuerySnapshotHttpError\";\n constructor(\n readonly status: number,\n readonly code: QuerySnapshotHttpErrorCode,\n message: string,\n readonly detail?: string,\n readonly serverCode?: string,\n ) { super(message); }\n}\n\nasync function snapshotHttpError(response: Response): Promise<QuerySnapshotHttpError> {\n // Error endpoints may return plain text (including Go's http.Error), JSON,\n // HTML proxy pages, or arbitrarily large bodies. Read at most 4 KiB and never\n // turn an infrastructure response or HTML into a browser-facing message.\n let detail: string | undefined;\n let serverCode: string | undefined;\n const type = response.headers.get(\"content-type\")?.split(\";\")[0]?.trim().toLowerCase();\n if (response.body && (type === \"text/plain\" || type === \"application/json\")) {\n const reader = response.body.getReader();\n try {\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n while (size <= 4096) {\n const next = await reader.read();\n if (next.done) { complete = true; break; }\n size += next.value.byteLength;\n if (size <= 4096) chunks.push(next.value);\n }\n if (complete) {\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n const text = new TextDecoder().decode(bytes);\n let reason: unknown = text;\n if (type === \"application/json\") {\n const body = JSON.parse(text);\n reason = body?.message ?? body?.error?.message ?? body?.error;\n const code = body?.code ?? body?.error?.code;\n if (typeof code === \"string\" && /^[A-Za-z0-9_.-]{1,64}$/.test(code)) serverCode = code;\n }\n if (typeof reason === \"string\" && !/[<>]/.test(reason)) {\n const safe = reason.replace(/[\\u0000-\\u001f\\u007f]/g, \" \").trim();\n if (safe) detail = safe.slice(0, 512);\n }\n }\n } catch { /* An unreadable error body must not hide the HTTP failure. */ }\n finally {\n try { await reader.cancel(); } catch { /* Already closed or disconnected. */ }\n reader.releaseLock();\n }\n }\n const status = response.status;\n const code: QuerySnapshotHttpErrorCode = status === 507 ? \"quota\" : status === 401 || status === 403 ? \"forbidden\"\n : status === 409 ? \"conflict\" : status === 404 ? \"unavailable\" : status >= 500 ? \"storage\" : \"http\";\n const messages: Record<QuerySnapshotHttpErrorCode, string> = {\n quota: \"Query snapshot storage is full. Ask your host to increase its quota, then retry saving. Existing links still work.\",\n forbidden: \"You do not have permission to save or open this query link. Sign in or ask your host for access.\",\n conflict: \"This query link code already identifies different state. Ask your host to check its snapshot store.\",\n unavailable: \"This query link is unavailable. Check its address or ask its author for a new link.\",\n storage: \"Query snapshot storage is temporarily unavailable. Retry later; your previous saved query is unchanged.\",\n http: `Query snapshot request failed (${status}). Check the request or retry later.`,\n };\n const message = messages[code] + (code !== \"http\" ? ` (HTTP ${status})` : \"\")\n + (detail && (status < 500 || status === 507) ? ` ${detail}` : \"\");\n return new QuerySnapshotHttpError(status, code, message, detail, serverCode);\n}\n\nexport function httpQuerySnapshotStore(base: string, fetcher: typeof fetch = fetch): QuerySnapshotStore {\n const url = (key: string, code: string) => `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(key)}&code=${encodeURIComponent(code)}`;\n async function responseSnapshot(response: Response): Promise<QuerySnapshot> {\n if (!response.ok) throw await snapshotHttpError(response);\n return validateQuerySnapshot(await response.json());\n }\n return {\n async save(key, snapshot, signal) {\n const result = await responseSnapshot(await fetcher(url(key, snapshot.code), {\n method: \"PUT\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(snapshot), ...(signal ? { signal } : {}),\n }));\n if (result.code !== snapshot.code || result.token !== snapshot.token) throw Error(\"The snapshot store changed this immutable query link.\");\n return result;\n },\n async resolve(key, code, signal) {\n const response = await fetcher(url(key, code), signal ? { signal } : {});\n if (response.status === 404) return null;\n const result = await responseSnapshot(response);\n if (result.code !== code) throw Error(\"The snapshot store returned a different query link.\");\n return result;\n },\n };\n}\n\nexport interface QueryLinkService {\n local(query: QueryState, baseUrl: string, parameter?: string): QueryLink;\n durable(query: QueryState, baseUrl: string, parameter?: string): Promise<QueryLink>;\n snapshot(query: QueryState): Promise<QuerySnapshot | null>;\n resolve(url: string, parameter?: string, signal?: AbortSignal): Promise<QueryState | null>;\n}\n\n/** Local URL synchronization never writes to the server. Only explicit\n * snapshot/durable calls (Save/Share/Bookmark) promote state to the host store. */\nexport function createQueryLinkService(key: string, store?: QuerySnapshotStore, options: QueryLinkOptions = {}): QueryLinkService {\n const budget = options.maxUrlBytes ?? 2000;\n if (!Number.isInteger(budget) || budget < 1) throw Error(\"Invalid query URL budget.\");\n const cache = options.cache ?? localQuerySnapshotCache();\n const promoted = new Map<string, Promise<QuerySnapshot>>();\n const attempts = new Map<string, QuerySnapshot>();\n const known = new Map<string, QuerySnapshot>();\n function remember(snapshot: QuerySnapshot) {\n known.set(snapshot.code, snapshot);\n while (known.size > 100) known.delete(known.keys().next().value!);\n try { cache.put(key, snapshot); cache.markDurable?.(key, snapshot.code); } catch { /* Durable link does not require a cache. */ }\n }\n function link(base: string, parameter: string, value: string, kind: QueryLink[\"kind\"]): QueryLink {\n const url = new URL(base);\n url.searchParams.set(parameter, value);\n const bytes = new TextEncoder().encode(url.toString()).length;\n if (bytes > budget) throw Error(\"The query link exceeds the URL budget, including the page address.\");\n return { url: url.toString(), kind, bytes, ...(kind !== \"inline\" ? { snapshotCode: value.slice(1) } : {}) };\n }\n function cached(token: string): QuerySnapshot | null {\n try { return cache.find(key, token); } catch { return null; }\n }\n async function snapshot(query: QueryState): Promise<QuerySnapshot | null> {\n if (!store) return null;\n const token = encodeQuery(query);\n const existing = promoted.get(token);\n if (existing) return existing;\n const local = attempts.get(token) ?? cached(token) ?? newSnapshot(token);\n attempts.set(token, local);\n while (attempts.size > 100) attempts.delete(attempts.keys().next().value!);\n // Also retain the code after failed/uncertain writes, so retries are idempotent.\n try { cache.put(key, local); } catch { /* A durable store works without browser storage. */ }\n const pending = store.save(key, local).then(result => {\n const valid = validateQuerySnapshot(result);\n if (valid.code !== local.code || valid.token !== token) throw Error(\"The snapshot store changed this immutable query link.\");\n remember(valid);\n return valid;\n });\n promoted.set(token, pending);\n while (promoted.size > 100) promoted.delete(promoted.keys().next().value!);\n try { return await pending; } catch (error) { promoted.delete(token); throw error; }\n }\n return {\n local(query, baseUrl, parameter = \"q\") {\n const token = encodeQuery(query);\n const current = new URL(baseUrl).searchParams.get(parameter);\n if (current?.startsWith(\"@\") && known.get(current.slice(1))?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n if (current?.startsWith(\"@\")) {\n try {\n const code = current.slice(1);\n if (cache.isDurable?.(key, code) && cache.get(key, code)?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n } catch { /* Try ordinary inline/local materialization next. */ }\n }\n const url = new URL(baseUrl); url.searchParams.set(parameter, token);\n if (new TextEncoder().encode(url.toString()).length <= budget) return link(baseUrl, parameter, token, \"inline\");\n const local = cached(token) ?? newSnapshot(token);\n const result = link(baseUrl, parameter, \"@\" + local.code, \"local\");\n cache.put(key, local);\n return result;\n },\n async durable(query, baseUrl, parameter = \"q\") {\n const saved = await snapshot(query);\n if (saved) return link(baseUrl, parameter, \"@\" + saved.code, \"durable\");\n const token = encodeQuery(query);\n // Small inline links are portable without a server; never share a local-only code.\n return link(baseUrl, parameter, token, \"inline\");\n },\n snapshot,\n async resolve(baseUrl, parameter = \"q\", signal) {\n const values = new URL(baseUrl).searchParams.getAll(parameter);\n if (!values.length || (values.length === 1 && values[0] === \"\")) return null;\n if (values.length !== 1) throw Error(\"Invalid or conflicting query link parameters.\");\n const value = values[0]!;\n if (!value.startsWith(\"@\")) return decodeQueryStrict(value);\n const code = value.slice(1);\n if (!codePattern.test(code)) throw Error(\"Invalid query link code.\");\n let local: QuerySnapshot | null = null;\n try { local = cache.get(key, code); if (local) local = validateQuerySnapshot(local); } catch { local = null; }\n const result = local ?? (store ? await store.resolve(key, code, signal) : null);\n if (!result) throw Error(\"This query link is unavailable. Its local cache entry may have expired; use a saved or shared link for permanent access.\");\n const valid = validateQuerySnapshot(result);\n if (valid.code !== code) throw Error(\"Invalid query snapshot code.\");\n if (!local) remember(valid);\n else { try { if (cache.isDurable?.(key, code)) remember(valid); } catch { /* Cache metadata is optional. */ } }\n return decodeQueryStrict(valid.token);\n },\n };\n}\n","import type { FormulaResult, FormulaValue } from \"./formula\";\n\n/** Reserved field token namespace. Query state stores IDs, never formula source. */\nexport const COMPUTED_PREFIX = \"@computed/\";\nexport const computedFieldName = (id: string): string => COMPUTED_PREFIX + id;\nexport const isComputedField = (name: string): boolean =>\n name.trim().toLowerCase().startsWith(COMPUTED_PREFIX);\nexport interface ComputedColumn {\n id: string;\n label: string;\n expression: { language: \"qt-expr\"; version: 1; source: string };\n /** Optimistic concurrency token issued by the store. */\n revision: string;\n}\nexport type ComputedColumnDraft = Omit<ComputedColumn, \"revision\">;\nexport interface ComputedColumnStore {\n /** Return the complete authorized catalogue for this dataset. */\n list(dataset: string, signal?: AbortSignal): Promise<ComputedColumn[]>;\n /** null creates a new ID; updates must match the current revision. */\n save(\n dataset: string,\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ): Promise<ComputedColumn>;\n /** Optional push invalidation, including changes from other sessions. */\n subscribe?(dataset: string, listener: () => void): () => void;\n}\nexport function validateComputedColumn(input: unknown): ComputedColumn {\n const c = input as ComputedColumn;\n if (\n !c ||\n typeof c.id !== \"string\" ||\n !/^[a-zA-Z0-9_-]{1,128}$/.test(c.id) ||\n typeof c.label !== \"string\" ||\n !c.label.trim() ||\n c.label.length > 200 ||\n typeof c.revision !== \"string\" ||\n !c.revision ||\n c.revision.length > 256 ||\n c.expression?.language !== \"qt-expr\" ||\n c.expression.version !== 1 ||\n typeof c.expression.source !== \"string\" ||\n !c.expression.source.trim() ||\n c.expression.source.length > 10000\n ) {\n throw new Error(\n \"Invalid computed column definition or unsupported formula version.\",\n );\n }\n return {\n id: c.id,\n label: c.label,\n revision: c.revision,\n expression: { ...c.expression },\n };\n}\nexport function memoryComputedColumnStore(\n seed: Record<string, ComputedColumn[]> = {},\n): ComputedColumnStore {\n const data = new Map(\n Object.entries(seed).map(([k, v]) => [\n k,\n new Map(v.map((c) => [c.id, validateComputedColumn(c)])),\n ]),\n );\n // Revisions are opaque: never derive a new token by parsing an existing one.\n // Reserve all seed tokens so even a seed from this namespace cannot recur.\n const seedRevisions = new Set(\n [...data.values()].flatMap((entries) =>\n [...entries.values()].map((c) => c.revision),\n ),\n );\n let revisionSequence = 0n;\n function freshRevision(): string {\n let revision: string;\n do {\n revision = `memory:${++revisionSequence}`;\n } while (seedRevisions.has(revision));\n return revision;\n }\n const listeners = new Map<string, Set<() => void>>();\n return {\n async list(dataset) {\n return [...(data.get(dataset)?.values() ?? [])].map(\n validateComputedColumn,\n );\n },\n async save(dataset, column, expectedRevision) {\n const entries = data.get(dataset) ?? new Map<string, ComputedColumn>();\n const current = entries.get(column.id);\n if ((current?.revision ?? null) !== expectedRevision)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n const next = validateComputedColumn({\n ...column,\n revision: freshRevision(),\n });\n entries.set(next.id, next);\n data.set(dataset, entries);\n listeners.get(dataset)?.forEach((fn) => fn());\n return validateComputedColumn(next);\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\n\n/** REST adapter. The implementing server owns authorization and DB persistence.\n * GET base?dataset=… → ComputedColumn[]\n * PUT base?dataset=… → {column, expectedRevision} → ComputedColumn\n * Return HTTP 409 for a stale revision. No formula evaluation happens there. */\nexport function httpComputedColumnStore(\n base: string,\n fetcher: typeof fetch = fetch,\n): ComputedColumnStore {\n const listeners = new Map<string, Set<() => void>>();\n const url = (dataset: string) =>\n `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(dataset)}`;\n async function read(response: Response): Promise<unknown> {\n if (response.status === 409)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n if (!response.ok)\n throw new Error(\n `Computed column store request failed (${response.status}).`,\n );\n return response.json();\n }\n return {\n async list(dataset, signal) {\n const raw = await read(\n await fetcher(url(dataset), { ...(signal ? { signal } : {}) }),\n );\n if (!Array.isArray(raw))\n throw new Error(\"Invalid computed column catalogue.\");\n return raw.map(validateComputedColumn);\n },\n async save(dataset, column, expectedRevision) {\n const result = validateComputedColumn(\n await read(\n await fetcher(url(dataset), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ column, expectedRevision }),\n }),\n ),\n );\n listeners.get(dataset)?.forEach((fn) => fn());\n return result;\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\nexport interface ComputedCellError {\n computedError: string;\n}\nexport function isComputedCellError(\n value: unknown,\n): value is ComputedCellError {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"computedError\" in value &&\n typeof (value as ComputedCellError).computedError === \"string\"\n );\n}\nexport interface PreviewGroup {\n inputs: FormulaValue[];\n result: FormulaResult;\n count: number;\n}\nexport interface ColumnPreview {\n dependencies: string[];\n groups: PreviewGroup[];\n processed: number;\n total: number;\n nulls: number;\n errors: number;\n}\nexport function groupPreview(\n dependencies: string[],\n inputs: Record<string, FormulaValue>[],\n results: FormulaResult[],\n total: number,\n): ColumnPreview {\n const groups = new Map<string, PreviewGroup>();\n let nulls = 0,\n errors = 0;\n inputs.forEach((row, i) => {\n const values = dependencies.map((name) => row[name] ?? null),\n result = results[i] ?? { value: null, error: \"No result.\" };\n const key = JSON.stringify([values, result.value, result.error ?? null]);\n const group = groups.get(key);\n if (group) group.count++;\n else groups.set(key, { inputs: values, result, count: 1 });\n if (result.error) errors++;\n else if (result.value === null) nulls++;\n });\n return {\n dependencies,\n groups: [...groups.values()].sort((a, b) => b.count - a.count),\n processed: inputs.length,\n total,\n nulls,\n errors,\n };\n}\n\n/** Server-issued capabilities are hints for client planning, never authorization. */\nexport interface ComputedFieldCapabilities {\n\n /** Host-approved canonical predicates; omitted retains the closed default. */\n filter?: boolean;\n type: import('./schema').FieldType;\n select: boolean;\n sort: boolean;\n measure: boolean;\n group: boolean;\n reason?: string;\n}\nexport interface ComputedExecution {\n profile: string;\n planToken: string;\n resolvedRevisions: Record<string,string>;\n fields: Record<string,ComputedFieldCapabilities>;\n fingerprint?: string;\n snapshot?: string;\n}\nexport type RowComputedValues = Record<string,{value: import('./metricTypes').MetricValue; error?: {code:string}}>;\n","import type { FieldType } from \"./schema\";\n\nexport type FormulaType = Exclude<FieldType, \"enum\"> | \"null\";\nexport type FormulaValue = string | number | boolean | string[] | null;\nexport interface FormulaDiagnostic {\n message: string;\n from: number;\n to: number;\n}\nexport type FormulaNode =\n | { kind: \"literal\"; value: FormulaValue; from: number; to: number }\n | {\n kind: \"field\";\n name: string;\n valueType?: FormulaType;\n from: number;\n to: number;\n }\n | {\n kind: \"call\";\n name: string;\n args: FormulaNode[];\n from: number;\n to: number;\n };\nexport interface FormulaPlan {\n ast: FormulaNode;\n dependencies: string[];\n type: FormulaType;\n}\nexport interface RegexInspection {\n input: string;\n start: number;\n end: number;\n groups: (string | null)[];\n}\nexport interface FormulaResult {\n value: FormulaValue;\n error?: string;\n regex?: RegexInspection;\n}\nexport interface FormulaFunction {\n name: string;\n signature: string;\n description: string;\n min: number;\n max: number;\n result: FormulaType | \"branch\";\n args: FormulaType[] | \"any\";\n}\n\nconst f = (\n name: string,\n signature: string,\n description: string,\n min: number,\n max: number,\n result: FormulaFunction[\"result\"],\n args: FormulaFunction[\"args\"],\n): FormulaFunction => ({\n name,\n signature,\n description,\n min,\n max,\n result,\n args,\n});\nexport const FORMULA_FUNCTIONS: FormulaFunction[] = [\n ...[\"LEFT\", \"RIGHT\"].map((n) =>\n f(\n n,\n `${n}(text, count)`,\n \"Take Unicode code points from the end indicated.\",\n 2,\n 2,\n \"text\",\n [\"text\", \"number\"],\n ),\n ),\n f(\n \"SUBSTRING\",\n \"SUBSTRING(text, start, length)\",\n \"One-based start; length is optional.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"number\"],\n ),\n f(\"LENGTH\", \"LENGTH(text)\", \"Count Unicode code points.\", 1, 1, \"number\", [\n \"text\",\n ]),\n f(\n \"URL_ENCODE\",\n \"URL_ENCODE(text)\",\n \"Percent-encode UTF-8 text for a URL. Only letters, digits and - . _ ~ are kept.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ...[\"LOWER\", \"UPPER\", \"TRIM\", \"LTRIM\", \"RTRIM\"].map((n) =>\n f(\n n,\n `${n}(text)`,\n \"Change case or remove surrounding whitespace.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ),\n f(\n \"REPLACE\",\n \"REPLACE(text, search, replacement)\",\n \"Replace all literal occurrences.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"text\"],\n ),\n ...[\"LPAD\", \"RPAD\"].map((n) =>\n f(\n n,\n `${n}(text, length, padding)`,\n \"Pad to a code-point length; default padding is a space.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"text\"],\n ),\n ),\n f(\n \"SPLIT_PART\",\n \"SPLIT_PART(text, separator, index)\",\n \"One-based part; missing part returns null.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"number\"],\n ),\n f(\n \"CONCAT\",\n \"CONCAT(text, ...)\",\n \"Combine text; null propagates.\",\n 1,\n 50,\n \"text\",\n [\"text\"],\n ),\n f(\n \"CONCAT_WS\",\n \"CONCAT_WS(separator, text, ...)\",\n \"Combine text, skipping null arguments.\",\n 2,\n 50,\n \"text\",\n [\"text\"],\n ),\n ...[\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].map((n) =>\n f(\n n,\n `${n}(text, search, ignoreCase)`,\n \"Case-sensitive unless the optional third argument is true.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"bool\"],\n ),\n ),\n f(\n \"REGEX_TEST\",\n \"REGEX_TEST(text, pattern, flags)\",\n \"Test a JavaScript Unicode regex; flags: i, m, s.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"text\"],\n ),\n f(\n \"REGEX_EXTRACT\",\n \"REGEX_EXTRACT(text, pattern, group, flags)\",\n \"Extract a capture (default 0: whole match); no match returns null.\",\n 2,\n 4,\n \"text\",\n [\"text\", \"text\", \"number\", \"text\"],\n ),\n f(\n \"REGEX_REPLACE\",\n \"REGEX_REPLACE(text, pattern, replacement, flags)\",\n \"Replace all matches; supports $1 capture references.\",\n 3,\n 4,\n \"text\",\n [\"text\", \"text\", \"text\", \"text\"],\n ),\n ...[\"ABS\", \"FLOOR\", \"CEIL\", \"TRUNC\", \"SQRT\"].map((n) =>\n f(n, `${n}(number)`, \"Numeric transformation.\", 1, 1, \"number\", [\"number\"]),\n ),\n f(\n \"ROUND\",\n \"ROUND(number, digits)\",\n \"Round to decimal places (default 0, range -15 to 15).\",\n 1,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"POWER\",\n \"POWER(base, exponent)\",\n \"Raise a number to a power.\",\n 2,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"CLAMP\",\n \"CLAMP(number, lower, upper)\",\n \"Constrain a number to an inclusive range.\",\n 3,\n 3,\n \"number\",\n [\"number\"],\n ),\n ...[\"LEAST\", \"GREATEST\"].map((n) =>\n f(\n n,\n `${n}(number, ...)`,\n \"Compare numbers within this row.\",\n 1,\n 50,\n \"number\",\n [\"number\"],\n ),\n ),\n f(\n \"IF\",\n \"IF(condition, then, otherwise)\",\n \"Evaluate only the chosen branch; null condition uses otherwise.\",\n 3,\n 3,\n \"branch\",\n \"any\",\n ),\n f(\n \"IFS\",\n \"IFS(condition, value, ..., fallback)\",\n \"First true condition wins; final fallback is required.\",\n 3,\n 49,\n \"branch\",\n \"any\",\n ),\n f(\n \"SWITCH\",\n \"SWITCH(value, match, result, ..., fallback)\",\n \"Match a value to a result; final fallback is required.\",\n 4,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"COALESCE\",\n \"COALESCE(value, ...)\",\n \"First non-null value, evaluated lazily.\",\n 1,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"NULLIF\",\n \"NULLIF(value, other)\",\n \"Return null if the values are equal.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...[\"IS_NULL\", \"IS_EMPTY\"].map((n) =>\n f(\n n,\n `${n}(value)`,\n \"Test null, or null/empty text/empty array.\",\n 1,\n 1,\n \"bool\",\n \"any\",\n ),\n ),\n f(\n \"IFERROR\",\n \"IFERROR(value, fallback)\",\n \"Use fallback only when evaluating value fails.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...(\n [\n [\"TO_TEXT\", \"text\"],\n [\"TO_NUMBER\", \"number\"],\n [\"TO_BOOLEAN\", \"bool\"],\n [\"TO_DATETIME\", \"datetime\"],\n ] as const\n ).map(([n, t]) =>\n f(\n n,\n `${n}(value)`,\n \"Explicit conversion; invalid input produces a cell error.\",\n 1,\n 1,\n t,\n \"any\",\n ),\n ),\n f(\n \"SPLIT\",\n \"SPLIT(text, separator)\",\n \"Split text into an array.\",\n 2,\n 2,\n \"textarray\",\n [\"text\", \"text\"],\n ),\n f(\"JOIN\", \"JOIN(array, separator)\", \"Join an array of text.\", 2, 2, \"text\", [\n \"textarray\",\n \"text\",\n ]),\n f(\n \"ARRAY_LENGTH\",\n \"ARRAY_LENGTH(array)\",\n \"Count array elements.\",\n 1,\n 1,\n \"number\",\n [\"textarray\"],\n ),\n f(\n \"ARRAY_CONTAINS\",\n \"ARRAY_CONTAINS(array, text)\",\n \"Case-sensitive array membership.\",\n 2,\n 2,\n \"bool\",\n [\"textarray\", \"text\"],\n ),\n f(\n \"ARRAY_GET\",\n \"ARRAY_GET(array, index)\",\n \"One-based element; out of range returns null.\",\n 2,\n 2,\n \"text\",\n [\"textarray\", \"number\"],\n ),\n ...[\"ARRAY_UNIQUE\", \"ARRAY_SORT\"].map((n) =>\n f(\n n,\n `${n}(array)`,\n \"Deduplicate or sort text elements by code-point order.\",\n 1,\n 1,\n \"textarray\",\n [\"textarray\"],\n ),\n ),\n ...[\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\", \"WEEKDAY\"].map((n) =>\n f(\n n,\n `${n}(datetime)`,\n \"UTC date component; weekday is Monday=1 through Sunday=7.\",\n 1,\n 1,\n \"number\",\n [\"datetime\"],\n ),\n ),\n f(\n \"DATE_TRUNC\",\n \"DATE_TRUNC(unit, datetime)\",\n \"UTC truncation: year, month, week (Monday), day, hour, minute, second.\",\n 2,\n 2,\n \"datetime\",\n [\"text\", \"datetime\"],\n ),\n f(\n \"DATE_ADD\",\n \"DATE_ADD(unit, amount, datetime)\",\n \"UTC calendar addition; month/year clamp to the last day.\",\n 3,\n 3,\n \"datetime\",\n [\"text\", \"number\", \"datetime\"],\n ),\n f(\n \"DATE_DIFF\",\n \"DATE_DIFF(unit, start, end)\",\n \"Elapsed whole units: week, day, hour, minute, second, millisecond.\",\n 3,\n 3,\n \"number\",\n [\"text\", \"datetime\", \"datetime\"],\n ),\n f(\n \"FORMAT_DATE\",\n \"FORMAT_DATE(datetime, pattern)\",\n \"UTC tokens: YYYY MM DD HH mm ss; other text is literal.\",\n 2,\n 2,\n \"text\",\n [\"datetime\", \"text\"],\n ),\n];\n\nexport class FormulaError extends Error {\n constructor(\n message: string,\n public from = 0,\n public to = from + 1,\n ) {\n super(message);\n }\n}\ninterface Token {\n text: string;\n kind: \"field\" | \"string\" | \"number\" | \"word\" | \"op\" | \"end\";\n from: number;\n to: number;\n}\nexport function compileFormula(\n source: string,\n fields: readonly { name: string; type: FieldType }[],\n resolve?: (name: string) => FormulaPlan | undefined,\n extension?: (node: FormulaNode, check: (node: FormulaNode) => FormulaType) => FormulaType | undefined,\n): FormulaPlan {\n if (!source.trim() || source.length > 10000)\n throw new FormulaError(\"Formula must contain 1–10,000 characters.\");\n const tokens: Token[] = [];\n let pos = 0;\n while (pos < source.length) {\n if (/\\s/.test(source[pos]!)) {\n pos++;\n continue;\n }\n const from = pos;\n let match: RegExpMatchArray | null;\n if (source[pos] === \"[\") {\n pos++;\n let text = \"\";\n let closed = false;\n while (pos < source.length) {\n if (source[pos] === \"]\") {\n if (source[pos + 1] === \"]\") {\n text += \"]\";\n pos += 2;\n } else {\n pos++;\n closed = true;\n break;\n }\n } else text += source[pos++];\n }\n if (!closed)\n throw new FormulaError(\"Unclosed field reference.\", from, pos);\n tokens.push({ kind: \"field\", text, from, to: pos });\n } else if (source[pos] === '\"') {\n pos++;\n while (pos < source.length && source[pos] !== '\"') {\n if (source[pos] === \"\\\\\") pos++;\n pos++;\n }\n pos++;\n try {\n tokens.push({\n kind: \"string\",\n text: JSON.parse(source.slice(from, pos)),\n from,\n to: pos,\n });\n } catch {\n throw new FormulaError(\"Invalid JSON string literal.\", from, pos);\n }\n } else if (source[pos] === \"'\") {\n // A common habit from SQL and spreadsheets; say what to write instead.\n const end = source.indexOf(\"'\", pos + 1);\n const text = end < 0 ? \"\" : source.slice(pos + 1, end);\n throw new FormulaError(\n end < 0 || text.length > 40 || /[\"\\\\\\n]/.test(text)\n ? 'Text literals use double quotes (\"text\"), not single quotes.'\n : `Text literals use double quotes: write \"${text}\" instead of '${text}'.`,\n from,\n end < 0 ? pos + 1 : end + 1,\n );\n } else if (\n (match = source\n .slice(pos)\n .match(/^(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"number\", text: match[0], from, to: pos });\n } else if ((match = source.slice(pos).match(/^[a-zA-Z_][a-zA-Z_0-9]*/))) {\n pos += match[0].length;\n tokens.push({\n kind: \"word\",\n text: match[0].toUpperCase(),\n from,\n to: pos,\n });\n } else if (\n (match = source.slice(pos).match(/^(>=|<=|!=|<>|[=<>+*/%(),-])/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"op\", text: match[0], from, to: pos });\n } else throw new FormulaError(`Unexpected character ${source[pos]}.`, from);\n if (tokens.length > 2000)\n throw new FormulaError(\"Formula is too complex.\", from);\n }\n tokens.push({ kind: \"end\", text: \"\", from: pos, to: pos });\n let i = 0,\n depth = 0;\n const peek = () => tokens[i]!;\n const take = () => tokens[i++]!;\n const expect = (s: string) => {\n if (peek().text !== s)\n throw new FormulaError(`Expected ${s}.`, peek().from, peek().to);\n return take();\n };\n const call = (\n name: string,\n args: FormulaNode[],\n from: number,\n to: number,\n ): FormulaNode => ({ kind: \"call\", name, args, from, to });\n const priority: Record<string, number> = {\n OR: 1,\n AND: 2,\n \"=\": 3,\n \"!=\": 3,\n \"<>\": 3,\n \"<\": 3,\n \">\": 3,\n \"<=\": 3,\n \">=\": 3,\n IN: 3,\n BETWEEN: 3,\n \"+\": 4,\n \"-\": 4,\n \"*\": 5,\n \"/\": 5,\n \"%\": 5,\n };\n function expression(min = 0): FormulaNode {\n if (++depth > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", peek().from);\n const t = take();\n let node: FormulaNode;\n if (t.kind === \"number\") {\n if (!Number.isFinite(Number(t.text)))\n throw new FormulaError(\"Number must be finite.\", t.from, t.to);\n node = { kind: \"literal\", value: Number(t.text), from: t.from, to: t.to };\n } else if (t.kind === \"string\")\n node = { kind: \"literal\", value: t.text, from: t.from, to: t.to };\n else if (t.kind === \"field\")\n node = { kind: \"field\", name: t.text, from: t.from, to: t.to };\n else if ([\"TRUE\", \"FALSE\", \"NULL\"].includes(t.text))\n node = {\n kind: \"literal\",\n value: t.text === \"NULL\" ? null : t.text === \"TRUE\",\n from: t.from,\n to: t.to,\n };\n else if (t.text === \"(\") {\n node = expression();\n expect(\")\");\n } else if ([\"NOT\", \"-\", \"+\"].includes(t.text)) {\n const arg = expression(t.text === \"NOT\" ? 3 : 6);\n node = call(`unary:${t.text}`, [arg], t.from, arg.to);\n } else if (t.kind === \"word\") {\n expect(\"(\");\n const args: FormulaNode[] = [];\n if (peek().text !== \")\") {\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n }\n node = call(t.text, args, t.from, expect(\")\").to);\n } else\n throw new FormulaError(\n \"Expected a value, field, or function.\",\n t.from,\n t.to,\n );\n while (peek().kind !== \"end\" && (priority[peek().text] ?? -1) >= min) {\n const op = take();\n const p = priority[op.text]!;\n if (op.text === \"IN\") {\n if (peek().text !== \"(\")\n throw new FormulaError(\n 'IN takes a parenthesized list, e.g. [status] IN (\"a\", \"b\"). To test array membership, use ARRAY_CONTAINS([tags], \"a\").',\n op.from,\n peek().to,\n );\n expect(\"(\");\n const args = [node];\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n node = call(\"op:IN\", args, node.from, expect(\")\").to);\n } else if (op.text === \"BETWEEN\") {\n const lo = expression(p + 1);\n expect(\"AND\");\n const hi = expression(p + 1);\n node = call(\"op:BETWEEN\", [node, lo, hi], node.from, hi.to);\n } else {\n const right = expression(p + 1);\n node = call(`op:${op.text}`, [node, right], node.from, right.to);\n }\n }\n if (peek().text === \"NOT\" && tokens[i + 1]?.text === \"IN\")\n throw new FormulaError(\n 'NOT IN is not supported. Write NOT ([status] IN (\"a\", \"b\")), or combine != comparisons with AND.',\n peek().from,\n tokens[i + 1]!.to,\n );\n depth--;\n return node;\n }\n const ast = expression();\n if (peek().kind !== \"end\")\n throw new FormulaError(\"Unexpected token.\", peek().from, peek().to);\n const deps = new Set<string>();\n const byName = new Map(fields.map((v) => [v.name, v.type]));\n const same = (ts: FormulaType[], n: FormulaNode): FormulaType => {\n const real = [...new Set(ts.filter((t) => t !== \"null\"))];\n if (real.length > 1)\n throw new FormulaError(\n \"Values must have compatible types; use an explicit conversion.\",\n n.from,\n n.to,\n );\n return real[0] ?? \"null\";\n };\n function check(n: FormulaNode, level = 0): FormulaType {\n if (level > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", n.from, n.to);\n if (n.kind === \"literal\")\n return n.value === null\n ? \"null\"\n : typeof n.value === \"boolean\"\n ? \"bool\"\n : typeof n.value === \"number\"\n ? \"number\"\n : \"text\";\n if (n.kind === \"field\") {\n const t = byName.get(n.name);\n if (!t) {\n const nested = resolve?.(n.name);\n if (nested) {\n Object.assign(n, nested.ast);\n nested.dependencies.forEach((d) => deps.add(d));\n return nested.type;\n }\n throw new FormulaError(\n `Unknown or unavailable field: ${n.name}`,\n n.from,\n n.to,\n );\n }\n deps.add(n.name);\n n.valueType = t === \"enum\" ? \"text\" : t;\n return n.valueType;\n }\n const extended = extension?.(n, (arg) => check(arg, level + 1));\n if (extended !== undefined) return extended;\n const ts = n.args.map((a) => check(a, level + 1));\n const need = (index: number, t: FormulaType) => {\n if (ts[index] !== undefined && ts[index] !== \"null\" && ts[index] !== t)\n throw new FormulaError(\n `Expected ${t}, received ${ts[index]}.`,\n n.args[index]!.from,\n n.args[index]!.to,\n );\n };\n if (n.name.startsWith(\"op:\") || n.name.startsWith(\"unary:\")) {\n const op = n.name.split(\":\")[1]!;\n if ([\"AND\", \"OR\", \"NOT\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"bool\"));\n return \"bool\";\n }\n if ([\"+\", \"-\", \"*\", \"/\", \"%\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"number\"));\n return \"number\";\n }\n if (op === \"IN\" && ts.some((t) => t === \"textarray\"))\n throw new FormulaError(\n 'IN compares one value with a list of values. For arrays, use ARRAY_CONTAINS([tags], \"a\"), or OR several ARRAY_CONTAINS calls.',\n n.from,\n n.to,\n );\n same(ts, n);\n return \"bool\";\n }\n const spec = FORMULA_FUNCTIONS.find((v) => v.name === n.name);\n if (!spec)\n throw new FormulaError(`Unknown function: ${n.name}`, n.from, n.to);\n if (ts.length < spec.min || ts.length > spec.max)\n throw new FormulaError(`Use ${spec.signature}.`, n.from, n.to);\n if (spec.args !== \"any\") {\n const args = spec.args;\n ts.forEach((_, j) => need(j, args[Math.min(j, args.length - 1)]!));\n }\n if (n.name === \"IF\") {\n need(0, \"bool\");\n return same(ts.slice(1), n);\n }\n if (n.name === \"IFS\") {\n if (ts.length % 2 !== 1)\n throw new FormulaError(\n \"IFS requires condition/value pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n ts.forEach((t, j) => {\n if (j === ts.length - 1 || j % 2 === 1) branches.push(t);\n else need(j, \"bool\");\n });\n return same(branches, n);\n }\n if (n.name === \"SWITCH\") {\n if (ts.length % 2 !== 0)\n throw new FormulaError(\n \"SWITCH requires match/result pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n for (let j = 1; j < ts.length - 1; j += 2) {\n same([ts[0]!, ts[j]!], n);\n branches.push(ts[j + 1]!);\n }\n branches.push(ts[ts.length - 1]!);\n return same(branches, n);\n }\n if (n.name.startsWith(\"REGEX_\")) {\n const pattern = n.args[1];\n const flags = n.args[n.name === \"REGEX_TEST\" ? 2 : 3];\n if (pattern?.kind === \"literal\" && typeof pattern.value === \"string\") {\n if (pattern.value.length > 2000)\n throw new FormulaError(\n \"Regex pattern exceeds 2,000 characters.\",\n pattern.from,\n pattern.to,\n );\n if (\n !flags ||\n (flags.kind === \"literal\" && typeof flags.value === \"string\")\n ) {\n const value = flags?.value ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(String(value)))\n throw new FormulaError(\n \"Regex flags must be unique i, m, or s.\",\n n.from,\n n.to,\n );\n try {\n new RegExp(pattern.value, `${value}u`);\n } catch {\n throw new FormulaError(\n \"Invalid regex pattern.\",\n pattern.from,\n pattern.to,\n );\n }\n }\n }\n }\n if (spec.result === \"branch\") return same(ts, n);\n return spec.result;\n }\n const type = check(ast);\n return { ast, dependencies: [...deps].sort(), type };\n}\n\n/** Self-contained runtime: serialized into the browser worker, never user code. */\nexport function formulaRuntime(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>,\n extension?: (node: Extract<FormulaNode, { kind: \"call\" }>) => FormulaResult | undefined,\n): FormulaResult {\n const fail = (s: string): never => {\n throw new Error(s);\n };\n const num = (v: FormulaValue): number =>\n typeof v === \"number\" && Number.isFinite(v)\n ? v\n : fail(\"Expected a finite number.\");\n const str = (v: FormulaValue): string =>\n typeof v === \"string\" ? v : fail(\"Expected text.\");\n const arr = (v: FormulaValue): string[] =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\")\n ? v\n : fail(\"Expected a text array.\");\n const integer = (v: FormulaValue, min = 0, max = 100000): number => {\n const n = num(v);\n return Number.isInteger(n) && n >= min && n <= max\n ? n\n : fail(`Expected an integer between ${min} and ${max}.`);\n };\n const equal = (a: FormulaValue, b: FormulaValue) =>\n JSON.stringify(a) === JSON.stringify(b);\n const date = (v: FormulaValue): Date => {\n const s = str(v);\n if (\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n s,\n )\n )\n fail(\"Expected an ISO date or timestamp with timezone.\");\n const d = new Date(s);\n const day = Number(s.slice(8, 10)),\n month = Number(s.slice(5, 7));\n if (\n !Number.isFinite(d.getTime()) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > new Date(Date.UTC(Number(s.slice(0, 4)), month, 0)).getUTCDate()\n )\n fail(\"Invalid date.\");\n return d;\n };\n const bound = (v: FormulaValue): FormulaValue => {\n if (\n v !== null &&\n typeof v !== \"number\" &&\n typeof v !== \"string\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v)\n )\n fail(\"Unsupported input value type.\");\n if (Array.isArray(v) && !v.every((x) => typeof x === \"string\"))\n fail(\"Expected a text array.\");\n if (typeof v === \"number\" && !Number.isFinite(v))\n fail(\"Result is not finite.\");\n if (typeof v === \"string\" && v.length > 100000)\n fail(\"Text result exceeds 100,000 characters.\");\n if (\n Array.isArray(v) &&\n (v.length > 10000 || v.reduce((s, x) => s + x.length, 0) > 100000)\n )\n fail(\"Array result is too large.\");\n return v;\n };\n let inspection: RegexInspection | undefined;\n let budget = 5000;\n function run(n: FormulaNode): FormulaValue {\n if (--budget < 0) fail(\"Formula operation limit exceeded.\");\n if (n.kind === \"literal\") return n.value;\n if (n.kind === \"field\") {\n if (!Object.prototype.hasOwnProperty.call(inputs, n.name)) return null;\n const v = bound(inputs[n.name] ?? null);\n if (v === null) return null;\n if (n.valueType === \"number\") return num(v);\n if (n.valueType === \"bool\" && typeof v !== \"boolean\")\n fail(\"Expected a boolean.\");\n if (n.valueType === \"datetime\") return date(v).toISOString();\n if (n.valueType === \"text\") return str(v);\n if (n.valueType === \"textarray\") return arr(v);\n return v;\n }\n const extended = extension?.(n);\n if (extended) {\n if (extended.error) fail(extended.error);\n return bound(extended.value);\n }\n const name = n.name;\n const args = n.args;\n if (name === \"IF\") return run(run(args[0]!) === true ? args[1]! : args[2]!);\n if (name === \"IFS\") {\n for (let j = 0; j < args.length - 1; j += 2)\n if (run(args[j]!) === true) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"SWITCH\") {\n const v = run(args[0]!);\n for (let j = 1; j < args.length - 1; j += 2)\n if (equal(v, run(args[j]!))) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"COALESCE\") {\n for (const arg of args) {\n const v = run(arg);\n if (v !== null) return v;\n }\n return null;\n }\n if (name === \"IFERROR\") {\n try {\n return run(args[0]!);\n } catch {\n return run(args[1]!);\n }\n }\n if (name === \"op:AND\" || name === \"op:OR\") {\n const a = run(args[0]!);\n if (name === \"op:AND\" && a === false) return false;\n if (name === \"op:OR\" && a === true) return true;\n const b = run(args[1]!);\n return name === \"op:AND\"\n ? b === false\n ? false\n : a === null || b === null\n ? null\n : true\n : b === true\n ? true\n : a === null || b === null\n ? null\n : false;\n }\n const vs = args.map(run);\n const a = vs[0] ?? null,\n b = vs[1] ?? null,\n c = vs[2] ?? null;\n if (name === \"IS_NULL\") return a === null;\n if (name === \"IS_EMPTY\")\n return a === null || a === \"\" || (Array.isArray(a) && a.length === 0);\n if (name === \"NULLIF\") return equal(a, b) ? null : a;\n if (name === \"CONCAT_WS\")\n return a === null\n ? null\n : bound(\n vs\n .slice(1)\n .filter((v) => v !== null)\n .map(str)\n .join(str(a)),\n );\n if (name === \"op:IN\") {\n if (a === null) return null;\n if (vs.slice(1).some((v) => v !== null && equal(a, v))) return true;\n return vs.slice(1).includes(null) ? null : false;\n }\n if (vs.some((v) => v === null)) return null;\n let out: FormulaValue;\n switch (name) {\n case \"unary:NOT\":\n out = !a;\n break;\n case \"unary:-\":\n out = -num(a);\n break;\n case \"unary:+\":\n out = num(a);\n break;\n case \"op:+\":\n out = num(a) + num(b);\n break;\n case \"op:-\":\n out = num(a) - num(b);\n break;\n case \"op:*\":\n out = num(a) * num(b);\n break;\n case \"op:/\":\n case \"op:%\":\n if (num(b) === 0) fail(\"Division by zero.\");\n out = name === \"op:/\" ? num(a) / num(b) : num(a) % num(b);\n break;\n case \"op:=\":\n out = equal(a, b);\n break;\n case \"op:!=\":\n case \"op:<>\":\n out = !equal(a, b);\n break;\n case \"op:<\":\n out = a! < b!;\n break;\n case \"op:>\":\n out = a! > b!;\n break;\n case \"op:<=\":\n out = a! <= b!;\n break;\n case \"op:>=\":\n out = a! >= b!;\n break;\n case \"op:BETWEEN\":\n out = a! >= b! && a! <= c!;\n break;\n case \"LEFT\":\n out = Array.from(str(a)).slice(0, integer(b)).join(\"\");\n break;\n case \"RIGHT\": {\n const n = integer(b);\n out = n ? Array.from(str(a)).slice(-n).join(\"\") : \"\";\n break;\n }\n case \"SUBSTRING\": {\n const start = integer(b, 1) - 1;\n out = Array.from(str(a))\n .slice(start, vs.length > 2 ? start + integer(c) : undefined)\n .join(\"\");\n break;\n }\n case \"LENGTH\":\n out = Array.from(str(a)).length;\n break;\n case \"URL_ENCODE\":\n // RFC 3986 unreserved characters only, matching DuckDB's url_encode.\n if (!/^(?:[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff])*$/.test(str(a)))\n fail(\"Text is not valid Unicode.\");\n out = encodeURIComponent(str(a)).replace(\n /[!'()*]/g,\n (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n break;\n case \"LOWER\":\n out = str(a).toLowerCase();\n break;\n case \"UPPER\":\n out = str(a).toUpperCase();\n break;\n case \"TRIM\":\n out = str(a).trim();\n break;\n case \"LTRIM\":\n out = str(a).trimStart();\n break;\n case \"RTRIM\":\n out = str(a).trimEnd();\n break;\n case \"REPLACE\":\n if (b === \"\") fail(\"Search text must not be empty.\");\n const parts = str(a).split(str(b));\n if (parts.length * str(c).length + str(a).length > 200000)\n fail(\"Replacement result is too large.\");\n out = parts.join(str(c));\n break;\n case \"LPAD\":\n case \"RPAD\": {\n const chars = Array.from(str(a)),\n len = integer(b),\n pad = Array.from(vs.length > 2 ? str(c) : \" \");\n if (!pad.length) fail(\"Padding must not be empty.\");\n const fill = Array.from(\n { length: Math.max(0, len - chars.length) },\n (_, i) => pad[i % pad.length]!,\n ).join(\"\");\n out =\n (name === \"LPAD\" ? fill : \"\") +\n chars.slice(0, len).join(\"\") +\n (name === \"RPAD\" ? fill : \"\");\n break;\n }\n case \"SPLIT_PART\":\n out = str(a).split(str(b))[integer(c, 1) - 1] ?? null;\n break;\n case \"CONCAT\":\n out = vs.map(str).join(\"\");\n break;\n case \"CONTAINS\":\n case \"STARTS_WITH\":\n case \"ENDS_WITH\": {\n const s = c === true ? str(a).toLowerCase() : str(a),\n t = c === true ? str(b).toLowerCase() : str(b);\n out =\n name === \"CONTAINS\"\n ? s.includes(t)\n : name === \"STARTS_WITH\"\n ? s.startsWith(t)\n : s.endsWith(t);\n break;\n }\n case \"REGEX_TEST\":\n case \"REGEX_EXTRACT\":\n case \"REGEX_REPLACE\": {\n const flags = vs[name === \"REGEX_TEST\" ? 2 : 3] ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(str(flags)))\n fail(\"Regex flags must be unique i, m, or s.\");\n if (str(b).length > 2000)\n fail(\"Regex pattern exceeds 2,000 characters.\");\n const re = new RegExp(\n str(b),\n `${flags}u${name === \"REGEX_REPLACE\" ? \"g\" : \"\"}`,\n );\n if (name === \"REGEX_TEST\") out = re.test(str(a));\n else if (name === \"REGEX_REPLACE\") {\n let produced = 0;\n out = str(a).replace(re, (...captures: unknown[]) => {\n const replacement = str(c).replace(\n /\\$(\\$|[0-9]{1,2}|&|`|')/g,\n (_token, key: string) => {\n if (key === \"$\") return \"$\";\n if (key === \"&\") return String(captures[0]);\n if (key === \"`\" || key === \"'\")\n return fail(\n \"Regex replacement supports $$, $&, and numbered captures only.\",\n );\n const extra =\n typeof captures[captures.length - 1] === \"object\" ? 3 : 2;\n const i = Number(key);\n return i > 0 && i < captures.length - extra\n ? String(captures[i] ?? \"\")\n : fail(\"Invalid replacement capture.\");\n },\n );\n produced += replacement.length;\n if (produced > 100000) fail(\"Replacement result is too large.\");\n return replacement;\n });\n } else {\n const match = re.exec(str(a));\n const group = vs.length > 2 ? integer(c, 0, 100) : 0;\n out = match?.[group] ?? null;\n if (match)\n inspection = {\n input: str(a),\n start: match.index,\n end: match.index + match[0].length,\n groups: Array.from(match, (v) => v ?? null),\n };\n }\n break;\n }\n case \"ABS\":\n out = Math.abs(num(a));\n break;\n case \"FLOOR\":\n out = Math.floor(num(a));\n break;\n case \"CEIL\":\n out = Math.ceil(num(a));\n break;\n case \"TRUNC\":\n out = Math.trunc(num(a));\n break;\n case \"SQRT\":\n out = Math.sqrt(num(a));\n break;\n case \"ROUND\": {\n const scale = 10 ** (vs.length > 1 ? integer(b, -15, 15) : 0);\n out = Math.round(num(a) * scale) / scale;\n break;\n }\n case \"POWER\":\n out = Math.pow(num(a), num(b));\n break;\n case \"CLAMP\":\n if (num(b) > num(c)) fail(\"Lower bound exceeds upper bound.\");\n out = Math.max(num(b), Math.min(num(c), num(a)));\n break;\n case \"LEAST\":\n out = Math.min(...vs.map(num));\n break;\n case \"GREATEST\":\n out = Math.max(...vs.map(num));\n break;\n case \"TO_TEXT\":\n out = Array.isArray(a) ? JSON.stringify(a) : String(a);\n break;\n case \"TO_NUMBER\":\n if (\n typeof a !== \"number\" &&\n (typeof a !== \"string\" ||\n !/^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/.test(a.trim()))\n )\n fail(\"Cannot convert to number.\");\n out = Number(a);\n break;\n case \"TO_BOOLEAN\":\n if (a === true || a === false) out = a;\n else if (a === \"true\" || a === 1) out = true;\n else if (a === \"false\" || a === 0) out = false;\n else return fail(\"Cannot convert to boolean.\");\n break;\n case \"TO_DATETIME\":\n out = date(a).toISOString();\n break;\n case \"SPLIT\":\n out = str(a).split(str(b));\n break;\n case \"JOIN\":\n out = arr(a).join(str(b));\n break;\n case \"ARRAY_LENGTH\":\n out = arr(a).length;\n break;\n case \"ARRAY_CONTAINS\":\n out = arr(a).includes(str(b));\n break;\n case \"ARRAY_GET\":\n out = arr(a)[integer(b, 1) - 1] ?? null;\n break;\n case \"ARRAY_UNIQUE\":\n out = [...new Set(arr(a))];\n break;\n case \"ARRAY_SORT\":\n out = [...arr(a)].sort((left, right) => {\n const l = Array.from(left),\n r = Array.from(right);\n for (let i = 0; i < Math.min(l.length, r.length); i++) {\n const delta = l[i]!.codePointAt(0)! - r[i]!.codePointAt(0)!;\n if (delta) return delta;\n }\n return l.length - r.length;\n });\n break;\n case \"YEAR\":\n out = date(a).getUTCFullYear();\n break;\n case \"MONTH\":\n out = date(a).getUTCMonth() + 1;\n break;\n case \"DAY\":\n out = date(a).getUTCDate();\n break;\n case \"HOUR\":\n out = date(a).getUTCHours();\n break;\n case \"WEEKDAY\":\n out = ((date(a).getUTCDay() + 6) % 7) + 1;\n break;\n case \"DATE_TRUNC\": {\n const d = date(b),\n unit = str(a).toLowerCase();\n if (\n ![\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n ].includes(unit)\n )\n fail(\"Unsupported date unit.\");\n d.setUTCMilliseconds(0);\n if (unit !== \"second\") d.setUTCSeconds(0);\n if (![\"second\", \"minute\"].includes(unit)) d.setUTCMinutes(0);\n if ([\"year\", \"month\", \"week\", \"day\"].includes(unit)) d.setUTCHours(0);\n if (unit === \"week\")\n d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7));\n if (unit === \"year\" || unit === \"month\") d.setUTCDate(1);\n if (unit === \"year\") d.setUTCMonth(0);\n out = d.toISOString();\n break;\n }\n case \"DATE_ADD\": {\n const d = date(c),\n unit = str(a).toLowerCase(),\n amount = integer(b, -100000, 100000);\n if (unit === \"year\" || unit === \"month\") {\n const day = d.getUTCDate();\n d.setUTCDate(1);\n d.setUTCMonth(d.getUTCMonth() + amount * (unit === \"year\" ? 12 : 1));\n const last = new Date(d.getTime());\n last.setUTCMonth(last.getUTCMonth() + 1, 0);\n d.setUTCDate(Math.min(day, last.getUTCDate()));\n } else {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[unit];\n if (!ms) fail(\"Unsupported date unit.\");\n d.setTime(d.getTime() + amount * ms!);\n }\n out = d.toISOString();\n break;\n }\n case \"DATE_DIFF\": {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[str(a).toLowerCase()];\n if (!ms) fail(\"Unsupported elapsed date unit.\");\n out = Math.trunc((date(c).getTime() - date(b).getTime()) / ms!);\n break;\n }\n case \"FORMAT_DATE\": {\n const d = date(a),\n pad = (n: number) => String(n).padStart(2, \"0\"),\n parts: Record<string, string> = {\n YYYY: String(d.getUTCFullYear()).padStart(4, \"0\"),\n MM: pad(d.getUTCMonth() + 1),\n DD: pad(d.getUTCDate()),\n HH: pad(d.getUTCHours()),\n mm: pad(d.getUTCMinutes()),\n ss: pad(d.getUTCSeconds()),\n };\n out = str(b).replace(/YYYY|MM|DD|HH|mm|ss/g, (t) => parts[t]!);\n break;\n }\n default:\n return fail(`Unknown operation: ${name}`);\n }\n return bound(out);\n }\n try {\n const value = run(ast);\n return inspection ? { value, regex: inspection } : { value };\n } catch (e) {\n return {\n value: null,\n error: e instanceof Error ? e.message : \"Formula evaluation failed.\",\n };\n }\n}\n","// groupKeys.ts — exact predicates selecting one group's key tuple.\n//\n// Shared by `groupSourceQuery` (drilldown) and query-kind link columns, so a\n// link's key filters are exactly the filters drilling into the group adds.\n\nimport { isFilterable, resolveField, type FieldDef, type FieldSchema } from \"./schema\";\nimport type { WhereClause } from \"./query\";\n\n/** Filters accept datetimes as ISO instants with an explicit offset. */\nexport function datetimeValue(value: unknown): string | null {\n const time =\n value instanceof Date ? value.getTime()\n : typeof value === \"number\" ? value\n : typeof value === \"string\" && value !== \"\" ? Date.parse(value)\n : NaN;\n return Number.isFinite(time) ? new Date(time).toISOString() : null;\n}\n\n/** One equality (or `is_null`) predicate selecting a group key, or null when\n * the field cannot express it exactly. */\nexport function keyClause(field: FieldDef | undefined, value: unknown): WhereClause | null {\n if (!field || field.type === \"textarray\" || !isFilterable(field)) return null;\n if (value == null) return { field: field.name, op: \"is_null\", value: \"\" };\n if (field.type === \"datetime\") {\n const iso = datetimeValue(value);\n return iso === null ? null : { field: field.name, op: \"=\", value: iso };\n }\n if (typeof value === \"number\" ? !Number.isFinite(value) : typeof value !== \"string\" && typeof value !== \"boolean\")\n return null;\n return { field: field.name, op: \"=\", value: String(value) };\n}\n\n/** `=` (or `is_null`) per key, in key order, or null when any key cannot be\n * matched exactly (textarray, unknown or unfilterable fields, unparseable\n * datetimes). */\nexport function groupKeyTerms(keys: readonly string[], group: Record<string, unknown>, schema: FieldSchema): WhereClause[] | null {\n const terms: WhereClause[] = [];\n for (const key of keys) {\n const term = keyClause(resolveField(schema, key), group[key]);\n if (!term) return null;\n terms.push(term);\n }\n return terms;\n}\n","import { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n compileMetric,\n metricAggregatePlans,\n reduceMetricValues,\n evaluateMetricReductions,\n metricPlans,\n hasRegex,\n selectMetricShownRows,\n} from \"./metrics\";\nimport { formulaRuntime, type FormulaNode, type FormulaValue } from \"./formula\";\nimport { isComputedCellError, isComputedField } from \"./computed\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { datetimeValue, groupKeyTerms } from \"./groupKeys\";\nimport { fillUrlTemplate, templateFields, urlTemplateProblem } from \"./itemPage\";\nimport type { QueryPatch } from \"./queryPatch\";\nimport { type QueryEvaluationOptions } from \"./relativeTime\";\nimport type { MetricPlan } from \"./metrics\";\nimport {\n isFilterable,\n isSortable,\n isSelectable,\n readFieldValue,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n MAX_GROUP_BY_FIELDS,\n normalizeQueryState,\n predicatesOf,\n type AggOp,\n type QueryState,\n type WhereClause,\n} from \"./query\";\n\nexport type GroupedRow = Record<string, unknown>;\ntype Row = GroupedRow;\nexport type SummaryOp = AggOp | \"row\" | \"formula\" | \"link\";\nexport interface RepresentativeOrder {\n field: string;\n dir: \"asc\" | \"desc\";\n nulls: \"first\" | \"last\";\n}\nexport interface RepresentativeRow {\n orderBy: RepresentativeOrder[];\n}\nexport interface SummaryColumn {\n id: string;\n op: SummaryOp;\n field?: string;\n expression?: string;\n label?: string;\n /** Cell format for this output column (for example `{ kind: \"percent\" }` for\n * a weighted rate). Replaces any render/display inherited from the source\n * field; metrics measuring the column default their value format from it. */\n display?: CellDisplay;\n /** Required for `op: \"link\"`; ignored otherwise. */\n link?: LinkSpec;\n}\n\n/** Where a link column points. Placeholders and key filters read the group\n * row: its keys and non-link summaries. */\nexport type LinkDestination =\n /** `{field:name}` placeholders over keys and summaries; values are\n * percent-encoded. The result must be an HTTP(S) or relative URL. */\n | { kind: \"template\"; template: string }\n /** A query composed by query-table and routed by the host's\n * `linkTargets[target](query, params)`. */\n | {\n kind: \"query\";\n target: string;\n /** \"source\" (default) starts from `grouping.source`, keeping its\n * filters, columns and order; \"empty\" starts from `EMPTY_QUERY`. */\n base?: \"source\" | \"empty\";\n /** Add `=`/`is_null` per group key, as `groupSourceQuery` does. Default true. */\n keyFilters?: boolean;\n /** Applied last, with `applyPatch`. */\n patch?: QueryPatch;\n /** Static parameters passed to the host target. */\n params?: Record<string, string>;\n };\n\n/** A group-grain link column (`SummaryColumn` with `op: \"link\"`). Computed on\n * the client from the returned group row; never sent to a server. */\nexport interface LinkSpec {\n /** Static text, or the value of a group key or summary column. */\n label: string | { column: string };\n to: LinkDestination;\n}\n\n/** The value of a link column for one group row: everything that depends on\n * the row. `resolveGroupLink` combines it with the current query and the\n * host's link targets. */\nexport interface GroupLinkValue {\n kind: \"group-link\";\n label: string;\n to: LinkDestination | null;\n /** Template links: the substituted, not yet safety-checked href. */\n href?: string;\n /** Query links with key filters: the group's key predicates. */\n terms?: WhereClause[];\n /** Why the link cannot be followed for this row. */\n problem?: string;\n}\nexport const GROUP_LINK_RENDER = \"qt_group_link\";\nexport function isGroupLinkValue(value: unknown): value is GroupLinkValue {\n return value != null && typeof value === \"object\" && (value as GroupLinkValue).kind === \"group-link\";\n}\nexport function isGroupLinkField(field: Pick<FieldDef, \"render\"> | undefined): boolean {\n return field?.render === GROUP_LINK_RENDER;\n}\nexport interface GroupingView {\n version: 2;\n mode: \"rows\" | \"groups\";\n keys: string[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n input: QueryState;\n result: QueryState;\n}\n\n/** One grouping stage over the complete source population. QueryState.where is\n * HAVING in this mode; source.where is the pre-group WHERE. The source snapshot\n * also restores the record layout, paging, metrics and item details on exit. */\nexport interface GroupingDefinition {\n keys: string[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n diagnostics?: string[];\n}\nexport interface GroupingState extends GroupingDefinition {\n source: QueryState;\n}\nexport const GROUP_ID_FIELD = \"__qt_group_id__\";\nexport const MAX_REPRESENTATIVE_SORTS = 8;\nexport const MAX_SUMMARY_COLUMNS = 64;\nexport const MAX_RESULT_GROUPS = 10000;\nexport function withoutGrouping(query: QueryState): QueryState {\n const { grouping: _grouping, ...result } = query;\n return result;\n}\n\n/** Leave the grouping stage: the source snapshot restores the record WHERE,\n * layout, ordering, paging, metrics and item details. Ungrouped queries are\n * returned unchanged. */\nexport function exitGrouping(query: QueryState): QueryState {\n return query.grouping ? query.grouping.source : query;\n}\n\n/** The grouping-key transition behind the grouping controls. Empty keys exit\n * the stage; an ungrouped query becomes the source of a new stage that shows\n * only its keys; a grouped query swaps keys, dropping result columns, HAVING\n * terms and sorts on removed keys and clearing group metrics. */\nexport function withGroupingKeys(query: QueryState, keys: string[]): QueryState {\n const before = query.grouping;\n if (!keys.length) return exitGrouping(query);\n if (!before)\n return {\n select: keys.map((field) => ({ field })),\n where: [],\n orderBy: [],\n limit: query.limit,\n offset: 0,\n grouping: { keys, summaries: [], representative: null, source: query },\n };\n const removed = new Set(before.keys.filter((key) => !keys.includes(key)));\n // An empty SELECT shows the existing keys by default. Materialize them\n // before adding keys so introducing an explicit SELECT keeps those columns.\n const columns = query.select.length\n ? query.select\n : before.keys.map((field) => ({ field }));\n return {\n ...query,\n grouping: { ...before, keys },\n offset: 0,\n aggregations: [],\n select: [\n ...keys\n .filter((key) => !before.keys.includes(key))\n .map((field) => ({ field })),\n ...columns.filter((c) => !removed.has(c.field)),\n ],\n where: query.where.filter(\n (term) => !predicatesOf(term).some((p) => removed.has(p.field)),\n ),\n orderBy: query.orderBy.filter((term) => !removed.has(term.field)),\n };\n}\nexport const OP_LABEL: Record<SummaryOp, string> = {\n count: \"COUNT\",\n count_distinct: \"DISTINCT\",\n sum: \"SUM\",\n avg: \"AVG\",\n min: \"MIN\",\n max: \"MAX\",\n row: \"ROW\",\n formula: \"ƒx\",\n link: \"LINK\",\n};\n\n/** Bind aggregation helpers to this instance's source catalogue. */\nexport function createGroupingModel<InputRow>(\n inputSchema: FieldSchema<InputRow>,\n) {\n const sourceField = (name: string) =>\n inputSchema.fields.find((f) => f.name === name);\n const groupableFields = inputSchema.fields.filter(\n (field) => isGroupable(field) && isSelectable(field),\n );\n const summaryFields = inputSchema.fields.filter(\n (f) => f.type !== \"textarray\" && isSelectable(f),\n );\n const representativeFields = inputSchema.fields.filter(\n (field) => isSortable(field) && field.type !== \"textarray\",\n );\n\n function representativeLabel(rule: RepresentativeRow): string {\n return rule.orderBy\n .map(\n (term) =>\n `${sourceField(term.field)?.label ?? term.field} ${term.dir === \"asc\" ? \"↑\" : \"↓\"}${term.nulls === \"first\" ? \" (empty first)\" : \"\"}`,\n )\n .join(\", \");\n }\n\n function allowedOps(field?: string): SummaryOp[] {\n if (!field) return [\"count\"];\n const f = sourceField(field);\n return f && isSelectable(f)\n ? [...(isMeasurable(f) ? aggOpsForField(f) : []), \"row\"]\n : [];\n }\n function summaryExpression(column: SummaryColumn): string {\n if (column.op === \"formula\") return column.expression ?? \"\";\n if (column.op === \"link\") return \"\";\n const field = column.field ? `[${column.field.replace(/\\]/g, \"]]\")}]` : \"\";\n return `${column.op === \"row\" ? \"COUNT\" : column.op.toUpperCase()}(${field})`;\n }\n function summaryProblem(column: SummaryColumn): string | null {\n if (column.op !== \"formula\") return null;\n try {\n const plan = compileMetric(summaryExpression(column), inputSchema);\n if (plan.dependencies.some((name) => !isSelectable(sourceField(name)!)))\n throw new Error(\"Aggregate fields must be selectable.\");\n if (hasRegex(plan))\n throw new Error(\n \"Regex aggregate formulas require isolated execution and are not supported in grouped columns.\",\n );\n return null;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n }\n function summaryLabel(column: SummaryColumn): string {\n if (column.op === \"formula\")\n return column.label?.trim() || \"Custom aggregate\";\n if (column.op === \"link\")\n return column.label?.trim() || (typeof column.link?.label === \"string\" && column.link.label.trim()) || \"Link\";\n if (!column.field) return \"Row count\";\n const label = sourceField(column.field)?.label ?? column.field;\n const prefix: Record<SummaryOp, string> = {\n count: \"Count of\",\n count_distinct: \"Distinct\",\n sum: \"Total\",\n avg: \"Average\",\n min: \"Min\",\n max: \"Max\",\n row: \"Representative ·\",\n formula: \"\",\n link: \"\",\n };\n return `${prefix[column.op]} ${label}`;\n }\n\n /** Group-row fields a link column reads, in a stable order. */\n function linkReferences(column: SummaryColumn, keys: string[]): string[] {\n const link = column.link;\n if (!link) return [];\n const names = new Set<string>();\n if (typeof link.label === \"object\") names.add(link.label.column);\n if (link.to.kind === \"template\")\n for (const name of templateFields(link.to.template)) names.add(name);\n else if (link.to.keyFilters !== false)\n for (const key of keys) names.add(key);\n return [...names];\n }\n\n /** Why a link column is invalid for this definition, or null. Problems are\n * diagnostics: the column renders as plain text and the rest of the grouped\n * table runs. Host target registration is checked when rendering. */\n function linkProblem(\n column: SummaryColumn,\n keys: string[],\n summaries: SummaryColumn[],\n ): string | null {\n const link = column.link;\n if (column.op !== \"link\") return null;\n if (!link) return \"Invalid link definition.\";\n const readable = (name: string) =>\n keys.includes(name) ||\n summaries.some((other) => other.id === name && other.op !== \"link\");\n if (typeof link.label === \"object\" && !readable(link.label.column))\n return `Unknown link label column: ${link.label.column}.`;\n if (link.to.kind === \"template\") {\n if (!link.to.template.trim()) return \"Enter a link URL template.\";\n return urlTemplateProblem(link.to.template, [], readable);\n }\n if (link.to.keyFilters !== false)\n for (const key of keys) {\n const field = sourceField(key);\n if (field?.type === \"textarray\")\n return `Key filters cannot match the textarray key ${field.label}.`;\n if (!field || !isFilterable(field))\n return `Key filters cannot match the key ${field?.label ?? key}.`;\n }\n return null;\n }\n\n /** One message per invalid link column, prefixed with its label. */\n function linkDiagnostics(definition: Pick<GroupingDefinition, \"keys\" | \"summaries\">): string[] {\n return definition.summaries.flatMap((column) => {\n const problem = linkProblem(column, definition.keys, definition.summaries);\n return problem ? [`${summaryLabel(column)}: ${problem}`] : [];\n });\n }\n\n function linkValue(\n column: SummaryColumn,\n problem: string | null,\n keys: string[],\n schema: FieldSchema<Row>,\n row: Row,\n ): GroupLinkValue {\n const link = column.link;\n const read = (name: string): unknown => {\n const field = schema.fields.find((f) => f.name === name);\n const value = field ? readFieldValue(field, row) : undefined;\n if (value == null || isComputedCellError(value)) return null;\n if (field?.type === \"datetime\" || value instanceof Date)\n return datetimeValue(value) ?? value;\n return Array.isArray(value) ? value.join(\", \") : value;\n };\n const label = !link\n ? summaryLabel(column)\n : typeof link.label === \"string\"\n ? link.label\n : String(read(link.label.column) ?? \"\");\n const value: GroupLinkValue = { kind: \"group-link\", label, to: link?.to ?? null };\n if (problem || !link) return { ...value, problem: problem ?? \"Invalid link definition.\" };\n if (link.to.kind === \"template\") {\n const href = fillUrlTemplate(link.to.template, [], (token) => read(token.slice(6)));\n return href === null ? { ...value, problem: \"A value in this link is empty.\" } : { ...value, href };\n }\n if (link.to.keyFilters === false) return value;\n const terms = groupKeyTerms(keys, row, inputSchema);\n return terms ? { ...value, terms } : { ...value, problem: \"This group cannot be matched exactly.\" };\n }\n\n function resultSchema(\n keys: string[],\n summaries: SummaryColumn[],\n ): FieldSchema<Row> {\n const fields: FieldDef<Row>[] = [\n {\n name: GROUP_ID_FIELD,\n label: \"Group identity\",\n type: \"text\",\n source: { kind: \"backend\" },\n select: { enabled: false },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n },\n ...keys.flatMap((key): FieldDef<Row>[] => {\n const field = sourceField(key);\n // Draft/saved views may contain fields removed by the host. Leave\n // them in query state for repair; validate() still rejects execution.\n if (!field) return [];\n return [{\n name: key,\n label: field.label,\n type: field.type,\n source: { kind: \"backend\" },\n ...(field.select ? { select: { ...field.select } } : {}),\n ...(field.filter ? { filter: { ...field.filter } } : {}),\n ...(field.aggregate ? { aggregate: { ...field.aggregate } } : {}),\n ...(field.sort?.enabled !== undefined\n ? { sort: { enabled: field.sort.enabled } }\n : {}),\n ...(typeof field.render === \"string\" ? { render: field.render } : {}),\n ...(field.display ? { display: field.display } : {}),\n group: \"Group keys\",\n }];\n }),\n ];\n let schema: FieldSchema<Row>;\n for (const column of summaries) {\n if (column.op === \"link\") {\n const problem = linkProblem(column, keys, summaries);\n // Client-only: toServerQuery requests the dependencies instead.\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type: \"text\",\n source: {\n kind: \"derived\",\n dependencies: linkReferences(column, keys),\n accessor: (row) => linkValue(column, problem, keys, schema, row),\n },\n select: { align: \"left\" },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n render: GROUP_LINK_RENDER,\n group: \"Links\",\n });\n continue;\n }\n if (column.op === \"formula\") {\n let type: FieldDef<Row>[\"type\"] = \"number\";\n try {\n const compiled = compileMetric(\n summaryExpression(column),\n inputSchema,\n );\n type = compiled.type === \"null\" ? \"number\" : compiled.type;\n } catch {\n /* Invalid drafts show diagnostics in the editor. */\n }\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type,\n source: { kind: \"backend\" },\n group: \"Aggregates\",\n select: { align: type === \"number\" ? \"right\" : \"left\" },\n ...(column.display ? { display: column.display } : {}),\n });\n continue;\n }\n const input = column.field ? sourceField(column.field) : undefined;\n const counting = column.op === \"count\" || column.op === \"count_distinct\";\n const numeric = counting || column.op === \"sum\" || column.op === \"avg\";\n const example = column.op === \"row\";\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type: numeric ? \"number\" : (input?.type ?? \"number\"),\n source: { kind: \"backend\" },\n select: {\n align: numeric || input?.type === \"number\" ? \"right\" : \"left\",\n },\n group: example ? \"Representative row\" : \"Summaries\",\n ...(!numeric && input?.aggregate?.groupable !== undefined\n ? { aggregate: { groupable: input.aggregate.groupable } }\n : {}),\n // An explicit summary format replaces the inherited source presentation.\n ...(column.display\n ? { display: column.display }\n : {\n ...(typeof input?.render === \"string\" && !counting\n ? { render: input.render }\n : {}),\n ...(input?.display && !counting ? { display: input.display } : {}),\n }),\n });\n }\n schema = {\n name: `${inputSchema.name}:groups`,\n idField: GROUP_ID_FIELD,\n fields,\n defaultSelect: keys.filter(key => sourceField(key)).map((field) => ({ field })),\n defaultLimit: 25,\n };\n return schema;\n }\n\n // Typed tuples distinguish NULL, empty string, booleans and numbers. Key field\n // names are part of identity; key order and row arrival order are not.\n function keyValue(value: unknown): FormulaValue {\n if (value == null) return null;\n if (value instanceof Date) return value.toISOString();\n if (\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n return value;\n throw new Error(\"Group keys must be finite scalar values.\");\n }\n function groupId(\n row: InputRow,\n keys: string[],\n schema: FieldSchema<InputRow>,\n ): string {\n const tuple = [...keys]\n .sort()\n .map((key) => [\n key,\n keyValue(\n readFieldValue(schema.fields.find((f) => f.name === key)!, row),\n ),\n ]);\n // Bound source strings before JSON escaping can multiply their allocation.\n if (\n tuple.some(\n ([key, value]) => String(key).length + String(value).length > 10000,\n )\n )\n throw new Error(\"Grouping key length budget exceeded.\");\n const id = JSON.stringify(tuple);\n if (id.length > 65536)\n throw new Error(\"Grouping key length budget exceeded.\");\n return id;\n }\n function compare(a: unknown, b: unknown): number {\n if (a === b) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n return a < b ? -1 : 1;\n }\n function representative(\n rows: InputRow[],\n rule: RepresentativeRow,\n schema: FieldSchema<InputRow>,\n ): InputRow {\n const identityField = schema.fields.find(\n (field) => field.name === schema.idField,\n );\n const identities = new Set<string | number>();\n for (const row of rows) {\n const id = identityField\n ? readFieldValue(identityField, row)\n : (row as Record<string, unknown>)[schema.idField];\n if (\n !(\n typeof id === \"string\" ||\n (typeof id === \"number\" && Number.isFinite(id))\n ) ||\n identities.has(id)\n )\n throw new Error(\n \"Representative rows require unique string or finite numeric source IDs.\",\n );\n identities.add(id);\n }\n // The same stable identity tie-break is used for every projection. Explicit\n // ordering by ID takes precedence; no arrival-order fallback is needed.\n const order = rule.orderBy.some((term) => term.field === schema.idField)\n ? rule.orderBy\n : [\n ...rule.orderBy,\n { field: schema.idField, dir: \"desc\", nulls: \"last\" } as const,\n ];\n const terms = order.map((term) => ({\n ...term,\n def: schema.fields.find((field) => field.name === term.field)!,\n }));\n return rows.reduce((best, row) => {\n for (const term of terms) {\n const value = (record: InputRow) => {\n const raw = term.def\n ? readFieldValue(term.def, record)\n : (record as Record<string, unknown>)[schema.idField];\n if (raw == null || term.def?.type !== \"datetime\") return raw;\n const instant = Date.parse(String(raw));\n return Number.isFinite(instant) ? instant : null;\n };\n const a = value(row),\n b = value(best);\n if (a == null || b == null) {\n if (a == null && b == null) continue;\n return (a == null) === (term.nulls === \"first\") ? row : best;\n }\n const rank = compare(a, b);\n if (rank !== 0)\n return (term.dir === \"asc\" ? rank < 0 : rank > 0) ? row : best;\n }\n return best;\n });\n }\n function groupRows(\n rows: InputRow[],\n schema: FieldSchema<InputRow>,\n keys: string[],\n summaries: SummaryColumn[],\n rule: RepresentativeRow | null = null,\n ): Row[] {\n if (!rule && summaries.some((column) => column.op === \"row\"))\n throw new Error(\n \"Configure representative-row ordering before selecting row values.\",\n );\n if (keys.length === 0) return [];\n if (keys.length > MAX_GROUP_BY_FIELDS || summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Grouping definition exceeds column limits.\");\n if (rows.length > 1_000_000)\n throw new Error(\"Grouping row budget exceeded.\");\n let bytes = rows.length * 16;\n let operations = 0;\n const groups = new Map<string, InputRow[]>();\n for (const row of rows) {\n const id = groupId(row, keys, schema);\n const bucket = groups.get(id);\n if (bucket) bucket.push(row);\n else {\n if (groups.size >= MAX_RESULT_GROUPS)\n throw new Error(\n `Grouping exceeds ${MAX_RESULT_GROUPS.toLocaleString()} groups.`,\n );\n bytes += id.length * 2 + 256;\n if (bytes > 16_000_000)\n throw new Error(\"Grouping retained-memory budget exceeded.\");\n groups.set(id, [row]);\n }\n }\n const formulas = new Map<string, { plan?: MetricPlan; error?: string }>(\n summaries\n .filter((c) => c.op !== \"row\" && c.op !== \"link\")\n .map((column) => {\n try {\n const problem = summaryProblem(column);\n if (problem) throw new Error(problem);\n return [\n column.id,\n { plan: compileMetric(summaryExpression(column), schema) },\n ] as const;\n } catch (error) {\n return [\n column.id,\n { error: error instanceof Error ? error.message : String(error) },\n ] as const;\n }\n }),\n );\n const nodeCost = (node: FormulaNode): number =>\n 1 +\n (node.kind === \"call\"\n ? node.args.reduce((cost, child) => cost + nodeCost(child), 0)\n : 0);\n const costs = new Map(\n [...formulas].map(([id, compiled]) => [\n id,\n compiled.plan?.aggregates.map(nodeCost) ?? [],\n ]),\n );\n return [...groups].map(([id, members]) => {\n const output: Row = Object.assign(Object.create(null), {\n [GROUP_ID_FIELD]: id,\n });\n for (const key of keys)\n output[key] = readFieldValue(\n schema.fields.find((f) => f.name === key)!,\n members[0]!,\n );\n const chosen =\n rule && summaries.some((column) => column.op === \"row\")\n ? representative(members, rule, schema)\n : null;\n for (const column of summaries) {\n if (column.op === \"link\") continue;\n if (column.op !== \"row\") {\n const compiled = formulas.get(column.id)!;\n if (!compiled.plan) {\n output[column.id] = { computedError: compiled.error };\n continue;\n }\n const plan = compiled.plan;\n const rowPlans = metricAggregatePlans(plan);\n const reductions = plan.aggregates.map((node, i) =>\n reduceMetricValues(\n node,\n members.map((row) => {\n if ((operations += costs.get(column.id)?.[i] ?? 1) > 10_000_000)\n throw new Error(\"Grouping operation budget exceeded.\");\n const rowPlan = rowPlans[i];\n if (!rowPlan) return { value: 1 };\n const values = Object.fromEntries(\n rowPlan.dependencies.map((name) => {\n const value = readFieldValue(\n schema.fields.find((f) => f.name === name)!,\n row,\n );\n return [\n name,\n (value instanceof Date\n ? value.toISOString()\n : (value ?? null)) as FormulaValue,\n ];\n }),\n );\n return formulaRuntime(rowPlan.ast, values);\n }),\n ),\n );\n const result = evaluateMetricReductions(plan, reductions);\n output[column.id] = result.error\n ? { computedError: result.error }\n : result.value;\n continue;\n }\n const field = schema.fields.find((f) => f.name === column.field);\n if (column.op === \"row\") {\n output[column.id] =\n field && chosen ? readFieldValue(field, chosen) : null;\n continue;\n }\n }\n return output;\n });\n }\n function filteredInput(\n rows: InputRow[],\n query: QueryState,\n schema: FieldSchema<InputRow>,\n options: QueryEvaluationOptions = {},\n ): InputRow[] {\n // GROUP BY operates on all matching source records, never on a displayed page.\n return selectMetricShownRows(\n rows,\n {\n ...withoutGrouping(query),\n aggregations: [],\n orderBy: [],\n offset: 0,\n limit: Math.max(1, rows.length),\n },\n { ...schema, defaultSort: [] },\n options,\n );\n }\n\n /** Reconcile only consumers of row values when the shared selection changes.\n * Aggregate outputs and metrics over them keep their meaning. */\n function reconcileRepresentative(\n query: QueryState,\n summaries: SummaryColumn[],\n schema: FieldSchema<Row>,\n remove: boolean,\n ): QueryState {\n const affected = new Set(\n summaries.filter((s) => s.op === \"row\").map((s) => s.id),\n );\n if (!affected.size) return query;\n // Computed columns can depend on representative fields transitively.\n let grew = true;\n while (grew) {\n grew = false;\n for (const f of schema.fields) {\n if (\n !affected.has(f.name) &&\n f.source.kind === \"derived\" &&\n f.source.dependencies?.some((name) => affected.has(name))\n ) {\n affected.add(f.name);\n grew = true;\n }\n }\n }\n return {\n ...query,\n offset: 0,\n select: remove\n ? query.select.filter((c) => !affected.has(c.field))\n : query.select,\n where: query.where.filter(\n (term) => !predicatesOf(term).some((p) => affected.has(p.field)),\n ),\n orderBy: query.orderBy.filter((term) => !affected.has(term.field)),\n aggregations: (query.aggregations ?? []).filter((metric) => {\n if (metric.groupBy.some((name) => affected.has(name))) return false;\n try {\n return !metricPlans(metric, schema).some((plan) =>\n plan.dependencies.some((name) => affected.has(name)),\n );\n } catch {\n // A broken expression cannot be proven independent of the changed values.\n return false;\n }\n }),\n };\n }\n\n function validate(definition: GroupingDefinition): void {\n if (definition.diagnostics?.length)\n throw new Error(definition.diagnostics.join(\" \"));\n if (\n !definition.keys.length ||\n definition.keys.length > MAX_GROUP_BY_FIELDS ||\n new Set(definition.keys).size !== definition.keys.length ||\n definition.keys.some(\n (key) =>\n key === GROUP_ID_FIELD ||\n !groupableFields.some((f) => f.name === key),\n )\n )\n throw new Error(\"Choose valid group keys from the source schema.\");\n if (definition.summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Too many aggregate columns.\");\n const ids = new Set([\n GROUP_ID_FIELD,\n ...inputSchema.fields.map((field) => field.name),\n ]);\n const sourceNames = new Set(inputSchema.fields.map((field) => field.name));\n for (const column of definition.summaries) {\n if (sourceNames.has(column.id))\n throw new Error(\n `Aggregate column ID \"${column.id}\" is already a source field name. Choose a different id, such as \"${column.op === \"formula\" || column.op === \"row\" ? \"summary\" : column.op}_${column.id}\".`,\n );\n if (ids.has(column.id) && column.id !== GROUP_ID_FIELD)\n throw new Error(\n `Aggregate column ID \"${column.id}\" is used by more than one column.`,\n );\n if (\n !column.id ||\n column.id.length > 256 ||\n ids.has(column.id) ||\n isComputedField(column.id) ||\n [\"__proto__\", \"constructor\", \"prototype\"].includes(column.id)\n )\n throw new Error(\n \"Aggregate column IDs must be 1–256 characters and cannot be reserved names or @computed/ references.\",\n );\n ids.add(column.id);\n // Link problems are diagnostics (linkDiagnostics), never execution errors.\n if (column.op === \"link\") continue;\n if (column.op === \"formula\") {\n const error = summaryProblem(column);\n if (error) throw new Error(error);\n } else if (\n !allowedOps(column.field).includes(column.op) ||\n (column.op === \"row\" && (!column.field || !definition.representative))\n )\n throw new Error(\"Invalid aggregate or representative column.\");\n }\n const rule = definition.representative;\n if (\n rule &&\n (!rule.orderBy.length ||\n rule.orderBy.length > MAX_REPRESENTATIVE_SORTS ||\n new Set(rule.orderBy.map((t) => t.field)).size !==\n rule.orderBy.length ||\n rule.orderBy.some(\n (t) =>\n !representativeFields.some((f) => f.name === t.field) ||\n ![\"asc\", \"desc\"].includes(t.dir) ||\n ![\"first\", \"last\"].includes(t.nulls),\n ))\n )\n throw new Error(\"Choose valid representative-row ordering.\");\n }\n\n return {\n inputSchema,\n sourceField,\n groupableFields,\n summaryFields,\n representativeFields,\n representativeLabel,\n allowedOps,\n summaryExpression,\n summaryProblem,\n summaryLabel,\n linkProblem,\n linkDiagnostics,\n resultSchema,\n groupRows,\n filteredInput,\n reconcileRepresentative,\n validate,\n };\n}\nexport type GroupingModel<Row> = ReturnType<typeof createGroupingModel<Row>>;\n\n/** Evaluate the WHERE and grouping stages once; callers apply HAVING and paging\n * with the resulting schema and withoutGrouping(query). Never accepts a page\n * fetched by a transport as a complete source dataset. */\nexport function prepareGrouping<Row>(\n rows: Row[],\n schema: FieldSchema<Row>,\n grouping: GroupingState,\n options: QueryEvaluationOptions = {},\n) {\n const model = createGroupingModel(schema);\n if (grouping.source.grouping)\n throw new Error(\"Only one grouping stage is supported.\");\n model.validate(grouping);\n const inputs = model.filteredInput(rows, grouping.source, schema, options);\n return {\n inputs,\n rows: model.groupRows(\n inputs,\n schema,\n grouping.keys,\n grouping.summaries,\n grouping.representative,\n ),\n schema: model.resultSchema(grouping.keys, grouping.summaries),\n };\n}\n","import {\n predicatesOf,\n normalizeQueryState,\n type QueryState,\n type RowId,\n} from \"./query\";\nimport { toServerQuery, type ServerQuery } from \"./encode\";\nimport {\n isComputedField,\n type ComputedExecution,\n type RowComputedValues,\n} from \"./computed\";\nimport { selectedFields, type FieldSchema } from \"./schema\";\nimport type { MetricDiagnostic } from \"./metricTypes\";\n/** Versioned row projection keeps server-computed payload separate from host row fields. */\nexport interface ServerQueryV2 extends ServerQuery {\n version: 2;\n profile: string;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n /** Host must enforce this binding against the row response. */\n snapshot?: string;\n diagnostics: MetricDiagnostic[];\n}\nexport interface FetchRowsResultV2<Row> {\n version: 2;\n rows: Row[];\n total: number;\n computed: { id: RowId; values: RowComputedValues }[];\n execution: ComputedExecution;\n}\n/** Project with a previously resolved server capability envelope. This does not\n * authorize definitions or upload their source; the backend revalidates revisions. */\nexport function toServerQueryV2<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution: ComputedExecution,\n): ServerQueryV2 {\n const normalized = normalizeQueryState(q),\n legacy = toServerQuery(normalized, schema);\n const diagnostics: MetricDiagnostic[] = [];\n const expectedRevisions = Object.create(null) as Record<string, string>;\n const requireField = (\n name: string,\n operation: \"select\" | \"sort\",\n ): boolean => {\n const cap = execution.fields[name];\n const revision =\n execution.resolvedRevisions[name] ??\n execution.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (!cap?.[operation] || !revision) {\n diagnostics.push({\n code: \"unsupported_computed\",\n message: `Computed field ${name} is unavailable for ${operation}.`,\n from: 0,\n to: 1,\n });\n return false;\n }\n return true;\n };\n for (const [key, value] of Object.entries(execution.resolvedRevisions)) {\n if (\n key.length > 256 ||\n typeof value !== \"string\" ||\n !value ||\n value.length > 256\n )\n throw Error(\"Invalid computed revision envelope.\");\n expectedRevisions[key] = value;\n }\n const select = [...legacy.select];\n for (const c of normalized.select.length\n ? normalized.select\n : selectedFields(schema, normalized).map((f) => ({ field: f.name })))\n if (\n isComputedField(c.field) &&\n execution.fields[c.field]?.select &&\n requireField(c.field, \"select\")\n )\n select.push(c.field);\n // Retain unsupported clauses in state; gate execution using the server envelope.\n const orderBy: ServerQuery[\"orderBy\"] = [];\n for (const term of normalized.orderBy.length\n ? normalized.orderBy\n : (schema.defaultSort ?? [])) {\n if (isComputedField(term.field)) {\n if (requireField(term.field, \"sort\")) {\n if ((term.dir !== \"asc\" && term.dir !== \"desc\") || term.extract) {\n diagnostics.push({\n code: \"unsupported_computed_sort\",\n message: \"Invalid computed sort or extraction.\",\n from: 0,\n to: 1,\n });\n continue;\n }\n orderBy.push({\n field: term.field,\n dir: term.dir,\n ...(term.nulls === \"first\" || term.nulls === \"last\"\n ? { nulls: term.nulls }\n : {}),\n });\n }\n } else {\n const projected = toServerQuery(\n { ...normalized, orderBy: [term] },\n schema,\n ).orderBy;\n if (!projected.length)\n diagnostics.push({\n code: \"unsupported_sort\",\n message: `Unavailable server sort: ${term.field}.`,\n from: 0,\n to: 1,\n });\n orderBy.push(...projected);\n }\n }\n // The host appends its configured tie-break terms and stable identity. An\n // identity term here would take precedence over the host's ordering.\n if (\n legacy.where.length !== normalized.where.length ||\n q.where.reduce((n, t) => n + predicatesOf(t).length, 0) !==\n normalized.where.reduce((n, t) => n + predicatesOf(t).length, 0)\n )\n diagnostics.push({\n code: \"residual_filter\",\n message:\n \"Global execution is unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n });\n return {\n ...legacy,\n select: [...new Set(select)].sort(),\n orderBy,\n version: 2,\n profile: execution.profile,\n expectedRevisions,\n ...(execution.planToken ? { planToken: execution.planToken } : {}),\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n diagnostics,\n };\n}\n","import type { FormulaResult } from \"./formula\";\n\n/** Display arithmetic uses doubles, but an integer outside the safe range is\n * never accepted as an exact metric sample or result. This is not decimal math. */\nexport function assertMetricNumber(value: number): void {\n if (\n !Number.isFinite(value) ||\n (Number.isInteger(value) && !Number.isSafeInteger(value))\n ) {\n throw Error(\"Aggregate exceeds finite safe numeric precision.\");\n }\n}\n\nexport function checkedMetricResult(result: FormulaResult): FormulaResult {\n if (result.error || typeof result.value !== \"number\") return result;\n try {\n assertMetricNumber(result.value);\n return result;\n } catch (e) {\n return { value: null, error: (e as Error).message };\n }\n}\n","import { assertMetricNumber } from \"./metricPrecision\";\n// Exact bounded reductions over the complete scoped population.\nexport function percentile(sorted: number[], p: number): number | null {\n if (!Number.isFinite(p) || p < 0 || p > 1)\n throw Error(\"Percentile must be between zero and one.\");\n if (\n sorted.some((v, i) => !Number.isFinite(v) || (i > 0 && v < sorted[i - 1]!))\n )\n throw Error(\"Percentile inputs must be sorted finite numbers.\");\n sorted.forEach(assertMetricNumber);\n if (!sorted.length) return null;\n const position = (sorted.length - 1) * p,\n lower = Math.floor(position),\n fraction = position - lower;\n const a = sorted[lower]!,\n b = sorted[Math.min(lower + 1, sorted.length - 1)]!;\n // Floating underflow/roundoff cannot move an interpolated percentile outside its two samples.\n const raw = (1 - fraction) * a + fraction * b;\n assertMetricNumber(raw);\n const value = Math.min(b, Math.max(a, raw));\n return value;\n}\nexport function boxSummary(\n values: number[],\n whiskers: \"minmax\" | \"tukey\" = \"minmax\",\n) {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Distribution inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n const sorted = [...values].sort((a, b) => a - b),\n n = sorted.length;\n if (!n) return null;\n const min = sorted[0]!,\n max = sorted[n - 1]!,\n q1 = percentile(sorted, 0.25)!,\n median = percentile(sorted, 0.5)!,\n q3 = percentile(sorted, 0.75)!;\n const lowFence = q1 - 1.5 * (q3 - q1),\n highFence = q3 + 1.5 * (q3 - q1);\n const low = whiskers === \"tukey\" ? sorted.find((v) => v >= lowFence)! : min;\n const high =\n whiskers === \"tukey\"\n ? [...sorted].reverse().find((v) => v <= highFence)!\n : max;\n const outside =\n whiskers === \"tukey\" ? sorted.filter((v) => v < low || v > high) : [];\n // Bound the response while retaining both tails. Report the total separately.\n const outliers =\n outside.length <= 20\n ? outside\n : [...outside.slice(0, 10), ...outside.slice(-10)];\n const rawMean = sorted.reduce((sum, value) => sum + value / n, 0);\n // Check the numeric boundary before correcting insignificant range drift.\n assertMetricNumber(rawMean);\n const mean = Math.min(max, Math.max(min, rawMean));\n [min, q1, median, q3, max, mean, low, high].forEach(assertMetricNumber);\n return {\n n,\n min,\n q1,\n median,\n q3,\n max,\n mean,\n low,\n high,\n outliers,\n outlierCount: outside.length,\n whiskers,\n method: \"exact-linear\" as const,\n };\n}\nexport function histogramEdges(values: number[], bins: number): number[] {\n if (!Number.isInteger(bins) || bins < 2 || bins > 30)\n throw Error(\"Choose 2–30 histogram bins.\");\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n if (!values.length) return [];\n let min = Infinity,\n max = -Infinity;\n for (const value of values) {\n min = Math.min(min, value);\n max = Math.max(max, value);\n }\n if (min === max) return [min, max]; // one point interval, not artificial spread\n if (!Number.isFinite(max - min))\n throw Error(\"Histogram range exceeds finite numeric precision.\");\n const edges = Array.from(\n { length: bins + 1 },\n (_, i) => min + (max - min) * (i / bins),\n );\n edges[0] = min;\n edges[bins] = max;\n edges.forEach(assertMetricNumber);\n if (edges.some((value, i) => i > 0 && value <= edges[i - 1]!))\n throw Error(\n \"Histogram bins are finer than numeric precision. Reduce the bin count.\",\n );\n return edges;\n}\nexport function histogramCounts(values: number[], edges: number[]): number[] {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n if (!edges.length) {\n if (values.length) throw Error(\"Histogram values require edges.\");\n return [];\n }\n if (\n edges.length < 2 ||\n edges.some(\n (v, i) =>\n !Number.isFinite(v) ||\n (i > 0 &&\n (v < edges[i - 1]! || (v === edges[i - 1]! && edges.length !== 2))),\n )\n )\n throw Error(\"Histogram edges must be ordered finite boundaries.\");\n values.forEach(assertMetricNumber);\n edges.forEach(assertMetricNumber);\n const counts = Array<number>(edges.length - 1).fill(0);\n for (const value of values) {\n if (value < edges[0]! || value > edges[edges.length - 1]!)\n throw Error(\"Value falls outside shared histogram edges.\");\n // Lower inclusive, upper exclusive; the last bin also includes the maximum.\n let bin = 0;\n while (bin < counts.length - 1 && value >= edges[bin + 1]!) bin++;\n counts[bin] = counts[bin]! + 1;\n }\n return counts;\n}\n","import { coerceValue } from \"./ops\";\nimport { isOrGroup, type QueryState } from \"./query\";\nimport type { MetricDateGrouping, MetricValue } from \"./metricTypes\";\nimport { Temporal } from \"temporal-polyfill\";\n\nexport const METRIC_DATE_INTERVALS = [\n \"hour\",\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n] as const;\n\n/** Strict calendar input; timestamps require an explicit offset. */\nexport function metricDateTime(value: MetricValue, timeZone = \"UTC\"): number {\n if (\n typeof value !== \"string\" ||\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n value,\n )\n )\n throw Error(\n \"Date grouping requires ISO dates or timestamps with a timezone.\",\n );\n const time = Date.parse(value),\n month = Number(value.slice(5, 7)),\n day = Number(value.slice(8, 10));\n const calendar = new Date(0);\n calendar.setUTCFullYear(Number(value.slice(0, 4)), month, 0);\n if (\n !Number.isFinite(time) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > calendar.getUTCDate()\n )\n throw Error(\"Invalid date grouping value.\");\n return value.length === 10 && timeZone !== \"UTC\"\n ? Temporal.PlainDate.from(value).toZonedDateTime(timeZone).epochMilliseconds\n : time;\n}\n\n/** Find an offset change inside one bucket window. The polyfill's \"previous\"\n * transition lookup caps future searches to about three years from today. */\nfunction metricOffsetTransition(\n start: number,\n end: number,\n timeZone: string,\n): number | undefined {\n if (end <= start) return undefined;\n const offset = (time: number) =>\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone)\n .offsetNanoseconds;\n const before = offset(start);\n if (before === offset(end)) return undefined;\n // IANA transitions are separated by more than this hour-sized window.\n while (end - start > 1) {\n const middle = Math.floor((start + end) / 2);\n if (offset(middle) === before) start = middle;\n else end = middle;\n }\n return end;\n}\n\nexport function metricDateFloor(\n time: number,\n interval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const floor =\n time - zoned.minute * 60000 - zoned.second * 1000 - zoned.millisecond;\n // An offset change can start a partial hour (e.g. Lord Howe's 30-minute\n // DST shift). Split there rather than mapping into the previous offset.\n return metricOffsetTransition(floor, time, timeZone) ?? floor;\n }\n let date = zoned.toPlainDate();\n if (interval === \"week\") date = date.subtract({ days: date.dayOfWeek - 1 });\n if (interval === \"month\" || interval === \"year\")\n date = date.with({ day: 1 });\n if (interval === \"year\") date = date.with({ month: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n date.setUTCMinutes(0, 0, 0);\n if (interval !== \"hour\") date.setUTCHours(0);\n if (interval === \"week\")\n date.setUTCDate(date.getUTCDate() - ((date.getUTCDay() + 6) % 7));\n if (interval === \"month\" || interval === \"year\") date.setUTCDate(1);\n if (interval === \"year\") date.setUTCMonth(0);\n return date.getTime();\n}\n\nexport function metricDateNext(\n time: number,\n interval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const target = zoned\n .toPlainDateTime()\n .with({\n minute: 0,\n second: 0,\n millisecond: 0,\n microsecond: 0,\n nanosecond: 0,\n })\n .add({ hours: 1 });\n let next = target.toZonedDateTime(timeZone).epochMilliseconds;\n if (next <= time)\n next = target.toZonedDateTime(timeZone, {\n disambiguation: \"later\",\n }).epochMilliseconds;\n return metricOffsetTransition(time, next, timeZone) ?? next;\n }\n let date = zoned.toPlainDate();\n if (interval === \"month\") date = date.with({ day: 1 }).add({ months: 1 });\n else if (interval === \"year\")\n date = date.with({ month: 1, day: 1 }).add({ years: 1 });\n else if (interval === \"week\")\n date = date.subtract({ days: date.dayOfWeek - 1 }).add({ weeks: 1 });\n else date = date.add({ days: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n if (interval === \"hour\") date.setUTCHours(date.getUTCHours() + 1);\n else if (interval === \"month\") date.setUTCMonth(date.getUTCMonth() + 1);\n else if (interval === \"year\") date.setUTCFullYear(date.getUTCFullYear() + 1);\n else date.setUTCDate(date.getUTCDate() + (interval === \"week\" ? 7 : 1));\n return date.getTime();\n}\n\n/** A date-only Through value includes the whole local day, even for hourly groups. */\nfunction customEndTime(value: string, timeZone = \"UTC\"): number {\n const time = metricDateTime(value, timeZone);\n return value.length === 10 ? metricDateNext(time, \"day\", timeZone) - 1 : time;\n}\n\nexport function validateDateGrouping(config: MetricDateGrouping): void {\n if (\n typeof config.field !== \"string\" ||\n !config.field ||\n config.field.length > 256 ||\n !METRIC_DATE_INTERVALS.includes(config.interval) ||\n typeof config.includeEmpty !== \"boolean\" ||\n ![\"query\", \"observed\", \"custom\"].includes(config.range)\n )\n throw Error(\"Invalid date grouping definition.\");\n if (config.timeZone !== undefined) {\n if (\n typeof config.timeZone !== \"string\" ||\n !config.timeZone ||\n config.timeZone.length > 80 ||\n /^[+-]/.test(config.timeZone)\n )\n throw Error(\n \"Use a valid IANA grouping timezone, such as America/Denver or UTC.\",\n );\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: config.timeZone });\n } catch {\n throw Error(\n \"Use a valid IANA grouping timezone, such as America/Denver or UTC.\",\n );\n }\n }\n if (config.includeEmpty && config.range === \"custom\") {\n const start = metricDateTime(config.start ?? \"\", config.timeZone),\n end = customEndTime(config.end ?? \"\", config.timeZone);\n if (end < start)\n throw Error(\"The end date must be on or after the start date.\");\n }\n}\n\n/** Only conjunctive bounds prove a domain; OR alternatives are not bounds. */\nexport function metricDateRange(\n config: MetricDateGrouping,\n query: QueryState,\n observed: readonly number[],\n now: number,\n canonical: (field: string) => string,\n): [number, number] | undefined {\n let min = Infinity,\n max = -Infinity;\n for (const time of observed) {\n min = Math.min(min, time);\n max = Math.max(max, time);\n }\n if (config.range === \"observed\")\n return observed.length ? [min, max] : undefined;\n if (config.range === \"custom\") {\n const start = metricDateFloor(\n metricDateTime(config.start ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n const end = metricDateFloor(\n customEndTime(config.end ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n if (observed.length && (start > min || end < max))\n throw Error(\n \"Custom date bounds must include all observed buckets. Narrow the query filters to exclude data.\",\n );\n return [start, end];\n }\n let start = -Infinity,\n end = Infinity;\n for (const term of query.where) {\n if (\n isOrGroup(term) ||\n term.negated ||\n canonical(term.field) !== canonical(config.field)\n )\n continue;\n if (![\"=\", \">\", \">=\", \"<\", \"<=\"].includes(term.op)) continue;\n const time = Number(coerceValue(\"datetime\", term.value, now));\n if (term.op === \">\" || term.op === \">=\" || term.op === \"=\")\n start = Math.max(start, time + (term.op === \">\" ? 1 : 0));\n if (term.op === \"<\" || term.op === \"<=\" || term.op === \"=\")\n end = Math.min(end, time - (term.op === \"<\" ? 1 : 0));\n }\n if (!Number.isFinite(start) || !Number.isFinite(end)) {\n const missing = [\n ...(Number.isFinite(start) ? [] : [\"a lower bound (>= or >)\"]),\n ...(Number.isFinite(end) ? [] : [\"an upper bound (<= or <)\"]),\n ].join(\" and \");\n throw Error(\n `Include empty dates with range \"query\" needs a bounded date filter on ${config.field}: add ${missing} as top-level filters (bounds inside OR groups do not count). Otherwise use range \"observed\" to fill from the first to the last observed date, or range \"custom\" with start and end.`,\n );\n }\n if (end < start) return undefined;\n return [\n metricDateFloor(start, config.interval, config.timeZone),\n metricDateFloor(end, config.interval, config.timeZone),\n ];\n}\n","import type { ComputedExecution } from \"./computed\";\nimport { isComputedField } from \"./computed\";\nimport {\n compileFormula,\n formulaRuntime,\n FormulaError,\n type FormulaNode,\n type FormulaPlan,\n type FormulaType,\n type FormulaValue,\n type FormulaDiagnostic,\n type FormulaResult,\n type FormulaFunction,\n} from \"./formula\";\nimport { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n indexFields,\n isFilterable,\n readFieldValue,\n resolveFieldName,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n EMPTY_QUERY,\n MAX_WHERE_CLAUSES,\n normalizeQueryState,\n predicatesOf,\n type AggregationClause,\n type AggOp,\n type QueryState,\n type WhereTerm,\n} from \"./query\";\nimport { opsForField } from \"./ops\";\nimport { applyQuery } from \"./apply\";\nimport { prepareGrouping, withoutGrouping, type GroupedRow } from \"./grouping\";\nimport { computedInputAllowed } from \"./apply\";\nimport { toServerQueryV2 } from \"./execution\";\nimport {\n toServerQuery,\n type AggregationResult,\n type AggregationBucket,\n} from \"./encode\";\nimport type { MetricQuery, MetricValue, MetricSort } from \"./metricTypes\";\nimport {\n boxSummary,\n histogramEdges,\n histogramCounts,\n} from \"./metricDistributions\";\nimport { assertMetricNumber, checkedMetricResult } from \"./metricPrecision\";\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport {\n metricDateTime,\n metricDateFloor,\n metricDateNext,\n metricDateRange,\n validateDateGrouping,\n} from \"./metricDates\";\nconst aggregates = new Set([\n \"COUNT\",\n \"COUNT_DISTINCT\",\n \"SUM\",\n \"AVG\",\n \"MIN\",\n \"MAX\",\n \"MEDIAN\",\n]);\n/** Functions available only in aggregate expressions, separate from row formulas. */\nexport const METRIC_FUNCTIONS: FormulaFunction[] = [\n [\"COUNT\", \"Count rows, or non-empty values.\"],\n [\"COUNT_DISTINCT\", \"Count distinct non-empty values.\"],\n [\"SUM\", \"Total numeric values in each group.\"],\n [\"AVG\", \"Average numeric values in each group.\"],\n [\"MIN\", \"Smallest non-empty value in each group.\"],\n [\"MAX\", \"Largest non-empty value in each group.\"],\n [\n \"MEDIAN\",\n \"Middle numeric value; averages the middle pair. Ignores empty values.\",\n ],\n].map(([name, description]) => ({\n name: name!,\n description: description!,\n signature: `${name}(row expression${name === \"COUNT\" ? \"?\" : \"\"})`,\n min: name === \"COUNT\" ? 0 : 1,\n max: 1,\n result: name === \"MIN\" || name === \"MAX\" ? \"branch\" : \"number\",\n args: [\"SUM\", \"AVG\", \"MEDIAN\"].includes(name!) ? [\"number\"] : \"any\",\n}));\nexport interface MetricPlan extends FormulaPlan {\n aggregates: Extract<FormulaNode, { kind: \"call\" }>[];\n aggregateTypes: FormulaType[];\n}\nexport function compileMetric(\n expression: string,\n schema: FieldSchema | readonly FieldDef[],\n resolve?: (name: string) => FormulaPlan | undefined,\n): MetricPlan {\n const fields: readonly FieldDef[] = Array.isArray(schema)\n ? schema\n : (schema as FieldSchema).fields;\n const nodes: MetricPlan[\"aggregates\"] = [];\n const aggregateTypes: FormulaType[] = [];\n let inAggregate = false;\n const plan = compileFormula(\n expression,\n resolve\n ? fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : fields,\n resolve,\n (node, check) => {\n if (node.kind !== \"call\" || !aggregates.has(node.name)) return undefined;\n if (inAggregate)\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n node.from,\n node.to,\n );\n if (\n node.args.length > 1 ||\n (node.name !== \"COUNT\" && node.args.length !== 1)\n )\n throw new FormulaError(\n `${node.name} requires ${node.name === \"COUNT\" ? \"zero or one argument\" : \"one argument\"}.`,\n node.from,\n node.to,\n );\n inAggregate = true;\n let type: FormulaType;\n try {\n type = node.args[0] ? check(node.args[0]) : \"number\";\n } finally {\n inAggregate = false;\n }\n const visit = (n: FormulaNode) => {\n if (n.kind === \"field\") {\n const field = fields.find((f) => f.name === n.name);\n if (!field)\n throw new FormulaError(\n `Unresolved dependency ${n.name}.`,\n n.from,\n n.to,\n );\n // MEDIAN is formula-only, so it is absent from the default AggOp\n // list. Explicit field restrictions still apply to every reduction.\n if (\n !isMeasurable(field) ||\n ((field.aggregate?.ops !== undefined ||\n (node.args[0] === n && node.name !== \"MEDIAN\")) &&\n !aggOpsForField(field).includes(node.name.toLowerCase() as AggOp))\n )\n throw new FormulaError(\n `Field ${n.name} does not allow ${node.name}.`,\n n.from,\n n.to,\n );\n } else if (n.kind === \"call\") {\n if (aggregates.has(n.name))\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n n.from,\n n.to,\n );\n n.args.forEach(visit);\n }\n };\n node.args.forEach(visit);\n if (\n [\"SUM\", \"AVG\", \"MEDIAN\"].includes(node.name) &&\n ![\"number\", \"null\"].includes(type)\n )\n throw new FormulaError(\n `${node.name} requires numeric input.`,\n node.from,\n node.to,\n );\n if (\n [\"MIN\", \"MAX\", \"COUNT_DISTINCT\"].includes(node.name) &&\n (type === \"textarray\" ||\n (type === \"bool\" && node.name !== \"COUNT_DISTINCT\"))\n )\n throw new FormulaError(\n `Unsupported ${node.name} input type.`,\n node.from,\n node.to,\n );\n nodes.push(node);\n aggregateTypes.push(type);\n return [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\", \"AVG\", \"MEDIAN\"].includes(\n node.name,\n )\n ? \"number\"\n : type;\n },\n );\n const groupCheck = (node: FormulaNode) => {\n if (node.kind === \"field\")\n throw new FormulaError(\n \"Row fields must be inside an aggregate.\",\n node.from,\n node.to,\n );\n if (node.kind === \"call\" && !aggregates.has(node.name)) {\n if (node.name.startsWith(\"REGEX_\"))\n throw new FormulaError(\n \"Regex is supported only inside aggregate row expressions.\",\n node.from,\n node.to,\n );\n node.args.forEach(groupCheck);\n }\n };\n groupCheck(plan.ast);\n if (!nodes.length)\n throw new FormulaError(\"A metric must contain an aggregate.\");\n if (plan.type === \"textarray\")\n throw new FormulaError(\"Metrics must return scalar values.\");\n return { ...plan, aggregates: nodes, aggregateTypes };\n}\n/** Row plans for worker evaluation. Null denotes COUNT(), which requires only row count. */\nexport function metricAggregatePlans(plan: MetricPlan): (FormulaPlan | null)[] {\n return plan.aggregates.map((node) => {\n if (!node.args[0]) return null;\n const dependencies = new Set<string>();\n const visit = (n: FormulaNode): void => {\n if (n.kind === \"field\") dependencies.add(n.name);\n else if (n.kind === \"call\") n.args.forEach(visit);\n };\n visit(node.args[0]);\n // Aggregate argument type is retained by the compiler in aggregateTypes.\n return {\n ast: node.args[0],\n dependencies: [...dependencies].sort(),\n type: plan.aggregateTypes[plan.aggregates.indexOf(node)]!,\n };\n });\n}\n/** Reduce exact per-row worker results; errors are not silently treated as NULL. */\nexport interface MetricReductionOptions {\n /** Retained distinct entries, independently bounded from row count. */\n maxDistinctValues?: number;\n /** Conservative UTF-16 payload plus per-entry storage estimate. */\n maxDistinctBytes?: number;\n}\nfunction distinctAccumulator(options: MetricReductionOptions) {\n const values = new Set<string | number | boolean>();\n let bytes = 0;\n const cardinality = options.maxDistinctValues ?? 100000;\n const byteLimit = options.maxDistinctBytes ?? 16000000;\n if (\n !Number.isSafeInteger(cardinality) ||\n cardinality < 0 ||\n !Number.isSafeInteger(byteLimit) ||\n byteLimit < 0\n )\n throw Error(\"Invalid distinct budget.\");\n return {\n add(value: FormulaValue) {\n const v = scalar(value);\n if (typeof v === \"number\") assertMetricNumber(v);\n if (v === null || values.has(v)) return;\n const size = 64 + (typeof v === \"string\" ? v.length * 2 : 8);\n if (values.size >= cardinality || size > byteLimit - bytes)\n throw Error(\"Metric distinct retained-memory budget exceeded.\");\n values.add(v);\n bytes += size;\n },\n result: () => ({ value: values.size }),\n };\n}\nexport function reduceMetricValues(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: readonly FormulaResult[],\n options: MetricReductionOptions = {},\n): FormulaResult {\n return reduceResults(node, results, options);\n}\nfunction reduceResults(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: Iterable<FormulaResult>,\n options: MetricReductionOptions,\n): FormulaResult {\n try {\n if (!aggregates.has(node.name)) throw Error(\"Expected an aggregate node.\");\n const distinct =\n node.name === \"COUNT_DISTINCT\" ? distinctAccumulator(options) : undefined;\n const values: FormulaValue[] = [];\n let count = 0,\n nonnull = 0,\n error: string | undefined;\n for (const r of results) {\n count++;\n if (r.error) {\n error ??= r.error;\n continue;\n }\n if (r.value === null) continue;\n if (node.name !== \"COUNT\" && !distinct && typeof r.value === \"number\")\n assertMetricNumber(r.value);\n nonnull++;\n if (distinct) distinct.add(r.value);\n else if (node.name !== \"COUNT\") values.push(r.value);\n }\n if (error) return { value: null, error };\n if (distinct) return distinct.result();\n if (node.name === \"COUNT\")\n return { value: node.args.length ? nonnull : count };\n if (!values.length) return { value: null };\n if (node.name === \"MEDIAN\") {\n const sorted = values\n .map((value) => {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw Error(\"Expected a finite number.\");\n return value;\n })\n .sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n const value =\n sorted.length % 2\n ? sorted[mid]!\n : sorted[mid - 1]! / 2 + sorted[mid]! / 2;\n assertMetricNumber(value);\n return { value };\n }\n if (node.name === \"SUM\" || node.name === \"AVG\") {\n let sum = 0;\n for (const v of values) {\n if (typeof v !== \"number\" || !Number.isFinite(v))\n throw Error(\"Expected a finite number.\");\n sum += v / (node.name === \"AVG\" ? values.length : 1);\n assertMetricNumber(sum);\n }\n return { value: sum };\n }\n return {\n value: values.reduce((a, b) =>\n compareMetricValues(scalar(a), scalar(b)) *\n (node.name === \"MIN\" ? 1 : -1) <=\n 0\n ? a\n : b,\n ),\n };\n } catch (e) {\n return { value: null, error: e instanceof Error ? e.message : String(e) };\n }\n}\n/** Evaluate the group AST lazily from reductions indexed like plan.aggregates.\n * A dead IF/COALESCE branch does not observe a failed aggregate in that branch. */\nexport function evaluateMetricReductions(\n plan: MetricPlan,\n reductions: readonly FormulaResult[],\n): FormulaResult {\n const key = (n: FormulaNode) =>\n `${n.from}:${n.to}:${n.kind === \"call\" ? n.name : n.kind}`;\n const byNode = new Map(\n plan.aggregates.map((n, i) => [key(n), reductions[i]]),\n );\n return checkedMetricResult(\n formulaRuntime(plan.ast, {}, (node) =>\n byNode.has(key(node))\n ? checkedMetricResult(\n byNode.get(key(node)) ?? {\n value: null,\n error: \"Missing aggregate reduction.\",\n },\n )\n : undefined,\n ),\n );\n}\nexport function metricExpression(clause: AggregationClause): string {\n return (\n clause.expression ??\n `${clause.op.toUpperCase()}(${clause.field ? `[${clause.field.replace(/]/g, \"]]\")}]` : \"\"})`\n );\n}\nexport function hasRegex(plan: FormulaPlan): boolean {\n const visit = (n: FormulaNode): boolean =>\n n.kind === \"call\" && (n.name.startsWith(\"REGEX_\") || n.args.some(visit));\n return visit(plan.ast);\n}\nfunction distributionActive(c: AggregationClause): boolean {\n return (\n !!c.distribution &&\n (!c.display || c.display.kind === \"box\" || c.display.kind === \"histogram\")\n );\n}\nexport function metricPlans(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaPlan[] {\n if (distributionActive(c)) {\n const p = compileFormula(\n c.distribution!.input,\n resolve\n ? schema.fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : schema.fields,\n resolve,\n );\n if (p.type !== \"number\" && p.type !== \"null\")\n throw new FormulaError(\"Distribution input must be numeric.\");\n if (![\"box\", \"histogram\"].includes(c.distribution!.kind))\n throw new FormulaError(\"Invalid distribution kind.\");\n if (\n c.distribution!.kind === \"histogram\" &&\n (!Number.isInteger(c.distribution!.bins ?? 10) ||\n (c.distribution!.bins ?? 10) < 2 ||\n (c.distribution!.bins ?? 10) > 30)\n )\n throw new FormulaError(\"Choose 2–30 histogram bins.\");\n for (const name of p.dependencies) {\n const field = schema.fields.find((f) => f.name === name)!;\n if (!isMeasurable(field))\n throw new FormulaError(`Field ${name} cannot be a distribution input.`);\n }\n if (c.scope !== \"shownRows\" && hasRegex(p))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return [p];\n }\n const out = [\n compileMetric(\n metricExpression(\n c.expression === undefined && c.field\n ? { ...c, field: resolveFieldName(schema, c.field) ?? c.field }\n : c,\n ),\n schema,\n resolve,\n ),\n ];\n if (c.display?.kind === \"scatter\") {\n out.push(compileMetric(c.expressionY ?? \"\", schema, resolve));\n if (out.some((p) => p.type !== \"number\" && p.type !== \"null\"))\n throw new FormulaError(\"Scatter expressions must be numeric.\");\n }\n if (c.scope !== \"shownRows\" && out.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return out;\n}\nexport function validateMetric(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaDiagnostic[] {\n try {\n if (c.diagnostics?.length) throw new FormulaError(c.diagnostics.join(\" \"));\n if (c.groupBy.length > 20)\n throw new FormulaError(\"At most 20 grouping fields are allowed.\");\n for (const key of c.groupBy) {\n const f = schema.fields.find(\n (f) => f.name === (resolveFieldName(schema, key) ?? key),\n );\n if (!f || !isGroupable(f))\n throw new FormulaError(`Field ${key} cannot group metrics.`);\n }\n if (c.dateGrouping) {\n validateDateGrouping(c.dateGrouping);\n const field =\n resolveFieldName(schema, c.dateGrouping.field) ?? c.dateGrouping.field;\n if (\n field !==\n (resolveFieldName(schema, c.groupBy[0] ?? \"\") ?? c.groupBy[0]) ||\n schema.fields.find((f) => f.name === field)?.type !== \"datetime\"\n )\n throw new FormulaError(\n \"Date grouping must use the first grouping field, with a datetime type.\",\n );\n if (distributionActive(c))\n throw new FormulaError(\n \"Date grouping currently supports scalar metrics, not distributions.\",\n );\n }\n if (\n c.groupLimit !== undefined &&\n (!Number.isInteger(c.groupLimit) ||\n c.groupLimit < 1 ||\n c.groupLimit > 10000)\n )\n throw new FormulaError(\"Group limit must be 1–10,000.\");\n if (c.minCount !== undefined) {\n if (\n !Number.isInteger(c.minCount) ||\n c.minCount < 1 ||\n c.minCount > 1000000\n )\n throw new FormulaError(\"Minimum rows per group must be 1–1,000,000.\");\n if (!c.groupBy.length)\n throw new FormulaError(\n \"Minimum rows per group requires at least one grouping field.\",\n );\n }\n validateMetricWhere(c.where, schema);\n for (const s of c.sort ?? []) {\n if (s.key === \"y\" && c.display?.kind !== \"scatter\")\n throw new FormulaError(\"Y sorting requires a scatter metric.\");\n if (s.key === \"samples\" && !distributionActive(c))\n throw new FormulaError(\n \"Sample sorting requires a distribution metric.\",\n );\n if (\n s.key.startsWith(\"group\") &&\n Number(s.key.slice(5)) >= c.groupBy.length\n )\n throw new FormulaError(\"Sort refers to an unavailable grouping key.\");\n }\n const compiled = metricPlans(c, schema, resolve);\n if (c.scope !== \"shownRows\" && compiled.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return [];\n } catch (e) {\n return [\n {\n message: e instanceof Error ? e.message : String(e),\n from: e instanceof FormulaError ? e.from : 0,\n to: e instanceof FormulaError ? e.to : 1,\n },\n ];\n }\n}\n/** A metric WHERE follows the table WHERE's allowlist and operators. Regex is\n * refused on every engine; local computed inputs need filter authority. */\nfunction validateMetricWhere(\n where: readonly WhereTerm[] | undefined,\n schema: FieldSchema,\n): void {\n if (where === undefined) return;\n if (!Array.isArray(where)) throw new FormulaError(\"Invalid metric filter.\");\n const predicates = where.flatMap((term) => predicatesOf(term));\n if (predicates.length > MAX_WHERE_CLAUSES)\n throw new FormulaError(\n `A metric filter allows at most ${MAX_WHERE_CLAUSES} predicates.`,\n );\n const fields = indexFields(schema);\n for (const p of predicates) {\n const name = resolveFieldName(schema, p.field) ?? p.field;\n const field = fields.get(name);\n if (\n !field ||\n !isFilterable(field) ||\n (isComputedField(name) && !computedInputAllowed(schema, name, \"filter\"))\n )\n throw new FormulaError(`Field ${p.field} cannot filter metrics.`);\n if (p.op === \"matches_regex\" || p.op === \"not_matches_regex\")\n throw new FormulaError(\"Regex is unavailable in metric filters.\");\n if (!opsForField(field).includes(p.op))\n throw new FormulaError(\n `Field ${p.field} does not support the ${p.op} filter.`,\n );\n }\n}\n/** Executor support for population controls, from either capability handshake. */\nexport interface MetricPopulationSupport {\n filters?: boolean | undefined;\n minCount?: boolean | undefined;\n}\n/** A clause the executor cannot run exactly gets its own error; it is never\n * sent with `where`/`minCount` silently dropped. */\nexport function metricPopulationError(\n clause: Pick<AggregationClause, \"where\" | \"minCount\">,\n support: MetricPopulationSupport,\n): string | undefined {\n if (clause.where?.length && !support.filters)\n return \"This server does not support metric filters.\";\n if (clause.minCount !== undefined && !support.minCount)\n return \"This server does not support a minimum rows per group.\";\n return undefined;\n}\nexport function metricDependencies(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): string[] {\n return [\n ...new Set([\n ...c.groupBy.map((name) => resolveFieldName(schema, name) ?? name),\n ...metricPlans(c, schema, resolve).flatMap((p) => p.dependencies),\n ]),\n ].sort();\n}\nexport function metricComputationKey(\n clauses: readonly AggregationClause[],\n): string {\n return JSON.stringify(\n clauses\n .map((c) => ({\n id: c.id,\n diagnostics: c.diagnostics,\n unsupportedOp: c.unsupportedOp,\n expression: distributionActive(c) ? undefined : metricExpression(c),\n expressionY: c.display?.kind === \"scatter\" ? c.expressionY : undefined,\n scope: c.scope ?? \"allMatching\",\n groupBy: c.groupBy,\n dateGrouping: c.dateGrouping,\n sort: c.sort,\n groupLimit: c.groupLimit,\n where: c.where,\n minCount: c.minCount,\n distribution: distributionActive(c) ? c.distribution : undefined,\n }))\n .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)),\n );\n}\nexport function toMetricQuery<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution?: ComputedExecution,\n): MetricQuery {\n const originalSchema = schema;\n const fields = new Map(schema.fields.map((f) => [f.name, f]));\n // A local computed field never establishes remote authority.\n for (const [name, prior] of fields)\n if (isComputedField(name))\n fields.set(name, {\n ...prior,\n aggregate: { measure: false, groupable: false },\n });\n for (const [name, cap] of Object.entries(execution?.fields ?? {}))\n if (isComputedField(name)) {\n const prior = fields.get(name);\n fields.set(name, {\n ...prior,\n name,\n label: prior?.label ?? name,\n type: cap.type,\n source: { kind: \"backend\" },\n filter: { enabled: false },\n sort: { enabled: cap.sort },\n aggregate: {\n ...prior?.aggregate,\n measure: cap.measure,\n groupable: cap.group,\n },\n });\n }\n schema = { ...schema, fields: [...fields.values()] };\n const raw = q;\n q = normalizeQueryState(q);\n const server = toServerQuery(q, schema);\n const metricWhere = new Map<string, WhereTerm[]>();\n for (const c of q.aggregations ?? [])\n if (c.where?.length) {\n const pushed = toServerQuery({ ...EMPTY_QUERY, where: c.where }, schema)\n .where;\n metricWhere.set(c.id, pushed);\n }\n const metrics = (q.aggregations ?? []).map((c) => {\n const {\n label,\n layout,\n display,\n distribution,\n expression,\n expressionY,\n dateGrouping,\n where,\n ...rest\n } = c;\n return {\n ...rest,\n ...(where?.length ? { where: metricWhere.get(c.id) ?? [] } : {}),\n ...(!distributionActive(c) && expression !== undefined\n ? { expression }\n : {}),\n ...(display?.kind === \"scatter\"\n ? {\n display: { kind: \"scatter\" as const },\n ...(expressionY !== undefined ? { expressionY } : {}),\n }\n : {}),\n ...(distributionActive(c) && distribution ? { distribution } : {}),\n };\n });\n const diagnostics = (q.aggregations ?? []).flatMap((c) =>\n validateMetric(c, schema).map((d) => ({\n ...d,\n metricId: c.id,\n code: \"invalid_metric\",\n })),\n );\n for (const c of q.aggregations ?? [])\n if (c.where?.length && metricWhere.get(c.id)?.length !== c.where.length)\n diagnostics.push({\n metricId: c.id,\n code: \"residual_metric_filter\",\n from: 0,\n to: 1,\n message: \"Metric filters must use server-filterable fields.\",\n });\n for (const c of q.aggregations ?? [])\n if (c.dateGrouping)\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_date_grouping\",\n from: 0,\n to: 1,\n message: \"Date grouping currently requires local metric execution.\",\n });\n try {\n assertMetricQueryState(raw, originalSchema);\n } catch (e) {\n diagnostics.push({\n message: String(e),\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"invalid_query\",\n });\n }\n const ids = new Set<string>();\n for (const c of q.aggregations ?? []) {\n if (ids.has(c.id))\n diagnostics.push({\n message: \"Duplicate metric ID.\",\n from: 0,\n to: 1,\n metricId: c.id,\n code: \"duplicate_metric\",\n });\n ids.add(c.id);\n }\n if (\n server.where.length !== q.where.length ||\n queryStateKey(raw.where) !== queryStateKey(q.where)\n )\n diagnostics.push({\n message: \"Metrics unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"residual_filter\",\n });\n for (const c of q.aggregations ?? []) {\n try {\n for (const name of metricDependencies(c, schema))\n if (isComputedField(name)) {\n const revision =\n execution?.resolvedRevisions[name] ??\n execution?.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (\n typeof revision !== \"string\" ||\n !revision ||\n revision.length > 256\n )\n diagnostics.push({\n metricId: c.id,\n code: \"definition_revision\",\n message: `Missing expected revision for ${name}.`,\n from: 0,\n to: 1,\n });\n if (!execution?.fields[name])\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_computed\",\n message: `Missing server capability for ${name}.`,\n from: 0,\n to: 1,\n });\n }\n } catch {\n /* compilation diagnostic already included */\n }\n }\n // Row and metric page membership share effective defaults and v2 gates.\n const rowProjection = toServerQueryV2(\n { ...q, select: [{ field: schema.idField }] },\n originalSchema,\n execution ?? {\n profile: \"\",\n planToken: \"\",\n fields: {},\n resolvedRevisions: {},\n },\n );\n if (q.aggregations?.some((c) => c.scope === \"shownRows\"))\n diagnostics.push(\n ...rowProjection.diagnostics.map((d) => ({\n ...d,\n metricId: \"\",\n code: d.code ?? \"residual_order\",\n })),\n );\n return {\n version: 2,\n where: server.where,\n orderBy: rowProjection.orderBy,\n limit: q.limit,\n offset: q.offset,\n metrics,\n diagnostics,\n ...(execution\n ? {\n profile: execution.profile,\n expectedRevisions: { ...execution.resolvedRevisions },\n planToken: execution.planToken,\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n }\n : {}),\n };\n}\nfunction queryStateKey(value: unknown): string | undefined {\n return JSON.stringify(value, (_key, item: unknown) =>\n item && typeof item === \"object\" && !Array.isArray(item)\n ? Object.fromEntries(\n Object.entries(item).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n )\n : item,\n );\n}\n/** Reject normalization losses before claiming an exact population. */\nfunction assertMetricQueryState<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n): void {\n const normalized = normalizeQueryState(q);\n if ((q.aggregations?.length ?? 0) !== (normalized.aggregations?.length ?? 0))\n throw Error(\"Malformed metric definitions cannot be dropped.\");\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n const normalizedOrder = normalizeQueryState({ ...q, orderBy }).orderBy;\n if (\n queryStateKey(q.where) !== queryStateKey(normalized.where) ||\n queryStateKey(orderBy) !== queryStateKey(normalizedOrder) ||\n q.limit !== normalized.limit ||\n q.offset !== normalized.offset\n )\n throw Error(\"Malformed metric query state cannot be executed exactly.\");\n}\n/** Safe pre-worker page selection. A supplied committed page needs no query execution.\n * Query regex is never executed here; all-matching regex filtering is unsupported. */\nexport function selectMetricShownRows<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): Row[] {\n if (options.signal?.aborted) throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if (options.shownRows) return options.shownRows;\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n assertMetricPopulation(q, schema, orderBy);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n if ((options.maxOperations ?? 10000000) <= 0)\n throw Error(\"Metric operation budget exceeded.\");\n return applyQuery(\n rows,\n // Local tables use a stable sort: ties retain input order. An extra ID\n // sort here would choose a different page than the one the table shows.\n { ...q, orderBy },\n schema,\n options,\n ).rows;\n}\nfunction assertMetricPopulation<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n orderBy: QueryState[\"orderBy\"],\n): void {\n const fields = indexFields(schema);\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n ) ||\n orderBy.some((s) => s.extract !== undefined)\n )\n throw Error(\n \"Query regex requires isolated execution; unavailable for metric population selection.\",\n );\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) =>\n isComputedField(p.field) && !computedInputAllowed(schema, p.field, \"filter\") ||\n !fields.has(resolveFieldName(schema, p.field) ?? p.field),\n ),\n )\n )\n throw Error(\"Metric filter references an unavailable field.\");\n if (\n orderBy.some(\n (s) =>\n isComputedField(s.field) && !computedInputAllowed(schema, s.field, \"sort\") ||\n !fields.has(resolveFieldName(schema, s.field) ?? s.field),\n )\n )\n throw Error(\"Shown-row ordering requires an authoritative committed page.\");\n}\nexport interface MetricEvaluationOptions<Row = unknown>\n extends QueryEvaluationOptions,\n MetricReductionOptions {\n resolveComputed?: (name: string) => FormulaPlan | undefined;\n /** Called only for regex row ASTs, using cached results from a terminable worker. */\n evaluateInput?: (\n node: FormulaNode,\n row: Row,\n plan: FormulaPlan,\n ) => FormulaResult;\n /** Exact committed page supplied by the host after filters/order/window. */\n /** Escaped tuple length bound, in UTF-16 code units (default 65,536). */\n maxGroupKeyLength?: number;\n /** Retained group keys, map/bucket overhead and row references, plus key scratch space (default 16 MB). */\n maxGroupBytes?: number;\n shownRows?: Row[];\n maxRows?: number;\n maxGroups?: number;\n /** Per-metric operation budget (default 10,000,000, allowing simple paired\n * aggregates across the default one-million-row population limit). */\n maxOperations?: number;\n /** @deprecated Regex requires cached evaluateInput; this flag grants no execution permission. */ allowRegex?: boolean;\n signal?: AbortSignal;\n}\nconst scalar = (v: unknown): MetricValue => {\n if (v instanceof Date) return v.toISOString();\n if (v == null) return null;\n if (\n typeof v === \"string\" ||\n typeof v === \"boolean\" ||\n (typeof v === \"number\" && Number.isFinite(v))\n )\n return v;\n throw Error(\"Metric keys and values must be finite scalars.\");\n};\n/** JSON string length without allocating escaped text; scan only bounded input. */\nfunction groupStringLength(value: string, limit: number): number {\n let length = value.length + 2;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (\n code === 34 ||\n code === 92 ||\n code === 8 ||\n code === 9 ||\n code === 10 ||\n code === 12 ||\n code === 13\n )\n length++;\n else if (code < 32) length += 5;\n else if (\n code >= 0xd800 &&\n code <= 0xdbff &&\n i + 1 < value.length &&\n value.charCodeAt(i + 1) >= 0xdc00 &&\n value.charCodeAt(i + 1) <= 0xdfff\n )\n i++;\n else if (code >= 0xd800 && code <= 0xdfff) length += 5;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n return length;\n}\n/** Typed lexicographic ordering with null placement independent of direction. */\nexport function compareMetricValues(a: MetricValue, b: MetricValue): number {\n if (a === b) return 0;\n if (a === null) return 1;\n if (b === null) return -1;\n if (typeof a !== typeof b) return typeof a < typeof b ? -1 : 1;\n if (typeof a === \"string\" && typeof b === \"string\") {\n const ac = Array.from(a),\n bc = Array.from(b);\n for (let i = 0; i < Math.min(ac.length, bc.length); i++) {\n const diff = ac[i]!.codePointAt(0)! - bc[i]!.codePointAt(0)!;\n if (diff) return Math.sign(diff);\n }\n return Math.sign(ac.length - bc.length);\n }\n return a < b ? -1 : 1;\n}\nexport function evaluateMetrics<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) {\n try {\n if (options.signal?.aborted) throw new Error(\"Metric evaluation cancelled.\");\n if (rows.length > (options.maxRows ?? 1_000_000)) throw new Error(\"Metric row budget exceeded.\");\n const now = evaluationTime(options);\n const prepared = prepareGrouping(rows, schema, q.grouping, { now });\n return evaluateMetrics(prepared.rows, withoutGrouping(q), prepared.schema, {\n ...options, now,\n } as unknown as MetricEvaluationOptions<GroupedRow>);\n } catch (error) {\n return { metrics: (q.aggregations ?? []).map(metric => ({ id: metric.id, buckets: [], error: error instanceof Error ? error.message : String(error) })) };\n }\n }\n const now = evaluationTime(options),\n fields = indexFields(schema);\n let matching: Row[] | undefined;\n let shown: Row[] | undefined;\n return {\n metrics: (q.aggregations ?? []).map((c) => {\n let budget = options.maxOperations ?? 10000000;\n const tick = () => {\n if (--budget < 0) throw Error(\"Metric operation budget exceeded.\");\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n };\n try {\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if ((q.aggregations?.length ?? 0) > 20)\n throw Error(\"At most 20 metrics are allowed.\");\n const diagnostics = validateMetric(c, schema, options.resolveComputed);\n if (diagnostics.length)\n throw Error(diagnostics.map((d) => d.message).join(\" \"));\n const ps = metricPlans(c, schema, options.resolveComputed);\n if (ps.some(hasRegex) && !options.evaluateInput)\n throw Error(\n \"Regex metrics require an isolated worker with a watchdog.\",\n );\n let inputRows: Row[];\n if (c.scope === \"shownRows\")\n inputRows = shown ??= selectMetricShownRows(rows, q, schema, options);\n else {\n if (!matching) {\n assertMetricPopulation(q, schema, []);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n matching = applyQuery(\n rows,\n { ...q, orderBy: [], offset: 0, limit: Number.MAX_SAFE_INTEGER },\n schema,\n { now },\n ).rows;\n }\n inputRows = matching;\n }\n if (inputRows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n // processedRows retains the scope population; this metric's own\n // predicate narrows the rows it reduces, inside a shown page as well.\n const population = inputRows.length;\n if (c.where?.length)\n inputRows = applyQuery(\n inputRows,\n {\n ...EMPTY_QUERY,\n where: c.where,\n limit: Number.MAX_SAFE_INTEGER,\n },\n schema,\n { now },\n ).rows;\n const groups = new Map<string, { keys: MetricValue[]; rows: Row[] }>();\n const keyLimit = options.maxGroupKeyLength ?? 65536,\n byteLimit = options.maxGroupBytes ?? 16000000;\n if (\n ![keyLimit, byteLimit].every((v) => Number.isSafeInteger(v) && v >= 0)\n )\n throw Error(\"Invalid grouping budget.\");\n let groupBytes = 0;\n const reserve = (bytes: number) => {\n if (bytes > byteLimit - groupBytes)\n throw Error(\"Metric grouping retained-memory budget exceeded.\");\n };\n if (!c.groupBy.length) {\n if (keyLimit < 2)\n throw Error(\"Metric grouping key length budget exceeded.\");\n reserve(256);\n groupBytes = 256;\n groups.set(\"[]\", { keys: [], rows: [] });\n }\n // Retain only the most recent calendar interval. Dense timestamp rows\n // share its boundaries and ISO key without repeating timezone work.\n // The half-open interval also separates repeated/partial DST hours;\n // out-of-order rows outside it always recompute the correct bucket.\n let dateStart = Infinity,\n dateEnd = -Infinity,\n dateKey = \"\";\n let dateInput: MetricValue | undefined,\n dateTime = NaN;\n for (const row of inputRows) {\n tick();\n if (!c.groupBy.length) {\n reserve(16);\n groupBytes += 16;\n groups.get(\"[]\")!.rows.push(row);\n continue;\n }\n const keys = c.groupBy.map((k) =>\n scalar(\n readFieldValue(\n fields.get(resolveFieldName(schema, k) ?? k)!,\n row,\n ),\n ),\n );\n if (c.dateGrouping && keys[0] !== null) {\n const config = c.dateGrouping;\n // Repeated date-only values would otherwise resolve local midnight\n // through Temporal for every row as well.\n if (keys[0] !== dateInput) {\n dateTime = metricDateTime(keys[0]!, config.timeZone);\n dateInput = keys[0];\n }\n if (dateTime < dateStart || dateTime >= dateEnd) {\n dateStart = metricDateFloor(\n dateTime,\n config.interval,\n config.timeZone,\n );\n dateEnd = metricDateNext(\n dateStart,\n config.interval,\n config.timeZone,\n );\n dateKey = new Date(dateStart).toISOString();\n }\n keys[0] = dateKey;\n }\n // Measure escaping without allocating a serialized key. Check BEFORE\n // stringify: shared source strings must not amplify into unbounded map keys. Charge source payload again\n // per group, even if shared, plus tuple slots, buckets and map overhead.\n let keyLength = 1,\n payloadBytes = 0;\n for (const value of keys) {\n keyLength +=\n 1 +\n (typeof value === \"string\"\n ? groupStringLength(value, keyLimit - keyLength - 1)\n : value === null\n ? 4\n : typeof value === \"boolean\"\n ? value\n ? 4\n : 5\n : String(value).length);\n payloadBytes += typeof value === \"string\" ? 2 * value.length : 8;\n if (keyLength > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n const retainedBytes =\n 256 + 16 * keys.length + payloadBytes + 2 * keyLength;\n // Reserve a candidate group plus serialization scratch, even for a\n // duplicate; this deliberately conservative check needs no large key.\n reserve(retainedBytes + 2 * keyLength + 16);\n const key = JSON.stringify(keys);\n let g = groups.get(key);\n if (!g) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n g = { keys, rows: [] };\n groups.set(key, g);\n groupBytes += retainedBytes;\n }\n groupBytes += 16;\n g.rows.push(row);\n }\n if (c.dateGrouping?.includeEmpty) {\n const config = c.dateGrouping;\n const observed: number[] = [];\n const series = new Map<string, MetricValue[]>();\n for (const group of groups.values())\n if (group.keys[0] !== null) {\n tick();\n reserve(8);\n groupBytes += 8;\n observed.push(metricDateTime(group.keys[0]!));\n const tuple = group.keys.slice(1);\n const key = JSON.stringify(tuple);\n if (!series.has(key)) {\n const bytes = 128 + 16 * tuple.length + 2 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n series.set(key, tuple);\n }\n }\n if (c.groupBy.length === 1 && !series.size) {\n reserve(132);\n groupBytes += 132;\n series.set(\"[]\", []);\n }\n const range = metricDateRange(\n config,\n q,\n observed,\n now,\n (name) => resolveFieldName(schema, name) ?? name,\n );\n if (range)\n for (let time = range[0]; time <= range[1]; ) {\n tick();\n for (const tuple of series.values()) {\n tick();\n const keys: MetricValue[] = [\n new Date(time).toISOString(),\n ...tuple,\n ];\n const key = JSON.stringify(keys);\n if (key.length > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n if (!groups.has(key)) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n const bytes = 256 + 16 * keys.length + 4 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n groups.set(key, { keys, rows: [] });\n }\n }\n const next = metricDateNext(\n time,\n config.interval,\n config.timeZone,\n );\n if (!Number.isFinite(next) || next <= time)\n throw Error(\"Date grouping exceeds calendar limits.\");\n time = next;\n }\n }\n const inputs = (\n row: Row,\n p: FormulaPlan,\n ): Record<string, FormulaValue> =>\n Object.fromEntries(\n p.dependencies.map((name) => [\n name,\n (() => {\n const value = readFieldValue(fields.get(name)!, row);\n return value instanceof Date\n ? value.toISOString()\n : (value ?? null);\n })(),\n ]),\n ) as Record<string, FormulaValue>;\n const nodeCosts = new Map<FormulaNode, number>();\n const cost = (n: FormulaNode): number => {\n const known = nodeCosts.get(n);\n if (known !== undefined) return known;\n const value =\n 1 +\n (n.kind === \"call\" ? n.args.reduce((s, a) => s + cost(a), 0) : 0);\n nodeCosts.set(n, value);\n return value;\n };\n const rowEval = (node: FormulaNode, row: Row, p: FormulaPlan) => {\n budget -= cost(node);\n tick();\n // A direct aggregate input needs only its own binding, even when the\n // composed metric reaches many other fields. Keep runtime validation.\n if (node.kind === \"field\") {\n const value = readFieldValue(fields.get(node.name)!, row);\n return formulaRuntime(node, {\n [node.name]:\n value instanceof Date\n ? value.toISOString()\n : ((value ?? null) as FormulaValue),\n });\n }\n return options.evaluateInput && hasRegex({ ...p, ast: node })\n ? options.evaluateInput(node, row, p)\n : formulaRuntime(node, inputs(row, p));\n };\n const reduce = (\n p: FormulaPlan,\n rs: Row[],\n inputErrors: Set<number>,\n ): FormulaResult => {\n const cache = new Map<FormulaNode, FormulaResult>();\n return checkedMetricResult(\n formulaRuntime(p.ast, {}, (node) => {\n if (!aggregates.has(node.name)) return undefined;\n if (cache.has(node)) return cache.get(node)!;\n let result: FormulaResult;\n try {\n function* results(): Generator<FormulaResult> {\n for (let i = 0; i < rs.length; i++) {\n tick();\n const v = node.args[0]\n ? rowEval(node.args[0], rs[i]!, p)\n : { value: 1 };\n if (v.error) inputErrors.add(i);\n yield v;\n }\n }\n result = reduceResults(node, results(), options);\n } catch (e) {\n result = {\n value: null,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n cache.set(node, result);\n return result;\n }),\n );\n };\n const populations = new Map<AggregationBucket, number[]>();\n let buckets: AggregationBucket[] = [...groups.values()].map((g) => {\n const bucket: AggregationBucket = {\n keys: g.keys,\n count: g.rows.length,\n value: null,\n };\n if (distributionActive(c)) {\n const values: number[] = [];\n bucket.nullCount = 0;\n bucket.inputErrorCount = 0;\n for (const row of g.rows) {\n const r = checkedMetricResult(rowEval(ps[0]!.ast, row, ps[0]!));\n if (r.error) {\n bucket.inputErrorCount++;\n bucket.error = r.error;\n } else if (r.value === null) bucket.nullCount++;\n else values.push(Number(r.value));\n }\n populations.set(bucket, values);\n } else {\n if (c.dateGrouping && !g.rows.length) {\n const empty = (p: FormulaPlan) =>\n p.ast.kind === \"call\" &&\n [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\"].includes(p.ast.name)\n ? 0\n : null;\n bucket.value = empty(ps[0]!);\n if (ps[1]) bucket.y = empty(ps[1]);\n return bucket;\n }\n const inputErrors = new Set<number>();\n const x = reduce(ps[0]!, g.rows, inputErrors);\n bucket.value = scalar(x.value);\n if (x.error) bucket.error = x.error;\n if (ps[1]) {\n const y = reduce(ps[1], g.rows, inputErrors);\n bucket.y = scalar(y.value);\n if (y.error) bucket.yError = y.error;\n }\n if (inputErrors.size) bucket.inputErrorCount = inputErrors.size;\n }\n return bucket;\n });\n if (distributionActive(c)) {\n const d = c.distribution!;\n if (d.kind === \"histogram\" && buckets.some((b) => b.error))\n throw Error(\n \"Histogram input errors prevent an exact shared extent.\",\n );\n const all: number[] = [];\n for (const values of populations.values())\n for (const v of values) all.push(v);\n const edges =\n d.kind === \"histogram\" ? histogramEdges(all, d.bins ?? 10) : [];\n for (const b of buckets) {\n const vs = populations.get(b)!;\n if (b.error) continue;\n if (d.kind === \"box\") {\n const summary = boxSummary(vs, d.whiskers);\n b.distribution = { kind: \"box\", summary };\n b.value = summary?.median ?? null;\n } else {\n b.distribution = {\n kind: \"histogram\",\n edges: [...edges],\n counts: histogramCounts(vs, edges),\n n: vs.length,\n };\n b.value = vs.length;\n }\n }\n }\n // Calendar fill-ins are the only empty groups; they are never hidden.\n // Hidden groups leave the ranking, the result limit and Other.\n let hiddenGroups: number | undefined;\n if (c.minCount !== undefined) {\n const kept = buckets.filter(\n (b) => b.count === 0 || b.count >= c.minCount!,\n );\n hiddenGroups = buckets.length - kept.length;\n buckets = kept;\n }\n const ordering: MetricSort[] = c.sort?.length\n ? c.sort\n : c.dateGrouping\n ? [{ key: \"group0\", dir: \"asc\", nulls: \"last\" }]\n : [{ key: \"value\", dir: \"desc\", nulls: \"last\" }];\n const target = (b: AggregationBucket, s: MetricSort): MetricValue =>\n s.key === \"samples\"\n ? b.count - (b.nullCount ?? 0) - (b.inputErrorCount ?? 0)\n : s.key.startsWith(\"group\")\n ? (b.keys[Number(s.key.slice(5))] ?? null)\n : s.key === \"count\"\n ? b.count\n : s.key === \"y\"\n ? (b.y ?? null)\n : b.value;\n buckets.sort((a, b) => {\n if (!!(a.error || a.yError) !== !!(b.error || b.yError))\n return a.error || a.yError ? 1 : -1;\n for (const s of ordering) {\n const av = target(a, s),\n bv = target(b, s);\n const cmp =\n av === null || bv === null\n ? av === bv\n ? 0\n : (av === null ? 1 : -1) * (s.nulls === \"first\" ? -1 : 1)\n : compareMetricValues(av, bv) * (s.dir === \"asc\" ? 1 : -1);\n if (cmp) return cmp;\n }\n for (let i = 0; i < a.keys.length; i++) {\n const cmp = compareMetricValues(a.keys[i]!, b.keys[i]!);\n if (cmp) return cmp;\n }\n return 0;\n });\n tick();\n const groupCount = buckets.length;\n let other: AggregationBucket | undefined;\n if (c.groupLimit && buckets.length > c.groupLimit) {\n const omitted = buckets.slice(c.groupLimit),\n ast = ps[0]!.ast;\n if (\n !distributionActive(c) &&\n ast.kind === \"call\" &&\n [\"SUM\", \"COUNT\"].includes(ast.name) &&\n omitted.every(\n (b) =>\n !b.error &&\n (typeof b.value === \"number\" ||\n (ast.name === \"SUM\" && b.value === null)),\n )\n ) {\n const value = omitted.reduce((s, b) => s + Number(b.value), 0);\n if (\n Number.isFinite(value) &&\n (!Number.isInteger(value) || Number.isSafeInteger(value))\n )\n other = {\n keys: [],\n value,\n count: omitted.reduce((s, b) => s + b.count, 0),\n };\n }\n buckets = buckets.slice(0, c.groupLimit);\n }\n return {\n id: c.id,\n buckets,\n scope: c.scope ?? \"allMatching\",\n processedRows: population,\n groupCount,\n coverage: \"exact\" as const,\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n ...(other ? { other } : {}),\n };\n } catch (e) {\n return {\n id: c.id,\n buckets: [],\n error: e instanceof Error ? e.message : String(e),\n };\n }\n }),\n };\n}\n","import { aggOpsForField, isMeasurable } from \"./agg\";\nimport type { MetricKey } from \"./metricTypes\";\nimport { evaluateMetrics, type MetricEvaluationOptions } from \"./metrics\";\n// apply.ts — client-side filter + multi-sort + paginate.\n//\n// applyQuery is the client mirror of the backend compiler. Three jobs:\n// 1. The executor for purely client-side datasets (no backend at all).\n// 2. The executor for derived / non-pushdown columns the backend can't filter.\n// 3. Idempotent defense-in-depth over server-filtered fields (re-applying a\n// server-handled clause must not change the result).\n//\n// It must agree with backends/go's Compile on operator semantics:\n// - `contains`/`starts_with`/`ends_with` are case-insensitive\n// - textarray `is_null` = empty-or-missing; `is_not_null` = any element;\n// `includes` = case-insensitive membership\n// - NULLs sort per OrderByClause.nulls (default \"last\")\n// - multi-sort is a stable lexicographic fold over orderBy in priority order\n\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport { isComputedField } from \"./computed\";\nimport type {\n AggOp,\n AggregationClause,\n QueryState,\n WhereClause,\n WhereTerm,\n} from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { AggregationBucket, AggregationResult } from \"./encode\";\nimport { indexFields, readFieldValue, resolveFieldName } from \"./schema\";\nimport { isOrGroup, predicatesOf, normalizeQueryState } from \"./query\";\nimport { coerceValue } from \"./ops\";\nimport { prepareGrouping, withoutGrouping } from \"./grouping\";\n\nexport interface ApplyResult<Row> {\n /** The page slice (after filter + sort + offset/limit). */\n rows: Row[];\n /** Total matching rows *before* pagination — powers \"showing N of M\". */\n total: number;\n}\n\n/** Filter + multi-sort + paginate `rows` per `q`, resolving field types/paths\n * from `schema`. Never mutates `rows`. Relative predicates use options.now or\n * one captured Date.now(). Clauses/sorts on unknown fields are\n * ignored (the backend already enforced its own allowlist). */\nexport function applyQuery<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): ApplyResult<Row> {\n const now = evaluationTime(options);\n if (q.grouping) {\n const grouped = prepareGrouping(rows, schema, q.grouping, { now });\n // Grouped results are projections described by grouped.schema; they do not\n // retain source-row accessors or identities.\n return applyQuery(grouped.rows, withoutGrouping(q), grouped.schema, { now }) as ApplyResult<Row>;\n }\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n // Terms touching a computed column are dropped here (the formula engine\n // evaluates those separately; `byName` has no opinion on them anyway). An OR\n // group is all-or-nothing, so a single computed member drops the whole term.\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field) && !computedInputAllowed(schema, c.field, \"filter\")))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const orderBy = q.orderBy\n .filter((term) => !isComputedField(term.field) || computedInputAllowed(schema, term.field, \"sort\"))\n .map((term) => ({ ...term, field: resolveField(term.field) }));\n\n let out = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const total = out.length;\n\n if (orderBy.length) {\n const terms = orderBy\n .map((t) => ({\n field: byName.get(t.field),\n dir: t.dir,\n nullsLast: (t.nulls ?? \"last\") === \"last\",\n extract: compileRegex(t.extract?.regex),\n }))\n .filter(\n (\n t,\n ): t is {\n field: FieldDef<Row>;\n dir: \"asc\" | \"desc\";\n nullsLast: boolean;\n extract: RegExp | null | undefined;\n } => t.field != null,\n );\n out = [...out].sort((a, b) => {\n for (const t of terms) {\n const av = extractSortValue(readFieldValue(t.field, a), t.extract);\n const bv = extractSortValue(readFieldValue(t.field, b), t.extract);\n const aNull = av == null;\n const bNull = bv == null;\n if (aNull || bNull) {\n if (aNull && bNull) continue;\n return (aNull ? 1 : -1) * (t.nullsLast ? 1 : -1);\n }\n const cmp = compare(av, bv);\n if (cmp !== 0) return t.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const start = q.offset > 0 ? q.offset : 0;\n const end = q.limit > 0 ? start + q.limit : out.length;\n return { rows: out.slice(start, end), total };\n}\n\n/** Explicit host bindings or approved evaluated accessors can participate in\n * local source stages. Ordinary unapproved computed controls stay disabled. */\nexport function computedInputAllowed(schema: FieldSchema, name: string, operation: \"filter\" | \"sort\"): boolean {\n const field = schema.fields.find(field => field.name === name);\n return !!field && (field.source.kind === \"backend\" && field[operation]?.enabled !== false || field[operation]?.enabled === true);\n}\n\n/** Does one row satisfy one clause? Exposed for the CellMenu preview + tests. */\nexport function matchesClause<Row>(\n row: Row,\n clause: WhereClause,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): boolean {\n const field = resolveFieldName(schema, clause.field) ?? clause.field;\n const byName = indexFields(schema);\n const prepared = prepareWhereClause(\n { ...clause, field },\n evaluationTime(options),\n );\n prepareDatetimePredicates([{ kind: \"lit\", predicate: prepared }], byName);\n return matchesWith(byName, row, prepared);\n}\n\n/** Client-side mirror of the backend GROUP BY (the executor for `clientRows`\n * mode / the demo). Scope matches the server contract: the WHERE-filtered set\n * only — ORDER BY / LIMIT / OFFSET are intentionally ignored, so a metric\n * reflects every matching row, not the visible page. Must agree with\n * backends/go's aggregate compile on op semantics. */\nexport function applyAggregations<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) return evaluateMetrics(rows, q, schema, options);\n if (\n options.signal?.aborted ||\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n )\n )\n return evaluateMetrics(rows, q, schema, options);\n const advanced = (q.aggregations ?? []).filter(\n (a) =>\n a.dateGrouping ||\n a.diagnostics?.length ||\n a.expression !== undefined ||\n a.expressionY !== undefined ||\n a.scope !== undefined ||\n a.distribution ||\n a.sort ||\n a.groupLimit !== undefined ||\n a.where !== undefined ||\n a.minCount !== undefined,\n );\n if (advanced.length) {\n // Partitioning must not hide invalid IDs/shapes or the query-wide card cap.\n if (\n (q.aggregations?.length ?? 0) > 20 ||\n normalizeQueryState(q).aggregations?.length !== q.aggregations?.length\n )\n return evaluateMetrics(rows, q, schema, options);\n const legacy = (q.aggregations ?? []).filter((a) => !advanced.includes(a));\n const results = [\n ...evaluateMetrics(\n rows,\n { ...q, aggregations: advanced },\n schema,\n options,\n ).metrics,\n ...(legacy.length\n ? applyAggregations(\n rows,\n { ...q, aggregations: legacy },\n schema,\n options,\n ).metrics\n : []),\n ];\n const byId = new Map(results.map((result) => [result.id, result]));\n return {\n metrics: (q.aggregations ?? []).flatMap((a) => byId.get(a.id) ?? []),\n };\n }\n const now = evaluationTime(options);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field)))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const filtered = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const metrics = (q.aggregations ?? [])\n .filter(\n (a) =>\n !isComputedField(a.field ?? \"\") && !a.groupBy.some(isComputedField),\n )\n .map((agg) => {\n const field = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n if (\n field &&\n (!isMeasurable(field) || !aggOpsForField(field).includes(agg.op))\n )\n return {\n id: agg.id,\n buckets: [],\n error: `Field ${field.name} does not allow ${agg.op}.`,\n };\n return {\n id: agg.id,\n buckets: computeBuckets(filtered, agg, byName, resolveField),\n };\n });\n return { metrics };\n}\n\nfunction computeBuckets<Row>(\n rows: Row[],\n agg: AggregationClause,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (field: string) => string,\n): AggregationBucket[] {\n // One slot per groupBy entry, preserving position. An unresolved field stays\n // in the array as `undefined` so every bucket's `keys` has exactly one element\n // per requested group field — the panel renders keys positionally against\n // `clause.groupBy`, so dropping an entry here would shift every later column.\n const groupFields = agg.groupBy.map((n) => byName.get(resolveField(n)));\n const measure = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n\n const groups = new Map<string, { keys: MetricKey[]; rows: Row[] }>();\n if (!agg.groupBy.length) groups.set(\"[]\", { keys: [], rows: [] });\n for (const row of rows) {\n const keys = groupFields.map((f) => {\n if (!f) return null; // unresolved group field → NULL bucket, never a missing column\n const v = readFieldValue(f, row);\n return v == null || v === \"\"\n ? null\n : typeof v === \"number\" ||\n typeof v === \"boolean\" ||\n typeof v === \"string\"\n ? v\n : String(v);\n });\n const k = JSON.stringify(keys);\n let g = groups.get(k);\n if (!g) {\n g = { keys, rows: [] };\n groups.set(k, g);\n }\n g.rows.push(row);\n }\n\n const buckets = [...groups.values()].map((g) => ({\n keys: g.keys,\n count: g.rows.length,\n value: aggValue(agg.op, measure, g.rows),\n }));\n return sortBuckets(buckets);\n}\n\nfunction aggValue<Row>(\n op: AggOp,\n measure: FieldDef<Row> | undefined,\n rows: Row[],\n): number | string | null {\n if (op === \"count\") {\n if (!measure) return rows.length; // COUNT(*)\n let n = 0;\n for (const r of rows) if (readFieldValue(measure, r) != null) n++; // COUNT(expr) = non-null\n return n;\n }\n if (!measure) return null;\n const values = rows\n .map((r) => readFieldValue(measure, r))\n .filter((v) => v != null);\n\n switch (op) {\n case \"count_distinct\":\n return new Set(values.map((v) => String(v))).size;\n case \"sum\":\n case \"avg\": {\n let sum = 0;\n let n = 0;\n for (const v of values) {\n const num = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(num)) {\n sum += num;\n n++;\n }\n }\n if (op === \"avg\") return n ? sum / n : null;\n return n ? sum : null;\n }\n case \"min\":\n case \"max\": {\n let best: unknown;\n for (const v of values) {\n if (best === undefined) {\n best = v;\n continue;\n }\n const cmp = compare(v, best);\n if (op === \"min\" ? cmp < 0 : cmp > 0) best = v;\n }\n return (best as number | string | undefined) ?? null;\n }\n default:\n return null;\n }\n}\n\n/** Stable display order: descending by the metric (or group size when the metric\n * isn't numeric), then by group key. The 2D pivot ignores this; the 1D bar list\n * and the flat N-column table read top-to-bottom from it. */\nfunction sortBuckets(buckets: AggregationBucket[]): AggregationBucket[] {\n return [...buckets].sort((a, b) => {\n const av = typeof a.value === \"number\" ? a.value : a.count;\n const bv = typeof b.value === \"number\" ? b.value : b.count;\n if (av !== bv) return bv - av;\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n}\n\ninterface PreparedWhereClause {\n clause: WhereClause;\n now: number;\n datetime?: number;\n regex: RegExp | null | undefined;\n}\n\ntype PreparedWhereTerm =\n | { kind: \"lit\"; predicate: PreparedWhereClause }\n | { kind: \"or\"; predicates: PreparedWhereClause[] };\n\nfunction prepareWhereClause(\n clause: WhereClause,\n now: number,\n): PreparedWhereClause {\n const usesRegex =\n clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\";\n return {\n clause,\n now,\n regex: usesRegex ? compileRegex(clause.value) : undefined,\n };\n}\n\nfunction prepareWhereTerm(\n term: WhereTerm,\n resolveField: (name: string) => string,\n now: number,\n): PreparedWhereTerm {\n if (isOrGroup(term)) {\n return {\n kind: \"or\",\n predicates: term.any.map((c) =>\n prepareWhereClause({ ...c, field: resolveField(c.field) }, now),\n ),\n };\n }\n return {\n kind: \"lit\",\n predicate: prepareWhereClause(\n { ...term, field: resolveField(term.field) },\n now,\n ),\n };\n}\n\nfunction prepareDatetimePredicates<Row>(\n terms: PreparedWhereTerm[],\n fields: Map<string, FieldDef<Row>>,\n): void {\n for (const term of terms)\n for (const p of term.kind === \"lit\" ? [term.predicate] : term.predicates) {\n const field = fields.get(p.clause.field);\n if (\n field?.type !== \"datetime\" ||\n p.clause.value === \"\" ||\n p.clause.op === \"is_null\" ||\n p.clause.op === \"is_not_null\"\n )\n continue;\n p.datetime = coerceValue(\"datetime\", p.clause.value, p.now) as number;\n }\n}\n\n/** A row satisfies the WHERE when every term matches (AND); a term matches when\n * its sole predicate matches, or — for an OR group — when any member does. */\nfunction matchesTerm<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n term: PreparedWhereTerm,\n): boolean {\n if (term.kind === \"lit\") return matchesWith(byName, row, term.predicate);\n // Normalization never yields an empty group (0 dropped, 1 flattened), so\n // `some` over a non-empty list is the OR.\n return term.predicates.some((p) => matchesWith(byName, row, p));\n}\n\nfunction matchesWith<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause } = prepared;\n const field = byName.get(clause.field);\n if (!field) return true; // unknown field → no client opinion\n const v = readFieldValue(field, row);\n\n // Empty value on a non-equality, value-taking op is a \"no filter\" signal —\n // true for BOTH the predicate and its negation (matches the UI + the Go\n // compiler, which skip such clauses). Nullary ops legitimately use value \"\".\n if (\n clause.value === \"\" &&\n clause.op !== \"=\" &&\n clause.op !== \"!=\" &&\n clause.op !== \"is_null\" &&\n clause.op !== \"is_not_null\"\n ) {\n return true;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (\n !/^(0|[1-9]\\d*)$/.test(clause.value) ||\n !Number.isSafeInteger(Number(clause.value))\n )\n return false;\n }\n\n let base: boolean;\n if (prepared.datetime !== undefined) {\n const timestamp =\n v instanceof Date\n ? v.getTime()\n : typeof v === \"number\"\n ? v\n : typeof v === \"string\"\n ? Date.parse(v)\n : NaN;\n if (v === \"\" || !Number.isFinite(timestamp)) return false;\n base = matchesDatetime(timestamp, prepared.datetime, clause.op);\n } else {\n base = matchesBase(field, v, prepared);\n }\n if (!clause.negated) return base;\n // Null-exclusive NOT: a NULL/empty value satisfies neither the predicate nor\n // its negation (mirrors `not_matches_regex` and the server's trailing\n // `AND <expr> IS NOT NULL`).\n const isNull = Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n return !isNull && !base;\n}\n\nfunction matchesDatetime(\n timestamp: number,\n rhs: number,\n op: WhereClause[\"op\"],\n): boolean {\n switch (op) {\n case \"=\":\n return timestamp === rhs;\n case \"!=\":\n return timestamp !== rhs;\n case \">\":\n return timestamp > rhs;\n case \">=\":\n return timestamp >= rhs;\n case \"<\":\n return timestamp < rhs;\n case \"<=\":\n return timestamp <= rhs;\n default:\n return false;\n }\n}\n\n/** The bare predicate result, ignoring `negated` and the empty-value skip\n * (both handled by `matchesWith`). */\nfunction matchesBase<Row>(\n field: FieldDef<Row>,\n v: unknown,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause, regex } = prepared;\n\n // Nullity, with array-aware semantics.\n if (clause.op === \"is_null\")\n return Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n if (clause.op === \"is_not_null\")\n return Array.isArray(v) ? v.length > 0 : v != null && v !== \"\";\n\n const arrayText = (value: unknown) =>\n field.filter?.arrayCaseSensitive\n ? String(value)\n : String(value).toLowerCase();\n\n // `includes` is array membership (ARRAY_HAS): a null/missing array contains\n // nothing. Handle before the array/scalar split so null can't fall through.\n if (clause.op === \"includes\") {\n const arr = Array.isArray(v) ? v : [];\n const needle = arrayText(clause.value);\n return arr.some((x) => arrayText(x) === needle);\n }\n\n if (clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\") {\n if (v == null || Array.isArray(v)) return false;\n if (!regex) return false;\n const matches = regex.test(String(v));\n return clause.op === \"matches_regex\" ? matches : !matches;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (typeof v !== \"string\" || !/^(0|[1-9]\\d*)$/.test(clause.value))\n return false;\n const limit = Number(clause.value);\n if (!Number.isSafeInteger(limit)) return false;\n const length = Array.from(v).length;\n return clause.op === \"length_gt\"\n ? length > limit\n : clause.op === \"length_lt\"\n ? length < limit\n : length === limit;\n }\n\n if (Array.isArray(v)) {\n const needle = arrayText(clause.value);\n const hay = v.map(arrayText);\n switch (clause.op) {\n case \"contains\":\n return hay.some((s) => s.includes(needle));\n case \"=\":\n return hay.includes(needle);\n case \"!=\":\n return !hay.includes(needle);\n default:\n return true;\n }\n }\n\n switch (clause.op) {\n case \"=\":\n return String(v ?? \"\") === String(coerceSafe(field, clause.value));\n case \"!=\":\n return String(v ?? \"\") !== String(coerceSafe(field, clause.value));\n case \">\":\n return compare(v, coerceSafe(field, clause.value)) > 0;\n case \">=\":\n return compare(v, coerceSafe(field, clause.value)) >= 0;\n case \"<\":\n return compare(v, coerceSafe(field, clause.value)) < 0;\n case \"<=\":\n return compare(v, coerceSafe(field, clause.value)) <= 0;\n case \"contains\":\n return String(v ?? \"\")\n .toLowerCase()\n .includes(clause.value.toLowerCase());\n case \"starts_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .startsWith(clause.value.toLowerCase());\n case \"ends_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .endsWith(clause.value.toLowerCase());\n default:\n return true;\n }\n}\n\n/** `null` means an invalid pattern; `undefined` means no regex was requested. */\nfunction compileRegex(pattern: string | undefined): RegExp | null | undefined {\n if (pattern === undefined) return undefined;\n try {\n return new RegExp(pattern);\n } catch {\n return null;\n }\n}\n\nfunction extractSortValue(\n value: unknown,\n regex: RegExp | null | undefined,\n): unknown {\n if (regex === undefined) return value;\n if (regex === null || value == null) return null;\n const match = regex.exec(String(value));\n if (!match) return null;\n return match.length > 1 ? (match[1] ?? null) : match[0];\n}\n\n/** Coerce per the field type, falling back to the raw string if coercion fails\n * (so a malformed value degrades to a string compare rather than throwing). */\nfunction coerceSafe(field: FieldDef, raw: string): string | number | boolean {\n try {\n return coerceValue(field.type, raw);\n } catch {\n return raw;\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\")\n return a === b ? 0 : a ? 1 : -1;\n return String(a).localeCompare(String(b));\n}\n","import type { ServerQueryV2, FetchRowsResultV2 } from \"./execution\";\nimport type { QueryCapabilitiesV3, QueryRequestV3, QueryResultV3 } from \"./queryV3\";\nimport type { MetricQuery, MetricCapabilities } from \"./metricTypes\";\n// adapters.ts — the pluggable seams. Everything project-specific is injected\n// here so the package core stays generic.\n//\n// - Transport : how rows + filter-value suggestions are fetched.\n// - StorageAdapter: where saved/last queries live (in-memory by default in\n// the React hook; explicitly durable when callers opt in).\n\nimport { normalizeQueryState } from \"./query\";\nimport type { QueryState, RowId } from \"./query\";\nimport type { QuerySnapshotStore } from \"./queryLinks\";\nimport type { ServerQuery, AggregationRequest, AggregationResult } from \"./encode\";\n\n// ---- Transport ------------------------------------------------------------\n\nexport interface FetchRowsResult<Row> {\n rows: Row[];\n /** Total matching rows before pagination (for \"N of M\" + paging bounds). */\n total: number;\n}\n\n/** A keystroke-driven distinct-value lookup. Autocomplete is the DEFAULT value\n * source for every field (design feedback), so this is how the filter combobox\n * finds options. `search` is the user's current input; the backend returns the\n * best matches and whether it truncated (so the UI can prompt \"keep typing\"). */\nexport interface DistinctValuesQuery {\n field: string;\n /** Current substring/prefix the user has typed (empty = top values). */\n search: string;\n /** Max suggestions to return (default chosen by the adapter, ~50). */\n limit?: number;\n}\n\nexport interface DistinctValuesResult {\n values: string[];\n /** true when more matches exist than were returned — refine by typing. */\n hasMore: boolean;\n /** True if the selected field has at least one NULL in the source dataset.\n * False if that field is guaranteed non-null. Omitted when the backend does\n * not compute this metadata. */\n hasNull?: boolean;\n}\n\n/** Per-field metadata for the field picker. */\nexport interface FieldStats {\n distinct?: number;\n min?: string | number;\n max?: string | number;\n}\n\nexport interface Transport<Row = any> {\n queryCapabilities?: QueryCapabilitiesV3;\n fetchQueryV3?(query: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;\n fetchRowsV2?(query: ServerQueryV2, signal?: AbortSignal): Promise<FetchRowsResultV2<Row>>;\n metricCapabilities?: MetricCapabilities;\n fetchMetrics?(query: MetricQuery, signal?: AbortSignal): Promise<AggregationResult>;\n /** Legacy row execution. A remote table needs this, fetchRowsV2 with a\n * computedExecution handshake, or fetchQueryV3 with queryCapabilities.\n * Modern hosts may omit the legacy endpoint, including for draft previews. */\n fetchRows?(query: ServerQuery, signal?: AbortSignal): Promise<FetchRowsResult<Row>>;\n\n /** Distinct values for filter autocomplete. Strongly recommended: without it,\n * fields fall back to freeform input. The backend should match `search`\n * server-side (e.g. ILIKE prefix) and cap at `limit` so large domains stay\n * fast and refine per keystroke. */\n fetchDistinctValues?(q: DistinctValuesQuery, signal?: AbortSignal): Promise<DistinctValuesResult>;\n\n /** Run the metric panel's GROUP BY queries (one per requested aggregation),\n * scoped to the WHERE-filtered set with no paging. Optional: without it, the\n * metric panel falls back to applyAggregations over local rows (client mode).\n * Implementations compile each AggSpec with backends/go CompileAggregation,\n * sharing the same WHERE as fetchRows. */\n fetchAggregations?(q: AggregationRequest, signal?: AbortSignal): Promise<AggregationResult>;\n\n /** Re-fetch a single row by id, for in-place updates without a full re-query\n * after a mutation. Optional. */\n fetchRow?(id: RowId, signal?: AbortSignal): Promise<Row | null>;\n\n /** Stats for the field picker. Optional. */\n fetchFieldStats?(fields: string[], signal?: AbortSignal): Promise<Record<string, FieldStats>>;\n}\n\n// ---- Saved queries --------------------------------------------------------\n\nexport interface SavedQuery {\n snapshotCode?: string;\n id: string;\n name: string;\n /** Epoch millis; injected by the caller so core stays deterministic/testable. */\n savedAt: number;\n query: QueryState;\n}\n\n/** Persistence for the \"last\" query (auto-restored) and named saved queries. All\n * methods are namespaced by `key` (the schema/dataset name) so multiple tables\n * on one origin don't collide. Async to allow backend implementations; the\n * browser adapters can still resolve synchronously. */\nexport interface StorageAdapter {\n /** Optional authenticated server store. Ordinary URL sync never calls it. */\n snapshots?: QuerySnapshotStore;\n loadLast(key: string): Promise<QueryState | null>;\n saveLast(key: string, query: QueryState): Promise<void>;\n\n listSaved(key: string): Promise<SavedQuery[]>;\n /** Load the saved query selected as the default view for this key. Optional so\n * existing backend adapters keep working until they add first-class support. */\n loadDefaultSaved?(key: string): Promise<SavedQuery | null>;\n /** Set or clear the saved query used as the default view for this key. */\n setDefaultSaved?(key: string, id: string | null): Promise<void>;\n /** Persist a named query snapshot. Rejects when a saved query with the same\n * name already exists in the key namespace. */\n saveNamed(key: string, name: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n /** Atomically replace a named query's state, preserving its id, name and default\n * selection. On rejection the original entry must remain unchanged. */\n updateNamed?(key: string, id: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n deleteSaved(key: string, id: string): Promise<void>;\n}\n\nconst LAST_PREFIX = \"query-table:last:\";\nconst SAVED_PREFIX = \"query-table:saved:\";\nconst DEFAULT_PREFIX = \"query-table:default:\";\nconst MAX_SAVED_QUERIES = 100;\nconst MAX_SAVED_NAME_LENGTH = 200;\n\nfunction normalizeSavedQuery(value: unknown): SavedQuery | null {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) return null;\n const raw = value as Record<string, unknown>;\n if (\n typeof raw.id !== \"string\" ||\n !raw.id ||\n raw.id.length > 256 ||\n typeof raw.name !== \"string\" ||\n !raw.name ||\n raw.name.length > MAX_SAVED_NAME_LENGTH ||\n typeof raw.savedAt !== \"number\" ||\n !Number.isFinite(raw.savedAt) ||\n raw.query == null ||\n typeof raw.query !== \"object\"\n ) {\n return null;\n }\n return { id: raw.id, name: raw.name, savedAt: raw.savedAt, query: normalizeQueryState(raw.query),\n ...(typeof raw.snapshotCode === \"string\" ? { snapshotCode: raw.snapshotCode } : {}) };\n}\n\nfunction normalizeSavedQueries(value: unknown): SavedQuery[] {\n if (!Array.isArray(value)) return [];\n return value\n .slice(0, MAX_SAVED_QUERIES)\n .map(normalizeSavedQuery)\n .filter((item): item is SavedQuery => item != null);\n}\n\n/** In-memory persistence used by default by the React package. It supports the\n * full saved-query UI for the lifetime of a mounted table without writing\n * filter values to durable browser storage. */\nexport function memoryStorageAdapter(): StorageAdapter {\n const last = new Map<string, QueryState>();\n const saved = new Map<string, SavedQuery[]>();\n const defaults = new Map<string, string>();\n\n return {\n async loadLast(key) {\n const query = last.get(key);\n return query ? normalizeQueryState(query) : null;\n },\n async saveLast(key, query) {\n last.set(key, normalizeQueryState(query));\n },\n async listSaved(key) {\n return (saved.get(key) ?? []).map((item) => ({ ...item, query: normalizeQueryState(item.query) }));\n },\n async loadDefaultSaved(key) {\n const id = defaults.get(key);\n return id ? (saved.get(key) ?? []).find((item) => item.id === id) ?? null : null;\n },\n async setDefaultSaved(key, id) {\n if (id == null) {\n defaults.delete(key);\n return;\n }\n if (!(saved.get(key) ?? []).some((item) => item.id === id)) throw new Error(`Saved query \"${id}\" does not exist.`);\n defaults.set(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = saved.get(key) ?? [];\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((item) => item.name === normalizedName)) throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n saved.set(key, [...items, item]);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = saved.get(key) ?? [];\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n saved.set(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n saved.set(key, (saved.get(key) ?? []).filter((item) => item.id !== id));\n if (defaults.get(key) === id) defaults.delete(key);\n },\n };\n}\n\n/** Opt-in StorageAdapter over window.localStorage. Query state includes raw\n * filter values and is stored as cleartext JSON; do not use it for sensitive\n * datasets. Falls back to no persistence when storage is unavailable. */\nexport function localStorageAdapter(): StorageAdapter {\n const ls: Storage | null = (() => {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null; // access can throw in some sandboxes\n }\n })();\n\n const readSaved = (key: string): SavedQuery[] => {\n if (!ls) return [];\n try {\n const raw = ls.getItem(SAVED_PREFIX + key);\n return normalizeSavedQueries(raw ? JSON.parse(raw) : []);\n } catch {\n return [];\n }\n };\n const writeSaved = (key: string, items: SavedQuery[]): void => {\n if (ls) ls.setItem(SAVED_PREFIX + key, JSON.stringify(items));\n };\n const readDefaultId = (key: string): string | null => {\n if (!ls) return null;\n return ls.getItem(DEFAULT_PREFIX + key);\n };\n const writeDefaultId = (key: string, id: string | null): void => {\n if (!ls) return;\n if (id) ls.setItem(DEFAULT_PREFIX + key, id);\n else ls.removeItem(DEFAULT_PREFIX + key);\n };\n\n return {\n async loadLast(key) {\n if (!ls) return null;\n try {\n const raw = ls.getItem(LAST_PREFIX + key);\n return raw ? normalizeQueryState(JSON.parse(raw)) : null;\n } catch {\n return null;\n }\n },\n async saveLast(key, query) {\n if (ls) ls.setItem(LAST_PREFIX + key, JSON.stringify(normalizeQueryState(query)));\n },\n async listSaved(key) {\n return readSaved(key).sort((a, b) => b.savedAt - a.savedAt);\n },\n async loadDefaultSaved(key) {\n const id = readDefaultId(key);\n if (!id) return null;\n const found = readSaved(key).find((q) => q.id === id);\n if (!found) writeDefaultId(key, null);\n return found ?? null;\n },\n async setDefaultSaved(key, id) {\n if (id && !readSaved(key).some((q) => q.id === id)) {\n throw new Error(`Saved query \"${id}\" does not exist.`);\n }\n writeDefaultId(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = readSaved(key);\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((q) => q.name === normalizedName)) {\n throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n }\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n items.push(item);\n writeSaved(key, items);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = readSaved(key);\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n writeSaved(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n writeSaved(\n key,\n readSaved(key).filter((q) => q.id !== id),\n );\n if (readDefaultId(key) === id) writeDefaultId(key, null);\n },\n };\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\n\nexport interface SavedPropertyView {\n id: string;\n name: string;\n savedAt: number;\n view: PropertyViewState;\n}\nexport interface PropertyViewStorage {\n loadLast(objectType: string): Promise<PropertyViewState | null>;\n saveLast(objectType: string, view: PropertyViewState): Promise<void>;\n listSaved(objectType: string): Promise<SavedPropertyView[]>;\n saveNamed(\n objectType: string,\n name: string,\n view: PropertyViewState,\n savedAt: number,\n ): Promise<SavedPropertyView>;\n deleteSaved(objectType: string, id: string): Promise<void>;\n loadDefaultSaved(objectType: string): Promise<SavedPropertyView | null>;\n setDefaultSaved(objectType: string, id: string | null): Promise<void>;\n}\ninterface StoredViews {\n last: PropertyViewState | null;\n saved: SavedPropertyView[];\n defaultId: string | null;\n}\nconst empty = (): StoredViews => ({ last: null, saved: [], defaultId: null });\nconst clone = (saved: SavedPropertyView): SavedPropertyView => ({\n ...saved,\n view: normalizePropertyView(saved.view),\n});\n\n/** The JSON-backed factory also supports application-owned synchronous preferences. */\nexport function jsonPropertyViewStorage(\n read: (key: string) => string | null,\n write: (key: string, value: string) => void,\n): PropertyViewStorage {\n const keyFor = (type: string) => `query-table:properties:${type}`;\n function load(type: string): StoredViews {\n const value = read(keyFor(type));\n if (value === null) return empty();\n const raw = JSON.parse(value) as StoredViews;\n if (\n !raw ||\n !Array.isArray(raw.saved) ||\n raw.saved.length > 100 ||\n !(raw.defaultId === null || typeof raw.defaultId === \"string\")\n )\n throw new Error(\"Invalid saved property views.\");\n const saved = raw.saved.map((item) => {\n if (\n !item ||\n typeof item.id !== \"string\" ||\n !item.id ||\n typeof item.name !== \"string\" ||\n !item.name.trim() ||\n item.name.length > 200 ||\n !Number.isFinite(item.savedAt)\n )\n throw new Error(\"Invalid saved property view.\");\n return clone(item);\n });\n return {\n last: raw.last === null ? null : normalizePropertyView(raw.last),\n saved,\n defaultId: raw.defaultId,\n };\n }\n const store = (type: string, value: StoredViews) =>\n write(keyFor(type), JSON.stringify(value));\n return {\n async loadLast(type) {\n return load(type).last;\n },\n async saveLast(type, view) {\n const data = load(type);\n data.last = normalizePropertyView(view);\n store(type, data);\n },\n async listSaved(type) {\n return load(type).saved;\n },\n async saveNamed(type, name, view, savedAt) {\n name = name.trim();\n if (!name || name.length > 200 || !Number.isFinite(savedAt))\n throw new Error(\n \"A view name (1–200 characters) and valid save time are required.\",\n );\n const data = load(type);\n if (data.saved.some((v) => v.name === name))\n throw new Error(`A property view named “${name}” already exists.`);\n if (data.saved.length >= 100)\n throw new Error(\"At most 100 saved property views are allowed.\");\n let suffix = 0;\n while (data.saved.some((v) => v.id === `${savedAt}-${suffix}`)) suffix++;\n const saved = {\n id: `${savedAt}-${suffix}`,\n name,\n savedAt,\n view: normalizePropertyView(view),\n };\n data.saved.push(saved);\n store(type, data);\n return clone(saved);\n },\n async deleteSaved(type, id) {\n const data = load(type);\n data.saved = data.saved.filter((v) => v.id !== id);\n if (data.defaultId === id) data.defaultId = null;\n store(type, data);\n },\n async loadDefaultSaved(type) {\n const data = load(type);\n return data.saved.find((v) => v.id === data.defaultId) ?? null;\n },\n async setDefaultSaved(type, id) {\n const data = load(type);\n if (id !== null && !data.saved.some((v) => v.id === id))\n throw new Error(\"Unknown property view.\");\n data.defaultId = id;\n store(type, data);\n },\n };\n}\nexport function memoryPropertyViewStorage(): PropertyViewStorage {\n const values = new Map<string, string>();\n return jsonPropertyViewStorage(\n (key) => values.get(key) ?? null,\n (key, value) => {\n values.set(key, value);\n },\n );\n}\n/** Durable browser persistence is explicitly opt-in, independently of table storage. */\nexport function localPropertyViewStorage(): PropertyViewStorage {\n return jsonPropertyViewStorage(\n (key) => localStorage.getItem(key),\n (key, value) => localStorage.setItem(key, value),\n );\n}\n","import { predicatesOf, ITEM_DETAILS_COLUMN, type QueryState } from \"./query\";\nimport { metricDependencies, compileMetric } from \"./metrics\";\nimport { createGroupingModel } from \"./grouping\";\nimport type { FieldSchema } from \"./schema\";\nimport type { FormulaPlan } from \"./formula\";\n\nexport interface SourceDependencies {\n fields: string[];\n baseFields: string[];\n identity: string;\n paths: Record<string, string>;\n}\n/** Source inputs are distinct from result/HAVING aliases. Includes hidden ROW\n * inputs and transitive computed/derived dependencies, even when not selected. */\nexport function sourceDependencies<Row>(query: QueryState, schema: FieldSchema<Row>, resolveComputed?: (name: string) => FormulaPlan | undefined): SourceDependencies {\n const fields = new Set<string>([schema.idField]);\n const addSort = (name: string) => {\n fields.add(name);\n const sortField = schema.fields.find(field => field.name === name)?.sort?.field;\n if (sortField) fields.add(sortField);\n };\n const source = query.grouping?.source ?? query;\n for (const term of source.where) for (const predicate of predicatesOf(term)) fields.add(predicate.field);\n if (query.grouping) {\n const model = createGroupingModel(schema);\n model.validate(query.grouping);\n for (const key of query.grouping.keys) fields.add(key);\n for (const summary of query.grouping.summaries) {\n // Link columns read result fields only; they have no source inputs.\n if (summary.op === \"link\") continue;\n if (summary.op === \"row\") fields.add(summary.field!);\n else for (const dependency of compileMetric(model.summaryExpression(summary), schema, resolveComputed).dependencies) fields.add(dependency);\n }\n for (const term of query.grouping.representative?.orderBy ?? []) addSort(term.field);\n } else {\n for (const column of source.select) if (column.field !== ITEM_DETAILS_COLUMN) fields.add(column.field);\n for (const term of source.orderBy) addSort(term.field);\n for (const metric of source.aggregations ?? []) for (const dependency of metricDependencies(metric, schema, resolveComputed)) fields.add(dependency);\n }\n const base = new Set<string>();\n const visiting = new Set<string>();\n const visit = (name: string) => {\n if (visiting.has(name)) throw Error(\"Source dependency cycle.\");\n const field = schema.fields.find(field => field.name === name);\n if (!field && name === schema.idField) { base.add(name); return; }\n const dependencies = field?.source.kind === \"derived\" ? field.source.dependencies : resolveComputed?.(name)?.dependencies;\n if (!field && !dependencies) throw Error(`Unavailable source dependency: ${name}.`);\n if (dependencies?.length) {\n visiting.add(name);\n for (const dependency of dependencies) visit(dependency);\n visiting.delete(name);\n } else base.add(name);\n };\n for (const name of fields) visit(name);\n const paths = Object.fromEntries([...base].map(name => {\n const field = schema.fields.find(field => field.name === name);\n return [name, field?.source.kind === \"backend\" ? field.source.path ?? name : name];\n }));\n return { fields: [...fields].sort(), baseFields: [...base].sort(), identity: schema.idField, paths };\n}\n","// queryPatch.ts — apply, recognise and remove partial queries (\"patches\").\n//\n// A host keeps reusable presets (a saved filter set, a column layout, a\n// grouped report) as patches. Each patch owns some facets of a QueryState and\n// leaves the others alone. Filters are additive and identified structurally:\n// there is no provenance on WHERE terms, so a term the user typed that is\n// structurally identical to a patch term is indistinguishable from it. See\n// docs/query-patches.md for the full contract.\n\nimport { exitGrouping, withGroupingKeys, type GroupingState, type SummaryColumn } from \"./grouping\";\nimport { NULLARY_OPS } from \"./ops\";\nimport {\n isOrGroup,\n normalizeQueryState,\n type AggregationClause,\n type QueryState,\n type WhereClause,\n type WhereTerm,\n} from \"./query\";\n\nexport type QueryFacet = \"filters\" | \"columns\" | \"order\" | \"grouping\" | \"metrics\" | \"limit\";\n\nexport interface QueryPatch {\n /** Host identity for the patch; not interpreted. */\n id: string;\n /** Facets this patch controls. Facets not listed are never touched. */\n owns: QueryFacet[];\n /** Values for the owned facets. A `grouping` value makes this a group-stage\n * patch: its `where` is HAVING and its filters are `grouping.source.where`. */\n query: Partial<QueryState>;\n}\n\nexport interface QueryPatchMatch {\n status: \"active\" | \"modified\" | \"inactive\";\n /** Owned facets that differ; only populated when `status` is \"modified\". */\n modified: QueryFacet[];\n}\n\nexport interface ApplyPatchOptions {\n /** A previously applied patch to remove first (see `removePatch`). */\n replacing?: QueryPatch;\n}\n\n// ---- structural WHERE helpers (shared with drilldown) -----------------------\n\nfunction clauseKey(clause: WhereClause): string {\n return JSON.stringify([\n clause.field,\n clause.op,\n NULLARY_OPS.has(clause.op) ? \"\" : clause.value,\n clause.negated === true,\n ]);\n}\n\n/** Structural identity of one WHERE term. OR-group members are unordered and\n * presentation metadata (set-filter identity) is ignored. */\nexport function whereTermKey(term: WhereTerm): string {\n if (!isOrGroup(term)) return clauseKey(term);\n return `any:${JSON.stringify(term.any.map(clauseKey).sort())}`;\n}\n\n/** Append terms that are not already structurally present. */\nexport function appendWhereTerms(where: readonly WhereTerm[], terms: readonly WhereTerm[]): WhereTerm[] {\n const present = new Set(where.map(whereTermKey));\n const out = [...where];\n for (const term of terms) {\n const key = whereTermKey(term);\n if (present.has(key)) continue;\n present.add(key);\n out.push(term);\n }\n return out;\n}\n\n/** Owned units: each OR group or literal alone, except that a run of\n * consecutive `!=` literals on one field (an exclusion list) is one unit. */\nfunction filterUnits(where: readonly WhereTerm[]): WhereTerm[][] {\n const units: WhereTerm[][] = [];\n for (const term of where) {\n const last = units[units.length - 1];\n const previous = last?.[last.length - 1];\n if (\n last && previous && !isOrGroup(term) && !isOrGroup(previous) &&\n term.op === \"!=\" && previous.op === \"!=\" && term.field === previous.field\n )\n last.push(term);\n else units.push([term]);\n }\n return units;\n}\n\nfunction unitPresent(unit: readonly WhereTerm[], present: ReadonlySet<string>): boolean {\n return unit.every((term) => present.has(whereTermKey(term)));\n}\n\nfunction removeUnits(where: readonly WhereTerm[], units: readonly WhereTerm[][]): WhereTerm[] {\n const present = new Set(where.map(whereTermKey));\n const remove = new Set(\n units.filter((unit) => unitPresent(unit, present)).flatMap((unit) => unit.map(whereTermKey)),\n );\n return where.filter((term) => !remove.has(whereTermKey(term)));\n}\n\nfunction sameTermSet(a: readonly WhereTerm[], b: readonly WhereTerm[]): boolean {\n const keys = (where: readonly WhereTerm[]) => JSON.stringify(where.map(whereTermKey).sort());\n return keys(a) === keys(b);\n}\n\n// ---- patch interpretation ---------------------------------------------------\n\ninterface PatchGrouping {\n keys: string[];\n summaries: SummaryColumn[];\n representative: GroupingState[\"representative\"];\n having: WhereTerm[];\n}\n\ninterface PatchParts {\n owns: Set<QueryFacet>;\n stage: \"records\" | \"groups\";\n filters: WhereTerm[];\n units: WhereTerm[][];\n grouping: PatchGrouping | null;\n select: QueryState[\"select\"];\n orderBy: QueryState[\"orderBy\"];\n limit: number | undefined;\n aggregations: AggregationClause[];\n}\n\nfunction patchParts(patch: QueryPatch): PatchParts {\n const raw = patch.query ?? {};\n const normalized = normalizeQueryState(raw);\n const stage = normalized.grouping ? \"groups\" : \"records\";\n const filters = normalized.grouping ? normalized.grouping.source.where : normalized.where;\n const owns = new Set(patch.owns);\n // A limit has no neutral value without the schema; an absent one is not owned.\n if (typeof raw.limit !== \"number\") owns.delete(\"limit\");\n return {\n owns,\n stage,\n filters,\n units: filterUnits(filters),\n grouping: normalized.grouping\n ? {\n keys: normalized.grouping.keys,\n summaries: normalized.grouping.summaries,\n representative: normalized.grouping.representative,\n having: normalized.where,\n }\n : null,\n select: normalized.select,\n orderBy: normalized.orderBy,\n limit: typeof raw.limit === \"number\" ? normalized.limit : undefined,\n aggregations: normalized.aggregations ?? [],\n };\n}\n\nconst recordStage = (query: QueryState): QueryState => query.grouping?.source ?? query;\n\nfunction withRecordStage(query: QueryState, next: QueryState): QueryState {\n return query.grouping ? { ...query, grouping: { ...query.grouping, source: next } } : next;\n}\n\n/** Columns, order, limit and metrics address the stage the patch was written\n * for: the record query (the source snapshot while grouped) for record-stage\n * patches, the grouped result for group-stage patches. */\nfunction stageOf(query: QueryState, stage: PatchParts[\"stage\"]): QueryState | undefined {\n if (stage === \"records\") return recordStage(query);\n return query.grouping ? query : undefined;\n}\n\nfunction withStage(query: QueryState, stage: PatchParts[\"stage\"], update: (stage: QueryState) => QueryState): QueryState {\n if (stage === \"records\") return withRecordStage(query, update(recordStage(query)));\n return query.grouping ? update(query) : query;\n}\n\nfunction withAggregations(query: QueryState, aggregations: AggregationClause[]): QueryState {\n const { aggregations: _previous, ...rest } = query;\n return aggregations.length ? { ...rest, aggregations } : rest;\n}\n\nconst clone = <T>(value: T): T => structuredClone(value);\n\n// ---- comparison -------------------------------------------------------------\n\nconst summaryMeaning = ({ id, op, field, expression, link }: SummaryColumn) =>\n JSON.stringify(op === \"link\" ? [id, op, link ?? null] : [id, op, field, expression]);\n\nfunction summarySignature(summaries: readonly SummaryColumn[]): string {\n return JSON.stringify(summaries.map(summaryMeaning));\n}\n\n/** JSON with object keys sorted at every depth; array order is kept. */\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, (_key, item: unknown) =>\n item && typeof item === \"object\" && !Array.isArray(item)\n ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)))\n : item,\n );\n}\n\nfunction metricSignature(metric: AggregationClause): string {\n const { id: _id, label: _label, display: _display, layout: _layout, ...rest } = metric;\n return canonicalJson(rest);\n}\n\nfunction facetMatches(query: QueryState, parts: PatchParts, facet: QueryFacet): boolean {\n switch (facet) {\n case \"filters\": {\n const present = new Set(recordStage(query).where.map(whereTermKey));\n return parts.units.every((unit) => unitPresent(unit, present));\n }\n case \"grouping\": {\n const grouping = query.grouping;\n if (!parts.grouping || !grouping) return !parts.grouping && !grouping;\n return (\n JSON.stringify(grouping.keys) === JSON.stringify(parts.grouping.keys) &&\n summarySignature(grouping.summaries) === summarySignature(parts.grouping.summaries) &&\n JSON.stringify(grouping.representative) === JSON.stringify(parts.grouping.representative) &&\n sameTermSet(query.where, parts.grouping.having)\n );\n }\n case \"columns\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && JSON.stringify(stage.select.map((c) => c.field)) === JSON.stringify(parts.select.map((c) => c.field));\n }\n case \"order\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && JSON.stringify(stage.orderBy) === JSON.stringify(parts.orderBy);\n }\n case \"limit\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && stage.limit === parts.limit;\n }\n case \"metrics\": {\n const stage = stageOf(query, parts.stage);\n const signatures = (metrics: readonly AggregationClause[]) => JSON.stringify(metrics.map(metricSignature).sort());\n return !!stage && signatures(stage.aggregations ?? []) === signatures(parts.aggregations);\n }\n }\n}\n\n/** Compare a query with a patch. Both are normalized first; column widths,\n * `fitToScreen`, labels, metric display/layout and metric IDs are ignored.\n *\n * - `active`: every owned facet matches.\n * - `modified`: some owned facet differs, but the patch is still recognizable:\n * at least one owned facet matches (an owned `filters` facet with no terms\n * does not count), or at least one of its filter units is still present.\n * - `inactive`: otherwise. */\nexport function matchPatch(query: QueryState, patch: QueryPatch): QueryPatchMatch {\n const normalized = normalizeQueryState(query);\n const parts = patchParts(patch);\n const owned = [...parts.owns];\n const modified = owned.filter((facet) => !facetMatches(normalized, parts, facet));\n if (!modified.length) return { status: \"active\", modified: [] };\n const present = new Set(recordStage(normalized).where.map(whereTermKey));\n const recognizable =\n owned.some((facet) => !modified.includes(facet) && (facet !== \"filters\" || parts.units.length > 0)) ||\n (parts.owns.has(\"filters\") && parts.units.some((unit) => unitPresent(unit, present)));\n return recognizable ? { status: \"modified\", modified } : { status: \"inactive\", modified: [] };\n}\n\n// ---- application ------------------------------------------------------------\n\nfunction resetOffsets(query: QueryState): QueryState {\n return query.grouping\n ? { ...query, offset: 0, grouping: { ...query.grouping, source: { ...query.grouping.source, offset: 0 } } }\n : { ...query, offset: 0 };\n}\n\nfunction applyGrouping(query: QueryState, grouping: PatchGrouping | null): QueryState {\n if (!grouping) return exitGrouping(query);\n const before = query.grouping;\n // Enter or re-key through the same transition the grouping controls use.\n const keyed = before && JSON.stringify(before.keys) === JSON.stringify(grouping.keys)\n ? query\n : withGroupingKeys(query, grouping.keys);\n const previous = keyed.grouping!;\n const summaries = clone(grouping.summaries);\n // Result columns, sorts and metrics over replaced aggregates lose their meaning.\n const kept = new Set(summaries.map(summaryMeaning));\n const changed = new Set(previous.summaries.filter((column) => !kept.has(summaryMeaning(column))).map((column) => column.id));\n const next: QueryState = {\n ...keyed,\n grouping: { ...previous, summaries, representative: clone(grouping.representative) },\n where: clone(grouping.having),\n select: keyed.select.filter((c) => !changed.has(c.field)),\n orderBy: keyed.orderBy.filter((term) => !changed.has(term.field)),\n };\n return changed.size ? withAggregations(next, []) : next;\n}\n\n/** Remove a patch: its filter units that are still fully present are removed;\n * each other owned facet that still matches the patch is reset (columns and\n * order to the schema defaults, metrics to none, grouping exited). Facets the\n * user has since changed, and `limit`, are left alone. Resets offsets to 0. */\nexport function removePatch(query: QueryState, patch: QueryPatch): QueryState {\n const parts = patchParts(patch);\n const matches = (facet: QueryFacet) => parts.owns.has(facet) && facetMatches(normalizeQueryState(query), parts, facet);\n const reset = {\n columns: matches(\"columns\"),\n order: matches(\"order\"),\n metrics: matches(\"metrics\"),\n grouping: matches(\"grouping\"),\n };\n let next = query;\n if (parts.owns.has(\"filters\")) {\n const records = recordStage(next);\n next = withRecordStage(next, { ...records, where: removeUnits(records.where, parts.units) });\n }\n next = withStage(next, parts.stage, (stage) => {\n let out = stage;\n if (reset.columns) out = { ...out, select: [] };\n if (reset.order) out = { ...out, orderBy: [] };\n if (reset.metrics) out = withAggregations(out, []);\n return out;\n });\n if (reset.grouping) next = exitGrouping(next);\n return resetOffsets(next);\n}\n\n/** Apply a patch. Facets it does not own are untouched. Owned non-filter\n * facets are replaced; owned filters are additive: units already present are\n * not duplicated and user-authored terms are never removed. With `replacing`,\n * that patch is first removed with `removePatch`. Resets offsets to 0. */\nexport function applyPatch(query: QueryState, patch: QueryPatch, options: ApplyPatchOptions = {}): QueryState {\n let next = options.replacing ? removePatch(query, options.replacing) : query;\n const parts = patchParts(patch);\n if (parts.owns.has(\"grouping\")) next = applyGrouping(next, parts.grouping);\n if (parts.owns.has(\"filters\")) {\n const records = recordStage(next);\n next = withRecordStage(next, { ...records, where: appendWhereTerms(records.where, clone(parts.filters)) });\n }\n next = withStage(next, parts.stage, (stage) => {\n let out = stage;\n if (parts.owns.has(\"columns\")) out = { ...out, select: clone(parts.select) };\n if (parts.owns.has(\"order\")) out = { ...out, orderBy: clone(parts.orderBy) };\n if (parts.owns.has(\"limit\")) out = { ...out, limit: parts.limit ?? out.limit };\n if (parts.owns.has(\"metrics\")) out = withAggregations(out, clone(parts.aggregations));\n return out;\n });\n return resetOffsets(next);\n}\n","// groupLinks.ts — compose and route group-grain link columns.\n//\n// A link column's cell value (`GroupLinkValue`) carries everything that\n// depends on the group row. These helpers combine it with the current query\n// and the host's routes. Query-table owns composing the query; the host owns\n// turning it into a URL.\n\nimport { exitGrouping, type GroupLinkValue, type SummaryColumn } from \"./grouping\";\nimport { EMPTY_QUERY, type QueryState } from \"./query\";\nimport { appendWhereTerms, applyPatch } from \"./queryPatch\";\n\n/** Host routes for query-kind links, keyed by `LinkSpec.to.target`. Each\n * returns an href; it is safety-checked before rendering. */\nexport type LinkTargets = Record<string, (query: QueryState, params: Record<string, string>) => string>;\n\nexport interface ResolvedGroupLink {\n label: string;\n /** Not yet safety-checked; null when the link cannot be followed. */\n href: string | null;\n problem?: string;\n}\n\n/** Link columns are computed on the client. Server requests carry only the\n * keys and summaries they read. */\nexport function withoutLinkSummaries(summaries: readonly SummaryColumn[]): SummaryColumn[] {\n return summaries.filter((column) => column.op !== \"link\");\n}\n\n/** The query a query-kind link opens, or null for template links, invalid\n * links and ungrouped queries.\n *\n * Starts from `grouping.source` (or `EMPTY_QUERY` for `base: \"empty\"`), adds\n * the group's key predicates unless `keyFilters` is false, resets the offset\n * and finally applies the link's patch. With the defaults this is\n * `groupSourceQuery` followed by the patch. */\nexport function groupLinkQuery(query: QueryState, value: GroupLinkValue): QueryState | null {\n const to = value.to;\n if (!query.grouping || to?.kind !== \"query\" || value.problem) return null;\n const base = to.base === \"empty\" ? structuredClone(EMPTY_QUERY) : exitGrouping(query);\n if (to.keyFilters !== false && !value.terms) return null;\n const filtered: QueryState = { ...base, where: appendWhereTerms(base.where, value.terms ?? []), offset: 0 };\n return to.patch ? applyPatch(filtered, to.patch) : filtered;\n}\n\n/** Resolve a link cell to its label and href. Unregistered targets, failing\n * routes and unresolvable values return `href: null` with a `problem`. */\nexport function resolveGroupLink(query: QueryState, value: GroupLinkValue, targets: LinkTargets = {}): ResolvedGroupLink {\n const unresolved = (problem: string): ResolvedGroupLink => ({ label: value.label, href: null, problem });\n if (value.problem) return unresolved(value.problem);\n if (value.to?.kind === \"template\") return value.href ? { label: value.label, href: value.href } : unresolved(\"Invalid link.\");\n if (value.to?.kind !== \"query\") return unresolved(\"Invalid link definition.\");\n const route = Object.prototype.hasOwnProperty.call(targets, value.to.target) ? targets[value.to.target] : undefined;\n if (typeof route !== \"function\") return unresolved(`Link target \"${value.to.target}\" is not registered.`);\n const destination = groupLinkQuery(query, value);\n if (!destination) return unresolved(\"This group cannot be matched exactly.\");\n try {\n const href = route(destination, { ...value.to.params });\n return typeof href === \"string\" && href.trim() ? { label: value.label, href } : unresolved(`Link target \"${value.to.target}\" returned no URL.`);\n } catch (error) {\n return unresolved(`Link target \"${value.to.target}\" failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","import { createGroupingModel, withoutGrouping, type GroupingDefinition } from \"./grouping\";\nimport { normalizeQueryState, predicatesOf, type QueryState, type AggregationClause } from \"./query\";\nimport { toServerQuery, type ServerQuery, type AggregationResult } from \"./encode\";\nimport { validateMetric, toMetricQuery } from \"./metrics\";\nimport type { ComputedExecution } from \"./computed\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport { evaluationTime } from \"./relativeTime\";\nimport { withoutLinkSummaries } from \"./groupLinks\";\n\nexport interface QueryCapabilitiesV3 {\n version: 3;\n groupedRows: boolean;\n calendarGrouping: boolean;\n computedSourceFilters: boolean;\n regex: boolean;\n regexSourceFilters?: boolean;\n regexAggregateExpressions?: boolean;\n /** Executes AggregationClause.where; clauses using it are refused otherwise. */\n metricFilters?: boolean;\n /** Executes AggregationClause.minCount and reports hiddenGroups. */\n metricMinCount?: boolean;\n maxRows: number;\n maxGroups: number;\n maxPopulation: number;\n profile: string;\n}\nexport interface QueryRequestV3 {\n version: 3;\n profile: string;\n now: number;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n snapshot?: string;\n source: ServerQuery;\n result: ServerQuery;\n grouping?: GroupingDefinition;\n rows: boolean;\n metrics: AggregationClause[];\n diagnostics: string[];\n}\nexport interface QueryResultV3 {\n version: 3;\n now: number;\n sourceTotal: number;\n rows: Record<string, unknown>[];\n total: number;\n schema: { name: string; idField: string; fields: { name: string; type: string }[] };\n metrics: AggregationResult[\"metrics\"];\n execution: ComputedExecution;\n}\n/** The handshake supplies authority, including capabilities for computed keys\n * absent from the base schema. Labels may be supplied by the editable catalogue. */\nexport function sourceExecutionSchema<Row>(schema: FieldSchema<Row>, execution?: ComputedExecution, catalogue: readonly { id: string; label: string; revision: string }[] = []): FieldSchema<Row> {\n const fields = new Map(schema.fields.map(field => [field.name, field]));\n for (const [name, capability] of Object.entries(execution?.fields ?? {})) {\n const definition = catalogue.find(definition => name === `@computed/${definition.id}`);\n const revision = execution?.resolvedRevisions[name] ?? execution?.resolvedRevisions[name.slice(10)];\n const current = !!revision && (!definition || definition.revision === revision);\n fields.set(name, { ...fields.get(name), name, label: definition?.label ?? fields.get(name)?.label ?? name,\n type: capability.type, source: { kind: \"backend\" },\n select: { enabled: current && capability.select }, filter: { enabled: current && capability.filter === true },\n sort: { enabled: current && capability.sort }, aggregate: { measure: current && capability.measure, groupable: current && capability.group } } as FieldDef<Row>);\n }\n return { ...schema, fields: [...fields.values()] };\n}\nexport function toQueryRequestV3<Row>(query: QueryState, baseSchema: FieldSchema<Row>, capabilities: QueryCapabilitiesV3,\n execution?: ComputedExecution, options: { now?: number; rows?: boolean } = {}): QueryRequestV3 {\n const now = evaluationTime(options), q = normalizeQueryState(query);\n const sourceSchema = sourceExecutionSchema(baseSchema, execution);\n const source = q.grouping?.source ?? withoutGrouping(q);\n const diagnostics: string[] = [];\n if ((query.aggregations?.length ?? 0) !== (q.aggregations?.length ?? 0)) diagnostics.push(\"The query exceeds its metric budget or contains malformed metric state.\");\n if (capabilities.version !== 3 || execution && execution.profile !== capabilities.profile) diagnostics.push(\"The negotiated query profile is unavailable.\");\n let resultSchema = sourceSchema as FieldSchema<any>;\n if (q.grouping) {\n if (!capabilities.groupedRows) diagnostics.push(\"This server does not support grouped rows.\");\n try { const model = createGroupingModel(sourceSchema); model.validate(q.grouping); resultSchema = model.resultSchema(q.grouping.keys, q.grouping.summaries); }\n catch (error) { diagnostics.push(error instanceof Error ? error.message : String(error)); }\n }\n const sourceRequest = toServerQuery(withoutGrouping(source), sourceSchema);\n for (const term of source.where) for (const predicate of predicatesOf(term)) if ([\"matches_regex\", \"not_matches_regex\"].includes(predicate.op) && !capabilities.regexSourceFilters)\n diagnostics.push(\"This server profile does not support isolated regex source filtering.\");\n const result = toServerQuery(withoutGrouping(q), resultSchema);\n if (sourceRequest.where.length !== source.where.length || result.where.length !== q.where.length) diagnostics.push(\"The query contains unsupported source or result predicates.\");\n if (result.orderBy.length !== q.orderBy.length) diagnostics.push(\"The query contains unsupported result ordering.\");\n if (q.grouping) for (const term of q.grouping.source.where) for (const predicate of predicatesOf(term))\n if (predicate.field.startsWith(\"@computed/\") && !capabilities.computedSourceFilters) diagnostics.push(\"This server does not support computed source predicates.\");\n const metricQuery = toMetricQuery(withoutGrouping(q), resultSchema, execution);\n // The projection keeps only pushdown metric-filter terms; never send the\n // narrowed population silently. (Its other diagnostics, such as calendar\n // grouping, describe the v2 transport and do not apply here.)\n diagnostics.push(...metricQuery.diagnostics.filter(issue => issue.code === \"residual_metric_filter\").map(issue => issue.message));\n const metrics = metricQuery.metrics.map(metric => {\n const dateGrouping = q.aggregations?.find(clause => clause.id === metric.id)?.dateGrouping;\n return dateGrouping ? { ...metric, dateGrouping } : metric;\n });\n for (const metric of metrics) {\n diagnostics.push(...validateMetric(metric, resultSchema).map(issue => issue.message));\n if (metric.dateGrouping && !capabilities.calendarGrouping) diagnostics.push(\"This server does not support calendar grouping.\");\n }\n const revisions: Record<string, string> = Object.create(null);\n for (const [id, revision] of Object.entries(execution?.resolvedRevisions ?? {})) {\n if (!revision || id.length > 256 || revision.length > 256) diagnostics.push(\"Invalid computed revision envelope.\");\n else revisions[id.startsWith(\"@computed/\") ? id.slice(10) : id] = revision;\n }\n return { version: 3, profile: capabilities.profile, now, expectedRevisions: revisions,\n ...(execution?.planToken ? { planToken: execution.planToken } : {}), ...(execution?.snapshot !== undefined ? { snapshot: execution.snapshot } : {}),\n source: sourceRequest, result, ...(q.grouping ? { grouping: { keys: q.grouping.keys,\n // Summary display is presentation only and link columns are computed on\n // the client; the wire contract is unchanged.\n summaries: withoutLinkSummaries(q.grouping.summaries).map(({ display: _display, ...summary }) => summary), representative: q.grouping.representative,\n ...(q.grouping.diagnostics ? { diagnostics: q.grouping.diagnostics } : {}) } } : {}), rows: options.rows !== false, metrics, diagnostics: [...new Set(diagnostics)] };\n}\nexport function validateQueryResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): void {\n if (!result || result.version !== 3 || result.now !== request.now || !Number.isSafeInteger(result.total) || result.total < 0 ||\n !Number.isSafeInteger(result.sourceTotal) || result.sourceTotal < 0 || !Array.isArray(result.rows) || !Array.isArray(result.metrics) ||\n result.execution?.profile !== request.profile || (result.execution.planToken ?? \"\") !== (request.planToken ?? \"\") ||\n (result.execution.snapshot ?? \"\") !== (request.snapshot ?? \"\") || result.schema?.idField !== schema.idField)\n throw Error(\"Invalid or mismatched query execution response.\");\n const expected = new Map(schema.fields.map(field => [field.name, field.type]));\n if (!Array.isArray(result.schema.fields) || result.schema.fields.some(field => expected.get(field.name) !== field.type) ||\n request.rows && request.result.select.some(name => !result.schema.fields.some(field => field.name === name))) throw Error(\"The server returned a different projected schema.\");\n for (const [id, revision] of Object.entries(request.expectedRevisions)) if (result.execution.resolvedRevisions[id] !== revision)\n throw Error(\"Computed definitions changed. Refresh the server execution handshake.\");\n const seen = new Set<unknown>();\n for (const row of result.rows) { const id = row[schema.idField]; if (typeof id !== \"string\" && typeof id !== \"number\" || seen.has(id)) throw Error(\"The server returned invalid or duplicate group identities.\"); seen.add(id); }\n}\n","// drilldown.ts — the query behind one metric bucket or one grouped row.\n//\n// Both helpers return a QueryState that selects exactly the records behind\n// what the user clicked, or null when no exact query exists. They never return\n// an approximate query: shown-row scopes and synthetic remainders are null.\n\nimport { compileFormula } from \"./formula\";\nimport { createGroupingModel, exitGrouping, GROUP_ID_FIELD, type GroupedRow } from \"./grouping\";\nimport { metricDateNext, metricDateTime } from \"./metricDates\";\nimport { isFilterable, resolveField, type FieldSchema } from \"./schema\";\nimport { groupKeyTerms, keyClause } from \"./groupKeys\";\nimport type { AggregationBucket } from \"./encode\";\nimport type { AggregationClause, QueryState, WhereTerm } from \"./query\";\nimport { appendWhereTerms } from \"./queryPatch\";\n\n/** Metrics over a grouped query read the group schema. Accept either that\n * schema or the source schema it is derived from. */\nfunction metricSchema(query: QueryState, schema: FieldSchema): FieldSchema {\n if (!query.grouping || schema.idField === GROUP_ID_FIELD) return schema;\n return createGroupingModel(schema).resultSchema(query.grouping.keys, query.grouping.summaries);\n}\n\nfunction distributionActive(clause: AggregationClause): boolean {\n return !!clause.distribution && (!clause.display || clause.display.kind === \"box\" || clause.display.kind === \"histogram\");\n}\n\n/** The query selecting the records behind one metric bucket, or null when no\n * exact query exists.\n *\n * - Each `clause.groupBy` key adds `=`; a null key adds `is_null` (legacy\n * aggregates already place empty text in that bucket).\n * - A date-grouped key becomes `>= start` and `< next`, using the clause's\n * interval and timezone.\n * - A histogram bin (`bucket.bin`) adds `>= min` and `< max` (`<= max` for\n * the final bin) on the distribution input, which must be a field reference.\n * Box cohorts are their group keys.\n * - The clause's own `where` is added first, so the records match the metric's\n * population. Groups hidden by `minCount` have no bucket to inspect.\n * - Over a grouped query the filters are HAVING terms on the group rows.\n * - `scope: \"shownRows\"`, a remainder bucket (keys that do not match the\n * grouping) and keys on fields that cannot be filtered return null.\n *\n * Existing terms are kept, duplicates are not added and the offset resets. */\nexport function inspectBucketQuery(\n query: QueryState,\n bucket: AggregationBucket,\n clause: AggregationClause,\n schema: FieldSchema,\n): QueryState | null {\n if (clause.scope === \"shownRows\" || bucket.keys.length !== clause.groupBy.length) return null;\n const fields = metricSchema(query, schema);\n const terms: WhereTerm[] = [...(clause.where ?? [])];\n for (const [index, name] of clause.groupBy.entries()) {\n const field = resolveField(fields, name);\n const key = bucket.keys[index] ?? null;\n if (clause.dateGrouping && index === 0 && key !== null) {\n if (!field || field.type !== \"datetime\" || !isFilterable(field)) return null;\n let start: number;\n try {\n start = metricDateTime(key);\n } catch {\n return null;\n }\n const { interval, timeZone } = clause.dateGrouping;\n const next = metricDateNext(start, interval, timeZone);\n terms.push(\n { field: field.name, op: \">=\", value: new Date(start).toISOString() },\n { field: field.name, op: \"<\", value: new Date(next).toISOString() },\n );\n continue;\n }\n const term = keyClause(field, key);\n if (!term) return null;\n terms.push(term);\n }\n if (bucket.bin) {\n const { min, max, inclusiveMax } = bucket.bin;\n if (!distributionActive(clause) || clause.distribution!.kind !== \"histogram\" || !Number.isFinite(min) || !Number.isFinite(max) || max < min)\n return null;\n let input;\n try {\n input = compileFormula(clause.distribution!.input, fields.fields).ast;\n } catch {\n return null;\n }\n const field = input.kind === \"field\" ? resolveField(fields, input.name) : undefined;\n if (!field || field.type !== \"number\" || !isFilterable(field)) return null;\n terms.push(\n { field: field.name, op: \">=\", value: String(min) },\n { field: field.name, op: inclusiveMax ? \"<=\" : \"<\", value: String(max) },\n );\n }\n return { ...query, where: appendWhereTerms(query.where, terms), offset: 0 };\n}\n\n/** The record query behind one grouped row, or null when the query is not\n * grouped or a key cannot be matched exactly (textarray, unknown or\n * unfilterable fields, unparseable datetimes).\n *\n * Starts from the grouping source, as leaving the grouping stage does, so its\n * WHERE, columns, order and item details are kept. Each key adds `=` (or\n * `is_null` for a null key) and the offset resets. */\nexport function groupSourceQuery(query: QueryState, group: GroupedRow, schema: FieldSchema): QueryState | null {\n if (!query.grouping) return null;\n const terms = groupKeyTerms(query.grouping.keys, group, schema);\n if (!terms) return null;\n const source = exitGrouping(query);\n return { ...source, where: appendWhereTerms(source.where, terms), offset: 0 };\n}\n"],"mappings":";AAmCA,IAAM,kBAAkB;AAAA,EACtB,OAAO,CAAC,SAAS,OAAO,QAAQ;AAAA,EAAG,SAAS;AAAA,EAAU,UAAU;AAAA,EAAU,QAAQ;AACpF;AACA,IAAM,gBAAgB,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,QAAQ,SAAS;AAC5D,IAAM,gBAAgB,CAAC,OAAO,gBAAgB,mBAAmB;AACjE,IAAM,UAA0F;AAAA,EAC9F,MAAM,EAAE,UAAU,CAAC,QAAQ,SAAS,QAAQ,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,IAAI,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE;AAAA,EAC9H,MAAM,EAAE,GAAG,iBAAiB,YAAY,cAAc;AAAA,EACtD,UAAU,EAAE,GAAG,iBAAiB,YAAY,cAAc;AAAA,EAC1D,MAAM,EAAE,GAAG,iBAAiB,YAAY,CAAC,GAAG,eAAe,gBAAgB,mBAAmB,EAAE;AAAA,EAChG,UAAU,EAAE,YAAY,CAAC,gBAAgB,WAAW,WAAW,SAAS,MAAM,GAAG,OAAO,CAAC,SAAS,QAAQ,SAAS,QAAQ,GAAG,SAAS,UAAU,UAAU,CAAC,GAAG,EAAE,EAAE;AAAA,EACnK,QAAQ;AAAA,EAAe,SAAS;AAAA,EAChC,MAAM,EAAE,QAAQ,UAAU,OAAO,QAAQ;AAAA,EACzC,MAAM,EAAE,UAAU,WAAW,OAAO,CAAC,GAAG,EAAE,EAAE;AAC9C;AAGO,SAAS,iBAAiB,KAAc,UAAU,gBAA6B;AACpF,QAAM,OAAO,CAAC,WAA0B;AAAE,UAAM,MAAM,GAAG,OAAO,KAAK,MAAM,EAAE;AAAA,EAAG;AAChF,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO,KAAK,oBAAoB;AAC3F,QAAMA,UAAS;AACf,MAAI,OAAOA,QAAO,SAAS,YAAY,CAAC,OAAO,UAAU,eAAe,KAAK,SAASA,QAAO,IAAI,EAAG,QAAO,KAAK,kBAAkB;AAClI,QAAM,UAAU,QAAQA,QAAO,IAAI;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQA,OAAM,GAAG;AACjD,QAAI,QAAQ,OAAQ;AACpB,UAAM,OAAO,OAAO,UAAU,eAAe,KAAK,SAAS,GAAG,IAAI,QAAQ,GAAG,IAAI;AACjF,QAAI,CAAC,KAAM,QAAO,KAAK,sBAAsB,GAAG,EAAE;AAClD,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,YAAI,OAAO,UAAU,YAAY,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,OAAO,KAAK,CAAC,CAAC,KAAK,QAAQ,OAAO,KAAK,CAAC,CAAC,EAAG,QAAO,KAAK,GAAG,GAAG,4BAA4B,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA,MACxL,WAAW,CAAC,KAAK,SAAS,KAAc,EAAG,QAAO,KAAK,eAAe,GAAG,EAAE;AAAA,IAC7E,WAAW,SAAS,YAAY,SAAS,SAAS;AAChD,UAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,KAAK,CAAC,OAAO,OAAO,KAAK,EAAE,MAAM,CAAC,SAAS,OAAO,SAAS,aAAa,SAAS,YAAY,CAAC,WAAW,WAAW,WAAW,QAAQ,EAAE,SAAS,IAAI,EAAE,EAAG,QAAO,KAAK,WAAW,GAAG,MAAM;AAAA,IAC3P,WAAW,OAAO,UAAU,KAAM,QAAO,KAAK,GAAG,GAAG,YAAY,IAAI,EAAE;AACtE,QAAI,QAAQ,aAAc,MAAiB,SAAS,IAAK,QAAO,KAAK,wCAAwC;AAAA,EAC/G;AACA,SAAO;AAAA,IAAE,GAAGA;AAAA,IACV,GAAIA,QAAO,SAAS,EAAE,QAAQ,EAAE,GAAGA,QAAO,OAAiC,EAAE,IAAI,CAAC;AAAA,IAClF,GAAIA,QAAO,QAAQ,EAAE,OAAO,EAAE,GAAGA,QAAO,MAAgC,EAAE,IAAI,CAAC;AAAA,EACjF;AACF;;;AChCO,IAAM,iBAAiB;AAC9B,IAAM,SAAS,CAAC,OAAgB,MAAM,QACpC,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,UAAU;AACnE,IAAM,SAAS,CAAC,UACd,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAE9D,SAAS,wBACd,OAC4B;AAC5B,MAAI,CAAC,OAAO,KAAK,EAAG;AACpB,QAAM,OAAO,MAAM;AACnB,MAAI,SAAS,UAAU,SAAS,QAAQ;AACtC,QAAI;AAAE,aAAO,iBAAiB,KAAK;AAAA,IAAqB,QAClD;AAAE;AAAA,IAAQ;AAAA,EAClB;AACA,MACE,MAAM,aAAa,UACnB,EACE,OAAO,MAAM,aAAa,YAC1B,OAAO,UAAU,MAAM,QAAQ,KAC/B,MAAM,YAAY,KAClB,MAAM,YAAY;AAGpB;AACF,MAAI,CAAC,QAAQ,QAAQ,WAAW,OAAO,EAAE,SAAS,OAAO,IAAI,CAAC;AAC5D,WAAO,EAAE,KAAK;AAChB,MAAI,SAAS,YAAY;AACvB,QACE,MAAM,eAAe,UACrB,CAAC,CAAC,OAAO,gBAAgB,mBAAmB,EAAE;AAAA,MAC5C,OAAO,MAAM,UAAU;AAAA,IACzB;AAEA;AACF,WAAO;AAAA,MACL;AAAA,MACA,GAAI,MAAM,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AACA,MAAI,SAAS,YAAY;AACvB,QACE,OAAO,MAAM,aAAa,YAC1B,CAAC,aAAa,KAAK,MAAM,QAAQ;AAEjC;AACF,WAAO;AAAA,MACL;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,GAAI,OAAO,MAAM,aAAa,YAC9B,OAAO,UAAU,MAAM,QAAQ,KAC/B,MAAM,YAAY,KAClB,MAAM,YAAY,KACd,EAAE,UAAU,MAAM,SAAS,IAC3B,CAAC;AAAA,IACP;AAAA,EACF;AACA,MACE,CAAC,CAAC,UAAU,WAAW,YAAY,QAAQ,QAAQ,UAAU,EAAE;AAAA,IAC7D,OAAO,IAAI;AAAA,EACb;AAEA;AACF,MACE,MAAM,eAAe,UACrB,CAAC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,OAAO,MAAM,UAAU,CAAC;AAEnC;AACF,MACE,MAAM,UAAU,UAChB,CAAC,CAAC,SAAS,QAAQ,SAAS,UAAU,KAAK,EAAE,SAAS,OAAO,MAAM,KAAK,CAAC;AAEzE;AACF,MAAI,MAAM,YAAY,UAAa,CAAC,OAAO,MAAM,SAAS,GAAI,EAAG;AACjE,MAAI,MAAM,aAAa,UAAa,CAAC,OAAO,MAAM,QAAQ,EAAG;AAC7D,QAAM,MAA+B,EAAE,KAAK;AAC5C,MACE,OAAO,MAAM,aAAa,YAC1B,OAAO,UAAU,MAAM,QAAQ,KAC/B,MAAM,YAAY,KAClB,MAAM,YAAY;AAElB,QAAI,WAAW,MAAM;AACvB,MACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,SAAS,OAAO,MAAM,UAAU,CAAC;AAEnC,QAAI,aAAa,MAAM;AACzB,MAAI,CAAC,SAAS,QAAQ,SAAS,UAAU,KAAK,EAAE,SAAS,OAAO,MAAM,KAAK,CAAC;AAC1E,QAAI,QAAQ,MAAM;AACpB,MAAI,OAAO,MAAM,SAAS,GAAI,EAAG,KAAI,UAAU,MAAM;AACrD,MAAI,OAAO,MAAM,QAAQ,EAAG,KAAI,WAAW,MAAM;AACjD,SAAO;AACT;AAGO,SAAS,sBAAsB,OAAmC;AACvE,MAAI,CAAC,OAAO,KAAK,KAAK,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,MAAM,UAAU;AAC1E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,MAAI,MAAM,WAAW,SAAS;AAC5B,UAAM,IAAI,MAAM,WAAW,cAAc,0BAA0B;AACrE,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,aAAa,MAAM,WAAW,IAAI,CAAC,SAA4B;AACnE,QACE,CAAC,OAAO,IAAI,KACZ,CAAC,OAAO,KAAK,EAAE,KACf,CAAC,OAAO,KAAK,KAAK,KAClB,IAAI,IAAI,KAAK,EAAE;AAEf,YAAM,IAAI,MAAM,uDAAuD;AACzE,QAAI,IAAI,KAAK,EAAE;AACf,UAAM,WAA8B,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,MAAM;AACrE,QAAI,OAAO,KAAK,OAAO,GAAI,EAAG,UAAS,QAAQ,KAAK;AACpD,QAAI,OAAO,KAAK,MAAM,EAAG,UAAS,SAAS,KAAK;AAChD,QAAI,KAAK,WAAW,QAAW;AAC7B,YAAM,SAAS,wBAAwB,KAAK,MAAM;AAClD,UAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+BAA+B,KAAK,EAAE,GAAG;AACtE,eAAS,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACT,CAAC;AACD,QAAM,aAAa,OAAO,MAAM,eAAe,YAAY,OAAO,SAAS,MAAM,UAAU,IACvF,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI;AAC/D,SAAO,EAAE,SAAS,GAAG,YAAY,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC,EAAG;AACvF;AAEO,SAAS,mBACd,QACA,OACmB;AACnB,QAAM,UAAU,OAAO,OAAO,OAAO,CAACC,OAAMA,GAAE,UAAU,YAAY,KAAK;AACzE,QAAM,sBAAsB,QAAQ;AAAA,IAClC,CAACA,OAAMA,GAAE,UAAU,YAAY;AAAA,EACjC;AACA,QAAM,WAAW,sBACb,QAAQ,OAAO,CAACA,OAAMA,GAAE,UAAU,OAAO,EAAE,IAAI,CAACA,OAAMA,GAAE,IAAI,IAC3D,OAAO,eAAe,IAAI,CAAC,WAAW,OAAO,KAAK,KACnD,QAAQ,OAAO,CAACA,OAAMA,GAAE,QAAQ,OAAO,EAAE,IAAI,CAACA,OAAMA,GAAE,IAAI;AAC9D,QAAM,SACJ,UACC,uBAAuB,SAAS,SAC7B,SAAS,OAAO,CAAC,SAAS,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,IAAI,CAAC,IACtE,QAAQ,IAAI,CAACA,OAAMA,GAAE,IAAI;AAC/B,SAAO,sBAAsB;AAAA,IAC3B,SAAS;AAAA,IACT,YAAY,OAAO,IAAI,CAAC,OAAO,OAAO,EAAE,IAAI,YAAY,CAAC,IAAI,MAAM,EAAE;AAAA,EACvE,CAAC;AACH;AAuCO,SAAS,mBAAmB,WAAoC;AACrE,SAAO,KAAK,UAAU;AAAA,IACpB,UAAU;AAAA,IACV,OAAO,QAAQ,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA,EACrE,CAAC;AACH;AACO,SAAS,oBACd,OACA,QACA,KACwB;AACxB,QAAM,eAAe,MAAM;AAC3B,MAAI,CAAC,aAAc,QAAO;AAC1B,QAAM,MAA6B,uBAAO,OAAO,IAAI;AACrD,aAAW,CAAC,QAAQ,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG,GAAG;AAC9D,UAAM,SAAS,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,KAAK;AAClD,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,QAAQ,eAAe,QAAQ,GAAG;AACxC,QACE,EACG,OAAO,UAAU,YAAY,UAAU,MACvC,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAGrD,aAAO;AACT,QAAI,MAAM,IAAI;AAAA,EAChB;AACA,SAAO,OAAO,KAAK,GAAG,EAAE,SACpB,EAAE,YAAY,aAAa,YAAY,IAAI,IAC3C;AACN;AAGO,SAAS,2BACd,QACA,MACA,OACiB;AACjB,SAAO,OAAO,IAAI,CAAC,UAAU;AAC3B,QAAI,MAAM,gBAAgB,CAAC,MAAM,OAAQ,QAAO;AAChD,UAAM,aAAkC,CAAC;AACzC,eAAW,MAAM,MAAM;AACrB,UACE,GAAG,gBAAgB,MAAM,OAAO,SAChC,CAAC,GAAG,cAAc,SAAS,MAAM,OAAO,MAAM,KAC9C,GAAG,cAAc,WAAW,KAC5B,GAAG,cAAc,WAAW,GAAG,cAAc;AAE7C;AACF,YAAM,UAAU,MAAM;AAAA,QACpB,CAAC,SACC,KAAK,UAAU,GAAG,eAClB,KAAK,UAAU,WAAW,GAAG,cAAc,UAC3C,KAAK,UAAU,MAAM,CAAC,MAAM,GAAG,cAAc,SAAS,CAAC,CAAC;AAAA,MAC5D;AACA,UAAI,QAAQ,WAAW,EAAG;AAC1B,YAAM,MAA8B,uBAAO,OAAO,IAAI;AACtD,UAAI,WAAW;AACf,SAAG,cAAc,QAAQ,CAAC,QAAQ,MAAM;AACtC,cAAM,QAAQ,OAAO;AAAA,UACnB,CAACA,OACCA,GAAE,QAAQ,UAAU,GAAG,eAAeA,GAAE,OAAO,WAAW;AAAA,QAC9D;AACA,YAAI,MAAM,WAAW,EAAG,YAAW;AAAA,YAC9B,KAAI,GAAG,cAAc,CAAC,CAAE,IAAI,MAAM,CAAC,EAAG;AAAA,MAC7C,CAAC;AACD,UAAI,SAAU,YAAW,KAAK,EAAE,YAAY,QAAQ,CAAC,EAAG,MAAM,IAAI,CAAC;AAAA,IACrE;AACA,WAAO,WAAW,WAAW,IACzB,EAAE,GAAG,OAAO,cAAc,WAAW,CAAC,EAAG,IACzC;AAAA,EACN,CAAC;AACH;;;AChJO,SAAS,aAAaC,IAAsB;AACjD,MAAIA,GAAE,OAAO,SAAS,aAAaA,GAAE,OAAO,WAAY,QAAO;AAC/D,SAAOA,GAAE,QAAQ,WAAWA,GAAE,OAAO,SAAS;AAChD;AACO,SAAS,iBAAiBA,IAAsB;AACrD,SAAO,aAAaA,EAAC,MAAMA,GAAE,QAAQ,YAAYA,GAAE,OAAO,SAAS;AACrE;AACO,SAAS,WAAWA,IAAsB;AAC/C,MAAIA,GAAE,OAAO,SAAS,aAAaA,GAAE,OAAO,WAAY,QAAOA,GAAE,MAAM,YAAY;AACnF,SAAOA,GAAE,MAAM,WAAWA,GAAE,OAAO,SAAS;AAC9C;AACO,SAAS,aAAaA,IAAsB;AACjD,SAAOA,GAAE,QAAQ,WAAW;AAC9B;AACO,SAAS,aAAaA,IAA2B;AACtD,SAAOA,GAAE,QAAQ,UAAU,EAAE,QAAQ,eAAe;AACtD;AAKO,SAAS,YAAiB,QAAsD;AACrF,SAAO,IAAI,IAAI,OAAO,OAAO,IAAI,CAACA,OAAM,CAACA,GAAE,MAAMA,EAAC,CAAC,CAAC;AACtD;AAKO,SAAS,eACd,QACA,GACiB;AACjB,QAAM,QACJ,EAAE,OAAO,SAAS,IACd,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,KAC1B,OAAO,iBAAiB,OAAO,OAAO,OAAO,CAACA,OAAMA,GAAE,QAAQ,OAAO,EAAE,IAAI,CAACA,QAAO,EAAE,OAAOA,GAAE,KAAK,EAAE,GAAG;AAAA,IACvG,CAAC,MAAM,EAAE;AAAA,EACX;AACN,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAuB,CAAC;AAC9B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,IAAI,IAAI,EAAG;AACpB,UAAMA,KAAI,aAAa,QAAQ,IAAI;AACnC,QAAI,CAACA,MAAK,CAAC,aAAaA,EAAC,EAAG;AAC5B,SAAK,IAAI,IAAI;AACb,SAAK,IAAIA,GAAE,IAAI;AACf,QAAI,KAAKA,EAAC;AAAA,EACZ;AACA,SAAO;AACT;AAIO,SAAS,aAAkB,QAA0B,OAA0C;AACpG,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,SAAS,YAAY,MAAM;AACjC,QAAM,cAAc,OAAO,IAAI,KAAK;AACpC,MAAI,YAAa,QAAO;AAExB,QAAM,SAAS,MAAM,YAAY;AACjC,aAAWA,MAAK,OAAO,QAAQ;AAC7B,QAAIA,GAAE,KAAK,YAAY,MAAM,OAAQ,QAAOA;AAC5C,QAAI,aAAaA,IAAG,MAAM,EAAG,QAAOA;AAAA,EACtC;AACA,SAAO;AACT;AAGO,SAAS,iBAAsB,QAA0B,OAAmC;AACjG,SAAO,aAAa,QAAQ,KAAK,GAAG;AACtC;AAGO,SAAS,cAAmB,OAAgC;AACjE,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAE7B,QAAM,MAAM,CAAC,QAAiB;AAC5B,QAAI,OAAO,QAAQ,SAAU;AAC7B,UAAM,QAAQ,IAAI,KAAK;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,MAAM,MAAM,YAAY;AAC9B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,QAAI,KAAK,KAAK;AAAA,EAChB;AAEA,MAAI,MAAM,KAAK;AACf,MAAI,MAAM,SAAS;AACjB,eAAW,SAAS,MAAM,QAAS,KAAI,KAAK;AAAA,EAC9C;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,OAAiB,QAAyB;AAC9D,aAAW,SAAS,cAAc,KAAK,GAAG;AACxC,QAAI,MAAM,YAAY,MAAM,OAAQ,QAAO;AAAA,EAC7C;AACA,SAAO;AACT;AAIO,SAAS,eAAiC,OAAyB,KAAoB;AAC5F,MAAI,OAAO,KAAM,QAAO;AACxB,MAAI,MAAM,OAAO,SAAS,aAAa,MAAM,OAAO,UAAU;AAC5D,WAAO,MAAM,OAAO,SAAS,GAAG;AAAA,EAClC;AACA,QAAM,OAAQ,MAAM,OAAO,SAAS,aAAa,MAAM,OAAO,QAAS,MAAM;AAC7E,QAAM,IAAI;AACV,MAAI,QAAQ,EAAG,QAAQ,EAAE,IAAI,KAAK;AAClC,MAAI,MAAe;AACnB,aAAW,QAAQ,KAAK,MAAM,GAAG,GAAG;AAClC,QAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACnD,UAAO,IAAgC,IAAI;AAAA,EAC7C;AACA,SAAQ,OAAO;AACjB;AAMO,SAAS,WAAsB,KAAgC;AACpE,QAAM,IAAI;AACV,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,OAAM,IAAI,MAAM,mCAAmC;AACpF,MAAI,OAAO,EAAE,SAAS,SAAU,OAAM,IAAI,MAAM,wBAAwB;AACxE,MAAI,OAAO,EAAE,YAAY,SAAU,OAAM,IAAI,MAAM,2BAA2B;AAC9E,MAAI,CAAC,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,WAAW,EAAG,OAAM,IAAI,MAAM,4CAA4C;AAEnH,QAAM,SAA0B,EAAE,OAAO,IAAI,CAAC,KAAU,MAAc,aAAkB,KAAK,CAAC,CAAC;AAC/F,SAAO;AAAA,IACL,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,IACX;AAAA,IACA,aAAa,EAAE;AAAA,IACf,eAAe,EAAE;AAAA,IACjB,cAAc,EAAE;AAAA,EAClB;AACF;AAEA,SAAS,aAAkB,KAAU,GAA0B;AAC7D,MAAI,CAAC,OAAO,OAAO,IAAI,SAAS,SAAU,OAAM,IAAI,MAAM,iBAAiB,CAAC,oBAAoB;AAChG,MAAI,OAAO,IAAI,UAAU,SAAU,OAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,oBAAoB;AAChG,MAAI,OAAO,IAAI,SAAS,SAAU,OAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,mBAAmB;AAC9F,MAAI,IAAI,aAAa,QAAW;AAC9B,UAAM,WAAW,IAAI;AACrB,QAAI,CAAC,YAAY,OAAO,aAAa,YAAY,MAAM,QAAQ,QAAQ,KACjE,SAAS,YAAY,UAAa,OAAO,SAAS,YAAY,aAC9D,SAAS,YAAY,UAAa,OAAO,SAAS,YAAY,aAC9D,SAAS,WAAW,WAAc,OAAO,SAAS,WAAW,YAAY,CAAC,SAAS,SAAU;AACjG,YAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,gCAAgC;AAAA,IAC3E;AACA,QAAI,SAAS,WAAW,UAAa,CAAC,wBAAwB,SAAS,MAAM,GAAG;AAC9E,YAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,iCAAiC;AAAA,IAC5E;AAAA,EACF;AACA,MAAI,IAAI,WAAW,WAAc,CAAC,IAAI,UACjC,OAAO,IAAI,OAAO,UAAU,YAAY,CAAC,IAAI,OAAO,SACpD,OAAO,IAAI,OAAO,WAAW,YAAY,CAAC,IAAI,OAAO,SAAS;AACjE,UAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,wBAAwB;AAAA,EACnE;AACA,MAAI,IAAI,iBAAiB,WAAc,CAAC,IAAI,gBACvC,OAAO,IAAI,aAAa,eAAe,YAAY,CAAC,IAAI,aAAa,cACrE,CAAC,IAAI,aAAa,OAAO,OAAO,IAAI,aAAa,QAAQ,YACzD,MAAM,QAAQ,IAAI,aAAa,GAAG,KAAK,OAAO,KAAK,IAAI,aAAa,GAAG,EAAE,WAAW,KACpF,OAAO,QAAQ,IAAI,aAAa,GAAG,EAAE,KAAK,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,OAAO,UAAU,YAAY,CAAC,KAAK,IAAI;AAC9G,UAAM,IAAI,MAAM,iBAAiB,IAAI,IAAI,8BAA8B;AAAA,EACzE;AAGA,QAAM,KAAK,IAAI,WAAW,IAAI,WAAW,YAAY;AACrD,MAAI;AACJ,MAAI,OAAO,OAAO,UAAU;AAC1B,aAAS,OAAO,YAAY,EAAE,MAAM,UAAU,IAAI,EAAE,MAAM,UAAU;AAAA,EACtE,WAAW,GAAG,SAAS,WAAW;AAChC,aAAS,EAAE,MAAM,UAAU;AAAA,EAC7B,OAAO;AACL,aAAS,EAAE,MAAM,WAAW,MAAM,GAAG,MAAM,WAAW,GAAG,UAAU;AAAA,EACrE;AAEA,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,MAAM,IAAI;AAAA,IACV;AAAA,IACA,QAAQ,IAAI;AAAA,IACZ,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI;AAAA,IACf,OAAO,IAAI;AAAA,IACX,OAAO,IAAI;AAAA,IACX,SAAS,iBAAiB,IAAI,SAAS,IAAI,KAAK;AAAA,IAChD,GAAI,IAAI,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,iBAAiB,IAAI,SAAS,iBAAiB,IAAI,IAAI,UAAU,EAAE;AAAA,IACnH,QAAQ,IAAI;AAAA;AAAA,IACZ,UAAU,IAAI,WAAW,EAAE,GAAG,IAAI,UAAU,QAAQ,IAAI,SAAS,WAAW,SAAY,SAAY,wBAAwB,IAAI,SAAS,MAAM,EAAE,IAAI;AAAA,IACrJ,QAAQ,IAAI;AAAA,IACZ,cAAc,IAAI;AAAA,EACpB;AACF;AAEA,SAAS,iBAAiB,YAAqB,UAA6B;AAC1E,QAAM,UAAoB,CAAC;AAC3B,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAM,CAAC,QAAiB;AAC5B,QAAI,OAAO,QAAQ,SAAU;AAC7B,UAAM,QAAQ,IAAI,KAAK;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,MAAM,MAAM,YAAY;AAC9B,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,SAAK,IAAI,GAAG;AACZ,YAAQ,KAAK,KAAK;AAAA,EACpB;AAEA,MAAI,QAAQ;AACZ,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,eAAW,QAAQ,WAAY,KAAI,IAAI;AAAA,EACzC;AACA,SAAO;AACT;;;AC3YA,IAAM,sBAAsB;AAC5B,IAAM,OAAO;AACb,IAAM,mBAAmB,CAAC,MAAM,OAAO;AAEvC,SAAS,aAAa,QAAmC;AACvD,SAAO,IAAI,OAAO,OAAO,CAAC,GAAG,QAAQ,cAAc,EAAE,KAAK,GAAG,CAAC,QAAQ,GAAG;AAC3E;AAEA,SAAS,eAAe,MAAuB;AAC7C,MAAI;AACF,WAAO,CAAC,SAAS,QAAQ,EAAE,SAAS,IAAI,IAAI,MAAM,IAAI,EAAE,QAAQ;AAAA,EAClE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,eAAe,UAA4B;AACzD,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,KAAK,SAAS,SAAS,qBAAqB,GAAG,WAAS,MAAM,CAAC,CAAE,CAAC,CAAC;AAC9F;AAKO,SAAS,mBAAmB,UAAkB,QAA2B,UAAoD;AAClI,MAAI,SAAS,SAAS,oBAAqB,QAAO;AAClD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,YAAY,SAAS,QAAQ,aAAa,MAAM,GAAG,OAAO;AAChE,MAAI,OAAO,KAAK,SAAS,GAAG;AAC1B,UAAM,QAAQ,CAAC,GAAG,OAAO,IAAI,WAAS,IAAI,KAAK,GAAG,GAAG,oBAAoB;AACzE,UAAM,OAAO,MAAM,SAAS,IAAI,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,SAAS,IAAI,MAAM,EAAE,OAAO,MAAM,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC;AAC7H,WAAO,OAAO,IAAI;AAAA,EACpB;AACA,aAAW,QAAQ,eAAe,QAAQ,GAAG;AAC3C,QAAI,CAAC,SAAS,IAAI,EAAG,QAAO,sBAAsB,IAAI;AAAA,EACxD;AACA,MAAI;AACF,QAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,IAAI,IAAI,WAAW,IAAI,EAAE,QAAQ;AACjE,aAAO;AAAA,EACX,QAAQ;AAAE,WAAO;AAAA,EAA2B;AAC5C,SAAO;AACT;AAMO,SAAS,gBAAgB,UAAkB,QAA2B,MAAiD;AAC5H,MAAI,UAAU;AACd,QAAM,OAAO,SAAS,QAAQ,aAAa,MAAM,GAAG,CAAC,QAAQ,UAAkB;AAC7E,UAAM,QAAQ,KAAK,KAAK;AACxB,QAAI,SAAS,QAAQ,CAAC,CAAC,UAAU,UAAU,SAAS,EAAE,SAAS,OAAO,KAAK,GAAG;AAAE,gBAAU;AAAM,aAAO;AAAA,IAAI;AAC3G,WAAO,mBAAmB,OAAO,KAAK,CAAC;AAAA,EACzC,CAAC;AAED,SAAO,WAAW,CAAC,eAAe,IAAI,IAAI,OAAO;AACnD;AAEO,SAAS,eAAe,UAA4B;AACzD,SAAO,eAAe,QAAQ;AAChC;AACO,SAAS,yBAA8B,UAAkB,QAAyC;AACvG,SAAO,mBAAmB,UAAU,kBAAkB,UAAQ,OAAO,OAAO,KAAK,WAAS,MAAM,SAAS,IAAI,CAAC;AAChH;AACO,SAAS,uBAA4B,UAAkB,QAA0B,KAAU,IAAkB,OAA8B;AAChJ,MAAI,CAAC,SAAS,KAAK,KAAK,yBAAyB,UAAU,MAAM,EAAG,QAAO;AAC3E,SAAO,gBAAgB,UAAU,kBAAkB,WAAS,UAAU,OAAO,KAAK,UAAU,UAAU,QAClG,eAAe,OAAO,OAAO,KAAK,WAAS,MAAM,SAAS,MAAM,MAAM,CAAC,CAAC,GAAI,GAAG,CAAC;AACtF;;;ACzEO,SAAS,uBACd,KAC4B;AAC5B,QAAM,MAA+B,CAAC,GACpC,cAAwB,CAAC;AAC3B,QAAMC,UAAS,CAAC,MACd,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AAClD,QAAM,OAAO,CACX,OACA,UAI4B;AAC5B,UAAM,SAAkC,CAAC;AACzC,eAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC/C,YAAM,IAAI,MAAM,GAAG;AACnB,UAAI,MAAM,OAAW;AACrB,UACE,SAAS,WACL,OAAO,MAAM,YAAY,EAAE,UAAU,MACrC,SAAS,WACP,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAC1C,SAAS,YACP,OAAO,MAAM,YACb,SAAS,aAAa,SAAS,oBAC7B,OAAO,MAAM,YACb,OAAO,cAAc,CAAC,KACtB,MAAM,SAAS,oBAAoB,IAAI,MACvC,KAAK,MACL,OAAO,MAAM,YAAY,KAAK,SAAS,CAAC;AAElD,eAAO,GAAG,IAAI;AAAA,UACX,aAAY,KAAK,kBAAkB,GAAG,GAAG;AAAA,IAChD;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA,KAAK,KAAK;AAAA,MACR,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,OAAO,CAAC,eAAe,WAAW;AAAA,MAClC,YAAY;AAAA,MACZ,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,MAAI,IAAI,iBAAiB,QAAW;AAClC,QAAIA,QAAO,IAAI,YAAY,GAAG;AAC5B,YAAM,IAAI,KAAK,IAAI,cAAc;AAAA,QAC/B,OAAO;AAAA,QACP,UAAU,CAAC,QAAQ,OAAO,QAAQ,SAAS,MAAM;AAAA,QACjD,UAAU;AAAA,QACV,cAAc;AAAA,QACd,OAAO,CAAC,SAAS,YAAY,QAAQ;AAAA,QACrC,OAAO;AAAA,QACP,KAAK;AAAA,MACP,CAAC;AACD,UACE,OAAO,EAAE,UAAU,YACnB,CAAC,EAAE,SACH,EAAE,MAAM,SAAS,OACjB,CAAC,EAAE,YACH,OAAO,EAAE,iBAAiB,aAC1B,CAAC,EAAE;AAEH,oBAAY,KAAK,+BAA+B;AAClD,UAAI,eAAe;AAAA,IACrB,MAAO,aAAY,KAAK,+BAA+B;AAAA,EACzD;AACA,MAAI,IAAI,YAAY,QAAW;AAC7B,QAAIA,QAAO,IAAI,OAAO,GAAG;AACvB,UAAI,OAAO,IAAI,QAAQ,SAAS;AAC9B,oBAAY,KAAK,8BAA8B;AACjD,YAAM,IAAI,KAAK,IAAI,SAAS;AAAA,QAC1B,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,gBAAgB,CAAC,QAAQ,SAAS,OAAO,UAAU,MAAM;AAAA,QACzD,WAAW;AAAA,QACX,WAAW;AAAA,QACX,SAAS;AAAA,MACX,CAAC;AACD,iBAAW,KAAK,CAAC,UAAU,QAAQ,GAAG;AACpC,YAAIA,QAAO,IAAI,QAAQ,CAAC,CAAC;AACvB,YAAE,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG;AAAA,YAC1B,MAAM,CAAC,UAAU,KAAK;AAAA,YACtB,KAAK;AAAA,YACL,KAAK;AAAA,UACP,CAAC;AAAA,iBACM,IAAI,QAAQ,CAAC,MAAM;AAC1B,sBAAY,KAAK,kBAAkB,CAAC,GAAG;AAAA,MAC3C;AACA,iBAAW,KAAK,CAAC,UAAU,WAAW,SAAS;AAC7C,YAAIA,QAAO,IAAI,QAAQ,CAAC,CAAC;AACvB,YAAE,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG;AAAA,YAC1B,MAAM,CAAC,UAAU,WAAW,YAAY,QAAQ,QAAQ,UAAU;AAAA,YAClE,UAAU;AAAA,YACV,YAAY;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,YACA,OAAO,CAAC,SAAS,QAAQ,SAAS,UAAU,KAAK;AAAA,YACjD,SAAS;AAAA,YACT,UAAU;AAAA,UACZ,CAAC;AACL,UAAIA,QAAO,IAAI,QAAQ,IAAI;AACzB,UAAE,OAAO,KAAK,IAAI,QAAQ,MAAM;AAAA,UAC9B,UAAU;AAAA,UACV,gBAAgB;AAAA,UAChB,YAAY;AAAA,UACZ,aAAa,CAAC,UAAU,OAAO;AAAA,UAC/B,eAAe;AAAA,QACjB,CAAC;AACH,UAAIA,QAAO,IAAI,QAAQ,KAAK;AAC1B,UAAE,QAAQ,KAAK,IAAI,QAAQ,OAAO;AAAA,UAChC,MAAM;AAAA,UACN,QAAQ,CAAC,OAAO,MAAM;AAAA,UACtB,WAAW,CAAC,OAAO,MAAM;AAAA,QAC3B,CAAC;AACH,UAAI,UAAU,EAAE,MAAM,QAAQ,GAAG,EAAE;AAAA,IACrC,MAAO,aAAY,KAAK,yBAAyB;AAAA,EACnD;AACA,MAAI,IAAI,iBAAiB,QAAW;AAClC,QAAIA,QAAO,IAAI,YAAY;AACzB,UAAI,eAAe,KAAK,IAAI,cAAc;AAAA,QACxC,MAAM,CAAC,OAAO,WAAW;AAAA,QACzB,OAAO;AAAA,QACP,UAAU,CAAC,UAAU,OAAO;AAAA,QAC5B,MAAM;AAAA,MACR,CAAC;AAAA,QACE,aAAY,KAAK,8BAA8B;AAAA,EACtD;AACA,MAAIA,QAAO,IAAI,MAAM,GAAG;AACtB,UAAM,IAAI,KAAK,IAAI,QAAQ;AAAA,MACzB,UAAU;AAAA,MACV,WAAW;AAAA,MACX,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AACD,eAAW,KAAK,CAAC,YAAY,aAAa,eAAe,cAAc;AACrE,QAAE,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AACtD,MAAE,WAAW,KAAK,IAAI,OAAO,EAAE,QAAQ,GAAG,OAAO,EAAE,WAAW,CAAC;AAC/D,MAAE,YAAY,KAAK,IAAI,OAAO,EAAE,SAAS,GAAG,OAAO,EAAE,YAAY,CAAC;AAClE,QAAI,SAAS;AAAA,EACf;AACA,MAAI,IAAI,SAAS,UAAa,CAAC,MAAM,QAAQ,IAAI,IAAI;AACnD,gBAAY,KAAK,sBAAsB;AACzC,MAAI,MAAM,QAAQ,IAAI,IAAI;AACxB,QAAI,OAAO,IAAI,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,CAAC,MAAM;AAC9C,UACE,CAACA,QAAO,CAAC,KACT,OAAO,EAAE,QAAQ,YACjB,CAAC,mDAAmD,KAAK,EAAE,GAAG,KAC9D,CAAC,CAAC,OAAO,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,CAAC,GACvC;AACA,oBAAY,KAAK,sBAAsB;AACvC,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL,KAAK,GAAG;AAAA,UACN,KAAK,CAAC,EAAE,GAAG;AAAA,UACX,KAAK,CAAC,OAAO,MAAM;AAAA,UACnB,OAAO,CAAC,SAAS,MAAM;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACH,MAAI,MAAM,QAAQ,IAAI,WAAW;AAC/B,gBAAY;AAAA,MACV,GAAG,IAAI,YACJ,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,UAAU,GAAI,EACpE,MAAM,GAAG,EAAE;AAAA,IAChB;AACF,MAAI,YAAY,OAAQ,KAAI,cAAc,CAAC,GAAG,IAAI,IAAI,WAAW,CAAC;AAClE,SAAO;AACT;;;AC9GO,SAAS,UAAU,MAAkC;AAC1D,SAAO,MAAM,QAAS,KAAiB,GAAG;AAC5C;AAKO,SAAS,aAAa,MAAgC;AAC3D,SAAO,UAAU,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI;AAC3C;AAsFO,IAAM,sBAAsB;AA2C5B,IAAM,cAA0B;AAAA,EACrC,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC;AAAA,EACR,SAAS,CAAC;AAAA,EACV,OAAO;AAAA,EACP,QAAQ;AACV;AAMO,IAAM,kBAAkB,OAAO;AAC/B,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB;AAC3B,IAAM,mBAAmB;AACzB,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB,IAAI,OAAO;AAEjD,IAAM,wBAAwB;AAC9B,IAAM,0BAA0B;AAChC,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AACzB,IAAM,mBAAmB;AAEzB,IAAM,aAAkC,oBAAI,IAAI;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,UAA+B,oBAAI,IAAI,CAAC,SAAS,kBAAkB,OAAO,OAAO,OAAO,KAAK,CAAC;AAEpG,SAAS,SAAS,OAAkD;AAClE,SAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,cAAc,OAAgB,WAAkC;AACvE,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,UAAU,YAAY,QAAQ;AAC9F;AAEA,SAAS,eAAe,OAAgB,UAAkB,KAAa,KAAqB;AAC1F,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,EAAG,QAAO;AACjE,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC;AACvD;AAIA,SAAS,qBAAqB,MAAmC;AAC/D,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,QAAM,QAAQ,cAAc,KAAK,OAAO,qBAAqB;AAC7D,QAAM,QAAQ,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,UAAU,0BAA0B,KAAK,QAAQ;AAC5G,MAAI,CAAC,SAAS,OAAO,KAAK,OAAO,YAAY,CAAC,WAAW,IAAI,KAAK,EAAE,KAAK,SAAS,MAAM;AACtF,WAAO;AAAA,EACT;AACA,QAAM,SAAsB,EAAE,OAAO,IAAI,KAAK,IAAgB,MAAM;AACpE,MAAI,KAAK,YAAY,KAAM,QAAO,UAAU;AAC5C,SAAO;AACT;AAIA,SAAS,eAAe,MAA4B;AAClD,QAAM,OAAO,UAAU,IAAI,IAAI,EAAE,GAAG,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK;AAC7F,MAAI,KAAK,UAAW,MAAK,YAAY,EAAE,GAAG,KAAK,WAAW,QAAQ,CAAC,GAAG,KAAK,UAAU,MAAM,EAAE;AAC7F,SAAO;AACT;AAEA,SAAS,mBAAmB,MAA8C;AACxE,MAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,QAAM,KAAK,cAAc,KAAK,IAAI,qBAAqB;AACvD,MAAI,CAAC,MAAM,CAAC,CAAC,OAAO,OAAO,QAAQ,OAAO,EAAE,SAAS,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,KAAK,MAAM,EAAG,QAAO;AAC/G,MAAI,KAAK,OAAO,SAAS,qBAAqB,CAAC,KAAK,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,UAAU,uBAAuB,EAAG,QAAO;AAC1J,SAAO,EAAE,IAAI,MAAM,KAAK,MAAuB,QAAQ,CAAC,GAAG,KAAK,MAAM,EAAc;AACtF;AAEA,SAAS,oBAAoB,OAAwC;AACnE,QAAM,QAAqB,CAAC;AAC5B,MAAI,gBAAgB;AACpB,aAAW,QAAQ,OAAO;AACxB,QAAI,iBAAiB,EAAG;AACxB,UAAM,QAAQ,MAAM;AACpB,QAAI,SAAS,IAAI,KAAK,MAAM,QAAS,KAA2B,GAAG,GAAG;AACpE,YAAM,UAAyB,CAAC;AAChC,iBAAW,SAAU,KAA4B,KAAK;AACpD,YAAI,iBAAiB,EAAG;AACxB,cAAM,SAAS,qBAAqB,KAAK;AACzC,YAAI,QAAQ;AACV,kBAAQ,KAAK,MAAM;AACnB;AAAA,QACF;AAAA,MACF;AACA,UAAI,QAAQ,WAAW,EAAG,OAAM,KAAK,QAAQ,CAAC,CAAE;AAAA,eACvC,QAAQ,SAAS,EAAG,OAAM,KAAK,EAAE,KAAK,QAAQ,CAAC;AAAA,IAE1D,OAAO;AACL,YAAM,SAAS,qBAAqB,IAAI;AACxC,UAAI,QAAQ;AACV,cAAM,KAAK,MAAM;AACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,MAAM,SAAS,SAAS,SAAS,IAAI,GAAG;AAC1C,YAAM,WAAW,mBAAmB,KAAK,SAAS;AAClD,UAAI,SAAU,OAAM,KAAK,EAAG,YAAY;AAAA,IAC1C;AAAA,EACF;AACA,SAAO;AACT;AAIA,SAAS,qBAAqB,OAA2D;AACvF,MAAI,UAAU,OAAW,QAAO,EAAE,SAAS,MAAM;AACjD,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,EAAE,SAAS,KAAK;AAClD,QAAM,QAAQ,oBAAoB,KAAK;AACvC,QAAM,WAAW,MAAM,OAAO,CAAC,OAAe,SAC5C,SAAS,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,IAAI,SAAS,IAAI,CAAC;AAC9E,QAAM,OAAO,MAAM,OAAO,CAAC,OAAO,SAAS,QAAQ,aAAa,IAAI,EAAE,QAAQ,CAAC;AAC/E,SAAO,EAAE,GAAI,MAAM,SAAS,EAAE,MAAM,IAAI,CAAC,GAAI,SAAS,aAAa,KAAK;AAC1E;AAMO,SAAS,oBAAoB,OAAgB,WAAuB,aAAyB;AAClG,SAAO,eAAe,OAAO,UAAU,IAAI;AAC7C;AAGA,SAAS,eAAe,OAAgB,UAAsB,OAA4B;AACxF,QAAM,MAAM,SAAS,KAAK,IAAI,QAAQ,CAAC;AAEvC,QAAM,SAAyB,CAAC;AAChC,MAAI,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC7B,eAAW,QAAQ,IAAI,OAAO,MAAM,GAAG,kBAAkB,GAAG;AAC1D,UAAI,CAAC,SAAS,IAAI,EAAG;AACrB,YAAM,QAAQ,cAAc,KAAK,OAAO,qBAAqB;AAC7D,UAAI,CAAC,MAAO;AACZ,YAAM,SAAuB,EAAE,MAAM;AACrC,UAAI,OAAO,KAAK,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,GAAG;AACjE,eAAO,QAAQ,eAAe,KAAK,OAAO,kBAAkB,kBAAkB,gBAAgB;AAAA,MAChG;AACA,UAAI,KAAK,YAAY,QAAW;AAG9B,YAAI;AAAE,iBAAO,UAAU,iBAAiB,KAAK,SAAS,UAAU,KAAK,UAAU;AAAA,QAAG,QAAQ;AAAA,QAAgB;AAAA,MAC5G;AACA,aAAO,KAAK,MAAM;AAAA,IACpB;AAAA,EACF,OAAO;AACL,WAAO,KAAK,GAAG,SAAS,OAAO,IAAI,CAAC,YAAY,EAAE,GAAG,QAAQ,GAAI,OAAO,UAAU,EAAE,SAAS,KAAK,MAAM,KAAK,UAAU,OAAO,OAAO,CAAC,EAAiB,IAAI,CAAC,EAAG,EAAE,CAAC;AAAA,EACpK;AAMA,QAAM,QAAqB,MAAM,QAAQ,IAAI,KAAK,IAC9C,oBAAoB,IAAI,KAAK,IAC7B,SAAS,MAAM,IAAI,cAAc;AAErC,QAAM,UAA2B,CAAC;AAClC,MAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC9B,eAAW,QAAQ,IAAI,QAAQ,MAAM,GAAG,kBAAkB,GAAG;AAC3D,UAAI,CAAC,SAAS,IAAI,EAAG;AACrB,YAAM,QAAQ,cAAc,KAAK,OAAO,qBAAqB;AAC7D,UAAI,CAAC,SAAU,KAAK,QAAQ,SAAS,KAAK,QAAQ,OAAS;AAC3D,YAAM,OAAsB,EAAE,OAAO,KAAK,KAAK,IAAI;AACnD,UAAI,KAAK,UAAU,WAAW,KAAK,UAAU,OAAQ,MAAK,QAAQ,KAAK;AACvE,UACE,SAAS,KAAK,OAAO,KACrB,OAAO,KAAK,QAAQ,UAAU,YAC9B,KAAK,QAAQ,MAAM,UAAU,yBAC7B;AACA,aAAK,UAAU,EAAE,OAAO,KAAK,QAAQ,MAAM;AAAA,MAC7C;AACA,cAAQ,KAAK,IAAI;AAAA,IACnB;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACN,GAAG,SAAS,QAAQ,IAAI,CAAC,SAAU,KAAK,UAAU,EAAE,GAAG,MAAM,SAAS,EAAE,GAAG,KAAK,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,CAAE;AAAA,IAC5G;AAAA,EACF;AAEA,QAAM,MAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,eAAe,IAAI,OAAO,SAAS,OAAO,GAAG,eAAe;AAAA,IACnE,QAAQ,eAAe,IAAI,QAAQ,SAAS,QAAQ,GAAG,gBAAgB;AAAA,EACzE;AAEA,MAAI,IAAI,gBAAgB,KAAM,KAAI,cAAc;AAEhD,MAAI,IAAI,YAAY,KAAM,KAAI,WAAW,uBAAuB,IAAI,UAAU,KAAK;AAEnF,MAAI,MAAM,QAAQ,IAAI,YAAY,GAAG;AACnC,UAAM,eAAoC,CAAC;AAC3C,eAAW,QAAQ,IAAI,aAAa,MAAM,GAAG,gBAAgB,GAAG;AAC9D,UAAI,CAAC,SAAS,IAAI,EAAG;AACrB,YAAM,KAAK,cAAc,KAAK,IAAI,qBAAqB;AACvD,UAAI,CAAC,GAAI;AACT,YAAM,UAAU,OAAO,KAAK,OAAO,YAAY,QAAQ,IAAI,KAAK,EAAE;AAClE,YAAM,YAAuB,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,UAAU,CAAC;AAC3E,YAAM,UAAU,UACb,MAAM,GAAG,mBAAmB,EAC5B,IAAI,CAACC,WAAU,cAAcA,QAAO,qBAAqB,CAAC,EAC1D,OAAO,CAACA,WAA2BA,UAAS,IAAI;AACnD,YAAM,cAAiC,EAAE,IAAI,IAAI,UAAU,KAAK,KAAc,SAAS,QAAQ;AAC/F,YAAM,QAAQ,cAAc,KAAK,OAAO,qBAAqB;AAC7D,YAAM,QAAQ,cAAc,KAAK,OAAO,gBAAgB;AACxD,UAAI,MAAO,aAAY,QAAQ;AAC/B,UAAI,MAAO,aAAY,QAAQ;AAC/B,aAAO,OAAO,aAAa,uBAAuB,IAAI,CAAC;AACvD,YAAM,cAAc,qBAAqB,KAAK,KAAK;AACnD,UAAI,YAAY,MAAO,aAAY,QAAQ,YAAY;AACvD,UAAI,YAAY,QAAS,aAAY,cAAc,CAAC,GAAI,YAAY,eAAe,CAAC,GAAI,wBAAwB;AAChH,UAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,UAAU,SAAS,uBAAuB,QAAQ,WAAW,UAAU,OAAQ,aAAY,cAAc,CAAC,GAAI,YAAY,eAAe,CAAC,GAAI,6DAA6D;AAC/O,YAAM,gBAAgB,cAAc,KAAK,kBAAkB,CAAC,UAAU,KAAK,KAAK,SAAY,qBAAqB;AACjH,UAAI,cAAe,aAAY,gBAAgB;AAC/C,UAAI,KAAK,UAAU,UAAa,CAAC,MAAO,aAAY,cAAc,CAAC,GAAI,YAAY,eAAe,CAAC,GAAI,+BAA+B;AACtI,UAAI,CAAC,WAAW,OAAO,KAAK,eAAe,SAAU,aAAY,cAAc,CAAC,GAAI,YAAY,eAAe,CAAC,GAAI,kCAAkC;AACtJ,mBAAa,KAAK,WAAW;AAAA,IAC/B;AACA,QAAI,aAAa,SAAS,EAAG,KAAI,eAAe;AAAA,EAClD,WAAW,SAAS,cAAc,QAAQ;AACxC,QAAI,eAAe,oBAAoB,EAAE,cAAc,SAAS,aAAa,CAAC,EAAE;AAAA,EAClF;AAEA,MAAI,SAAS,IAAI,WAAW,KAAK,MAAM,QAAQ,IAAI,YAAY,KAAK,GAAG;AACrE,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,IAAI,YAAY,MAAM;AAAA,MAC9C,CAAC,SAAiC,OAAO,SAAS,YAAY,CAAC,SAAS,SAAS,UAAU,MAAM,EAAE,SAAS,IAAI;AAAA,IAClH,CAAC,CAAC;AACF,UAAM,UAA4B,EAAE,MAAM;AAC1C,QAAI,SAAS,IAAI,YAAY,IAAI,KAAK,OAAO,IAAI,YAAY,KAAK,gBAAgB,YAC7E,IAAI,YAAY,KAAK,YAAY,UAAU,KAAM;AACpD,cAAQ,OAAO;AAAA,QAAE,aAAa,IAAI,YAAY,KAAK;AAAA,QACjD,QAAQ,IAAI,YAAY,KAAK,WAAW,UAAU,UAAU;AAAA,MAAS;AAAA,IACzE;AACA,QAAI,IAAI,YAAY,SAAS,QAAW;AACtC,UAAI;AAAE,gBAAQ,OAAO,sBAAsB,IAAI,YAAY,IAAI;AAAA,MAAG,QAAQ;AAAA,MAAyC;AAAA,IACrH;AACA,QAAI,SAAS,IAAI,YAAY,KAAK,GAAG;AACnC,YAAM,QAAgD,CAAC;AACvD,iBAAW,QAAQ,CAAC,SAAS,SAAS,QAAQ,GAAY;AACxD,YAAI;AACF,cAAI,IAAI,YAAY,MAAM,IAAI,MAAM,OAAW,OAAM,IAAI,IAAI,sBAAsB,IAAI,YAAY,MAAM,IAAI,CAAC;AAAA,QAChH,QAAQ;AAAA,QAA6C;AAAA,MACvD;AACA,UAAI,OAAO,KAAK,KAAK,EAAE,OAAQ,SAAQ,QAAQ;AAAA,IACjD;AACA,UAAM,SAAS,IAAI,YAAY;AAC/B,QAAI,SAAS,MAAM,MAAM,OAAO,SAAS,WAAW,OAAO,SAAS,aAAa,MAAM,SAAS,OAAO,IAAI,MACpG,OAAO,OAAO,OAAO,YAAY,OAAO,GAAG,SAAS,KAAK,OAAO,GAAG,UAAU,OAC5E,OAAO,OAAO,OAAO,YAAY,OAAO,SAAS,OAAO,EAAE,IAAK;AACrE,cAAQ,SAAS,EAAE,IAAI,OAAO,IAAa,MAAM,OAAO,KAAK;AAAA,IAC/D;AACA,QAAI,cAAc;AAAA,EACpB;AAEA,SAAO;AACT;AAIA,SAAS,uBAAuB,OAAgB,OAA+B;AAC7E,QAAM,MAAM,SAAS,KAAK,IAAI,QAAQ,CAAC;AACvC,QAAM,cAAwB,CAAC;AAE/B,QAAM,OAAO,CAAC,YAAoB;AAAE,gBAAY,KAAK,qBAAqB,OAAO,EAAE;AAAA,EAAG;AACtF,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAI,IAAI,KAAK,MAAM,GAAG,mBAAmB,EAAE,OAAO,CAAC,QAAuB,CAAC,CAAC,cAAc,KAAK,qBAAqB,CAAC,IAAI,CAAC;AAC7J,MAAI,CAAC,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,KAAK,UAAU,KAAK,WAAW,IAAI,KAAK,UAAU,IAAI,IAAI,IAAI,EAAE,SAAS,KAAK;AAC7G,SAAK,yBAAoB,mBAAmB,wBAAwB;AACtE,QAAM,YAA6B,CAAC;AACpC,MAAI,CAAC,MAAM,QAAQ,IAAI,SAAS,KAAK,IAAI,UAAU,SAAS,GAAI,MAAK,iDAAiD;AACtH,QAAM,aAAa,oBAAI,IAAY;AACnC,aAAW,CAAC,OAAO,IAAI,MAAM,MAAM,QAAQ,IAAI,SAAS,IAAI,IAAI,UAAU,MAAM,GAAG,EAAE,IAAI,CAAC,GAAG,QAAQ,GAAG;AACtG,UAAM,OAAO,SAAS,IAAI,KAAK,cAAc,KAAK,IAAI,qBAAqB,IAAI,YAAY,KAAK,EAAY,MAAM,WAAW,QAAQ,CAAC;AACtI,QAAI,CAAC,SAAS,IAAI,KAAK,CAAC,cAAc,KAAK,IAAI,qBAAqB,GAAG;AAAE,WAAK,GAAG,IAAI,0BAAqB,qBAAqB,cAAc;AAAG;AAAA,IAAU;AAC1J,QAAI,OAAO,KAAK,OAAO,YAAa,CAAC,QAAQ,IAAI,KAAK,EAAE,KAAK,KAAK,OAAO,SAAS,KAAK,OAAO,cAAc,KAAK,OAAO,UAAU,CAAC,QAAS;AAC1I,WAAK,KAAK,OAAO,SACb,GAAG,IAAI,mEACP,GAAG,IAAI,uBAAuB,KAAK,UAAU,OAAO,KAAK,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC,yEAAyE,OAAO,KAAK,EAAE,EAAE,YAAY,MAAM,WAAW,wEAAwE,EAAE,GAAG;AACjR;AAAA,IACF;AACA,UAAM,SAAwB,EAAE,IAAI,KAAK,IAAc,IAAI,KAAK,GAA0B;AAG1F,QAAI,WAAW,IAAI,OAAO,EAAE,EAAG,MAAK,GAAG,IAAI,8CAA8C;AAAA,aAChF,KAAK,SAAS,OAAO,EAAE,EAAG,MAAK,GAAG,IAAI,mCAAmC,OAAO,EAAE,qDAAqD;AAChJ,eAAW,IAAI,OAAO,EAAE;AACxB,QAAI,KAAK,OAAO,QAAQ;AAEtB,YAAM,OAAO,kBAAkB,KAAK,IAAI;AACxC,UAAI,KAAM,QAAO,OAAO;AACxB,UAAI,KAAK,UAAU,QAAW;AAC5B,YAAI,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,SAAS,iBAAkB,MAAK,GAAG,IAAI,kCAAkC,iBAAiB,eAAe,OAAO,CAAC,cAAc;AAAA,YAC3K,QAAO,QAAQ,KAAK;AAAA,MAC3B;AACA,gBAAU,KAAK,MAAM;AACrB;AAAA,IACF;AACA,QAAI,KAAK,UAAU,QAAW;AAC5B,UAAI,CAAC,cAAc,KAAK,OAAO,qBAAqB,EAAG,MAAK,GAAG,IAAI,6BAA6B;AAAA,UAC3F,QAAO,QAAQ,KAAK;AAAA,IAC3B;AACA,QAAI,KAAK,OAAO,WAAW;AACzB,UAAI,OAAO,KAAK,eAAe,YAAY,KAAK,WAAW,SAAS,IAAQ,MAAK,GAAG,IAAI,oDAAoD;AAAA,UACvI,QAAO,aAAa,KAAK;AAAA,IAChC;AACA,QAAI,KAAK,UAAU,QAAW;AAC5B,UAAI,OAAO,KAAK,UAAU,YAAY,KAAK,MAAM,SAAS,iBAAkB,MAAK,GAAG,IAAI,kCAAkC,iBAAiB,eAAe,OAAO,CAAC,cAAc;AAAA,UAC3K,QAAO,QAAQ,KAAK;AAAA,IAC3B;AACA,QAAI,KAAK,YAAY,QAAW;AAC9B,UAAI;AAAE,eAAO,UAAU,iBAAiB,KAAK,SAAS,GAAG,IAAI,UAAU;AAAA,MAAG,SACnE,OAAO;AAAE,aAAK,GAAG,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,GAAG;AAAA,MAAG;AAAA,IACtF;AACA,cAAU,KAAK,MAAM;AAAA,EACvB;AACA,MAAI,iBAAkD;AACtD,MAAI,IAAI,kBAAkB,MAAM;AAC9B,UAAM,WAAW,SAAS,IAAI,cAAc,IAAI,IAAI,eAAe,UAAU;AAC7E,UAAM,UAAiC,CAAC;AACxC,QAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,CAAC,SAAS,UAAU,SAAS,SAAS,EAAG,MAAK,oDAA+C;AAC7H,eAAW,QAAQ,MAAM,QAAQ,QAAQ,IAAI,SAAS,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG;AACtE,UAAI,CAAC,SAAS,IAAI,KAAK,CAAC,cAAc,KAAK,OAAO,qBAAqB,KAAK,CAAC,CAAC,OAAO,MAAM,EAAE,SAAS,OAAO,KAAK,GAAG,CAAC,KAAM,KAAK,UAAU,UAAa,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,OAAO,KAAK,KAAK,CAAC,GAAI;AACxM,aAAK,6GAA6G;AAClH;AAAA,MACF;AACA,cAAQ,KAAK,EAAE,OAAO,KAAK,OAAiB,KAAK,KAAK,KAAuB,OAAO,KAAK,UAAU,UAAU,UAAU,OAAO,CAAC;AAAA,IACjI;AACA,qBAAiB,EAAE,QAAQ;AAAA,EAC7B;AACA,MAAI,CAAC,SAAS,IAAI,MAAM,EAAG,MAAK,kDAAkD;AAAA,WACzE,IAAI,OAAO,YAAY,KAAM,MAAK,kFAAkF;AAC7H,QAAM,EAAE,UAAU,SAAS,GAAG,OAAO,IAAI,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AAE9E,MAAI,MAAM,QAAQ,IAAI,WAAW;AAC/B,eAAW,WAAW,IAAI,YAAY,MAAM,GAAG,EAAE;AAC/C,kBAAY,KAAK,OAAO,YAAY,YAAY,UAAU,QAAQ,MAAM,GAAG,gBAAgB,IAAI,8BAA8B;AACjI,QAAM,mBAAmB,oBAAoB,MAAM;AACnD,MAAI,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/B,UAAM,WAAW,OAAO,MAAM,OAAO,CAAC,OAAe,SAAkB,SAAS,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,IAAI,SAAS,IAAI,CAAC;AACnJ,QAAI,aAAa,iBAAiB,MAAM,OAAO,CAAC,OAAO,SAAS,QAAQ,aAAa,IAAI,EAAE,QAAQ,CAAC,EAAG,MAAK,6EAA6E;AAAA,EAC3L;AACA,SAAO,EAAE,MAAM,WAAW,gBAAgB,QAAQ,kBAAkB,GAAI,YAAY,SAAS,EAAE,aAAa,CAAC,GAAG,IAAI,IAAI,WAAW,CAAC,EAAE,IAAI,CAAC,EAAG;AAChJ;AAEA,IAAM,eAAoC,oBAAI,IAAI,CAAC,WAAW,WAAW,SAAS,YAAY,WAAW,OAAO,CAAC;AACjH,IAAM,mBAAmB,CAAC,UAAU,SAAS,WAAW,SAAS,gBAAgB,YAAY,aAAa;AAC1G,IAAM,kBAAkB;AAIxB,SAAS,kBAAkB,OAAsC;AAC/D,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,EAAE,EAAG,QAAO;AACpD,MAAI;AACJ,MAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,UAAU,iBAAkB,SAAQ,MAAM;AAAA,WACpF,SAAS,MAAM,KAAK,KAAK,cAAc,MAAM,MAAM,QAAQ,qBAAqB,EAAG,SAAQ,EAAE,QAAQ,MAAM,MAAM,OAAiB;AAAA,MACtI,QAAO;AACZ,QAAM,KAAK,MAAM;AACjB,MAAI,GAAG,SAAS,YAAY;AAC1B,QAAI,OAAO,GAAG,aAAa,YAAY,GAAG,SAAS,SAAS,IAAM,QAAO;AACzE,WAAO,EAAE,OAAO,IAAI,EAAE,MAAM,YAAY,UAAU,GAAG,SAAS,EAAE;AAAA,EAClE;AACA,MAAI,GAAG,SAAS,WAAW,CAAC,cAAc,GAAG,QAAQ,qBAAqB,EAAG,QAAO;AACpF,QAAM,cAA2D,EAAE,MAAM,SAAS,QAAQ,GAAG,OAAiB;AAC9G,MAAI,GAAG,SAAS,QAAW;AACzB,QAAI,GAAG,SAAS,YAAY,GAAG,SAAS,QAAS,QAAO;AACxD,gBAAY,OAAO,GAAG;AAAA,EACxB;AACA,MAAI,GAAG,eAAe,QAAW;AAC/B,QAAI,OAAO,GAAG,eAAe,UAAW,QAAO;AAC/C,gBAAY,aAAa,GAAG;AAAA,EAC9B;AACA,MAAI,GAAG,UAAU,QAAW;AAC1B,UAAM,QAAQ,mBAAmB,GAAG,KAAK;AACzC,QAAI,CAAC,MAAO,QAAO;AACnB,gBAAY,QAAQ;AAAA,EACtB;AACA,MAAI,GAAG,WAAW,QAAW;AAC3B,QAAI,CAAC,SAAS,GAAG,MAAM,EAAG,QAAO;AACjC,UAAM,UAAU,OAAO,QAAQ,GAAG,MAAM;AACxC,QAAI,QAAQ,SAAS,mBAAmB,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,cAAc,KAAK,qBAAqB,KAAK,OAAO,SAAS,YAAY,KAAK,SAAS,uBAAuB;AACnL,aAAO;AACT,gBAAY,SAAS,OAAO,YAAY,OAAO;AAAA,EACjD;AACA,SAAO,EAAE,OAAO,IAAI,YAAY;AAClC;AAKA,SAAS,cAAc,UAAmB,MAAqC;AAC7E,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACrC,QAAM,QAAQ,SAAS,OAAO,CAAC,OAAe,SAC5C,SAAS,SAAS,IAAI,KAAK,MAAM,QAAQ,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC;AAC3F,SAAO,UAAU,KAAK,OAAO,CAAC,OAAO,SAAS,QAAQ,aAAa,IAAI,EAAE,QAAQ,CAAC;AACpF;AAKA,SAAS,mBAAmB,OAAwC;AAClE,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,cAAc,MAAM,IAAI,qBAAqB,KAAK,CAAC,MAAM,QAAQ,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,KAAK,EAAG,QAAO;AACxI,MAAI,MAAM,KAAK,SAAS,aAAa,QAAQ,MAAM,KAAK,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,CAAC,aAAa,IAAI,KAAK,CAAC,EAAG,QAAO;AACvI,QAAM,MAAM,MAAM;AAClB,QAAM,aAAa,eAAe,KAAK,aAAa,KAAK;AACzD,MAAI,WAAW,UAAU,YAAa,QAAO;AAC7C,MAAI,IAAI,UAAU,UAAa,CAAC,cAAc,IAAI,OAAO,WAAW,KAAK,EAAG,QAAO;AACnF,MAAI,IAAI,iBAAiB,WAAc,CAAC,MAAM,QAAQ,IAAI,YAAY,KACpE,IAAI,aAAa,YAAY,WAAW,cAAc,UAAU,MAChE,WAAW,cAAc,KAAK,CAAC,WAAW,OAAO,aAAa,MAAM,GAAI,QAAO;AACjF,QAAM,QAA6B,CAAC;AACpC,aAAW,OAAO,kBAAkB;AAClC,QAAI,IAAI,GAAG,MAAM,UAAa,WAAW,GAAG,MAAM,OAAW,CAAC,MAAkC,GAAG,IAAI,WAAW,GAAG;AAAA,EACvH;AACA,SAAO,EAAE,IAAI,MAAM,IAAc,MAAM,CAAC,GAAG,IAAI,IAAI,MAAM,IAAoB,CAAC,GAAG,MAAM;AACzF;AAIO,SAAS,aAAa,GAAe,GAAwB;AAClE,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAQ,QAAO;AACzD,MAAK,EAAE,gBAAgB,UAAW,EAAE,gBAAgB,MAAO,QAAO;AAClE,MAAI,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAG,QAAO;AACzC,MAAI,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAG,QAAO;AAC7C,MAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAG,QAAO;AAC3C,MAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,EAAG,QAAO;AACnE,MAAI,KAAK,UAAU,EAAE,WAAW,MAAM,KAAK,UAAU,EAAE,WAAW,EAAG,QAAO;AAC5E,MAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,KAAK,UAAU,EAAE,QAAQ,EAAG,QAAO;AACtE,SAAO;AACT;AAEA,SAAS,UAAa,GAAiB,GAA0B;AAC/D,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAGjC,QAAI,KAAK,UAAU,EAAE,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC,CAAC,EAAG,QAAO;AAAA,EAC5D;AACA,SAAO;AACT;;;ACjrBA,IAAM,UAAkC,EAAE,IAAI,GAAG,GAAG,KAAM,GAAG,KAAO,GAAG,MAAS,GAAG,OAAU,GAAG,OAAU;AAEnG,IAAM,uBAAuB;AAM7B,SAAS,sBAAsB,OAA8B;AAClE,QAAM,QAAQ,oCAAoC,KAAK,KAAK;AAC5D,MAAI,CAAC,SAAS,MAAM,CAAC,MAAM,MAAO,QAAO;AACzC,QAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,QAAM,aAAa;AACnB,MAAI,QAAQ;AACZ,aAAW,SAAS,KAAK,SAAS,UAAU,GAAG;AAC7C,UAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAC9B,UAAM,OAAO,QAAQ,MAAM,CAAC,CAAE;AAC9B,QAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,KAAK,OAAO,uBAAuB,SAAS,IAAI,EAAG,QAAO;AACxG,aAAS,SAAS;AAAA,EACpB;AACA,SAAO,MAAM,CAAC,MAAM,OAAO,UAAU,IAAI,CAAC,QAAQ;AACpD;AAKO,SAAS,eAAeC,UAAyC;AACtE,QAAM,MAAMA,SAAQ,OAAO,KAAK,IAAI;AACpC,MAAI,CAAC,OAAO,cAAc,GAAG,KAAK,KAAK,IAAI,GAAG,IAAI,qBAAsB,OAAM,IAAI,MAAM,+BAA+B;AACvH,SAAO;AACT;AAEO,SAAS,kBAAkB,KAAa,UAA0B;AACvE,QAAM,SAAS,MAAM;AACrB,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,KAAK,IAAI,MAAM,IAAI,qBAAsB,OAAM,IAAI,MAAM,uCAAuC;AACrI,SAAO;AACT;;;ACvBA,IAAM,UAAsB,CAAC,WAAW,aAAa;AAOrD,IAAM,gBAAqD;AAAA,EACzD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AAAA,EACN,KAAK;AAAA,EACL,SAAS;AAAA,EACT,aAAa;AAAA,EACb,eAAe;AAAA,EACf,mBAAmB;AACrB;AAQO,SAAS,aAAa,QAAqB,YAA+C;AAC/F,MAAI,OAAO,UAAU,OAAO,CAAC,OAAO,SAAS;AAC3C,UAAM,iBAAiB,OAAO,OAAO,cAAc,cAAc,OAAO,OAAO,cAAc,cAAc;AAC3G,QAAI,mBAAmB,CAAC,cAAc,WAAW,SAAS,cAAc,IAAI;AAC1E,aAAO,EAAE,OAAO,OAAO,OAAO,IAAI,gBAAgB,OAAO,IAAI;AAAA,IAC/D;AAAA,EACF;AACA,QAAM,aAAa,cAAc,OAAO,EAAE;AAC1C,MAAI,eAAe,CAAC,cAAc,WAAW,SAAS,UAAU,IAAI;AAClE,UAAMC,QAAoB,EAAE,OAAO,OAAO,OAAO,IAAI,YAAY,OAAO,OAAO,MAAM;AACrF,WAAOA;AAAA,EACT;AACA,QAAM,OAAoB,EAAE,OAAO,OAAO,OAAO,IAAI,OAAO,IAAI,OAAO,OAAO,MAAM;AACpF,MAAI,CAAC,OAAO,QAAS,MAAK,UAAU;AACpC,SAAO;AACT;AAKO,SAAS,oBAAoB,QAAsD;AACxF,SAAO,QAAQ,OAAO,OAAO,KAAK,OAAO,OAAO,QAAQ,OAAO,OAAO,uBAAuB,OAAO,OAAO;AAC7G;AAoBA,IAAM,oBAAgC,CAAC,KAAK,KAAK,MAAM,YAAY,eAAe,aAAa,aAAa,aAAa,aAAa,iBAAiB,UAAU;AAM1J,SAAS,gBAAgB,OAAoD;AAClF,QAAM,MAAM,YAAY,KAAK;AAC7B,QAAM,QAAQ,IAAI,IAAI,GAAG;AACzB,QAAM,QAAkB,CAAC;AACzB,aAAW,MAAM,mBAAmB;AAClC,QAAI,CAAC,MAAM,IAAI,EAAE,EAAG;AACpB,UAAM,MAAM,aAAa,EAAE,OAAO,IAAI,IAAI,OAAO,GAAG,GAAG,GAAG;AAC1D,UAAM,KAAK,EAAE,MAAM,EAAE,IAAI,SAAS,MAAM,GAAG,SAAS,EAAE,IAAI,IAAI,IAAI,SAAS,QAAQ,IAAI,OAAO,EAAE,EAAE,CAAC;AAAA,EACrG;AACA,MAAI,MAAM,IAAI,SAAS,KAAK,MAAM,IAAI,aAAa,GAAG;AACpD,UAAM,KAAK,EAAE,MAAM,EAAE,IAAI,WAAW,SAAS,MAAM,GAAG,SAAS,EAAE,IAAI,eAAe,SAAS,MAAM,EAAE,CAAC;AAAA,EACxG;AACA,SAAO;AACT;AAGO,IAAM,cAA6C;AAAA,EACxD,MAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAAA,EACA,MAAM,CAAC,KAAK,MAAM,GAAG,OAAO;AAAA,EAC5B,QAAQ,CAAC,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,GAAG,OAAO;AAAA,EACpD,UAAU,CAAC,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,GAAG,OAAO;AAAA,EACtD,MAAM,CAAC,KAAK,MAAM,GAAG,OAAO;AAAA,EAC5B,WAAW,CAAC,YAAY,GAAG,OAAO;AACpC;AAGO,IAAM,cAAqC,IAAI,IAAc,OAAO;AAGpE,SAAS,YAAY,OAAsD;AAChF,SAAO,MAAM,QAAQ,OAAO,YAAY,MAAM,IAAI;AACpD;AAIO,SAAS,iBAAiB,MAAiB,IAAuB;AACvE,SAAO,YAAY,IAAI,EAAE,SAAS,EAAE;AACtC;AAKO,SAAS,YAAY,MAAiB,KAAa,KAAyC;AACjG,UAAQ,MAAM;AAAA,IACZ,KAAK,UAAU;AACb,YAAM,IAAI,OAAO,GAAG;AACpB,UAAI,IAAI,KAAK,MAAM,MAAM,OAAO,MAAM,CAAC,EAAG,OAAM,IAAI,MAAM,iBAAiB,KAAK,UAAU,GAAG,CAAC,EAAE;AAChG,aAAO;AAAA,IACT;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,IAAI,IAAI,YAAY;AAC1B,UAAI,MAAM,UAAU,MAAM,OAAO,MAAM,IAAK,QAAO;AACnD,UAAI,MAAM,WAAW,MAAM,OAAO,MAAM,IAAK,QAAO;AACpD,YAAM,IAAI,MAAM,eAAe,KAAK,UAAU,GAAG,CAAC,EAAE;AAAA,IACtD;AAAA,IACA,KAAK,YAAY;AACf,UAAI,IAAI,WAAW,GAAG,KAAK,IAAI,WAAW,GAAG,GAAG;AAC9C,cAAM,SAAS,sBAAsB,GAAG;AACxC,YAAI,WAAW,KAAM,OAAM,IAAI,MAAM,0BAA0B,KAAK,UAAU,GAAG,CAAC,EAAE;AACpF,eAAO,kBAAkB,OAAO,KAAK,IAAI,GAAG,MAAM;AAAA,MACpD;AACA,YAAM,KAAK,KAAK,MAAM,GAAG;AACzB,UAAI,OAAO,MAAM,EAAE,EAAG,OAAM,IAAI,MAAM,mBAAmB,KAAK,UAAU,GAAG,CAAC,EAAE;AAC9E,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;;;AC3JO,IAAM,kBAA8C;AAAA,EACzD,QAAQ,CAAC,SAAS,kBAAkB,OAAO,OAAO,OAAO,KAAK;AAAA,EAC9D,UAAU,CAAC,SAAS,kBAAkB,OAAO,KAAK;AAAA,EAClD,MAAM,CAAC,SAAS,kBAAkB,OAAO,KAAK;AAAA,EAC9C,MAAM,CAAC,SAAS,kBAAkB,OAAO,KAAK;AAAA,EAC9C,MAAM,CAAC,SAAS,gBAAgB;AAAA,EAChC,WAAW,CAAC,OAAO;AACrB;AAIO,IAAM,wBAA4C,oBAAI,IAAW;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGM,SAAS,gBAAgB,IAAoB;AAClD,SAAO,sBAAsB,IAAI,EAAE;AACrC;AAGO,SAAS,eAAe,OAAsD;AACnF,SAAO,MAAM,WAAW,OAAO,gBAAgB,MAAM,IAAI;AAC3D;AAIO,SAAS,oBAAoB,MAAiB,IAAoB;AACvE,SAAO,gBAAgB,IAAI,EAAE,SAAS,EAAE;AAC1C;AAKO,SAAS,aAAa,OAA0B;AACrD,MAAI,MAAM,OAAO,SAAS,aAAa,MAAM,OAAO,WAAY,QAAO,MAAM,WAAW,YAAY;AACpG,MAAI,MAAM,OAAO,SAAS,UAAW,QAAO;AAC5C,MAAI,MAAM,WAAW,WAAW,KAAM,QAAO,MAAM,UAAU;AAC7D,SAAO,eAAe,KAAK,EAAE,SAAS;AACxC;AAKO,SAAS,YAAY,OAA0B;AACpD,MAAI,MAAM,OAAO,SAAS,aAAa,MAAM,OAAO,WAAY,QAAO,MAAM,WAAW,cAAc;AACtG,MAAI,MAAM,OAAO,SAAS,UAAW,QAAO;AAC5C,MAAI,MAAM,WAAW,aAAa,KAAM,QAAO,MAAM,UAAU;AAC/D,SAAO,MAAM,SAAS,UAAU,MAAM,SAAS,UAAU,MAAM,SAAS;AAC1E;;;AChEA,SAAS,aAAa,eAAe;;;ACQ9B,SAAS,gBAAgB,OAAyC;AACvE,MAAI,MAAM,QAAQ,WAAW,MAAO,QAAO;AAC3C,MAAI,MAAM,SAAS,YAAa,QAAO;AACvC,MAAI,MAAM,SAAS,UAAW,MAAM,SAAS,UAAU,aAAa,KAAK,EAAE,WAAW,SAAW,QAAO;AACxG,SAAO;AACT;AAGO,SAAS,eAAe,QAA0C;AACvE,SAAO,WAAW,UAAU,CAAC,OAAO,OAAO,QAAQ,OAAO,IAAI,CAAC,OAAO,MAAM;AAC9E;AAKO,SAAS,gBAAgB,OAAe,MAAqB,QAAkB,IAAY,SAA0B,SAAsB;AAChJ,MAAI,CAAC,eAAe,MAAM,EAAE,SAAS,IAAI,EAAG,OAAM,IAAI,MAAM,GAAG,KAAK,YAAY,CAAC,yCAAyC;AAC1H,QAAM,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC;AAChC,MAAI,SAAS,WAAW,KAAK,WAAW,EAAG,QAAO,CAAC;AACnD,QAAM,UAAU,KAAK,IAAI,CAAC,WAAW,EAAE,OAAO,IAAI,WAAW,UAAU,aAAsB,KAAc,MAAM,EAAE;AACnH,QAAM,SAAS,EAAE,OAAO,IAAI,WAAoB,OAAO,GAAG;AAC1D,MAAI;AACJ,MAAI,SAAS,QAAS,SAAQ,CAAC,MAAM;AAAA,WAC5B,SAAS,MAAO,SAAQ,QAAQ,WAAW,IAAI,UAAU,CAAC,EAAE,KAAK,QAAQ,CAAC;AAAA,WAC1E,SAAS,MAAO,SAAQ;AAAA,MAC5B,SAAQ,QAAQ,IAAI,CAAC,YAAY,EAAE,KAAK,CAAC,QAAQ,WAAW,UAAU,EAAE,GAAG,QAAQ,SAAS,KAAK,IAAI,EAAE,GAAG,QAAQ,IAAI,KAAc,CAAC,EAAE,EAAE;AAC9I,SAAO,MAAM,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,EAAE,IAAI,MAAM,QAAQ,SAAS,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE;AAC9G;AAGO,SAAS,eAAe,MAA4B;AACzD,QAAM,QAAQ,CAAC,EAAE,WAAW,WAAW,GAAG,OAAO,MAA+C;AAChG,SAAO,UAAU,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,EAAE,IAAI,MAAM,IAAI;AACpE;AAGO,SAAS,cAAc,OAAoB,OAA8G;AAC9J,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,WAAW,MAAM;AACvB,MAAI,CAAC,QAAQ,CAAC,YAAY,MAAM,QAAQ,CAAC,GAAG,WAAW,OAAO,SAAS,GAAI,QAAO;AAClF,QAAM,QAAQ,aAAa,IAAI,EAAE,CAAC,GAAG;AACrC,MAAI,CAAC,MAAO,QAAO;AAGnB,QAAM,SAA0B,aAAa,IAAI,EAAE,KAAK,CAAC,WAAW,OAAO,OAAO,UAAU,KAAK,CAAC,eAAe,QAAQ,EAAE,SAAS,SAAS,IAAI,IAAI,UAAU;AAC/J,QAAM,WAAW,gBAAgB,OAAO,SAAS,MAAM,SAAS,QAAQ,SAAS,IAAI,MAAM;AAC3F,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,WAAS,SAAS,GAAG,SAAS,SAAS,QAAQ,UAAU;AACvD,UAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,QAAI,CAAC,UAAU,KAAK,UAAU,OAAO,SAAS,MAAM,KAAK,UAAU,SAAS,MAAM,EAAG,SAAS,KAAK,KAAK,UAAU,eAAe,MAAM,CAAC,MAAM,KAAK,UAAU,eAAe,SAAS,MAAM,CAAE,CAAC,EAAG,QAAO;AAAA,EAC1M;AACA,MAAI,MAAM,QAAQ,SAAS,MAAM,GAAG,WAAW,OAAO,SAAS,GAAI,QAAO;AAC1E,SAAO,EAAE,OAAO,UAAU,OAAO,SAAS,QAAQ,OAAO;AAC3D;AAGO,SAAS,mBAAmB,OAAoB,cAAqE;AAC1H,QAAM,SAAsB,CAAC;AAC7B,WAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;AACjD,UAAM,MAAM,cAAc,OAAO,KAAK;AACtC,QAAI,CAAC,KAAK;AAAE,aAAO,KAAK,MAAM,KAAK,CAAE;AAAG;AAAA,IAAU;AAClD,WAAO,KAAK,GAAG,gBAAgB,IAAI,OAAO,IAAI,SAAS,MAAM,IAAI,SAAS,OAAO,IAAI,CAAC,UAAU,aAAa,IAAI,OAAO,KAAK,CAAC,GAAG,IAAI,SAAS,IAAI,IAAI,MAAM,CAAC;AAC7J,aAAS,IAAI,QAAQ;AAAA,EACvB;AACA,SAAO;AACT;;;AD5CA,SAAS,YAAY,MAAsB;AACzC,MAAI;AACJ,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,QAAQ;AAAA,EACnD,OAAO;AACL,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI;AAC3C,QAAI,MAAM;AACV,eAAW,KAAK,MAAO,QAAO,OAAO,aAAa,CAAC;AACnD,UAAM,KAAK,GAAG;AAAA,EAChB;AACA,SAAO,IAAI,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AACtE;AAEA,SAAS,cAAc,GAAmB;AACxC,QAAM,MAAM,EAAE,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,IAAI,MAAM,OAAO,EAAE,SAAS,KAAK,CAAC;AACpF,MAAI,OAAO,WAAW,YAAa,QAAO,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,MAAM;AACpF,QAAM,MAAM,KAAK,GAAG;AACpB,QAAM,QAAQ,WAAW,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AACzD,SAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AACvC;AAyBA,SAAS,aAAa,GAA6B;AACjD,MAAI,oBAAoB,CAAC;AACzB,QAAM,IAAkB,CAAC;AACzB,MAAI,EAAE,OAAO;AACX,MAAE,IAAI,EAAE,OAAO,IAAI,CAAC,QAClB,IAAI,UAAU,CAAC,IAAI,OAAO,IAAI,SAAS,MAAM,IAAI,OAAO,IACpD,IAAI,SAAS,OAAO,CAAC,IAAI,OAAO,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC;AAChE,MAAI,EAAE,MAAM,OAAQ,GAAE,IAAI,EAAE;AAC5B,MAAI,EAAE,QAAQ,OAAQ,GAAE,IAAI,EAAE;AAC9B,IAAE,IAAI,EAAE;AACR,MAAI,EAAE,OAAQ,GAAE,IAAI,EAAE;AACtB,MAAI,EAAE,cAAc,OAAQ,GAAE,IAAI,EAAE;AACpC,MAAI,EAAE,YAAa,GAAE,IAAI,EAAE;AAC3B,MAAI,EAAE,YAAa,GAAE,KAAK;AAC1B,MAAI,EAAE,SAAU,GAAE,IAAI,EAAE;AACxB,SAAO;AACT;AAEO,IAAM,wBAAwB,IAAI,OAAO;AACzC,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAA4B,MAAuD,SAAiB;AAClG,UAAM,OAAO;AADa;AACV,SAAK,OAAO;AAAA,EAC9B;AACF;AAIA,SAAS,UAAU,GAA0C;AAC3D,QAAM,SAAkC,EAAE,GAAG,EAAE;AAC/C,MAAI,EAAE,MAAM,YAAY,MAAO,QAAO,OAAO;AAC7C,MAAI,EAAE,GAAG;AACP,UAAM,QAAmB,CAAC;AAC1B,aAAS,IAAI,GAAG,IAAI,EAAE,EAAE,QAAQ,KAAK;AACnC,YAAM,MAAM,cAAc,EAAE,GAAG,CAAC;AAGhC,UAAI,KAAK,WAAW,SAAS;AAC3B,cAAM,KAAK,CAAC,OAAO,IAAI,OAAO,IAAI,SAAS,MAAM,IAAI,SAAS,QAAQ,IAAI,SAAS,EAAE,CAAC;AACtF,aAAK,IAAI,QAAQ;AAAA,MACnB,MAAO,OAAM,KAAK,EAAE,EAAE,CAAC,CAAC;AAAA,IAC1B;AACA,WAAO,IAAI;AAAA,EACb;AACA,MAAI,EAAE,GAAG,OAAO;AACd,UAAM,OAAkB,CAAC;AACzB,UAAM,OAA+B,CAAC;AACtC,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,EAAE,EAAE,KAAK,GAAG;AACpD,UAAI,QAAQ,KAAK,UAAU,OAAK,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC;AAC1E,UAAI,QAAQ,GAAG;AAAE,gBAAQ,KAAK;AAAQ,aAAK,KAAK,IAAI;AAAA,MAAG;AACvD,WAAK,IAAI,IAAI;AAAA,IACf;AACA,WAAO,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,MAAM,KAAK,EAAE;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,YAAY,GAA0C;AAC7D,MAAI,MAAM,QAAQ,EAAE,CAAC,EAAG,GAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,SAAkB;AAC3D,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO,CAAC,IAAI;AACtC,QAAI,KAAK,WAAW,KAAK,KAAK,CAAC,MAAM,SAAS,OAAO,KAAK,CAAC,MAAM,YAC/D,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,OAAO,QAAQ,OAAO,EAAE,SAAS,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,CAAC,KAC3G,KAAK,CAAC,EAAE,SAAS,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAe,OAAO,MAAM,YAAY,EAAE,UAAU,GAAK,KAAK,OAAO,KAAK,CAAC,MAAM;AACzH,YAAM,IAAI,iBAAiB,WAAW,mCAAmC;AAC3E,WAAO,gBAAgB,KAAK,CAAC,GAAG,KAAK,CAAC,GAAoB,KAAK,CAAC,GAAe,KAAK,CAAC,CAAC;AAAA,EACxF,CAAC;AACD,QAAM,UAAU,EAAE;AAClB,QAAM,QAAQ,WAAW,OAAO,YAAY,YAAY,WAAW,UAAU,QAAQ,QAAQ;AAC7F,MAAI,WAAW,OAAO,YAAY,YAAY,SAAS,OAAO,UAAU,YAAY,UAAU,OAAO;AACnG,UAAM,OAAO,MAAM;AACnB,UAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;AAC5C,QAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,KAAK,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI;AACpG,YAAM,IAAI,iBAAiB,WAAW,uCAAuC;AAC/E,MAAE,IAAI,EAAE,GAAG,SAAS,OAAO,OAAO,YAAY,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;AACxF,UAAI,CAAC,CAAC,SAAS,SAAS,QAAQ,EAAE,SAAS,IAAI,KAAK,CAAC,OAAO,UAAU,KAAK,KAAM,QAAmB,KAAM,SAAoB,KAAK;AACjI,cAAM,IAAI,iBAAiB,WAAW,kCAAkC;AAC1E,aAAO,CAAC,MAAM,KAAK,KAAe,CAAC;AAAA,IACrC,CAAC,CAAC,EAAE;AAAA,EACN;AACA,SAAO;AACT;AAGO,SAAS,YAAY,GAAuB;AACjD,QAAM,OAAO,KAAK,UAAU,UAAU,aAAa,CAAC,CAAC,CAAC;AACtD,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI;AAC3C,MAAI,MAAM,SAAS,sBAAuB,OAAM,IAAI,iBAAiB,aAAa,wCAAwC;AAC1H,QAAM,QAAQ,QAAQ,YAAY,IAAI;AACtC,QAAM,aAAa,QAAQ,cAAc,YAAY,KAAK,CAAC;AAC3D,QAAM,QAAQ,WAAW,SAAS,MAAM,SAAS,aAAa;AAC9D,MAAI,MAAM,SAAS,uBAAwB,OAAM,IAAI,iBAAiB,aAAa,gDAAgD;AACnI,SAAO;AACT;AAEA,SAAS,cAAc,OAA2B;AAChD,MAAI,OAAO,WAAW,YAAa,QAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AACzI,MAAI,MAAM;AACV,aAAW,QAAQ,MAAO,QAAO,OAAO,aAAa,IAAI;AACzD,SAAO,KAAK,GAAG,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AAC5E;AAEA,SAAS,aAAa,OAAuB;AAC3C,QAAM,MAAM,KAAK,MAAM,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,CAAC;AAC5D,QAAM,QAAQ,WAAW,KAAK,KAAK,OAAK,EAAE,WAAW,CAAC,CAAC;AACvD,QAAM,SAAuB,CAAC;AAC9B,MAAI,OAAO;AACX,MAAI,WAAW;AACf,QAAM,SAAS,IAAI,QAAQ,CAAC,OAAO,UAAU;AAC3C,YAAQ,MAAM;AACd,QAAI,OAAO,sBAAuB,OAAM,IAAI,iBAAiB,aAAa,iDAAiD;AAC3H,WAAO,KAAK,KAAK;AAAG,eAAW;AAAA,EACjC,CAAC;AAED,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAK,QAAO,KAAK,MAAM,SAAS,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,MAAM,MAAM;AAC3G,MAAI,CAAC,SAAU,OAAM,IAAI,iBAAiB,WAAW,mCAAmC;AACxF,QAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAAE,UAAM,IAAI,OAAO,MAAM;AAAG,cAAU,MAAM;AAAA,EAAQ;AAChF,SAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,EAAE,OAAO,KAAK;AAC/D;AAIO,SAAS,YAAY,OAA2B;AACrD,MAAI;AAAE,WAAO,YAAY,OAAO,KAAK;AAAA,EAAG,QAAQ;AAAE,WAAO,EAAE,GAAG,YAAY;AAAA,EAAG;AAC/E;AAGO,SAAS,kBAAkB,OAA2B;AAC3D,SAAO,YAAY,OAAO,IAAI;AAChC;AACA,SAAS,YAAY,OAAe,QAA6B;AAC/D,MAAI,CAAC,MAAO,QAAO,EAAE,GAAG,YAAY;AACpC,MAAI,MAAM,SAAS,uBAAwB,OAAM,IAAI,iBAAiB,aAAa,uCAAuC;AAC1H,MAAI;AACF,UAAM,YAAY,MAAM,SAAS,GAAG;AACpC,QAAI,aAAa,CAAC,MAAM,WAAW,KAAK,KAAK,CAAC,MAAM,WAAW,KAAK;AAClE,YAAM,IAAI,iBAAiB,uBAAuB,iCAAiC;AACrF,UAAM,UAAU,YAAY,MAAM,MAAM,CAAC,IAAI;AAC7C,QAAI,CAAC,mBAAmB,KAAK,OAAO,KAAK,QAAQ,SAAS,MAAM,EAAG,OAAM,IAAI,iBAAiB,WAAW,8BAA8B;AACvI,UAAM,OAAO,MAAM,WAAW,KAAK,IAAI,aAAa,OAAO,IAAI,cAAc,OAAO;AACpF,QAAI,IAAI,YAAY,EAAE,OAAO,IAAI,EAAE,SAAS,sBAAuB,OAAM,IAAI,iBAAiB,aAAa,wCAAwC;AACnJ,UAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,QAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,EAAE,KAAK,OAAK,IAAI,CAAC,MAAM,UAAa,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC,CAAC;AAC9H,YAAM,IAAI,iBAAiB,WAAW,2BAA2B;AACnE,UAAM,IAAI,YAAY,YAAY,GAAG,IAAI;AACzC,QAAI,UAAU,EAAE,GAAG;AACjB,UAAI,EAAE,EAAE,KAAK,CAAC,SAAoB,CAAC,QAAQ,OAAO,SAAS,QAAQ,EAAG,OAAM,IAAI,iBAAiB,WAAW,2BAA2B;AACvI,YAAM,QAAQ,EAAE,EAAE,OAAO,CAAC,GAAW,SAAoB,IAAI,aAAa,IAAI,EAAE,QAAQ,CAAC;AACzF,YAAM,aAAa,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;AACrD,YAAM,kBAAkB,WAAW,MAAM,OAAO,CAAC,GAAG,SAAS,IAAI,aAAa,IAAI,EAAE,QAAQ,CAAC;AAC7F,UAAI,QAAQ,OAAO,UAAU,mBAAmB,EAAE,EAAE,KAAK,CAAC,SAAoB,aAAa,IAAI,EAAE,KAAK,YACpG,CAAC,UAAU,OAAO,WAAW,YAAa,OAAO,YAAY,UAAa,OAAO,OAAO,YAAY,SAAU,CAAC;AAC/G,cAAM,IAAI,iBAAiB,WAAW,wDAAwD;AAAA,IAClG;AACA,UAAM,MAAM,oBAAoB;AAAA,MAC9B,QAAQ,gBAAgB,EAAE,KAAK,EAAE,CAAC;AAAA,MAClC,OAAO,MAAM,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;AAAA,MACnC,SAAS,iBAAiB,EAAE,CAAC;AAAA,MAC7B,OAAO,EAAE;AAAA,MACT,QAAQ,EAAE;AAAA,MACV,cAAc,EAAE;AAAA,MAChB,aAAa,EAAE;AAAA,MACf,aAAa,EAAE;AAAA,MACf,UAAU,EAAE;AAAA,IACd,CAAC;AACD,QAAI,UAAU,EAAE,KAAK,IAAI,cAAc,WAAW,EAAE,EAAE,OAAQ,OAAM,IAAI,iBAAiB,WAAW,wBAAwB;AAC5H,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAkB,OAAM;AAC7C,UAAM,IAAI,iBAAiB,WAAW,mCAAmC;AAAA,EAC3E;AACF;AAEA,SAAS,gBAAgB,GAA0D;AACjF,MAAI,CAAC,MAAM,QAAQ,CAAC,EAAG,QAAO,CAAC;AAC/B,SAAO,EACJ,IAAI,CAAC,SAA8B;AAClC,QAAI,OAAO,SAAS,SAAU,QAAO,EAAE,OAAO,KAAK;AACnD,QAAI,MAAM,QAAQ,IAAI,KAAK,OAAO,KAAK,CAAC,MAAM,UAAU;AACtD,YAAM,SAAuB,EAAE,OAAO,KAAK,CAAC,EAAE;AAC9C,UAAI,OAAO,KAAK,CAAC,MAAM,SAAU,QAAO,QAAQ,KAAK,CAAC;AAEtD,UAAI,KAAK,CAAC,MAAM,OAAW,QAAO,UAAU,KAAK,CAAC;AAClD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,CAAC,EACA,OAAO,CAAC,MAAyB,KAAK,IAAI;AAC/C;AAEA,SAAS,iBAAiB,GAAuC;AAC/D,MAAI,CAAC,EAAG,QAAO,CAAC;AAChB,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC7B,SAAO,CAAC,CAAC;AACX;AAoBO,SAAS,cAAmB,GAAe,QAAuC;AACvF,MAAI,EAAE,SAAU,OAAM,IAAI,MAAM,gFAAgF;AAChH,MAAI,oBAAoB,CAAC;AACzB,QAAM,SAAS,YAAY,MAAM;AACjC,QAAMC,gBAAe,CAAC,SAAiB,iBAAiB,QAAQ,IAAI,KAAK;AAEzE,QAAM,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,MAAM,QAAQA,aAAY,CAAC,EAAE,IAAI,cAAc;AAErG,QAAM,UAA2B,CAAC;AAClC,aAAW,QAAQ,EAAE,SAAS;AAC5B,UAAM,QAAQA,cAAa,KAAK,KAAK;AACrC,UAAMC,KAAI,OAAO,IAAI,KAAK;AAC1B,QAAI,CAACA,MAAK,CAAC,WAAWA,EAAC,KAAKA,GAAE,OAAO,SAAS,UAAW;AACzD,YAAQ,KAAK,EAAE,GAAG,MAAM,OAAOA,GAAE,MAAM,SAASA,GAAE,KAAK,CAAC;AAAA,EAC1D;AAOA,QAAM,SAAS,IAAI;AAAA,IACjB,eAAe,QAAQ,CAAC,EACrB,OAAO,CAACA,OAAMA,GAAE,OAAO,SAAS,SAAS,EACzC,IAAI,CAACA,OAAMA,GAAE,IAAI;AAAA,EACtB;AACA,aAAW,SAAS,eAAe,QAAQ,CAAC,GAAG;AAC7C,QAAI,MAAM,OAAO,SAAS,WAAW;AACnC,iBAAW,QAAQ,MAAM,OAAO,gBAAgB,CAAC,GAAG;AAClD,YAAI,OAAO,IAAI,IAAI,GAAG,OAAO,SAAS,UAAW,QAAO,IAAI,IAAI;AAAA,MAClE;AAAA,IACF;AAAA,EACF;AACA,SAAO,IAAI,OAAO,OAAO;AACzB,aAAW,QAAQ,EAAE,OAAO;AAC1B,eAAW,MAAM,aAAa,IAAI,GAAG;AACnC,YAAM,QAAQD,cAAa,GAAG,KAAK;AACnC,YAAMC,KAAI,OAAO,IAAI,KAAK;AAC1B,UAAIA,MAAK,aAAaA,EAAC,KAAK,CAAC,iBAAiBA,EAAC,KAAKA,GAAE,OAAO,SAAS,UAAW,QAAO,IAAI,KAAK;AAAA,IACnG;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG,OAAO,SAAS,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO;AACxF;AAMA,SAAS,eACP,MACA,QACAD,eACS;AACT,SAAO,aAAa,IAAI,EAAE,MAAM,CAAC,OAAO;AACtC,UAAMC,KAAI,OAAO,IAAID,cAAa,GAAG,KAAK,CAAC;AAC3C,WAAOC,MAAK,QAAQ,iBAAiBA,EAAC;AAAA,EACxC,CAAC;AACH;AA+DO,SAAS,mBAAwB,GAAe,QAA8C;AACnG,MAAI,EAAE,SAAU,OAAM,IAAI,MAAM,4DAA4D;AAC5F,QAAM,yBAAyB,EAAE,MAAM,OAAO,CAAC,GAAE,MAAI,IAAE,aAAa,CAAC,EAAE,QAAO,CAAC;AAC/E,MAAI,oBAAoB,CAAC;AACzB,MAAI,EAAE,cAAc,KAAK,OAAK,EAAE,YAAY,EAAG,OAAM,IAAI,MAAM,0DAA0D;AACzH,MAAI,EAAE,cAAc,KAAK,OAAK,EAAE,aAAa,UAAU,EAAE,eAAe,UAAa,EAAE,gBAAgB,UAAa,EAAE,gBAAgB,EAAE,UAAU,eAAe,EAAE,MAAM,UAAU,EAAE,cAAc,EAAE,OAAO,UAAU,EAAE,aAAa,MAAS,EAAG,OAAM,IAAI,MAAM,4DAA4D;AAC7T,QAAM,SAAS,YAAY,MAAM;AACjC,QAAMD,gBAAe,CAAC,SAAiB,iBAAiB,QAAQ,IAAI,KAAK;AAEzE,QAAM,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,MAAM,QAAQA,aAAY,CAAC,EAAE,IAAI,cAAc;AAErG,QAAM,YAAY,CAAC,SAAsC;AACvD,QAAI,QAAQ,KAAM,QAAO;AACzB,UAAM,QAAQA,cAAa,IAAI;AAC/B,UAAMC,KAAI,OAAO,IAAI,KAAK;AAC1B,WAAOA,MAAK,QAAQA,GAAE,OAAO,SAAS;AAAA,EACxC;AAEA,QAAM,gBAAgB,EAAE,gBAAgB,CAAC,GAAG;AAAA,IAC1C,CAAC,MAAM,UAAU,EAAE,KAAK,KAAK,EAAE,QAAQ,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC;AAAA,EAClE;AAEA,QAAM,cAAkC,CAAC;AACzC,aAAW,KAAK,EAAE,gBAAgB,CAAC,EAAG,KAAI,CAAC,aAAa,SAAS,CAAC,EAAG,aAAY,KAAK,EAAE,UAAU,EAAE,IAAI,MAAM,sBAAsB,SAAS,+CAA+C,MAAM,GAAG,IAAI,EAAE,CAAC;AAC5M,MAAI,MAAM,WAAW,EAAE,MAAM,UAAU,2BAA2B,EAAE,MAAM,OAAO,CAAC,GAAE,MAAI,IAAE,aAAa,CAAC,EAAE,QAAO,CAAC,EAAG,aAAY,KAAK,EAAE,MAAM,mBAAmB,SAAS,2EAA2E,MAAM,GAAG,IAAI,EAAE,CAAC;AACrQ,SAAO,EAAE,OAAO,cAAc,GAAI,YAAY,SAAS,EAAE,YAAY,IAAI,CAAC,EAAG;AAC/E;;;AElZA,IAAM,cAAc;AACb,SAAS,sBAAsB,OAA+B;AACnE,QAAM,IAAI;AACV,MAAI,CAAC,KAAK,EAAE,YAAY,KAAK,CAAC,YAAY,KAAK,EAAE,IAAI,KAAK,OAAO,EAAE,UAAU,YAC3E,EAAE,MAAM,SAAS,0BAA0B,CAAC,OAAO,SAAS,EAAE,SAAS,EAAG,OAAM,MAAM,yBAAyB;AACjH,oBAAkB,EAAE,KAAK;AACzB,SAAO,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,OAAO,EAAE,OAAO,WAAW,EAAE,UAAU;AAC5E;AACA,SAAS,YAAY,OAA8B;AACjD,QAAM,QAAQ,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC;AACvD,MAAI,MAAM;AACV,aAAW,KAAK,MAAO,QAAO,OAAO,aAAa,CAAC;AACnD,SAAO,EAAE,SAAS,GAAG,MAAM,KAAK,GAAG,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,GAAG,OAAO,WAAW,KAAK,IAAI,EAAE;AAChI;AAKO,SAAS,wBAAwBC,WAKpC,CAAC,GAAuB;AAC1B,QAAM,aAAaA,SAAQ,cAAc;AACzC,QAAM,aAAaA,SAAQ,cAAc;AACzC,QAAM,WAAWA,SAAQ,YAAY,IAAI,OAAO;AAChD,MAAI,CAAC,OAAO,UAAU,UAAU,KAAK,aAAa,KAAK,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,EAAG,OAAM,MAAM,kCAAkC;AAEjJ,QAAM,UAAU,MAAMA,SAAQ,WAAW,WAAW;AACpD,WAAS,OAAgB;AACvB,UAAM,OAAO,QAAQ,EAAE,QAAQ,UAAU;AACzC,QAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAI;AACJ,QAAI;AAAE,YAAM,KAAK,MAAM,IAAI;AAAA,IAAG,QAAQ;AAAE,aAAO,CAAC;AAAA,IAAG;AACnD,QAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,UAAM,UAAmB,IAAI,OAAO,OAAK,KAAK,OAAO,EAAE,QAAQ,YAAY,EAAE,YAC3E,EAAE,SAAS,YAAY,KAAK,YAAY,KAAK,EAAE,SAAS,IAAI,KAAK,OAAO,EAAE,SAAS,UAAU,YAC7F,EAAE,SAAS,MAAM,UAAU,0BAA0B,OAAO,SAAS,EAAE,SAAS,SAAS,CAAC,EAAE,MAAM,CAAC,UAAU;AAG/G,WAAO,QAAQ,UAAU,KAAK,UAAU,OAAO,EAAE,SAAS,IAAI,SAAU,SAAQ,MAAM;AACtF,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,UAAU,KAAK,MAAM;AAAE,aAAO,KAAK,EAAE,KAAK,OAAK,EAAE,QAAQ,OAAO,EAAE,SAAS,SAAS,QAAQ,EAAE,OAAO;AAAA,IAAG;AAAA,IACxG,YAAY,KAAK,MAAM;AACrB,YAAM,UAAU,KAAK;AAAG,YAAM,QAAQ,QAAQ,KAAK,OAAK,EAAE,QAAQ,OAAO,EAAE,SAAS,SAAS,IAAI;AACjG,UAAI,OAAO;AACT,cAAM,UAAU;AAChB,YAAI,OAAO,KAAK,UAAU,OAAO;AACjC,eAAO,KAAK,SAAS,IAAI,YAAY,QAAQ,SAAS,GAAG;AACvD,kBAAQ,OAAO,QAAQ,CAAC,MAAM,QAAQ,IAAI,GAAG,CAAC;AAAG,iBAAO,KAAK,UAAU,OAAO;AAAA,QAChF;AACA,YAAI,KAAK,SAAS,KAAK,SAAU,SAAQ,EAAE,QAAQ,YAAY,IAAI;AAAA,MACrE;AAAA,IACF;AAAA,IACA,IAAI,KAAK,MAAM;AAAE,aAAO,KAAK,EAAE,KAAK,OAAK,EAAE,QAAQ,OAAO,EAAE,SAAS,SAAS,IAAI,GAAG,YAAY;AAAA,IAAM;AAAA,IACvG,KAAK,KAAK,OAAO;AAAE,aAAO,KAAK,EAAE,KAAK,OAAK,EAAE,QAAQ,OAAO,EAAE,SAAS,UAAU,KAAK,GAAG,YAAY;AAAA,IAAM;AAAA,IAC3G,IAAI,KAAK,UAAU;AACjB,YAAM,UAAU,KAAK;AACrB,YAAM,MAAM,QAAQ,KAAK,OAAK,EAAE,QAAQ,OAAO,EAAE,SAAS,SAAS,SAAS,IAAI;AAChF,UAAI,KAAK;AACP,YAAI,IAAI,SAAS,UAAU,SAAS,MAAO,OAAM,MAAM,0CAA0C;AACjG,cAAMC,QAAO,KAAK,UAAU,OAAO;AACnC,YAAI,QAAQ,EAAE,QAAQ,UAAU,MAAMA,MAAM,SAAQ,EAAE,QAAQ,YAAYA,KAAI;AAC9E;AAAA,MACF;AACA,cAAQ,KAAK,EAAE,KAAK,UAAU,sBAAsB,QAAQ,EAAE,CAAC;AAC/D,aAAO,QAAQ,SAAS,WAAY,SAAQ,MAAM;AAClD,UAAI,OAAO,KAAK,UAAU,OAAO;AAEjC,aAAO,KAAK,SAAS,IAAI,YAAY,QAAQ,SAAS,GAAG;AAAE,gBAAQ,MAAM;AAAG,eAAO,KAAK,UAAU,OAAO;AAAA,MAAG;AAC5G,UAAI,KAAK,SAAS,IAAI,SAAU,OAAM,MAAM,mDAAmD;AAC/F,cAAQ,EAAE,QAAQ,YAAY,IAAI;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,2BAA+C;AAC7D,MAAI,OAAsB;AAC1B,SAAO,wBAAwB,EAAE,SAAS,EAAE,SAAS,MAAM,MAAM,SAAS,CAAC,MAAM,UAAU;AAAE,WAAO;AAAA,EAAO,EAAE,EAAE,CAAC;AAClH;AAMO,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAEhD,YACW,QACA,MACT,SACS,QACA,YACT;AAAE,UAAM,OAAO;AALN;AACA;AAEA;AACA;AANX,SAAS,OAAO;AAAA,EAOI;AACtB;AAEA,eAAe,kBAAkB,UAAqD;AAIpF,MAAI;AACJ,MAAI;AACJ,QAAM,OAAO,SAAS,QAAQ,IAAI,cAAc,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY;AACrF,MAAI,SAAS,SAAS,SAAS,gBAAgB,SAAS,qBAAqB;AAC3E,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAI;AACF,YAAM,SAAuB,CAAC;AAC9B,UAAI,OAAO;AACX,UAAI,WAAW;AACf,aAAO,QAAQ,MAAM;AACnB,cAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,YAAI,KAAK,MAAM;AAAE,qBAAW;AAAM;AAAA,QAAO;AACzC,gBAAQ,KAAK,MAAM;AACnB,YAAI,QAAQ,KAAM,QAAO,KAAK,KAAK,KAAK;AAAA,MAC1C;AACA,UAAI,UAAU;AACZ,cAAM,QAAQ,IAAI,WAAW,IAAI;AACjC,YAAI,SAAS;AACb,mBAAW,SAAS,QAAQ;AAAE,gBAAM,IAAI,OAAO,MAAM;AAAG,oBAAU,MAAM;AAAA,QAAQ;AAChF,cAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAC3C,YAAI,SAAkB;AACtB,YAAI,SAAS,oBAAoB;AAC/B,gBAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,mBAAS,MAAM,WAAW,MAAM,OAAO,WAAW,MAAM;AACxD,gBAAMC,QAAO,MAAM,QAAQ,MAAM,OAAO;AACxC,cAAI,OAAOA,UAAS,YAAY,yBAAyB,KAAKA,KAAI,EAAG,cAAaA;AAAA,QACpF;AACA,YAAI,OAAO,WAAW,YAAY,CAAC,OAAO,KAAK,MAAM,GAAG;AACtD,gBAAM,OAAO,OAAO,QAAQ,0BAA0B,GAAG,EAAE,KAAK;AAChE,cAAI,KAAM,UAAS,KAAK,MAAM,GAAG,GAAG;AAAA,QACtC;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAAiE,UACzE;AACE,UAAI;AAAE,cAAM,OAAO,OAAO;AAAA,MAAG,QAAQ;AAAA,MAAwC;AAC7E,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AACA,QAAM,SAAS,SAAS;AACxB,QAAM,OAAmC,WAAW,MAAM,UAAU,WAAW,OAAO,WAAW,MAAM,cACnG,WAAW,MAAM,aAAa,WAAW,MAAM,gBAAgB,UAAU,MAAM,YAAY;AAC/F,QAAM,WAAuD;AAAA,IAC3D,OAAO;AAAA,IACP,WAAW;AAAA,IACX,UAAU;AAAA,IACV,aAAa;AAAA,IACb,SAAS;AAAA,IACT,MAAM,kCAAkC,MAAM;AAAA,EAChD;AACA,QAAM,UAAU,SAAS,IAAI,KAAK,SAAS,SAAS,UAAU,MAAM,MAAM,OACrE,WAAW,SAAS,OAAO,WAAW,OAAO,IAAI,MAAM,KAAK;AACjE,SAAO,IAAI,uBAAuB,QAAQ,MAAM,SAAS,QAAQ,UAAU;AAC7E;AAEO,SAAS,uBAAuB,MAAc,UAAwB,OAA2B;AACtG,QAAM,MAAM,CAAC,KAAa,SAAiB,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,WAAW,mBAAmB,GAAG,CAAC,SAAS,mBAAmB,IAAI,CAAC;AACtJ,iBAAe,iBAAiB,UAA4C;AAC1E,QAAI,CAAC,SAAS,GAAI,OAAM,MAAM,kBAAkB,QAAQ;AACxD,WAAO,sBAAsB,MAAM,SAAS,KAAK,CAAC;AAAA,EACpD;AACA,SAAO;AAAA,IACL,MAAM,KAAK,KAAK,UAAU,QAAQ;AAChC,YAAM,SAAS,MAAM,iBAAiB,MAAM,QAAQ,IAAI,KAAK,SAAS,IAAI,GAAG;AAAA,QAC3E,QAAQ;AAAA,QAAO,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAAG,MAAM,KAAK,UAAU,QAAQ;AAAA,QAAG,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7H,CAAC,CAAC;AACF,UAAI,OAAO,SAAS,SAAS,QAAQ,OAAO,UAAU,SAAS,MAAO,OAAM,MAAM,uDAAuD;AACzI,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ,KAAK,MAAM,QAAQ;AAC/B,YAAM,WAAW,MAAM,QAAQ,IAAI,KAAK,IAAI,GAAG,SAAS,EAAE,OAAO,IAAI,CAAC,CAAC;AACvE,UAAI,SAAS,WAAW,IAAK,QAAO;AACpC,YAAM,SAAS,MAAM,iBAAiB,QAAQ;AAC9C,UAAI,OAAO,SAAS,KAAM,OAAM,MAAM,qDAAqD;AAC3F,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAWO,SAAS,uBAAuB,KAAa,OAA4BF,WAA4B,CAAC,GAAqB;AAChI,QAAM,SAASA,SAAQ,eAAe;AACtC,MAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,EAAG,OAAM,MAAM,2BAA2B;AACpF,QAAM,QAAQA,SAAQ,SAAS,wBAAwB;AACvD,QAAM,WAAW,oBAAI,IAAoC;AACzD,QAAM,WAAW,oBAAI,IAA2B;AAChD,QAAM,QAAQ,oBAAI,IAA2B;AAC7C,WAAS,SAASG,WAAyB;AACzC,UAAM,IAAIA,UAAS,MAAMA,SAAQ;AACjC,WAAO,MAAM,OAAO,IAAK,OAAM,OAAO,MAAM,KAAK,EAAE,KAAK,EAAE,KAAM;AAChE,QAAI;AAAE,YAAM,IAAI,KAAKA,SAAQ;AAAG,YAAM,cAAc,KAAKA,UAAS,IAAI;AAAA,IAAG,QAAQ;AAAA,IAA+C;AAAA,EAClI;AACA,WAAS,KAAK,MAAc,WAAmB,OAAe,MAAoC;AAChG,UAAM,MAAM,IAAI,IAAI,IAAI;AACxB,QAAI,aAAa,IAAI,WAAW,KAAK;AACrC,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,SAAS,CAAC,EAAE;AACvD,QAAI,QAAQ,OAAQ,OAAM,MAAM,oEAAoE;AACpG,WAAO,EAAE,KAAK,IAAI,SAAS,GAAG,MAAM,OAAO,GAAI,SAAS,WAAW,EAAE,cAAc,MAAM,MAAM,CAAC,EAAE,IAAI,CAAC,EAAG;AAAA,EAC5G;AACA,WAAS,OAAO,OAAqC;AACnD,QAAI;AAAE,aAAO,MAAM,KAAK,KAAK,KAAK;AAAA,IAAG,QAAQ;AAAE,aAAO;AAAA,IAAM;AAAA,EAC9D;AACA,iBAAe,SAAS,OAAkD;AACxE,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,QAAQ,YAAY,KAAK;AAC/B,UAAM,WAAW,SAAS,IAAI,KAAK;AACnC,QAAI,SAAU,QAAO;AACrB,UAAM,QAAQ,SAAS,IAAI,KAAK,KAAK,OAAO,KAAK,KAAK,YAAY,KAAK;AACvE,aAAS,IAAI,OAAO,KAAK;AACzB,WAAO,SAAS,OAAO,IAAK,UAAS,OAAO,SAAS,KAAK,EAAE,KAAK,EAAE,KAAM;AAEzE,QAAI;AAAE,YAAM,IAAI,KAAK,KAAK;AAAA,IAAG,QAAQ;AAAA,IAAuD;AAC5F,UAAM,UAAU,MAAM,KAAK,KAAK,KAAK,EAAE,KAAK,YAAU;AACpD,YAAM,QAAQ,sBAAsB,MAAM;AAC1C,UAAI,MAAM,SAAS,MAAM,QAAQ,MAAM,UAAU,MAAO,OAAM,MAAM,uDAAuD;AAC3H,eAAS,KAAK;AACd,aAAO;AAAA,IACT,CAAC;AACD,aAAS,IAAI,OAAO,OAAO;AAC3B,WAAO,SAAS,OAAO,IAAK,UAAS,OAAO,SAAS,KAAK,EAAE,KAAK,EAAE,KAAM;AACzE,QAAI;AAAE,aAAO,MAAM;AAAA,IAAS,SAAS,OAAO;AAAE,eAAS,OAAO,KAAK;AAAG,YAAM;AAAA,IAAO;AAAA,EACrF;AACA,SAAO;AAAA,IACL,MAAM,OAAO,SAAS,YAAY,KAAK;AACrC,YAAM,QAAQ,YAAY,KAAK;AAC/B,YAAM,UAAU,IAAI,IAAI,OAAO,EAAE,aAAa,IAAI,SAAS;AAC3D,UAAI,SAAS,WAAW,GAAG,KAAK,MAAM,IAAI,QAAQ,MAAM,CAAC,CAAC,GAAG,UAAU;AACrE,eAAO,KAAK,SAAS,WAAW,SAAS,SAAS;AACpD,UAAI,SAAS,WAAW,GAAG,GAAG;AAC5B,YAAI;AACF,gBAAM,OAAO,QAAQ,MAAM,CAAC;AAC5B,cAAI,MAAM,YAAY,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG,UAAU;AAClE,mBAAO,KAAK,SAAS,WAAW,SAAS,SAAS;AAAA,QACtD,QAAQ;AAAA,QAAwD;AAAA,MAClE;AACA,YAAM,MAAM,IAAI,IAAI,OAAO;AAAG,UAAI,aAAa,IAAI,WAAW,KAAK;AACnE,UAAI,IAAI,YAAY,EAAE,OAAO,IAAI,SAAS,CAAC,EAAE,UAAU,OAAQ,QAAO,KAAK,SAAS,WAAW,OAAO,QAAQ;AAC9G,YAAM,QAAQ,OAAO,KAAK,KAAK,YAAY,KAAK;AAChD,YAAM,SAAS,KAAK,SAAS,WAAW,MAAM,MAAM,MAAM,OAAO;AACjE,YAAM,IAAI,KAAK,KAAK;AACpB,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ,OAAO,SAAS,YAAY,KAAK;AAC7C,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,MAAO,QAAO,KAAK,SAAS,WAAW,MAAM,MAAM,MAAM,SAAS;AACtE,YAAM,QAAQ,YAAY,KAAK;AAE/B,aAAO,KAAK,SAAS,WAAW,OAAO,QAAQ;AAAA,IACjD;AAAA,IACA;AAAA,IACA,MAAM,QAAQ,SAAS,YAAY,KAAK,QAAQ;AAC9C,YAAM,SAAS,IAAI,IAAI,OAAO,EAAE,aAAa,OAAO,SAAS;AAC7D,UAAI,CAAC,OAAO,UAAW,OAAO,WAAW,KAAK,OAAO,CAAC,MAAM,GAAK,QAAO;AACxE,UAAI,OAAO,WAAW,EAAG,OAAM,MAAM,+CAA+C;AACpF,YAAM,QAAQ,OAAO,CAAC;AACtB,UAAI,CAAC,MAAM,WAAW,GAAG,EAAG,QAAO,kBAAkB,KAAK;AAC1D,YAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,UAAI,CAAC,YAAY,KAAK,IAAI,EAAG,OAAM,MAAM,0BAA0B;AACnE,UAAI,QAA8B;AAClC,UAAI;AAAE,gBAAQ,MAAM,IAAI,KAAK,IAAI;AAAG,YAAI,MAAO,SAAQ,sBAAsB,KAAK;AAAA,MAAG,QAAQ;AAAE,gBAAQ;AAAA,MAAM;AAC7G,YAAM,SAAS,UAAU,QAAQ,MAAM,MAAM,QAAQ,KAAK,MAAM,MAAM,IAAI;AAC1E,UAAI,CAAC,OAAQ,OAAM,MAAM,0HAA0H;AACnJ,YAAM,QAAQ,sBAAsB,MAAM;AAC1C,UAAI,MAAM,SAAS,KAAM,OAAM,MAAM,8BAA8B;AACnE,UAAI,CAAC,MAAO,UAAS,KAAK;AAAA,WACrB;AAAE,YAAI;AAAE,cAAI,MAAM,YAAY,KAAK,IAAI,EAAG,UAAS,KAAK;AAAA,QAAG,QAAQ;AAAA,QAAoC;AAAA,MAAE;AAC9G,aAAO,kBAAkB,MAAM,KAAK;AAAA,IACtC;AAAA,EACF;AACF;;;ACrTO,IAAM,kBAAkB;AACxB,IAAM,oBAAoB,CAAC,OAAuB,kBAAkB;AACpE,IAAM,kBAAkB,CAAC,SAC9B,KAAK,KAAK,EAAE,YAAY,EAAE,WAAW,eAAe;AAqB/C,SAAS,uBAAuB,OAAgC;AACrE,QAAM,IAAI;AACV,MACE,CAAC,KACD,OAAO,EAAE,OAAO,YAChB,CAAC,yBAAyB,KAAK,EAAE,EAAE,KACnC,OAAO,EAAE,UAAU,YACnB,CAAC,EAAE,MAAM,KAAK,KACd,EAAE,MAAM,SAAS,OACjB,OAAO,EAAE,aAAa,YACtB,CAAC,EAAE,YACH,EAAE,SAAS,SAAS,OACpB,EAAE,YAAY,aAAa,aAC3B,EAAE,WAAW,YAAY,KACzB,OAAO,EAAE,WAAW,WAAW,YAC/B,CAAC,EAAE,WAAW,OAAO,KAAK,KAC1B,EAAE,WAAW,OAAO,SAAS,KAC7B;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,IAAI,EAAE;AAAA,IACN,OAAO,EAAE;AAAA,IACT,UAAU,EAAE;AAAA,IACZ,YAAY,EAAE,GAAG,EAAE,WAAW;AAAA,EAChC;AACF;AACO,SAAS,0BACd,OAAyC,CAAC,GACrB;AACrB,QAAM,OAAO,IAAI;AAAA,IACf,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAAA,MACnC;AAAA,MACA,IAAI,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,uBAAuB,CAAC,CAAC,CAAC,CAAC;AAAA,IACzD,CAAC;AAAA,EACH;AAGA,QAAM,gBAAgB,IAAI;AAAA,IACxB,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE;AAAA,MAAQ,CAAC,YAC1B,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,IAC7C;AAAA,EACF;AACA,MAAI,mBAAmB;AACvB,WAAS,gBAAwB;AAC/B,QAAI;AACJ,OAAG;AACD,iBAAW,UAAU,EAAE,gBAAgB;AAAA,IACzC,SAAS,cAAc,IAAI,QAAQ;AACnC,WAAO;AAAA,EACT;AACA,QAAM,YAAY,oBAAI,IAA6B;AACnD,SAAO;AAAA,IACL,MAAM,KAAK,SAAS;AAClB,aAAO,CAAC,GAAI,KAAK,IAAI,OAAO,GAAG,OAAO,KAAK,CAAC,CAAE,EAAE;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,KAAK,SAAS,QAAQ,kBAAkB;AAC5C,YAAM,UAAU,KAAK,IAAI,OAAO,KAAK,oBAAI,IAA4B;AACrE,YAAM,UAAU,QAAQ,IAAI,OAAO,EAAE;AACrC,WAAK,SAAS,YAAY,UAAU;AAClC,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,YAAM,OAAO,uBAAuB;AAAA,QAClC,GAAG;AAAA,QACH,UAAU,cAAc;AAAA,MAC1B,CAAC;AACD,cAAQ,IAAI,KAAK,IAAI,IAAI;AACzB,WAAK,IAAI,SAAS,OAAO;AACzB,gBAAU,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC5C,aAAO,uBAAuB,IAAI;AAAA,IACpC;AAAA,IACA,UAAU,SAAS,UAAU;AAC3B,YAAM,MAAM,UAAU,IAAI,OAAO,KAAK,oBAAI,IAAI;AAC9C,UAAI,IAAI,QAAQ;AAChB,gBAAU,IAAI,SAAS,GAAG;AAC1B,aAAO,MAAM;AACX,YAAI,OAAO,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,wBACd,MACA,UAAwB,OACH;AACrB,QAAM,YAAY,oBAAI,IAA6B;AACnD,QAAM,MAAM,CAAC,YACX,GAAG,IAAI,GAAG,KAAK,SAAS,GAAG,IAAI,MAAM,GAAG,WAAW,mBAAmB,OAAO,CAAC;AAChF,iBAAe,KAAK,UAAsC;AACxD,QAAI,SAAS,WAAW;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,yCAAyC,SAAS,MAAM;AAAA,MAC1D;AACF,WAAO,SAAS,KAAK;AAAA,EACvB;AACA,SAAO;AAAA,IACL,MAAM,KAAK,SAAS,QAAQ;AAC1B,YAAM,MAAM,MAAM;AAAA,QAChB,MAAM,QAAQ,IAAI,OAAO,GAAG,EAAE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AAAA,MAC/D;AACA,UAAI,CAAC,MAAM,QAAQ,GAAG;AACpB,cAAM,IAAI,MAAM,oCAAoC;AACtD,aAAO,IAAI,IAAI,sBAAsB;AAAA,IACvC;AAAA,IACA,MAAM,KAAK,SAAS,QAAQ,kBAAkB;AAC5C,YAAM,SAAS;AAAA,QACb,MAAM;AAAA,UACJ,MAAM,QAAQ,IAAI,OAAO,GAAG;AAAA,YAC1B,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU,EAAE,QAAQ,iBAAiB,CAAC;AAAA,UACnD,CAAC;AAAA,QACH;AAAA,MACF;AACA,gBAAU,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC;AAC5C,aAAO;AAAA,IACT;AAAA,IACA,UAAU,SAAS,UAAU;AAC3B,YAAM,MAAM,UAAU,IAAI,OAAO,KAAK,oBAAI,IAAI;AAC9C,UAAI,IAAI,QAAQ;AAChB,gBAAU,IAAI,SAAS,GAAG;AAC1B,aAAO,MAAM;AACX,YAAI,OAAO,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAIO,SAAS,oBACd,OAC4B;AAC5B,SACE,UAAU,QACV,OAAO,UAAU,YACjB,mBAAmB,SACnB,OAAQ,MAA4B,kBAAkB;AAE1D;AAcO,SAAS,aACd,cACA,QACA,SACA,OACe;AACf,QAAM,SAAS,oBAAI,IAA0B;AAC7C,MAAI,QAAQ,GACV,SAAS;AACX,SAAO,QAAQ,CAAC,KAAK,MAAM;AACzB,UAAM,SAAS,aAAa,IAAI,CAAC,SAAS,IAAI,IAAI,KAAK,IAAI,GACzD,SAAS,QAAQ,CAAC,KAAK,EAAE,OAAO,MAAM,OAAO,aAAa;AAC5D,UAAM,MAAM,KAAK,UAAU,CAAC,QAAQ,OAAO,OAAO,OAAO,SAAS,IAAI,CAAC;AACvE,UAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,QAAI,MAAO,OAAM;AAAA,QACZ,QAAO,IAAI,KAAK,EAAE,QAAQ,QAAQ,QAAQ,OAAO,EAAE,CAAC;AACzD,QAAI,OAAO,MAAO;AAAA,aACT,OAAO,UAAU,KAAM;AAAA,EAClC,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAAA,IAC7D,WAAW,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AC1KA,IAAM,IAAI,CACR,MACA,WACA,aACA,KACA,KACA,QACA,UACqB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,oBAAuC;AAAA,EAClD,GAAG,CAAC,QAAQ,OAAO,EAAE;AAAA,IAAI,CAAC,MACxB;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,QAAQ;AAAA,IACnB;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,UAAU,QAAQ;AAAA,EAC7B;AAAA,EACA,EAAE,UAAU,gBAAgB,8BAA8B,GAAG,GAAG,UAAU;AAAA,IACxE;AAAA,EACF,CAAC;AAAA,EACD;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAAA,EACA,GAAG,CAAC,SAAS,SAAS,QAAQ,SAAS,OAAO,EAAE;AAAA,IAAI,CAAC,MACnD;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,MAAM;AAAA,IACT;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,QAAQ,MAAM;AAAA,EACzB;AAAA,EACA,GAAG,CAAC,QAAQ,MAAM,EAAE;AAAA,IAAI,CAAC,MACvB;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,UAAU,MAAM;AAAA,IAC3B;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,QAAQ,QAAQ;AAAA,EAC3B;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AAAA,EACA,GAAG,CAAC,YAAY,eAAe,WAAW,EAAE;AAAA,IAAI,CAAC,MAC/C;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,QAAQ,MAAM;AAAA,IACzB;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,QAAQ,MAAM;AAAA,EACzB;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,QAAQ,UAAU,MAAM;AAAA,EACnC;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,QAAQ,QAAQ,MAAM;AAAA,EACjC;AAAA,EACA,GAAG,CAAC,OAAO,SAAS,QAAQ,SAAS,MAAM,EAAE;AAAA,IAAI,CAAC,MAChD,EAAE,GAAG,GAAG,CAAC,YAAY,2BAA2B,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC;AAAA,EAC5E;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAAA,EACA,GAAG,CAAC,SAAS,UAAU,EAAE;AAAA,IAAI,CAAC,MAC5B;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,QAAQ;AAAA,IACX;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,GAAG,CAAC,WAAW,UAAU,EAAE;AAAA,IAAI,CAAC,MAC9B;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,GACE;AAAA,IACE,CAAC,WAAW,MAAM;AAAA,IAClB,CAAC,aAAa,QAAQ;AAAA,IACtB,CAAC,cAAc,MAAM;AAAA,IACrB,CAAC,eAAe,UAAU;AAAA,EAC5B,EACA;AAAA,IAAI,CAAC,CAAC,GAAG,CAAC,MACV;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,MAAM;AAAA,EACjB;AAAA,EACA,EAAE,QAAQ,0BAA0B,0BAA0B,GAAG,GAAG,QAAQ;AAAA,IAC1E;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,aAAa,MAAM;AAAA,EACtB;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,aAAa,QAAQ;AAAA,EACxB;AAAA,EACA,GAAG,CAAC,gBAAgB,YAAY,EAAE;AAAA,IAAI,CAAC,MACrC;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,WAAW;AAAA,IACd;AAAA,EACF;AAAA,EACA,GAAG,CAAC,QAAQ,SAAS,OAAO,QAAQ,SAAS,EAAE;AAAA,IAAI,CAAC,MAClD;AAAA,MACE;AAAA,MACA,GAAG,CAAC;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,CAAC,UAAU;AAAA,IACb;AAAA,EACF;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,UAAU,UAAU;AAAA,EAC/B;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,QAAQ,YAAY,UAAU;AAAA,EACjC;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,CAAC,YAAY,MAAM;AAAA,EACrB;AACF;AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YACE,SACO,OAAO,GACP,KAAK,OAAO,GACnB;AACA,UAAM,OAAO;AAHN;AACA;AAAA,EAGT;AACF;AAOO,SAAS,eACd,QACA,QACA,SACA,WACa;AACb,MAAI,CAAC,OAAO,KAAK,KAAK,OAAO,SAAS;AACpC,UAAM,IAAI,aAAa,gDAA2C;AACpE,QAAM,SAAkB,CAAC;AACzB,MAAI,MAAM;AACV,SAAO,MAAM,OAAO,QAAQ;AAC1B,QAAI,KAAK,KAAK,OAAO,GAAG,CAAE,GAAG;AAC3B;AACA;AAAA,IACF;AACA,UAAM,OAAO;AACb,QAAI;AACJ,QAAI,OAAO,GAAG,MAAM,KAAK;AACvB;AACA,UAAI,OAAO;AACX,UAAI,SAAS;AACb,aAAO,MAAM,OAAO,QAAQ;AAC1B,YAAI,OAAO,GAAG,MAAM,KAAK;AACvB,cAAI,OAAO,MAAM,CAAC,MAAM,KAAK;AAC3B,oBAAQ;AACR,mBAAO;AAAA,UACT,OAAO;AACL;AACA,qBAAS;AACT;AAAA,UACF;AAAA,QACF,MAAO,SAAQ,OAAO,KAAK;AAAA,MAC7B;AACA,UAAI,CAAC;AACH,cAAM,IAAI,aAAa,6BAA6B,MAAM,GAAG;AAC/D,aAAO,KAAK,EAAE,MAAM,SAAS,MAAM,MAAM,IAAI,IAAI,CAAC;AAAA,IACpD,WAAW,OAAO,GAAG,MAAM,KAAK;AAC9B;AACA,aAAO,MAAM,OAAO,UAAU,OAAO,GAAG,MAAM,KAAK;AACjD,YAAI,OAAO,GAAG,MAAM,KAAM;AAC1B;AAAA,MACF;AACA;AACA,UAAI;AACF,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,MAAM,KAAK,MAAM,OAAO,MAAM,MAAM,GAAG,CAAC;AAAA,UACxC;AAAA,UACA,IAAI;AAAA,QACN,CAAC;AAAA,MACH,QAAQ;AACN,cAAM,IAAI,aAAa,gCAAgC,MAAM,GAAG;AAAA,MAClE;AAAA,IACF,WAAW,OAAO,GAAG,MAAM,KAAK;AAE9B,YAAM,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACvC,YAAM,OAAO,MAAM,IAAI,KAAK,OAAO,MAAM,MAAM,GAAG,GAAG;AACrD,YAAM,IAAI;AAAA,QACR,MAAM,KAAK,KAAK,SAAS,MAAM,UAAU,KAAK,IAAI,IAC9C,iEACA,2CAA2C,IAAI,iBAAiB,IAAI;AAAA,QACxE;AAAA,QACA,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,MAC5B;AAAA,IACF,WACG,QAAQ,OACN,MAAM,GAAG,EACT,MAAM,2CAA2C,GACpD;AACA,aAAO,MAAM,CAAC,EAAE;AAChB,aAAO,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC;AAAA,IAC/D,WAAY,QAAQ,OAAO,MAAM,GAAG,EAAE,MAAM,yBAAyB,GAAI;AACvE,aAAO,MAAM,CAAC,EAAE;AAChB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,MAAM,MAAM,CAAC,EAAE,YAAY;AAAA,QAC3B;AAAA,QACA,IAAI;AAAA,MACN,CAAC;AAAA,IACH,WACG,QAAQ,OAAO,MAAM,GAAG,EAAE,MAAM,8BAA8B,GAC/D;AACA,aAAO,MAAM,CAAC,EAAE;AAChB,aAAO,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC;AAAA,IAC3D,MAAO,OAAM,IAAI,aAAa,wBAAwB,OAAO,GAAG,CAAC,KAAK,IAAI;AAC1E,QAAI,OAAO,SAAS;AAClB,YAAM,IAAI,aAAa,2BAA2B,IAAI;AAAA,EAC1D;AACA,SAAO,KAAK,EAAE,MAAM,OAAO,MAAM,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC;AACzD,MAAI,IAAI,GACN,QAAQ;AACV,QAAM,OAAO,MAAM,OAAO,CAAC;AAC3B,QAAM,OAAO,MAAM,OAAO,GAAG;AAC7B,QAAM,SAAS,CAAC,MAAc;AAC5B,QAAI,KAAK,EAAE,SAAS;AAClB,YAAM,IAAI,aAAa,YAAY,CAAC,KAAK,KAAK,EAAE,MAAM,KAAK,EAAE,EAAE;AACjE,WAAO,KAAK;AAAA,EACd;AACA,QAAM,OAAO,CACX,MACA,MACA,MACA,QACiB,EAAE,MAAM,QAAQ,MAAM,MAAM,MAAM,GAAG;AACxD,QAAM,WAAmC;AAAA,IACvC,IAAI;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACA,WAAS,WAAW,MAAM,GAAgB;AACxC,QAAI,EAAE,QAAQ;AACZ,YAAM,IAAI,aAAa,gCAAgC,KAAK,EAAE,IAAI;AACpE,UAAM,IAAI,KAAK;AACf,QAAI;AACJ,QAAI,EAAE,SAAS,UAAU;AACvB,UAAI,CAAC,OAAO,SAAS,OAAO,EAAE,IAAI,CAAC;AACjC,cAAM,IAAI,aAAa,0BAA0B,EAAE,MAAM,EAAE,EAAE;AAC/D,aAAO,EAAE,MAAM,WAAW,OAAO,OAAO,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,IAAI,EAAE,GAAG;AAAA,IAC1E,WAAW,EAAE,SAAS;AACpB,aAAO,EAAE,MAAM,WAAW,OAAO,EAAE,MAAM,MAAM,EAAE,MAAM,IAAI,EAAE,GAAG;AAAA,aACzD,EAAE,SAAS;AAClB,aAAO,EAAE,MAAM,SAAS,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,IAAI,EAAE,GAAG;AAAA,aACtD,CAAC,QAAQ,SAAS,MAAM,EAAE,SAAS,EAAE,IAAI;AAChD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,EAAE,SAAS,SAAS,OAAO,EAAE,SAAS;AAAA,QAC7C,MAAM,EAAE;AAAA,QACR,IAAI,EAAE;AAAA,MACR;AAAA,aACO,EAAE,SAAS,KAAK;AACvB,aAAO,WAAW;AAClB,aAAO,GAAG;AAAA,IACZ,WAAW,CAAC,OAAO,KAAK,GAAG,EAAE,SAAS,EAAE,IAAI,GAAG;AAC7C,YAAM,MAAM,WAAW,EAAE,SAAS,QAAQ,IAAI,CAAC;AAC/C,aAAO,KAAK,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,MAAM,IAAI,EAAE;AAAA,IACtD,WAAW,EAAE,SAAS,QAAQ;AAC5B,aAAO,GAAG;AACV,YAAM,OAAsB,CAAC;AAC7B,UAAI,KAAK,EAAE,SAAS,KAAK;AACvB,WAAG;AACD,eAAK,KAAK,WAAW,CAAC;AACtB,cAAI,KAAK,EAAE,SAAS,IAAK;AACzB,eAAK;AAAA,QACP,SAAS;AAAA,MACX;AACA,aAAO,KAAK,EAAE,MAAM,MAAM,EAAE,MAAM,OAAO,GAAG,EAAE,EAAE;AAAA,IAClD;AACE,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE;AAAA,QACF,EAAE;AAAA,MACJ;AACF,WAAO,KAAK,EAAE,SAAS,UAAU,SAAS,KAAK,EAAE,IAAI,KAAK,OAAO,KAAK;AACpE,YAAM,KAAK,KAAK;AAChB,YAAM,IAAI,SAAS,GAAG,IAAI;AAC1B,UAAI,GAAG,SAAS,MAAM;AACpB,YAAI,KAAK,EAAE,SAAS;AAClB,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,GAAG;AAAA,YACH,KAAK,EAAE;AAAA,UACT;AACF,eAAO,GAAG;AACV,cAAM,OAAO,CAAC,IAAI;AAClB,WAAG;AACD,eAAK,KAAK,WAAW,CAAC;AACtB,cAAI,KAAK,EAAE,SAAS,IAAK;AACzB,eAAK;AAAA,QACP,SAAS;AACT,eAAO,KAAK,SAAS,MAAM,KAAK,MAAM,OAAO,GAAG,EAAE,EAAE;AAAA,MACtD,WAAW,GAAG,SAAS,WAAW;AAChC,cAAM,KAAK,WAAW,IAAI,CAAC;AAC3B,eAAO,KAAK;AACZ,cAAM,KAAK,WAAW,IAAI,CAAC;AAC3B,eAAO,KAAK,cAAc,CAAC,MAAM,IAAI,EAAE,GAAG,KAAK,MAAM,GAAG,EAAE;AAAA,MAC5D,OAAO;AACL,cAAM,QAAQ,WAAW,IAAI,CAAC;AAC9B,eAAO,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,KAAK,MAAM,MAAM,EAAE;AAAA,MACjE;AAAA,IACF;AACA,QAAI,KAAK,EAAE,SAAS,SAAS,OAAO,IAAI,CAAC,GAAG,SAAS;AACnD,YAAM,IAAI;AAAA,QACR;AAAA,QACA,KAAK,EAAE;AAAA,QACP,OAAO,IAAI,CAAC,EAAG;AAAA,MACjB;AACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,MAAM,WAAW;AACvB,MAAI,KAAK,EAAE,SAAS;AAClB,UAAM,IAAI,aAAa,qBAAqB,KAAK,EAAE,MAAM,KAAK,EAAE,EAAE;AACpE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAAS,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAC1D,QAAM,OAAO,CAAC,IAAmB,MAAgC;AAC/D,UAAM,OAAO,CAAC,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,MAAM,MAAM,CAAC,CAAC;AACxD,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,EAAE;AAAA,QACF,EAAE;AAAA,MACJ;AACF,WAAO,KAAK,CAAC,KAAK;AAAA,EACpB;AACA,WAAS,MAAM,GAAgB,QAAQ,GAAgB;AACrD,QAAI,QAAQ;AACV,YAAM,IAAI,aAAa,gCAAgC,EAAE,MAAM,EAAE,EAAE;AACrE,QAAI,EAAE,SAAS;AACb,aAAO,EAAE,UAAU,OACf,SACA,OAAO,EAAE,UAAU,YACjB,SACA,OAAO,EAAE,UAAU,WACjB,WACA;AACV,QAAI,EAAE,SAAS,SAAS;AACtB,YAAM,IAAI,OAAO,IAAI,EAAE,IAAI;AAC3B,UAAI,CAAC,GAAG;AACN,cAAM,SAAS,UAAU,EAAE,IAAI;AAC/B,YAAI,QAAQ;AACV,iBAAO,OAAO,GAAG,OAAO,GAAG;AAC3B,iBAAO,aAAa,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAC9C,iBAAO,OAAO;AAAA,QAChB;AACA,cAAM,IAAI;AAAA,UACR,iCAAiC,EAAE,IAAI;AAAA,UACvC,EAAE;AAAA,UACF,EAAE;AAAA,QACJ;AAAA,MACF;AACA,WAAK,IAAI,EAAE,IAAI;AACf,QAAE,YAAY,MAAM,SAAS,SAAS;AACtC,aAAO,EAAE;AAAA,IACX;AACA,UAAM,WAAW,YAAY,GAAG,CAAC,QAAQ,MAAM,KAAK,QAAQ,CAAC,CAAC;AAC9D,QAAI,aAAa,OAAW,QAAO;AACnC,UAAM,KAAK,EAAE,KAAK,IAAI,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC;AAChD,UAAM,OAAO,CAAC,OAAe,MAAmB;AAC9C,UAAI,GAAG,KAAK,MAAM,UAAa,GAAG,KAAK,MAAM,UAAU,GAAG,KAAK,MAAM;AACnE,cAAM,IAAI;AAAA,UACR,YAAY,CAAC,cAAc,GAAG,KAAK,CAAC;AAAA,UACpC,EAAE,KAAK,KAAK,EAAG;AAAA,UACf,EAAE,KAAK,KAAK,EAAG;AAAA,QACjB;AAAA,IACJ;AACA,QAAI,EAAE,KAAK,WAAW,KAAK,KAAK,EAAE,KAAK,WAAW,QAAQ,GAAG;AAC3D,YAAM,KAAK,EAAE,KAAK,MAAM,GAAG,EAAE,CAAC;AAC9B,UAAI,CAAC,OAAO,MAAM,KAAK,EAAE,SAAS,EAAE,GAAG;AACrC,WAAG,QAAQ,CAAC,GAAG,MAAM,KAAK,GAAG,MAAM,CAAC;AACpC,eAAO;AAAA,MACT;AACA,UAAI,CAAC,KAAK,KAAK,KAAK,KAAK,GAAG,EAAE,SAAS,EAAE,GAAG;AAC1C,WAAG,QAAQ,CAAC,GAAG,MAAM,KAAK,GAAG,QAAQ,CAAC;AACtC,eAAO;AAAA,MACT;AACA,UAAI,OAAO,QAAQ,GAAG,KAAK,CAAC,MAAM,MAAM,WAAW;AACjD,cAAM,IAAI;AAAA,UACR;AAAA,UACA,EAAE;AAAA,UACF,EAAE;AAAA,QACJ;AACF,WAAK,IAAI,CAAC;AACV,aAAO;AAAA,IACT;AACA,UAAM,OAAO,kBAAkB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI;AAC5D,QAAI,CAAC;AACH,YAAM,IAAI,aAAa,qBAAqB,EAAE,IAAI,IAAI,EAAE,MAAM,EAAE,EAAE;AACpE,QAAI,GAAG,SAAS,KAAK,OAAO,GAAG,SAAS,KAAK;AAC3C,YAAM,IAAI,aAAa,OAAO,KAAK,SAAS,KAAK,EAAE,MAAM,EAAE,EAAE;AAC/D,QAAI,KAAK,SAAS,OAAO;AACvB,YAAM,OAAO,KAAK;AAClB,SAAG,QAAQ,CAAC,GAAG,MAAM,KAAK,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,CAAE,CAAC;AAAA,IACnE;AACA,QAAI,EAAE,SAAS,MAAM;AACnB,WAAK,GAAG,MAAM;AACd,aAAO,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;AAAA,IAC5B;AACA,QAAI,EAAE,SAAS,OAAO;AACpB,UAAI,GAAG,SAAS,MAAM;AACpB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,EAAE;AAAA,UACF,EAAE;AAAA,QACJ;AACF,YAAM,WAA0B,CAAC;AACjC,SAAG,QAAQ,CAAC,GAAG,MAAM;AACnB,YAAI,MAAM,GAAG,SAAS,KAAK,IAAI,MAAM,EAAG,UAAS,KAAK,CAAC;AAAA,YAClD,MAAK,GAAG,MAAM;AAAA,MACrB,CAAC;AACD,aAAO,KAAK,UAAU,CAAC;AAAA,IACzB;AACA,QAAI,EAAE,SAAS,UAAU;AACvB,UAAI,GAAG,SAAS,MAAM;AACpB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,EAAE;AAAA,UACF,EAAE;AAAA,QACJ;AACF,YAAM,WAA0B,CAAC;AACjC,eAAS,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,GAAG;AACzC,aAAK,CAAC,GAAG,CAAC,GAAI,GAAG,CAAC,CAAE,GAAG,CAAC;AACxB,iBAAS,KAAK,GAAG,IAAI,CAAC,CAAE;AAAA,MAC1B;AACA,eAAS,KAAK,GAAG,GAAG,SAAS,CAAC,CAAE;AAChC,aAAO,KAAK,UAAU,CAAC;AAAA,IACzB;AACA,QAAI,EAAE,KAAK,WAAW,QAAQ,GAAG;AAC/B,YAAM,UAAU,EAAE,KAAK,CAAC;AACxB,YAAM,QAAQ,EAAE,KAAK,EAAE,SAAS,eAAe,IAAI,CAAC;AACpD,UAAI,SAAS,SAAS,aAAa,OAAO,QAAQ,UAAU,UAAU;AACpE,YAAI,QAAQ,MAAM,SAAS;AACzB,gBAAM,IAAI;AAAA,YACR;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,UACV;AACF,YACE,CAAC,SACA,MAAM,SAAS,aAAa,OAAO,MAAM,UAAU,UACpD;AACA,gBAAM,QAAQ,OAAO,SAAS;AAC9B,cAAI,CAAC,wBAAwB,KAAK,OAAO,KAAK,CAAC;AAC7C,kBAAM,IAAI;AAAA,cACR;AAAA,cACA,EAAE;AAAA,cACF,EAAE;AAAA,YACJ;AACF,cAAI;AACF,gBAAI,OAAO,QAAQ,OAAO,GAAG,KAAK,GAAG;AAAA,UACvC,QAAQ;AACN,kBAAM,IAAI;AAAA,cACR;AAAA,cACA,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,WAAW,SAAU,QAAO,KAAK,IAAI,CAAC;AAC/C,WAAO,KAAK;AAAA,EACd;AACA,QAAM,OAAO,MAAM,GAAG;AACtB,SAAO,EAAE,KAAK,cAAc,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG,KAAK;AACrD;AAGO,SAAS,eACd,KACA,QACA,WACe;AACf,QAAM,OAAO,CAAC,MAAqB;AACjC,UAAM,IAAI,MAAM,CAAC;AAAA,EACnB;AACA,QAAM,MAAM,CAAC,MACX,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IACtC,IACA,KAAK,2BAA2B;AACtC,QAAM,MAAM,CAAC,MACX,OAAO,MAAM,WAAW,IAAI,KAAK,gBAAgB;AACnD,QAAM,MAAM,CAAC,MACX,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,IACpD,IACA,KAAK,wBAAwB;AACnC,QAAM,UAAU,CAAC,GAAiB,MAAM,GAAG,MAAM,QAAmB;AAClE,UAAM,IAAI,IAAI,CAAC;AACf,WAAO,OAAO,UAAU,CAAC,KAAK,KAAK,OAAO,KAAK,MAC3C,IACA,KAAK,+BAA+B,GAAG,QAAQ,GAAG,GAAG;AAAA,EAC3D;AACA,QAAM,QAAQ,CAAC,GAAiB,MAC9B,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AACxC,QAAM,OAAO,CAAC,MAA0B;AACtC,UAAM,IAAI,IAAI,CAAC;AACf,QACE,CAAC,gFAAgF;AAAA,MAC/E;AAAA,IACF;AAEA,WAAK,kDAAkD;AACzD,UAAM,IAAI,IAAI,KAAK,CAAC;AACpB,UAAM,MAAM,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC,GAC/B,QAAQ,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC;AAC9B,QACE,CAAC,OAAO,SAAS,EAAE,QAAQ,CAAC,KAC5B,QAAQ,KACR,QAAQ,MACR,MAAM,KACN,MAAM,IAAI,KAAK,KAAK,IAAI,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,WAAW;AAErE,WAAK,eAAe;AACtB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,CAAC,MAAkC;AAC/C,QACE,MAAM,QACN,OAAO,MAAM,YACb,OAAO,MAAM,YACb,OAAO,MAAM,aACb,CAAC,MAAM,QAAQ,CAAC;AAEhB,WAAK,+BAA+B;AACtC,QAAI,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ;AAC3D,WAAK,wBAAwB;AAC/B,QAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC;AAC7C,WAAK,uBAAuB;AAC9B,QAAI,OAAO,MAAM,YAAY,EAAE,SAAS;AACtC,WAAK,yCAAyC;AAChD,QACE,MAAM,QAAQ,CAAC,MACd,EAAE,SAAS,OAAS,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,CAAC,IAAI;AAE3D,WAAK,4BAA4B;AACnC,WAAO;AAAA,EACT;AACA,MAAI;AACJ,MAAI,SAAS;AACb,WAAS,IAAI,GAA8B;AACzC,QAAI,EAAE,SAAS,EAAG,MAAK,mCAAmC;AAC1D,QAAI,EAAE,SAAS,UAAW,QAAO,EAAE;AACnC,QAAI,EAAE,SAAS,SAAS;AACtB,UAAI,CAAC,OAAO,UAAU,eAAe,KAAK,QAAQ,EAAE,IAAI,EAAG,QAAO;AAClE,YAAM,IAAI,MAAM,OAAO,EAAE,IAAI,KAAK,IAAI;AACtC,UAAI,MAAM,KAAM,QAAO;AACvB,UAAI,EAAE,cAAc,SAAU,QAAO,IAAI,CAAC;AAC1C,UAAI,EAAE,cAAc,UAAU,OAAO,MAAM;AACzC,aAAK,qBAAqB;AAC5B,UAAI,EAAE,cAAc,WAAY,QAAO,KAAK,CAAC,EAAE,YAAY;AAC3D,UAAI,EAAE,cAAc,OAAQ,QAAO,IAAI,CAAC;AACxC,UAAI,EAAE,cAAc,YAAa,QAAO,IAAI,CAAC;AAC7C,aAAO;AAAA,IACT;AACA,UAAM,WAAW,YAAY,CAAC;AAC9B,QAAI,UAAU;AACZ,UAAI,SAAS,MAAO,MAAK,SAAS,KAAK;AACvC,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B;AACA,UAAM,OAAO,EAAE;AACf,UAAM,OAAO,EAAE;AACf,QAAI,SAAS,KAAM,QAAO,IAAI,IAAI,KAAK,CAAC,CAAE,MAAM,OAAO,KAAK,CAAC,IAAK,KAAK,CAAC,CAAE;AAC1E,QAAI,SAAS,OAAO;AAClB,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AACxC,YAAI,IAAI,KAAK,CAAC,CAAE,MAAM,KAAM,QAAO,IAAI,KAAK,IAAI,CAAC,CAAE;AACrD,aAAO,IAAI,KAAK,KAAK,SAAS,CAAC,CAAE;AAAA,IACnC;AACA,QAAI,SAAS,UAAU;AACrB,YAAM,IAAI,IAAI,KAAK,CAAC,CAAE;AACtB,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AACxC,YAAI,MAAM,GAAG,IAAI,KAAK,CAAC,CAAE,CAAC,EAAG,QAAO,IAAI,KAAK,IAAI,CAAC,CAAE;AACtD,aAAO,IAAI,KAAK,KAAK,SAAS,CAAC,CAAE;AAAA,IACnC;AACA,QAAI,SAAS,YAAY;AACvB,iBAAW,OAAO,MAAM;AACtB,cAAM,IAAI,IAAI,GAAG;AACjB,YAAI,MAAM,KAAM,QAAO;AAAA,MACzB;AACA,aAAO;AAAA,IACT;AACA,QAAI,SAAS,WAAW;AACtB,UAAI;AACF,eAAO,IAAI,KAAK,CAAC,CAAE;AAAA,MACrB,QAAQ;AACN,eAAO,IAAI,KAAK,CAAC,CAAE;AAAA,MACrB;AAAA,IACF;AACA,QAAI,SAAS,YAAY,SAAS,SAAS;AACzC,YAAMC,KAAI,IAAI,KAAK,CAAC,CAAE;AACtB,UAAI,SAAS,YAAYA,OAAM,MAAO,QAAO;AAC7C,UAAI,SAAS,WAAWA,OAAM,KAAM,QAAO;AAC3C,YAAMC,KAAI,IAAI,KAAK,CAAC,CAAE;AACtB,aAAO,SAAS,WACZA,OAAM,QACJ,QACAD,OAAM,QAAQC,OAAM,OAClB,OACA,OACJA,OAAM,OACJ,OACAD,OAAM,QAAQC,OAAM,OAClB,OACA;AAAA,IACV;AACA,UAAM,KAAK,KAAK,IAAI,GAAG;AACvB,UAAM,IAAI,GAAG,CAAC,KAAK,MACjB,IAAI,GAAG,CAAC,KAAK,MACb,IAAI,GAAG,CAAC,KAAK;AACf,QAAI,SAAS,UAAW,QAAO,MAAM;AACrC,QAAI,SAAS;AACX,aAAO,MAAM,QAAQ,MAAM,MAAO,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW;AACrE,QAAI,SAAS,SAAU,QAAO,MAAM,GAAG,CAAC,IAAI,OAAO;AACnD,QAAI,SAAS;AACX,aAAO,MAAM,OACT,OACA;AAAA,QACE,GACG,MAAM,CAAC,EACP,OAAO,CAAC,MAAM,MAAM,IAAI,EACxB,IAAI,GAAG,EACP,KAAK,IAAI,CAAC,CAAC;AAAA,MAChB;AACN,QAAI,SAAS,SAAS;AACpB,UAAI,MAAM,KAAM,QAAO;AACvB,UAAI,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,MAAM,QAAQ,MAAM,GAAG,CAAC,CAAC,EAAG,QAAO;AAC/D,aAAO,GAAG,MAAM,CAAC,EAAE,SAAS,IAAI,IAAI,OAAO;AAAA,IAC7C;AACA,QAAI,GAAG,KAAK,CAAC,MAAM,MAAM,IAAI,EAAG,QAAO;AACvC,QAAI;AACJ,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,cAAM,CAAC;AACP;AAAA,MACF,KAAK;AACH,cAAM,CAAC,IAAI,CAAC;AACZ;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC;AACX;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,IAAI,IAAI,CAAC;AACpB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,IAAI,IAAI,CAAC;AACpB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,IAAI,IAAI,CAAC;AACpB;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,YAAI,IAAI,CAAC,MAAM,EAAG,MAAK,mBAAmB;AAC1C,cAAM,SAAS,SAAS,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC;AACxD;AAAA,MACF,KAAK;AACH,cAAM,MAAM,GAAG,CAAC;AAChB;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,cAAM,CAAC,MAAM,GAAG,CAAC;AACjB;AAAA,MACF,KAAK;AACH,cAAM,IAAK;AACX;AAAA,MACF,KAAK;AACH,cAAM,IAAK;AACX;AAAA,MACF,KAAK;AACH,cAAM,KAAM;AACZ;AAAA,MACF,KAAK;AACH,cAAM,KAAM;AACZ;AAAA,MACF,KAAK;AACH,cAAM,KAAM,KAAM,KAAM;AACxB;AAAA,MACF,KAAK;AACH,cAAM,MAAM,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE;AACrD;AAAA,MACF,KAAK,SAAS;AACZ,cAAMC,KAAI,QAAQ,CAAC;AACnB,cAAMA,KAAI,MAAM,KAAK,IAAI,CAAC,CAAC,EAAE,MAAM,CAACA,EAAC,EAAE,KAAK,EAAE,IAAI;AAClD;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,QAAQ,QAAQ,GAAG,CAAC,IAAI;AAC9B,cAAM,MAAM,KAAK,IAAI,CAAC,CAAC,EACpB,MAAM,OAAO,GAAG,SAAS,IAAI,QAAQ,QAAQ,CAAC,IAAI,MAAS,EAC3D,KAAK,EAAE;AACV;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,MAAM,KAAK,IAAI,CAAC,CAAC,EAAE;AACzB;AAAA,MACF,KAAK;AAEH,YAAI,CAAC,yDAAyD,KAAK,IAAI,CAAC,CAAC;AACvE,eAAK,4BAA4B;AACnC,cAAM,mBAAmB,IAAI,CAAC,CAAC,EAAE;AAAA,UAC/B;AAAA,UACA,CAAC,OAAO,IAAI,GAAG,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE,YAAY,CAAC;AAAA,QACzD;AACA;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,YAAY;AACzB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,YAAY;AACzB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,KAAK;AAClB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,UAAU;AACvB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,QAAQ;AACrB;AAAA,MACF,KAAK;AACH,YAAI,MAAM,GAAI,MAAK,gCAAgC;AACnD,cAAM,QAAQ,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;AACjC,YAAI,MAAM,SAAS,IAAI,CAAC,EAAE,SAAS,IAAI,CAAC,EAAE,SAAS;AACjD,eAAK,kCAAkC;AACzC,cAAM,MAAM,KAAK,IAAI,CAAC,CAAC;AACvB;AAAA,MACF,KAAK;AAAA,MACL,KAAK,QAAQ;AACX,cAAM,QAAQ,MAAM,KAAK,IAAI,CAAC,CAAC,GAC7B,MAAM,QAAQ,CAAC,GACf,MAAM,MAAM,KAAK,GAAG,SAAS,IAAI,IAAI,CAAC,IAAI,GAAG;AAC/C,YAAI,CAAC,IAAI,OAAQ,MAAK,4BAA4B;AAClD,cAAM,OAAO,MAAM;AAAA,UACjB,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,MAAM,MAAM,EAAE;AAAA,UAC1C,CAAC,GAAG,MAAM,IAAI,IAAI,IAAI,MAAM;AAAA,QAC9B,EAAE,KAAK,EAAE;AACT,eACG,SAAS,SAAS,OAAO,MAC1B,MAAM,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,KAC1B,SAAS,SAAS,OAAO;AAC5B;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK;AACjD;AAAA,MACF,KAAK;AACH,cAAM,GAAG,IAAI,GAAG,EAAE,KAAK,EAAE;AACzB;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,aAAa;AAChB,cAAM,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE,YAAY,IAAI,IAAI,CAAC,GACjD,IAAI,MAAM,OAAO,IAAI,CAAC,EAAE,YAAY,IAAI,IAAI,CAAC;AAC/C,cACE,SAAS,aACL,EAAE,SAAS,CAAC,IACZ,SAAS,gBACP,EAAE,WAAW,CAAC,IACd,EAAE,SAAS,CAAC;AACpB;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,iBAAiB;AACpB,cAAM,QAAQ,GAAG,SAAS,eAAe,IAAI,CAAC,KAAK;AACnD,YAAI,CAAC,wBAAwB,KAAK,IAAI,KAAK,CAAC;AAC1C,eAAK,wCAAwC;AAC/C,YAAI,IAAI,CAAC,EAAE,SAAS;AAClB,eAAK,yCAAyC;AAChD,cAAM,KAAK,IAAI;AAAA,UACb,IAAI,CAAC;AAAA,UACL,GAAG,KAAK,IAAI,SAAS,kBAAkB,MAAM,EAAE;AAAA,QACjD;AACA,YAAI,SAAS,aAAc,OAAM,GAAG,KAAK,IAAI,CAAC,CAAC;AAAA,iBACtC,SAAS,iBAAiB;AACjC,cAAI,WAAW;AACf,gBAAM,IAAI,CAAC,EAAE,QAAQ,IAAI,IAAI,aAAwB;AACnD,kBAAM,cAAc,IAAI,CAAC,EAAE;AAAA,cACzB;AAAA,cACA,CAAC,QAAQ,QAAgB;AACvB,oBAAI,QAAQ,IAAK,QAAO;AACxB,oBAAI,QAAQ,IAAK,QAAO,OAAO,SAAS,CAAC,CAAC;AAC1C,oBAAI,QAAQ,OAAO,QAAQ;AACzB,yBAAO;AAAA,oBACL;AAAA,kBACF;AACF,sBAAM,QACJ,OAAO,SAAS,SAAS,SAAS,CAAC,MAAM,WAAW,IAAI;AAC1D,sBAAM,IAAI,OAAO,GAAG;AACpB,uBAAO,IAAI,KAAK,IAAI,SAAS,SAAS,QAClC,OAAO,SAAS,CAAC,KAAK,EAAE,IACxB,KAAK,8BAA8B;AAAA,cACzC;AAAA,YACF;AACA,wBAAY,YAAY;AACxB,gBAAI,WAAW,IAAQ,MAAK,kCAAkC;AAC9D,mBAAO;AAAA,UACT,CAAC;AAAA,QACH,OAAO;AACL,gBAAM,QAAQ,GAAG,KAAK,IAAI,CAAC,CAAC;AAC5B,gBAAM,QAAQ,GAAG,SAAS,IAAI,QAAQ,GAAG,GAAG,GAAG,IAAI;AACnD,gBAAM,QAAQ,KAAK,KAAK;AACxB,cAAI;AACF,yBAAa;AAAA,cACX,OAAO,IAAI,CAAC;AAAA,cACZ,OAAO,MAAM;AAAA,cACb,KAAK,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,cAC5B,QAAQ,MAAM,KAAK,OAAO,CAAC,MAAM,KAAK,IAAI;AAAA,YAC5C;AAAA,QACJ;AACA;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,KAAK,IAAI,IAAI,CAAC,CAAC;AACrB;AAAA,MACF,KAAK;AACH,cAAM,KAAK,MAAM,IAAI,CAAC,CAAC;AACvB;AAAA,MACF,KAAK;AACH,cAAM,KAAK,KAAK,IAAI,CAAC,CAAC;AACtB;AAAA,MACF,KAAK;AACH,cAAM,KAAK,MAAM,IAAI,CAAC,CAAC;AACvB;AAAA,MACF,KAAK;AACH,cAAM,KAAK,KAAK,IAAI,CAAC,CAAC;AACtB;AAAA,MACF,KAAK,SAAS;AACZ,cAAM,QAAQ,OAAO,GAAG,SAAS,IAAI,QAAQ,GAAG,KAAK,EAAE,IAAI;AAC3D,cAAM,KAAK,MAAM,IAAI,CAAC,IAAI,KAAK,IAAI;AACnC;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,KAAK,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAC7B;AAAA,MACF,KAAK;AACH,YAAI,IAAI,CAAC,IAAI,IAAI,CAAC,EAAG,MAAK,kCAAkC;AAC5D,cAAM,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC/C;AAAA,MACF,KAAK;AACH,cAAM,KAAK,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC;AAC7B;AAAA,MACF,KAAK;AACH,cAAM,KAAK,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC;AAC7B;AAAA,MACF,KAAK;AACH,cAAM,MAAM,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,OAAO,CAAC;AACrD;AAAA,MACF,KAAK;AACH,YACE,OAAO,MAAM,aACZ,OAAO,MAAM,YACZ,CAAC,kDAAkD,KAAK,EAAE,KAAK,CAAC;AAElE,eAAK,2BAA2B;AAClC,cAAM,OAAO,CAAC;AACd;AAAA,MACF,KAAK;AACH,YAAI,MAAM,QAAQ,MAAM,MAAO,OAAM;AAAA,iBAC5B,MAAM,UAAU,MAAM,EAAG,OAAM;AAAA,iBAC/B,MAAM,WAAW,MAAM,EAAG,OAAM;AAAA,YACpC,QAAO,KAAK,4BAA4B;AAC7C;AAAA,MACF,KAAK;AACH,cAAM,KAAK,CAAC,EAAE,YAAY;AAC1B;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC;AACzB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;AACxB;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE;AACb;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;AAC5B;AAAA,MACF,KAAK;AACH,cAAM,IAAI,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK;AACnC;AAAA,MACF,KAAK;AACH,cAAM,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC;AACzB;AAAA,MACF,KAAK;AACH,cAAM,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU;AACtC,gBAAM,IAAI,MAAM,KAAK,IAAI,GACvB,IAAI,MAAM,KAAK,KAAK;AACtB,mBAAS,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK;AACrD,kBAAM,QAAQ,EAAE,CAAC,EAAG,YAAY,CAAC,IAAK,EAAE,CAAC,EAAG,YAAY,CAAC;AACzD,gBAAI,MAAO,QAAO;AAAA,UACpB;AACA,iBAAO,EAAE,SAAS,EAAE;AAAA,QACtB,CAAC;AACD;AAAA,MACF,KAAK;AACH,cAAM,KAAK,CAAC,EAAE,eAAe;AAC7B;AAAA,MACF,KAAK;AACH,cAAM,KAAK,CAAC,EAAE,YAAY,IAAI;AAC9B;AAAA,MACF,KAAK;AACH,cAAM,KAAK,CAAC,EAAE,WAAW;AACzB;AAAA,MACF,KAAK;AACH,cAAM,KAAK,CAAC,EAAE,YAAY;AAC1B;AAAA,MACF,KAAK;AACH,eAAQ,KAAK,CAAC,EAAE,UAAU,IAAI,KAAK,IAAK;AACxC;AAAA,MACF,KAAK,cAAc;AACjB,cAAM,IAAI,KAAK,CAAC,GACd,OAAO,IAAI,CAAC,EAAE,YAAY;AAC5B,YACE,CAAC;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,SAAS,IAAI;AAEf,eAAK,wBAAwB;AAC/B,UAAE,mBAAmB,CAAC;AACtB,YAAI,SAAS,SAAU,GAAE,cAAc,CAAC;AACxC,YAAI,CAAC,CAAC,UAAU,QAAQ,EAAE,SAAS,IAAI,EAAG,GAAE,cAAc,CAAC;AAC3D,YAAI,CAAC,QAAQ,SAAS,QAAQ,KAAK,EAAE,SAAS,IAAI,EAAG,GAAE,YAAY,CAAC;AACpE,YAAI,SAAS;AACX,YAAE,WAAW,EAAE,WAAW,KAAM,EAAE,UAAU,IAAI,KAAK,CAAE;AACzD,YAAI,SAAS,UAAU,SAAS,QAAS,GAAE,WAAW,CAAC;AACvD,YAAI,SAAS,OAAQ,GAAE,YAAY,CAAC;AACpC,cAAM,EAAE,YAAY;AACpB;AAAA,MACF;AAAA,MACA,KAAK,YAAY;AACf,cAAM,IAAI,KAAK,CAAC,GACd,OAAO,IAAI,CAAC,EAAE,YAAY,GAC1B,SAAS,QAAQ,GAAG,MAAS,GAAM;AACrC,YAAI,SAAS,UAAU,SAAS,SAAS;AACvC,gBAAM,MAAM,EAAE,WAAW;AACzB,YAAE,WAAW,CAAC;AACd,YAAE,YAAY,EAAE,YAAY,IAAI,UAAU,SAAS,SAAS,KAAK,EAAE;AACnE,gBAAM,OAAO,IAAI,KAAK,EAAE,QAAQ,CAAC;AACjC,eAAK,YAAY,KAAK,YAAY,IAAI,GAAG,CAAC;AAC1C,YAAE,WAAW,KAAK,IAAI,KAAK,KAAK,WAAW,CAAC,CAAC;AAAA,QAC/C,OAAO;AACL,gBAAM,QAAgC;AAAA,YACpC,MAAM;AAAA,YACN,KAAK;AAAA,YACL,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,aAAa;AAAA,UACf;AACA,gBAAM,KAAK,MAAM,IAAI;AACrB,cAAI,CAAC,GAAI,MAAK,wBAAwB;AACtC,YAAE,QAAQ,EAAE,QAAQ,IAAI,SAAS,EAAG;AAAA,QACtC;AACA,cAAM,EAAE,YAAY;AACpB;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAChB,cAAM,QAAgC;AAAA,UACpC,MAAM;AAAA,UACN,KAAK;AAAA,UACL,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,aAAa;AAAA,QACf;AACA,cAAM,KAAK,MAAM,IAAI,CAAC,EAAE,YAAY,CAAC;AACrC,YAAI,CAAC,GAAI,MAAK,gCAAgC;AAC9C,cAAM,KAAK,OAAO,KAAK,CAAC,EAAE,QAAQ,IAAI,KAAK,CAAC,EAAE,QAAQ,KAAK,EAAG;AAC9D;AAAA,MACF;AAAA,MACA,KAAK,eAAe;AAClB,cAAM,IAAI,KAAK,CAAC,GACd,MAAM,CAACA,OAAc,OAAOA,EAAC,EAAE,SAAS,GAAG,GAAG,GAC9CC,SAAgC;AAAA,UAC9B,MAAM,OAAO,EAAE,eAAe,CAAC,EAAE,SAAS,GAAG,GAAG;AAAA,UAChD,IAAI,IAAI,EAAE,YAAY,IAAI,CAAC;AAAA,UAC3B,IAAI,IAAI,EAAE,WAAW,CAAC;AAAA,UACtB,IAAI,IAAI,EAAE,YAAY,CAAC;AAAA,UACvB,IAAI,IAAI,EAAE,cAAc,CAAC;AAAA,UACzB,IAAI,IAAI,EAAE,cAAc,CAAC;AAAA,QAC3B;AACF,cAAM,IAAI,CAAC,EAAE,QAAQ,wBAAwB,CAAC,MAAMA,OAAM,CAAC,CAAE;AAC7D;AAAA,MACF;AAAA,MACA;AACE,eAAO,KAAK,sBAAsB,IAAI,EAAE;AAAA,IAC5C;AACA,WAAO,MAAM,GAAG;AAAA,EAClB;AACA,MAAI;AACF,UAAM,QAAQ,IAAI,GAAG;AACrB,WAAO,aAAa,EAAE,OAAO,OAAO,WAAW,IAAI,EAAE,MAAM;AAAA,EAC7D,SAAS,GAAG;AACV,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO,aAAa,QAAQ,EAAE,UAAU;AAAA,IAC1C;AAAA,EACF;AACF;;;AC1yCO,SAAS,cAAc,OAA+B;AAC3D,QAAM,OACJ,iBAAiB,OAAO,MAAM,QAAQ,IACpC,OAAO,UAAU,WAAW,QAC5B,OAAO,UAAU,YAAY,UAAU,KAAK,KAAK,MAAM,KAAK,IAC5D;AACJ,SAAO,OAAO,SAAS,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,YAAY,IAAI;AAChE;AAIO,SAAS,UAAU,OAA6B,OAAoC;AACzF,MAAI,CAAC,SAAS,MAAM,SAAS,eAAe,CAAC,aAAa,KAAK,EAAG,QAAO;AACzE,MAAI,SAAS,KAAM,QAAO,EAAE,OAAO,MAAM,MAAM,IAAI,WAAW,OAAO,GAAG;AACxE,MAAI,MAAM,SAAS,YAAY;AAC7B,UAAM,MAAM,cAAc,KAAK;AAC/B,WAAO,QAAQ,OAAO,OAAO,EAAE,OAAO,MAAM,MAAM,IAAI,KAAK,OAAO,IAAI;AAAA,EACxE;AACA,MAAI,OAAO,UAAU,WAAW,CAAC,OAAO,SAAS,KAAK,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU;AACtG,WAAO;AACT,SAAO,EAAE,OAAO,MAAM,MAAM,IAAI,KAAK,OAAO,OAAO,KAAK,EAAE;AAC5D;AAKO,SAAS,cAAc,MAAyB,OAAgC,QAA2C;AAChI,QAAM,QAAuB,CAAC;AAC9B,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,UAAU,aAAa,QAAQ,GAAG,GAAG,MAAM,GAAG,CAAC;AAC5D,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,SAAO;AACT;;;AC6DO,IAAM,oBAAoB;AAC1B,SAAS,iBAAiB,OAAyC;AACxE,SAAO,SAAS,QAAQ,OAAO,UAAU,YAAa,MAAyB,SAAS;AAC1F;AACO,SAAS,iBAAiB,OAAsD;AACrF,SAAO,OAAO,WAAW;AAC3B;AAuBO,IAAM,iBAAiB;AACvB,IAAM,2BAA2B;AACjC,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,SAAS,gBAAgB,OAA+B;AAC7D,QAAM,EAAE,UAAU,WAAW,GAAG,OAAO,IAAI;AAC3C,SAAO;AACT;AAKO,SAAS,aAAa,OAA+B;AAC1D,SAAO,MAAM,WAAW,MAAM,SAAS,SAAS;AAClD;AAMO,SAAS,iBAAiB,OAAmB,MAA4B;AAC9E,QAAM,SAAS,MAAM;AACrB,MAAI,CAAC,KAAK,OAAQ,QAAO,aAAa,KAAK;AAC3C,MAAI,CAAC;AACH,WAAO;AAAA,MACL,QAAQ,KAAK,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAAA,MACvC,OAAO,CAAC;AAAA,MACR,SAAS,CAAC;AAAA,MACV,OAAO,MAAM;AAAA,MACb,QAAQ;AAAA,MACR,UAAU,EAAE,MAAM,WAAW,CAAC,GAAG,gBAAgB,MAAM,QAAQ,MAAM;AAAA,IACvE;AACF,QAAM,UAAU,IAAI,IAAI,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,KAAK,SAAS,GAAG,CAAC,CAAC;AAGxE,QAAM,UAAU,MAAM,OAAO,SACzB,MAAM,SACN,OAAO,KAAK,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAC1C,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,EAAE,GAAG,QAAQ,KAAK;AAAA,IAC5B,QAAQ;AAAA,IACR,cAAc,CAAC;AAAA,IACf,QAAQ;AAAA,MACN,GAAG,KACA,OAAO,CAAC,QAAQ,CAAC,OAAO,KAAK,SAAS,GAAG,CAAC,EAC1C,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAAA,MAC7B,GAAG,QAAQ,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,IAChD;AAAA,IACA,OAAO,MAAM,MAAM;AAAA,MACjB,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,KAAK,CAAC,MAAM,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,IAChE;AAAA,IACA,SAAS,MAAM,QAAQ,OAAO,CAAC,SAAS,CAAC,QAAQ,IAAI,KAAK,KAAK,CAAC;AAAA,EAClE;AACF;AACO,IAAM,WAAsC;AAAA,EACjD,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AACR;AAGO,SAAS,oBACd,aACA;AACA,QAAM,cAAc,CAAC,SACnB,YAAY,OAAO,KAAK,CAACC,OAAMA,GAAE,SAAS,IAAI;AAChD,QAAM,kBAAkB,YAAY,OAAO;AAAA,IACzC,CAAC,UAAU,YAAY,KAAK,KAAK,aAAa,KAAK;AAAA,EACrD;AACA,QAAM,gBAAgB,YAAY,OAAO;AAAA,IACvC,CAACA,OAAMA,GAAE,SAAS,eAAe,aAAaA,EAAC;AAAA,EACjD;AACA,QAAM,uBAAuB,YAAY,OAAO;AAAA,IAC9C,CAAC,UAAU,WAAW,KAAK,KAAK,MAAM,SAAS;AAAA,EACjD;AAEA,WAAS,oBAAoB,MAAiC;AAC5D,WAAO,KAAK,QACT;AAAA,MACC,CAAC,SACC,GAAG,YAAY,KAAK,KAAK,GAAG,SAAS,KAAK,KAAK,IAAI,KAAK,QAAQ,QAAQ,WAAM,QAAG,GAAG,KAAK,UAAU,UAAU,mBAAmB,EAAE;AAAA,IACtI,EACC,KAAK,IAAI;AAAA,EACd;AAEA,WAAS,WAAW,OAA6B;AAC/C,QAAI,CAAC,MAAO,QAAO,CAAC,OAAO;AAC3B,UAAMA,KAAI,YAAY,KAAK;AAC3B,WAAOA,MAAK,aAAaA,EAAC,IACtB,CAAC,GAAI,aAAaA,EAAC,IAAI,eAAeA,EAAC,IAAI,CAAC,GAAI,KAAK,IACrD,CAAC;AAAA,EACP;AACA,WAAS,kBAAkB,QAA+B;AACxD,QAAI,OAAO,OAAO,UAAW,QAAO,OAAO,cAAc;AACzD,QAAI,OAAO,OAAO,OAAQ,QAAO;AACjC,UAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM;AACxE,WAAO,GAAG,OAAO,OAAO,QAAQ,UAAU,OAAO,GAAG,YAAY,CAAC,IAAI,KAAK;AAAA,EAC5E;AACA,WAAS,eAAe,QAAsC;AAC5D,QAAI,OAAO,OAAO,UAAW,QAAO;AACpC,QAAI;AACF,YAAM,OAAO,cAAc,kBAAkB,MAAM,GAAG,WAAW;AACjE,UAAI,KAAK,aAAa,KAAK,CAAC,SAAS,CAAC,aAAa,YAAY,IAAI,CAAE,CAAC;AACpE,cAAM,IAAI,MAAM,sCAAsC;AACxD,UAAI,SAAS,IAAI;AACf,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,aAAO;AAAA,IACT,SAAS,OAAO;AACd,aAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IAC9D;AAAA,EACF;AACA,WAAS,aAAa,QAA+B;AACnD,QAAI,OAAO,OAAO;AAChB,aAAO,OAAO,OAAO,KAAK,KAAK;AACjC,QAAI,OAAO,OAAO;AAChB,aAAO,OAAO,OAAO,KAAK,KAAM,OAAO,OAAO,MAAM,UAAU,YAAY,OAAO,KAAK,MAAM,KAAK,KAAM;AACzG,QAAI,CAAC,OAAO,MAAO,QAAO;AAC1B,UAAM,QAAQ,YAAY,OAAO,KAAK,GAAG,SAAS,OAAO;AACzD,UAAM,SAAoC;AAAA,MACxC,OAAO;AAAA,MACP,gBAAgB;AAAA,MAChB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AACA,WAAO,GAAG,OAAO,OAAO,EAAE,CAAC,IAAI,KAAK;AAAA,EACtC;AAGA,WAAS,eAAe,QAAuB,MAA0B;AACvE,UAAM,OAAO,OAAO;AACpB,QAAI,CAAC,KAAM,QAAO,CAAC;AACnB,UAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAI,OAAO,KAAK,UAAU,SAAU,OAAM,IAAI,KAAK,MAAM,MAAM;AAC/D,QAAI,KAAK,GAAG,SAAS;AACnB,iBAAW,QAAQ,eAAe,KAAK,GAAG,QAAQ,EAAG,OAAM,IAAI,IAAI;AAAA,aAC5D,KAAK,GAAG,eAAe;AAC9B,iBAAW,OAAO,KAAM,OAAM,IAAI,GAAG;AACvC,WAAO,CAAC,GAAG,KAAK;AAAA,EAClB;AAKA,WAAS,YACP,QACA,MACA,WACe;AACf,UAAM,OAAO,OAAO;AACpB,QAAI,OAAO,OAAO,OAAQ,QAAO;AACjC,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,WAAW,CAAC,SAChB,KAAK,SAAS,IAAI,KAClB,UAAU,KAAK,CAAC,UAAU,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM;AACpE,QAAI,OAAO,KAAK,UAAU,YAAY,CAAC,SAAS,KAAK,MAAM,MAAM;AAC/D,aAAO,8BAA8B,KAAK,MAAM,MAAM;AACxD,QAAI,KAAK,GAAG,SAAS,YAAY;AAC/B,UAAI,CAAC,KAAK,GAAG,SAAS,KAAK,EAAG,QAAO;AACrC,aAAO,mBAAmB,KAAK,GAAG,UAAU,CAAC,GAAG,QAAQ;AAAA,IAC1D;AACA,QAAI,KAAK,GAAG,eAAe;AACzB,iBAAW,OAAO,MAAM;AACtB,cAAM,QAAQ,YAAY,GAAG;AAC7B,YAAI,OAAO,SAAS;AAClB,iBAAO,8CAA8C,MAAM,KAAK;AAClE,YAAI,CAAC,SAAS,CAAC,aAAa,KAAK;AAC/B,iBAAO,oCAAoC,OAAO,SAAS,GAAG;AAAA,MAClE;AACF,WAAO;AAAA,EACT;AAGA,WAAS,gBAAgB,YAAsE;AAC7F,WAAO,WAAW,UAAU,QAAQ,CAAC,WAAW;AAC9C,YAAM,UAAU,YAAY,QAAQ,WAAW,MAAM,WAAW,SAAS;AACzE,aAAO,UAAU,CAAC,GAAG,aAAa,MAAM,CAAC,KAAK,OAAO,EAAE,IAAI,CAAC;AAAA,IAC9D,CAAC;AAAA,EACH;AAEA,WAAS,UACP,QACA,SACA,MACA,QACA,KACgB;AAChB,UAAM,OAAO,OAAO;AACpB,UAAM,OAAO,CAAC,SAA0B;AACtC,YAAM,QAAQ,OAAO,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,IAAI;AACvD,YAAMC,SAAQ,QAAQ,eAAe,OAAO,GAAG,IAAI;AACnD,UAAIA,UAAS,QAAQ,oBAAoBA,MAAK,EAAG,QAAO;AACxD,UAAI,OAAO,SAAS,cAAcA,kBAAiB;AACjD,eAAO,cAAcA,MAAK,KAAKA;AACjC,aAAO,MAAM,QAAQA,MAAK,IAAIA,OAAM,KAAK,IAAI,IAAIA;AAAA,IACnD;AACA,UAAM,QAAQ,CAAC,OACX,aAAa,MAAM,IACnB,OAAO,KAAK,UAAU,WACpB,KAAK,QACL,OAAO,KAAK,KAAK,MAAM,MAAM,KAAK,EAAE;AAC1C,UAAM,QAAwB,EAAE,MAAM,cAAc,OAAO,IAAI,MAAM,MAAM,KAAK;AAChF,QAAI,WAAW,CAAC,KAAM,QAAO,EAAE,GAAG,OAAO,SAAS,WAAW,2BAA2B;AACxF,QAAI,KAAK,GAAG,SAAS,YAAY;AAC/B,YAAM,OAAO,gBAAgB,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC,CAAC;AAClF,aAAO,SAAS,OAAO,EAAE,GAAG,OAAO,SAAS,iCAAiC,IAAI,EAAE,GAAG,OAAO,KAAK;AAAA,IACpG;AACA,QAAI,KAAK,GAAG,eAAe,MAAO,QAAO;AACzC,UAAM,QAAQ,cAAc,MAAM,KAAK,WAAW;AAClD,WAAO,QAAQ,EAAE,GAAG,OAAO,MAAM,IAAI,EAAE,GAAG,OAAO,SAAS,wCAAwC;AAAA,EACpG;AAEA,WAAS,aACP,MACA,WACkB;AAClB,UAAM,SAA0B;AAAA,MAC9B;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,UAAU;AAAA,QAC1B,QAAQ,EAAE,SAAS,MAAM;AAAA,QACzB,QAAQ,EAAE,SAAS,MAAM;AAAA,QACzB,MAAM,EAAE,SAAS,MAAM;AAAA,QACvB,WAAW,EAAE,SAAS,OAAO,WAAW,MAAM;AAAA,MAChD;AAAA,MACA,GAAG,KAAK,QAAQ,CAAC,QAAyB;AACxC,cAAM,QAAQ,YAAY,GAAG;AAG7B,YAAI,CAAC,MAAO,QAAO,CAAC;AACpB,eAAO,CAAC;AAAA,UACN,MAAM;AAAA,UACN,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,QAAQ,EAAE,MAAM,UAAU;AAAA,UAC1B,GAAI,MAAM,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,UACtD,GAAI,MAAM,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,UACtD,GAAI,MAAM,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,UAAU,EAAE,IAAI,CAAC;AAAA,UAC/D,GAAI,MAAM,MAAM,YAAY,SACxB,EAAE,MAAM,EAAE,SAAS,MAAM,KAAK,QAAQ,EAAE,IACxC,CAAC;AAAA,UACL,GAAI,OAAO,MAAM,WAAW,WAAW,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,UACnE,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,UAClD,OAAO;AAAA,QACT,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AACA,QAAI;AACJ,eAAW,UAAU,WAAW;AAC9B,UAAI,OAAO,OAAO,QAAQ;AACxB,cAAM,UAAU,YAAY,QAAQ,MAAM,SAAS;AAEnD,eAAO,KAAK;AAAA,UACV,MAAM,OAAO;AAAA,UACb,OAAO,aAAa,MAAM;AAAA,UAC1B,MAAM;AAAA,UACN,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,cAAc,eAAe,QAAQ,IAAI;AAAA,YACzC,UAAU,CAAC,QAAQ,UAAU,QAAQ,SAAS,MAAM,QAAQ,GAAG;AAAA,UACjE;AAAA,UACA,QAAQ,EAAE,OAAO,OAAO;AAAA,UACxB,QAAQ,EAAE,SAAS,MAAM;AAAA,UACzB,MAAM,EAAE,SAAS,MAAM;AAAA,UACvB,WAAW,EAAE,SAAS,OAAO,WAAW,MAAM;AAAA,UAC9C,QAAQ;AAAA,UACR,OAAO;AAAA,QACT,CAAC;AACD;AAAA,MACF;AACA,UAAI,OAAO,OAAO,WAAW;AAC3B,YAAI,OAA8B;AAClC,YAAI;AACF,gBAAM,WAAW;AAAA,YACf,kBAAkB,MAAM;AAAA,YACxB;AAAA,UACF;AACA,iBAAO,SAAS,SAAS,SAAS,WAAW,SAAS;AAAA,QACxD,QAAQ;AAAA,QAER;AACA,eAAO,KAAK;AAAA,UACV,MAAM,OAAO;AAAA,UACb,OAAO,aAAa,MAAM;AAAA,UAC1B;AAAA,UACA,QAAQ,EAAE,MAAM,UAAU;AAAA,UAC1B,OAAO;AAAA,UACP,QAAQ,EAAE,OAAO,SAAS,WAAW,UAAU,OAAO;AAAA,UACtD,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,QACtD,CAAC;AACD;AAAA,MACF;AACA,YAAM,QAAQ,OAAO,QAAQ,YAAY,OAAO,KAAK,IAAI;AACzD,YAAM,WAAW,OAAO,OAAO,WAAW,OAAO,OAAO;AACxD,YAAM,UAAU,YAAY,OAAO,OAAO,SAAS,OAAO,OAAO;AACjE,YAAM,UAAU,OAAO,OAAO;AAC9B,aAAO,KAAK;AAAA,QACV,MAAM,OAAO;AAAA,QACb,OAAO,aAAa,MAAM;AAAA,QAC1B,MAAM,UAAU,WAAY,OAAO,QAAQ;AAAA,QAC3C,QAAQ,EAAE,MAAM,UAAU;AAAA,QAC1B,QAAQ;AAAA,UACN,OAAO,WAAW,OAAO,SAAS,WAAW,UAAU;AAAA,QACzD;AAAA,QACA,OAAO,UAAU,uBAAuB;AAAA,QACxC,GAAI,CAAC,WAAW,OAAO,WAAW,cAAc,SAC5C,EAAE,WAAW,EAAE,WAAW,MAAM,UAAU,UAAU,EAAE,IACtD,CAAC;AAAA;AAAA,QAEL,GAAI,OAAO,UACP,EAAE,SAAS,OAAO,QAAQ,IAC1B;AAAA,UACE,GAAI,OAAO,OAAO,WAAW,YAAY,CAAC,WACtC,EAAE,QAAQ,MAAM,OAAO,IACvB,CAAC;AAAA,UACL,GAAI,OAAO,WAAW,CAAC,WAAW,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClE;AAAA,MACN,CAAC;AAAA,IACH;AACA,aAAS;AAAA,MACP,MAAM,GAAG,YAAY,IAAI;AAAA,MACzB,SAAS;AAAA,MACT;AAAA,MACA,eAAe,KAAK,OAAO,SAAO,YAAY,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE;AAAA,MAC9E,cAAc;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAIA,WAAS,SAAS,OAA8B;AAC9C,QAAI,SAAS,KAAM,QAAO;AAC1B,QAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,QACE,OAAO,UAAU,YACjB,OAAO,UAAU,aAChB,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAEnD,aAAO;AACT,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,WAAS,QACP,KACA,MACA,QACQ;AACR,UAAM,QAAQ,CAAC,GAAG,IAAI,EACnB,KAAK,EACL,IAAI,CAAC,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,QACE,eAAe,OAAO,OAAO,KAAK,CAACD,OAAMA,GAAE,SAAS,GAAG,GAAI,GAAG;AAAA,MAChE;AAAA,IACF,CAAC;AAEH,QACE,MAAM;AAAA,MACJ,CAAC,CAAC,KAAK,KAAK,MAAM,OAAO,GAAG,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS;AAAA,IAChE;AAEA,YAAM,IAAI,MAAM,sCAAsC;AACxD,UAAM,KAAK,KAAK,UAAU,KAAK;AAC/B,QAAI,GAAG,SAAS;AACd,YAAM,IAAI,MAAM,sCAAsC;AACxD,WAAO;AAAA,EACT;AACA,WAASE,SAAQ,GAAY,GAAoB;AAC/C,QAAI,MAAM,EAAG,QAAO;AACpB,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,KAAK,KAAM,QAAO;AACtB,WAAO,IAAI,IAAI,KAAK;AAAA,EACtB;AACA,WAAS,eACP,MACA,MACA,QACU;AACV,UAAM,gBAAgB,OAAO,OAAO;AAAA,MAClC,CAAC,UAAU,MAAM,SAAS,OAAO;AAAA,IACnC;AACA,UAAM,aAAa,oBAAI,IAAqB;AAC5C,eAAW,OAAO,MAAM;AACtB,YAAM,KAAK,gBACP,eAAe,eAAe,GAAG,IAChC,IAAgC,OAAO,OAAO;AACnD,UACE,EACE,OAAO,OAAO,YACb,OAAO,OAAO,YAAY,OAAO,SAAS,EAAE,MAE/C,WAAW,IAAI,EAAE;AAEjB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,iBAAW,IAAI,EAAE;AAAA,IACnB;AAGA,UAAM,QAAQ,KAAK,QAAQ,KAAK,CAAC,SAAS,KAAK,UAAU,OAAO,OAAO,IACnE,KAAK,UACL;AAAA,MACE,GAAG,KAAK;AAAA,MACR,EAAE,OAAO,OAAO,SAAS,KAAK,QAAQ,OAAO,OAAO;AAAA,IACtD;AACJ,UAAM,QAAQ,MAAM,IAAI,CAAC,UAAU;AAAA,MACjC,GAAG;AAAA,MACH,KAAK,OAAO,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK,KAAK;AAAA,IAC9D,EAAE;AACF,WAAO,KAAK,OAAO,CAAC,MAAM,QAAQ;AAChC,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,CAACC,YAAqB;AAClC,gBAAM,MAAM,KAAK,MACb,eAAe,KAAK,KAAKA,OAAM,IAC9BA,QAAmC,OAAO,OAAO;AACtD,cAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,WAAY,QAAO;AACzD,gBAAM,UAAU,KAAK,MAAM,OAAO,GAAG,CAAC;AACtC,iBAAO,OAAO,SAAS,OAAO,IAAI,UAAU;AAAA,QAC9C;AACA,cAAM,IAAI,MAAM,GAAG,GACjB,IAAI,MAAM,IAAI;AAChB,YAAI,KAAK,QAAQ,KAAK,MAAM;AAC1B,cAAI,KAAK,QAAQ,KAAK,KAAM;AAC5B,iBAAQ,KAAK,UAAW,KAAK,UAAU,WAAW,MAAM;AAAA,QAC1D;AACA,cAAM,OAAOD,SAAQ,GAAG,CAAC;AACzB,YAAI,SAAS;AACX,kBAAQ,KAAK,QAAQ,QAAQ,OAAO,IAAI,OAAO,KAAK,MAAM;AAAA,MAC9D;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,WAAS,UACP,MACA,QACA,MACA,WACA,OAAiC,MAC1B;AACP,QAAI,CAAC,QAAQ,UAAU,KAAK,CAAC,WAAW,OAAO,OAAO,KAAK;AACzD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,QAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAC/B,QAAI,KAAK,SAAS,uBAAuB,UAAU,SAAS;AAC1D,YAAM,IAAI,MAAM,4CAA4C;AAC9D,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI,MAAM,+BAA+B;AACjD,QAAI,QAAQ,KAAK,SAAS;AAC1B,QAAI,aAAa;AACjB,UAAM,SAAS,oBAAI,IAAwB;AAC3C,eAAW,OAAO,MAAM;AACtB,YAAM,KAAK,QAAQ,KAAK,MAAM,MAAM;AACpC,YAAM,SAAS,OAAO,IAAI,EAAE;AAC5B,UAAI,OAAQ,QAAO,KAAK,GAAG;AAAA,WACtB;AACH,YAAI,OAAO,QAAQ;AACjB,gBAAM,IAAI;AAAA,YACR,oBAAoB,kBAAkB,eAAe,CAAC;AAAA,UACxD;AACF,iBAAS,GAAG,SAAS,IAAI;AACzB,YAAI,QAAQ;AACV,gBAAM,IAAI,MAAM,2CAA2C;AAC7D,eAAO,IAAI,IAAI,CAAC,GAAG,CAAC;AAAA,MACtB;AAAA,IACF;AACA,UAAM,WAAW,IAAI;AAAA,MACnB,UACG,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,EAAE,OAAO,MAAM,EAC/C,IAAI,CAAC,WAAW;AACf,YAAI;AACF,gBAAM,UAAU,eAAe,MAAM;AACrC,cAAI,QAAS,OAAM,IAAI,MAAM,OAAO;AACpC,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,EAAE,MAAM,cAAc,kBAAkB,MAAM,GAAG,MAAM,EAAE;AAAA,UAC3D;AAAA,QACF,SAAS,OAAO;AACd,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AAAA,UAClE;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACL;AACA,UAAM,WAAW,CAAC,SAChB,KACC,KAAK,SAAS,SACX,KAAK,KAAK,OAAO,CAAC,MAAM,UAAU,OAAO,SAAS,KAAK,GAAG,CAAC,IAC3D;AACN,UAAM,QAAQ,IAAI;AAAA,MAChB,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,QAAQ,MAAM;AAAA,QACpC;AAAA,QACA,SAAS,MAAM,WAAW,IAAI,QAAQ,KAAK,CAAC;AAAA,MAC9C,CAAC;AAAA,IACH;AACA,WAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,OAAO,MAAM;AACxC,YAAM,SAAc,OAAO,OAAO,uBAAO,OAAO,IAAI,GAAG;AAAA,QACrD,CAAC,cAAc,GAAG;AAAA,MACpB,CAAC;AACD,iBAAW,OAAO;AAChB,eAAO,GAAG,IAAI;AAAA,UACZ,OAAO,OAAO,KAAK,CAACF,OAAMA,GAAE,SAAS,GAAG;AAAA,UACxC,QAAQ,CAAC;AAAA,QACX;AACF,YAAM,SACJ,QAAQ,UAAU,KAAK,CAAC,WAAW,OAAO,OAAO,KAAK,IAClD,eAAe,SAAS,MAAM,MAAM,IACpC;AACN,iBAAW,UAAU,WAAW;AAC9B,YAAI,OAAO,OAAO,OAAQ;AAC1B,YAAI,OAAO,OAAO,OAAO;AACvB,gBAAM,WAAW,SAAS,IAAI,OAAO,EAAE;AACvC,cAAI,CAAC,SAAS,MAAM;AAClB,mBAAO,OAAO,EAAE,IAAI,EAAE,eAAe,SAAS,MAAM;AACpD;AAAA,UACF;AACA,gBAAM,OAAO,SAAS;AACtB,gBAAM,WAAW,qBAAqB,IAAI;AAC1C,gBAAM,aAAa,KAAK,WAAW;AAAA,YAAI,CAAC,MAAM,MAC5C;AAAA,cACE;AAAA,cACA,QAAQ,IAAI,CAAC,QAAQ;AACnB,qBAAK,cAAc,MAAM,IAAI,OAAO,EAAE,IAAI,CAAC,KAAK,KAAK;AACnD,wBAAM,IAAI,MAAM,qCAAqC;AACvD,sBAAM,UAAU,SAAS,CAAC;AAC1B,oBAAI,CAAC,QAAS,QAAO,EAAE,OAAO,EAAE;AAChC,sBAAM,SAAS,OAAO;AAAA,kBACpB,QAAQ,aAAa,IAAI,CAAC,SAAS;AACjC,0BAAM,QAAQ;AAAA,sBACZ,OAAO,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,IAAI;AAAA,sBACzC;AAAA,oBACF;AACA,2BAAO;AAAA,sBACL;AAAA,sBACC,iBAAiB,OACd,MAAM,YAAY,IACjB,SAAS;AAAA,oBAChB;AAAA,kBACF,CAAC;AAAA,gBACH;AACA,uBAAO,eAAe,QAAQ,KAAK,MAAM;AAAA,cAC3C,CAAC;AAAA,YACH;AAAA,UACF;AACA,gBAAM,SAAS,yBAAyB,MAAM,UAAU;AACxD,iBAAO,OAAO,EAAE,IAAI,OAAO,QACvB,EAAE,eAAe,OAAO,MAAM,IAC9B,OAAO;AACX;AAAA,QACF;AACA,cAAM,QAAQ,OAAO,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,OAAO,KAAK;AAC/D,YAAI,OAAO,OAAO,OAAO;AACvB,iBAAO,OAAO,EAAE,IACd,SAAS,SAAS,eAAe,OAAO,MAAM,IAAI;AACpD;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,WAAS,cACP,MACA,OACA,QACAI,WAAkC,CAAC,GACvB;AAEZ,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,GAAG,gBAAgB,KAAK;AAAA,QACxB,cAAc,CAAC;AAAA,QACf,SAAS,CAAC;AAAA,QACV,QAAQ;AAAA,QACR,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM;AAAA,MAChC;AAAA,MACA,EAAE,GAAG,QAAQ,aAAa,CAAC,EAAE;AAAA,MAC7BA;AAAA,IACF;AAAA,EACF;AAIA,WAAS,wBACP,OACA,WACA,QACA,QACY;AACZ,UAAM,WAAW,IAAI;AAAA,MACnB,UAAU,OAAO,CAAC,MAAM,EAAE,OAAO,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,IACzD;AACA,QAAI,CAAC,SAAS,KAAM,QAAO;AAE3B,QAAI,OAAO;AACX,WAAO,MAAM;AACX,aAAO;AACP,iBAAWJ,MAAK,OAAO,QAAQ;AAC7B,YACE,CAAC,SAAS,IAAIA,GAAE,IAAI,KACpBA,GAAE,OAAO,SAAS,aAClBA,GAAE,OAAO,cAAc,KAAK,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC,GACxD;AACA,mBAAS,IAAIA,GAAE,IAAI;AACnB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,QAAQ,SACJ,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC,IACjD,MAAM;AAAA,MACV,OAAO,MAAM,MAAM;AAAA,QACjB,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,KAAK,CAAC,MAAM,SAAS,IAAI,EAAE,KAAK,CAAC;AAAA,MACjE;AAAA,MACA,SAAS,MAAM,QAAQ,OAAO,CAAC,SAAS,CAAC,SAAS,IAAI,KAAK,KAAK,CAAC;AAAA,MACjE,eAAe,MAAM,gBAAgB,CAAC,GAAG,OAAO,CAAC,WAAW;AAC1D,YAAI,OAAO,QAAQ,KAAK,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC,EAAG,QAAO;AAC9D,YAAI;AACF,iBAAO,CAAC,YAAY,QAAQ,MAAM,EAAE;AAAA,YAAK,CAAC,SACxC,KAAK,aAAa,KAAK,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC;AAAA,UACrD;AAAA,QACF,QAAQ;AAEN,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,SAAS,YAAsC;AACtD,QAAI,WAAW,aAAa;AAC1B,YAAM,IAAI,MAAM,WAAW,YAAY,KAAK,GAAG,CAAC;AAClD,QACE,CAAC,WAAW,KAAK,UACjB,WAAW,KAAK,SAAS,uBACzB,IAAI,IAAI,WAAW,IAAI,EAAE,SAAS,WAAW,KAAK,UAClD,WAAW,KAAK;AAAA,MACd,CAAC,QACC,QAAQ,kBACR,CAAC,gBAAgB,KAAK,CAACA,OAAMA,GAAE,SAAS,GAAG;AAAA,IAC/C;AAEA,YAAM,IAAI,MAAM,iDAAiD;AACnE,QAAI,WAAW,UAAU,SAAS;AAChC,YAAM,IAAI,MAAM,6BAA6B;AAC/C,UAAM,MAAM,oBAAI,IAAI;AAAA,MAClB;AAAA,MACA,GAAG,YAAY,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,IACjD,CAAC;AACD,UAAM,cAAc,IAAI,IAAI,YAAY,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AACzE,eAAW,UAAU,WAAW,WAAW;AACzC,UAAI,YAAY,IAAI,OAAO,EAAE;AAC3B,cAAM,IAAI;AAAA,UACR,wBAAwB,OAAO,EAAE,qEAAqE,OAAO,OAAO,aAAa,OAAO,OAAO,QAAQ,YAAY,OAAO,EAAE,IAAI,OAAO,EAAE;AAAA,QAC3L;AACF,UAAI,IAAI,IAAI,OAAO,EAAE,KAAK,OAAO,OAAO;AACtC,cAAM,IAAI;AAAA,UACR,wBAAwB,OAAO,EAAE;AAAA,QACnC;AACF,UACE,CAAC,OAAO,MACR,OAAO,GAAG,SAAS,OACnB,IAAI,IAAI,OAAO,EAAE,KACjB,gBAAgB,OAAO,EAAE,KACzB,CAAC,aAAa,eAAe,WAAW,EAAE,SAAS,OAAO,EAAE;AAE5D,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,UAAI,IAAI,OAAO,EAAE;AAEjB,UAAI,OAAO,OAAO,OAAQ;AAC1B,UAAI,OAAO,OAAO,WAAW;AAC3B,cAAM,QAAQ,eAAe,MAAM;AACnC,YAAI,MAAO,OAAM,IAAI,MAAM,KAAK;AAAA,MAClC,WACE,CAAC,WAAW,OAAO,KAAK,EAAE,SAAS,OAAO,EAAE,KAC3C,OAAO,OAAO,UAAU,CAAC,OAAO,SAAS,CAAC,WAAW;AAEtD,cAAM,IAAI,MAAM,6CAA6C;AAAA,IACjE;AACA,UAAM,OAAO,WAAW;AACxB,QACE,SACC,CAAC,KAAK,QAAQ,UACb,KAAK,QAAQ,SAAS,4BACtB,IAAI,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,SACxC,KAAK,QAAQ,UACf,KAAK,QAAQ;AAAA,MACX,CAAC,MACC,CAAC,qBAAqB,KAAK,CAACA,OAAMA,GAAE,SAAS,EAAE,KAAK,KACpD,CAAC,CAAC,OAAO,MAAM,EAAE,SAAS,EAAE,GAAG,KAC/B,CAAC,CAAC,SAAS,MAAM,EAAE,SAAS,EAAE,KAAK;AAAA,IACvC;AAEF,YAAM,IAAI,MAAM,2CAA2C;AAAA,EAC/D;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,gBACd,MACA,QACA,UACAI,WAAkC,CAAC,GACnC;AACA,QAAM,QAAQ,oBAAoB,MAAM;AACxC,MAAI,SAAS,OAAO;AAClB,UAAM,IAAI,MAAM,uCAAuC;AACzD,QAAM,SAAS,QAAQ;AACvB,QAAM,SAAS,MAAM,cAAc,MAAM,SAAS,QAAQ,QAAQA,QAAO;AACzE,SAAO;AAAA,IACL;AAAA,IACA,MAAM,MAAM;AAAA,MACV;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,QAAQ,MAAM,aAAa,SAAS,MAAM,SAAS,SAAS;AAAA,EAC9D;AACF;;;ACj2BO,SAAS,gBACd,GACA,QACA,WACe;AACf,QAAM,aAAa,oBAAoB,CAAC,GACtC,SAAS,cAAc,YAAY,MAAM;AAC3C,QAAM,cAAkC,CAAC;AACzC,QAAM,oBAAoB,uBAAO,OAAO,IAAI;AAC5C,QAAM,eAAe,CACnB,MACA,cACY;AACZ,UAAM,MAAM,UAAU,OAAO,IAAI;AACjC,UAAM,WACJ,UAAU,kBAAkB,IAAI,KAChC,UAAU,kBAAkB,KAAK,MAAM,aAAa,MAAM,CAAC;AAC7D,QAAI,CAAC,MAAM,SAAS,KAAK,CAAC,UAAU;AAClC,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,SAAS,kBAAkB,IAAI,uBAAuB,SAAS;AAAA,QAC/D,MAAM;AAAA,QACN,IAAI;AAAA,MACN,CAAC;AACD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,iBAAiB,GAAG;AACtE,QACE,IAAI,SAAS,OACb,OAAO,UAAU,YACjB,CAAC,SACD,MAAM,SAAS;AAEf,YAAM,MAAM,qCAAqC;AACnD,sBAAkB,GAAG,IAAI;AAAA,EAC3B;AACA,QAAM,SAAS,CAAC,GAAG,OAAO,MAAM;AAChC,aAAW,KAAK,WAAW,OAAO,SAC9B,WAAW,SACX,eAAe,QAAQ,UAAU,EAAE,IAAI,CAACC,QAAO,EAAE,OAAOA,GAAE,KAAK,EAAE;AACnE,QACE,gBAAgB,EAAE,KAAK,KACvB,UAAU,OAAO,EAAE,KAAK,GAAG,UAC3B,aAAa,EAAE,OAAO,QAAQ;AAE9B,aAAO,KAAK,EAAE,KAAK;AAEvB,QAAM,UAAkC,CAAC;AACzC,aAAW,QAAQ,WAAW,QAAQ,SAClC,WAAW,UACV,OAAO,eAAe,CAAC,GAAI;AAC9B,QAAI,gBAAgB,KAAK,KAAK,GAAG;AAC/B,UAAI,aAAa,KAAK,OAAO,MAAM,GAAG;AACpC,YAAK,KAAK,QAAQ,SAAS,KAAK,QAAQ,UAAW,KAAK,SAAS;AAC/D,sBAAY,KAAK;AAAA,YACf,MAAM;AAAA,YACN,SAAS;AAAA,YACT,MAAM;AAAA,YACN,IAAI;AAAA,UACN,CAAC;AACD;AAAA,QACF;AACA,gBAAQ,KAAK;AAAA,UACX,OAAO,KAAK;AAAA,UACZ,KAAK,KAAK;AAAA,UACV,GAAI,KAAK,UAAU,WAAW,KAAK,UAAU,SACzC,EAAE,OAAO,KAAK,MAAM,IACpB,CAAC;AAAA,QACP,CAAC;AAAA,MACH;AAAA,IACF,OAAO;AACL,YAAM,YAAY;AAAA,QAChB,EAAE,GAAG,YAAY,SAAS,CAAC,IAAI,EAAE;AAAA,QACjC;AAAA,MACF,EAAE;AACF,UAAI,CAAC,UAAU;AACb,oBAAY,KAAK;AAAA,UACf,MAAM;AAAA,UACN,SAAS,4BAA4B,KAAK,KAAK;AAAA,UAC/C,MAAM;AAAA,UACN,IAAI;AAAA,QACN,CAAC;AACH,cAAQ,KAAK,GAAG,SAAS;AAAA,IAC3B;AAAA,EACF;AAGA,MACE,OAAO,MAAM,WAAW,WAAW,MAAM,UACzC,EAAE,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,aAAa,CAAC,EAAE,QAAQ,CAAC,MACpD,WAAW,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,aAAa,CAAC,EAAE,QAAQ,CAAC;AAEjE,gBAAY,KAAK;AAAA,MACf,MAAM;AAAA,MACN,SACE;AAAA,MACF,MAAM;AAAA,MACN,IAAI;AAAA,IACN,CAAC;AACH,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,CAAC,EAAE,KAAK;AAAA,IAClC;AAAA,IACA,SAAS;AAAA,IACT,SAAS,UAAU;AAAA,IACnB;AAAA,IACA,GAAI,UAAU,YAAY,EAAE,WAAW,UAAU,UAAU,IAAI,CAAC;AAAA,IAChE,GAAI,UAAU,aAAa,SACvB,EAAE,UAAU,UAAU,SAAS,IAC/B,CAAC;AAAA,IACL;AAAA,EACF;AACF;;;AC/IO,SAAS,mBAAmB,OAAqB;AACtD,MACE,CAAC,OAAO,SAAS,KAAK,KACrB,OAAO,UAAU,KAAK,KAAK,CAAC,OAAO,cAAc,KAAK,GACvD;AACA,UAAM,MAAM,kDAAkD;AAAA,EAChE;AACF;AAEO,SAAS,oBAAoB,QAAsC;AACxE,MAAI,OAAO,SAAS,OAAO,OAAO,UAAU,SAAU,QAAO;AAC7D,MAAI;AACF,uBAAmB,OAAO,KAAK;AAC/B,WAAO;AAAA,EACT,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,MAAM,OAAQ,EAAY,QAAQ;AAAA,EACpD;AACF;;;ACnBO,SAAS,WAAW,QAAkB,GAA0B;AACrE,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,KAAK,IAAI;AACtC,UAAM,MAAM,0CAA0C;AACxD,MACE,OAAO,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,SAAS,CAAC,KAAM,IAAI,KAAK,IAAI,OAAO,IAAI,CAAC,CAAG;AAE1E,UAAM,MAAM,kDAAkD;AAChE,SAAO,QAAQ,kBAAkB;AACjC,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,YAAY,OAAO,SAAS,KAAK,GACrC,QAAQ,KAAK,MAAM,QAAQ,GAC3B,WAAW,WAAW;AACxB,QAAM,IAAI,OAAO,KAAK,GACpB,IAAI,OAAO,KAAK,IAAI,QAAQ,GAAG,OAAO,SAAS,CAAC,CAAC;AAEnD,QAAM,OAAO,IAAI,YAAY,IAAI,WAAW;AAC5C,qBAAmB,GAAG;AACtB,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC;AAC1C,SAAO;AACT;AACO,SAAS,WACd,QACA,WAA+B,UAC/B;AACA,MAAI,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AACxC,UAAM,MAAM,6CAA6C;AAC3D,SAAO,QAAQ,kBAAkB;AACjC,QAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,GAC7C,IAAI,OAAO;AACb,MAAI,CAAC,EAAG,QAAO;AACf,QAAM,MAAM,OAAO,CAAC,GAClB,MAAM,OAAO,IAAI,CAAC,GAClB,KAAK,WAAW,QAAQ,IAAI,GAC5B,SAAS,WAAW,QAAQ,GAAG,GAC/B,KAAK,WAAW,QAAQ,IAAI;AAC9B,QAAM,WAAW,KAAK,OAAO,KAAK,KAChC,YAAY,KAAK,OAAO,KAAK;AAC/B,QAAM,MAAM,aAAa,UAAU,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAK;AACxE,QAAM,OACJ,aAAa,UACT,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,SAAS,IAChD;AACN,QAAM,UACJ,aAAa,UAAU,OAAO,OAAO,CAAC,MAAM,IAAI,OAAO,IAAI,IAAI,IAAI,CAAC;AAEtE,QAAM,WACJ,QAAQ,UAAU,KACd,UACA,CAAC,GAAG,QAAQ,MAAM,GAAG,EAAE,GAAG,GAAG,QAAQ,MAAM,GAAG,CAAC;AACrD,QAAM,UAAU,OAAO,OAAO,CAAC,KAAK,UAAU,MAAM,QAAQ,GAAG,CAAC;AAEhE,qBAAmB,OAAO;AAC1B,QAAM,OAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,OAAO,CAAC;AACjD,GAAC,KAAK,IAAI,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI,EAAE,QAAQ,kBAAkB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,QAAQ;AAAA,IACtB;AAAA,IACA,QAAQ;AAAA,EACV;AACF;AACO,SAAS,eAAe,QAAkB,MAAwB;AACvE,MAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO;AAChD,UAAM,MAAM,kCAA6B;AAC3C,MAAI,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AACxC,UAAM,MAAM,0CAA0C;AACxD,SAAO,QAAQ,kBAAkB;AACjC,MAAI,CAAC,OAAO,OAAQ,QAAO,CAAC;AAC5B,MAAI,MAAM,UACR,MAAM;AACR,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,IAAI,KAAK,KAAK;AACzB,UAAM,KAAK,IAAI,KAAK,KAAK;AAAA,EAC3B;AACA,MAAI,QAAQ,IAAK,QAAO,CAAC,KAAK,GAAG;AACjC,MAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC5B,UAAM,MAAM,mDAAmD;AACjE,QAAM,QAAQ,MAAM;AAAA,IAClB,EAAE,QAAQ,OAAO,EAAE;AAAA,IACnB,CAAC,GAAG,MAAM,OAAO,MAAM,QAAQ,IAAI;AAAA,EACrC;AACA,QAAM,CAAC,IAAI;AACX,QAAM,IAAI,IAAI;AACd,QAAM,QAAQ,kBAAkB;AAChC,MAAI,MAAM,KAAK,CAAC,OAAO,MAAM,IAAI,KAAK,SAAS,MAAM,IAAI,CAAC,CAAE;AAC1D,UAAM;AAAA,MACJ;AAAA,IACF;AACF,SAAO;AACT;AACO,SAAS,gBAAgB,QAAkB,OAA2B;AAC3E,MAAI,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AACxC,UAAM,MAAM,0CAA0C;AACxD,MAAI,CAAC,MAAM,QAAQ;AACjB,QAAI,OAAO,OAAQ,OAAM,MAAM,iCAAiC;AAChE,WAAO,CAAC;AAAA,EACV;AACA,MACE,MAAM,SAAS,KACf,MAAM;AAAA,IACJ,CAAC,GAAG,MACF,CAAC,OAAO,SAAS,CAAC,KACjB,IAAI,MACF,IAAI,MAAM,IAAI,CAAC,KAAO,MAAM,MAAM,IAAI,CAAC,KAAM,MAAM,WAAW;AAAA,EACrE;AAEA,UAAM,MAAM,oDAAoD;AAClE,SAAO,QAAQ,kBAAkB;AACjC,QAAM,QAAQ,kBAAkB;AAChC,QAAM,SAAS,MAAc,MAAM,SAAS,CAAC,EAAE,KAAK,CAAC;AACrD,aAAW,SAAS,QAAQ;AAC1B,QAAI,QAAQ,MAAM,CAAC,KAAM,QAAQ,MAAM,MAAM,SAAS,CAAC;AACrD,YAAM,MAAM,6CAA6C;AAE3D,QAAI,MAAM;AACV,WAAO,MAAM,OAAO,SAAS,KAAK,SAAS,MAAM,MAAM,CAAC,EAAI;AAC5D,WAAO,GAAG,IAAI,OAAO,GAAG,IAAK;AAAA,EAC/B;AACA,SAAO;AACT;;;AC/HA,SAAS,gBAAgB;AAElB,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,SAAS,eAAe,OAAoB,WAAW,OAAe;AAC3E,MACE,OAAO,UAAU,YACjB,CAAC,gFAAgF;AAAA,IAC/E;AAAA,EACF;AAEA,UAAM;AAAA,MACJ;AAAA,IACF;AACF,QAAM,OAAO,KAAK,MAAM,KAAK,GAC3B,QAAQ,OAAO,MAAM,MAAM,GAAG,CAAC,CAAC,GAChC,MAAM,OAAO,MAAM,MAAM,GAAG,EAAE,CAAC;AACjC,QAAM,WAAW,oBAAI,KAAK,CAAC;AAC3B,WAAS,eAAe,OAAO,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC;AAC3D,MACE,CAAC,OAAO,SAAS,IAAI,KACrB,QAAQ,KACR,QAAQ,MACR,MAAM,KACN,MAAM,SAAS,WAAW;AAE1B,UAAM,MAAM,8BAA8B;AAC5C,SAAO,MAAM,WAAW,MAAM,aAAa,QACvC,SAAS,UAAU,KAAK,KAAK,EAAE,gBAAgB,QAAQ,EAAE,oBACzD;AACN;AAIA,SAAS,uBACP,OACA,KACA,UACoB;AACpB,MAAI,OAAO,MAAO,QAAO;AACzB,QAAM,SAAS,CAAC,SACd,SAAS,QAAQ,sBAAsB,IAAI,EAAE,mBAAmB,QAAQ,EACrE;AACL,QAAM,SAAS,OAAO,KAAK;AAC3B,MAAI,WAAW,OAAO,GAAG,EAAG,QAAO;AAEnC,SAAO,MAAM,QAAQ,GAAG;AACtB,UAAM,SAAS,KAAK,OAAO,QAAQ,OAAO,CAAC;AAC3C,QAAI,OAAO,MAAM,MAAM,OAAQ,SAAQ;AAAA,QAClC,OAAM;AAAA,EACb;AACA,SAAO;AACT;AAEO,SAAS,gBACd,MACA,UACA,WAAW,OACH;AACR,MAAI,aAAa,OAAO;AACtB,UAAM,QACJ,SAAS,QAAQ,sBAAsB,IAAI,EAAE,mBAAmB,QAAQ;AAC1E,QAAI,aAAa,QAAQ;AACvB,YAAM,QACJ,OAAO,MAAM,SAAS,MAAQ,MAAM,SAAS,MAAO,MAAM;AAG5D,aAAO,uBAAuB,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC1D;AACA,QAAIC,QAAO,MAAM,YAAY;AAC7B,QAAI,aAAa,OAAQ,CAAAA,QAAOA,MAAK,SAAS,EAAE,MAAMA,MAAK,YAAY,EAAE,CAAC;AAC1E,QAAI,aAAa,WAAW,aAAa;AACvC,MAAAA,QAAOA,MAAK,KAAK,EAAE,KAAK,EAAE,CAAC;AAC7B,QAAI,aAAa,OAAQ,CAAAA,QAAOA,MAAK,KAAK,EAAE,OAAO,EAAE,CAAC;AACtD,WAAOA,MAAK,gBAAgB,QAAQ,EAAE;AAAA,EACxC;AACA,QAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,OAAK,cAAc,GAAG,GAAG,CAAC;AAC1B,MAAI,aAAa,OAAQ,MAAK,YAAY,CAAC;AAC3C,MAAI,aAAa;AACf,SAAK,WAAW,KAAK,WAAW,KAAM,KAAK,UAAU,IAAI,KAAK,CAAE;AAClE,MAAI,aAAa,WAAW,aAAa,OAAQ,MAAK,WAAW,CAAC;AAClE,MAAI,aAAa,OAAQ,MAAK,YAAY,CAAC;AAC3C,SAAO,KAAK,QAAQ;AACtB;AAEO,SAAS,eACd,MACA,UACA,WAAW,OACH;AACR,MAAI,aAAa,OAAO;AACtB,UAAM,QACJ,SAAS,QAAQ,sBAAsB,IAAI,EAAE,mBAAmB,QAAQ;AAC1E,QAAI,aAAa,QAAQ;AACvB,YAAM,SAAS,MACZ,gBAAgB,EAChB,KAAK;AAAA,QACJ,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,aAAa;AAAA,QACb,YAAY;AAAA,MACd,CAAC,EACA,IAAI,EAAE,OAAO,EAAE,CAAC;AACnB,UAAI,OAAO,OAAO,gBAAgB,QAAQ,EAAE;AAC5C,UAAI,QAAQ;AACV,eAAO,OAAO,gBAAgB,UAAU;AAAA,UACtC,gBAAgB;AAAA,QAClB,CAAC,EAAE;AACL,aAAO,uBAAuB,MAAM,MAAM,QAAQ,KAAK;AAAA,IACzD;AACA,QAAIA,QAAO,MAAM,YAAY;AAC7B,QAAI,aAAa,QAAS,CAAAA,QAAOA,MAAK,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAAA,aAC/D,aAAa;AACpB,MAAAA,QAAOA,MAAK,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,aAChD,aAAa;AACpB,MAAAA,QAAOA,MAAK,SAAS,EAAE,MAAMA,MAAK,YAAY,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAAA,QAChE,CAAAA,QAAOA,MAAK,IAAI,EAAE,MAAM,EAAE,CAAC;AAChC,WAAOA,MAAK,gBAAgB,QAAQ,EAAE;AAAA,EACxC;AACA,QAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,MAAI,aAAa,OAAQ,MAAK,YAAY,KAAK,YAAY,IAAI,CAAC;AAAA,WACvD,aAAa,QAAS,MAAK,YAAY,KAAK,YAAY,IAAI,CAAC;AAAA,WAC7D,aAAa,OAAQ,MAAK,eAAe,KAAK,eAAe,IAAI,CAAC;AAAA,MACtE,MAAK,WAAW,KAAK,WAAW,KAAK,aAAa,SAAS,IAAI,EAAE;AACtE,SAAO,KAAK,QAAQ;AACtB;AAGA,SAAS,cAAc,OAAe,WAAW,OAAe;AAC9D,QAAM,OAAO,eAAe,OAAO,QAAQ;AAC3C,SAAO,MAAM,WAAW,KAAK,eAAe,MAAM,OAAO,QAAQ,IAAI,IAAI;AAC3E;AAEO,SAAS,qBAAqB,QAAkC;AACrE,MACE,OAAO,OAAO,UAAU,YACxB,CAAC,OAAO,SACR,OAAO,MAAM,SAAS,OACtB,CAAC,sBAAsB,SAAS,OAAO,QAAQ,KAC/C,OAAO,OAAO,iBAAiB,aAC/B,CAAC,CAAC,SAAS,YAAY,QAAQ,EAAE,SAAS,OAAO,KAAK;AAEtD,UAAM,MAAM,mCAAmC;AACjD,MAAI,OAAO,aAAa,QAAW;AACjC,QACE,OAAO,OAAO,aAAa,YAC3B,CAAC,OAAO,YACR,OAAO,SAAS,SAAS,MACzB,QAAQ,KAAK,OAAO,QAAQ;AAE5B,YAAM;AAAA,QACJ;AAAA,MACF;AACF,QAAI;AACF,UAAI,KAAK,eAAe,SAAS,EAAE,UAAU,OAAO,SAAS,CAAC;AAAA,IAChE,QAAQ;AACN,YAAM;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,gBAAgB,OAAO,UAAU,UAAU;AACpD,UAAM,QAAQ,eAAe,OAAO,SAAS,IAAI,OAAO,QAAQ,GAC9D,MAAM,cAAc,OAAO,OAAO,IAAI,OAAO,QAAQ;AACvD,QAAI,MAAM;AACR,YAAM,MAAM,kDAAkD;AAAA,EAClE;AACF;AAGO,SAAS,gBACd,QACA,OACA,UACA,KACA,WAC8B;AAC9B,MAAI,MAAM,UACR,MAAM;AACR,aAAW,QAAQ,UAAU;AAC3B,UAAM,KAAK,IAAI,KAAK,IAAI;AACxB,UAAM,KAAK,IAAI,KAAK,IAAI;AAAA,EAC1B;AACA,MAAI,OAAO,UAAU;AACnB,WAAO,SAAS,SAAS,CAAC,KAAK,GAAG,IAAI;AACxC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAMC,SAAQ;AAAA,MACZ,eAAe,OAAO,SAAS,IAAI,OAAO,QAAQ;AAAA,MAClD,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,UAAMC,OAAM;AAAA,MACV,cAAc,OAAO,OAAO,IAAI,OAAO,QAAQ;AAAA,MAC/C,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AACA,QAAI,SAAS,WAAWD,SAAQ,OAAOC,OAAM;AAC3C,YAAM;AAAA,QACJ;AAAA,MACF;AACF,WAAO,CAACD,QAAOC,IAAG;AAAA,EACpB;AACA,MAAI,QAAQ,WACV,MAAM;AACR,aAAW,QAAQ,MAAM,OAAO;AAC9B,QACE,UAAU,IAAI,KACd,KAAK,WACL,UAAU,KAAK,KAAK,MAAM,UAAU,OAAO,KAAK;AAEhD;AACF,QAAI,CAAC,CAAC,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE,SAAS,KAAK,EAAE,EAAG;AACpD,UAAM,OAAO,OAAO,YAAY,YAAY,KAAK,OAAO,GAAG,CAAC;AAC5D,QAAI,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACrD,cAAQ,KAAK,IAAI,OAAO,QAAQ,KAAK,OAAO,MAAM,IAAI,EAAE;AAC1D,QAAI,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AACrD,YAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,OAAO,MAAM,IAAI,EAAE;AAAA,EACxD;AACA,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;AACpD,UAAM,UAAU;AAAA,MACd,GAAI,OAAO,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,yBAAyB;AAAA,MAC5D,GAAI,OAAO,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,0BAA0B;AAAA,IAC7D,EAAE,KAAK,OAAO;AACd,UAAM;AAAA,MACJ,yEAAyE,OAAO,KAAK,SAAS,OAAO;AAAA,IACvG;AAAA,EACF;AACA,MAAI,MAAM,MAAO,QAAO;AACxB,SAAO;AAAA,IACL,gBAAgB,OAAO,OAAO,UAAU,OAAO,QAAQ;AAAA,IACvD,gBAAgB,KAAK,OAAO,UAAU,OAAO,QAAQ;AAAA,EACvD;AACF;;;AC1LA,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,mBAAsC;AAAA,EACjD,CAAC,SAAS,kCAAkC;AAAA,EAC5C,CAAC,kBAAkB,kCAAkC;AAAA,EACrD,CAAC,OAAO,qCAAqC;AAAA,EAC7C,CAAC,OAAO,uCAAuC;AAAA,EAC/C,CAAC,OAAO,yCAAyC;AAAA,EACjD,CAAC,OAAO,wCAAwC;AAAA,EAChD;AAAA,IACE;AAAA,IACA;AAAA,EACF;AACF,EAAE,IAAI,CAAC,CAAC,MAAM,WAAW,OAAO;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,WAAW,GAAG,IAAI,kBAAkB,SAAS,UAAU,MAAM,EAAE;AAAA,EAC/D,KAAK,SAAS,UAAU,IAAI;AAAA,EAC5B,KAAK;AAAA,EACL,QAAQ,SAAS,SAAS,SAAS,QAAQ,WAAW;AAAA,EACtD,MAAM,CAAC,OAAO,OAAO,QAAQ,EAAE,SAAS,IAAK,IAAI,CAAC,QAAQ,IAAI;AAChE,EAAE;AAKK,SAAS,cACd,YACA,QACA,SACY;AACZ,QAAM,SAA8B,MAAM,QAAQ,MAAM,IACpD,SACC,OAAuB;AAC5B,QAAM,QAAkC,CAAC;AACzC,QAAM,iBAAgC,CAAC;AACvC,MAAI,cAAc;AAClB,QAAM,OAAO;AAAA,IACX;AAAA,IACA,UACI,OAAO;AAAA,MACL,CAACC,OAAMA,GAAE,OAAO,SAAS,aAAa,CAACA,GAAE,OAAO;AAAA,IAClD,IACA;AAAA,IACJ;AAAA,IACA,CAAC,MAAM,UAAU;AACf,UAAI,KAAK,SAAS,UAAU,CAAC,WAAW,IAAI,KAAK,IAAI,EAAG,QAAO;AAC/D,UAAI;AACF,cAAM,IAAI;AAAA,UACR;AAAA,UACA,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AACF,UACE,KAAK,KAAK,SAAS,KAClB,KAAK,SAAS,WAAW,KAAK,KAAK,WAAW;AAE/C,cAAM,IAAI;AAAA,UACR,GAAG,KAAK,IAAI,aAAa,KAAK,SAAS,UAAU,yBAAyB,cAAc;AAAA,UACxF,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AACF,oBAAc;AACd,UAAI;AACJ,UAAI;AACF,eAAO,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,IAAI;AAAA,MAC9C,UAAE;AACA,sBAAc;AAAA,MAChB;AACA,YAAM,QAAQ,CAAC,MAAmB;AAChC,YAAI,EAAE,SAAS,SAAS;AACtB,gBAAM,QAAQ,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,EAAE,IAAI;AAClD,cAAI,CAAC;AACH,kBAAM,IAAI;AAAA,cACR,yBAAyB,EAAE,IAAI;AAAA,cAC/B,EAAE;AAAA,cACF,EAAE;AAAA,YACJ;AAGF,cACE,CAAC,aAAa,KAAK,MACjB,MAAM,WAAW,QAAQ,UACxB,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,SAAS,aACrC,CAAC,eAAe,KAAK,EAAE,SAAS,KAAK,KAAK,YAAY,CAAU;AAElE,kBAAM,IAAI;AAAA,cACR,SAAS,EAAE,IAAI,mBAAmB,KAAK,IAAI;AAAA,cAC3C,EAAE;AAAA,cACF,EAAE;AAAA,YACJ;AAAA,QACJ,WAAW,EAAE,SAAS,QAAQ;AAC5B,cAAI,WAAW,IAAI,EAAE,IAAI;AACvB,kBAAM,IAAI;AAAA,cACR;AAAA,cACA,EAAE;AAAA,cACF,EAAE;AAAA,YACJ;AACF,YAAE,KAAK,QAAQ,KAAK;AAAA,QACtB;AAAA,MACF;AACA,WAAK,KAAK,QAAQ,KAAK;AACvB,UACE,CAAC,OAAO,OAAO,QAAQ,EAAE,SAAS,KAAK,IAAI,KAC3C,CAAC,CAAC,UAAU,MAAM,EAAE,SAAS,IAAI;AAEjC,cAAM,IAAI;AAAA,UACR,GAAG,KAAK,IAAI;AAAA,UACZ,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AACF,UACE,CAAC,OAAO,OAAO,gBAAgB,EAAE,SAAS,KAAK,IAAI,MAClD,SAAS,eACP,SAAS,UAAU,KAAK,SAAS;AAEpC,cAAM,IAAI;AAAA,UACR,eAAe,KAAK,IAAI;AAAA,UACxB,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AACF,YAAM,KAAK,IAAI;AACf,qBAAe,KAAK,IAAI;AACxB,aAAO,CAAC,SAAS,kBAAkB,OAAO,OAAO,QAAQ,EAAE;AAAA,QACzD,KAAK;AAAA,MACP,IACI,WACA;AAAA,IACN;AAAA,EACF;AACA,QAAM,aAAa,CAAC,SAAsB;AACxC,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACF,QAAI,KAAK,SAAS,UAAU,CAAC,WAAW,IAAI,KAAK,IAAI,GAAG;AACtD,UAAI,KAAK,KAAK,WAAW,QAAQ;AAC/B,cAAM,IAAI;AAAA,UACR;AAAA,UACA,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AACF,WAAK,KAAK,QAAQ,UAAU;AAAA,IAC9B;AAAA,EACF;AACA,aAAW,KAAK,GAAG;AACnB,MAAI,CAAC,MAAM;AACT,UAAM,IAAI,aAAa,qCAAqC;AAC9D,MAAI,KAAK,SAAS;AAChB,UAAM,IAAI,aAAa,oCAAoC;AAC7D,SAAO,EAAE,GAAG,MAAM,YAAY,OAAO,eAAe;AACtD;AAEO,SAAS,qBAAqB,MAA0C;AAC7E,SAAO,KAAK,WAAW,IAAI,CAAC,SAAS;AACnC,QAAI,CAAC,KAAK,KAAK,CAAC,EAAG,QAAO;AAC1B,UAAM,eAAe,oBAAI,IAAY;AACrC,UAAM,QAAQ,CAAC,MAAyB;AACtC,UAAI,EAAE,SAAS,QAAS,cAAa,IAAI,EAAE,IAAI;AAAA,eACtC,EAAE,SAAS,OAAQ,GAAE,KAAK,QAAQ,KAAK;AAAA,IAClD;AACA,UAAM,KAAK,KAAK,CAAC,CAAC;AAElB,WAAO;AAAA,MACL,KAAK,KAAK,KAAK,CAAC;AAAA,MAChB,cAAc,CAAC,GAAG,YAAY,EAAE,KAAK;AAAA,MACrC,MAAM,KAAK,eAAe,KAAK,WAAW,QAAQ,IAAI,CAAC;AAAA,IACzD;AAAA,EACF,CAAC;AACH;AAQA,SAAS,oBAAoBC,UAAiC;AAC5D,QAAM,SAAS,oBAAI,IAA+B;AAClD,MAAI,QAAQ;AACZ,QAAM,cAAcA,SAAQ,qBAAqB;AACjD,QAAM,YAAYA,SAAQ,oBAAoB;AAC9C,MACE,CAAC,OAAO,cAAc,WAAW,KACjC,cAAc,KACd,CAAC,OAAO,cAAc,SAAS,KAC/B,YAAY;AAEZ,UAAM,MAAM,0BAA0B;AACxC,SAAO;AAAA,IACL,IAAI,OAAqB;AACvB,YAAM,IAAI,OAAO,KAAK;AACtB,UAAI,OAAO,MAAM,SAAU,oBAAmB,CAAC;AAC/C,UAAI,MAAM,QAAQ,OAAO,IAAI,CAAC,EAAG;AACjC,YAAM,OAAO,MAAM,OAAO,MAAM,WAAW,EAAE,SAAS,IAAI;AAC1D,UAAI,OAAO,QAAQ,eAAe,OAAO,YAAY;AACnD,cAAM,MAAM,kDAAkD;AAChE,aAAO,IAAI,CAAC;AACZ,eAAS;AAAA,IACX;AAAA,IACA,QAAQ,OAAO,EAAE,OAAO,OAAO,KAAK;AAAA,EACtC;AACF;AACO,SAAS,mBACd,MACA,SACAA,WAAkC,CAAC,GACpB;AACf,SAAO,cAAc,MAAM,SAASA,QAAO;AAC7C;AACA,SAAS,cACP,MACA,SACAA,UACe;AACf,MAAI;AACF,QAAI,CAAC,WAAW,IAAI,KAAK,IAAI,EAAG,OAAM,MAAM,6BAA6B;AACzE,UAAM,WACJ,KAAK,SAAS,mBAAmB,oBAAoBA,QAAO,IAAI;AAClE,UAAM,SAAyB,CAAC;AAChC,QAAI,QAAQ,GACV,UAAU,GACV;AACF,eAAW,KAAK,SAAS;AACvB;AACA,UAAI,EAAE,OAAO;AACX,0BAAU,EAAE;AACZ;AAAA,MACF;AACA,UAAI,EAAE,UAAU,KAAM;AACtB,UAAI,KAAK,SAAS,WAAW,CAAC,YAAY,OAAO,EAAE,UAAU;AAC3D,2BAAmB,EAAE,KAAK;AAC5B;AACA,UAAI,SAAU,UAAS,IAAI,EAAE,KAAK;AAAA,eACzB,KAAK,SAAS,QAAS,QAAO,KAAK,EAAE,KAAK;AAAA,IACrD;AACA,QAAI,MAAO,QAAO,EAAE,OAAO,MAAM,MAAM;AACvC,QAAI,SAAU,QAAO,SAAS,OAAO;AACrC,QAAI,KAAK,SAAS;AAChB,aAAO,EAAE,OAAO,KAAK,KAAK,SAAS,UAAU,MAAM;AACrD,QAAI,CAAC,OAAO,OAAQ,QAAO,EAAE,OAAO,KAAK;AACzC,QAAI,KAAK,SAAS,UAAU;AAC1B,YAAM,SAAS,OACZ,IAAI,CAACC,WAAU;AACd,YAAI,OAAOA,WAAU,YAAY,CAAC,OAAO,SAASA,MAAK;AACrD,gBAAM,MAAM,2BAA2B;AACzC,eAAOA;AAAA,MACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACvB,YAAM,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC;AACxC,YAAM,QACJ,OAAO,SAAS,IACZ,OAAO,GAAG,IACV,OAAO,MAAM,CAAC,IAAK,IAAI,OAAO,GAAG,IAAK;AAC5C,yBAAmB,KAAK;AACxB,aAAO,EAAE,MAAM;AAAA,IACjB;AACA,QAAI,KAAK,SAAS,SAAS,KAAK,SAAS,OAAO;AAC9C,UAAI,MAAM;AACV,iBAAW,KAAK,QAAQ;AACtB,YAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC;AAC7C,gBAAM,MAAM,2BAA2B;AACzC,eAAO,KAAK,KAAK,SAAS,QAAQ,OAAO,SAAS;AAClD,2BAAmB,GAAG;AAAA,MACxB;AACA,aAAO,EAAE,OAAO,IAAI;AAAA,IACtB;AACA,WAAO;AAAA,MACL,OAAO,OAAO;AAAA,QAAO,CAAC,GAAG,MACvB,oBAAoB,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,KACrC,KAAK,SAAS,QAAQ,IAAI,OAC7B,IACI,IACA;AAAA,MACN;AAAA,IACF;AAAA,EACF,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,MAAM,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE;AAAA,EAC1E;AACF;AAGO,SAAS,yBACd,MACA,YACe;AACf,QAAM,MAAM,CAAC,MACX,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,SAAS,EAAE,OAAO,EAAE,IAAI;AAC1D,QAAM,SAAS,IAAI;AAAA,IACjB,KAAK,WAAW,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;AAAA,EACvD;AACA,SAAO;AAAA,IACL;AAAA,MAAe,KAAK;AAAA,MAAK,CAAC;AAAA,MAAG,CAAC,SAC5B,OAAO,IAAI,IAAI,IAAI,CAAC,IAChB;AAAA,QACE,OAAO,IAAI,IAAI,IAAI,CAAC,KAAK;AAAA,UACvB,OAAO;AAAA,UACP,OAAO;AAAA,QACT;AAAA,MACF,IACA;AAAA,IACN;AAAA,EACF;AACF;AACO,SAAS,iBAAiB,QAAmC;AAClE,SACE,OAAO,cACP,GAAG,OAAO,GAAG,YAAY,CAAC,IAAI,OAAO,QAAQ,IAAI,OAAO,MAAM,QAAQ,MAAM,IAAI,CAAC,MAAM,EAAE;AAE7F;AACO,SAAS,SAAS,MAA4B;AACnD,QAAM,QAAQ,CAAC,MACb,EAAE,SAAS,WAAW,EAAE,KAAK,WAAW,QAAQ,KAAK,EAAE,KAAK,KAAK,KAAK;AACxE,SAAO,MAAM,KAAK,GAAG;AACvB;AACA,SAAS,mBAAmB,GAA+B;AACzD,SACE,CAAC,CAAC,EAAE,iBACH,CAAC,EAAE,WAAW,EAAE,QAAQ,SAAS,SAAS,EAAE,QAAQ,SAAS;AAElE;AACO,SAAS,YACd,GACA,QACA,SACe;AACf,MAAI,mBAAmB,CAAC,GAAG;AACzB,UAAM,IAAI;AAAA,MACR,EAAE,aAAc;AAAA,MAChB,UACI,OAAO,OAAO;AAAA,QACZ,CAACF,OAAMA,GAAE,OAAO,SAAS,aAAa,CAACA,GAAE,OAAO;AAAA,MAClD,IACA,OAAO;AAAA,MACX;AAAA,IACF;AACA,QAAI,EAAE,SAAS,YAAY,EAAE,SAAS;AACpC,YAAM,IAAI,aAAa,qCAAqC;AAC9D,QAAI,CAAC,CAAC,OAAO,WAAW,EAAE,SAAS,EAAE,aAAc,IAAI;AACrD,YAAM,IAAI,aAAa,4BAA4B;AACrD,QACE,EAAE,aAAc,SAAS,gBACxB,CAAC,OAAO,UAAU,EAAE,aAAc,QAAQ,EAAE,MAC1C,EAAE,aAAc,QAAQ,MAAM,MAC9B,EAAE,aAAc,QAAQ,MAAM;AAEjC,YAAM,IAAI,aAAa,kCAA6B;AACtD,eAAW,QAAQ,EAAE,cAAc;AACjC,YAAM,QAAQ,OAAO,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,IAAI;AACvD,UAAI,CAAC,aAAa,KAAK;AACrB,cAAM,IAAI,aAAa,SAAS,IAAI,kCAAkC;AAAA,IAC1E;AACA,QAAI,EAAE,UAAU,eAAe,SAAS,CAAC;AACvC,YAAM,IAAI,aAAa,gDAAgD;AACzE,WAAO,CAAC,CAAC;AAAA,EACX;AACA,QAAM,MAAM;AAAA,IACV;AAAA,MACE;AAAA,QACE,EAAE,eAAe,UAAa,EAAE,QAC5B,EAAE,GAAG,GAAG,OAAO,iBAAiB,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,IAC5D;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,MAAI,EAAE,SAAS,SAAS,WAAW;AACjC,QAAI,KAAK,cAAc,EAAE,eAAe,IAAI,QAAQ,OAAO,CAAC;AAC5D,QAAI,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,SAAS,MAAM;AAC1D,YAAM,IAAI,aAAa,sCAAsC;AAAA,EACjE;AACA,MAAI,EAAE,UAAU,eAAe,IAAI,KAAK,QAAQ;AAC9C,UAAM,IAAI,aAAa,gDAAgD;AACzE,SAAO;AACT;AACO,SAAS,eACd,GACA,QACA,SACqB;AACrB,MAAI;AACF,QAAI,EAAE,aAAa,OAAQ,OAAM,IAAI,aAAa,EAAE,YAAY,KAAK,GAAG,CAAC;AACzE,QAAI,EAAE,QAAQ,SAAS;AACrB,YAAM,IAAI,aAAa,yCAAyC;AAClE,eAAW,OAAO,EAAE,SAAS;AAC3B,YAAMA,KAAI,OAAO,OAAO;AAAA,QACtB,CAACA,OAAMA,GAAE,UAAU,iBAAiB,QAAQ,GAAG,KAAK;AAAA,MACtD;AACA,UAAI,CAACA,MAAK,CAAC,YAAYA,EAAC;AACtB,cAAM,IAAI,aAAa,SAAS,GAAG,wBAAwB;AAAA,IAC/D;AACA,QAAI,EAAE,cAAc;AAClB,2BAAqB,EAAE,YAAY;AACnC,YAAM,QACJ,iBAAiB,QAAQ,EAAE,aAAa,KAAK,KAAK,EAAE,aAAa;AACnE,UACE,WACG,iBAAiB,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,MAC9D,OAAO,OAAO,KAAK,CAACA,OAAMA,GAAE,SAAS,KAAK,GAAG,SAAS;AAEtD,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,UAAI,mBAAmB,CAAC;AACtB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,IACJ;AACA,QACE,EAAE,eAAe,WAChB,CAAC,OAAO,UAAU,EAAE,UAAU,KAC7B,EAAE,aAAa,KACf,EAAE,aAAa;AAEjB,YAAM,IAAI,aAAa,oCAA+B;AACxD,QAAI,EAAE,aAAa,QAAW;AAC5B,UACE,CAAC,OAAO,UAAU,EAAE,QAAQ,KAC5B,EAAE,WAAW,KACb,EAAE,WAAW;AAEb,cAAM,IAAI,aAAa,kDAA6C;AACtE,UAAI,CAAC,EAAE,QAAQ;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,IACJ;AACA,wBAAoB,EAAE,OAAO,MAAM;AACnC,eAAW,KAAK,EAAE,QAAQ,CAAC,GAAG;AAC5B,UAAI,EAAE,QAAQ,OAAO,EAAE,SAAS,SAAS;AACvC,cAAM,IAAI,aAAa,sCAAsC;AAC/D,UAAI,EAAE,QAAQ,aAAa,CAAC,mBAAmB,CAAC;AAC9C,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,UACE,EAAE,IAAI,WAAW,OAAO,KACxB,OAAO,EAAE,IAAI,MAAM,CAAC,CAAC,KAAK,EAAE,QAAQ;AAEpC,cAAM,IAAI,aAAa,6CAA6C;AAAA,IACxE;AACA,UAAM,WAAW,YAAY,GAAG,QAAQ,OAAO;AAC/C,QAAI,EAAE,UAAU,eAAe,SAAS,KAAK,QAAQ;AACnD,YAAM,IAAI,aAAa,gDAAgD;AACzE,WAAO,CAAC;AAAA,EACV,SAAS,GAAG;AACV,WAAO;AAAA,MACL;AAAA,QACE,SAAS,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,QAClD,MAAM,aAAa,eAAe,EAAE,OAAO;AAAA,QAC3C,IAAI,aAAa,eAAe,EAAE,KAAK;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,oBACP,OACA,QACM;AACN,MAAI,UAAU,OAAW;AACzB,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,aAAa,wBAAwB;AAC1E,QAAM,aAAa,MAAM,QAAQ,CAAC,SAAS,aAAa,IAAI,CAAC;AAC7D,MAAI,WAAW,SAAS;AACtB,UAAM,IAAI;AAAA,MACR,kCAAkC,iBAAiB;AAAA,IACrD;AACF,QAAM,SAAS,YAAY,MAAM;AACjC,aAAW,KAAK,YAAY;AAC1B,UAAM,OAAO,iBAAiB,QAAQ,EAAE,KAAK,KAAK,EAAE;AACpD,UAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,QACE,CAAC,SACD,CAAC,aAAa,KAAK,KAClB,gBAAgB,IAAI,KAAK,CAAC,qBAAqB,QAAQ,MAAM,QAAQ;AAEtE,YAAM,IAAI,aAAa,SAAS,EAAE,KAAK,yBAAyB;AAClE,QAAI,EAAE,OAAO,mBAAmB,EAAE,OAAO;AACvC,YAAM,IAAI,aAAa,yCAAyC;AAClE,QAAI,CAAC,YAAY,KAAK,EAAE,SAAS,EAAE,EAAE;AACnC,YAAM,IAAI;AAAA,QACR,SAAS,EAAE,KAAK,yBAAyB,EAAE,EAAE;AAAA,MAC/C;AAAA,EACJ;AACF;AAQO,SAAS,sBACd,QACA,SACoB;AACpB,MAAI,OAAO,OAAO,UAAU,CAAC,QAAQ;AACnC,WAAO;AACT,MAAI,OAAO,aAAa,UAAa,CAAC,QAAQ;AAC5C,WAAO;AACT,SAAO;AACT;AACO,SAAS,mBACd,GACA,QACA,SACU;AACV,SAAO;AAAA,IACL,GAAG,oBAAI,IAAI;AAAA,MACT,GAAG,EAAE,QAAQ,IAAI,CAAC,SAAS,iBAAiB,QAAQ,IAAI,KAAK,IAAI;AAAA,MACjE,GAAG,YAAY,GAAG,QAAQ,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,YAAY;AAAA,IAClE,CAAC;AAAA,EACH,EAAE,KAAK;AACT;AACO,SAAS,qBACd,SACQ;AACR,SAAO,KAAK;AAAA,IACV,QACG,IAAI,CAAC,OAAO;AAAA,MACX,IAAI,EAAE;AAAA,MACN,aAAa,EAAE;AAAA,MACf,eAAe,EAAE;AAAA,MACjB,YAAY,mBAAmB,CAAC,IAAI,SAAY,iBAAiB,CAAC;AAAA,MAClE,aAAa,EAAE,SAAS,SAAS,YAAY,EAAE,cAAc;AAAA,MAC7D,OAAO,EAAE,SAAS;AAAA,MAClB,SAAS,EAAE;AAAA,MACX,cAAc,EAAE;AAAA,MAChB,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,MACd,OAAO,EAAE;AAAA,MACT,UAAU,EAAE;AAAA,MACZ,cAAc,mBAAmB,CAAC,IAAI,EAAE,eAAe;AAAA,IACzD,EAAE,EACD,KAAK,CAAC,GAAG,MAAO,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAE;AAAA,EAC5D;AACF;AACO,SAAS,cACd,GACA,QACA,WACa;AACb,QAAM,iBAAiB;AACvB,QAAM,SAAS,IAAI,IAAI,OAAO,OAAO,IAAI,CAACA,OAAM,CAACA,GAAE,MAAMA,EAAC,CAAC,CAAC;AAE5D,aAAW,CAAC,MAAM,KAAK,KAAK;AAC1B,QAAI,gBAAgB,IAAI;AACtB,aAAO,IAAI,MAAM;AAAA,QACf,GAAG;AAAA,QACH,WAAW,EAAE,SAAS,OAAO,WAAW,MAAM;AAAA,MAChD,CAAC;AACL,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,WAAW,UAAU,CAAC,CAAC;AAC9D,QAAI,gBAAgB,IAAI,GAAG;AACzB,YAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,aAAO,IAAI,MAAM;AAAA,QACf,GAAG;AAAA,QACH;AAAA,QACA,OAAO,OAAO,SAAS;AAAA,QACvB,MAAM,IAAI;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU;AAAA,QAC1B,QAAQ,EAAE,SAAS,MAAM;AAAA,QACzB,MAAM,EAAE,SAAS,IAAI,KAAK;AAAA,QAC1B,WAAW;AAAA,UACT,GAAG,OAAO;AAAA,UACV,SAAS,IAAI;AAAA,UACb,WAAW,IAAI;AAAA,QACjB;AAAA,MACF,CAAC;AAAA,IACH;AACF,WAAS,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE;AACnD,QAAM,MAAM;AACZ,MAAI,oBAAoB,CAAC;AACzB,QAAM,SAAS,cAAc,GAAG,MAAM;AACtC,QAAM,cAAc,oBAAI,IAAyB;AACjD,aAAW,KAAK,EAAE,gBAAgB,CAAC;AACjC,QAAI,EAAE,OAAO,QAAQ;AACnB,YAAM,SAAS,cAAc,EAAE,GAAG,aAAa,OAAO,EAAE,MAAM,GAAG,MAAM,EACpE;AACH,kBAAY,IAAI,EAAE,IAAI,MAAM;AAAA,IAC9B;AACF,QAAM,WAAW,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAAC,MAAM;AAChD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AACJ,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAI,OAAO,SAAS,EAAE,OAAO,YAAY,IAAI,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,MAC9D,GAAI,CAAC,mBAAmB,CAAC,KAAK,eAAe,SACzC,EAAE,WAAW,IACb,CAAC;AAAA,MACL,GAAI,SAAS,SAAS,YAClB;AAAA,QACE,SAAS,EAAE,MAAM,UAAmB;AAAA,QACpC,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,MACrD,IACA,CAAC;AAAA,MACL,GAAI,mBAAmB,CAAC,KAAK,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,IAClE;AAAA,EACF,CAAC;AACD,QAAM,eAAe,EAAE,gBAAgB,CAAC,GAAG;AAAA,IAAQ,CAAC,MAClD,eAAe,GAAG,MAAM,EAAE,IAAI,CAAC,OAAO;AAAA,MACpC,GAAG;AAAA,MACH,UAAU,EAAE;AAAA,MACZ,MAAM;AAAA,IACR,EAAE;AAAA,EACJ;AACA,aAAW,KAAK,EAAE,gBAAgB,CAAC;AACjC,QAAI,EAAE,OAAO,UAAU,YAAY,IAAI,EAAE,EAAE,GAAG,WAAW,EAAE,MAAM;AAC/D,kBAAY,KAAK;AAAA,QACf,UAAU,EAAE;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,SAAS;AAAA,MACX,CAAC;AACL,aAAW,KAAK,EAAE,gBAAgB,CAAC;AACjC,QAAI,EAAE;AACJ,kBAAY,KAAK;AAAA,QACf,UAAU,EAAE;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,SAAS;AAAA,MACX,CAAC;AACL,MAAI;AACF,2BAAuB,KAAK,cAAc;AAAA,EAC5C,SAAS,GAAG;AACV,gBAAY,KAAK;AAAA,MACf,SAAS,OAAO,CAAC;AAAA,MACjB,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,KAAK,EAAE,gBAAgB,CAAC,GAAG;AACpC,QAAI,IAAI,IAAI,EAAE,EAAE;AACd,kBAAY,KAAK;AAAA,QACf,SAAS;AAAA,QACT,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,EAAE;AAAA,QACZ,MAAM;AAAA,MACR,CAAC;AACH,QAAI,IAAI,EAAE,EAAE;AAAA,EACd;AACA,MACE,OAAO,MAAM,WAAW,EAAE,MAAM,UAChC,cAAc,IAAI,KAAK,MAAM,cAAc,EAAE,KAAK;AAElD,gBAAY,KAAK;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AACH,aAAW,KAAK,EAAE,gBAAgB,CAAC,GAAG;AACpC,QAAI;AACF,iBAAW,QAAQ,mBAAmB,GAAG,MAAM;AAC7C,YAAI,gBAAgB,IAAI,GAAG;AACzB,gBAAM,WACJ,WAAW,kBAAkB,IAAI,KACjC,WAAW,kBAAkB,KAAK,MAAM,aAAa,MAAM,CAAC;AAC9D,cACE,OAAO,aAAa,YACpB,CAAC,YACD,SAAS,SAAS;AAElB,wBAAY,KAAK;AAAA,cACf,UAAU,EAAE;AAAA,cACZ,MAAM;AAAA,cACN,SAAS,iCAAiC,IAAI;AAAA,cAC9C,MAAM;AAAA,cACN,IAAI;AAAA,YACN,CAAC;AACH,cAAI,CAAC,WAAW,OAAO,IAAI;AACzB,wBAAY,KAAK;AAAA,cACf,UAAU,EAAE;AAAA,cACZ,MAAM;AAAA,cACN,SAAS,iCAAiC,IAAI;AAAA,cAC9C,MAAM;AAAA,cACN,IAAI;AAAA,YACN,CAAC;AAAA,QACL;AAAA,IACJ,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,EAAE,GAAG,GAAG,QAAQ,CAAC,EAAE,OAAO,OAAO,QAAQ,CAAC,EAAE;AAAA,IAC5C;AAAA,IACA,aAAa;AAAA,MACX,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ,CAAC;AAAA,MACT,mBAAmB,CAAC;AAAA,IACtB;AAAA,EACF;AACA,MAAI,EAAE,cAAc,KAAK,CAAC,MAAM,EAAE,UAAU,WAAW;AACrD,gBAAY;AAAA,MACV,GAAG,cAAc,YAAY,IAAI,CAAC,OAAO;AAAA,QACvC,GAAG;AAAA,QACH,UAAU;AAAA,QACV,MAAM,EAAE,QAAQ;AAAA,MAClB,EAAE;AAAA,IACJ;AACF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO,OAAO;AAAA,IACd,SAAS,cAAc;AAAA,IACvB,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE;AAAA,IACV;AAAA,IACA;AAAA,IACA,GAAI,YACA;AAAA,MACE,SAAS,UAAU;AAAA,MACnB,mBAAmB,EAAE,GAAG,UAAU,kBAAkB;AAAA,MACpD,WAAW,UAAU;AAAA,MACrB,GAAI,UAAU,aAAa,SACvB,EAAE,UAAU,UAAU,SAAS,IAC/B,CAAC;AAAA,IACP,IACA,CAAC;AAAA,EACP;AACF;AACA,SAAS,cAAc,OAAoC;AACzD,SAAO,KAAK;AAAA,IAAU;AAAA,IAAO,CAAC,MAAM,SAClC,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IACnD,OAAO;AAAA,MACL,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE;AAAA,IACtE,IACA;AAAA,EACN;AACF;AAEA,SAAS,uBACP,GACA,QACM;AACN,QAAM,aAAa,oBAAoB,CAAC;AACxC,OAAK,EAAE,cAAc,UAAU,QAAQ,WAAW,cAAc,UAAU;AACxE,UAAM,MAAM,iDAAiD;AAC/D,QAAM,UAAU,EAAE,QAAQ,SAAS,EAAE,UAAW,OAAO,eAAe,CAAC;AACvE,QAAM,kBAAkB,oBAAoB,EAAE,GAAG,GAAG,QAAQ,CAAC,EAAE;AAC/D,MACE,cAAc,EAAE,KAAK,MAAM,cAAc,WAAW,KAAK,KACzD,cAAc,OAAO,MAAM,cAAc,eAAe,KACxD,EAAE,UAAU,WAAW,SACvB,EAAE,WAAW,WAAW;AAExB,UAAM,MAAM,0DAA0D;AAC1E;AAGO,SAAS,sBACd,MACA,GACA,QACAC,WAAwC,CAAC,GAClC;AACP,MAAIA,SAAQ,QAAQ,QAAS,OAAM,MAAM,8BAA8B;AACvE,yBAAuB,GAAG,MAAM;AAChC,MAAIA,SAAQ,UAAW,QAAOA,SAAQ;AACtC,QAAM,UAAU,EAAE,QAAQ,SAAS,EAAE,UAAW,OAAO,eAAe,CAAC;AACvE,yBAAuB,GAAG,QAAQ,OAAO;AACzC,MAAI,KAAK,UAAUA,SAAQ,WAAW;AACpC,UAAM,MAAM,6BAA6B;AAC3C,OAAKA,SAAQ,iBAAiB,QAAa;AACzC,UAAM,MAAM,mCAAmC;AACjD,SAAO;AAAA,IACL;AAAA;AAAA;AAAA,IAGA,EAAE,GAAG,GAAG,QAAQ;AAAA,IAChB;AAAA,IACAA;AAAA,EACF,EAAE;AACJ;AACA,SAAS,uBACP,GACA,QACA,SACM;AACN,QAAM,SAAS,YAAY,MAAM;AACjC,MACE,EAAE,MAAM;AAAA,IAAK,CAAC,MACZ,aAAa,CAAC,EAAE;AAAA,MACd,CAAC,MAAM,EAAE,OAAO,mBAAmB,EAAE,OAAO;AAAA,IAC9C;AAAA,EACF,KACA,QAAQ,KAAK,CAAC,MAAM,EAAE,YAAY,MAAS;AAE3C,UAAM;AAAA,MACJ;AAAA,IACF;AACF,MACE,EAAE,MAAM;AAAA,IAAK,CAAC,MACZ,aAAa,CAAC,EAAE;AAAA,MACd,CAAC,MACC,gBAAgB,EAAE,KAAK,KAAK,CAAC,qBAAqB,QAAQ,EAAE,OAAO,QAAQ,KAC3E,CAAC,OAAO,IAAI,iBAAiB,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK;AAAA,IAC5D;AAAA,EACF;AAEA,UAAM,MAAM,gDAAgD;AAC9D,MACE,QAAQ;AAAA,IACN,CAAC,MACC,gBAAgB,EAAE,KAAK,KAAK,CAAC,qBAAqB,QAAQ,EAAE,OAAO,MAAM,KACzE,CAAC,OAAO,IAAI,iBAAiB,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK;AAAA,EAC5D;AAEA,UAAM,MAAM,8DAA8D;AAC9E;AAyBA,IAAM,SAAS,CAAC,MAA4B;AAC1C,MAAI,aAAa,KAAM,QAAO,EAAE,YAAY;AAC5C,MAAI,KAAK,KAAM,QAAO;AACtB,MACE,OAAO,MAAM,YACb,OAAO,MAAM,aACZ,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;AAE3C,WAAO;AACT,QAAM,MAAM,gDAAgD;AAC9D;AAEA,SAAS,kBAAkB,OAAe,OAAuB;AAC/D,MAAI,SAAS,MAAM,SAAS;AAC5B,MAAI,SAAS;AACX,UAAM,MAAM,6CAA6C;AAC3D,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,WAAW,CAAC;AAC/B,QACE,SAAS,MACT,SAAS,MACT,SAAS,KACT,SAAS,KACT,SAAS,MACT,SAAS,MACT,SAAS;AAET;AAAA,aACO,OAAO,GAAI,WAAU;AAAA,aAE5B,QAAQ,SACR,QAAQ,SACR,IAAI,IAAI,MAAM,UACd,MAAM,WAAW,IAAI,CAAC,KAAK,SAC3B,MAAM,WAAW,IAAI,CAAC,KAAK;AAE3B;AAAA,aACO,QAAQ,SAAU,QAAQ,MAAQ,WAAU;AACrD,QAAI,SAAS;AACX,YAAM,MAAM,6CAA6C;AAAA,EAC7D;AACA,SAAO;AACT;AAEO,SAAS,oBAAoB,GAAgB,GAAwB;AAC1E,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,OAAO,MAAM,OAAO,EAAG,QAAO,OAAO,IAAI,OAAO,IAAI,KAAK;AAC7D,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAClD,UAAM,KAAK,MAAM,KAAK,CAAC,GACrB,KAAK,MAAM,KAAK,CAAC;AACnB,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK;AACvD,YAAM,OAAO,GAAG,CAAC,EAAG,YAAY,CAAC,IAAK,GAAG,CAAC,EAAG,YAAY,CAAC;AAC1D,UAAI,KAAM,QAAO,KAAK,KAAK,IAAI;AAAA,IACjC;AACA,WAAO,KAAK,KAAK,GAAG,SAAS,GAAG,MAAM;AAAA,EACxC;AACA,SAAO,IAAI,IAAI,KAAK;AACtB;AACO,SAAS,gBACd,MACA,GACA,QACAA,WAAwC,CAAC,GACtB;AACnB,MAAI,EAAE,UAAU;AACd,QAAI;AACF,UAAIA,SAAQ,QAAQ,QAAS,OAAM,IAAI,MAAM,8BAA8B;AAC3E,UAAI,KAAK,UAAUA,SAAQ,WAAW,KAAY,OAAM,IAAI,MAAM,6BAA6B;AAC/F,YAAME,OAAM,eAAeF,QAAO;AAClC,YAAM,WAAW,gBAAgB,MAAM,QAAQ,EAAE,UAAU,EAAE,KAAAE,KAAI,CAAC;AAClE,aAAO,gBAAgB,SAAS,MAAM,gBAAgB,CAAC,GAAG,SAAS,QAAQ;AAAA,QACzE,GAAGF;AAAA,QAAS,KAAAE;AAAA,MACd,CAAmD;AAAA,IACrD,SAAS,OAAO;AACd,aAAO,EAAE,UAAU,EAAE,gBAAgB,CAAC,GAAG,IAAI,aAAW,EAAE,IAAI,OAAO,IAAI,SAAS,CAAC,GAAG,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,EAAE,EAAE;AAAA,IAC1J;AAAA,EACF;AACA,QAAM,MAAM,eAAeF,QAAO,GAChC,SAAS,YAAY,MAAM;AAC7B,MAAI;AACJ,MAAI;AACJ,SAAO;AAAA,IACL,UAAU,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAAC,MAAM;AACzC,UAAI,SAASA,SAAQ,iBAAiB;AACtC,YAAM,OAAO,MAAM;AACjB,YAAI,EAAE,SAAS,EAAG,OAAM,MAAM,mCAAmC;AACjE,YAAIA,SAAQ,QAAQ;AAClB,gBAAM,MAAM,8BAA8B;AAAA,MAC9C;AACA,UAAI;AACF,YAAIA,SAAQ,QAAQ;AAClB,gBAAM,MAAM,8BAA8B;AAC5C,+BAAuB,GAAG,MAAM;AAChC,aAAK,EAAE,cAAc,UAAU,KAAK;AAClC,gBAAM,MAAM,iCAAiC;AAC/C,cAAM,cAAc,eAAe,GAAG,QAAQA,SAAQ,eAAe;AACrE,YAAI,YAAY;AACd,gBAAM,MAAM,YAAY,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC;AACzD,cAAM,KAAK,YAAY,GAAG,QAAQA,SAAQ,eAAe;AACzD,YAAI,GAAG,KAAK,QAAQ,KAAK,CAACA,SAAQ;AAChC,gBAAM;AAAA,YACJ;AAAA,UACF;AACF,YAAI;AACJ,YAAI,EAAE,UAAU;AACd,sBAAY,kBAAU,sBAAsB,MAAM,GAAG,QAAQA,QAAO;AAAA,aACjE;AACH,cAAI,CAAC,UAAU;AACb,mCAAuB,GAAG,QAAQ,CAAC,CAAC;AACpC,gBAAI,KAAK,UAAUA,SAAQ,WAAW;AACpC,oBAAM,MAAM,6BAA6B;AAC3C,uBAAW;AAAA,cACT;AAAA,cACA,EAAE,GAAG,GAAG,SAAS,CAAC,GAAG,QAAQ,GAAG,OAAO,OAAO,iBAAiB;AAAA,cAC/D;AAAA,cACA,EAAE,IAAI;AAAA,YACR,EAAE;AAAA,UACJ;AACA,sBAAY;AAAA,QACd;AACA,YAAI,UAAU,UAAUA,SAAQ,WAAW;AACzC,gBAAM,MAAM,6BAA6B;AAG3C,cAAM,aAAa,UAAU;AAC7B,YAAI,EAAE,OAAO;AACX,sBAAY;AAAA,YACV;AAAA,YACA;AAAA,cACE,GAAG;AAAA,cACH,OAAO,EAAE;AAAA,cACT,OAAO,OAAO;AAAA,YAChB;AAAA,YACA;AAAA,YACA,EAAE,IAAI;AAAA,UACR,EAAE;AACJ,cAAM,SAAS,oBAAI,IAAkD;AACrE,cAAM,WAAWA,SAAQ,qBAAqB,OAC5C,YAAYA,SAAQ,iBAAiB;AACvC,YACE,CAAC,CAAC,UAAU,SAAS,EAAE,MAAM,CAAC,MAAM,OAAO,cAAc,CAAC,KAAK,KAAK,CAAC;AAErE,gBAAM,MAAM,0BAA0B;AACxC,YAAI,aAAa;AACjB,cAAM,UAAU,CAAC,UAAkB;AACjC,cAAI,QAAQ,YAAY;AACtB,kBAAM,MAAM,kDAAkD;AAAA,QAClE;AACA,YAAI,CAAC,EAAE,QAAQ,QAAQ;AACrB,cAAI,WAAW;AACb,kBAAM,MAAM,6CAA6C;AAC3D,kBAAQ,GAAG;AACX,uBAAa;AACb,iBAAO,IAAI,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,QACzC;AAKA,YAAI,YAAY,UACd,UAAU,WACV,UAAU;AACZ,YAAI,WACF,WAAW;AACb,mBAAW,OAAO,WAAW;AAC3B,eAAK;AACL,cAAI,CAAC,EAAE,QAAQ,QAAQ;AACrB,oBAAQ,EAAE;AACV,0BAAc;AACd,mBAAO,IAAI,IAAI,EAAG,KAAK,KAAK,GAAG;AAC/B;AAAA,UACF;AACA,gBAAM,OAAO,EAAE,QAAQ;AAAA,YAAI,CAAC,MAC1B;AAAA,cACE;AAAA,gBACE,OAAO,IAAI,iBAAiB,QAAQ,CAAC,KAAK,CAAC;AAAA,gBAC3C;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,cAAI,EAAE,gBAAgB,KAAK,CAAC,MAAM,MAAM;AACtC,kBAAM,SAAS,EAAE;AAGjB,gBAAI,KAAK,CAAC,MAAM,WAAW;AACzB,yBAAW,eAAe,KAAK,CAAC,GAAI,OAAO,QAAQ;AACnD,0BAAY,KAAK,CAAC;AAAA,YACpB;AACA,gBAAI,WAAW,aAAa,YAAY,SAAS;AAC/C,0BAAY;AAAA,gBACV;AAAA,gBACA,OAAO;AAAA,gBACP,OAAO;AAAA,cACT;AACA,wBAAU;AAAA,gBACR;AAAA,gBACA,OAAO;AAAA,gBACP,OAAO;AAAA,cACT;AACA,wBAAU,IAAI,KAAK,SAAS,EAAE,YAAY;AAAA,YAC5C;AACA,iBAAK,CAAC,IAAI;AAAA,UACZ;AAIA,cAAI,YAAY,GACd,eAAe;AACjB,qBAAW,SAAS,MAAM;AACxB,yBACE,KACC,OAAO,UAAU,WACd,kBAAkB,OAAO,WAAW,YAAY,CAAC,IACjD,UAAU,OACR,IACA,OAAO,UAAU,YACf,QACE,IACA,IACF,OAAO,KAAK,EAAE;AACxB,4BAAgB,OAAO,UAAU,WAAW,IAAI,MAAM,SAAS;AAC/D,gBAAI,YAAY;AACd,oBAAM,MAAM,6CAA6C;AAAA,UAC7D;AACA,gBAAM,gBACJ,MAAM,KAAK,KAAK,SAAS,eAAe,IAAI;AAG9C,kBAAQ,gBAAgB,IAAI,YAAY,EAAE;AAC1C,gBAAM,MAAM,KAAK,UAAU,IAAI;AAC/B,cAAI,IAAI,OAAO,IAAI,GAAG;AACtB,cAAI,CAAC,GAAG;AACN,gBAAI,OAAO,SAASA,SAAQ,aAAa;AACvC,oBAAM,MAAM,+BAA+B;AAC7C,gBAAI,EAAE,MAAM,MAAM,CAAC,EAAE;AACrB,mBAAO,IAAI,KAAK,CAAC;AACjB,0BAAc;AAAA,UAChB;AACA,wBAAc;AACd,YAAE,KAAK,KAAK,GAAG;AAAA,QACjB;AACA,YAAI,EAAE,cAAc,cAAc;AAChC,gBAAM,SAAS,EAAE;AACjB,gBAAM,WAAqB,CAAC;AAC5B,gBAAM,SAAS,oBAAI,IAA2B;AAC9C,qBAAW,SAAS,OAAO,OAAO;AAChC,gBAAI,MAAM,KAAK,CAAC,MAAM,MAAM;AAC1B,mBAAK;AACL,sBAAQ,CAAC;AACT,4BAAc;AACd,uBAAS,KAAK,eAAe,MAAM,KAAK,CAAC,CAAE,CAAC;AAC5C,oBAAM,QAAQ,MAAM,KAAK,MAAM,CAAC;AAChC,oBAAM,MAAM,KAAK,UAAU,KAAK;AAChC,kBAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,sBAAM,QAAQ,MAAM,KAAK,MAAM,SAAS,IAAI,IAAI;AAChD,wBAAQ,KAAK;AACb,8BAAc;AACd,uBAAO,IAAI,KAAK,KAAK;AAAA,cACvB;AAAA,YACF;AACF,cAAI,EAAE,QAAQ,WAAW,KAAK,CAAC,OAAO,MAAM;AAC1C,oBAAQ,GAAG;AACX,0BAAc;AACd,mBAAO,IAAI,MAAM,CAAC,CAAC;AAAA,UACrB;AACA,gBAAM,QAAQ;AAAA,YACZ;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,CAAC,SAAS,iBAAiB,QAAQ,IAAI,KAAK;AAAA,UAC9C;AACA,cAAI;AACF,qBAAS,OAAO,MAAM,CAAC,GAAG,QAAQ,MAAM,CAAC,KAAK;AAC5C,mBAAK;AACL,yBAAW,SAAS,OAAO,OAAO,GAAG;AACnC,qBAAK;AACL,sBAAM,OAAsB;AAAA,kBAC1B,IAAI,KAAK,IAAI,EAAE,YAAY;AAAA,kBAC3B,GAAG;AAAA,gBACL;AACA,sBAAM,MAAM,KAAK,UAAU,IAAI;AAC/B,oBAAI,IAAI,SAAS;AACf,wBAAM,MAAM,6CAA6C;AAC3D,oBAAI,CAAC,OAAO,IAAI,GAAG,GAAG;AACpB,sBAAI,OAAO,SAASA,SAAQ,aAAa;AACvC,0BAAM,MAAM,+BAA+B;AAC7C,wBAAM,QAAQ,MAAM,KAAK,KAAK,SAAS,IAAI,IAAI;AAC/C,0BAAQ,KAAK;AACb,gCAAc;AACd,yBAAO,IAAI,KAAK,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,gBACpC;AAAA,cACF;AACA,oBAAM,OAAO;AAAA,gBACX;AAAA,gBACA,OAAO;AAAA,gBACP,OAAO;AAAA,cACT;AACA,kBAAI,CAAC,OAAO,SAAS,IAAI,KAAK,QAAQ;AACpC,sBAAM,MAAM,wCAAwC;AACtD,qBAAO;AAAA,YACT;AAAA,QACJ;AACA,cAAM,SAAS,CACb,KACA,MAEA,OAAO;AAAA,UACL,EAAE,aAAa,IAAI,CAAC,SAAS;AAAA,YAC3B;AAAA,aACC,MAAM;AACL,oBAAM,QAAQ,eAAe,OAAO,IAAI,IAAI,GAAI,GAAG;AACnD,qBAAO,iBAAiB,OACpB,MAAM,YAAY,IACjB,SAAS;AAAA,YAChB,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AACF,cAAM,YAAY,oBAAI,IAAyB;AAC/C,cAAM,OAAO,CAAC,MAA2B;AACvC,gBAAM,QAAQ,UAAU,IAAI,CAAC;AAC7B,cAAI,UAAU,OAAW,QAAO;AAChC,gBAAM,QACJ,KACC,EAAE,SAAS,SAAS,EAAE,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI;AACjE,oBAAU,IAAI,GAAG,KAAK;AACtB,iBAAO;AAAA,QACT;AACA,cAAM,UAAU,CAAC,MAAmB,KAAU,MAAmB;AAC/D,oBAAU,KAAK,IAAI;AACnB,eAAK;AAGL,cAAI,KAAK,SAAS,SAAS;AACzB,kBAAM,QAAQ,eAAe,OAAO,IAAI,KAAK,IAAI,GAAI,GAAG;AACxD,mBAAO,eAAe,MAAM;AAAA,cAC1B,CAAC,KAAK,IAAI,GACR,iBAAiB,OACb,MAAM,YAAY,IAChB,SAAS;AAAA,YACnB,CAAC;AAAA,UACH;AACA,iBAAOA,SAAQ,iBAAiB,SAAS,EAAE,GAAG,GAAG,KAAK,KAAK,CAAC,IACxDA,SAAQ,cAAc,MAAM,KAAK,CAAC,IAClC,eAAe,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,QACzC;AACA,cAAM,SAAS,CACb,GACA,IACA,gBACkB;AAClB,gBAAM,QAAQ,oBAAI,IAAgC;AAClD,iBAAO;AAAA,YACL,eAAe,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS;AAClC,kBAAI,CAAC,WAAW,IAAI,KAAK,IAAI,EAAG,QAAO;AACvC,kBAAI,MAAM,IAAI,IAAI,EAAG,QAAO,MAAM,IAAI,IAAI;AAC1C,kBAAI;AACJ,kBAAI;AACF,0BAAU,UAAoC;AAC5C,2BAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,yBAAK;AACL,0BAAM,IAAI,KAAK,KAAK,CAAC,IACjB,QAAQ,KAAK,KAAK,CAAC,GAAG,GAAG,CAAC,GAAI,CAAC,IAC/B,EAAE,OAAO,EAAE;AACf,wBAAI,EAAE,MAAO,aAAY,IAAI,CAAC;AAC9B,0BAAM;AAAA,kBACR;AAAA,gBACF;AACA,yBAAS,cAAc,MAAM,QAAQ,GAAGA,QAAO;AAAA,cACjD,SAAS,GAAG;AACV,yBAAS;AAAA,kBACP,OAAO;AAAA,kBACP,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,gBAClD;AAAA,cACF;AACA,oBAAM,IAAI,MAAM,MAAM;AACtB,qBAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,cAAc,oBAAI,IAAiC;AACzD,YAAI,UAA+B,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM;AACjE,gBAAM,SAA4B;AAAA,YAChC,MAAM,EAAE;AAAA,YACR,OAAO,EAAE,KAAK;AAAA,YACd,OAAO;AAAA,UACT;AACA,cAAI,mBAAmB,CAAC,GAAG;AACzB,kBAAM,SAAmB,CAAC;AAC1B,mBAAO,YAAY;AACnB,mBAAO,kBAAkB;AACzB,uBAAW,OAAO,EAAE,MAAM;AACxB,oBAAM,IAAI,oBAAoB,QAAQ,GAAG,CAAC,EAAG,KAAK,KAAK,GAAG,CAAC,CAAE,CAAC;AAC9D,kBAAI,EAAE,OAAO;AACX,uBAAO;AACP,uBAAO,QAAQ,EAAE;AAAA,cACnB,WAAW,EAAE,UAAU,KAAM,QAAO;AAAA,kBAC/B,QAAO,KAAK,OAAO,EAAE,KAAK,CAAC;AAAA,YAClC;AACA,wBAAY,IAAI,QAAQ,MAAM;AAAA,UAChC,OAAO;AACL,gBAAI,EAAE,gBAAgB,CAAC,EAAE,KAAK,QAAQ;AACpC,oBAAMG,SAAQ,CAAC,MACb,EAAE,IAAI,SAAS,UACf,CAAC,SAAS,kBAAkB,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,IAClD,IACA;AACN,qBAAO,QAAQA,OAAM,GAAG,CAAC,CAAE;AAC3B,kBAAI,GAAG,CAAC,EAAG,QAAO,IAAIA,OAAM,GAAG,CAAC,CAAC;AACjC,qBAAO;AAAA,YACT;AACA,kBAAM,cAAc,oBAAI,IAAY;AACpC,kBAAM,IAAI,OAAO,GAAG,CAAC,GAAI,EAAE,MAAM,WAAW;AAC5C,mBAAO,QAAQ,OAAO,EAAE,KAAK;AAC7B,gBAAI,EAAE,MAAO,QAAO,QAAQ,EAAE;AAC9B,gBAAI,GAAG,CAAC,GAAG;AACT,oBAAM,IAAI,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,WAAW;AAC3C,qBAAO,IAAI,OAAO,EAAE,KAAK;AACzB,kBAAI,EAAE,MAAO,QAAO,SAAS,EAAE;AAAA,YACjC;AACA,gBAAI,YAAY,KAAM,QAAO,kBAAkB,YAAY;AAAA,UAC7D;AACA,iBAAO;AAAA,QACT,CAAC;AACD,YAAI,mBAAmB,CAAC,GAAG;AACzB,gBAAM,IAAI,EAAE;AACZ,cAAI,EAAE,SAAS,eAAe,QAAQ,KAAK,CAAC,MAAM,EAAE,KAAK;AACvD,kBAAM;AAAA,cACJ;AAAA,YACF;AACF,gBAAM,MAAgB,CAAC;AACvB,qBAAW,UAAU,YAAY,OAAO;AACtC,uBAAW,KAAK,OAAQ,KAAI,KAAK,CAAC;AACpC,gBAAM,QACJ,EAAE,SAAS,cAAc,eAAe,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC;AAChE,qBAAW,KAAK,SAAS;AACvB,kBAAM,KAAK,YAAY,IAAI,CAAC;AAC5B,gBAAI,EAAE,MAAO;AACb,gBAAI,EAAE,SAAS,OAAO;AACpB,oBAAM,UAAU,WAAW,IAAI,EAAE,QAAQ;AACzC,gBAAE,eAAe,EAAE,MAAM,OAAO,QAAQ;AACxC,gBAAE,QAAQ,SAAS,UAAU;AAAA,YAC/B,OAAO;AACL,gBAAE,eAAe;AAAA,gBACf,MAAM;AAAA,gBACN,OAAO,CAAC,GAAG,KAAK;AAAA,gBAChB,QAAQ,gBAAgB,IAAI,KAAK;AAAA,gBACjC,GAAG,GAAG;AAAA,cACR;AACA,gBAAE,QAAQ,GAAG;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAGA,YAAI;AACJ,YAAI,EAAE,aAAa,QAAW;AAC5B,gBAAM,OAAO,QAAQ;AAAA,YACnB,CAAC,MAAM,EAAE,UAAU,KAAK,EAAE,SAAS,EAAE;AAAA,UACvC;AACA,yBAAe,QAAQ,SAAS,KAAK;AACrC,oBAAU;AAAA,QACZ;AACA,cAAM,WAAyB,EAAE,MAAM,SACnC,EAAE,OACF,EAAE,eACA,CAAC,EAAE,KAAK,UAAU,KAAK,OAAO,OAAO,OAAO,CAAC,IAC7C,CAAC,EAAE,KAAK,SAAS,KAAK,QAAQ,OAAO,OAAO,CAAC;AACnD,cAAM,SAAS,CAAC,GAAsB,MACpC,EAAE,QAAQ,YACN,EAAE,SAAS,EAAE,aAAa,MAAM,EAAE,mBAAmB,KACrD,EAAE,IAAI,WAAW,OAAO,IACrB,EAAE,KAAK,OAAO,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,OACnC,EAAE,QAAQ,UACR,EAAE,QACF,EAAE,QAAQ,MACP,EAAE,KAAK,OACR,EAAE;AACd,gBAAQ,KAAK,CAAC,GAAG,MAAM;AACrB,cAAI,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE;AAC9C,mBAAO,EAAE,SAAS,EAAE,SAAS,IAAI;AACnC,qBAAW,KAAK,UAAU;AACxB,kBAAM,KAAK,OAAO,GAAG,CAAC,GACpB,KAAK,OAAO,GAAG,CAAC;AAClB,kBAAM,MACJ,OAAO,QAAQ,OAAO,OAClB,OAAO,KACL,KACC,OAAO,OAAO,IAAI,OAAO,EAAE,UAAU,UAAU,KAAK,KACvD,oBAAoB,IAAI,EAAE,KAAK,EAAE,QAAQ,QAAQ,IAAI;AAC3D,gBAAI,IAAK,QAAO;AAAA,UAClB;AACA,mBAAS,IAAI,GAAG,IAAI,EAAE,KAAK,QAAQ,KAAK;AACtC,kBAAM,MAAM,oBAAoB,EAAE,KAAK,CAAC,GAAI,EAAE,KAAK,CAAC,CAAE;AACtD,gBAAI,IAAK,QAAO;AAAA,UAClB;AACA,iBAAO;AAAA,QACT,CAAC;AACD,aAAK;AACL,cAAM,aAAa,QAAQ;AAC3B,YAAI;AACJ,YAAI,EAAE,cAAc,QAAQ,SAAS,EAAE,YAAY;AACjD,gBAAM,UAAU,QAAQ,MAAM,EAAE,UAAU,GACxC,MAAM,GAAG,CAAC,EAAG;AACf,cACE,CAAC,mBAAmB,CAAC,KACrB,IAAI,SAAS,UACb,CAAC,OAAO,OAAO,EAAE,SAAS,IAAI,IAAI,KAClC,QAAQ;AAAA,YACN,CAAC,MACC,CAAC,EAAE,UACF,OAAO,EAAE,UAAU,YACjB,IAAI,SAAS,SAAS,EAAE,UAAU;AAAA,UACzC,GACA;AACA,kBAAM,QAAQ,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,KAAK,GAAG,CAAC;AAC7D,gBACE,OAAO,SAAS,KAAK,MACpB,CAAC,OAAO,UAAU,KAAK,KAAK,OAAO,cAAc,KAAK;AAEvD,sBAAQ;AAAA,gBACN,MAAM,CAAC;AAAA,gBACP;AAAA,gBACA,OAAO,QAAQ,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,OAAO,CAAC;AAAA,cAChD;AAAA,UACJ;AACA,oBAAU,QAAQ,MAAM,GAAG,EAAE,UAAU;AAAA,QACzC;AACA,eAAO;AAAA,UACL,IAAI,EAAE;AAAA,UACN;AAAA,UACA,OAAO,EAAE,SAAS;AAAA,UAClB,eAAe;AAAA,UACf;AAAA,UACA,UAAU;AAAA,UACV,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,UACrD,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,QAC3B;AAAA,MACF,SAAS,GAAG;AACV,eAAO;AAAA,UACL,IAAI,EAAE;AAAA,UACN,SAAS,CAAC;AAAA,UACV,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,QAClD;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACh5CO,SAAS,WACd,MACA,GACA,QACAC,WAAkC,CAAC,GACjB;AAClB,QAAM,MAAM,eAAeA,QAAO;AAClC,MAAI,EAAE,UAAU;AACd,UAAM,UAAU,gBAAgB,MAAM,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC;AAGjE,WAAO,WAAW,QAAQ,MAAM,gBAAgB,CAAC,GAAG,QAAQ,QAAQ,EAAE,IAAI,CAAC;AAAA,EAC7E;AACA,QAAM,SAAS,YAAY,MAAM;AACjC,QAAMC,gBAAe,CAAC,SAAiB,iBAAiB,QAAQ,IAAI,KAAK;AAIzE,QAAM,aAAa,EAAE,MAClB,OAAO,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,KAAK,CAAC,MAAM,gBAAgB,EAAE,KAAK,KAAK,CAAC,qBAAqB,QAAQ,EAAE,OAAO,QAAQ,CAAC,CAAC,EAC9H,IAAI,CAAC,SAAS,iBAAiB,MAAMA,eAAc,GAAG,CAAC;AAC1D,4BAA0B,YAAY,MAAM;AAC5C,QAAM,UAAU,EAAE,QACf,OAAO,CAAC,SAAS,CAAC,gBAAgB,KAAK,KAAK,KAAK,qBAAqB,QAAQ,KAAK,OAAO,MAAM,CAAC,EACjG,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,OAAOA,cAAa,KAAK,KAAK,EAAE,EAAE;AAE/D,MAAI,MAAM,KAAK;AAAA,IAAO,CAAC,QACrB,WAAW,MAAM,CAAC,SAAS,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,EAC3D;AACA,QAAM,QAAQ,IAAI;AAElB,MAAI,QAAQ,QAAQ;AAClB,UAAM,QAAQ,QACX,IAAI,CAAC,OAAO;AAAA,MACX,OAAO,OAAO,IAAI,EAAE,KAAK;AAAA,MACzB,KAAK,EAAE;AAAA,MACP,YAAY,EAAE,SAAS,YAAY;AAAA,MACnC,SAAS,aAAa,EAAE,SAAS,KAAK;AAAA,IACxC,EAAE,EACD;AAAA,MACC,CACE,MAMG,EAAE,SAAS;AAAA,IAClB;AACF,UAAM,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM;AAC5B,iBAAW,KAAK,OAAO;AACrB,cAAM,KAAK,iBAAiB,eAAe,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO;AACjE,cAAM,KAAK,iBAAiB,eAAe,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO;AACjE,cAAM,QAAQ,MAAM;AACpB,cAAM,QAAQ,MAAM;AACpB,YAAI,SAAS,OAAO;AAClB,cAAI,SAAS,MAAO;AACpB,kBAAQ,QAAQ,IAAI,OAAO,EAAE,YAAY,IAAI;AAAA,QAC/C;AACA,cAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,YAAI,QAAQ,EAAG,QAAO,EAAE,QAAQ,QAAQ,MAAM,CAAC;AAAA,MACjD;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,EAAE,SAAS,IAAI,EAAE,SAAS;AACxC,QAAM,MAAM,EAAE,QAAQ,IAAI,QAAQ,EAAE,QAAQ,IAAI;AAChD,SAAO,EAAE,MAAM,IAAI,MAAM,OAAO,GAAG,GAAG,MAAM;AAC9C;AAIO,SAAS,qBAAqB,QAAqB,MAAc,WAAuC;AAC7G,QAAM,QAAQ,OAAO,OAAO,KAAK,CAAAC,WAASA,OAAM,SAAS,IAAI;AAC7D,SAAO,CAAC,CAAC,UAAU,MAAM,OAAO,SAAS,aAAa,MAAM,SAAS,GAAG,YAAY,SAAS,MAAM,SAAS,GAAG,YAAY;AAC7H;AAGO,SAAS,cACd,KACA,QACA,QACAF,WAAkC,CAAC,GAC1B;AACT,QAAM,QAAQ,iBAAiB,QAAQ,OAAO,KAAK,KAAK,OAAO;AAC/D,QAAM,SAAS,YAAY,MAAM;AACjC,QAAM,WAAW;AAAA,IACf,EAAE,GAAG,QAAQ,MAAM;AAAA,IACnB,eAAeA,QAAO;AAAA,EACxB;AACA,4BAA0B,CAAC,EAAE,MAAM,OAAO,WAAW,SAAS,CAAC,GAAG,MAAM;AACxE,SAAO,YAAY,QAAQ,KAAK,QAAQ;AAC1C;AAOO,SAAS,kBACd,MACA,GACA,QACAA,WAAwC,CAAC,GACtB;AACnB,MAAI,EAAE,SAAU,QAAO,gBAAgB,MAAM,GAAG,QAAQA,QAAO;AAC/D,MACEA,SAAQ,QAAQ,WAChB,EAAE,MAAM;AAAA,IAAK,CAAC,MACZ,aAAa,CAAC,EAAE;AAAA,MACd,CAAC,MAAM,EAAE,OAAO,mBAAmB,EAAE,OAAO;AAAA,IAC9C;AAAA,EACF;AAEA,WAAO,gBAAgB,MAAM,GAAG,QAAQA,QAAO;AACjD,QAAM,YAAY,EAAE,gBAAgB,CAAC,GAAG;AAAA,IACtC,CAAC,MACC,EAAE,gBACF,EAAE,aAAa,UACf,EAAE,eAAe,UACjB,EAAE,gBAAgB,UAClB,EAAE,UAAU,UACZ,EAAE,gBACF,EAAE,QACF,EAAE,eAAe,UACjB,EAAE,UAAU,UACZ,EAAE,aAAa;AAAA,EACnB;AACA,MAAI,SAAS,QAAQ;AAEnB,SACG,EAAE,cAAc,UAAU,KAAK,MAChC,oBAAoB,CAAC,EAAE,cAAc,WAAW,EAAE,cAAc;AAEhE,aAAO,gBAAgB,MAAM,GAAG,QAAQA,QAAO;AACjD,UAAM,UAAU,EAAE,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC;AACzE,UAAM,UAAU;AAAA,MACd,GAAG;AAAA,QACD;AAAA,QACA,EAAE,GAAG,GAAG,cAAc,SAAS;AAAA,QAC/B;AAAA,QACAA;AAAA,MACF,EAAE;AAAA,MACF,GAAI,OAAO,SACP;AAAA,QACE;AAAA,QACA,EAAE,GAAG,GAAG,cAAc,OAAO;AAAA,QAC7B;AAAA,QACAA;AAAA,MACF,EAAE,UACF,CAAC;AAAA,IACP;AACA,UAAM,OAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC;AACjE,WAAO;AAAA,MACL,UAAU,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AACA,QAAM,MAAM,eAAeA,QAAO;AAClC,QAAM,SAAS,YAAY,MAAM;AACjC,QAAMC,gBAAe,CAAC,SAAiB,iBAAiB,QAAQ,IAAI,KAAK;AACzE,QAAM,aAAa,EAAE,MAClB,OAAO,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,KAAK,CAAC,MAAM,gBAAgB,EAAE,KAAK,CAAC,CAAC,EAC1E,IAAI,CAAC,SAAS,iBAAiB,MAAMA,eAAc,GAAG,CAAC;AAC1D,4BAA0B,YAAY,MAAM;AAC5C,QAAM,WAAW,KAAK;AAAA,IAAO,CAAC,QAC5B,WAAW,MAAM,CAAC,SAAS,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,EAC3D;AACA,QAAM,WAAW,EAAE,gBAAgB,CAAC,GACjC;AAAA,IACC,CAAC,MACC,CAAC,gBAAgB,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,QAAQ,KAAK,eAAe;AAAA,EACtE,EACC,IAAI,CAAC,QAAQ;AACZ,UAAM,QAAQ,IAAI,QAAQ,OAAO,IAAIA,cAAa,IAAI,KAAK,CAAC,IAAI;AAChE,QACE,UACC,CAAC,aAAa,KAAK,KAAK,CAAC,eAAe,KAAK,EAAE,SAAS,IAAI,EAAE;AAE/D,aAAO;AAAA,QACL,IAAI,IAAI;AAAA,QACR,SAAS,CAAC;AAAA,QACV,OAAO,SAAS,MAAM,IAAI,mBAAmB,IAAI,EAAE;AAAA,MACrD;AACF,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,SAAS,eAAe,UAAU,KAAK,QAAQA,aAAY;AAAA,IAC7D;AAAA,EACF,CAAC;AACH,SAAO,EAAE,QAAQ;AACnB;AAEA,SAAS,eACP,MACA,KACA,QACAA,eACqB;AAKrB,QAAM,cAAc,IAAI,QAAQ,IAAI,CAAC,MAAM,OAAO,IAAIA,cAAa,CAAC,CAAC,CAAC;AACtE,QAAM,UAAU,IAAI,QAAQ,OAAO,IAAIA,cAAa,IAAI,KAAK,CAAC,IAAI;AAElE,QAAM,SAAS,oBAAI,IAAgD;AACnE,MAAI,CAAC,IAAI,QAAQ,OAAQ,QAAO,IAAI,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAChE,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,YAAY,IAAI,CAACE,OAAM;AAClC,UAAI,CAACA,GAAG,QAAO;AACf,YAAM,IAAI,eAAeA,IAAG,GAAG;AAC/B,aAAO,KAAK,QAAQ,MAAM,KACtB,OACA,OAAO,MAAM,YACX,OAAO,MAAM,aACb,OAAO,MAAM,WACb,IACA,OAAO,CAAC;AAAA,IAChB,CAAC;AACD,UAAM,IAAI,KAAK,UAAU,IAAI;AAC7B,QAAI,IAAI,OAAO,IAAI,CAAC;AACpB,QAAI,CAAC,GAAG;AACN,UAAI,EAAE,MAAM,MAAM,CAAC,EAAE;AACrB,aAAO,IAAI,GAAG,CAAC;AAAA,IACjB;AACA,MAAE,KAAK,KAAK,GAAG;AAAA,EACjB;AAEA,QAAM,UAAU,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO;AAAA,IAC/C,MAAM,EAAE;AAAA,IACR,OAAO,EAAE,KAAK;AAAA,IACd,OAAO,SAAS,IAAI,IAAI,SAAS,EAAE,IAAI;AAAA,EACzC,EAAE;AACF,SAAO,YAAY,OAAO;AAC5B;AAEA,SAAS,SACP,IACA,SACA,MACwB;AACxB,MAAI,OAAO,SAAS;AAClB,QAAI,CAAC,QAAS,QAAO,KAAK;AAC1B,QAAI,IAAI;AACR,eAAW,KAAK,KAAM,KAAI,eAAe,SAAS,CAAC,KAAK,KAAM;AAC9D,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,SAAS,KACZ,IAAI,CAAC,MAAM,eAAe,SAAS,CAAC,CAAC,EACrC,OAAO,CAAC,MAAM,KAAK,IAAI;AAE1B,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE;AAAA,IAC/C,KAAK;AAAA,IACL,KAAK,OAAO;AACV,UAAI,MAAM;AACV,UAAI,IAAI;AACR,iBAAW,KAAK,QAAQ;AACtB,cAAM,MAAM,OAAO,MAAM,WAAW,IAAI,OAAO,CAAC;AAChD,YAAI,OAAO,SAAS,GAAG,GAAG;AACxB,iBAAO;AACP;AAAA,QACF;AAAA,MACF;AACA,UAAI,OAAO,MAAO,QAAO,IAAI,MAAM,IAAI;AACvC,aAAO,IAAI,MAAM;AAAA,IACnB;AAAA,IACA,KAAK;AAAA,IACL,KAAK,OAAO;AACV,UAAI;AACJ,iBAAW,KAAK,QAAQ;AACtB,YAAI,SAAS,QAAW;AACtB,iBAAO;AACP;AAAA,QACF;AACA,cAAM,MAAM,QAAQ,GAAG,IAAI;AAC3B,YAAI,OAAO,QAAQ,MAAM,IAAI,MAAM,EAAG,QAAO;AAAA,MAC/C;AACA,aAAQ,QAAwC;AAAA,IAClD;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,YAAY,SAAmD;AACtE,SAAO,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM;AACjC,UAAM,KAAK,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE;AACrD,UAAM,KAAK,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,EAAE;AACrD,QAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,WAAO,KAAK,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,UAAU,EAAE,IAAI,CAAC;AAAA,EACpE,CAAC;AACH;AAaA,SAAS,mBACP,QACA,KACqB;AACrB,QAAM,YACJ,OAAO,OAAO,mBAAmB,OAAO,OAAO;AACjD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,YAAY,aAAa,OAAO,KAAK,IAAI;AAAA,EAClD;AACF;AAEA,SAAS,iBACP,MACAF,eACA,KACmB;AACnB,MAAI,UAAU,IAAI,GAAG;AACnB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY,KAAK,IAAI;AAAA,QAAI,CAAC,MACxB,mBAAmB,EAAE,GAAG,GAAG,OAAOA,cAAa,EAAE,KAAK,EAAE,GAAG,GAAG;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,MACT,EAAE,GAAG,MAAM,OAAOA,cAAa,KAAK,KAAK,EAAE;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,0BACP,OACA,QACM;AACN,aAAW,QAAQ;AACjB,eAAW,KAAK,KAAK,SAAS,QAAQ,CAAC,KAAK,SAAS,IAAI,KAAK,YAAY;AACxE,YAAM,QAAQ,OAAO,IAAI,EAAE,OAAO,KAAK;AACvC,UACE,OAAO,SAAS,cAChB,EAAE,OAAO,UAAU,MACnB,EAAE,OAAO,OAAO,aAChB,EAAE,OAAO,OAAO;AAEhB;AACF,QAAE,WAAW,YAAY,YAAY,EAAE,OAAO,OAAO,EAAE,GAAG;AAAA,IAC5D;AACJ;AAIA,SAAS,YACP,QACA,KACA,MACS;AACT,MAAI,KAAK,SAAS,MAAO,QAAO,YAAY,QAAQ,KAAK,KAAK,SAAS;AAGvE,SAAO,KAAK,WAAW,KAAK,CAAC,MAAM,YAAY,QAAQ,KAAK,CAAC,CAAC;AAChE;AAEA,SAAS,YACP,QACA,KACA,UACS;AACT,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,QAAQ,OAAO,IAAI,OAAO,KAAK;AACrC,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,IAAI,eAAe,OAAO,GAAG;AAKnC,MACE,OAAO,UAAU,MACjB,OAAO,OAAO,OACd,OAAO,OAAO,QACd,OAAO,OAAO,aACd,OAAO,OAAO,eACd;AACA,WAAO;AAAA,EACT;AAEA,MACE,OAAO,OAAO,eACd,OAAO,OAAO,eACd,OAAO,OAAO,aACd;AACA,QACE,CAAC,iBAAiB,KAAK,OAAO,KAAK,KACnC,CAAC,OAAO,cAAc,OAAO,OAAO,KAAK,CAAC;AAE1C,aAAO;AAAA,EACX;AAEA,MAAI;AACJ,MAAI,SAAS,aAAa,QAAW;AACnC,UAAM,YACJ,aAAa,OACT,EAAE,QAAQ,IACV,OAAO,MAAM,WACX,IACA,OAAO,MAAM,WACX,KAAK,MAAM,CAAC,IACZ;AACV,QAAI,MAAM,MAAM,CAAC,OAAO,SAAS,SAAS,EAAG,QAAO;AACpD,WAAO,gBAAgB,WAAW,SAAS,UAAU,OAAO,EAAE;AAAA,EAChE,OAAO;AACL,WAAO,YAAY,OAAO,GAAG,QAAQ;AAAA,EACvC;AACA,MAAI,CAAC,OAAO,QAAS,QAAO;AAI5B,QAAM,SAAS,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI,KAAK,QAAQ,MAAM;AACtE,SAAO,CAAC,UAAU,CAAC;AACrB;AAEA,SAAS,gBACP,WACA,KACA,IACS;AACT,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,cAAc;AAAA,IACvB,KAAK;AACH,aAAO,cAAc;AAAA,IACvB,KAAK;AACH,aAAO,YAAY;AAAA,IACrB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB,KAAK;AACH,aAAO,YAAY;AAAA,IACrB,KAAK;AACH,aAAO,aAAa;AAAA,IACtB;AACE,aAAO;AAAA,EACX;AACF;AAIA,SAAS,YACP,OACA,GACA,UACS;AACT,QAAM,EAAE,QAAQ,MAAM,IAAI;AAG1B,MAAI,OAAO,OAAO;AAChB,WAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,WAAW,IAAI,KAAK,QAAQ,MAAM;AAChE,MAAI,OAAO,OAAO;AAChB,WAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,SAAS,IAAI,KAAK,QAAQ,MAAM;AAE9D,QAAM,YAAY,CAAC,UACjB,MAAM,QAAQ,qBACV,OAAO,KAAK,IACZ,OAAO,KAAK,EAAE,YAAY;AAIhC,MAAI,OAAO,OAAO,YAAY;AAC5B,UAAM,MAAM,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AACpC,UAAM,SAAS,UAAU,OAAO,KAAK;AACrC,WAAO,IAAI,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,MAAM;AAAA,EAChD;AAEA,MAAI,OAAO,OAAO,mBAAmB,OAAO,OAAO,qBAAqB;AACtE,QAAI,KAAK,QAAQ,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC1C,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,UAAU,MAAM,KAAK,OAAO,CAAC,CAAC;AACpC,WAAO,OAAO,OAAO,kBAAkB,UAAU,CAAC;AAAA,EACpD;AAEA,MACE,OAAO,OAAO,eACd,OAAO,OAAO,eACd,OAAO,OAAO,aACd;AACA,QAAI,OAAO,MAAM,YAAY,CAAC,iBAAiB,KAAK,OAAO,KAAK;AAC9D,aAAO;AACT,UAAM,QAAQ,OAAO,OAAO,KAAK;AACjC,QAAI,CAAC,OAAO,cAAc,KAAK,EAAG,QAAO;AACzC,UAAM,SAAS,MAAM,KAAK,CAAC,EAAE;AAC7B,WAAO,OAAO,OAAO,cACjB,SAAS,QACT,OAAO,OAAO,cACZ,SAAS,QACT,WAAW;AAAA,EACnB;AAEA,MAAI,MAAM,QAAQ,CAAC,GAAG;AACpB,UAAM,SAAS,UAAU,OAAO,KAAK;AACrC,UAAM,MAAM,EAAE,IAAI,SAAS;AAC3B,YAAQ,OAAO,IAAI;AAAA,MACjB,KAAK;AACH,eAAO,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,CAAC;AAAA,MAC3C,KAAK;AACH,eAAO,IAAI,SAAS,MAAM;AAAA,MAC5B,KAAK;AACH,eAAO,CAAC,IAAI,SAAS,MAAM;AAAA,MAC7B;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAEA,UAAQ,OAAO,IAAI;AAAA,IACjB,KAAK;AACH,aAAO,OAAO,KAAK,EAAE,MAAM,OAAO,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,IACnE,KAAK;AACH,aAAO,OAAO,KAAK,EAAE,MAAM,OAAO,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,IACnE,KAAK;AACH,aAAO,QAAQ,GAAG,WAAW,OAAO,OAAO,KAAK,CAAC,IAAI;AAAA,IACvD,KAAK;AACH,aAAO,QAAQ,GAAG,WAAW,OAAO,OAAO,KAAK,CAAC,KAAK;AAAA,IACxD,KAAK;AACH,aAAO,QAAQ,GAAG,WAAW,OAAO,OAAO,KAAK,CAAC,IAAI;AAAA,IACvD,KAAK;AACH,aAAO,QAAQ,GAAG,WAAW,OAAO,OAAO,KAAK,CAAC,KAAK;AAAA,IACxD,KAAK;AACH,aAAO,OAAO,KAAK,EAAE,EAClB,YAAY,EACZ,SAAS,OAAO,MAAM,YAAY,CAAC;AAAA,IACxC,KAAK;AACH,aAAO,OAAO,KAAK,EAAE,EAClB,YAAY,EACZ,WAAW,OAAO,MAAM,YAAY,CAAC;AAAA,IAC1C,KAAK;AACH,aAAO,OAAO,KAAK,EAAE,EAClB,YAAY,EACZ,SAAS,OAAO,MAAM,YAAY,CAAC;AAAA,IACxC;AACE,aAAO;AAAA,EACX;AACF;AAGA,SAAS,aAAa,SAAwD;AAC5E,MAAI,YAAY,OAAW,QAAO;AAClC,MAAI;AACF,WAAO,IAAI,OAAO,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,iBACP,OACA,OACS;AACT,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU,QAAQ,SAAS,KAAM,QAAO;AAC5C,QAAM,QAAQ,MAAM,KAAK,OAAO,KAAK,CAAC;AACtC,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,SAAS,IAAK,MAAM,CAAC,KAAK,OAAQ,MAAM,CAAC;AACxD;AAIA,SAAS,WAAW,OAAiB,KAAwC;AAC3E,MAAI;AACF,WAAO,YAAY,MAAM,MAAM,GAAG;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,GAAY,GAAoB;AAC/C,MAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,MAAI,KAAK,KAAM,QAAO;AACtB,MAAI,KAAK,KAAM,QAAO;AACtB,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO,IAAI;AAC/D,MAAI,OAAO,MAAM,aAAa,OAAO,MAAM;AACzC,WAAO,MAAM,IAAI,IAAI,IAAI,IAAI;AAC/B,SAAO,OAAO,CAAC,EAAE,cAAc,OAAO,CAAC,CAAC;AAC1C;;;ACtgBA,IAAM,cAAc;AACpB,IAAM,eAAe;AACrB,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAE9B,SAAS,oBAAoB,OAAmC;AAC9D,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AAC/E,QAAM,MAAM;AACZ,MACE,OAAO,IAAI,OAAO,YAClB,CAAC,IAAI,MACL,IAAI,GAAG,SAAS,OAChB,OAAO,IAAI,SAAS,YACpB,CAAC,IAAI,QACL,IAAI,KAAK,SAAS,yBAClB,OAAO,IAAI,YAAY,YACvB,CAAC,OAAO,SAAS,IAAI,OAAO,KAC5B,IAAI,SAAS,QACb,OAAO,IAAI,UAAU,UACrB;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IAAE,IAAI,IAAI;AAAA,IAAI,MAAM,IAAI;AAAA,IAAM,SAAS,IAAI;AAAA,IAAS,OAAO,oBAAoB,IAAI,KAAK;AAAA,IAC7F,GAAI,OAAO,IAAI,iBAAiB,WAAW,EAAE,cAAc,IAAI,aAAa,IAAI,CAAC;AAAA,EAAG;AACxF;AAEA,SAAS,sBAAsB,OAA8B;AAC3D,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MACJ,MAAM,GAAG,iBAAiB,EAC1B,IAAI,mBAAmB,EACvB,OAAO,CAAC,SAA6B,QAAQ,IAAI;AACtD;AAKO,SAAS,uBAAuC;AACrD,QAAM,OAAO,oBAAI,IAAwB;AACzC,QAAM,QAAQ,oBAAI,IAA0B;AAC5C,QAAM,WAAW,oBAAI,IAAoB;AAEzC,SAAO;AAAA,IACL,MAAM,SAAS,KAAK;AAClB,YAAM,QAAQ,KAAK,IAAI,GAAG;AAC1B,aAAO,QAAQ,oBAAoB,KAAK,IAAI;AAAA,IAC9C;AAAA,IACA,MAAM,SAAS,KAAK,OAAO;AACzB,WAAK,IAAI,KAAK,oBAAoB,KAAK,CAAC;AAAA,IAC1C;AAAA,IACA,MAAM,UAAU,KAAK;AACnB,cAAQ,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,oBAAoB,KAAK,KAAK,EAAE,EAAE;AAAA,IACnG;AAAA,IACA,MAAM,iBAAiB,KAAK;AAC1B,YAAM,KAAK,SAAS,IAAI,GAAG;AAC3B,aAAO,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE,KAAK,OAAO;AAAA,IAC9E;AAAA,IACA,MAAM,gBAAgB,KAAK,IAAI;AAC7B,UAAI,MAAM,MAAM;AACd,iBAAS,OAAO,GAAG;AACnB;AAAA,MACF;AACA,UAAI,EAAE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE,EAAG,OAAM,IAAI,MAAM,gBAAgB,EAAE,mBAAmB;AACjH,eAAS,IAAI,KAAK,EAAE;AAAA,IACtB;AAAA,IACA,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS,cAAc;AACvD,YAAM,iBAAiB,KAAK,KAAK;AACjC,UAAI,CAAC,kBAAkB,eAAe,SAAS,uBAAuB;AACpE,cAAM,IAAI,MAAM,0CAA0C,qBAAqB,cAAc;AAAA,MAC/F;AACA,YAAM,QAAQ,MAAM,IAAI,GAAG,KAAK,CAAC;AACjC,UAAI,MAAM,UAAU,kBAAmB,OAAM,IAAI,MAAM,WAAW,iBAAiB,6BAA6B;AAChH,UAAI,MAAM,KAAK,CAACG,UAASA,MAAK,SAAS,cAAc,EAAG,OAAM,IAAI,MAAM,gBAAgB,cAAc,mBAAmB;AACzH,YAAM,OAAmB;AAAA,QACvB,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,QACvC,IAAI,GAAG,OAAO,IAAI,KAAK,OAAO,UAAU,OAAO,SAAS,MAAM,CAAC;AAAA,QAC/D,MAAM;AAAA,QACN;AAAA,QACA,OAAO,oBAAoB,KAAK;AAAA,MAClC;AACA,YAAM,IAAI,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC;AAC/B,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YAAY,KAAK,IAAI,OAAO,SAAS,cAAc;AACvD,YAAM,QAAQ,MAAM,IAAI,GAAG,KAAK,CAAC;AACjC,YAAM,WAAW,MAAM,KAAK,CAACA,UAASA,MAAK,OAAO,EAAE;AACpD,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,gBAAgB,EAAE,mBAAmB;AACpE,YAAM,OAAmB;AAAA,QACvB;AAAA,QAAI,MAAM,SAAS;AAAA,QAAM;AAAA,QACzB,OAAO,oBAAoB,KAAK;AAAA,QAChC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,MACzC;AACA,YAAM,IAAI,KAAK,MAAM,IAAI,CAAC,UAAU,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC;AACnE,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YAAY,KAAK,IAAI;AACzB,YAAM,IAAI,MAAM,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;AACtE,UAAI,SAAS,IAAI,GAAG,MAAM,GAAI,UAAS,OAAO,GAAG;AAAA,IACnD;AAAA,EACF;AACF;AAKO,SAAS,sBAAsC;AACpD,QAAM,MAAsB,MAAM;AAChC,QAAI;AACF,aAAO,OAAO,iBAAiB,cAAc,eAAe;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AAEH,QAAM,YAAY,CAAC,QAA8B;AAC/C,QAAI,CAAC,GAAI,QAAO,CAAC;AACjB,QAAI;AACF,YAAM,MAAM,GAAG,QAAQ,eAAe,GAAG;AACzC,aAAO,sBAAsB,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,IACzD,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACA,QAAM,aAAa,CAAC,KAAa,UAA8B;AAC7D,QAAI,GAAI,IAAG,QAAQ,eAAe,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EAC9D;AACA,QAAM,gBAAgB,CAAC,QAA+B;AACpD,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO,GAAG,QAAQ,iBAAiB,GAAG;AAAA,EACxC;AACA,QAAM,iBAAiB,CAAC,KAAa,OAA4B;AAC/D,QAAI,CAAC,GAAI;AACT,QAAI,GAAI,IAAG,QAAQ,iBAAiB,KAAK,EAAE;AAAA,QACtC,IAAG,WAAW,iBAAiB,GAAG;AAAA,EACzC;AAEA,SAAO;AAAA,IACL,MAAM,SAAS,KAAK;AAClB,UAAI,CAAC,GAAI,QAAO;AAChB,UAAI;AACF,cAAM,MAAM,GAAG,QAAQ,cAAc,GAAG;AACxC,eAAO,MAAM,oBAAoB,KAAK,MAAM,GAAG,CAAC,IAAI;AAAA,MACtD,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,MAAM,SAAS,KAAK,OAAO;AACzB,UAAI,GAAI,IAAG,QAAQ,cAAc,KAAK,KAAK,UAAU,oBAAoB,KAAK,CAAC,CAAC;AAAA,IAClF;AAAA,IACA,MAAM,UAAU,KAAK;AACnB,aAAO,UAAU,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,OAAO;AAAA,IAC5D;AAAA,IACA,MAAM,iBAAiB,KAAK;AAC1B,YAAM,KAAK,cAAc,GAAG;AAC5B,UAAI,CAAC,GAAI,QAAO;AAChB,YAAM,QAAQ,UAAU,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACpD,UAAI,CAAC,MAAO,gBAAe,KAAK,IAAI;AACpC,aAAO,SAAS;AAAA,IAClB;AAAA,IACA,MAAM,gBAAgB,KAAK,IAAI;AAC7B,UAAI,MAAM,CAAC,UAAU,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG;AAClD,cAAM,IAAI,MAAM,gBAAgB,EAAE,mBAAmB;AAAA,MACvD;AACA,qBAAe,KAAK,EAAE;AAAA,IACxB;AAAA,IACA,MAAM,UAAU,KAAK,MAAM,OAAO,SAAS,cAAc;AACvD,YAAM,iBAAiB,KAAK,KAAK;AACjC,UAAI,CAAC,kBAAkB,eAAe,SAAS,uBAAuB;AACpE,cAAM,IAAI,MAAM,0CAA0C,qBAAqB,cAAc;AAAA,MAC/F;AACA,YAAM,QAAQ,UAAU,GAAG;AAC3B,UAAI,MAAM,UAAU,kBAAmB,OAAM,IAAI,MAAM,WAAW,iBAAiB,6BAA6B;AAChH,UAAI,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,cAAc,GAAG;AAChD,cAAM,IAAI,MAAM,gBAAgB,cAAc,mBAAmB;AAAA,MACnE;AACA,YAAM,OAAmB;AAAA,QACvB,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,QACvC,IAAI,GAAG,OAAO,IAAI,KAAK,OAAO,UAAU,OAAO,SAAS,MAAM,CAAC;AAAA,QAC/D,MAAM;AAAA,QACN;AAAA,QACA,OAAO,oBAAoB,KAAK;AAAA,MAClC;AACA,YAAM,KAAK,IAAI;AACf,iBAAW,KAAK,KAAK;AACrB,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YAAY,KAAK,IAAI,OAAO,SAAS,cAAc;AACvD,YAAM,QAAQ,UAAU,GAAG;AAC3B,YAAM,WAAW,MAAM,KAAK,CAACA,UAASA,MAAK,OAAO,EAAE;AACpD,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,gBAAgB,EAAE,mBAAmB;AACpE,YAAM,OAAmB;AAAA,QACvB;AAAA,QAAI,MAAM,SAAS;AAAA,QAAM;AAAA,QACzB,OAAO,oBAAoB,KAAK;AAAA,QAChC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA,MACzC;AACA,iBAAW,KAAK,MAAM,IAAI,CAAC,UAAU,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC;AACpE,aAAO;AAAA,IACT;AAAA,IACA,MAAM,YAAY,KAAK,IAAI;AACzB;AAAA,QACE;AAAA,QACA,UAAU,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,MAC1C;AACA,UAAI,cAAc,GAAG,MAAM,GAAI,gBAAe,KAAK,IAAI;AAAA,IACzD;AAAA,EACF;AACF;;;AC5SA,IAAM,QAAQ,OAAoB,EAAE,MAAM,MAAM,OAAO,CAAC,GAAG,WAAW,KAAK;AAC3E,IAAM,QAAQ,CAAC,WAAiD;AAAA,EAC9D,GAAG;AAAA,EACH,MAAM,sBAAsB,MAAM,IAAI;AACxC;AAGO,SAAS,wBACd,MACA,OACqB;AACrB,QAAM,SAAS,CAAC,SAAiB,0BAA0B,IAAI;AAC/D,WAAS,KAAK,MAA2B;AACvC,UAAM,QAAQ,KAAK,OAAO,IAAI,CAAC;AAC/B,QAAI,UAAU,KAAM,QAAO,MAAM;AACjC,UAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,QACE,CAAC,OACD,CAAC,MAAM,QAAQ,IAAI,KAAK,KACxB,IAAI,MAAM,SAAS,OACnB,EAAE,IAAI,cAAc,QAAQ,OAAO,IAAI,cAAc;AAErD,YAAM,IAAI,MAAM,+BAA+B;AACjD,UAAM,QAAQ,IAAI,MAAM,IAAI,CAAC,SAAS;AACpC,UACE,CAAC,QACD,OAAO,KAAK,OAAO,YACnB,CAAC,KAAK,MACN,OAAO,KAAK,SAAS,YACrB,CAAC,KAAK,KAAK,KAAK,KAChB,KAAK,KAAK,SAAS,OACnB,CAAC,OAAO,SAAS,KAAK,OAAO;AAE7B,cAAM,IAAI,MAAM,8BAA8B;AAChD,aAAO,MAAM,IAAI;AAAA,IACnB,CAAC;AACD,WAAO;AAAA,MACL,MAAM,IAAI,SAAS,OAAO,OAAO,sBAAsB,IAAI,IAAI;AAAA,MAC/D;AAAA,MACA,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACA,QAAM,QAAQ,CAAC,MAAc,UAC3B,MAAM,OAAO,IAAI,GAAG,KAAK,UAAU,KAAK,CAAC;AAC3C,SAAO;AAAA,IACL,MAAM,SAAS,MAAM;AACnB,aAAO,KAAK,IAAI,EAAE;AAAA,IACpB;AAAA,IACA,MAAM,SAAS,MAAM,MAAM;AACzB,YAAM,OAAO,KAAK,IAAI;AACtB,WAAK,OAAO,sBAAsB,IAAI;AACtC,YAAM,MAAM,IAAI;AAAA,IAClB;AAAA,IACA,MAAM,UAAU,MAAM;AACpB,aAAO,KAAK,IAAI,EAAE;AAAA,IACpB;AAAA,IACA,MAAM,UAAU,MAAM,MAAM,MAAM,SAAS;AACzC,aAAO,KAAK,KAAK;AACjB,UAAI,CAAC,QAAQ,KAAK,SAAS,OAAO,CAAC,OAAO,SAAS,OAAO;AACxD,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AACF,YAAM,OAAO,KAAK,IAAI;AACtB,UAAI,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACxC,cAAM,IAAI,MAAM,+BAA0B,IAAI,wBAAmB;AACnE,UAAI,KAAK,MAAM,UAAU;AACvB,cAAM,IAAI,MAAM,+CAA+C;AACjE,UAAI,SAAS;AACb,aAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI,MAAM,EAAE,EAAG;AAChE,YAAM,QAAQ;AAAA,QACZ,IAAI,GAAG,OAAO,IAAI,MAAM;AAAA,QACxB;AAAA,QACA;AAAA,QACA,MAAM,sBAAsB,IAAI;AAAA,MAClC;AACA,WAAK,MAAM,KAAK,KAAK;AACrB,YAAM,MAAM,IAAI;AAChB,aAAO,MAAM,KAAK;AAAA,IACpB;AAAA,IACA,MAAM,YAAY,MAAM,IAAI;AAC1B,YAAM,OAAO,KAAK,IAAI;AACtB,WAAK,QAAQ,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACjD,UAAI,KAAK,cAAc,GAAI,MAAK,YAAY;AAC5C,YAAM,MAAM,IAAI;AAAA,IAClB;AAAA,IACA,MAAM,iBAAiB,MAAM;AAC3B,YAAM,OAAO,KAAK,IAAI;AACtB,aAAO,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,SAAS,KAAK;AAAA,IAC5D;AAAA,IACA,MAAM,gBAAgB,MAAM,IAAI;AAC9B,YAAM,OAAO,KAAK,IAAI;AACtB,UAAI,OAAO,QAAQ,CAAC,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACpD,cAAM,IAAI,MAAM,wBAAwB;AAC1C,WAAK,YAAY;AACjB,YAAM,MAAM,IAAI;AAAA,IAClB;AAAA,EACF;AACF;AACO,SAAS,4BAAiD;AAC/D,QAAM,SAAS,oBAAI,IAAoB;AACvC,SAAO;AAAA,IACL,CAAC,QAAQ,OAAO,IAAI,GAAG,KAAK;AAAA,IAC5B,CAAC,KAAK,UAAU;AACd,aAAO,IAAI,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AACF;AAEO,SAAS,2BAAgD;AAC9D,SAAO;AAAA,IACL,CAAC,QAAQ,aAAa,QAAQ,GAAG;AAAA,IACjC,CAAC,KAAK,UAAU,aAAa,QAAQ,KAAK,KAAK;AAAA,EACjD;AACF;;;AC9HO,SAAS,mBAAwB,OAAmB,QAA0B,iBAAiF;AACpK,QAAM,SAAS,oBAAI,IAAY,CAAC,OAAO,OAAO,CAAC;AAC/C,QAAM,UAAU,CAAC,SAAiB;AAChC,WAAO,IAAI,IAAI;AACf,UAAM,YAAY,OAAO,OAAO,KAAK,WAAS,MAAM,SAAS,IAAI,GAAG,MAAM;AAC1E,QAAI,UAAW,QAAO,IAAI,SAAS;AAAA,EACrC;AACA,QAAM,SAAS,MAAM,UAAU,UAAU;AACzC,aAAW,QAAQ,OAAO,MAAO,YAAW,aAAa,aAAa,IAAI,EAAG,QAAO,IAAI,UAAU,KAAK;AACvG,MAAI,MAAM,UAAU;AAClB,UAAM,QAAQ,oBAAoB,MAAM;AACxC,UAAM,SAAS,MAAM,QAAQ;AAC7B,eAAW,OAAO,MAAM,SAAS,KAAM,QAAO,IAAI,GAAG;AACrD,eAAW,WAAW,MAAM,SAAS,WAAW;AAE9C,UAAI,QAAQ,OAAO,OAAQ;AAC3B,UAAI,QAAQ,OAAO,MAAO,QAAO,IAAI,QAAQ,KAAM;AAAA,UAC9C,YAAW,cAAc,cAAc,MAAM,kBAAkB,OAAO,GAAG,QAAQ,eAAe,EAAE,aAAc,QAAO,IAAI,UAAU;AAAA,IAC5I;AACA,eAAW,QAAQ,MAAM,SAAS,gBAAgB,WAAW,CAAC,EAAG,SAAQ,KAAK,KAAK;AAAA,EACrF,OAAO;AACL,eAAW,UAAU,OAAO,OAAQ,KAAI,OAAO,UAAU,oBAAqB,QAAO,IAAI,OAAO,KAAK;AACrG,eAAW,QAAQ,OAAO,QAAS,SAAQ,KAAK,KAAK;AACrD,eAAW,UAAU,OAAO,gBAAgB,CAAC,EAAG,YAAW,cAAc,mBAAmB,QAAQ,QAAQ,eAAe,EAAG,QAAO,IAAI,UAAU;AAAA,EACrJ;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,QAAQ,CAAC,SAAiB;AAC9B,QAAI,SAAS,IAAI,IAAI,EAAG,OAAM,MAAM,0BAA0B;AAC9D,UAAM,QAAQ,OAAO,OAAO,KAAK,CAAAC,WAASA,OAAM,SAAS,IAAI;AAC7D,QAAI,CAAC,SAAS,SAAS,OAAO,SAAS;AAAE,WAAK,IAAI,IAAI;AAAG;AAAA,IAAQ;AACjE,UAAM,eAAe,OAAO,OAAO,SAAS,YAAY,MAAM,OAAO,eAAe,kBAAkB,IAAI,GAAG;AAC7G,QAAI,CAAC,SAAS,CAAC,aAAc,OAAM,MAAM,kCAAkC,IAAI,GAAG;AAClF,QAAI,cAAc,QAAQ;AACxB,eAAS,IAAI,IAAI;AACjB,iBAAW,cAAc,aAAc,OAAM,UAAU;AACvD,eAAS,OAAO,IAAI;AAAA,IACtB,MAAO,MAAK,IAAI,IAAI;AAAA,EACtB;AACA,aAAW,QAAQ,OAAQ,OAAM,IAAI;AACrC,QAAM,QAAQ,OAAO,YAAY,CAAC,GAAG,IAAI,EAAE,IAAI,UAAQ;AACrD,UAAM,QAAQ,OAAO,OAAO,KAAK,CAAAA,WAASA,OAAM,SAAS,IAAI;AAC7D,WAAO,CAAC,MAAM,OAAO,OAAO,SAAS,YAAY,MAAM,OAAO,QAAQ,OAAO,IAAI;AAAA,EACnF,CAAC,CAAC;AACF,SAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG,YAAY,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG,UAAU,OAAO,SAAS,MAAM;AACrG;;;ACdA,SAAS,UAAU,QAA6B;AAC9C,SAAO,KAAK,UAAU;AAAA,IACpB,OAAO;AAAA,IACP,OAAO;AAAA,IACP,YAAY,IAAI,OAAO,EAAE,IAAI,KAAK,OAAO;AAAA,IACzC,OAAO,YAAY;AAAA,EACrB,CAAC;AACH;AAIO,SAAS,aAAa,MAAyB;AACpD,MAAI,CAAC,UAAU,IAAI,EAAG,QAAO,UAAU,IAAI;AAC3C,SAAO,OAAO,KAAK,UAAU,KAAK,IAAI,IAAI,SAAS,EAAE,KAAK,CAAC,CAAC;AAC9D;AAGO,SAAS,iBAAiB,OAA6B,OAA0C;AACtG,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,YAAY,CAAC;AAC/C,QAAM,MAAM,CAAC,GAAG,KAAK;AACrB,aAAW,QAAQ,OAAO;AACxB,UAAM,MAAM,aAAa,IAAI;AAC7B,QAAI,QAAQ,IAAI,GAAG,EAAG;AACtB,YAAQ,IAAI,GAAG;AACf,QAAI,KAAK,IAAI;AAAA,EACf;AACA,SAAO;AACT;AAIA,SAAS,YAAY,OAA4C;AAC/D,QAAM,QAAuB,CAAC;AAC9B,aAAW,QAAQ,OAAO;AACxB,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,UAAM,WAAW,OAAO,KAAK,SAAS,CAAC;AACvC,QACE,QAAQ,YAAY,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,QAAQ,KAC3D,KAAK,OAAO,QAAQ,SAAS,OAAO,QAAQ,KAAK,UAAU,SAAS;AAEpE,WAAK,KAAK,IAAI;AAAA,QACX,OAAM,KAAK,CAAC,IAAI,CAAC;AAAA,EACxB;AACA,SAAO;AACT;AAEA,SAAS,YAAY,MAA4B,SAAuC;AACtF,SAAO,KAAK,MAAM,CAAC,SAAS,QAAQ,IAAI,aAAa,IAAI,CAAC,CAAC;AAC7D;AAEA,SAAS,YAAY,OAA6B,OAA4C;AAC5F,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,YAAY,CAAC;AAC/C,QAAM,SAAS,IAAI;AAAA,IACjB,MAAM,OAAO,CAAC,SAAS,YAAY,MAAM,OAAO,CAAC,EAAE,QAAQ,CAAC,SAAS,KAAK,IAAI,YAAY,CAAC;AAAA,EAC7F;AACA,SAAO,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,aAAa,IAAI,CAAC,CAAC;AAC/D;AAEA,SAAS,YAAY,GAAyB,GAAkC;AAC9E,QAAM,OAAO,CAAC,UAAgC,KAAK,UAAU,MAAM,IAAI,YAAY,EAAE,KAAK,CAAC;AAC3F,SAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAC3B;AAuBA,SAAS,WAAW,OAA+B;AACjD,QAAM,MAAM,MAAM,SAAS,CAAC;AAC5B,QAAM,aAAa,oBAAoB,GAAG;AAC1C,QAAM,QAAQ,WAAW,WAAW,WAAW;AAC/C,QAAM,UAAU,WAAW,WAAW,WAAW,SAAS,OAAO,QAAQ,WAAW;AACpF,QAAM,OAAO,IAAI,IAAI,MAAM,IAAI;AAE/B,MAAI,OAAO,IAAI,UAAU,SAAU,MAAK,OAAO,OAAO;AACtD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,YAAY,OAAO;AAAA,IAC1B,UAAU,WAAW,WACjB;AAAA,MACE,MAAM,WAAW,SAAS;AAAA,MAC1B,WAAW,WAAW,SAAS;AAAA,MAC/B,gBAAgB,WAAW,SAAS;AAAA,MACpC,QAAQ,WAAW;AAAA,IACrB,IACA;AAAA,IACJ,QAAQ,WAAW;AAAA,IACnB,SAAS,WAAW;AAAA,IACpB,OAAO,OAAO,IAAI,UAAU,WAAW,WAAW,QAAQ;AAAA,IAC1D,cAAc,WAAW,gBAAgB,CAAC;AAAA,EAC5C;AACF;AAEA,IAAM,cAAc,CAAC,UAAkC,MAAM,UAAU,UAAU;AAEjF,SAAS,gBAAgB,OAAmB,MAA8B;AACxE,SAAO,MAAM,WAAW,EAAE,GAAG,OAAO,UAAU,EAAE,GAAG,MAAM,UAAU,QAAQ,KAAK,EAAE,IAAI;AACxF;AAKA,SAAS,QAAQ,OAAmB,OAAoD;AACtF,MAAI,UAAU,UAAW,QAAO,YAAY,KAAK;AACjD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAEA,SAAS,UAAU,OAAmB,OAA4B,QAAuD;AACvH,MAAI,UAAU,UAAW,QAAO,gBAAgB,OAAO,OAAO,YAAY,KAAK,CAAC,CAAC;AACjF,SAAO,MAAM,WAAW,OAAO,KAAK,IAAI;AAC1C;AAEA,SAAS,iBAAiB,OAAmB,cAA+C;AAC1F,QAAM,EAAE,cAAc,WAAW,GAAG,KAAK,IAAI;AAC7C,SAAO,aAAa,SAAS,EAAE,GAAG,MAAM,aAAa,IAAI;AAC3D;AAEA,IAAMC,SAAQ,CAAI,UAAgB,gBAAgB,KAAK;AAIvD,IAAM,iBAAiB,CAAC,EAAE,IAAI,IAAI,OAAO,YAAY,KAAK,MACxD,KAAK,UAAU,OAAO,SAAS,CAAC,IAAI,IAAI,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,UAAU,CAAC;AAErF,SAAS,iBAAiB,WAA6C;AACrE,SAAO,KAAK,UAAU,UAAU,IAAI,cAAc,CAAC;AACrD;AAGA,SAAS,cAAc,OAAwB;AAC7C,SAAO,KAAK;AAAA,IAAU;AAAA,IAAO,CAAC,MAAM,SAClC,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IACnD,OAAO,YAAY,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,IACxF;AAAA,EACN;AACF;AAEA,SAAS,gBAAgB,QAAmC;AAC1D,QAAM,EAAE,IAAI,KAAK,OAAO,QAAQ,SAAS,UAAU,QAAQ,SAAS,GAAG,KAAK,IAAI;AAChF,SAAO,cAAc,IAAI;AAC3B;AAEA,SAAS,aAAa,OAAmB,OAAmB,OAA4B;AACtF,UAAQ,OAAO;AAAA,IACb,KAAK,WAAW;AACd,YAAM,UAAU,IAAI,IAAI,YAAY,KAAK,EAAE,MAAM,IAAI,YAAY,CAAC;AAClE,aAAO,MAAM,MAAM,MAAM,CAAC,SAAS,YAAY,MAAM,OAAO,CAAC;AAAA,IAC/D;AAAA,IACA,KAAK,YAAY;AACf,YAAM,WAAW,MAAM;AACvB,UAAI,CAAC,MAAM,YAAY,CAAC,SAAU,QAAO,CAAC,MAAM,YAAY,CAAC;AAC7D,aACE,KAAK,UAAU,SAAS,IAAI,MAAM,KAAK,UAAU,MAAM,SAAS,IAAI,KACpE,iBAAiB,SAAS,SAAS,MAAM,iBAAiB,MAAM,SAAS,SAAS,KAClF,KAAK,UAAU,SAAS,cAAc,MAAM,KAAK,UAAU,MAAM,SAAS,cAAc,KACxF,YAAY,MAAM,OAAO,MAAM,SAAS,MAAM;AAAA,IAElD;AAAA,IACA,KAAK,WAAW;AACd,YAAM,QAAQ,QAAQ,OAAO,MAAM,KAAK;AACxC,aAAO,CAAC,CAAC,SAAS,KAAK,UAAU,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,KAAK,UAAU,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IACxH;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,QAAQ,QAAQ,OAAO,MAAM,KAAK;AACxC,aAAO,CAAC,CAAC,SAAS,KAAK,UAAU,MAAM,OAAO,MAAM,KAAK,UAAU,MAAM,OAAO;AAAA,IAClF;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,QAAQ,QAAQ,OAAO,MAAM,KAAK;AACxC,aAAO,CAAC,CAAC,SAAS,MAAM,UAAU,MAAM;AAAA,IAC1C;AAAA,IACA,KAAK,WAAW;AACd,YAAM,QAAQ,QAAQ,OAAO,MAAM,KAAK;AACxC,YAAM,aAAa,CAAC,YAA0C,KAAK,UAAU,QAAQ,IAAI,eAAe,EAAE,KAAK,CAAC;AAChH,aAAO,CAAC,CAAC,SAAS,WAAW,MAAM,gBAAgB,CAAC,CAAC,MAAM,WAAW,MAAM,YAAY;AAAA,IAC1F;AAAA,EACF;AACF;AAUO,SAAS,WAAW,OAAmB,OAAoC;AAChF,QAAM,aAAa,oBAAoB,KAAK;AAC5C,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,QAAQ,CAAC,GAAG,MAAM,IAAI;AAC5B,QAAM,WAAW,MAAM,OAAO,CAAC,UAAU,CAAC,aAAa,YAAY,OAAO,KAAK,CAAC;AAChF,MAAI,CAAC,SAAS,OAAQ,QAAO,EAAE,QAAQ,UAAU,UAAU,CAAC,EAAE;AAC9D,QAAM,UAAU,IAAI,IAAI,YAAY,UAAU,EAAE,MAAM,IAAI,YAAY,CAAC;AACvE,QAAM,eACJ,MAAM,KAAK,CAAC,UAAU,CAAC,SAAS,SAAS,KAAK,MAAM,UAAU,aAAa,MAAM,MAAM,SAAS,EAAE,KACjG,MAAM,KAAK,IAAI,SAAS,KAAK,MAAM,MAAM,KAAK,CAAC,SAAS,YAAY,MAAM,OAAO,CAAC;AACrF,SAAO,eAAe,EAAE,QAAQ,YAAY,SAAS,IAAI,EAAE,QAAQ,YAAY,UAAU,CAAC,EAAE;AAC9F;AAIA,SAAS,aAAa,OAA+B;AACnD,SAAO,MAAM,WACT,EAAE,GAAG,OAAO,QAAQ,GAAG,UAAU,EAAE,GAAG,MAAM,UAAU,QAAQ,EAAE,GAAG,MAAM,SAAS,QAAQ,QAAQ,EAAE,EAAE,EAAE,IACxG,EAAE,GAAG,OAAO,QAAQ,EAAE;AAC5B;AAEA,SAAS,cAAc,OAAmB,UAA4C;AACpF,MAAI,CAAC,SAAU,QAAO,aAAa,KAAK;AACxC,QAAM,SAAS,MAAM;AAErB,QAAM,QAAQ,UAAU,KAAK,UAAU,OAAO,IAAI,MAAM,KAAK,UAAU,SAAS,IAAI,IAChF,QACA,iBAAiB,OAAO,SAAS,IAAI;AACzC,QAAM,WAAW,MAAM;AACvB,QAAM,YAAYA,OAAM,SAAS,SAAS;AAE1C,QAAM,OAAO,IAAI,IAAI,UAAU,IAAI,cAAc,CAAC;AAClD,QAAM,UAAU,IAAI,IAAI,SAAS,UAAU,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,eAAe,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,OAAO,EAAE,CAAC;AAC3H,QAAM,OAAmB;AAAA,IACvB,GAAG;AAAA,IACH,UAAU,EAAE,GAAG,UAAU,WAAW,gBAAgBA,OAAM,SAAS,cAAc,EAAE;AAAA,IACnF,OAAOA,OAAM,SAAS,MAAM;AAAA,IAC5B,QAAQ,MAAM,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,IACxD,SAAS,MAAM,QAAQ,OAAO,CAAC,SAAS,CAAC,QAAQ,IAAI,KAAK,KAAK,CAAC;AAAA,EAClE;AACA,SAAO,QAAQ,OAAO,iBAAiB,MAAM,CAAC,CAAC,IAAI;AACrD;AAMO,SAAS,YAAY,OAAmB,OAA+B;AAC5E,QAAM,QAAQ,WAAW,KAAK;AAC9B,QAAM,UAAU,CAAC,UAAsB,MAAM,KAAK,IAAI,KAAK,KAAK,aAAa,oBAAoB,KAAK,GAAG,OAAO,KAAK;AACrH,QAAM,QAAQ;AAAA,IACZ,SAAS,QAAQ,SAAS;AAAA,IAC1B,OAAO,QAAQ,OAAO;AAAA,IACtB,SAAS,QAAQ,SAAS;AAAA,IAC1B,UAAU,QAAQ,UAAU;AAAA,EAC9B;AACA,MAAI,OAAO;AACX,MAAI,MAAM,KAAK,IAAI,SAAS,GAAG;AAC7B,UAAM,UAAU,YAAY,IAAI;AAChC,WAAO,gBAAgB,MAAM,EAAE,GAAG,SAAS,OAAO,YAAY,QAAQ,OAAO,MAAM,KAAK,EAAE,CAAC;AAAA,EAC7F;AACA,SAAO,UAAU,MAAM,MAAM,OAAO,CAAC,UAAU;AAC7C,QAAI,MAAM;AACV,QAAI,MAAM,QAAS,OAAM,EAAE,GAAG,KAAK,QAAQ,CAAC,EAAE;AAC9C,QAAI,MAAM,MAAO,OAAM,EAAE,GAAG,KAAK,SAAS,CAAC,EAAE;AAC7C,QAAI,MAAM,QAAS,OAAM,iBAAiB,KAAK,CAAC,CAAC;AACjD,WAAO;AAAA,EACT,CAAC;AACD,MAAI,MAAM,SAAU,QAAO,aAAa,IAAI;AAC5C,SAAO,aAAa,IAAI;AAC1B;AAMO,SAAS,WAAW,OAAmB,OAAmBC,WAA6B,CAAC,GAAe;AAC5G,MAAI,OAAOA,SAAQ,YAAY,YAAY,OAAOA,SAAQ,SAAS,IAAI;AACvE,QAAM,QAAQ,WAAW,KAAK;AAC9B,MAAI,MAAM,KAAK,IAAI,UAAU,EAAG,QAAO,cAAc,MAAM,MAAM,QAAQ;AACzE,MAAI,MAAM,KAAK,IAAI,SAAS,GAAG;AAC7B,UAAM,UAAU,YAAY,IAAI;AAChC,WAAO,gBAAgB,MAAM,EAAE,GAAG,SAAS,OAAO,iBAAiB,QAAQ,OAAOD,OAAM,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,EAC3G;AACA,SAAO,UAAU,MAAM,MAAM,OAAO,CAAC,UAAU;AAC7C,QAAI,MAAM;AACV,QAAI,MAAM,KAAK,IAAI,SAAS,EAAG,OAAM,EAAE,GAAG,KAAK,QAAQA,OAAM,MAAM,MAAM,EAAE;AAC3E,QAAI,MAAM,KAAK,IAAI,OAAO,EAAG,OAAM,EAAE,GAAG,KAAK,SAASA,OAAM,MAAM,OAAO,EAAE;AAC3E,QAAI,MAAM,KAAK,IAAI,OAAO,EAAG,OAAM,EAAE,GAAG,KAAK,OAAO,MAAM,SAAS,IAAI,MAAM;AAC7E,QAAI,MAAM,KAAK,IAAI,SAAS,EAAG,OAAM,iBAAiB,KAAKA,OAAM,MAAM,YAAY,CAAC;AACpF,WAAO;AAAA,EACT,CAAC;AACD,SAAO,aAAa,IAAI;AAC1B;;;AC/TO,SAAS,qBAAqB,WAAsD;AACzF,SAAO,UAAU,OAAO,CAAC,WAAW,OAAO,OAAO,MAAM;AAC1D;AASO,SAAS,eAAe,OAAmB,OAA0C;AAC1F,QAAM,KAAK,MAAM;AACjB,MAAI,CAAC,MAAM,YAAY,IAAI,SAAS,WAAW,MAAM,QAAS,QAAO;AACrE,QAAM,OAAO,GAAG,SAAS,UAAU,gBAAgB,WAAW,IAAI,aAAa,KAAK;AACpF,MAAI,GAAG,eAAe,SAAS,CAAC,MAAM,MAAO,QAAO;AACpD,QAAM,WAAuB,EAAE,GAAG,MAAM,OAAO,iBAAiB,KAAK,OAAO,MAAM,SAAS,CAAC,CAAC,GAAG,QAAQ,EAAE;AAC1G,SAAO,GAAG,QAAQ,WAAW,UAAU,GAAG,KAAK,IAAI;AACrD;AAIO,SAAS,iBAAiB,OAAmB,OAAuB,UAAuB,CAAC,GAAsB;AACvH,QAAM,aAAa,CAAC,aAAwC,EAAE,OAAO,MAAM,OAAO,MAAM,MAAM,QAAQ;AACtG,MAAI,MAAM,QAAS,QAAO,WAAW,MAAM,OAAO;AAClD,MAAI,MAAM,IAAI,SAAS,WAAY,QAAO,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,MAAM,MAAM,KAAK,IAAI,WAAW,eAAe;AAC5H,MAAI,MAAM,IAAI,SAAS,QAAS,QAAO,WAAW,0BAA0B;AAC5E,QAAM,QAAQ,OAAO,UAAU,eAAe,KAAK,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,MAAM,GAAG,MAAM,IAAI;AAC1G,MAAI,OAAO,UAAU,WAAY,QAAO,WAAW,gBAAgB,MAAM,GAAG,MAAM,sBAAsB;AACxG,QAAM,cAAc,eAAe,OAAO,KAAK;AAC/C,MAAI,CAAC,YAAa,QAAO,WAAW,uCAAuC;AAC3E,MAAI;AACF,UAAM,OAAO,MAAM,aAAa,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC;AACtD,WAAO,OAAO,SAAS,YAAY,KAAK,KAAK,IAAI,EAAE,OAAO,MAAM,OAAO,KAAK,IAAI,WAAW,gBAAgB,MAAM,GAAG,MAAM,oBAAoB;AAAA,EAChJ,SAAS,OAAO;AACd,WAAO,WAAW,gBAAgB,MAAM,GAAG,MAAM,aAAa,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EACxH;AACF;;;ACTO,SAAS,sBAA2B,QAA0B,WAA+B,YAAwE,CAAC,GAAqB;AAChM,QAAM,SAAS,IAAI,IAAI,OAAO,OAAO,IAAI,WAAS,CAAC,MAAM,MAAM,KAAK,CAAC,CAAC;AACtE,aAAW,CAAC,MAAM,UAAU,KAAK,OAAO,QAAQ,WAAW,UAAU,CAAC,CAAC,GAAG;AACxE,UAAM,aAAa,UAAU,KAAK,CAAAE,gBAAc,SAAS,aAAaA,YAAW,EAAE,EAAE;AACrF,UAAM,WAAW,WAAW,kBAAkB,IAAI,KAAK,WAAW,kBAAkB,KAAK,MAAM,EAAE,CAAC;AAClG,UAAM,UAAU,CAAC,CAAC,aAAa,CAAC,cAAc,WAAW,aAAa;AACtE,WAAO,IAAI,MAAM;AAAA,MAAE,GAAG,OAAO,IAAI,IAAI;AAAA,MAAG;AAAA,MAAM,OAAO,YAAY,SAAS,OAAO,IAAI,IAAI,GAAG,SAAS;AAAA,MACnG,MAAM,WAAW;AAAA,MAAM,QAAQ,EAAE,MAAM,UAAU;AAAA,MACjD,QAAQ,EAAE,SAAS,WAAW,WAAW,OAAO;AAAA,MAAG,QAAQ,EAAE,SAAS,WAAW,WAAW,WAAW,KAAK;AAAA,MAC5G,MAAM,EAAE,SAAS,WAAW,WAAW,KAAK;AAAA,MAAG,WAAW,EAAE,SAAS,WAAW,WAAW,SAAS,WAAW,WAAW,WAAW,MAAM;AAAA,IAAE,CAAkB;AAAA,EACnK;AACA,SAAO,EAAE,GAAG,QAAQ,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE;AACnD;AACO,SAAS,iBAAsB,OAAmB,YAA8B,cACrF,WAA+BC,WAA4C,CAAC,GAAmB;AAC/F,QAAM,MAAM,eAAeA,QAAO,GAAG,IAAI,oBAAoB,KAAK;AAClE,QAAM,eAAe,sBAAsB,YAAY,SAAS;AAChE,QAAM,SAAS,EAAE,UAAU,UAAU,gBAAgB,CAAC;AACtD,QAAM,cAAwB,CAAC;AAC/B,OAAK,MAAM,cAAc,UAAU,QAAQ,EAAE,cAAc,UAAU,GAAI,aAAY,KAAK,yEAAyE;AACnK,MAAI,aAAa,YAAY,KAAK,aAAa,UAAU,YAAY,aAAa,QAAS,aAAY,KAAK,8CAA8C;AAC1J,MAAI,eAAe;AACnB,MAAI,EAAE,UAAU;AACd,QAAI,CAAC,aAAa,YAAa,aAAY,KAAK,4CAA4C;AAC5F,QAAI;AAAE,YAAM,QAAQ,oBAAoB,YAAY;AAAG,YAAM,SAAS,EAAE,QAAQ;AAAG,qBAAe,MAAM,aAAa,EAAE,SAAS,MAAM,EAAE,SAAS,SAAS;AAAA,IAAG,SACtJ,OAAO;AAAE,kBAAY,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IAAG;AAAA,EAC5F;AACA,QAAM,gBAAgB,cAAc,gBAAgB,MAAM,GAAG,YAAY;AACzE,aAAW,QAAQ,OAAO,MAAO,YAAW,aAAa,aAAa,IAAI,EAAG,KAAI,CAAC,iBAAiB,mBAAmB,EAAE,SAAS,UAAU,EAAE,KAAK,CAAC,aAAa;AAC9J,gBAAY,KAAK,uEAAuE;AAC1F,QAAM,SAAS,cAAc,gBAAgB,CAAC,GAAG,YAAY;AAC7D,MAAI,cAAc,MAAM,WAAW,OAAO,MAAM,UAAU,OAAO,MAAM,WAAW,EAAE,MAAM,OAAQ,aAAY,KAAK,6DAA6D;AAChL,MAAI,OAAO,QAAQ,WAAW,EAAE,QAAQ,OAAQ,aAAY,KAAK,iDAAiD;AAClH,MAAI,EAAE;AAAU,eAAW,QAAQ,EAAE,SAAS,OAAO,MAAO,YAAW,aAAa,aAAa,IAAI;AACnG,UAAI,UAAU,MAAM,WAAW,YAAY,KAAK,CAAC,aAAa,sBAAuB,aAAY,KAAK,0DAA0D;AAAA;AAClK,QAAM,cAAc,cAAc,gBAAgB,CAAC,GAAG,cAAc,SAAS;AAI7E,cAAY,KAAK,GAAG,YAAY,YAAY,OAAO,WAAS,MAAM,SAAS,wBAAwB,EAAE,IAAI,WAAS,MAAM,OAAO,CAAC;AAChI,QAAM,UAAU,YAAY,QAAQ,IAAI,YAAU;AAChD,UAAM,eAAe,EAAE,cAAc,KAAK,YAAU,OAAO,OAAO,OAAO,EAAE,GAAG;AAC9E,WAAO,eAAe,EAAE,GAAG,QAAQ,aAAa,IAAI;AAAA,EACtD,CAAC;AACD,aAAW,UAAU,SAAS;AAC5B,gBAAY,KAAK,GAAG,eAAe,QAAQ,YAAY,EAAE,IAAI,WAAS,MAAM,OAAO,CAAC;AACpF,QAAI,OAAO,gBAAgB,CAAC,aAAa,iBAAkB,aAAY,KAAK,iDAAiD;AAAA,EAC/H;AACA,QAAM,YAAoC,uBAAO,OAAO,IAAI;AAC5D,aAAW,CAAC,IAAI,QAAQ,KAAK,OAAO,QAAQ,WAAW,qBAAqB,CAAC,CAAC,GAAG;AAC/E,QAAI,CAAC,YAAY,GAAG,SAAS,OAAO,SAAS,SAAS,IAAK,aAAY,KAAK,qCAAqC;AAAA,QAC5G,WAAU,GAAG,WAAW,YAAY,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI;AAAA,EACpE;AACA,SAAO;AAAA,IAAE,SAAS;AAAA,IAAG,SAAS,aAAa;AAAA,IAAS;AAAA,IAAK,mBAAmB;AAAA,IAC1E,GAAI,WAAW,YAAY,EAAE,WAAW,UAAU,UAAU,IAAI,CAAC;AAAA,IAAI,GAAI,WAAW,aAAa,SAAY,EAAE,UAAU,UAAU,SAAS,IAAI,CAAC;AAAA,IACjJ,QAAQ;AAAA,IAAe;AAAA,IAAQ,GAAI,EAAE,WAAW,EAAE,UAAU;AAAA,MAAE,MAAM,EAAE,SAAS;AAAA;AAAA;AAAA,MAG7E,WAAW,qBAAqB,EAAE,SAAS,SAAS,EAAE,IAAI,CAAC,EAAE,SAAS,UAAU,GAAG,QAAQ,MAAM,OAAO;AAAA,MAAG,gBAAgB,EAAE,SAAS;AAAA,MACtI,GAAI,EAAE,SAAS,cAAc,EAAE,aAAa,EAAE,SAAS,YAAY,IAAI,CAAC;AAAA,IAAG,EAAE,IAAI,CAAC;AAAA,IAAI,MAAMA,SAAQ,SAAS;AAAA,IAAO;AAAA,IAAS,aAAa,CAAC,GAAG,IAAI,IAAI,WAAW,CAAC;AAAA,EAAE;AAC1K;AACO,SAAS,sBAAsB,QAAuB,SAAyB,QAA2B;AAC/G,MAAI,CAAC,UAAU,OAAO,YAAY,KAAK,OAAO,QAAQ,QAAQ,OAAO,CAAC,OAAO,cAAc,OAAO,KAAK,KAAK,OAAO,QAAQ,KACzH,CAAC,OAAO,cAAc,OAAO,WAAW,KAAK,OAAO,cAAc,KAAK,CAAC,MAAM,QAAQ,OAAO,IAAI,KAAK,CAAC,MAAM,QAAQ,OAAO,OAAO,KACnI,OAAO,WAAW,YAAY,QAAQ,YAAY,OAAO,UAAU,aAAa,SAAS,QAAQ,aAAa,QAC7G,OAAO,UAAU,YAAY,SAAS,QAAQ,YAAY,OAAO,OAAO,QAAQ,YAAY,OAAO;AACpG,UAAM,MAAM,iDAAiD;AAC/D,QAAM,WAAW,IAAI,IAAI,OAAO,OAAO,IAAI,WAAS,CAAC,MAAM,MAAM,MAAM,IAAI,CAAC,CAAC;AAC7E,MAAI,CAAC,MAAM,QAAQ,OAAO,OAAO,MAAM,KAAK,OAAO,OAAO,OAAO,KAAK,WAAS,SAAS,IAAI,MAAM,IAAI,MAAM,MAAM,IAAI,KACpH,QAAQ,QAAQ,QAAQ,OAAO,OAAO,KAAK,UAAQ,CAAC,OAAO,OAAO,OAAO,KAAK,WAAS,MAAM,SAAS,IAAI,CAAC,EAAG,OAAM,MAAM,mDAAmD;AAC/K,aAAW,CAAC,IAAI,QAAQ,KAAK,OAAO,QAAQ,QAAQ,iBAAiB,EAAG,KAAI,OAAO,UAAU,kBAAkB,EAAE,MAAM;AACrH,UAAM,MAAM,uEAAuE;AACrF,QAAM,OAAO,oBAAI,IAAa;AAC9B,aAAW,OAAO,OAAO,MAAM;AAAE,UAAM,KAAK,IAAI,OAAO,OAAO;AAAG,QAAI,OAAO,OAAO,YAAY,OAAO,OAAO,YAAY,KAAK,IAAI,EAAE,EAAG,OAAM,MAAM,4DAA4D;AAAG,SAAK,IAAI,EAAE;AAAA,EAAG;AAClO;;;AC7GA,SAAS,aAAa,OAAmB,QAAkC;AACzE,MAAI,CAAC,MAAM,YAAY,OAAO,YAAY,eAAgB,QAAO;AACjE,SAAO,oBAAoB,MAAM,EAAE,aAAa,MAAM,SAAS,MAAM,MAAM,SAAS,SAAS;AAC/F;AAEA,SAASC,oBAAmB,QAAoC;AAC9D,SAAO,CAAC,CAAC,OAAO,iBAAiB,CAAC,OAAO,WAAW,OAAO,QAAQ,SAAS,SAAS,OAAO,QAAQ,SAAS;AAC/G;AAmBO,SAAS,mBACd,OACA,QACA,QACA,QACmB;AACnB,MAAI,OAAO,UAAU,eAAe,OAAO,KAAK,WAAW,OAAO,QAAQ,OAAQ,QAAO;AACzF,QAAM,SAAS,aAAa,OAAO,MAAM;AACzC,QAAM,QAAqB,CAAC,GAAI,OAAO,SAAS,CAAC,CAAE;AACnD,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACpD,UAAM,QAAQ,aAAa,QAAQ,IAAI;AACvC,UAAM,MAAM,OAAO,KAAK,KAAK,KAAK;AAClC,QAAI,OAAO,gBAAgB,UAAU,KAAK,QAAQ,MAAM;AACtD,UAAI,CAAC,SAAS,MAAM,SAAS,cAAc,CAAC,aAAa,KAAK,EAAG,QAAO;AACxE,UAAI;AACJ,UAAI;AACF,gBAAQ,eAAe,GAAG;AAAA,MAC5B,QAAQ;AACN,eAAO;AAAA,MACT;AACA,YAAM,EAAE,UAAU,SAAS,IAAI,OAAO;AACtC,YAAM,OAAO,eAAe,OAAO,UAAU,QAAQ;AACrD,YAAM;AAAA,QACJ,EAAE,OAAO,MAAM,MAAM,IAAI,MAAM,OAAO,IAAI,KAAK,KAAK,EAAE,YAAY,EAAE;AAAA,QACpE,EAAE,OAAO,MAAM,MAAM,IAAI,KAAK,OAAO,IAAI,KAAK,IAAI,EAAE,YAAY,EAAE;AAAA,MACpE;AACA;AAAA,IACF;AACA,UAAM,OAAO,UAAU,OAAO,GAAG;AACjC,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,MAAI,OAAO,KAAK;AACd,UAAM,EAAE,KAAK,KAAK,aAAa,IAAI,OAAO;AAC1C,QAAI,CAACA,oBAAmB,MAAM,KAAK,OAAO,aAAc,SAAS,eAAe,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM;AACtI,aAAO;AACT,QAAI;AACJ,QAAI;AACF,cAAQ,eAAe,OAAO,aAAc,OAAO,OAAO,MAAM,EAAE;AAAA,IACpE,QAAQ;AACN,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,MAAM,SAAS,UAAU,aAAa,QAAQ,MAAM,IAAI,IAAI;AAC1E,QAAI,CAAC,SAAS,MAAM,SAAS,YAAY,CAAC,aAAa,KAAK,EAAG,QAAO;AACtE,UAAM;AAAA,MACJ,EAAE,OAAO,MAAM,MAAM,IAAI,MAAM,OAAO,OAAO,GAAG,EAAE;AAAA,MAClD,EAAE,OAAO,MAAM,MAAM,IAAI,eAAe,OAAO,KAAK,OAAO,OAAO,GAAG,EAAE;AAAA,IACzE;AAAA,EACF;AACA,SAAO,EAAE,GAAG,OAAO,OAAO,iBAAiB,MAAM,OAAO,KAAK,GAAG,QAAQ,EAAE;AAC5E;AASO,SAAS,iBAAiB,OAAmB,OAAmB,QAAwC;AAC7G,MAAI,CAAC,MAAM,SAAU,QAAO;AAC5B,QAAM,QAAQ,cAAc,MAAM,SAAS,MAAM,OAAO,MAAM;AAC9D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,SAAS,aAAa,KAAK;AACjC,SAAO,EAAE,GAAG,QAAQ,OAAO,iBAAiB,OAAO,OAAO,KAAK,GAAG,QAAQ,EAAE;AAC9E;","names":["record","f","f","record","field","options","next","resolveField","f","options","text","code","snapshot","a","b","n","parts","f","value","compare","record","options","f","date","start","end","f","options","value","now","empty","options","resolveField","field","f","item","field","clone","options","definition","options","distributionActive"]}
1
+ {"version":3,"sources":["../src/cellDisplay.ts","../src/properties.ts","../src/schema.ts","../src/itemPage.ts","../src/metricNormalize.ts","../src/relativeTime.ts","../src/ops.ts","../src/metricDates.ts","../src/groupKeys.ts","../src/query.ts","../src/agg.ts","../src/encode.ts","../src/setFilter.ts","../src/queryLinks.ts","../src/computed.ts","../src/formula.ts","../src/metricPrecision.ts","../src/metricDistributions.ts","../src/metricSeries.ts","../src/grouping.ts","../src/execution.ts","../src/metrics.ts","../src/apply.ts","../src/adapters.ts","../src/propertyStorage.ts","../src/source.ts","../src/queryPatch.ts","../src/groupLinks.ts","../src/queryV3.ts","../src/drilldown.ts"],"sourcesContent":["/** Presentation hints only: field types still determine query/filter semantics. */\nexport interface JsonCellDisplay {\n kind: \"json\";\n /** auto accepts objects, JSON text and repeatedly encoded/escaped JSON text.\n * value keeps a native string literal; json parses text once; escaped unwraps it. */\n encoding?: \"auto\" | \"value\" | \"json\" | \"escaped\";\n /** Maximum string-unwrapping passes, 1–8. Default 4. */\n maxDecodeDepth?: number;\n /** Inline preview length, 20–500 characters. Default 80. */\n previewLength?: number;\n /** Override initially expanded container levels, 0–8.\n * The root starts open. By default, nested containers with up to 3 entries\n * open; larger nested containers collapse. */\n expandDepth?: number;\n}\n\ntype CalendarDisplay = {\n style?: \"human\" | \"iso\" | \"custom\";\n pattern?: string;\n /** UTC by default; an IANA timezone or local may be selected explicitly. */\n timeZone?: string;\n locale?: string;\n};\n\nexport type CellDisplay =\n | JsonCellDisplay\n | ({ kind: \"date\" | \"datetime\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" } & CalendarDisplay)\n | ({ kind: \"time\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" | \"secondsOfDay\" | \"millisecondsOfDay\" } & CalendarDisplay)\n | { kind: \"duration\"; sourceUnit?: \"milliseconds\" | \"seconds\" | \"minutes\" | \"hours\" | \"days\"; style?: \"human\" | \"long\" | \"clock\" | \"custom\"; pattern?: string; decimals?: number }\n | { kind: \"number\" | \"percent\"; decimals?: number; locale?: string }\n | { kind: \"chip\"; labels?: Record<string, string>; tones?: Record<string, \"neutral\" | \"success\" | \"warning\" | \"danger\"> }\n /** `truncate` keeps one line with an ellipsis. `lines` (1–20) wraps the text\n * and clamps it to that many lines with an ellipsis; it takes precedence. */\n | { kind: \"text\"; truncate?: boolean; lines?: number };\n\nconst calendarOptions = {\n style: [\"human\", \"iso\", \"custom\"], pattern: \"string\", timeZone: \"string\", locale: \"string\",\n} as const;\nconst numberOptions = { decimals: [0, 20], locale: \"string\" } as const;\nconst calendarUnits = [\"iso\", \"epochSeconds\", \"epochMilliseconds\"];\nconst options: Record<string, Record<string, readonly string[] | readonly number[] | string>> = {\n json: { encoding: [\"auto\", \"value\", \"json\", \"escaped\"], maxDecodeDepth: [1, 8], previewLength: [20, 500], expandDepth: [0, 8] },\n date: { ...calendarOptions, sourceUnit: calendarUnits },\n datetime: { ...calendarOptions, sourceUnit: calendarUnits },\n time: { ...calendarOptions, sourceUnit: [...calendarUnits, \"secondsOfDay\", \"millisecondsOfDay\"] },\n duration: { sourceUnit: [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\"], style: [\"human\", \"long\", \"clock\", \"custom\"], pattern: \"string\", decimals: [0, 20] },\n number: numberOptions, percent: numberOptions,\n chip: { labels: \"labels\", tones: \"tones\" },\n text: { truncate: \"boolean\", lines: [1, 20] },\n};\n\n/** Validate the serializable contract at schema loading, before rendering cells. */\nexport function parseCellDisplay(raw: unknown, context = \"cell display\"): CellDisplay {\n const fail = (reason: string): never => { throw Error(`${context}: ${reason}`); };\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return fail(\"expected an object\");\n const record = raw as Record<string, unknown>;\n if (typeof record.kind !== \"string\" || !Object.prototype.hasOwnProperty.call(options, record.kind)) return fail(\"unsupported kind\");\n const allowed = options[record.kind]!;\n for (const [key, value] of Object.entries(record)) {\n if (key === \"kind\") continue;\n const rule = Object.prototype.hasOwnProperty.call(allowed, key) ? allowed[key] : undefined;\n if (!rule) return fail(`unsupported option ${key}`);\n if (Array.isArray(rule)) {\n if (typeof rule[0] === \"number\") {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value < Number(rule[0]) || value > Number(rule[1])) return fail(`${key} must be an integer from ${rule[0]} to ${rule[1]}`);\n } else if (!rule.includes(value as never)) return fail(`unsupported ${key}`);\n } else if (rule === \"labels\" || rule === \"tones\") {\n if (!value || typeof value !== \"object\" || Array.isArray(value) || !Object.values(value).every((item) => typeof item === \"string\" && (rule === \"labels\" || [\"neutral\", \"success\", \"warning\", \"danger\"].includes(item)))) return fail(`invalid ${key} map`);\n } else if (typeof value !== rule) return fail(`${key} must be ${rule}`);\n if (key === \"pattern\" && (value as string).length > 160) return fail(\"pattern must be at most 160 characters\");\n }\n return { ...record,\n ...(record.labels ? { labels: { ...record.labels as Record<string, string> } } : {}),\n ...(record.tones ? { tones: { ...record.tones as Record<string, string> } } : {}),\n } as CellDisplay;\n}\n","import type { MetricValueFormat } from \"./metricTypes\";\nimport type { FieldDef, FieldSchema } from \"./schema\";\nimport { readFieldValue } from \"./schema\";\nimport type { RowId } from \"./query\";\nimport { parseCellDisplay, type CellDisplay, type JsonCellDisplay } from \"./cellDisplay\";\n\n/** Formats change presentation only; values retain their original types/units. */\nexport type PropertyFormat =\n | MetricValueFormat\n | { kind: \"text\" | \"code\" | \"boolean\" | \"chips\" }\n | JsonCellDisplay\n | Extract<CellDisplay, { kind: \"chip\" }>\n | {\n kind: \"relative\";\n sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\";\n }\n | { kind: \"currency\"; currency: string; decimals?: number };\n\nexport interface PropertyFieldConfig {\n enabled?: boolean;\n default?: boolean;\n /** Detail-specific renderer. Table renderers remain unchanged. */\n render?: string;\n format?: PropertyFormat;\n}\n\nexport interface PropertySelection {\n /** Instance identity allows the same field to appear with different formats. */\n id: string;\n field: string;\n label?: string;\n render?: string;\n format?: PropertyFormat;\n}\n\n/** Independent of object identity and collection QueryState. [] shows no fields. */\nexport interface PropertyViewState {\n version: 1;\n properties: PropertySelection[];\n /** Property label column width as a percentage, shared with the saved view. */\n labelWidth?: number;\n}\n\nexport const MAX_PROPERTIES = 200;\nconst string = (value: unknown, max = 256): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= max;\nconst record = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nexport function normalizePropertyFormat(\n input: unknown,\n): PropertyFormat | undefined {\n if (!record(input)) return;\n const kind = input.kind;\n if (kind === \"json\" || kind === \"chip\") {\n try { return parseCellDisplay(input) as PropertyFormat; }\n catch { return; }\n }\n if (\n input.decimals !== undefined &&\n !(\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n )\n return;\n if ([\"text\", \"code\", \"boolean\", \"chips\"].includes(String(kind)))\n return { kind } as PropertyFormat;\n if (kind === \"relative\") {\n if (\n input.sourceUnit !== undefined &&\n ![\"iso\", \"epochSeconds\", \"epochMilliseconds\"].includes(\n String(input.sourceUnit),\n )\n )\n return;\n return {\n kind,\n ...(input.sourceUnit ? { sourceUnit: input.sourceUnit } : {}),\n } as PropertyFormat;\n }\n if (kind === \"currency\") {\n if (\n typeof input.currency !== \"string\" ||\n !/^[A-Z]{3}$/.test(input.currency)\n )\n return;\n return {\n kind,\n currency: input.currency,\n ...(typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n ? { decimals: input.decimals }\n : {}),\n };\n }\n if (\n ![\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"].includes(\n String(kind),\n )\n )\n return;\n if (\n input.sourceUnit !== undefined &&\n ![\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n return;\n if (\n input.style !== undefined &&\n ![\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style))\n )\n return;\n if (input.pattern !== undefined && !string(input.pattern, 1000)) return;\n if (input.timeZone !== undefined && !string(input.timeZone)) return;\n const out: Record<string, unknown> = { kind };\n if (\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n out.decimals = input.decimals;\n if (\n [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n out.sourceUnit = input.sourceUnit;\n if ([\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style)))\n out.style = input.style;\n if (string(input.pattern, 1000)) out.pattern = input.pattern;\n if (string(input.timeZone)) out.timeZone = input.timeZone;\n return out as unknown as PropertyFormat;\n}\n\n/** Strict envelope/version checks prevent interpreting future saved views as empty. */\nexport function normalizePropertyView(input: unknown): PropertyViewState {\n if (!record(input) || input.version !== 1 || !Array.isArray(input.properties))\n throw new Error(\n \"Unsupported or invalid property view (expected version 1).\",\n );\n if (input.properties.length > MAX_PROPERTIES)\n throw new Error(`At most ${MAX_PROPERTIES} properties are allowed.`);\n const ids = new Set<string>();\n const properties = input.properties.map((item): PropertySelection => {\n if (\n !record(item) ||\n !string(item.id) ||\n !string(item.field) ||\n ids.has(item.id)\n )\n throw new Error(\"Property fields and unique instance IDs are required.\");\n ids.add(item.id);\n const property: PropertySelection = { id: item.id, field: item.field };\n if (string(item.label, 1000)) property.label = item.label;\n if (string(item.render)) property.render = item.render;\n if (item.format !== undefined) {\n const format = normalizePropertyFormat(item.format);\n if (!format) throw new Error(`Invalid format for property ${item.id}.`);\n property.format = format;\n }\n return property;\n });\n const labelWidth = typeof input.labelWidth === \"number\" && Number.isFinite(input.labelWidth)\n ? Math.max(15, Math.min(75, Math.round(input.labelWidth))) : undefined;\n return { version: 1, properties, ...(labelWidth !== undefined ? { labelWidth } : {}) };\n}\n\nexport function createPropertyView<Row>(\n schema: FieldSchema<Row>,\n names?: string[],\n): PropertyViewState {\n const enabled = schema.fields.filter((f) => f.property?.enabled !== false);\n const hasPropertyDefaults = enabled.some(\n (f) => f.property?.default !== undefined,\n );\n const defaults = hasPropertyDefaults\n ? enabled.filter((f) => f.property?.default).map((f) => f.name)\n : (schema.defaultSelect?.map((column) => column.field) ??\n enabled.filter((f) => f.select?.default).map((f) => f.name));\n const fields =\n names ??\n (hasPropertyDefaults || defaults.length\n ? defaults.filter((name) => enabled.some((field) => field.name === name))\n : enabled.map((f) => f.name));\n return normalizePropertyView({\n version: 1,\n properties: fields.map((field, i) => ({ id: `property-${i}`, field })),\n });\n}\n\nexport interface FieldOrigin {\n table: string;\n column: string;\n}\n/** Backend discovery groups composite key columns in constraint order. */\nexport interface ForeignKey {\n sourceTable: string;\n sourceColumns: string[];\n targetTable: string;\n targetColumns: string[];\n}\nexport interface ObjectTypeDefinition {\n name: string;\n table: string;\n keyFields: string[];\n}\nexport interface FieldRelationship {\n objectType: string;\n /** Target key field -> local catalogue field, including composite keys. */\n key: Record<string, string>;\n}\nexport interface ObjectReference {\n objectType: string;\n key: Record<string, RowId>;\n}\nexport interface ResolvedObjectReference {\n reference: ObjectReference;\n label?: string;\n href?: string;\n}\n/** Hosts resolve a batch through their authorized APIs, and own application routes. */\nexport interface RelationshipAdapter {\n resolve(\n references: ObjectReference[],\n signal?: AbortSignal,\n ): Promise<ResolvedObjectReference[]>;\n}\nexport function objectReferenceKey(reference: ObjectReference): string {\n return JSON.stringify([\n reference.objectType,\n Object.entries(reference.key).sort(([a], [b]) => a.localeCompare(b)),\n ]);\n}\nexport function readObjectReference<Row>(\n field: FieldDef<Row>,\n fields: FieldDef<Row>[],\n row: Row,\n): ObjectReference | null {\n const relationship = field.relationship;\n if (!relationship) return null;\n const key: Record<string, RowId> = Object.create(null);\n for (const [target, local] of Object.entries(relationship.key)) {\n const source = fields.find((f) => f.name === local);\n if (!source) return null;\n const value = readFieldValue(source, row);\n if (\n !(\n (typeof value === \"string\" && value !== \"\") ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n )\n return null;\n key[target] = value as RowId;\n }\n return Object.keys(key).length\n ? { objectType: relationship.objectType, key }\n : null;\n}\n\n/** Only unambiguous, fully mapped constraints become links. Explicit metadata wins. */\nexport function discoverFieldRelationships<Row>(\n fields: FieldDef<Row>[],\n keys: ForeignKey[],\n types: ObjectTypeDefinition[],\n): FieldDef<Row>[] {\n return fields.map((field) => {\n if (field.relationship || !field.origin) return field;\n const candidates: FieldRelationship[] = [];\n for (const fk of keys) {\n if (\n fk.sourceTable !== field.origin.table ||\n !fk.sourceColumns.includes(field.origin.column) ||\n fk.sourceColumns.length === 0 ||\n fk.sourceColumns.length !== fk.targetColumns.length\n )\n continue;\n const targets = types.filter(\n (type) =>\n type.table === fk.targetTable &&\n type.keyFields.length === fk.targetColumns.length &&\n type.keyFields.every((k) => fk.targetColumns.includes(k)),\n );\n if (targets.length !== 1) continue;\n const key: Record<string, string> = Object.create(null);\n let complete = true;\n fk.sourceColumns.forEach((column, i) => {\n const local = fields.filter(\n (f) =>\n f.origin?.table === fk.sourceTable && f.origin.column === column,\n );\n if (local.length !== 1) complete = false;\n else key[fk.targetColumns[i]!] = local[0]!.name;\n });\n if (complete) candidates.push({ objectType: targets[0]!.name, key });\n }\n return candidates.length === 1\n ? { ...field, relationship: candidates[0]! }\n : field;\n });\n}\n","// schema.ts — the field schema: the contract that binds frontend and backend.\n//\n// A `FieldSchema` is the runtime, frontend-facing projection of a JSON schema\n// document (schema/query-table.schema.json). The same document is projected on\n// the backend into a Go `Schema` of SQL bindings. Codegen keeps the two in sync.\n//\n// `FieldDef` is organized to make two things obvious (per design feedback):\n//\n// 1. WHAT KIND of field it is — the `source` discriminated union. A `backend`\n// field is a column the server returns and can filter/sort; a `derived`\n// field is computed on the client (or render-only) and is never pushed to\n// the server. Each kind uses its own property subset, so you can't, say,\n// mark a client-only column as server-filterable.\n//\n// 2. CONFIG vs CODE. Everything except `source.accessor` and `render` is\n// declarative, serializable config grouped by capability (`filter`, `sort`,\n// `select`, `display`). The only code-bearing members are the derived\n// `accessor` and the `render` function — kept apart from the config.\n\nimport type { AggOp, FilterOp, OrderByClause, SelectColumn } from \"./query\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { parseCellDisplay } from \"./cellDisplay\";\nimport { normalizePropertyFormat, type PropertyFieldConfig, type FieldOrigin, type FieldRelationship } from \"./properties\";\n\nexport type FieldType =\n | \"text\"\n | \"number\"\n | \"enum\"\n | \"datetime\"\n | \"bool\"\n | \"textarray\"; // array-of-text; supports `includes`, and null-as-empty semantics\n\nexport type Align = \"left\" | \"right\" | \"center\";\n\n/** A cell renderer is resolved by name against a `RenderRegistry` (in\n * @pythia-software/query-table-ui) or supplied inline. The type lives in core so FieldDef can\n * reference it, but core never imports React — `unknown` stands in for the node\n * and @pythia-software/query-table-ui narrows it to `React.ReactNode`. */\nexport type CellRenderer<Row = any, V = unknown> = (ctx: {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n}) => unknown;\n\n// ---- source: WHAT KIND of field (discriminated union) ---------------------\n\n/** A column the backend returns and can filter/sort. Its SQL expression lives in\n * the JSON schema doc's `bindings` (and the Go Schema), never on the frontend. */\nexport interface BackendField {\n kind: \"backend\";\n /** Dotted path into the API row when it differs from `name` (e.g. \"enqueued_at.Time\"). */\n path?: string;\n /** Computed SQL with no backing column (e.g. is_starred). Documentation hint\n * surfaced to the picker; the actual expression is server-side. */\n synthetic?: boolean;\n}\n\n/** A value computed on the client, or a purely render-driven column. Never\n * pushed to the server; client-side filtering/sorting (if any) reads `accessor`. */\nexport interface DerivedField<Row = any, V = unknown> {\n kind: \"derived\";\n /** Backend inputs required for accessors and computed formulas. */\n dependencies?: string[];\n /** Reusable computed column ID; always select-only. */\n computedId?: string;\n /** Compute the value from the row for client filter/sort. Omit for render-only\n * columns (the renderer reads the whole row from CellContext instead). */\n accessor?: (row: Row) => V;\n}\n\nexport type FieldSource<Row = any, V = unknown> = BackendField | DerivedField<Row, V>;\n\n// ---- capability config (declarative; serializable; shared with backend) ----\n\n/** How filter-value candidates are offered. Autocomplete is the DEFAULT for\n * every field (design feedback): the value input is a combobox backed by\n * Transport.fetchDistinctValues, which takes a search string so large domains\n * refine per keystroke on the backend. `static` is for closed domains you don't\n * want a round-trip for; `freeform` opts out of suggestions entirely. */\nexport type FilterValues =\n | { source: \"autocomplete\" }\n | { source: \"static\"; options: Array<string | { value: string; label: string }> }\n | { source: \"freeform\" };\n\nexport interface FilterConfig {\n /** Opt into the native multi-value editor: ANY/ALL/NONE/EMPTY for textarray\n * fields; ANY/NONE for enum fields and text fields with static options. */\n editor?: \"set\";\n /** Preserve case when matching textarray values. Default false. */\n arrayCaseSensitive?: boolean;\n /** Whether this field is filterable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Evaluate on the backend (predicate pushdown)? Default: backend ⇒ true.\n * false ⇒ the clause is stripped from the server request and applied locally\n * by applyQuery (the \"serverFilter:false\" derived/JSONB-less columns). */\n pushdown?: boolean;\n /** Override the default operator set for the field's type. */\n ops?: FilterOp[];\n /** Value-suggestion strategy. Default { source: \"autocomplete\" }. */\n values?: FilterValues;\n}\n\nexport interface SortConfig {\n /** Whether this field is sortable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Server field to ORDER BY when it differs from the display field\n * (e.g. a \"★\" column whose server sort key is `is_starred`). */\n field?: string;\n}\n\nexport interface SelectConfig {\n /** Can this appear as a visible column? Default true. false ⇒ filter-only field. */\n enabled?: boolean;\n /** Shown by default when QueryState.select is empty. */\n default?: boolean;\n /** Default column width (px); a per-column override rides in QueryState.select. */\n width?: number;\n /** Narrowest usable width (px) when fitting columns to the screen, such as\n * the room a host renderer's buttons need. Measured native controls are\n * always kept whole; this adds room they cannot measure. */\n minWidth?: number;\n align?: Align;\n}\n\nexport interface AggregateConfig {\n /** Can this field be a metric's MEASURE (sum/avg/min/max/count_distinct)?\n * Default: backend ⇒ true, derived ⇒ false. */\n measure?: boolean;\n /** Can this field be a GROUP BY key? Default: enum/text/bool ⇒ true. */\n groupable?: boolean;\n /** Override the default aggregate-op set for the field's type. */\n ops?: AggOp[];\n}\n\n// ---- the field ------------------------------------------------------------\n\nexport interface FieldDef<Row = any, V = unknown> {\n // identity\n name: string; // canonical id; matches the backend binding key + Where/OrderBy `field`\n label: string;\n type: FieldType;\n\n // WHAT KIND of field (value origin + server capability)\n source: FieldSource<Row, V>;\n\n // capabilities (declarative config; omit for sensible per-source defaults)\n filter?: FilterConfig;\n sort?: SortConfig;\n select?: SelectConfig;\n aggregate?: AggregateConfig;\n\n // discovery (picker UX, declarative)\n group?: string; // grouping bucket\n alias?: string; // single alternative search term\n aliases?: string[]; // extra search terms\n\n /** Declarative built-in presentation, independent of the query's field type.\n * An explicit render function or registered render key takes precedence. */\n display?: CellDisplay;\n // custom presentation: registry key or inline fn\n render?: string | CellRenderer<Row, V>;\n property?: PropertyFieldConfig;\n /** Structured provenance for relationship discovery; never SQL text. */\n origin?: FieldOrigin;\n relationship?: FieldRelationship;\n}\n\n/** The frontend's loaded schema for one dataset. */\nexport interface FieldSchema<Row = any> {\n /** Dataset id, also the StorageAdapter namespace for saved queries. */\n name: string;\n /** Field that yields a row's stable id for selection / per-row refresh. */\n idField: string;\n fields: FieldDef<Row>[];\n /** Sort applied when QueryState.orderBy is empty. */\n defaultSort?: OrderByClause[];\n /** Columns shown when QueryState.select is empty. */\n defaultSelect?: SelectColumn[];\n /** Page size for a fresh query. */\n defaultLimit?: number;\n}\n\n// ---- derived capability helpers (the per-source defaults, in one place) ----\n\nexport function isFilterable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return false;\n return f.filter?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isPushdownFilter(f: FieldDef): boolean {\n return isFilterable(f) && (f.filter?.pushdown ?? f.source.kind === \"backend\");\n}\nexport function isSortable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return f.sort?.enabled === true;\n return f.sort?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isSelectable(f: FieldDef): boolean {\n return f.select?.enabled ?? true;\n}\nexport function filterValues(f: FieldDef): FilterValues {\n return f.filter?.values ?? { source: \"autocomplete\" };\n}\n\n// ---- schema operations ----------------------------------------------------\n\n/** Index fields by name for O(1) lookup. */\nexport function indexFields<Row>(schema: FieldSchema<Row>): Map<string, FieldDef<Row>> {\n return new Map(schema.fields.map((f) => [f.name, f]));\n}\n\n/** Resolve the ordered, selectable FieldDefs for a query, falling back to schema\n * defaults, then to every `select.default` field. Unknown/duplicate/unselectable\n * names in `select` are dropped. */\nexport function selectedFields<Row>(\n schema: FieldSchema<Row>,\n q: { select: SelectColumn[] },\n): FieldDef<Row>[] {\n const order =\n q.select.length > 0\n ? q.select.map((c) => c.field)\n : (schema.defaultSelect ?? schema.fields.filter((f) => f.select?.default).map((f) => ({ field: f.name }))).map(\n (c) => c.field,\n );\n const seen = new Set<string>();\n const out: FieldDef<Row>[] = [];\n for (const name of order) {\n if (seen.has(name)) continue;\n const f = resolveField(schema, name);\n if (!f || !isSelectable(f)) continue;\n seen.add(name);\n seen.add(f.name);\n out.push(f);\n }\n return out;\n}\n\n/** Resolve a field token to a concrete field by canonical name, case-insensitive\n * name match, or alias match. */\nexport function resolveField<Row>(schema: FieldSchema<Row>, field: string): FieldDef<Row> | undefined {\n const token = field.trim();\n if (!token) return undefined;\n\n const byName = indexFields(schema);\n const byExactName = byName.get(token);\n if (byExactName) return byExactName;\n\n const needle = token.toLowerCase();\n for (const f of schema.fields) {\n if (f.name.toLowerCase() === needle) return f;\n if (aliasMatches(f, needle)) return f;\n }\n return undefined;\n}\n\n/** Return the canonical name for a query token, or undefined when unresolved. */\nexport function resolveFieldName<Row>(schema: FieldSchema<Row>, field: string): string | undefined {\n return resolveField(schema, field)?.name;\n}\n\n/** All configured aliases for a field (deduped, preserving display shape). */\nexport function aliasTermsFor<Row>(field: FieldDef<Row>): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(value);\n };\n\n add(field.alias);\n if (field.aliases) {\n for (const alias of field.aliases) add(alias);\n }\n\n return out;\n}\n\nfunction aliasMatches(field: FieldDef, needle: string): boolean {\n for (const alias of aliasTermsFor(field)) {\n if (alias.toLowerCase() === needle) return true;\n }\n return false;\n}\n\n/** Read a field's value from a row: derived `accessor` if present, else the\n * backend `path` (dotted) / `name`. Returns null when any path segment is missing. */\nexport function readFieldValue<Row, V = unknown>(field: FieldDef<Row, V>, row: Row): V | null {\n if (row == null) return null;\n if (field.source.kind === \"derived\" && field.source.accessor) {\n return field.source.accessor(row);\n }\n const path = (field.source.kind === \"backend\" && field.source.path) || field.name;\n const r = row as Record<string, unknown>;\n if (path in r) return (r[path] ?? null) as V | null;\n let cur: unknown = row;\n for (const part of path.split(\".\")) {\n if (cur == null || typeof cur !== \"object\") return null;\n cur = (cur as Record<string, unknown>)[part];\n }\n return (cur ?? null) as V | null;\n}\n\n/** Parse + validate a raw JSON schema document into a FieldSchema. The doc is the\n * same one the Go backend loads; here we drop backend `bindings` (the frontend\n * never sees SQL) and leave `render` as a string key the consumer maps to a\n * renderer at runtime. Throws with a readable message on a malformed document. */\nexport function loadSchema<Row = any>(doc: unknown): FieldSchema<Row> {\n const d = doc as Record<string, any>;\n if (!d || typeof d !== \"object\") throw new Error(\"schema: document is not an object\");\n if (typeof d.name !== \"string\") throw new Error(\"schema: missing `name`\");\n if (typeof d.idField !== \"string\") throw new Error(\"schema: missing `idField`\");\n if (!Array.isArray(d.fields) || d.fields.length === 0) throw new Error(\"schema: `fields` must be a non-empty array\");\n\n const fields: FieldDef<Row>[] = d.fields.map((raw: any, i: number) => projectField<Row>(raw, i));\n return {\n name: d.name,\n idField: d.idField,\n fields,\n defaultSort: d.defaultSort,\n defaultSelect: d.defaultSelect,\n defaultLimit: d.defaultLimit,\n };\n}\n\nfunction projectField<Row>(raw: any, i: number): FieldDef<Row> {\n if (!raw || typeof raw.name !== \"string\") throw new Error(`schema: field[${i}] missing \\`name\\``);\n if (typeof raw.label !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`label\\``);\n if (typeof raw.type !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`type\\``);\n if (raw.property !== undefined) {\n const property = raw.property;\n if (!property || typeof property !== \"object\" || Array.isArray(property)\n || (property.enabled !== undefined && typeof property.enabled !== \"boolean\")\n || (property.default !== undefined && typeof property.default !== \"boolean\")\n || (property.render !== undefined && (typeof property.render !== \"string\" || !property.render))) {\n throw new Error(`schema: field ${raw.name} has invalid property metadata`);\n }\n if (property.format !== undefined && !normalizePropertyFormat(property.format)) {\n throw new Error(`schema: field ${raw.name} has an invalid property format`);\n }\n }\n if (raw.origin !== undefined && (!raw.origin\n || typeof raw.origin.table !== \"string\" || !raw.origin.table\n || typeof raw.origin.column !== \"string\" || !raw.origin.column)) {\n throw new Error(`schema: field ${raw.name} has an invalid origin`);\n }\n if (raw.relationship !== undefined && (!raw.relationship\n || typeof raw.relationship.objectType !== \"string\" || !raw.relationship.objectType\n || !raw.relationship.key || typeof raw.relationship.key !== \"object\"\n || Array.isArray(raw.relationship.key) || Object.keys(raw.relationship.key).length === 0\n || Object.entries(raw.relationship.key).some(([key, value]) => !key || typeof value !== \"string\" || !value))) {\n throw new Error(`schema: field ${raw.name} has an invalid relationship`);\n }\n\n // `source` accepts a string shorthand (\"backend\"|\"derived\") or an object.\n const rs = raw.source ?? (raw.bindings ? \"backend\" : \"derived\");\n let source: FieldSource<Row>;\n if (typeof rs === \"string\") {\n source = rs === \"derived\" ? { kind: \"derived\" } : { kind: \"backend\" };\n } else if (rs.kind === \"derived\") {\n source = { kind: \"derived\" }; // accessor is code → attached at runtime, never from JSON\n } else {\n source = { kind: \"backend\", path: rs.path, synthetic: rs.synthetic };\n }\n\n return {\n name: raw.name,\n label: raw.label,\n type: raw.type,\n source,\n filter: raw.filter,\n sort: raw.sort,\n select: raw.select,\n aggregate: raw.aggregate,\n group: raw.group,\n alias: raw.alias,\n aliases: normalizeAliases(raw.aliases, raw.alias),\n ...(raw.display === undefined ? {} : { display: parseCellDisplay(raw.display, `schema: field ${raw.name} display`) }),\n render: raw.render, // string key from JSON; consumer may override with a fn\n property: raw.property ? { ...raw.property, format: raw.property.format === undefined ? undefined : normalizePropertyFormat(raw.property.format) } : undefined,\n origin: raw.origin,\n relationship: raw.relationship,\n };\n}\n\nfunction normalizeAliases(rawAliases: unknown, rawAlias: unknown): string[] {\n const aliases: string[] = [];\n const seen = new Set<string>();\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n aliases.push(value);\n };\n\n add(rawAlias);\n if (Array.isArray(rawAliases)) {\n for (const item of rawAliases) add(item);\n }\n return aliases;\n}\n","import { readFieldValue, type FieldSchema } from \"./schema\";\nimport type { RowId } from \"./query\";\n\n// Literal URL templates, shared by item pages and group link columns.\n// Substitution never evaluates code or nested paths: each placeholder is a bare\n// token or {field:name}, and every substituted value is percent-encoded.\n\nconst MAX_TEMPLATE_LENGTH = 8000;\nconst BASE = \"https://query-table.invalid/\";\nconst ITEM_PAGE_TOKENS = [\"id\", \"query\"] as const;\n\nfunction placeholders(tokens: readonly string[]): RegExp {\n return new RegExp(`\\\\{(${[...tokens, \"field:[^{}]+\"].join(\"|\")})\\\\}`, \"g\");\n}\n\nfunction httpOrRelative(href: string): boolean {\n try {\n return [\"http:\", \"https:\"].includes(new URL(href, BASE).protocol);\n } catch {\n return false;\n }\n}\n\n/** The distinct `{field:name}` references in a template. */\nexport function templateFields(template: string): string[] {\n return [...new Set(Array.from(template.matchAll(/\\{field:([^{}]+)\\}/g), match => match[1]!))];\n}\n\n/** Why a URL template is invalid, or null. An empty template is valid here;\n * callers that require a URL check for it. `tokens` are the bare placeholders\n * allowed besides `{field:name}`; `hasField` decides which names exist. */\nexport function urlTemplateProblem(template: string, tokens: readonly string[], hasField: (name: string) => boolean): string | null {\n if (template.length > MAX_TEMPLATE_LENGTH) return \"Use a URL template of at most 8,000 characters.\";\n if (!template.trim()) return null;\n const remainder = template.replace(placeholders(tokens), \"value\");\n if (/[{}]/.test(remainder)) {\n const names = [...tokens.map(token => `{${token}}`), \"{field:field_name}\"];\n const list = names.length > 1 ? `${names.slice(0, -1).join(\", \")}${names.length > 2 ? \",\" : \"\"} or ${names.at(-1)}` : names[0];\n return `Use ${list} placeholders.`;\n }\n for (const name of templateFields(template)) {\n if (!hasField(name)) return `Unknown URL field: ${name}.`;\n }\n try {\n if (![\"http:\", \"https:\"].includes(new URL(remainder, BASE).protocol))\n return \"Use an HTTP, HTTPS, or relative page URL.\";\n } catch { return \"Enter a valid page URL.\"; }\n return null;\n}\n\n/** Substitute a validated template. `read` returns each token's value (bare\n * tokens by name, fields as `field:name`); only strings, numbers and booleans\n * substitute. Returns null when a value is missing or the result would not be\n * an HTTP(S) or relative URL. */\nexport function fillUrlTemplate(template: string, tokens: readonly string[], read: (token: string) => unknown): string | null {\n let missing = false;\n const href = template.replace(placeholders(tokens), (_match, token: string) => {\n const value = read(token);\n if (value == null || ![\"string\", \"number\", \"boolean\"].includes(typeof value)) { missing = true; return \"\"; }\n return encodeURIComponent(String(value));\n });\n // Validate again after substitution: a placeholder cannot introduce a scheme.\n return missing || !httpOrRelative(href) ? null : href;\n}\n\nexport function itemPageFields(template: string): string[] {\n return templateFields(template);\n}\nexport function validateItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>): string | null {\n return urlTemplateProblem(template, ITEM_PAGE_TOKENS, name => schema.fields.some(field => field.name === name));\n}\nexport function renderItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>, row: Row, id: RowId | null, query: string): string | null {\n if (!template.trim() || validateItemPageTemplate(template, schema)) return null;\n return fillUrlTemplate(template, ITEM_PAGE_TOKENS, token => token === \"id\" ? id : token === \"query\" ? query\n : readFieldValue(schema.fields.find(field => field.name === token.slice(6))!, row));\n}\n","import type { AggregationClause } from \"./query\";\n\n/** How normalizeMetricOptions validates one option: an allowed value list or a\n * type. \"minCount\" is a positive integer, or an object read with the\n * `minCount` table that has `min` and exactly one of `distinct` and `sum`. */\nexport type MetricOptionSpec = readonly string[] | \"string\" | \"boolean\" | \"integer\" | \"positiveInteger\" | \"number\" | \"minCount\";\n\n/** The option tables normalizeMetricOptions copies from, in output order. Other\n * implementations of query links (the Go module) are checked against this\n * table through schema/fixtures/metric-options.json. */\nexport const METRIC_OPTION_SPECS = {\n top: {\n expression: \"string\",\n expressionY: \"string\",\n scope: [\"allMatching\", \"shownRows\"],\n groupLimit: \"integer\",\n minCount: \"minCount\",\n share: [\"total\", \"group0\"],\n },\n minCount: {\n min: \"positiveInteger\",\n distinct: \"string\",\n sum: \"string\",\n },\n window: {\n reduce: [\"total\", \"mean\"],\n partial: [\"omit\", \"include\"],\n },\n dateGrouping: {\n field: \"string\",\n interval: [\n \"hour\",\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n \"hourOfDay\",\n \"dayOfWeek\",\n ],\n timeZone: \"string\",\n includeEmpty: \"boolean\",\n range: [\"query\", \"observed\", \"custom\"],\n start: \"string\",\n end: \"string\",\n partialIntervals: [\"include\", \"exclude\"],\n },\n occurrence: {\n interval: [\"hour\", \"day\"],\n includeEmpty: \"boolean\",\n },\n display: {\n kind: [\n \"auto\",\n \"value\",\n \"table\",\n \"list\",\n \"bar-horizontal\",\n \"bar-vertical\",\n \"line\",\n \"pie\",\n \"donut\",\n \"scatter\",\n \"box\",\n \"histogram\",\n ],\n valueLabel: \"string\",\n xLabel: \"string\",\n yLabel: \"string\",\n legendPosition: [\"left\", \"right\", \"top\", \"bottom\", \"none\"],\n maxGroups: \"positiveInteger\",\n showOther: \"boolean\",\n boxMean: \"boolean\",\n },\n scale: {\n mode: [\"linear\", \"log\"],\n min: \"number\",\n max: \"number\",\n },\n format: {\n kind: [\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"],\n decimals: \"integer\",\n sourceUnit: [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ],\n style: [\"human\", \"long\", \"clock\", \"custom\", \"iso\"],\n pattern: \"string\",\n timeZone: \"string\",\n },\n list: {\n showBars: \"boolean\",\n useGroupColors: \"boolean\",\n showValues: \"boolean\",\n barPosition: [\"inline\", \"below\"],\n maxLabelLines: \"positiveInteger\",\n },\n pivot: {\n swap: \"boolean\",\n rowDir: [\"asc\", \"desc\"],\n columnDir: [\"asc\", \"desc\"],\n },\n distribution: {\n kind: [\"box\", \"histogram\"],\n input: \"string\",\n whiskers: [\"minmax\", \"tukey\"],\n bins: \"integer\",\n },\n layout: {\n widthRem: \"integer\",\n heightRem: \"integer\",\n minWidthRem: \"integer\",\n minHeightRem: \"integer\",\n },\n} as const satisfies Record<string, Record<string, MetricOptionSpec>>;\n\n/** Whitelist every nested property: URL/storage objects never become executable plans. */\nexport function normalizeMetricOptions(\n raw: Record<string, unknown>,\n): Partial<AggregationClause> {\n const out: Record<string, unknown> = {},\n diagnostics: string[] = [];\n const record = (x: unknown): x is Record<string, unknown> =>\n !!x && typeof x === \"object\" && !Array.isArray(x);\n const copy = (\n input: Record<string, unknown>,\n specs: Readonly<Record<string, MetricOptionSpec>>,\n ): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, spec] of Object.entries(specs)) {\n const v = input[key];\n if (v === undefined) continue;\n if (spec === \"minCount\") {\n const m = record(v) ? copy(v, METRIC_OPTION_SPECS.minCount) : v;\n const named = (x: unknown) =>\n x === undefined || (typeof x === \"string\" && !!x && x.length <= 256);\n if (\n record(m)\n ? m.min !== undefined &&\n (m.distinct === undefined) !== (m.sum === undefined) &&\n named(m.distinct) &&\n named(m.sum)\n : typeof m === \"number\" &&\n Number.isSafeInteger(m) &&\n m >= 1 &&\n m <= 1000000\n )\n result[key] = m;\n else diagnostics.push(`Invalid metric ${key}.`);\n continue;\n }\n if (\n spec === \"string\"\n ? typeof v === \"string\" && v.length <= 10000\n : spec === \"number\"\n ? typeof v === \"number\" && Number.isFinite(v)\n : spec === \"boolean\"\n ? typeof v === \"boolean\"\n : spec === \"integer\" || spec === \"positiveInteger\"\n ? typeof v === \"number\" &&\n Number.isSafeInteger(v) &&\n v >= (spec === \"positiveInteger\" ? 1 : 0) &&\n v <= 1000000\n : typeof v === \"string\" && spec.includes(v)\n )\n result[key] = v;\n else diagnostics.push(`Invalid metric ${key}.`);\n }\n return result;\n };\n Object.assign(\n out,\n copy(raw, METRIC_OPTION_SPECS.top),\n );\n if (raw.window !== undefined) {\n if (record(raw.window)) {\n const w = copy(raw.window, METRIC_OPTION_SPECS.window);\n const periods = raw.window.periods;\n if (periods === \"all\" || (Number.isSafeInteger(periods) && (periods as number) >= 0 && (periods as number) <= 1000000))\n w.periods = periods;\n else diagnostics.push(\"Invalid metric window.\");\n out.window = w;\n } else diagnostics.push(\"Invalid metric window.\");\n }\n if (raw.dateGrouping !== undefined) {\n if (record(raw.dateGrouping)) {\n const d = copy(raw.dateGrouping, METRIC_OPTION_SPECS.dateGrouping);\n if (\n typeof d.field !== \"string\" ||\n !d.field ||\n d.field.length > 256 ||\n !d.interval ||\n typeof d.includeEmpty !== \"boolean\" ||\n !d.range\n )\n diagnostics.push(\"Invalid metric date grouping.\");\n const occurrence = raw.dateGrouping.occurrence;\n if (record(occurrence)) {\n const o = copy(occurrence, METRIC_OPTION_SPECS.occurrence);\n if (!o.interval || typeof o.includeEmpty !== \"boolean\")\n diagnostics.push(\"Invalid metric date grouping occurrence.\");\n d.occurrence = o;\n } else if (occurrence !== undefined)\n diagnostics.push(\"Invalid metric date grouping occurrence.\");\n out.dateGrouping = d;\n } else diagnostics.push(\"Invalid metric date grouping.\");\n }\n if (raw.display !== undefined) {\n if (record(raw.display)) {\n if (typeof raw.display.kind !== \"string\")\n diagnostics.push(\"Invalid metric display kind.\");\n const d = copy(raw.display, METRIC_OPTION_SPECS.display);\n for (const k of [\"xScale\", \"yScale\"]) {\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], METRIC_OPTION_SPECS.scale);\n else if (raw.display[k] !== undefined)\n diagnostics.push(`Invalid metric ${k}.`);\n }\n for (const k of [\"format\", \"xFormat\", \"yFormat\"])\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], METRIC_OPTION_SPECS.format);\n if (record(raw.display.list))\n d.list = copy(raw.display.list, METRIC_OPTION_SPECS.list);\n if (record(raw.display.pivot))\n d.pivot = copy(raw.display.pivot, METRIC_OPTION_SPECS.pivot);\n out.display = { kind: \"auto\", ...d };\n } else diagnostics.push(\"Invalid metric display.\");\n }\n if (raw.distribution !== undefined) {\n if (record(raw.distribution))\n out.distribution = copy(raw.distribution, METRIC_OPTION_SPECS.distribution);\n else diagnostics.push(\"Invalid metric distribution.\");\n }\n if (record(raw.layout)) {\n const l = copy(raw.layout, METRIC_OPTION_SPECS.layout);\n for (const k of [\"widthRem\", \"heightRem\", \"minWidthRem\", \"minHeightRem\"])\n l[k] = Math.max(1, Math.min(1000, Number(l[k] ?? 1)));\n l.widthRem = Math.max(Number(l.widthRem), Number(l.minWidthRem));\n l.heightRem = Math.max(Number(l.heightRem), Number(l.minHeightRem));\n out.layout = l;\n }\n if (raw.sort !== undefined && !Array.isArray(raw.sort))\n diagnostics.push(\"Invalid metric sort.\");\n if (Array.isArray(raw.sort))\n out.sort = raw.sort.slice(0, 20).flatMap((s) => {\n if (\n !record(s) ||\n typeof s.key !== \"string\" ||\n !/^(value|y|count|samples|group(?:0|[1-9][0-9]?))$/.test(s.key) ||\n ![\"asc\", \"desc\"].includes(String(s.dir))\n ) {\n diagnostics.push(\"Invalid metric sort.\");\n return [];\n }\n return [\n copy(s, {\n key: [s.key],\n dir: [\"asc\", \"desc\"],\n nulls: [\"first\", \"last\"],\n }),\n ];\n });\n if (Array.isArray(raw.diagnostics))\n diagnostics.push(\n ...raw.diagnostics\n .filter((s): s is string => typeof s === \"string\" && s.length <= 1000)\n .slice(0, 20),\n );\n if (diagnostics.length) out.diagnostics = [...new Set(diagnostics)];\n return out as Partial<AggregationClause>;\n}\n","const UNIT_MS: Record<string, number> = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000 };\n/** Portable datetime/offset bound in milliseconds (also below MAX_SAFE_INTEGER). */\nexport const MAX_RELATIVE_TIME_MS = 8_640_000_000_000_000;\n\n/** A signed elapsed offset, e.g. -1h or +8d2h10m. The sign applies to the\n * complete sum. Returns null for absolute values or invalid duration syntax.\n * Units are lowercase; amounts are whole integers. No whitespace, calendar\n * arithmetic, locale, or Date.parse heuristics are used. */\nexport function parseRelativeDuration(value: string): number | null {\n const valid = /^[+-](?:[0-9]+(?:ms|s|m|h|d|w))+$/.exec(value);\n if (!valid || valid[0] !== value) return null;\n const body = value.slice(1);\n const components = /([0-9]+)(ms|s|m|h|d|w)/g;\n let total = 0;\n for (const match of body.matchAll(components)) {\n const amount = Number(match[1]);\n const unit = UNIT_MS[match[2]!]!;\n if (!Number.isSafeInteger(amount) || amount > Math.floor((MAX_RELATIVE_TIME_MS - total) / unit)) return null;\n total += amount * unit;\n }\n return value[0] === \"-\" && total !== 0 ? -total : total;\n}\n\n/** Local execution only. The server independently owns its execution clock. */\nexport interface QueryEvaluationOptions { now?: number }\n\nexport function evaluationTime(options: QueryEvaluationOptions): number {\n const now = options.now ?? Date.now();\n if (!Number.isSafeInteger(now) || Math.abs(now) > MAX_RELATIVE_TIME_MS) throw new Error(\"Invalid query evaluation time\");\n return now;\n}\n\nexport function relativeTimestamp(now: number, offsetMs: number): number {\n const result = now + offsetMs;\n if (!Number.isSafeInteger(result) || Math.abs(result) > MAX_RELATIVE_TIME_MS) throw new Error(\"Relative time exceeds datetime limits\");\n return result;\n}\n","// ops.ts — which operators a field type allows, and value coercion.\n//\n// Single source of truth for \"what filters can I build on this field\", shared by\n// the QueryBuilder UI, the CellMenu quick-filters, and client-side applyQuery.\n// The backend (backends/go) enforces the same matrix independently — never trust\n// the client.\n//\n// Every value can be NULL, so `is_null`/`is_not_null` are available on EVERY\n// type, including bool (design feedback).\n\nimport { parseRelativeDuration, relativeTimestamp } from \"./relativeTime\";\nimport type { FilterOp, FieldType, FieldDef, WhereClause } from \"./index\";\n\nconst NULLITY: FilterOp[] = [\"is_null\", \"is_not_null\"];\n\n/** Operators that are each other's logical complement. Negating one of these is\n * a clean op flip (no NULL surprises the two ops don't already share), so the\n * UI can render `≥ 10`'s negation as `< 10` rather than `NOT (≥ 10)`. Ops absent\n * here (`contains`/`starts_with`/`ends_with`/`includes`) have no single-op\n * complement and negate via the `WhereClause.negated` flag instead. */\nconst COMPLEMENT_OP: Partial<Record<FilterOp, FilterOp>> = {\n \"=\": \"!=\",\n \"!=\": \"=\",\n \">\": \"<=\",\n \"<=\": \">\",\n \">=\": \"<\",\n \"<\": \">=\",\n is_null: \"is_not_null\",\n is_not_null: \"is_null\",\n matches_regex: \"not_matches_regex\",\n not_matches_regex: \"matches_regex\",\n};\n\n/** The logical negation of a predicate. Prefers flipping to the complementary\n * operator (nicer to read, and the server's op allowlist already covers it);\n * falls back to toggling the `negated` flag when the op has no complement, or\n * when the complement is not in `allowedOps` (a field's `filter.ops` override\n * could disable it, and the server would reject a disabled op). `allowedOps`,\n * when given, is the field's effective operator set from `opsForField`. */\nexport function negateClause(clause: WhereClause, allowedOps?: readonly FilterOp[]): WhereClause {\n if (clause.value === \"0\" && !clause.negated) {\n const zeroComplement = clause.op === \"length_gt\" ? \"length_eq\" : clause.op === \"length_eq\" ? \"length_gt\" : null;\n if (zeroComplement && (!allowedOps || allowedOps.includes(zeroComplement))) {\n return { field: clause.field, op: zeroComplement, value: \"0\" };\n }\n }\n const complement = COMPLEMENT_OP[clause.op];\n if (complement && (!allowedOps || allowedOps.includes(complement))) {\n const next: WhereClause = { field: clause.field, op: complement, value: clause.value };\n return next; // a complement fully expresses the negation; drop any stale flag\n }\n const next: WhereClause = { field: clause.field, op: clause.op, value: clause.value };\n if (!clause.negated) next.negated = true;\n return next;\n}\n\n/** Whether a predicate is negative — either an op that reads as a negation\n * (`!=`, `not_matches_regex`, `is_not_null`) or one carrying the `negated`\n * flag. Used to sort candidate filters into the CellMenu's two columns. */\nexport function isNegativePredicate(clause: Pick<WhereClause, \"op\" | \"negated\">): boolean {\n return Boolean(clause.negated) || clause.op === \"!=\" || clause.op === \"not_matches_regex\" || clause.op === \"is_not_null\";\n}\n\n/** A specific operator + negation state, e.g. `{ op: \"<\", negated: false }` or\n * `{ op: \"contains\", negated: true }`. */\nexport interface OpChoice {\n op: FilterOp;\n negated: boolean;\n}\n\n/** A positive operator (\"keep\") and its logical negation (\"exclude\") — the row\n * shape rendered by both the CellMenu quick-filters and the WHERE operator\n * picker, so the two read identically. */\nexport interface OpPair {\n keep: OpChoice;\n exclude: OpChoice;\n}\n\n/** Positive operators surfaced in the \"keep\" column, in display order. Each\n * one's negation lands opposite via `negateClause`, so the pair covers\n * `<`/`<=`/`!=`/`not_matches_regex` without listing them separately. */\nconst POSITIVE_OP_ORDER: FilterOp[] = [\"=\", \">\", \">=\", \"contains\", \"starts_with\", \"ends_with\", \"length_gt\", \"length_lt\", \"length_eq\", \"matches_regex\", \"includes\"];\n\n/** The keep/exclude operator pairs offered for a field: each positive op with\n * its negation opposite, then a nullity row (`is null`/`is not null`) when the\n * field allows it. Derived from the field's effective op set and `negateClause`,\n * so a `filter.ops` override narrows the offered pairs too. */\nexport function opPairsForField(field: Pick<FieldDef, \"type\" | \"filter\">): OpPair[] {\n const ops = opsForField(field);\n const allow = new Set(ops);\n const pairs: OpPair[] = [];\n for (const op of POSITIVE_OP_ORDER) {\n if (!allow.has(op)) continue;\n const neg = negateClause({ field: \"\", op, value: \"\" }, ops);\n pairs.push({ keep: { op, negated: false }, exclude: { op: neg.op, negated: Boolean(neg.negated) } });\n }\n if (allow.has(\"is_null\") || allow.has(\"is_not_null\")) {\n pairs.push({ keep: { op: \"is_null\", negated: false }, exclude: { op: \"is_not_null\", negated: false } });\n }\n return pairs;\n}\n\n/** Default operator set per type. A FieldDef.filter.ops overrides this. */\nexport const OPS_BY_TYPE: Record<FieldType, FilterOp[]> = {\n text: [\n \"=\",\n \"!=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n ...NULLITY,\n ],\n enum: [\"=\", \"!=\", ...NULLITY],\n number: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n datetime: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n bool: [\"=\", \"!=\", ...NULLITY],\n textarray: [\"includes\", ...NULLITY],\n};\n\n/** Operators that take no value (the value input is hidden). */\nexport const NULLARY_OPS: ReadonlySet<FilterOp> = new Set<FilterOp>(NULLITY);\n\n/** Effective operators for a field (its override, else the type default). */\nexport function opsForField(field: Pick<FieldDef, \"type\" | \"filter\">): FilterOp[] {\n return field.filter?.ops ?? OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (server mirror lives\n * in Go opAllowed; keep them in lockstep). */\nexport function opAllowedForType(type: FieldType, op: FilterOp): boolean {\n return OPS_BY_TYPE[type].includes(op);\n}\n\n/** Coerce a raw string value to the type the field expects, for client-side\n * comparison. Throws on invalid input (e.g. a non-numeric value on a number\n * field) so callers can surface it rather than silently mis-filtering. */\nexport function coerceValue(type: FieldType, raw: string, now?: number): string | number | boolean {\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n if (raw.trim() === \"\" || Number.isNaN(n)) throw new Error(`not a number: ${JSON.stringify(raw)}`);\n return n;\n }\n case \"bool\": {\n const v = raw.toLowerCase();\n if (v === \"true\" || v === \"1\" || v === \"t\") return true;\n if (v === \"false\" || v === \"0\" || v === \"f\") return false;\n throw new Error(`not a bool: ${JSON.stringify(raw)}`);\n }\n case \"datetime\": {\n if (raw.startsWith(\"+\") || raw.startsWith(\"-\")) {\n const offset = parseRelativeDuration(raw);\n if (offset === null) throw new Error(`not a signed duration: ${JSON.stringify(raw)}`);\n return relativeTimestamp(now ?? Date.now(), offset);\n }\n const ms = Date.parse(raw);\n if (Number.isNaN(ms)) throw new Error(`not a datetime: ${JSON.stringify(raw)}`);\n return ms;\n }\n default:\n return raw;\n }\n}\n","import { coerceValue } from \"./ops\";\nimport { isWhereGroup, type QueryState } from \"./query\";\nimport type {\n MetricCycleInterval,\n MetricDateGrouping,\n MetricValue,\n} from \"./metricTypes\";\nimport { Temporal } from \"temporal-polyfill\";\n\nexport const METRIC_DATE_INTERVALS = [\n \"hour\",\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n \"hourOfDay\",\n \"dayOfWeek\",\n] as const;\nexport const METRIC_CYCLE_INTERVALS = [\"hourOfDay\", \"dayOfWeek\"] as const;\n\n/** Whether an interval is cyclic: keyed by slot number, not by date. */\nexport function isMetricCycle(\n interval: string | undefined,\n): interval is MetricCycleInterval {\n return interval === \"hourOfDay\" || interval === \"dayOfWeek\";\n}\n\n/** Every slot of a cyclic interval, in order: 0–23 or 1–7 (ISO, Monday 1). */\nexport function metricCycleSlots(interval: MetricCycleInterval): number[] {\n return interval === \"hourOfDay\"\n ? Array.from({ length: 24 }, (_, i) => i)\n : [1, 2, 3, 4, 5, 6, 7];\n}\n\n/** The calendar interval one occurrence of a slot spans: its hour or day.\n * Calendar intervals are their own unit. */\nexport function metricCalendarUnit(\n interval: MetricDateGrouping[\"interval\"],\n): Exclude<MetricDateGrouping[\"interval\"], MetricCycleInterval> {\n return interval === \"hourOfDay\"\n ? \"hour\"\n : interval === \"dayOfWeek\"\n ? \"day\"\n : interval;\n}\n\n/** The slot an instant occupies in `timeZone`: its local wall-clock hour\n * (0–23), or its local ISO weekday (1 = Monday … 7 = Sunday). */\nexport function metricCycleSlot(\n time: number,\n interval: MetricCycleInterval,\n timeZone = \"UTC\",\n): number {\n if (timeZone === \"UTC\") {\n const date = new Date(time);\n return interval === \"hourOfDay\"\n ? date.getUTCHours()\n : ((date.getUTCDay() + 6) % 7) + 1;\n }\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n return interval === \"hourOfDay\" ? zoned.hour : zoned.dayOfWeek;\n}\n\n/** Strict calendar input; timestamps require an explicit offset. */\nexport function metricDateTime(value: MetricValue, timeZone = \"UTC\"): number {\n if (\n typeof value !== \"string\" ||\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n value,\n )\n )\n throw Error(\n \"Date grouping requires ISO dates or timestamps with a timezone.\",\n );\n const time = Date.parse(value),\n month = Number(value.slice(5, 7)),\n day = Number(value.slice(8, 10));\n const calendar = new Date(0);\n calendar.setUTCFullYear(Number(value.slice(0, 4)), month, 0);\n if (\n !Number.isFinite(time) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > calendar.getUTCDate()\n )\n throw Error(\"Invalid date grouping value.\");\n return value.length === 10 && timeZone !== \"UTC\"\n ? Temporal.PlainDate.from(value).toZonedDateTime(timeZone).epochMilliseconds\n : time;\n}\n\n/** Find an offset change inside one bucket window. The polyfill's \"previous\"\n * transition lookup caps future searches to about three years from today. */\nfunction metricOffsetTransition(\n start: number,\n end: number,\n timeZone: string,\n): number | undefined {\n if (end <= start) return undefined;\n const offset = (time: number) =>\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone)\n .offsetNanoseconds;\n const before = offset(start);\n if (before === offset(end)) return undefined;\n // IANA transitions are separated by more than this hour-sized window.\n while (end - start > 1) {\n const middle = Math.floor((start + end) / 2);\n if (offset(middle) === before) start = middle;\n else end = middle;\n }\n return end;\n}\n\nexport function metricDateFloor(\n time: number,\n cycleOrInterval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n const interval = metricCalendarUnit(cycleOrInterval);\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const floor =\n time - zoned.minute * 60000 - zoned.second * 1000 - zoned.millisecond;\n // An offset change can start a partial hour (e.g. Lord Howe's 30-minute\n // DST shift). Split there rather than mapping into the previous offset.\n return metricOffsetTransition(floor, time, timeZone) ?? floor;\n }\n let date = zoned.toPlainDate();\n if (interval === \"week\") date = date.subtract({ days: date.dayOfWeek - 1 });\n if (interval === \"month\" || interval === \"year\")\n date = date.with({ day: 1 });\n if (interval === \"year\") date = date.with({ month: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n date.setUTCMinutes(0, 0, 0);\n if (interval !== \"hour\") date.setUTCHours(0);\n if (interval === \"week\")\n date.setUTCDate(date.getUTCDate() - ((date.getUTCDay() + 6) % 7));\n if (interval === \"month\" || interval === \"year\") date.setUTCDate(1);\n if (interval === \"year\") date.setUTCMonth(0);\n return date.getTime();\n}\n\nexport function metricDateNext(\n time: number,\n cycleOrInterval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n const interval = metricCalendarUnit(cycleOrInterval);\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const target = zoned\n .toPlainDateTime()\n .with({\n minute: 0,\n second: 0,\n millisecond: 0,\n microsecond: 0,\n nanosecond: 0,\n })\n .add({ hours: 1 });\n let next = target.toZonedDateTime(timeZone).epochMilliseconds;\n if (next <= time)\n next = target.toZonedDateTime(timeZone, {\n disambiguation: \"later\",\n }).epochMilliseconds;\n return metricOffsetTransition(time, next, timeZone) ?? next;\n }\n let date = zoned.toPlainDate();\n if (interval === \"month\") date = date.with({ day: 1 }).add({ months: 1 });\n else if (interval === \"year\")\n date = date.with({ month: 1, day: 1 }).add({ years: 1 });\n else if (interval === \"week\")\n date = date.subtract({ days: date.dayOfWeek - 1 }).add({ weeks: 1 });\n else date = date.add({ days: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n if (interval === \"hour\") date.setUTCHours(date.getUTCHours() + 1);\n else if (interval === \"month\") date.setUTCMonth(date.getUTCMonth() + 1);\n else if (interval === \"year\") date.setUTCFullYear(date.getUTCFullYear() + 1);\n else date.setUTCDate(date.getUTCDate() + (interval === \"week\" ? 7 : 1));\n return date.getTime();\n}\n\n/** A date-only Through value includes the whole local day, even for hourly groups. */\nexport function metricCustomEndTime(value: string, timeZone = \"UTC\"): number {\n const time = metricDateTime(value, timeZone);\n return value.length === 10 ? metricDateNext(time, \"day\", timeZone) - 1 : time;\n}\n\n/** An IANA timezone identifier this runtime knows, such as America/Denver or\n * UTC. Fixed offsets (\"+02:00\") are refused: they do not follow DST. */\nexport function isGroupingTimeZone(value: unknown): value is string {\n if (\n typeof value !== \"string\" ||\n !value ||\n value.length > 80 ||\n /^[+-]/.test(value)\n )\n return false;\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: value });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function validateDateGrouping(config: MetricDateGrouping): void {\n if (\n typeof config.field !== \"string\" ||\n !config.field ||\n config.field.length > 256 ||\n !METRIC_DATE_INTERVALS.includes(config.interval) ||\n typeof config.includeEmpty !== \"boolean\" ||\n ![\"query\", \"observed\", \"custom\"].includes(config.range) ||\n (config.partialIntervals !== undefined &&\n ![\"include\", \"exclude\"].includes(config.partialIntervals))\n )\n throw Error(\"Invalid date grouping definition.\");\n if (config.timeZone !== undefined && !isGroupingTimeZone(config.timeZone))\n throw Error(\n \"Use a valid IANA grouping timezone, such as America/Denver or UTC.\",\n );\n if (config.occurrence !== undefined) {\n const o = config.occurrence as unknown as Record<string, unknown>;\n if (\n !o ||\n typeof o !== \"object\" ||\n Array.isArray(o) ||\n ![\"hour\", \"day\"].includes(o.interval as string) ||\n typeof o.includeEmpty !== \"boolean\"\n )\n throw Error(\"Invalid date grouping occurrence.\");\n if (!isMetricCycle(config.interval))\n throw Error(\n \"Occurrences summarise an hour-of-day or day-of-week slot; calendar intervals are already one occurrence each.\",\n );\n if (config.interval === \"hourOfDay\" && o.interval !== \"hour\")\n throw Error(\"An hour-of-day slot occurs once per hour: use hourly occurrences.\");\n if (config.partialIntervals === \"include\")\n throw Error(\n \"Occurrences are always whole: a partial day or hour would bias the typical value. Leave out partialIntervals.\",\n );\n }\n if (\n config.range === \"custom\" &&\n (isMetricCycle(config.interval)\n ? config.occurrence?.includeEmpty\n : config.includeEmpty)\n ) {\n const start = metricDateTime(config.start ?? \"\", config.timeZone),\n end = metricCustomEndTime(config.end ?? \"\", config.timeZone);\n if (end < start)\n throw Error(\"The end date must be on or after the start date.\");\n }\n}\n\n/** Only conjunctive bounds prove a domain; OR alternatives are not bounds. */\nexport function metricDateRange(\n config: MetricDateGrouping,\n query: QueryState,\n observed: readonly number[],\n now: number,\n canonical: (field: string) => string,\n): [number, number] | undefined {\n let min = Infinity,\n max = -Infinity;\n for (const time of observed) {\n min = Math.min(min, time);\n max = Math.max(max, time);\n }\n if (config.range === \"observed\")\n return observed.length ? [min, max] : undefined;\n if (config.range === \"custom\") {\n const start = metricDateFloor(\n metricDateTime(config.start ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n const end = metricDateFloor(\n metricCustomEndTime(config.end ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n if (observed.length && (start > min || end < max))\n throw Error(\n \"Custom date bounds must include all observed buckets. Narrow the query filters to exclude data.\",\n );\n return [start, end];\n }\n let start = -Infinity,\n end = Infinity;\n for (const term of query.where) {\n if (\n isWhereGroup(term) ||\n term.negated ||\n canonical(term.field) !== canonical(config.field)\n )\n continue;\n if (![\"=\", \">\", \">=\", \"<\", \"<=\"].includes(term.op)) continue;\n const time = Number(coerceValue(\"datetime\", term.value, now));\n if (term.op === \">\" || term.op === \">=\" || term.op === \"=\")\n start = Math.max(start, time + (term.op === \">\" ? 1 : 0));\n if (term.op === \"<\" || term.op === \"<=\" || term.op === \"=\")\n end = Math.min(end, time - (term.op === \"<\" ? 1 : 0));\n }\n if (!Number.isFinite(start) || !Number.isFinite(end)) {\n const missing = [\n ...(Number.isFinite(start) ? [] : [\"a lower bound (>= or >)\"]),\n ...(Number.isFinite(end) ? [] : [\"an upper bound (<= or <)\"]),\n ].join(\" and \");\n throw Error(\n `Include empty dates with range \"query\" needs a bounded date filter on ${config.field}: add ${missing} as top-level filters (bounds inside OR groups do not count). Otherwise use range \"observed\" to fill from the first to the last observed date, or range \"custom\" with start and end.`,\n );\n }\n if (end < start) return undefined;\n return [\n metricDateFloor(start, config.interval, config.timeZone),\n metricDateFloor(end, config.interval, config.timeZone),\n ];\n}\n","// groupKeys.ts — grouping keys and the exact predicates selecting one group.\n//\n// Shared by `groupSourceQuery` (drilldown) and query-kind link columns, so a\n// link's key filters are exactly the filters drilling into the group adds.\n\nimport { isFilterable, resolveField, type FieldDef, type FieldSchema } from \"./schema\";\nimport type { WhereClause } from \"./query\";\nimport type { MetricCalendarInterval } from \"./metricTypes\";\nimport { metricDateFloor, metricDateNext, metricDateTime } from \"./metricDates\";\n\n/** Calendar intervals a grouping key can bucket a datetime field by. */\nexport const GROUP_KEY_INTERVALS: readonly MetricCalendarInterval[] = [\"hour\", \"day\", \"week\", \"month\", \"year\"];\n\n/** A grouping key that buckets a datetime field by calendar interval: one\n * group per interval, keyed by the interval's start as an ISO instant. The\n * result column is named after the field. Intervals follow the metric\n * calendar (`dateGrouping`), including daylight-saving changes; weeks start\n * on Monday. */\nexport interface CalendarGroupKey {\n field: string;\n interval: MetricCalendarInterval;\n /** IANA timezone identifier; omitted means UTC. */\n timeZone?: string;\n}\n/** A field name (group by its exact value) or a calendar key. */\nexport type GroupKey = string | CalendarGroupKey;\n\nexport function isCalendarGroupKey(key: GroupKey): key is CalendarGroupKey {\n return typeof key === \"object\" && key !== null;\n}\n\n/** The source field a key reads; also the name of its result column. */\nexport function groupKeyField(key: GroupKey): string {\n return isCalendarGroupKey(key) ? key.field : key;\n}\n\n/** Result column names, in key order. */\nexport function groupKeyFields(keys: readonly GroupKey[]): string[] {\n return keys.map(groupKeyField);\n}\n\n/** The calendar key on `field`, if that key buckets by interval. */\nexport function calendarGroupKey(keys: readonly GroupKey[], field: string): CalendarGroupKey | undefined {\n return keys.find((key): key is CalendarGroupKey => isCalendarGroupKey(key) && key.field === field);\n}\n\n/** Read a calendar key's value: the start of the interval a source value falls\n * in, as an ISO instant, or null for a null value. Reuses the last interval,\n * so dense timestamps do not repeat timezone work. */\nexport function calendarKeyReader(key: CalendarGroupKey): (value: unknown) => string | null {\n let start = Infinity, end = -Infinity, iso = \"\";\n return (value) => {\n if (value == null) return null;\n const input = value instanceof Date ? value.toISOString() : value;\n if (typeof input !== \"string\")\n throw Error(`Calendar group key ${key.field} needs ISO dates or timestamps with a timezone.`);\n const time = metricDateTime(input, key.timeZone);\n if (time < start || time >= end) {\n start = metricDateFloor(time, key.interval, key.timeZone);\n end = metricDateNext(start, key.interval, key.timeZone);\n iso = new Date(start).toISOString();\n }\n return iso;\n };\n}\n\n/** Filters accept datetimes as ISO instants with an explicit offset. */\nexport function datetimeValue(value: unknown): string | null {\n const time =\n value instanceof Date ? value.getTime()\n : typeof value === \"number\" ? value\n : typeof value === \"string\" && value !== \"\" ? Date.parse(value)\n : NaN;\n return Number.isFinite(time) ? new Date(time).toISOString() : null;\n}\n\n/** One equality (or `is_null`) predicate selecting a group key, or null when\n * the field cannot express it exactly. */\nexport function keyClause(field: FieldDef | undefined, value: unknown): WhereClause | null {\n if (!field || field.type === \"textarray\" || !isFilterable(field)) return null;\n if (value == null) return { field: field.name, op: \"is_null\", value: \"\" };\n if (field.type === \"datetime\") {\n const iso = datetimeValue(value);\n return iso === null ? null : { field: field.name, op: \"=\", value: iso };\n }\n if (typeof value === \"number\" ? !Number.isFinite(value) : typeof value !== \"string\" && typeof value !== \"boolean\")\n return null;\n return { field: field.name, op: \"=\", value: String(value) };\n}\n\n/** `>= start` and `< end` selecting one calendar key's interval (or `is_null`\n * for its null group), or null when the field cannot express it exactly. */\nexport function calendarKeyClauses(field: FieldDef | undefined, key: CalendarGroupKey, value: unknown): WhereClause[] | null {\n if (!field || field.type !== \"datetime\" || !isFilterable(field)) return null;\n if (value == null) return [{ field: field.name, op: \"is_null\", value: \"\" }];\n const iso = datetimeValue(value);\n if (iso === null) return null;\n const start = Date.parse(iso), end = metricDateNext(start, key.interval, key.timeZone);\n if (!Number.isFinite(end) || end <= start) return null;\n return [\n { field: field.name, op: \">=\", value: iso },\n { field: field.name, op: \"<\", value: new Date(end).toISOString() },\n ];\n}\n\n/** `=` (or `is_null`) per key, in key order, or null when any key cannot be\n * matched exactly (textarray, unknown or unfilterable fields, unparseable\n * datetimes). A calendar key adds `>= start` and `< end` for its interval. */\nexport function groupKeyTerms(keys: readonly GroupKey[], group: Record<string, unknown>, schema: FieldSchema): WhereClause[] | null {\n const terms: WhereClause[] = [];\n for (const key of keys) {\n const name = groupKeyField(key);\n const field = resolveField(schema, name);\n if (isCalendarGroupKey(key)) {\n const range = calendarKeyClauses(field, key, group[name]);\n if (!range) return null;\n terms.push(...range);\n continue;\n }\n const term = keyClause(field, group[name]);\n if (!term) return null;\n terms.push(term);\n }\n return terms;\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\nimport type { MetricDisplay, MetricLayout, MetricDistribution, MetricSort, MetricScope, MetricDateGrouping, MetricWindow, MetricShare, MetricMinCountOf } from \"./metricTypes\";\nimport { normalizeMetricOptions } from \"./metricNormalize\";\nimport type { GroupingState, SummaryColumn, RepresentativeOrder, LinkSpec, LinkDestination } from \"./grouping\";\nimport { GROUP_KEY_INTERVALS, groupKeyFields, type CalendarGroupKey, type GroupKey } from \"./groupKeys\";\nimport type { QueryFacet, QueryPatch } from \"./queryPatch\";\nimport { parseCellDisplay, type CellDisplay } from \"./cellDisplay\";\n// query.ts — the canonical query state shape.\n//\n// We lean into SQL vocabulary at every layer (per design feedback): a QueryState\n// reads top-to-bottom like the statement it compiles to —\n//\n// SELECT <select> WHERE <where> ORDER BY <orderBy> LIMIT <limit> OFFSET <offset>\n//\n// Both \"what data\" (where/orderBy/limit/offset) and \"how viewed\" (select +\n// per-column width) can be serialized together when a consumer explicitly opts\n// into URL synchronization.\n\n/** All filter operators across both source projects, unioned. Every value can\n * be NULL, so `is_null`/`is_not_null` are valid for every field type. */\nexport type FilterOp =\n // comparison — number / datetime (and =,!= for any scalar)\n | \"=\"\n | \"!=\"\n | \">\"\n | \">=\"\n | \"<\"\n | \"<=\"\n // text matching\n | \"contains\"\n | \"starts_with\"\n | \"ends_with\"\n | \"matches_regex\"\n | \"not_matches_regex\"\n | \"length_gt\"\n | \"length_lt\"\n | \"length_eq\"\n // array (textarray) containment\n | \"includes\"\n // nullity — valid for EVERY type; for arrays, \"empty\" vs \"non-empty\"\n | \"is_null\"\n | \"is_not_null\";\n\n/** A single filter predicate (a \"literal\" in CNF terms). `value` is always the\n * raw string the UI captured; coercion to number/bool/date happens at\n * apply/compile time based on the field's declared type (never on the value's\n * runtime shape). Datetime comparisons also accept signed duration offsets\n * such as \"-1h\" or \"+8d2h10m\", resolved relative to execution time.\n * Unused for the nullary ops (`is_null`/`is_not_null`).\n *\n * `negated` wraps the predicate in a logical NOT. It is only ever set for ops\n * that have no complementary operator (`contains`/`starts_with`/`ends_with`/\n * `includes`); ops with a complement negate by flipping the op itself (`>=`→`<`,\n * `=`→`!=`, `is_null`→`is_not_null`, `matches_regex`→`not_matches_regex`) — see\n * `negateClause` in ops.ts. NOT is null-exclusive: a NULL/empty value satisfies\n * neither the predicate nor its negation, matching `not_matches_regex`. */\nexport interface WhereClause {\n field: string; // FieldDef.name\n op: FilterOp;\n value: string;\n negated?: boolean;\n setFilter?: SetFilterMetadata;\n}\n\nexport type SetFilterMode = \"any\" | \"all\" | \"none\" | \"empty\";\n\n/** Presentation-only identity; execution always uses the accompanying predicates. */\nexport interface SetFilterMetadata {\n id: string;\n mode: SetFilterMode;\n values: string[];\n}\n\n/** A disjunction of predicates — the inner OR of conjunctive normal form. Every\n * member is a plain literal. See `OrOfAndsGroup` for an OR whose members may\n * themselves be conjunctions. */\nexport interface OrGroup {\n any: WhereClause[];\n setFilter?: SetFilterMetadata;\n}\n\n/** One branch of an `OrOfAndsGroup` that ANDs several literals. Members are\n * always plain literals: nesting stops at `any` → `all` → clause. */\nexport interface WhereConjunction {\n all: WhereClause[];\n}\n\n/** One alternative of an `OrOfAndsGroup`: a literal or a conjunction. */\nexport type WhereBranch = WhereClause | WhereConjunction;\n\n/** A disjunction of conjunctions — `(a AND b) OR (c AND d)` — written\n * `{ any: [{ all: [a, b] }, { all: [c, d] }] }`. A branch may also be a bare\n * literal. It selects the union of its branches' rows, such as a legend\n * selection of several (provider, model) pairs, without the exponential\n * AND-of-ORs rewrite. Normalization keeps the shape canonical: a one-literal\n * conjunction becomes that literal, a group whose branches are all literals is\n * an `OrGroup`, and a single conjunction becomes top-level literals. Every\n * literal counts against `MAX_WHERE_CLAUSES`, which therefore also bounds the\n * number of branches. Each literal keeps its own null-exclusive negation; the\n * group itself is never negated. */\nexport interface OrOfAndsGroup {\n any: WhereBranch[];\n setFilter?: SetFilterMetadata;\n}\n\n/** One conjunct of the WHERE clause: a single predicate, an OR group, or an OR\n * of conjunctions. `QueryState.where` is the AND of these terms —\n * `(a) AND (b OR c) AND ((d AND e) OR f)`. A bare literal is equivalent to a\n * one-element OR group; normalization flattens singleton groups back to a\n * literal so equality/encoding stay canonical. */\nexport type WhereTerm = WhereClause | OrGroup | OrOfAndsGroup;\n\n/** Narrow a branch to a conjunction. */\nexport function isWhereConjunction(branch: WhereBranch): branch is WhereConjunction {\n return branch != null && Array.isArray((branch as WhereConjunction).all);\n}\n\n/** Narrow a term to a plain OR group (every member a literal). A literal\n * always carries `field`; a group never does and always carries an `any`\n * array. An `OrOfAndsGroup` is not an `OrGroup`. */\nexport function isOrGroup(term: WhereTerm): term is OrGroup {\n const any = (term as OrGroup).any;\n return Array.isArray(any) && !any.some((member) => isWhereConjunction(member as WhereBranch));\n}\n\n/** Narrow a term to an OR group with at least one conjunction branch. */\nexport function isOrOfAndsGroup(term: WhereTerm): term is OrOfAndsGroup {\n const any = (term as OrOfAndsGroup).any;\n return Array.isArray(any) && any.some(isWhereConjunction);\n}\n\n/** Narrow a term to either kind of group (anything carrying `any`). */\nexport function isWhereGroup(term: WhereTerm): term is OrGroup | OrOfAndsGroup {\n return Array.isArray((term as OrGroup).any);\n}\n\n/** The predicate literals a term references, in order: the term itself for a\n * literal, a group's members, and the members of each conjunction branch.\n * Handy for anything that must visit every predicate regardless of grouping\n * (field allowlisting, SELECT projection, budgets); it does not preserve\n * meaning — use `branchesOf` to evaluate a term. */\nexport function predicatesOf(term: WhereTerm): WhereClause[] {\n if (!isWhereGroup(term)) return [term];\n return term.any.flatMap((member: WhereBranch) => isWhereConjunction(member) ? member.all : [member]);\n}\n\n/** A term as a disjunction of conjunctions: it matches when every literal of\n * some branch matches. A literal is `[[literal]]`, an OR group one\n * single-literal branch per member. */\nexport function branchesOf(term: WhereTerm): WhereClause[][] {\n if (!isWhereGroup(term)) return [[term]];\n return term.any.map((member: WhereBranch) => isWhereConjunction(member) ? member.all : [member]);\n}\n\n/** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */\nexport interface OrderByClause {\n field: string; // FieldDef.name (server may sort a different expr via FieldDef.sort.field)\n dir: \"asc\" | \"desc\";\n /** NULL placement. Omitted = \"last\" (the historical default both projects used,\n * preserved so old `?q=` links round-trip identically). */\n nulls?: \"first\" | \"last\";\n /** Sort by the first capture group of a regex match (or by the whole match\n * when the pattern has no capture group). A non-match produces NULL. Regex\n * syntax is interpreted by the executor (JavaScript locally, PostgreSQL on\n * the bundled Go backend), so portable patterns should use their common\n * syntax subset. */\n extract?: { regex: string };\n}\n\n/** One column in the SELECT list, plus the view state that travels with it.\n * Order in `QueryState.select` is the left-to-right display order. */\nexport interface SelectColumn {\n field: string; // FieldDef.name, or @computed/<id> (source lives in ComputedColumnStore)\n /** Pixel width override. Omitted = FieldDef.select.width, else the type default. */\n width?: number;\n /** Table-cell presentation for this column in this layout, e.g.\n * `{ kind: \"text\", lines: 3 }`. Takes precedence over the field's `render`\n * and `display`; other surfaces (details, menus, metrics) keep the field's. */\n display?: CellDisplay;\n}\n\n/** A single aggregate operation. `count` is the only op that needs no measure\n * column (it counts rows); the rest reduce one column's values. The server-side\n * matrix (backends/go aggOpAllowed + the TS AGG_OPS_BY_TYPE) decides which ops a\n * field's type permits. */\nexport type AggOp = \"count\" | \"count_distinct\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\n/** One optional \"metric\" pinned above the table: a single aggregate over a single\n * measure column, optionally broken down by one or more group columns.\n *\n * Scope is deliberately the *whole filtered set* — the same WHERE as the table,\n * but NOT its ORDER BY / LIMIT / OFFSET. It is always evaluated on the server\n * (a real GROUP BY), so it reflects every matching row, not just the visible\n * page. Lives inside QueryState so it round-trips through `?q=`, saved queries,\n * and undo/redo for free — a saved query is a saved dashboard. */\nexport interface AggregationClause {\n dateGrouping?: MetricDateGrouping;\n expression?: string;\n expressionY?: string;\n scope?: MetricScope;\n sort?: MetricSort[];\n groupLimit?: number;\n display?: MetricDisplay;\n layout?: MetricLayout;\n distribution?: MetricDistribution;\n diagnostics?: string[];\n /** Preserved source operation when this client does not implement it. */\n unsupportedOp?: string;\n /** Stable id; keys the metric panel and survives a `?q=` round-trip. */\n id: string;\n op: AggOp;\n /** Measure column (FieldDef.name). Omit only for `count` (⇒ COUNT(*)). */\n field?: string;\n /** Group-by columns, in axis order. `[]` = a single grand-total value.\n * One ⇒ a list/bar breakdown; two ⇒ an x/y pivot; three+ ⇒ a flat table. */\n groupBy: string[];\n /** Panel header override; defaults to a derived label like \"avg total\". */\n label?: string;\n /** This metric's own row predicate (CNF, like `QueryState.where`), ANDed with\n * the table WHERE before grouping. The table rows are unchanged. In grouped\n * mode it refers to grouped-result fields. Shown-row metrics apply it inside\n * the shown page. */\n where?: WhereTerm[];\n /** Drop small groups before sorting, `groupLimit` and Other. A number counts\n * rows (after `where`); `{ min, distinct: field }` counts a field's distinct\n * non-null values and `{ min, sum: field }` sums a numeric field, ignoring\n * nulls. Requires at least one grouping field; `min` is an integer\n * 1–1,000,000. Removed groups are reported as `hiddenGroups`. */\n minCount?: number | MetricMinCountOf;\n /** A trailing window or running value over the calendar intervals of\n * `dateGrouping`. Computed from ordinary metrics, so every engine supports it. */\n window?: MetricWindow;\n /** Express each bucket as a fraction of a total of the same measure. */\n share?: MetricShare;\n}\n\n/** Detail affordances are presentation state, never backend SELECT fields. */\nexport type ItemPropertyMode = \"hover\" | \"modal\" | \"expand\";\nexport type ItemDetailMode = ItemPropertyMode | \"page\";\nexport interface ItemPageOptions {\n /** Empty uses the current page with the item modal and query state. */\n urlTemplate: string;\n target: \"_blank\" | \"_self\";\n}\n/** Reserved presentation column; never sent to a data source. */\nexport const ITEM_DETAILS_COLUMN = \"__qt_item_details__\";\nexport interface ItemDetailsState {\n modes: ItemDetailMode[];\n /** A self-contained view travels with shared links; saved-view IDs are device-local. */\n view?: PropertyViewState;\n /** Independent layouts for each modality. Legacy view is the fallback. */\n views?: Partial<Record<ItemPropertyMode, PropertyViewState>>;\n page?: ItemPageOptions;\n active?: { id: RowId; mode: \"modal\" | \"expand\" };\n}\n\n/**\n * Query state a host owns and registers with `useQueryTable({ hostQuery })`,\n * such as a keyword clause it runs itself. It travels with the table query\n * through saves, links, history and resets as one definition. `params` are\n * named lists of strings, like URL search parameters; the host's own\n * `normalize` interprets them. Version 0 marks a payload that could not be\n * read, and is always rejected on restore.\n */\nexport interface HostQueryState {\n version: number;\n params: Record<string, string[]>;\n}\nexport const MAX_HOST_QUERY_PARAMS = 64;\nexport const MAX_HOST_QUERY_VALUES = 64;\nexport const MAX_HOST_QUERY_VALUE_LENGTH = 4000;\nexport const MAX_HOST_QUERY_STATE_BYTES = 32 * 1024;\n/** URL-style names; ASCII keeps the sorted order identical in every codec. */\nconst HOST_QUERY_PARAM_NAME = /^[A-Za-z_][A-Za-z0-9_.-]{0,127}$/;\n\n/** Validates host state and returns its canonical form (parameters sorted by\n * name, values in order). Throws on a malformed or oversized payload. */\nexport function parseHostQueryState(input: unknown): HostQueryState {\n const fail = (why: string): never => { throw Error(`Invalid host query state: ${why}`); };\n if (!isRecord(input)) return fail(\"expected an object.\");\n if (Object.keys(input).some((key) => key !== \"version\" && key !== \"params\")) fail(\"unexpected properties.\");\n const version = input.version;\n if (typeof version !== \"number\" || !Number.isSafeInteger(version) || version < 1) return fail(\"unsupported version.\");\n if (!isRecord(input.params)) return fail(\"params must be an object.\");\n const names = Object.keys(input.params).sort();\n if (names.length > MAX_HOST_QUERY_PARAMS) fail(\"too many parameters.\");\n const params: Record<string, string[]> = {};\n for (const name of names) {\n const values = input.params[name];\n if (!HOST_QUERY_PARAM_NAME.test(name)) fail(\"invalid parameter name.\");\n if (!Array.isArray(values) || values.length > MAX_HOST_QUERY_VALUES ||\n values.some((value) => typeof value !== \"string\" || value.length > MAX_HOST_QUERY_VALUE_LENGTH))\n fail(`parameter ${name} must be a list of strings.`);\n params[name] = [...values as string[]];\n }\n const state = { version, params };\n if (new TextEncoder().encode(JSON.stringify(state)).length > MAX_HOST_QUERY_STATE_BYTES) fail(\"payload too large.\");\n return state;\n}\n\nexport interface QueryState {\n /** Host-owned state registered through `useQueryTable({ hostQuery })`.\n * Only the top-level query carries it; a grouping source never does. */\n hostState?: HostQueryState;\n /** Optional row-producing stage. `grouping.source` is the original record\n * query (its WHERE runs first). This query selects/filters/sorts the groups;\n * its `where` therefore represents HAVING. Only one stage is supported. */\n grouping?: GroupingState;\n itemDetails?: ItemDetailsState;\n /** Ordered SELECT list + per-column widths. Empty = the schema's default columns. */\n select: SelectColumn[];\n /** Refit columns to each viewer's table viewport after loading. Manual width\n * changes clear this view preference; omitted/false uses stored widths. */\n fitToScreen?: boolean;\n /** WHERE in conjunctive normal form: the AND of these terms, each a single\n * predicate or an OR group. A flat list of literals (no groups) is the common\n * case and the legacy shape, decoded unchanged. */\n where: WhereTerm[];\n /** Multi-sort terms in priority order. Empty = the schema's default sort. */\n orderBy: OrderByClause[];\n /** Page size. */\n limit: number;\n /** Page offset (rows). */\n offset: number;\n /** Optional aggregate metrics shown above the table. Omitted/empty = none.\n * Each runs as its own server GROUP BY over the WHERE-filtered set (no paging). */\n aggregations?: AggregationClause[];\n}\n\n/** A row's stable identity, used for selection and per-row refresh. */\nexport type RowId = string | number;\n\n/** The query a fresh table starts from before schema defaults are layered on.\n * Empty `select`/`orderBy`/`where` mean \"defer to the schema\", which also keeps\n * encoded `?q=` tokens short (defaults are omitted). */\nexport const EMPTY_QUERY: QueryState = {\n select: [],\n where: [],\n orderBy: [],\n limit: 100,\n offset: 0,\n};\n\n/** Structural limits applied whenever query state crosses a trust boundary\n * (URL, storage, an imperative setQuery call, or a server projection). Row\n * limits may use the full safe-integer range; consumers and their backends own\n * any smaller operational cap appropriate for their dataset. */\nexport const MAX_QUERY_LIMIT = Number.MAX_SAFE_INTEGER;\nexport const MAX_QUERY_OFFSET = 1_000_000;\nexport const MAX_SELECT_COLUMNS = 200;\nexport const MAX_WHERE_CLAUSES = 100;\nexport const MAX_ORDER_BY_TERMS = 20;\nexport const MAX_AGGREGATIONS = 20;\nexport const MAX_GROUP_BY_FIELDS = 20;\nexport const MAX_QUERY_TOKEN_LENGTH = 2 * 1024 * 1024;\n\nconst MAX_FIELD_NAME_LENGTH = 256;\nconst MAX_FILTER_VALUE_LENGTH = 10_000;\nconst MAX_LABEL_LENGTH = 1_000;\nconst MIN_COLUMN_WIDTH = 24;\nconst MAX_COLUMN_WIDTH = 2_000;\n\nconst FILTER_OPS: ReadonlySet<string> = new Set([\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n \"includes\",\n \"is_null\",\n \"is_not_null\",\n]);\n\nconst AGG_OPS: ReadonlySet<string> = new Set([\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction boundedString(value: unknown, maxLength: number): string | null {\n return typeof value === \"string\" && value.length > 0 && value.length <= maxLength ? value : null;\n}\n\nfunction boundedInteger(value: unknown, fallback: number, min: number, max: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.min(max, Math.round(value)));\n}\n\n/** Validate one raw predicate into a bounded WhereClause, or null if malformed.\n * Shared by top-level literals and the members of an OR group. */\nfunction normalizeWhereClause(item: unknown): WhereClause | null {\n if (!isRecord(item)) return null;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const value = typeof item.value === \"string\" && item.value.length <= MAX_FILTER_VALUE_LENGTH ? item.value : null;\n if (!field || typeof item.op !== \"string\" || !FILTER_OPS.has(item.op) || value == null) {\n return null;\n }\n const clause: WhereClause = { field, op: item.op as FilterOp, value };\n if (item.negated === true) clause.negated = true;\n return clause;\n}\n\n/** Deep-clone one WHERE term (literal or group) so a normalized/fallback state\n * never aliases the caller's arrays. */\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy: WhereTerm = isWhereGroup(term)\n ? { ...term, any: term.any.map((c: WhereBranch) => isWhereConjunction(c) ? { all: c.all.map((m) => ({ ...m })) } : { ...c }) }\n : { ...term };\n if (term.setFilter) copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction normalizeSetFilter(item: unknown): SetFilterMetadata | undefined {\n if (!isRecord(item)) return undefined;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id || typeof item.mode !== \"string\" || ![\"any\", \"all\", \"none\", \"empty\"].includes(item.mode) || !Array.isArray(item.values)) return undefined;\n if (item.values.length > MAX_WHERE_CLAUSES || !item.values.every((value) => typeof value === \"string\" && value.length <= MAX_FILTER_VALUE_LENGTH)) return undefined;\n return { id, mode: item.mode as SetFilterMode, values: [...item.values] as string[] };\n}\n\n/** How many predicates a raw (unnormalized) term supplies, so callers can tell\n * whether normalization lost any: a group counts its members, a conjunction\n * branch its literals (an empty one counts one: dropping it would narrow the\n * group), anything else one. An empty top-level group counts zero. */\nexport function suppliedPredicateCount(term: unknown): number {\n if (!isRecord(term) || !Array.isArray(term.any)) return 1;\n let count = 0;\n for (const member of term.any as unknown[])\n count += isRecord(member) && Array.isArray(member.all) ? Math.max(1, member.all.length) : 1;\n return count;\n}\n\nfunction normalizeWhereTerms(input: readonly unknown[]): WhereTerm[] {\n const where: WhereTerm[] = [];\n let literalBudget = MAX_WHERE_CLAUSES;\n for (const item of input) {\n if (literalBudget <= 0) break;\n const start = where.length;\n if (isRecord(item) && Array.isArray((item as { any?: unknown }).any)) {\n const members: WhereBranch[] = [];\n for (const inner of (item as { any: unknown[] }).any) {\n if (literalBudget <= 0) break;\n if (isRecord(inner) && Array.isArray(inner.all)) {\n // A conjunction branch: plain literals only, one level deep.\n const all: WhereClause[] = [];\n for (const literal of inner.all as unknown[]) {\n if (literalBudget <= 0) break;\n const clause = normalizeWhereClause(literal);\n if (clause) {\n all.push(clause);\n literalBudget--;\n }\n }\n if (all.length === 1) members.push(all[0]!);\n else if (all.length > 1) members.push({ all });\n continue;\n }\n const clause = normalizeWhereClause(inner);\n if (clause) {\n members.push(clause);\n literalBudget--;\n }\n }\n if (members.length === 1) {\n // One branch is plain AND: a literal, or the conjunction's literals.\n const only = members[0]!;\n if (isWhereConjunction(only)) where.push(...only.all);\n else where.push(only);\n } else if (members.length > 1) where.push({ any: members } as OrGroup | OrOfAndsGroup);\n // 0 members → drop the term entirely\n } else {\n const clause = normalizeWhereClause(item);\n if (clause) {\n where.push(clause);\n literalBudget--;\n }\n }\n if (where.length > start && isRecord(item)) {\n const metadata = normalizeSetFilter(item.setFilter);\n if (metadata) where[start]!.setFilter = metadata;\n }\n }\n return where;\n}\n\n/** A metric WHERE narrows its population. Dropping a malformed predicate would\n * silently widen it, so any loss is retained as a clause diagnostic instead. */\nfunction normalizeMetricWhere(value: unknown): { where?: WhereTerm[]; invalid: boolean } {\n if (value === undefined) return { invalid: false };\n if (!Array.isArray(value)) return { invalid: true };\n const where = normalizeWhereTerms(value);\n const supplied = value.reduce((count: number, term: unknown) => count + suppliedPredicateCount(term), 0);\n const kept = where.reduce((count, term) => count + predicatesOf(term).length, 0);\n return { ...(where.length ? { where } : {}), invalid: supplied !== kept };\n}\n\n/** Convert unknown input into a bounded, structurally valid QueryState.\n * Invalid members are dropped; invalid scalar paging values use the supplied\n * fallback. This function is intentionally schema-agnostic—field allowlisting\n * still happens in toServerQuery and in the backend compiler. */\nexport function normalizeQueryState(input: unknown, fallback: QueryState = EMPTY_QUERY): QueryState {\n return normalizeQuery(input, fallback, true);\n}\n\n/** `links` is false inside a link's patch, which bounds nesting at one level. */\nfunction normalizeQuery(input: unknown, fallback: QueryState, links: boolean): QueryState {\n const raw = isRecord(input) ? input : {};\n\n const select: SelectColumn[] = [];\n if (Array.isArray(raw.select)) {\n for (const item of raw.select.slice(0, MAX_SELECT_COLUMNS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field) continue;\n const column: SelectColumn = { field };\n if (typeof item.width === \"number\" && Number.isFinite(item.width)) {\n column.width = boundedInteger(item.width, MIN_COLUMN_WIDTH, MIN_COLUMN_WIDTH, MAX_COLUMN_WIDTH);\n }\n if (item.display !== undefined) {\n // A malformed presentation hint never hides the column; it falls back\n // to the field's own presentation.\n try { column.display = parseCellDisplay(item.display, `column ${field} display`); } catch { /* dropped */ }\n }\n select.push(column);\n }\n } else {\n select.push(...fallback.select.map((column) => ({ ...column, ...(column.display ? { display: JSON.parse(JSON.stringify(column.display)) as CellDisplay } : {}) })));\n }\n\n // WHERE is an AND of terms, each a literal, an `{ any: [...] }` OR group, or\n // an OR of `{ all: [...] }` conjunctions. MAX_WHERE_CLAUSES bounds the TOTAL\n // predicate count across all terms and branches\n // (legacy flat lists are all literals, so the cap is unchanged for them).\n // Singleton/empty groups are canonicalized (flattened / dropped).\n const where: WhereTerm[] = Array.isArray(raw.where)\n ? normalizeWhereTerms(raw.where)\n : fallback.where.map(cloneWhereTerm);\n\n const orderBy: OrderByClause[] = [];\n if (Array.isArray(raw.orderBy)) {\n for (const item of raw.orderBy.slice(0, MAX_ORDER_BY_TERMS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field || (item.dir !== \"asc\" && item.dir !== \"desc\")) continue;\n const term: OrderByClause = { field, dir: item.dir };\n if (item.nulls === \"first\" || item.nulls === \"last\") term.nulls = item.nulls;\n if (\n isRecord(item.extract) &&\n typeof item.extract.regex === \"string\" &&\n item.extract.regex.length <= MAX_FILTER_VALUE_LENGTH\n ) {\n term.extract = { regex: item.extract.regex };\n }\n orderBy.push(term);\n }\n } else {\n orderBy.push(\n ...fallback.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n );\n }\n\n const out: QueryState = {\n select,\n where,\n orderBy,\n limit: boundedInteger(raw.limit, fallback.limit, 1, MAX_QUERY_LIMIT),\n offset: boundedInteger(raw.offset, fallback.offset, 0, MAX_QUERY_OFFSET),\n };\n\n if (raw.fitToScreen === true) out.fitToScreen = true;\n\n // Unreadable host state is kept as version 0 rather than dropped, so a\n // restore can reject it instead of running a broadened table-only query.\n if (links && raw.hostState !== undefined) {\n try { out.hostState = parseHostQueryState(raw.hostState); } catch { out.hostState = { version: 0, params: {} }; }\n }\n\n if (raw.grouping != null) out.grouping = normalizeGroupingState(raw.grouping, links);\n\n if (Array.isArray(raw.aggregations)) {\n const aggregations: AggregationClause[] = [];\n for (const item of raw.aggregations.slice(0, MAX_AGGREGATIONS)) {\n if (!isRecord(item)) continue;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id) continue;\n const validOp = typeof item.op === \"string\" && AGG_OPS.has(item.op);\n const rawGroups: unknown[] = Array.isArray(item.groupBy) ? item.groupBy : [];\n const groupBy = rawGroups\n .slice(0, MAX_GROUP_BY_FIELDS)\n .map((field) => boundedString(field, MAX_FIELD_NAME_LENGTH))\n .filter((field): field is string => field != null);\n const aggregation: AggregationClause = { id, op: validOp ? item.op as AggOp : \"count\", groupBy };\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const label = boundedString(item.label, MAX_LABEL_LENGTH);\n if (field) aggregation.field = field;\n if (label) aggregation.label = label;\n Object.assign(aggregation, normalizeMetricOptions(item));\n const metricWhere = normalizeMetricWhere(item.where);\n if (metricWhere.where) aggregation.where = metricWhere.where;\n if (metricWhere.invalid) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric filter.\"];\n if (!Array.isArray(item.groupBy) || rawGroups.length > MAX_GROUP_BY_FIELDS || groupBy.length !== rawGroups.length) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric grouping fields or grouping budget exceeded.\"];\n const unsupportedOp = boundedString(item.unsupportedOp ?? (!validOp ? item.op : undefined), MAX_FIELD_NAME_LENGTH);\n if (unsupportedOp) aggregation.unsupportedOp = unsupportedOp;\n if (item.field !== undefined && !field) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric measure field.\"];\n if (!validOp && typeof item.expression !== \"string\") aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Unsupported aggregate operation.\"];\n aggregations.push(aggregation);\n }\n if (aggregations.length > 0) out.aggregations = aggregations;\n } else if (fallback.aggregations?.length) {\n out.aggregations = normalizeQueryState({ aggregations: fallback.aggregations }).aggregations!;\n }\n\n if (isRecord(raw.itemDetails) && Array.isArray(raw.itemDetails.modes)) {\n const modes = [...new Set(raw.itemDetails.modes.filter(\n (mode): mode is ItemDetailMode => typeof mode === \"string\" && [\"hover\", \"modal\", \"expand\", \"page\"].includes(mode),\n ))];\n const details: ItemDetailsState = { modes };\n if (isRecord(raw.itemDetails.page) && typeof raw.itemDetails.page.urlTemplate === \"string\"\n && raw.itemDetails.page.urlTemplate.length <= 8000) {\n details.page = { urlTemplate: raw.itemDetails.page.urlTemplate,\n target: raw.itemDetails.page.target === \"_self\" ? \"_self\" : \"_blank\" };\n }\n if (raw.itemDetails.view !== undefined) {\n try { details.view = normalizePropertyView(raw.itemDetails.view); } catch { /* Ignore malformed view snapshots. */ }\n }\n if (isRecord(raw.itemDetails.views)) {\n const views: NonNullable<ItemDetailsState[\"views\"]> = {};\n for (const mode of [\"hover\", \"modal\", \"expand\"] as const) {\n try {\n if (raw.itemDetails.views[mode] !== undefined) views[mode] = normalizePropertyView(raw.itemDetails.views[mode]);\n } catch { /* Ignore malformed modality snapshots. */ }\n }\n if (Object.keys(views).length) details.views = views;\n }\n const active = raw.itemDetails.active;\n if (isRecord(active) && (active.mode === \"modal\" || active.mode === \"expand\") && modes.includes(active.mode)\n && ((typeof active.id === \"string\" && active.id.length > 0 && active.id.length <= 1000)\n || (typeof active.id === \"number\" && Number.isFinite(active.id)))) {\n details.active = { id: active.id as RowId, mode: active.mode };\n }\n out.itemDetails = details;\n }\n\n return out;\n}\n\n/** Retain an invalid stage as a diagnostic rather than silently executing an\n * ungrouped query. Strip nesting before normalizing the source snapshot. */\nfunction normalizeGroupingState(value: unknown, links: boolean): GroupingState {\n const raw = isRecord(value) ? value : {};\n const diagnostics: string[] = [];\n // Each problem gets its own message; the stage still refuses to execute.\n const fail = (message: string) => { diagnostics.push(`Invalid grouping: ${message}`); };\n const keys: GroupKey[] = [];\n for (const [index, key] of (Array.isArray(raw.keys) ? raw.keys.slice(0, MAX_GROUP_BY_FIELDS) : []).entries()) {\n if (boundedString(key, MAX_FIELD_NAME_LENGTH)) { keys.push(key as string); continue; }\n if (!isRecord(key)) continue;\n // A calendar key: the timezone's validity is checked with the schema.\n const field = boundedString(key.field, MAX_FIELD_NAME_LENGTH), zone = key.timeZone;\n if (field && GROUP_KEY_INTERVALS.includes(key.interval as never) &&\n (zone === undefined || (typeof zone === \"string\" && zone.length > 0 && zone.length <= 80 && !/^[+-]/.test(zone))))\n keys.push({ field, interval: key.interval as CalendarGroupKey[\"interval\"], ...(zone !== undefined ? { timeZone: zone as string } : {}) });\n else fail(`key ${index + 1} must be a field name or a calendar key {field, interval, timeZone} with interval hour, day, week, month or year; hour-of-day and day-of-week are metric intervals.`);\n }\n const keyNames = groupKeyFields(keys);\n if (!Array.isArray(raw.keys) || !keys.length || keys.length !== raw.keys.length || new Set(keyNames).size !== keys.length)\n fail(`keys must list 1–${MAX_GROUP_BY_FIELDS} distinct field names.`);\n const summaries: SummaryColumn[] = [];\n if (!Array.isArray(raw.summaries) || raw.summaries.length > 64) fail(\"summaries must be a list of at most 64 columns.\");\n const summaryIds = new Set<string>();\n for (const [index, item] of (Array.isArray(raw.summaries) ? raw.summaries.slice(0, 64) : []).entries()) {\n const name = isRecord(item) && boundedString(item.id, MAX_FIELD_NAME_LENGTH) ? `summary \"${item.id as string}\"` : `summary ${index + 1}`;\n if (!isRecord(item) || !boundedString(item.id, MAX_FIELD_NAME_LENGTH)) { fail(`${name} needs an id of 1–${MAX_FIELD_NAME_LENGTH} characters.`); continue; }\n if (typeof item.op !== \"string\" || (!AGG_OPS.has(item.op) && item.op !== \"row\" && item.op !== \"formula\" && (item.op !== \"link\" || !links))) {\n fail(item.op === \"link\"\n ? `${name} is a link column; a link's patch cannot contain link columns.`\n : `${name} has unsupported op ${JSON.stringify(String(item.op).slice(0, 40))}; use count, count_distinct, sum, avg, min, max, row, formula, or link${String(item.op).toLowerCase() === \"median\" ? ' (for a median, use op \"formula\" with expression \"MEDIAN([field])\")' : \"\"}.`);\n continue;\n }\n const column: SummaryColumn = { id: item.id as string, op: item.op as SummaryColumn[\"op\"] };\n // Collisions with source fields need the schema and are reported by\n // createGroupingModel().validate(); keys and duplicates are visible here.\n if (summaryIds.has(column.id)) fail(`${name} uses the same id as another summary column.`);\n else if (keyNames.includes(column.id)) fail(`${name} uses the same id as group key \"${column.id}\"; summary ids must differ from source field names.`);\n summaryIds.add(column.id);\n if (item.op === \"link\") {\n // A malformed spec is isolated to its column (see linkDiagnostics).\n const link = normalizeLinkSpec(item.link);\n if (link) column.link = link;\n if (item.label !== undefined) {\n if (typeof item.label !== \"string\" || item.label.length > MAX_LABEL_LENGTH) fail(`${name} label must be text of at most ${MAX_LABEL_LENGTH.toLocaleString(\"en-US\")} characters.`);\n else column.label = item.label;\n }\n summaries.push(column);\n continue;\n }\n if (item.field !== undefined) {\n if (!boundedString(item.field, MAX_FIELD_NAME_LENGTH)) fail(`${name} has an invalid field name.`);\n else column.field = item.field as string;\n }\n if (item.op === \"formula\") {\n if (typeof item.expression !== \"string\" || item.expression.length > 10_000) fail(`${name} needs an expression of at most 10,000 characters.`);\n else column.expression = item.expression;\n }\n if (item.label !== undefined) {\n if (typeof item.label !== \"string\" || item.label.length > MAX_LABEL_LENGTH) fail(`${name} label must be text of at most ${MAX_LABEL_LENGTH.toLocaleString(\"en-US\")} characters.`);\n else column.label = item.label;\n }\n if (item.display !== undefined) {\n try { column.display = parseCellDisplay(item.display, `${name} display`); }\n catch (error) { fail(`${error instanceof Error ? error.message : String(error)}.`); }\n }\n summaries.push(column);\n }\n let representative: GroupingState[\"representative\"] = null;\n if (raw.representative != null) {\n const ordering = isRecord(raw.representative) ? raw.representative.orderBy : undefined;\n const orderBy: RepresentativeOrder[] = [];\n if (!Array.isArray(ordering) || !ordering.length || ordering.length > 8) fail(\"representative ordering must list 1–8 fields.\");\n for (const term of Array.isArray(ordering) ? ordering.slice(0, 8) : []) {\n if (!isRecord(term) || !boundedString(term.field, MAX_FIELD_NAME_LENGTH) || ![\"asc\", \"desc\"].includes(String(term.dir)) || (term.nulls !== undefined && ![\"first\", \"last\"].includes(String(term.nulls)))) {\n fail('each representative ordering term needs a field, dir \"asc\" or \"desc\", and optional nulls \"first\" or \"last\".');\n continue;\n }\n orderBy.push({ field: term.field as string, dir: term.dir as \"asc\" | \"desc\", nulls: term.nulls === \"first\" ? \"first\" : \"last\" });\n }\n representative = { orderBy };\n }\n if (!isRecord(raw.source)) fail(\"source must be the record query that is grouped.\");\n else if (raw.source.grouping != null) fail(\"only one grouping stage is supported; the source query cannot itself be grouped.\");\n const { grouping: _nested, hostState: _host, ...source } = isRecord(raw.source) ? raw.source : {};\n // Retain earlier diagnostics (bounded) instead of collapsing them.\n if (Array.isArray(raw.diagnostics))\n for (const message of raw.diagnostics.slice(0, 20))\n diagnostics.push(typeof message === \"string\" && message ? message.slice(0, MAX_LABEL_LENGTH) : \"Invalid grouping definition.\");\n const normalizedSource = normalizeQueryState(source);\n if (Array.isArray(source.where)) {\n const supplied = source.where.reduce((count: number, term: unknown) => count + suppliedPredicateCount(term), 0);\n if (supplied !== normalizedSource.where.reduce((count, term) => count + predicatesOf(term).length, 0)) fail(\"source filters contain malformed predicates or exceed the predicate budget.\");\n }\n return { keys, summaries, representative, source: normalizedSource, ...(diagnostics.length ? { diagnostics: [...new Set(diagnostics)] } : {}) };\n}\n\nconst QUERY_FACETS: ReadonlySet<string> = new Set([\"filters\", \"columns\", \"order\", \"grouping\", \"metrics\", \"limit\"]);\nconst PATCH_QUERY_KEYS = [\"select\", \"where\", \"orderBy\", \"limit\", \"aggregations\", \"grouping\", \"fitToScreen\"] as const;\nconst MAX_LINK_PARAMS = 50;\n\n/** A link spec, or undefined when any part is malformed. Never partially kept:\n * dropping a key filter or patch term would silently widen the destination. */\nfunction normalizeLinkSpec(value: unknown): LinkSpec | undefined {\n if (!isRecord(value) || !isRecord(value.to)) return undefined;\n let label: LinkSpec[\"label\"];\n if (typeof value.label === \"string\" && value.label.length <= MAX_LABEL_LENGTH) label = value.label;\n else if (isRecord(value.label) && boundedString(value.label.column, MAX_FIELD_NAME_LENGTH)) label = { column: value.label.column as string };\n else return undefined;\n const to = value.to;\n if (to.kind === \"template\") {\n if (typeof to.template !== \"string\" || to.template.length > 8000) return undefined;\n return { label, to: { kind: \"template\", template: to.template } };\n }\n if (to.kind !== \"query\" || !boundedString(to.target, MAX_FIELD_NAME_LENGTH)) return undefined;\n const destination: Extract<LinkDestination, { kind: \"query\" }> = { kind: \"query\", target: to.target as string };\n if (to.base !== undefined) {\n if (to.base !== \"source\" && to.base !== \"empty\") return undefined;\n destination.base = to.base;\n }\n if (to.keyFilters !== undefined) {\n if (typeof to.keyFilters !== \"boolean\") return undefined;\n destination.keyFilters = to.keyFilters;\n }\n if (to.patch !== undefined) {\n const patch = normalizeLinkPatch(to.patch);\n if (!patch) return undefined;\n destination.patch = patch;\n }\n if (to.params !== undefined) {\n if (!isRecord(to.params)) return undefined;\n const entries = Object.entries(to.params);\n if (entries.length > MAX_LINK_PARAMS || entries.some(([key, item]) => !boundedString(key, MAX_FIELD_NAME_LENGTH) || typeof item !== \"string\" || item.length > MAX_FILTER_VALUE_LENGTH))\n return undefined;\n destination.params = Object.fromEntries(entries) as Record<string, string>;\n }\n return { label, to: destination };\n}\n\n/** True when normalization kept every supplied WHERE term. An OR group counts\n * as its members' literals (an empty group or conjunction as one), so dropping\n * any literal, a whole group or anything past the predicate budget is detected. */\nfunction keptEveryTerm(supplied: unknown, kept: readonly WhereTerm[]): boolean {\n if (!Array.isArray(supplied)) return false;\n const count = supplied.reduce((total: number, term: unknown) =>\n total + Math.max(1, suppliedPredicateCount(term)), 0);\n return count === kept.reduce((total, term) => total + predicatesOf(term).length, 0);\n}\n\n/** Keep only the facets the patch supplies, each normalized like any query.\n * Ordinary normalization drops malformed filter terms, which here would\n * silently widen the destination, so any loss rejects the whole patch. */\nfunction normalizeLinkPatch(value: unknown): QueryPatch | undefined {\n if (!isRecord(value) || !boundedString(value.id, MAX_FIELD_NAME_LENGTH) || !Array.isArray(value.owns) || !isRecord(value.query)) return undefined;\n if (value.owns.length > QUERY_FACETS.size || value.owns.some((facet) => typeof facet !== \"string\" || !QUERY_FACETS.has(facet))) return undefined;\n const raw = value.query;\n const normalized = normalizeQuery(raw, EMPTY_QUERY, false);\n if (normalized.grouping?.diagnostics) return undefined;\n if (raw.where !== undefined && !keptEveryTerm(raw.where, normalized.where)) return undefined;\n if (raw.aggregations !== undefined && (!Array.isArray(raw.aggregations) ||\n raw.aggregations.length !== (normalized.aggregations?.length ?? 0) ||\n normalized.aggregations?.some((clause) => clause.diagnostics?.length))) return undefined;\n const query: Partial<QueryState> = {};\n for (const key of PATCH_QUERY_KEYS) {\n if (raw[key] !== undefined && normalized[key] !== undefined) (query as Record<string, unknown>)[key] = normalized[key];\n }\n return { id: value.id as string, owns: [...new Set(value.owns as QueryFacet[])], query };\n}\n\n/** Structural equality on two queries — used to decide whether a `?q=` write or a\n * refetch is actually needed (avoids history spam / redundant fetches). */\nexport function queriesEqual(a: QueryState, b: QueryState): boolean {\n if (a === b) return true;\n if (a.limit !== b.limit || a.offset !== b.offset) return false;\n if ((a.fitToScreen === true) !== (b.fitToScreen === true)) return false;\n if (!sameArray(a.where, b.where)) return false;\n if (!sameArray(a.orderBy, b.orderBy)) return false;\n if (!sameArray(a.select, b.select)) return false;\n if (!sameArray(a.aggregations ?? [], b.aggregations ?? [])) return false;\n if (JSON.stringify(a.itemDetails) !== JSON.stringify(b.itemDetails)) return false;\n if (JSON.stringify(a.grouping) !== JSON.stringify(b.grouping)) return false;\n if (JSON.stringify(a.hostState) !== JSON.stringify(b.hostState)) return false;\n return true;\n}\n\nfunction sameArray<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n // Members are records of primitives (WHERE terms may nest one `any` array of\n // them) — a structural JSON compare is correct and cheap here.\n if (JSON.stringify(a[i]) !== JSON.stringify(b[i])) return false;\n }\n return true;\n}\n","// agg.ts — which aggregate ops a field type allows, and which fields can be a\n// measure or a group-by key. The single source of truth shared by the\n// QueryBuilder's metric editor, the client-side applyAggregations, and (mirrored\n// independently in backends/go) the SQL compiler. Never trust the client: the Go\n// `aggOpAllowed` enforces the same matrix before any GROUP BY is built.\n\nimport type { AggOp } from \"./query\";\nimport type { FieldType, FieldDef } from \"./schema\";\n\n/** Default aggregate ops per field type. A FieldDef.aggregate.ops overrides this.\n * `count`/`count_distinct` work on anything countable; sum/avg are numeric-only;\n * min/max need an ordered domain (numbers, datetimes, and lexical text/enum). */\nexport const AGG_OPS_BY_TYPE: Record<FieldType, AggOp[]> = {\n number: [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"],\n datetime: [\"count\", \"count_distinct\", \"min\", \"max\"],\n enum: [\"count\", \"count_distinct\", \"min\", \"max\"],\n text: [\"count\", \"count_distinct\", \"min\", \"max\"],\n bool: [\"count\", \"count_distinct\"],\n textarray: [\"count\"],\n};\n\n/** Ops that reduce a measure column. `count` is the only op that may omit a\n * field (counting rows), so it's the only one absent here. */\nexport const AGG_OPS_NEEDING_FIELD: ReadonlySet<AggOp> = new Set<AggOp>([\n \"count_distinct\",\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n]);\n\n/** Whether an op requires a measure column. */\nexport function aggOpNeedsField(op: AggOp): boolean {\n return AGG_OPS_NEEDING_FIELD.has(op);\n}\n\n/** Effective aggregate ops for a field (its override, else the type default). */\nexport function aggOpsForField(field: Pick<FieldDef, \"type\" | \"aggregate\">): AggOp[] {\n return field.aggregate?.ops ?? AGG_OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (Go aggOpAllowed is\n * the server mirror; keep them in lockstep). */\nexport function aggOpAllowedForType(type: FieldType, op: AggOp): boolean {\n return AGG_OPS_BY_TYPE[type].includes(op);\n}\n\n/** Can this field be the MEASURE of a metric? Only backend fields (they have SQL\n * to aggregate); derived/render-only columns are never pushed to the server. An\n * explicit `aggregate.measure` wins over the type default. */\nexport function isMeasurable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.measure === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.measure != null) return field.aggregate.measure;\n return aggOpsForField(field).length > 0;\n}\n\n/** Can this field be a GROUP BY key? Backend fields only. Default: low-cardinality\n * types (enum/text/bool); numbers/datetimes need bucketing (out of scope) so they\n * default off, but `aggregate.groupable: true` opts any backend field in. */\nexport function isGroupable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.groupable === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.groupable != null) return field.aggregate.groupable;\n return field.type === \"enum\" || field.type === \"text\" || field.type === \"bool\";\n}\n","import type { MetricKey, MetricValue, MetricScope, MetricDistributionResult, MetricDiagnostic, MetricHistogramBin } from \"./metricTypes\";\nimport { deflateSync, Inflate } from \"fflate\";\nimport { createSetFilter, readSetFilter } from \"./setFilter\";\n// encode.ts — URL serialization + the server-bound query subset.\n//\n// Two distinct serializations, deliberately kept apart:\n//\n// 1. encodeQuery / decodeQuery — the *whole* QueryState (incl. view state:\n// select columns + widths) ⇄ a base64url `?q=` token. This is what makes\n// reload, back/forward, bookmarks, and \"send a coworker your view\" all work\n// (decisions #4 + #5). Defaults are omitted to keep the token short.\n//\n// 2. toServerQuery — the subset the backend acts on: pushdown\n// WHERE clauses, server-sortable ORDER BY (remapped through sort.field), the\n// page window, and the field names to SELECT (so the backend evaluates the\n// computed/synthetic columns the view needs — requested ∪ always-needed,\n// design decision #2). Per-column widths never leave the client.\n//\n// Back-compat: decodeQuery accepts legacy compact shapes: `o` as a single\n// object (pre-multi-sort) and `c`/`s` as a string[] (pre-width).\n\nimport { EMPTY_QUERY, MAX_QUERY_TOKEN_LENGTH, normalizeQueryState, parseHostQueryState, predicatesOf, suppliedPredicateCount } from \"./query\";\nimport { stripSetFilter } from \"./setFilter\";\nimport type { QueryState, WhereTerm, OrderByClause, SelectColumn, AggregationClause, SetFilterMode, HostQueryState } from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { indexFields, isFilterable, isPushdownFilter, isSortable, resolveFieldName, selectedFields } from \"./schema\";\n\n// ---- base64url (browser + node) -------------------------------------------\n\nfunction toBase64Url(json: string): string {\n let b64: string;\n if (typeof Buffer !== \"undefined\") {\n b64 = Buffer.from(json, \"utf8\").toString(\"base64\");\n } else {\n const bytes = new TextEncoder().encode(json);\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n b64 = btoa(bin);\n }\n return b64.replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction fromBase64Url(s: string): string {\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4);\n // TextDecoder drops a leading byte-order mark; Buffer keeps it. Drop it on\n // every engine so a link opens the same way in browsers and Node.\n if (typeof Buffer !== \"undefined\") return Buffer.from(b64, \"base64\").toString(\"utf8\").replace(/^\\uFEFF/, \"\");\n const bin = atob(b64);\n const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n// ---- compact wire form ----------------------------------------------------\n// Keys are short to keep `?q=` small; any field at its default is omitted.\n// s = select (as [field], [field, width] or [field, width | null, display]\n// tuples; older decoders read the first two members and ignore display)\n// w = where, o = orderBy, l = limit, f = offset\n// fs = fit to the viewer's screen\n\ntype CompactColumn = [string] | [string, number] | [string, number | null, CellDisplay];\n\ninterface CompactQuery {\n s?: CompactColumn[] | string[]; // string[] = legacy\n w?: WhereTerm[];\n o?: OrderByClause[] | OrderByClause; // object accepted for legacy decode\n l?: number;\n f?: number;\n g?: AggregationClause[]; // aggregation metrics (omitted when none)\n d?: QueryState[\"itemDetails\"];\n c?: string[]; // legacy alias for select column names\n fs?: boolean;\n b?: QueryState[\"grouping\"];\n h?: QueryState[\"hostState\"];\n}\n\n/** Canonical query projected into the URL wire form. */\nfunction compactQuery(q: QueryState): CompactQuery {\n q = normalizeQueryState(q);\n const c: CompactQuery = {};\n if (q.select.length)\n c.s = q.select.map((col): CompactColumn =>\n col.display ? [col.field, col.width ?? null, col.display]\n : col.width != null ? [col.field, col.width] : [col.field]);\n if (q.where.length) c.w = q.where;\n if (q.orderBy.length) c.o = q.orderBy;\n c.l = q.limit;\n if (q.offset) c.f = q.offset;\n if (q.aggregations?.length) c.g = q.aggregations;\n if (q.itemDetails) c.d = q.itemDetails;\n if (q.fitToScreen) c.fs = true;\n if (q.grouping) c.b = q.grouping;\n if (q.hostState) c.h = q.hostState;\n return c;\n}\n\nexport const MAX_QUERY_STATE_BYTES = 4 * 1024 * 1024;\nexport class QueryDecodeError extends Error {\n constructor(public readonly code: \"invalid\" | \"too_large\" | \"unsupported_version\", message: string) {\n super(message); this.name = \"QueryDecodeError\";\n }\n}\n\n// v2 keeps execution state unchanged, but represents intact set editors once.\n// Equal property layouts share one entry rather than repeating every modality.\nfunction packQuery(c: CompactQuery): Record<string, unknown> {\n const packed: Record<string, unknown> = { ...c };\n if (c.l === EMPTY_QUERY.limit) delete packed.l;\n if (c.w) {\n const terms: unknown[] = [];\n for (let i = 0; i < c.w.length; i++) {\n const set = readSetFilter(c.w, i);\n // Scalar sets stay as plain marked terms: the packed tuple always means\n // array membership, so older decoders must not rebuild them as includes.\n if (set?.target === \"array\") {\n terms.push([\"set\", set.field, set.metadata.mode, set.metadata.values, set.metadata.id]);\n i += set.count - 1;\n } else terms.push(c.w[i]);\n }\n packed.w = terms;\n }\n if (c.d?.views) {\n const pool: unknown[] = [];\n const refs: Record<string, number> = {};\n for (const [mode, view] of Object.entries(c.d.views)) {\n let index = pool.findIndex(v => JSON.stringify(v) === JSON.stringify(view));\n if (index < 0) { index = pool.length; pool.push(view); }\n refs[mode] = index;\n }\n packed.d = { ...c.d, views: { pool, refs } };\n }\n return packed;\n}\n\nfunction unpackQuery(c: Record<string, unknown>): CompactQuery {\n if (Array.isArray(c.w)) c.w = c.w.flatMap((term: unknown) => {\n if (!Array.isArray(term)) return [term];\n if (term.length !== 5 || term[0] !== \"set\" || typeof term[1] !== \"string\" ||\n typeof term[2] !== \"string\" || ![\"any\", \"all\", \"none\", \"empty\"].includes(term[2]) || !Array.isArray(term[3]) ||\n term[3].length > 100 || !term[3].every((v: unknown) => typeof v === \"string\" && v.length <= 10000) || typeof term[4] !== \"string\")\n throw new QueryDecodeError(\"invalid\", \"Invalid set filter in query link.\");\n return createSetFilter(term[1], term[2] as SetFilterMode, term[3] as string[], term[4]);\n });\n const details = c.d;\n const views = details && typeof details === \"object\" && \"views\" in details ? details.views : undefined;\n if (details && typeof details === \"object\" && views && typeof views === \"object\" && \"pool\" in views) {\n const pool = views.pool;\n const refs = \"refs\" in views ? views.refs : undefined;\n if (!Array.isArray(pool) || pool.length > 3 || !refs || typeof refs !== \"object\" || Array.isArray(refs))\n throw new QueryDecodeError(\"invalid\", \"Invalid property views in query link.\");\n c.d = { ...details, views: Object.fromEntries(Object.entries(refs).map(([mode, index]) => {\n if (![\"hover\", \"modal\", \"expand\"].includes(mode) || !Number.isInteger(index) || (index as number) < 0 || (index as number) >= pool.length)\n throw new QueryDecodeError(\"invalid\", \"Invalid property view reference.\");\n return [mode, pool[index as number]];\n })) };\n }\n return c as CompactQuery;\n}\n\n/** v2 JSON or raw-DEFLATE UTF-8, whichever produces the shorter URL token. */\nexport function encodeQuery(q: QueryState): string {\n const json = JSON.stringify(packQuery(compactQuery(q)));\n const bytes = new TextEncoder().encode(json);\n if (bytes.length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const plain = \"2j.\" + toBase64Url(json);\n const compressed = \"2d.\" + bytesToBase64(deflateSync(bytes));\n const token = compressed.length < plain.length ? compressed : plain;\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Encoded query state exceeds the storage limit.\");\n return token;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") return Buffer.from(bytes).toString(\"base64\").replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n let bin = \"\";\n for (const byte of bytes) bin += String.fromCharCode(byte);\n return btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction inflateToken(token: string): string {\n const bin = atob(token.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const input = Uint8Array.from(bin, c => c.charCodeAt(0));\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n const stream = new Inflate((chunk, final) => {\n size += chunk.length;\n if (size > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Expanded query state exceeds the storage limit.\");\n chunks.push(chunk); complete = final;\n });\n // Small input chunks bound allocations before the expanded-size check.\n for (let i = 0; i < input.length; i += 256) stream.push(input.subarray(i, i + 256), i + 256 >= input.length);\n if (!complete) throw new QueryDecodeError(\"invalid\", \"Incomplete compressed query link.\");\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n}\n\n/** base64url token → QueryState. Tolerant: bad input and legacy shapes both\n * normalize to a valid QueryState (never throws). */\nexport function decodeQuery(token: string): QueryState {\n try { return decodeToken(token, false); } catch { return { ...EMPTY_QUERY }; }\n}\n\n/** Navigation uses this decoder so corrupt links cannot silently run defaults. */\nexport function decodeQueryStrict(token: string): QueryState {\n return decodeToken(token, true);\n}\nfunction decodeToken(token: string, strict: boolean): QueryState {\n if (!token) return { ...EMPTY_QUERY };\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Query link exceeds the storage limit.\");\n try {\n const versioned = token.includes(\".\");\n if (versioned && !token.startsWith(\"2j.\") && !token.startsWith(\"2d.\"))\n throw new QueryDecodeError(\"unsupported_version\", \"Unsupported query link version.\");\n const payload = versioned ? token.slice(3) : token;\n if (!/^[A-Za-z0-9_-]+$/.test(payload) || payload.length % 4 === 1) throw new QueryDecodeError(\"invalid\", \"Invalid query link encoding.\");\n const json = token.startsWith(\"2d.\") ? inflateToken(payload) : fromBase64Url(payload);\n if (new TextEncoder().encode(json).length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const raw = JSON.parse(json);\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw) || [\"w\", \"g\"].some(k => raw[k] !== undefined && !Array.isArray(raw[k])))\n throw new QueryDecodeError(\"invalid\", \"Invalid query link state.\");\n const c = versioned ? unpackQuery(raw) : raw as CompactQuery;\n if (strict && c.w) {\n if (c.w.some((term: WhereTerm) => !term || typeof term !== \"object\")) throw new QueryDecodeError(\"invalid\", \"Invalid query predicates.\");\n const count = c.w.reduce((n: number, term: WhereTerm) => n + suppliedPredicateCount(term), 0);\n const normalized = normalizeQueryState({ where: c.w });\n const normalizedCount = normalized.where.reduce((n, term) => n + predicatesOf(term).length, 0);\n if (count > 100 || count !== normalizedCount || c.w.some((term: WhereTerm) => predicatesOf(term).some(clause =>\n !clause || typeof clause !== \"object\" || (clause.negated !== undefined && typeof clause.negated !== \"boolean\"))))\n throw new QueryDecodeError(\"invalid\", \"Invalid query predicates or predicate budget exceeded.\");\n }\n const out = normalizeQueryState({\n select: normalizeSelect(c.s ?? c.c),\n where: Array.isArray(c.w) ? c.w : [],\n orderBy: normalizeOrderBy(c.o),\n limit: c.l,\n offset: c.f,\n aggregations: c.g,\n itemDetails: c.d,\n fitToScreen: c.fs,\n grouping: c.b,\n hostState: c.h,\n });\n if (strict && c.h !== undefined) {\n try { parseHostQueryState(c.h); } catch { throw new QueryDecodeError(\"invalid\", \"Invalid host state in query link.\"); }\n }\n if (strict && c.g && out.aggregations?.length !== c.g.length) throw new QueryDecodeError(\"invalid\", \"Invalid query metrics.\");\n return out;\n } catch (error) {\n if (error instanceof QueryDecodeError) throw error;\n throw new QueryDecodeError(\"invalid\", \"Invalid or incomplete query link.\");\n }\n}\n\nfunction normalizeSelect(s: CompactQuery[\"s\"] | CompactQuery[\"c\"]): SelectColumn[] {\n if (!Array.isArray(s)) return [];\n return s\n .map((item): SelectColumn | null => {\n if (typeof item === \"string\") return { field: item }; // legacy string[]\n if (Array.isArray(item) && typeof item[0] === \"string\") {\n const column: SelectColumn = { field: item[0] };\n if (typeof item[1] === \"number\") column.width = item[1];\n // normalizeQueryState validates the display and drops a malformed one.\n if (item[2] !== undefined) column.display = item[2] as CellDisplay;\n return column;\n }\n return null;\n })\n .filter((x): x is SelectColumn => x != null);\n}\n\nfunction normalizeOrderBy(o: CompactQuery[\"o\"]): OrderByClause[] {\n if (!o) return [];\n if (Array.isArray(o)) return o;\n return [o]; // legacy single-object form → one-element array\n}\n\n// ---- server-bound subset --------------------------------------------------\n\n/** The backend request derived from a QueryState + its schema. Mirrors the Go\n * `WireQuery`. View-only state (column widths) is intentionally absent. */\nexport interface ServerQuery {\n /** field names to return — visible columns ∪ fields referenced by where/orderBy. */\n select: string[];\n /** only terms whose every predicate is on a pushdown-filterable field. */\n where: WhereTerm[];\n /** only terms on server-sortable fields, with `field` already remapped to the\n * field's server sort key (FieldDef.sort.field) when set. */\n orderBy: OrderByClause[];\n limit: number;\n offset: number;\n /** The table's host-owned state when `hostQuery` is configured; hosts run\n * their own clauses from it. Query Table does not interpret it. */\n hostState?: HostQueryState;\n}\n\n/** Project a QueryState into the server request, dropping client-only filters,\n * client-only sorts, and remapping sort fields through `sort.field`. */\nexport function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): ServerQuery {\n if (q.grouping) throw new Error(\"This transport does not support grouped queries. Enable the v3 query executor.\");\n q = normalizeQueryState(q);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const orderBy: OrderByClause[] = [];\n for (const term of q.orderBy) {\n const field = resolveField(term.field);\n const f = byName.get(field);\n if (!f || !isSortable(f) || f.source.kind !== \"backend\") continue;\n orderBy.push({ ...term, field: f.sort?.field ?? f.name });\n }\n\n // SELECT = the BACKEND columns the response rows must carry: visible backend\n // columns, the id (for selection/refresh), and any backend column a\n // CLIENT-SIDE filter reads. Derived/render-only columns are computed on the\n // client and have no SQL to select; pushdown filters/sorts run in SQL and need\n // not be returned (design decision #2: requested ∪ always-needed).\n const select = new Set<string>(\n selectedFields(schema, q)\n .filter((f) => f.source.kind === \"backend\")\n .map((f) => f.name),\n );\n for (const field of selectedFields(schema, q)) {\n if (field.source.kind === \"derived\") {\n for (const name of field.source.dependencies ?? []) {\n if (byName.get(name)?.source.kind === \"backend\") select.add(name);\n }\n }\n }\n select.add(schema.idField);\n for (const term of q.where) {\n for (const cl of predicatesOf(term)) {\n const field = resolveField(cl.field);\n const f = byName.get(field);\n if (f && isFilterable(f) && !isPushdownFilter(f) && f.source.kind === \"backend\") select.add(field);\n }\n }\n\n return { select: [...select].sort(), where, orderBy, limit: q.limit, offset: q.offset };\n}\n\n/** A term can push down only if EVERY predicate it contains is on a\n * pushdown-filterable field. An OR group is all-or-nothing: dropping one\n * disjunct would change the set the group matches, so a group with any\n * non-pushdown member stays client-side in full. */\nfunction termIsPushdown<Row>(\n term: WhereTerm,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (name: string) => string,\n): boolean {\n return predicatesOf(term).every((cl) => {\n const f = byName.get(resolveField(cl.field));\n return f != null && isPushdownFilter(f);\n });\n}\n\n// ---- aggregation server subset --------------------------------------------\n\n/** The backend request for the metric panel. Scope is the whole filtered set:\n * the SAME pushdown WHERE as the rows query, but NO ORDER BY / LIMIT / OFFSET —\n * metrics describe every matching row, not the visible page. Mirrors the Go\n * AggSpec list. */\nexport interface AggregationRequest {\n /** The table's host-owned state when `hostQuery` is configured. */\n hostState?: HostQueryState;\n diagnostics?: MetricDiagnostic[];\n where: WhereTerm[];\n aggregations: AggregationClause[];\n}\n\n/** One group's result. `keys` has one entry per AggregationClause.groupBy field,\n * in axis order (`[]` for a grand total); a null key is the NULL/empty bucket. */\nexport interface AggregationBucket {\n keys: MetricKey[];\n error?: string;\n y?: MetricValue;\n yError?: string;\n components?: {expression:string; value:MetricValue}[];\n nullCount?: number;\n inputErrorCount?: number;\n distribution?: MetricDistributionResult;\n /** Client-side only: set by the metric UI when one histogram bin of this\n * cohort is inspected (`count`/`value` are then the bin's count). Never part\n * of a transport result. */\n bin?: MetricHistogramBin;\n /** Calendar intervals combined into a windowed point (`AggregationClause.window`);\n * fewer than its periods where the window starts before the first interval. */\n intervals?: number;\n /** Occurrences summarised by a cyclic slot (`dateGrouping.occurrence`):\n * those with a value, the samples of its mean and box. */\n occurrences?: number;\n /** The metric: a number for count/sum/avg, or the column's value for min/max\n * (which may be a string for text/datetime). null when undefined (e.g. avg of\n * an all-null column). */\n value: MetricValue;\n /** COUNT(*) of rows in the group — always present, even when `value` isn't a\n * count, so the panel can show group sizes / shares. */\n count: number;\n}\n\nexport interface AggregationResultEntry {\n /** Exact omitted additive quantity; unavailable for ratios/averages/distinct. */\n other?: AggregationBucket;\n error?: string;\n scope?: MetricScope;\n processedRows?: number;\n groupCount?: number;\n coverage?: \"exact\" | \"partial\";\n /** Groups removed by AggregationClause.minCount (present whenever it is set).\n * They are not part of `groupCount`, `buckets` or `other`. */\n hiddenGroups?: number;\n /** Echoes AggregationClause.id. */\n id: string;\n buckets: AggregationBucket[];\n}\n\nexport interface AggregationResult {\n /** One entry per requested aggregation, in request order. */\n metrics: AggregationResultEntry[];\n}\n\n/** Project a QueryState into the metric request: the pushdown WHERE subset (same\n * rule as toServerQuery) plus the aggregations whose measure + group fields are\n * all server-capable backend columns. Aggregations referencing a derived /\n * unknown field are dropped — the server has no SQL for them. */\nexport function toAggregationQuery<Row>(q: QueryState, schema: FieldSchema<Row>): AggregationRequest {\n if (q.grouping) throw new Error(\"Metrics over grouped rows require grouped-query execution.\");\n const suppliedCount = q.where.reduce((n,t)=>n+predicatesOf(t).length,0);\n q = normalizeQueryState(q);\n if (q.aggregations?.some(a => a.dateGrouping)) throw new Error(\"Date grouping currently requires local metric execution.\");\n if (q.aggregations?.some(a => a.diagnostics?.length || a.expression !== undefined || a.expressionY !== undefined || a.distribution || a.scope === \"shownRows\" || a.sort?.length || a.groupLimit || a.where?.length || a.minCount !== undefined)) throw new Error(\"Metric definition requires the version 2 metric transport.\");\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const isBackend = (name: string | undefined): boolean => {\n if (name == null) return true; // omitted measure (count(*)) is fine\n const field = resolveField(name);\n const f = byName.get(field);\n return f != null && f.source.kind === \"backend\";\n };\n\n const aggregations = (q.aggregations ?? []).filter(\n (a) => isBackend(a.field) && a.groupBy.every((g) => isBackend(g)),\n );\n\n const diagnostics: MetricDiagnostic[] = [];\n for (const c of q.aggregations ?? []) if (!aggregations.includes(c)) diagnostics.push({ metricId: c.id, code: \"unsupported_metric\", message: \"Metric requires unavailable backend fields.\", from: 0, to: 1 });\n if (where.length !== q.where.length || suppliedCount !== q.where.reduce((n,t)=>n+predicatesOf(t).length,0)) diagnostics.push({ code: \"residual_filter\", message: \"All-matching metrics are unavailable with residual client-only filters.\", from: 0, to: 1 });\n return { where, aggregations, ...(diagnostics.length ? { diagnostics } : {}) };\n}\n","import { isWhereConjunction, isWhereGroup, predicatesOf, type SetFilterMetadata, type SetFilterMode, type WhereBranch, type WhereTerm } from \"./query\";\nimport { filterValues, type FieldDef } from \"./schema\";\n\n/** What a set editor compiles to: array membership (`includes`) for textarray\n * fields, or scalar equality (`=` / `!=`) for enum and static-option text fields. */\nexport type SetFilterTarget = \"array\" | \"scalar\";\n\n/** The set editor a field opted into with `filter.editor: \"set\"`, or null.\n * Text fields qualify only with static `filter.values.options`. */\nexport function setFilterTarget(field: FieldDef): SetFilterTarget | null {\n if (field.filter?.editor !== \"set\") return null;\n if (field.type === \"textarray\") return \"array\";\n if (field.type === \"enum\" || (field.type === \"text\" && filterValues(field).source === \"static\")) return \"scalar\";\n return null;\n}\n\n/** Modes a target supports. ALL and EMPTY describe arrays; a scalar holds one value. */\nexport function setFilterModes(target: SetFilterTarget): SetFilterMode[] {\n return target === \"array\" ? [\"any\", \"all\", \"none\", \"empty\"] : [\"any\", \"none\"];\n}\n\n/** Compile an explicitly identified editor into existing CNF predicates.\n * Scalar NONE keeps NULL rows: one `(is_null OR != v)` group per value, because\n * a bare `!=` is null-exclusive. */\nexport function createSetFilter(field: string, mode: SetFilterMode, values: string[], id: string, target: SetFilterTarget = \"array\"): WhereTerm[] {\n if (!setFilterModes(target).includes(mode)) throw new Error(`${mode.toUpperCase()} set filters require a textarray field.`);\n const keys = [...new Set(values)];\n if (mode !== \"empty\" && keys.length === 0) return [];\n const members = keys.map((value) => ({ field, op: target === \"array\" ? \"includes\" as const : \"=\" as const, value }));\n const isNull = { field, op: \"is_null\" as const, value: \"\" };\n let terms: WhereTerm[];\n if (mode === \"empty\") terms = [isNull];\n else if (mode === \"any\") terms = members.length === 1 ? members : [{ any: members }];\n else if (mode === \"all\") terms = members;\n else terms = members.map((clause) => ({ any: [isNull, target === \"array\" ? { ...clause, negated: true } : { ...clause, op: \"!=\" as const }] }));\n return terms.map((term) => ({ ...term, setFilter: { id, mode, values: mode === \"empty\" ? [] : [...keys] } }));\n}\n\n/** Remove presentation metadata at transport boundaries, including inner literals. */\nexport function stripSetFilter(term: WhereTerm): WhereTerm {\n const strip = ({ setFilter: _metadata, ...clause }: ReturnType<typeof predicatesOf>[number]) => clause;\n if (!isWhereGroup(term)) return strip(term);\n return { any: term.any.map((member: WhereBranch) => isWhereConjunction(member) ? { all: member.all.map(strip) } : strip(member)) } as WhereTerm;\n}\n\n/** Only collapse explicitly marked, intact editor output. Never infer from predicates. */\nexport function readSetFilter(where: WhereTerm[], index: number): { field: string; metadata: SetFilterMetadata; count: number; target: SetFilterTarget } | null {\n const term = where[index];\n const metadata = term?.setFilter;\n if (!term || !metadata || where[index - 1]?.setFilter?.id === metadata.id) return null;\n const field = predicatesOf(term)[0]?.field;\n if (!field) return null;\n // The compiled operator distinguishes the two shapes; the exact comparison\n // below still rejects anything the compiler would not have produced.\n const target: SetFilterTarget = predicatesOf(term).some((clause) => clause.op === \"includes\") || !setFilterModes(\"scalar\").includes(metadata.mode) ? \"array\" : \"scalar\";\n const expected = createSetFilter(field, metadata.mode, metadata.values, metadata.id, target);\n if (expected.length === 0) return null;\n for (let offset = 0; offset < expected.length; offset++) {\n const actual = where[index + offset];\n if (!actual || JSON.stringify(actual.setFilter) !== JSON.stringify(expected[offset]!.setFilter) || JSON.stringify(stripSetFilter(actual)) !== JSON.stringify(stripSetFilter(expected[offset]!))) return null;\n }\n if (where[index + expected.length]?.setFilter?.id === metadata.id) return null;\n return { field, metadata, count: expected.length, target };\n}\n\n/** Canonicalize consumer-owned value aliases without disconnecting editor metadata. */\nexport function mapSetFilterValues(where: WhereTerm[], canonicalize: (field: string, value: string) => string): WhereTerm[] {\n const result: WhereTerm[] = [];\n for (let index = 0; index < where.length; index++) {\n const set = readSetFilter(where, index);\n if (!set) { result.push(where[index]!); continue; }\n result.push(...createSetFilter(set.field, set.metadata.mode, set.metadata.values.map((value) => canonicalize(set.field, value)), set.metadata.id, set.target));\n index += set.count - 1;\n }\n return result;\n}\n","import { decodeQueryStrict, encodeQuery } from \"./encode\";\nimport { MAX_QUERY_TOKEN_LENGTH, type QueryState } from \"./query\";\n\nexport interface QuerySnapshot {\n version: 1;\n code: string;\n token: string;\n createdAt: number;\n}\n/** The host owns authenticated, durable storage. Save is immutable/idempotent\n * by code: an existing code may never be assigned a different token. */\nexport interface QuerySnapshotStore {\n save(key: string, snapshot: QuerySnapshot, signal?: AbortSignal): Promise<QuerySnapshot>;\n resolve(key: string, code: string, signal?: AbortSignal): Promise<QuerySnapshot | null>;\n}\nexport interface QuerySnapshotCache {\n get(key: string, code: string): QuerySnapshot | null;\n find(key: string, token: string): QuerySnapshot | null;\n put(key: string, snapshot: QuerySnapshot): void;\n isDurable?(key: string, code: string): boolean;\n markDurable?(key: string, code: string): void;\n}\nexport interface QueryLink {\n url: string;\n kind: \"inline\" | \"local\" | \"durable\";\n bytes: number;\n snapshotCode?: string;\n}\nexport interface QueryLinkOptions {\n /** Complete URL budget, including host parameters and fragment. Default 2000. */\n maxUrlBytes?: number;\n cache?: QuerySnapshotCache;\n}\nconst codePattern = /^[A-Za-z0-9_-]{22}$/;\nexport function validateQuerySnapshot(input: unknown): QuerySnapshot {\n const s = input as QuerySnapshot;\n if (!s || s.version !== 1 || !codePattern.test(s.code) || typeof s.token !== \"string\" ||\n s.token.length > MAX_QUERY_TOKEN_LENGTH || !Number.isFinite(s.createdAt)) throw Error(\"Invalid query snapshot.\");\n decodeQueryStrict(s.token);\n return { version: 1, code: s.code, token: s.token, createdAt: s.createdAt };\n}\nfunction newSnapshot(token: string): QuerySnapshot {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return { version: 1, code: btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\"), token, createdAt: Date.now() };\n}\n\n/** FIFO entries are scoped by dataset. One bounded envelope makes each write\n * atomic; the new entry is protected from eviction and stored before URL use.\n * Browser profiles, origins, and devices do not share these entries. */\nexport function localQuerySnapshotCache(options: {\n storage?: Pick<Storage, \"getItem\" | \"setItem\">;\n storageKey?: string;\n maxEntries?: number;\n maxBytes?: number;\n} = {}): QuerySnapshotCache {\n const storageKey = options.storageKey ?? \"query-table:link-cache:v1\";\n const maxEntries = options.maxEntries ?? 100;\n const maxBytes = options.maxBytes ?? 2 * 1024 * 1024;\n if (!Number.isInteger(maxEntries) || maxEntries < 1 || !Number.isFinite(maxBytes) || maxBytes < 1) throw Error(\"Invalid query link cache limits.\");\n type Entry = { key: string; snapshot: QuerySnapshot; durable?: boolean };\n const storage = () => options.storage ?? globalThis.localStorage;\n function read(): Entry[] {\n const text = storage().getItem(storageKey);\n if (!text) return [];\n let raw: unknown;\n try { raw = JSON.parse(text); } catch { return []; }\n if (!Array.isArray(raw)) return [];\n const entries: Entry[] = raw.filter(e => e && typeof e.key === \"string\" && e.snapshot &&\n e.snapshot.version === 1 && codePattern.test(e.snapshot.code) && typeof e.snapshot.token === \"string\" &&\n e.snapshot.token.length <= MAX_QUERY_TOKEN_LENGTH && Number.isFinite(e.snapshot.createdAt)).slice(-maxEntries);\n // A lowered host limit trims the oldest entries instead of poisoning the\n // cache. The next successful write replaces malformed/outdated envelopes.\n while (entries.length && JSON.stringify(entries).length * 2 > maxBytes) entries.shift();\n return entries;\n }\n return {\n isDurable(key, code) { return read().some(e => e.key === key && e.snapshot.code === code && e.durable); },\n markDurable(key, code) {\n const entries = read(); const entry = entries.find(e => e.key === key && e.snapshot.code === code);\n if (entry) {\n entry.durable = true;\n let text = JSON.stringify(entries);\n while (text.length * 2 > maxBytes && entries.length > 1) {\n entries.splice(entries[0] === entry ? 1 : 0, 1); text = JSON.stringify(entries);\n }\n if (text.length * 2 <= maxBytes) storage().setItem(storageKey, text);\n }\n },\n get(key, code) { return read().find(e => e.key === key && e.snapshot.code === code)?.snapshot ?? null; },\n find(key, token) { return read().find(e => e.key === key && e.snapshot.token === token)?.snapshot ?? null; },\n put(key, snapshot) {\n const entries = read();\n const old = entries.find(e => e.key === key && e.snapshot.code === snapshot.code);\n if (old) {\n if (old.snapshot.token !== snapshot.token) throw Error(\"A query link code cannot be overwritten.\");\n const text = JSON.stringify(entries);\n if (storage().getItem(storageKey) !== text) storage().setItem(storageKey, text);\n return;\n }\n entries.push({ key, snapshot: validateQuerySnapshot(snapshot) });\n while (entries.length > maxEntries) entries.shift();\n let text = JSON.stringify(entries);\n // Web Storage stores UTF-16 strings; charge both bytes of each code unit.\n while (text.length * 2 > maxBytes && entries.length > 1) { entries.shift(); text = JSON.stringify(entries); }\n if (text.length * 2 > maxBytes) throw Error(\"This query is too large for the local link cache.\");\n storage().setItem(storageKey, text); // Throws on quota/access failure; caller keeps the previous URL.\n },\n };\n}\n\nexport function memoryQuerySnapshotCache(): QuerySnapshotCache {\n let text: string | null = null;\n return localQuerySnapshotCache({ storage: { getItem: () => text, setItem: (_key, value) => { text = value; } } });\n}\n\nexport type QuerySnapshotHttpErrorCode = \"quota\" | \"forbidden\" | \"conflict\" | \"unavailable\" | \"storage\" | \"http\";\n\n/** HTTP failures retain structured information for host error formatting. The\n * message is plain text suitable for displaying in the Save/Share UI. */\nexport class QuerySnapshotHttpError extends Error {\n readonly name = \"QuerySnapshotHttpError\";\n constructor(\n readonly status: number,\n readonly code: QuerySnapshotHttpErrorCode,\n message: string,\n readonly detail?: string,\n readonly serverCode?: string,\n ) { super(message); }\n}\n\nasync function snapshotHttpError(response: Response): Promise<QuerySnapshotHttpError> {\n // Error endpoints may return plain text (including Go's http.Error), JSON,\n // HTML proxy pages, or arbitrarily large bodies. Read at most 4 KiB and never\n // turn an infrastructure response or HTML into a browser-facing message.\n let detail: string | undefined;\n let serverCode: string | undefined;\n const type = response.headers.get(\"content-type\")?.split(\";\")[0]?.trim().toLowerCase();\n if (response.body && (type === \"text/plain\" || type === \"application/json\")) {\n const reader = response.body.getReader();\n try {\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n while (size <= 4096) {\n const next = await reader.read();\n if (next.done) { complete = true; break; }\n size += next.value.byteLength;\n if (size <= 4096) chunks.push(next.value);\n }\n if (complete) {\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n const text = new TextDecoder().decode(bytes);\n let reason: unknown = text;\n if (type === \"application/json\") {\n const body = JSON.parse(text);\n reason = body?.message ?? body?.error?.message ?? body?.error;\n const code = body?.code ?? body?.error?.code;\n if (typeof code === \"string\" && /^[A-Za-z0-9_.-]{1,64}$/.test(code)) serverCode = code;\n }\n if (typeof reason === \"string\" && !/[<>]/.test(reason)) {\n const safe = reason.replace(/[\\u0000-\\u001f\\u007f]/g, \" \").trim();\n if (safe) detail = safe.slice(0, 512);\n }\n }\n } catch { /* An unreadable error body must not hide the HTTP failure. */ }\n finally {\n try { await reader.cancel(); } catch { /* Already closed or disconnected. */ }\n reader.releaseLock();\n }\n }\n const status = response.status;\n const code: QuerySnapshotHttpErrorCode = status === 507 ? \"quota\" : status === 401 || status === 403 ? \"forbidden\"\n : status === 409 ? \"conflict\" : status === 404 ? \"unavailable\" : status >= 500 ? \"storage\" : \"http\";\n const messages: Record<QuerySnapshotHttpErrorCode, string> = {\n quota: \"Query snapshot storage is full. Ask your host to increase its quota, then retry saving. Existing links still work.\",\n forbidden: \"You do not have permission to save or open this query link. Sign in or ask your host for access.\",\n conflict: \"This query link code already identifies different state. Ask your host to check its snapshot store.\",\n unavailable: \"This query link is unavailable. Check its address or ask its author for a new link.\",\n storage: \"Query snapshot storage is temporarily unavailable. Retry later; your previous saved query is unchanged.\",\n http: `Query snapshot request failed (${status}). Check the request or retry later.`,\n };\n const message = messages[code] + (code !== \"http\" ? ` (HTTP ${status})` : \"\")\n + (detail && (status < 500 || status === 507) ? ` ${detail}` : \"\");\n return new QuerySnapshotHttpError(status, code, message, detail, serverCode);\n}\n\nexport function httpQuerySnapshotStore(base: string, fetcher: typeof fetch = fetch): QuerySnapshotStore {\n const url = (key: string, code: string) => `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(key)}&code=${encodeURIComponent(code)}`;\n async function responseSnapshot(response: Response): Promise<QuerySnapshot> {\n if (!response.ok) throw await snapshotHttpError(response);\n return validateQuerySnapshot(await response.json());\n }\n return {\n async save(key, snapshot, signal) {\n const result = await responseSnapshot(await fetcher(url(key, snapshot.code), {\n method: \"PUT\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(snapshot), ...(signal ? { signal } : {}),\n }));\n if (result.code !== snapshot.code || result.token !== snapshot.token) throw Error(\"The snapshot store changed this immutable query link.\");\n return result;\n },\n async resolve(key, code, signal) {\n const response = await fetcher(url(key, code), signal ? { signal } : {});\n if (response.status === 404) return null;\n const result = await responseSnapshot(response);\n if (result.code !== code) throw Error(\"The snapshot store returned a different query link.\");\n return result;\n },\n };\n}\n\nexport interface QueryLinkService {\n local(query: QueryState, baseUrl: string, parameter?: string): QueryLink;\n durable(query: QueryState, baseUrl: string, parameter?: string): Promise<QueryLink>;\n snapshot(query: QueryState): Promise<QuerySnapshot | null>;\n resolve(url: string, parameter?: string, signal?: AbortSignal): Promise<QueryState | null>;\n}\n\n/** Local URL synchronization never writes to the server. Only explicit\n * snapshot/durable calls (Save/Share/Bookmark) promote state to the host store. */\nexport function createQueryLinkService(key: string, store?: QuerySnapshotStore, options: QueryLinkOptions = {}): QueryLinkService {\n const budget = options.maxUrlBytes ?? 2000;\n if (!Number.isInteger(budget) || budget < 1) throw Error(\"Invalid query URL budget.\");\n const cache = options.cache ?? localQuerySnapshotCache();\n const promoted = new Map<string, Promise<QuerySnapshot>>();\n const attempts = new Map<string, QuerySnapshot>();\n const known = new Map<string, QuerySnapshot>();\n function remember(snapshot: QuerySnapshot) {\n known.set(snapshot.code, snapshot);\n while (known.size > 100) known.delete(known.keys().next().value!);\n try { cache.put(key, snapshot); cache.markDurable?.(key, snapshot.code); } catch { /* Durable link does not require a cache. */ }\n }\n function link(base: string, parameter: string, value: string, kind: QueryLink[\"kind\"]): QueryLink {\n const url = new URL(base);\n url.searchParams.set(parameter, value);\n const bytes = new TextEncoder().encode(url.toString()).length;\n if (bytes > budget) throw Error(\"The query link exceeds the URL budget, including the page address.\");\n return { url: url.toString(), kind, bytes, ...(kind !== \"inline\" ? { snapshotCode: value.slice(1) } : {}) };\n }\n function cached(token: string): QuerySnapshot | null {\n try { return cache.find(key, token); } catch { return null; }\n }\n async function snapshot(query: QueryState): Promise<QuerySnapshot | null> {\n if (!store) return null;\n const token = encodeQuery(query);\n const existing = promoted.get(token);\n if (existing) return existing;\n const local = attempts.get(token) ?? cached(token) ?? newSnapshot(token);\n attempts.set(token, local);\n while (attempts.size > 100) attempts.delete(attempts.keys().next().value!);\n // Also retain the code after failed/uncertain writes, so retries are idempotent.\n try { cache.put(key, local); } catch { /* A durable store works without browser storage. */ }\n const pending = store.save(key, local).then(result => {\n const valid = validateQuerySnapshot(result);\n if (valid.code !== local.code || valid.token !== token) throw Error(\"The snapshot store changed this immutable query link.\");\n remember(valid);\n return valid;\n });\n promoted.set(token, pending);\n while (promoted.size > 100) promoted.delete(promoted.keys().next().value!);\n try { return await pending; } catch (error) { promoted.delete(token); throw error; }\n }\n return {\n local(query, baseUrl, parameter = \"q\") {\n const token = encodeQuery(query);\n const current = new URL(baseUrl).searchParams.get(parameter);\n if (current?.startsWith(\"@\") && known.get(current.slice(1))?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n if (current?.startsWith(\"@\")) {\n try {\n const code = current.slice(1);\n if (cache.isDurable?.(key, code) && cache.get(key, code)?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n } catch { /* Try ordinary inline/local materialization next. */ }\n }\n const url = new URL(baseUrl); url.searchParams.set(parameter, token);\n if (new TextEncoder().encode(url.toString()).length <= budget) return link(baseUrl, parameter, token, \"inline\");\n const local = cached(token) ?? newSnapshot(token);\n const result = link(baseUrl, parameter, \"@\" + local.code, \"local\");\n cache.put(key, local);\n return result;\n },\n async durable(query, baseUrl, parameter = \"q\") {\n const saved = await snapshot(query);\n if (saved) return link(baseUrl, parameter, \"@\" + saved.code, \"durable\");\n const token = encodeQuery(query);\n // Small inline links are portable without a server; never share a local-only code.\n return link(baseUrl, parameter, token, \"inline\");\n },\n snapshot,\n async resolve(baseUrl, parameter = \"q\", signal) {\n const values = new URL(baseUrl).searchParams.getAll(parameter);\n if (!values.length || (values.length === 1 && values[0] === \"\")) return null;\n if (values.length !== 1) throw Error(\"Invalid or conflicting query link parameters.\");\n const value = values[0]!;\n if (!value.startsWith(\"@\")) return decodeQueryStrict(value);\n const code = value.slice(1);\n if (!codePattern.test(code)) throw Error(\"Invalid query link code.\");\n let local: QuerySnapshot | null = null;\n try { local = cache.get(key, code); if (local) local = validateQuerySnapshot(local); } catch { local = null; }\n const result = local ?? (store ? await store.resolve(key, code, signal) : null);\n if (!result) throw Error(\"This query link is unavailable. Its local cache entry may have expired; use a saved or shared link for permanent access.\");\n const valid = validateQuerySnapshot(result);\n if (valid.code !== code) throw Error(\"Invalid query snapshot code.\");\n if (!local) remember(valid);\n else { try { if (cache.isDurable?.(key, code)) remember(valid); } catch { /* Cache metadata is optional. */ } }\n return decodeQueryStrict(valid.token);\n },\n };\n}\n","import type { FormulaResult, FormulaValue } from \"./formula\";\n\n/** Reserved field token namespace. Query state stores IDs, never formula source. */\nexport const COMPUTED_PREFIX = \"@computed/\";\nexport const computedFieldName = (id: string): string => COMPUTED_PREFIX + id;\nexport const isComputedField = (name: string): boolean =>\n name.trim().toLowerCase().startsWith(COMPUTED_PREFIX);\nexport interface ComputedColumn {\n id: string;\n label: string;\n expression: { language: \"qt-expr\"; version: 1; source: string };\n /** Optimistic concurrency token issued by the store. */\n revision: string;\n}\nexport type ComputedColumnDraft = Omit<ComputedColumn, \"revision\">;\nexport interface ComputedColumnStore {\n /** Return the complete authorized catalogue for this dataset. */\n list(dataset: string, signal?: AbortSignal): Promise<ComputedColumn[]>;\n /** null creates a new ID; updates must match the current revision. */\n save(\n dataset: string,\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ): Promise<ComputedColumn>;\n /** Optional push invalidation, including changes from other sessions. */\n subscribe?(dataset: string, listener: () => void): () => void;\n}\nexport function validateComputedColumn(input: unknown): ComputedColumn {\n const c = input as ComputedColumn;\n if (\n !c ||\n typeof c.id !== \"string\" ||\n !/^[a-zA-Z0-9_-]{1,128}$/.test(c.id) ||\n typeof c.label !== \"string\" ||\n !c.label.trim() ||\n c.label.length > 200 ||\n typeof c.revision !== \"string\" ||\n !c.revision ||\n c.revision.length > 256 ||\n c.expression?.language !== \"qt-expr\" ||\n c.expression.version !== 1 ||\n typeof c.expression.source !== \"string\" ||\n !c.expression.source.trim() ||\n c.expression.source.length > 10000\n ) {\n throw new Error(\n \"Invalid computed column definition or unsupported formula version.\",\n );\n }\n return {\n id: c.id,\n label: c.label,\n revision: c.revision,\n expression: { ...c.expression },\n };\n}\nexport function memoryComputedColumnStore(\n seed: Record<string, ComputedColumn[]> = {},\n): ComputedColumnStore {\n const data = new Map(\n Object.entries(seed).map(([k, v]) => [\n k,\n new Map(v.map((c) => [c.id, validateComputedColumn(c)])),\n ]),\n );\n // Revisions are opaque: never derive a new token by parsing an existing one.\n // Reserve all seed tokens so even a seed from this namespace cannot recur.\n const seedRevisions = new Set(\n [...data.values()].flatMap((entries) =>\n [...entries.values()].map((c) => c.revision),\n ),\n );\n let revisionSequence = 0n;\n function freshRevision(): string {\n let revision: string;\n do {\n revision = `memory:${++revisionSequence}`;\n } while (seedRevisions.has(revision));\n return revision;\n }\n const listeners = new Map<string, Set<() => void>>();\n return {\n async list(dataset) {\n return [...(data.get(dataset)?.values() ?? [])].map(\n validateComputedColumn,\n );\n },\n async save(dataset, column, expectedRevision) {\n const entries = data.get(dataset) ?? new Map<string, ComputedColumn>();\n const current = entries.get(column.id);\n if ((current?.revision ?? null) !== expectedRevision)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n const next = validateComputedColumn({\n ...column,\n revision: freshRevision(),\n });\n entries.set(next.id, next);\n data.set(dataset, entries);\n listeners.get(dataset)?.forEach((fn) => fn());\n return validateComputedColumn(next);\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\n\n/** REST adapter. The implementing server owns authorization and DB persistence.\n * GET base?dataset=… → ComputedColumn[]\n * PUT base?dataset=… → {column, expectedRevision} → ComputedColumn\n * Return HTTP 409 for a stale revision. No formula evaluation happens there. */\nexport function httpComputedColumnStore(\n base: string,\n fetcher: typeof fetch = fetch,\n): ComputedColumnStore {\n const listeners = new Map<string, Set<() => void>>();\n const url = (dataset: string) =>\n `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(dataset)}`;\n async function read(response: Response): Promise<unknown> {\n if (response.status === 409)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n if (!response.ok)\n throw new Error(\n `Computed column store request failed (${response.status}).`,\n );\n return response.json();\n }\n return {\n async list(dataset, signal) {\n const raw = await read(\n await fetcher(url(dataset), { ...(signal ? { signal } : {}) }),\n );\n if (!Array.isArray(raw))\n throw new Error(\"Invalid computed column catalogue.\");\n return raw.map(validateComputedColumn);\n },\n async save(dataset, column, expectedRevision) {\n const result = validateComputedColumn(\n await read(\n await fetcher(url(dataset), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ column, expectedRevision }),\n }),\n ),\n );\n listeners.get(dataset)?.forEach((fn) => fn());\n return result;\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\nexport interface ComputedCellError {\n computedError: string;\n}\nexport function isComputedCellError(\n value: unknown,\n): value is ComputedCellError {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"computedError\" in value &&\n typeof (value as ComputedCellError).computedError === \"string\"\n );\n}\nexport interface PreviewGroup {\n inputs: FormulaValue[];\n result: FormulaResult;\n count: number;\n}\nexport interface ColumnPreview {\n dependencies: string[];\n groups: PreviewGroup[];\n processed: number;\n total: number;\n nulls: number;\n errors: number;\n}\nexport function groupPreview(\n dependencies: string[],\n inputs: Record<string, FormulaValue>[],\n results: FormulaResult[],\n total: number,\n): ColumnPreview {\n const groups = new Map<string, PreviewGroup>();\n let nulls = 0,\n errors = 0;\n inputs.forEach((row, i) => {\n const values = dependencies.map((name) => row[name] ?? null),\n result = results[i] ?? { value: null, error: \"No result.\" };\n const key = JSON.stringify([values, result.value, result.error ?? null]);\n const group = groups.get(key);\n if (group) group.count++;\n else groups.set(key, { inputs: values, result, count: 1 });\n if (result.error) errors++;\n else if (result.value === null) nulls++;\n });\n return {\n dependencies,\n groups: [...groups.values()].sort((a, b) => b.count - a.count),\n processed: inputs.length,\n total,\n nulls,\n errors,\n };\n}\n\n/** Server-issued capabilities are hints for client planning, never authorization. */\nexport interface ComputedFieldCapabilities {\n\n /** Host-approved canonical predicates; omitted retains the closed default. */\n filter?: boolean;\n type: import('./schema').FieldType;\n select: boolean;\n sort: boolean;\n measure: boolean;\n group: boolean;\n reason?: string;\n}\nexport interface ComputedExecution {\n profile: string;\n planToken: string;\n resolvedRevisions: Record<string,string>;\n fields: Record<string,ComputedFieldCapabilities>;\n fingerprint?: string;\n snapshot?: string;\n}\nexport type RowComputedValues = Record<string,{value: import('./metricTypes').MetricValue; error?: {code:string}}>;\n","import type { FieldType } from \"./schema\";\n\nexport type FormulaType = Exclude<FieldType, \"enum\"> | \"null\";\nexport type FormulaValue = string | number | boolean | string[] | null;\nexport interface FormulaDiagnostic {\n message: string;\n from: number;\n to: number;\n}\nexport type FormulaNode =\n | { kind: \"literal\"; value: FormulaValue; from: number; to: number }\n | {\n kind: \"field\";\n name: string;\n valueType?: FormulaType;\n from: number;\n to: number;\n }\n | {\n kind: \"call\";\n name: string;\n args: FormulaNode[];\n from: number;\n to: number;\n };\nexport interface FormulaPlan {\n ast: FormulaNode;\n dependencies: string[];\n type: FormulaType;\n}\nexport interface RegexInspection {\n input: string;\n start: number;\n end: number;\n groups: (string | null)[];\n}\nexport interface FormulaResult {\n value: FormulaValue;\n error?: string;\n regex?: RegexInspection;\n}\nexport interface FormulaFunction {\n name: string;\n signature: string;\n description: string;\n min: number;\n max: number;\n result: FormulaType | \"branch\";\n args: FormulaType[] | \"any\";\n}\n\nconst f = (\n name: string,\n signature: string,\n description: string,\n min: number,\n max: number,\n result: FormulaFunction[\"result\"],\n args: FormulaFunction[\"args\"],\n): FormulaFunction => ({\n name,\n signature,\n description,\n min,\n max,\n result,\n args,\n});\nexport const FORMULA_FUNCTIONS: FormulaFunction[] = [\n ...[\"LEFT\", \"RIGHT\"].map((n) =>\n f(\n n,\n `${n}(text, count)`,\n \"Take Unicode code points from the end indicated.\",\n 2,\n 2,\n \"text\",\n [\"text\", \"number\"],\n ),\n ),\n f(\n \"SUBSTRING\",\n \"SUBSTRING(text, start, length)\",\n \"One-based start; length is optional.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"number\"],\n ),\n f(\"LENGTH\", \"LENGTH(text)\", \"Count Unicode code points.\", 1, 1, \"number\", [\n \"text\",\n ]),\n f(\n \"URL_ENCODE\",\n \"URL_ENCODE(text)\",\n \"Percent-encode UTF-8 text for a URL. Only letters, digits and - . _ ~ are kept.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ...[\"LOWER\", \"UPPER\", \"TRIM\", \"LTRIM\", \"RTRIM\"].map((n) =>\n f(\n n,\n `${n}(text)`,\n \"Change case or remove surrounding whitespace.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ),\n f(\n \"REPLACE\",\n \"REPLACE(text, search, replacement)\",\n \"Replace all literal occurrences.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"text\"],\n ),\n ...[\"LPAD\", \"RPAD\"].map((n) =>\n f(\n n,\n `${n}(text, length, padding)`,\n \"Pad to a code-point length; default padding is a space.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"text\"],\n ),\n ),\n f(\n \"SPLIT_PART\",\n \"SPLIT_PART(text, separator, index)\",\n \"One-based part; missing part returns null.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"number\"],\n ),\n f(\n \"CONCAT\",\n \"CONCAT(text, ...)\",\n \"Combine text; null propagates.\",\n 1,\n 50,\n \"text\",\n [\"text\"],\n ),\n f(\n \"CONCAT_WS\",\n \"CONCAT_WS(separator, text, ...)\",\n \"Combine text, skipping null arguments.\",\n 2,\n 50,\n \"text\",\n [\"text\"],\n ),\n ...[\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].map((n) =>\n f(\n n,\n `${n}(text, search, ignoreCase)`,\n \"Case-sensitive unless the optional third argument is true.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"bool\"],\n ),\n ),\n f(\n \"REGEX_TEST\",\n \"REGEX_TEST(text, pattern, flags)\",\n \"Test a JavaScript Unicode regex; flags: i, m, s.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"text\"],\n ),\n f(\n \"REGEX_EXTRACT\",\n \"REGEX_EXTRACT(text, pattern, group, flags)\",\n \"Extract a capture (default 0: whole match); no match returns null.\",\n 2,\n 4,\n \"text\",\n [\"text\", \"text\", \"number\", \"text\"],\n ),\n f(\n \"REGEX_REPLACE\",\n \"REGEX_REPLACE(text, pattern, replacement, flags)\",\n \"Replace all matches; supports $1 capture references.\",\n 3,\n 4,\n \"text\",\n [\"text\", \"text\", \"text\", \"text\"],\n ),\n ...[\"ABS\", \"FLOOR\", \"CEIL\", \"TRUNC\", \"SQRT\"].map((n) =>\n f(n, `${n}(number)`, \"Numeric transformation.\", 1, 1, \"number\", [\"number\"]),\n ),\n f(\n \"ROUND\",\n \"ROUND(number, digits)\",\n \"Round to decimal places (default 0, range -15 to 15).\",\n 1,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"POWER\",\n \"POWER(base, exponent)\",\n \"Raise a number to a power.\",\n 2,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"CLAMP\",\n \"CLAMP(number, lower, upper)\",\n \"Constrain a number to an inclusive range.\",\n 3,\n 3,\n \"number\",\n [\"number\"],\n ),\n ...[\"LEAST\", \"GREATEST\"].map((n) =>\n f(\n n,\n `${n}(number, ...)`,\n \"Compare numbers within this row.\",\n 1,\n 50,\n \"number\",\n [\"number\"],\n ),\n ),\n f(\n \"IF\",\n \"IF(condition, then, otherwise)\",\n \"Evaluate only the chosen branch; null condition uses otherwise.\",\n 3,\n 3,\n \"branch\",\n \"any\",\n ),\n f(\n \"IFS\",\n \"IFS(condition, value, ..., fallback)\",\n \"First true condition wins; final fallback is required.\",\n 3,\n 49,\n \"branch\",\n \"any\",\n ),\n f(\n \"SWITCH\",\n \"SWITCH(value, match, result, ..., fallback)\",\n \"Match a value to a result; final fallback is required.\",\n 4,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"COALESCE\",\n \"COALESCE(value, ...)\",\n \"First non-null value, evaluated lazily.\",\n 1,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"NULLIF\",\n \"NULLIF(value, other)\",\n \"Return null if the values are equal.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...[\"IS_NULL\", \"IS_EMPTY\"].map((n) =>\n f(\n n,\n `${n}(value)`,\n \"Test null, or null/empty text/empty array.\",\n 1,\n 1,\n \"bool\",\n \"any\",\n ),\n ),\n f(\n \"IFERROR\",\n \"IFERROR(value, fallback)\",\n \"Use fallback only when evaluating value fails.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...(\n [\n [\"TO_TEXT\", \"text\"],\n [\"TO_NUMBER\", \"number\"],\n [\"TO_BOOLEAN\", \"bool\"],\n [\"TO_DATETIME\", \"datetime\"],\n ] as const\n ).map(([n, t]) =>\n f(\n n,\n `${n}(value)`,\n \"Explicit conversion; invalid input produces a cell error.\",\n 1,\n 1,\n t,\n \"any\",\n ),\n ),\n f(\n \"SPLIT\",\n \"SPLIT(text, separator)\",\n \"Split text into an array.\",\n 2,\n 2,\n \"textarray\",\n [\"text\", \"text\"],\n ),\n f(\"JOIN\", \"JOIN(array, separator)\", \"Join an array of text.\", 2, 2, \"text\", [\n \"textarray\",\n \"text\",\n ]),\n f(\n \"ARRAY_LENGTH\",\n \"ARRAY_LENGTH(array)\",\n \"Count array elements.\",\n 1,\n 1,\n \"number\",\n [\"textarray\"],\n ),\n f(\n \"ARRAY_CONTAINS\",\n \"ARRAY_CONTAINS(array, text)\",\n \"Case-sensitive array membership.\",\n 2,\n 2,\n \"bool\",\n [\"textarray\", \"text\"],\n ),\n f(\n \"ARRAY_GET\",\n \"ARRAY_GET(array, index)\",\n \"One-based element; out of range returns null.\",\n 2,\n 2,\n \"text\",\n [\"textarray\", \"number\"],\n ),\n ...[\"ARRAY_UNIQUE\", \"ARRAY_SORT\"].map((n) =>\n f(\n n,\n `${n}(array)`,\n \"Deduplicate or sort text elements by code-point order.\",\n 1,\n 1,\n \"textarray\",\n [\"textarray\"],\n ),\n ),\n ...[\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\", \"WEEKDAY\"].map((n) =>\n f(\n n,\n `${n}(datetime)`,\n \"UTC date component; weekday is Monday=1 through Sunday=7.\",\n 1,\n 1,\n \"number\",\n [\"datetime\"],\n ),\n ),\n f(\n \"DATE_TRUNC\",\n \"DATE_TRUNC(unit, datetime)\",\n \"UTC truncation: year, month, week (Monday), day, hour, minute, second.\",\n 2,\n 2,\n \"datetime\",\n [\"text\", \"datetime\"],\n ),\n f(\n \"DATE_ADD\",\n \"DATE_ADD(unit, amount, datetime)\",\n \"UTC calendar addition; month/year clamp to the last day.\",\n 3,\n 3,\n \"datetime\",\n [\"text\", \"number\", \"datetime\"],\n ),\n f(\n \"DATE_DIFF\",\n \"DATE_DIFF(unit, start, end)\",\n \"Elapsed whole units: week, day, hour, minute, second, millisecond.\",\n 3,\n 3,\n \"number\",\n [\"text\", \"datetime\", \"datetime\"],\n ),\n f(\n \"FORMAT_DATE\",\n \"FORMAT_DATE(datetime, pattern)\",\n \"UTC tokens: YYYY MM DD HH mm ss; other text is literal.\",\n 2,\n 2,\n \"text\",\n [\"datetime\", \"text\"],\n ),\n];\n\nexport class FormulaError extends Error {\n constructor(\n message: string,\n public from = 0,\n public to = from + 1,\n ) {\n super(message);\n }\n}\ninterface Token {\n text: string;\n kind: \"field\" | \"string\" | \"number\" | \"word\" | \"op\" | \"end\";\n from: number;\n to: number;\n}\nexport function compileFormula(\n source: string,\n fields: readonly { name: string; type: FieldType }[],\n resolve?: (name: string) => FormulaPlan | undefined,\n extension?: (node: FormulaNode, check: (node: FormulaNode) => FormulaType) => FormulaType | undefined,\n): FormulaPlan {\n if (!source.trim() || source.length > 10000)\n throw new FormulaError(\"Formula must contain 1–10,000 characters.\");\n const tokens: Token[] = [];\n let pos = 0;\n while (pos < source.length) {\n if (/\\s/.test(source[pos]!)) {\n pos++;\n continue;\n }\n const from = pos;\n let match: RegExpMatchArray | null;\n if (source[pos] === \"[\") {\n pos++;\n let text = \"\";\n let closed = false;\n while (pos < source.length) {\n if (source[pos] === \"]\") {\n if (source[pos + 1] === \"]\") {\n text += \"]\";\n pos += 2;\n } else {\n pos++;\n closed = true;\n break;\n }\n } else text += source[pos++];\n }\n if (!closed)\n throw new FormulaError(\"Unclosed field reference.\", from, pos);\n tokens.push({ kind: \"field\", text, from, to: pos });\n } else if (source[pos] === '\"') {\n pos++;\n while (pos < source.length && source[pos] !== '\"') {\n if (source[pos] === \"\\\\\") pos++;\n pos++;\n }\n pos++;\n try {\n tokens.push({\n kind: \"string\",\n text: JSON.parse(source.slice(from, pos)),\n from,\n to: pos,\n });\n } catch {\n throw new FormulaError(\"Invalid JSON string literal.\", from, pos);\n }\n } else if (source[pos] === \"'\") {\n // A common habit from SQL and spreadsheets; say what to write instead.\n const end = source.indexOf(\"'\", pos + 1);\n const text = end < 0 ? \"\" : source.slice(pos + 1, end);\n throw new FormulaError(\n end < 0 || text.length > 40 || /[\"\\\\\\n]/.test(text)\n ? 'Text literals use double quotes (\"text\"), not single quotes.'\n : `Text literals use double quotes: write \"${text}\" instead of '${text}'.`,\n from,\n end < 0 ? pos + 1 : end + 1,\n );\n } else if (\n (match = source\n .slice(pos)\n .match(/^(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"number\", text: match[0], from, to: pos });\n } else if ((match = source.slice(pos).match(/^[a-zA-Z_][a-zA-Z_0-9]*/))) {\n pos += match[0].length;\n tokens.push({\n kind: \"word\",\n text: match[0].toUpperCase(),\n from,\n to: pos,\n });\n } else if (\n (match = source.slice(pos).match(/^(>=|<=|!=|<>|[=<>+*/%(),-])/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"op\", text: match[0], from, to: pos });\n } else throw new FormulaError(`Unexpected character ${source[pos]}.`, from);\n if (tokens.length > 2000)\n throw new FormulaError(\"Formula is too complex.\", from);\n }\n tokens.push({ kind: \"end\", text: \"\", from: pos, to: pos });\n let i = 0,\n depth = 0;\n const peek = () => tokens[i]!;\n const take = () => tokens[i++]!;\n const expect = (s: string) => {\n if (peek().text !== s)\n throw new FormulaError(`Expected ${s}.`, peek().from, peek().to);\n return take();\n };\n const call = (\n name: string,\n args: FormulaNode[],\n from: number,\n to: number,\n ): FormulaNode => ({ kind: \"call\", name, args, from, to });\n const priority: Record<string, number> = {\n OR: 1,\n AND: 2,\n \"=\": 3,\n \"!=\": 3,\n \"<>\": 3,\n \"<\": 3,\n \">\": 3,\n \"<=\": 3,\n \">=\": 3,\n IN: 3,\n BETWEEN: 3,\n \"+\": 4,\n \"-\": 4,\n \"*\": 5,\n \"/\": 5,\n \"%\": 5,\n };\n function expression(min = 0): FormulaNode {\n if (++depth > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", peek().from);\n const t = take();\n let node: FormulaNode;\n if (t.kind === \"number\") {\n if (!Number.isFinite(Number(t.text)))\n throw new FormulaError(\"Number must be finite.\", t.from, t.to);\n node = { kind: \"literal\", value: Number(t.text), from: t.from, to: t.to };\n } else if (t.kind === \"string\")\n node = { kind: \"literal\", value: t.text, from: t.from, to: t.to };\n else if (t.kind === \"field\")\n node = { kind: \"field\", name: t.text, from: t.from, to: t.to };\n else if ([\"TRUE\", \"FALSE\", \"NULL\"].includes(t.text))\n node = {\n kind: \"literal\",\n value: t.text === \"NULL\" ? null : t.text === \"TRUE\",\n from: t.from,\n to: t.to,\n };\n else if (t.text === \"(\") {\n node = expression();\n expect(\")\");\n } else if ([\"NOT\", \"-\", \"+\"].includes(t.text)) {\n const arg = expression(t.text === \"NOT\" ? 3 : 6);\n node = call(`unary:${t.text}`, [arg], t.from, arg.to);\n } else if (t.kind === \"word\") {\n expect(\"(\");\n const args: FormulaNode[] = [];\n if (peek().text !== \")\") {\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n }\n node = call(t.text, args, t.from, expect(\")\").to);\n } else\n throw new FormulaError(\n \"Expected a value, field, or function.\",\n t.from,\n t.to,\n );\n while (peek().kind !== \"end\" && (priority[peek().text] ?? -1) >= min) {\n const op = take();\n const p = priority[op.text]!;\n if (op.text === \"IN\") {\n if (peek().text !== \"(\")\n throw new FormulaError(\n 'IN takes a parenthesized list, e.g. [status] IN (\"a\", \"b\"). To test array membership, use ARRAY_CONTAINS([tags], \"a\").',\n op.from,\n peek().to,\n );\n expect(\"(\");\n const args = [node];\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n node = call(\"op:IN\", args, node.from, expect(\")\").to);\n } else if (op.text === \"BETWEEN\") {\n const lo = expression(p + 1);\n expect(\"AND\");\n const hi = expression(p + 1);\n node = call(\"op:BETWEEN\", [node, lo, hi], node.from, hi.to);\n } else {\n const right = expression(p + 1);\n node = call(`op:${op.text}`, [node, right], node.from, right.to);\n }\n }\n if (peek().text === \"NOT\" && tokens[i + 1]?.text === \"IN\")\n throw new FormulaError(\n 'NOT IN is not supported. Write NOT ([status] IN (\"a\", \"b\")), or combine != comparisons with AND.',\n peek().from,\n tokens[i + 1]!.to,\n );\n depth--;\n return node;\n }\n const ast = expression();\n if (peek().kind !== \"end\")\n throw new FormulaError(\"Unexpected token.\", peek().from, peek().to);\n const deps = new Set<string>();\n const byName = new Map(fields.map((v) => [v.name, v.type]));\n const same = (ts: FormulaType[], n: FormulaNode): FormulaType => {\n const real = [...new Set(ts.filter((t) => t !== \"null\"))];\n if (real.length > 1)\n throw new FormulaError(\n \"Values must have compatible types; use an explicit conversion.\",\n n.from,\n n.to,\n );\n return real[0] ?? \"null\";\n };\n function check(n: FormulaNode, level = 0): FormulaType {\n if (level > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", n.from, n.to);\n if (n.kind === \"literal\")\n return n.value === null\n ? \"null\"\n : typeof n.value === \"boolean\"\n ? \"bool\"\n : typeof n.value === \"number\"\n ? \"number\"\n : \"text\";\n if (n.kind === \"field\") {\n const t = byName.get(n.name);\n if (!t) {\n const nested = resolve?.(n.name);\n if (nested) {\n Object.assign(n, nested.ast);\n nested.dependencies.forEach((d) => deps.add(d));\n return nested.type;\n }\n throw new FormulaError(\n `Unknown or unavailable field: ${n.name}`,\n n.from,\n n.to,\n );\n }\n deps.add(n.name);\n n.valueType = t === \"enum\" ? \"text\" : t;\n return n.valueType;\n }\n const extended = extension?.(n, (arg) => check(arg, level + 1));\n if (extended !== undefined) return extended;\n const ts = n.args.map((a) => check(a, level + 1));\n const need = (index: number, t: FormulaType) => {\n if (ts[index] !== undefined && ts[index] !== \"null\" && ts[index] !== t)\n throw new FormulaError(\n `Expected ${t}, received ${ts[index]}.`,\n n.args[index]!.from,\n n.args[index]!.to,\n );\n };\n if (n.name.startsWith(\"op:\") || n.name.startsWith(\"unary:\")) {\n const op = n.name.split(\":\")[1]!;\n if ([\"AND\", \"OR\", \"NOT\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"bool\"));\n return \"bool\";\n }\n if ([\"+\", \"-\", \"*\", \"/\", \"%\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"number\"));\n return \"number\";\n }\n if (op === \"IN\" && ts.some((t) => t === \"textarray\"))\n throw new FormulaError(\n 'IN compares one value with a list of values. For arrays, use ARRAY_CONTAINS([tags], \"a\"), or OR several ARRAY_CONTAINS calls.',\n n.from,\n n.to,\n );\n same(ts, n);\n return \"bool\";\n }\n const spec = FORMULA_FUNCTIONS.find((v) => v.name === n.name);\n if (!spec)\n throw new FormulaError(`Unknown function: ${n.name}`, n.from, n.to);\n if (ts.length < spec.min || ts.length > spec.max)\n throw new FormulaError(`Use ${spec.signature}.`, n.from, n.to);\n if (spec.args !== \"any\") {\n const args = spec.args;\n ts.forEach((_, j) => need(j, args[Math.min(j, args.length - 1)]!));\n }\n if (n.name === \"IF\") {\n need(0, \"bool\");\n return same(ts.slice(1), n);\n }\n if (n.name === \"IFS\") {\n if (ts.length % 2 !== 1)\n throw new FormulaError(\n \"IFS requires condition/value pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n ts.forEach((t, j) => {\n if (j === ts.length - 1 || j % 2 === 1) branches.push(t);\n else need(j, \"bool\");\n });\n return same(branches, n);\n }\n if (n.name === \"SWITCH\") {\n if (ts.length % 2 !== 0)\n throw new FormulaError(\n \"SWITCH requires match/result pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n for (let j = 1; j < ts.length - 1; j += 2) {\n same([ts[0]!, ts[j]!], n);\n branches.push(ts[j + 1]!);\n }\n branches.push(ts[ts.length - 1]!);\n return same(branches, n);\n }\n if (n.name.startsWith(\"REGEX_\")) {\n const pattern = n.args[1];\n const flags = n.args[n.name === \"REGEX_TEST\" ? 2 : 3];\n if (pattern?.kind === \"literal\" && typeof pattern.value === \"string\") {\n if (pattern.value.length > 2000)\n throw new FormulaError(\n \"Regex pattern exceeds 2,000 characters.\",\n pattern.from,\n pattern.to,\n );\n if (\n !flags ||\n (flags.kind === \"literal\" && typeof flags.value === \"string\")\n ) {\n const value = flags?.value ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(String(value)))\n throw new FormulaError(\n \"Regex flags must be unique i, m, or s.\",\n n.from,\n n.to,\n );\n try {\n new RegExp(pattern.value, `${value}u`);\n } catch {\n throw new FormulaError(\n \"Invalid regex pattern.\",\n pattern.from,\n pattern.to,\n );\n }\n }\n }\n }\n if (spec.result === \"branch\") return same(ts, n);\n return spec.result;\n }\n const type = check(ast);\n return { ast, dependencies: [...deps].sort(), type };\n}\n\n/** Self-contained runtime: serialized into the browser worker, never user code. */\nexport function formulaRuntime(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>,\n extension?: (node: Extract<FormulaNode, { kind: \"call\" }>) => FormulaResult | undefined,\n): FormulaResult {\n const fail = (s: string): never => {\n throw new Error(s);\n };\n const num = (v: FormulaValue): number =>\n typeof v === \"number\" && Number.isFinite(v)\n ? v\n : fail(\"Expected a finite number.\");\n const str = (v: FormulaValue): string =>\n typeof v === \"string\" ? v : fail(\"Expected text.\");\n const arr = (v: FormulaValue): string[] =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\")\n ? v\n : fail(\"Expected a text array.\");\n const integer = (v: FormulaValue, min = 0, max = 100000): number => {\n const n = num(v);\n return Number.isInteger(n) && n >= min && n <= max\n ? n\n : fail(`Expected an integer between ${min} and ${max}.`);\n };\n const equal = (a: FormulaValue, b: FormulaValue) =>\n JSON.stringify(a) === JSON.stringify(b);\n const date = (v: FormulaValue): Date => {\n const s = str(v);\n if (\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n s,\n )\n )\n fail(\"Expected an ISO date or timestamp with timezone.\");\n const d = new Date(s);\n const day = Number(s.slice(8, 10)),\n month = Number(s.slice(5, 7));\n if (\n !Number.isFinite(d.getTime()) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > new Date(Date.UTC(Number(s.slice(0, 4)), month, 0)).getUTCDate()\n )\n fail(\"Invalid date.\");\n return d;\n };\n const bound = (v: FormulaValue): FormulaValue => {\n if (\n v !== null &&\n typeof v !== \"number\" &&\n typeof v !== \"string\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v)\n )\n fail(\"Unsupported input value type.\");\n if (Array.isArray(v) && !v.every((x) => typeof x === \"string\"))\n fail(\"Expected a text array.\");\n if (typeof v === \"number\" && !Number.isFinite(v))\n fail(\"Result is not finite.\");\n if (typeof v === \"string\" && v.length > 100000)\n fail(\"Text result exceeds 100,000 characters.\");\n if (\n Array.isArray(v) &&\n (v.length > 10000 || v.reduce((s, x) => s + x.length, 0) > 100000)\n )\n fail(\"Array result is too large.\");\n return v;\n };\n let inspection: RegexInspection | undefined;\n let budget = 5000;\n function run(n: FormulaNode): FormulaValue {\n if (--budget < 0) fail(\"Formula operation limit exceeded.\");\n if (n.kind === \"literal\") return n.value;\n if (n.kind === \"field\") {\n if (!Object.prototype.hasOwnProperty.call(inputs, n.name)) return null;\n const v = bound(inputs[n.name] ?? null);\n if (v === null) return null;\n if (n.valueType === \"number\") return num(v);\n if (n.valueType === \"bool\" && typeof v !== \"boolean\")\n fail(\"Expected a boolean.\");\n if (n.valueType === \"datetime\") return date(v).toISOString();\n if (n.valueType === \"text\") return str(v);\n if (n.valueType === \"textarray\") return arr(v);\n return v;\n }\n const extended = extension?.(n);\n if (extended) {\n if (extended.error) fail(extended.error);\n return bound(extended.value);\n }\n const name = n.name;\n const args = n.args;\n if (name === \"IF\") return run(run(args[0]!) === true ? args[1]! : args[2]!);\n if (name === \"IFS\") {\n for (let j = 0; j < args.length - 1; j += 2)\n if (run(args[j]!) === true) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"SWITCH\") {\n const v = run(args[0]!);\n for (let j = 1; j < args.length - 1; j += 2)\n if (equal(v, run(args[j]!))) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"COALESCE\") {\n for (const arg of args) {\n const v = run(arg);\n if (v !== null) return v;\n }\n return null;\n }\n if (name === \"IFERROR\") {\n try {\n return run(args[0]!);\n } catch {\n return run(args[1]!);\n }\n }\n if (name === \"op:AND\" || name === \"op:OR\") {\n const a = run(args[0]!);\n if (name === \"op:AND\" && a === false) return false;\n if (name === \"op:OR\" && a === true) return true;\n const b = run(args[1]!);\n return name === \"op:AND\"\n ? b === false\n ? false\n : a === null || b === null\n ? null\n : true\n : b === true\n ? true\n : a === null || b === null\n ? null\n : false;\n }\n const vs = args.map(run);\n const a = vs[0] ?? null,\n b = vs[1] ?? null,\n c = vs[2] ?? null;\n if (name === \"IS_NULL\") return a === null;\n if (name === \"IS_EMPTY\")\n return a === null || a === \"\" || (Array.isArray(a) && a.length === 0);\n if (name === \"NULLIF\") return equal(a, b) ? null : a;\n if (name === \"CONCAT_WS\")\n return a === null\n ? null\n : bound(\n vs\n .slice(1)\n .filter((v) => v !== null)\n .map(str)\n .join(str(a)),\n );\n if (name === \"op:IN\") {\n if (a === null) return null;\n if (vs.slice(1).some((v) => v !== null && equal(a, v))) return true;\n return vs.slice(1).includes(null) ? null : false;\n }\n if (vs.some((v) => v === null)) return null;\n let out: FormulaValue;\n switch (name) {\n case \"unary:NOT\":\n out = !a;\n break;\n case \"unary:-\":\n out = -num(a);\n break;\n case \"unary:+\":\n out = num(a);\n break;\n case \"op:+\":\n out = num(a) + num(b);\n break;\n case \"op:-\":\n out = num(a) - num(b);\n break;\n case \"op:*\":\n out = num(a) * num(b);\n break;\n case \"op:/\":\n case \"op:%\":\n if (num(b) === 0) fail(\"Division by zero.\");\n out = name === \"op:/\" ? num(a) / num(b) : num(a) % num(b);\n break;\n case \"op:=\":\n out = equal(a, b);\n break;\n case \"op:!=\":\n case \"op:<>\":\n out = !equal(a, b);\n break;\n case \"op:<\":\n out = a! < b!;\n break;\n case \"op:>\":\n out = a! > b!;\n break;\n case \"op:<=\":\n out = a! <= b!;\n break;\n case \"op:>=\":\n out = a! >= b!;\n break;\n case \"op:BETWEEN\":\n out = a! >= b! && a! <= c!;\n break;\n case \"LEFT\":\n out = Array.from(str(a)).slice(0, integer(b)).join(\"\");\n break;\n case \"RIGHT\": {\n const n = integer(b);\n out = n ? Array.from(str(a)).slice(-n).join(\"\") : \"\";\n break;\n }\n case \"SUBSTRING\": {\n const start = integer(b, 1) - 1;\n out = Array.from(str(a))\n .slice(start, vs.length > 2 ? start + integer(c) : undefined)\n .join(\"\");\n break;\n }\n case \"LENGTH\":\n out = Array.from(str(a)).length;\n break;\n case \"URL_ENCODE\":\n // RFC 3986 unreserved characters only, matching DuckDB's url_encode.\n if (!/^(?:[^\\ud800-\\udfff]|[\\ud800-\\udbff][\\udc00-\\udfff])*$/.test(str(a)))\n fail(\"Text is not valid Unicode.\");\n out = encodeURIComponent(str(a)).replace(\n /[!'()*]/g,\n (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase()}`,\n );\n break;\n case \"LOWER\":\n out = str(a).toLowerCase();\n break;\n case \"UPPER\":\n out = str(a).toUpperCase();\n break;\n case \"TRIM\":\n out = str(a).trim();\n break;\n case \"LTRIM\":\n out = str(a).trimStart();\n break;\n case \"RTRIM\":\n out = str(a).trimEnd();\n break;\n case \"REPLACE\":\n if (b === \"\") fail(\"Search text must not be empty.\");\n const parts = str(a).split(str(b));\n if (parts.length * str(c).length + str(a).length > 200000)\n fail(\"Replacement result is too large.\");\n out = parts.join(str(c));\n break;\n case \"LPAD\":\n case \"RPAD\": {\n const chars = Array.from(str(a)),\n len = integer(b),\n pad = Array.from(vs.length > 2 ? str(c) : \" \");\n if (!pad.length) fail(\"Padding must not be empty.\");\n const fill = Array.from(\n { length: Math.max(0, len - chars.length) },\n (_, i) => pad[i % pad.length]!,\n ).join(\"\");\n out =\n (name === \"LPAD\" ? fill : \"\") +\n chars.slice(0, len).join(\"\") +\n (name === \"RPAD\" ? fill : \"\");\n break;\n }\n case \"SPLIT_PART\":\n out = str(a).split(str(b))[integer(c, 1) - 1] ?? null;\n break;\n case \"CONCAT\":\n out = vs.map(str).join(\"\");\n break;\n case \"CONTAINS\":\n case \"STARTS_WITH\":\n case \"ENDS_WITH\": {\n const s = c === true ? str(a).toLowerCase() : str(a),\n t = c === true ? str(b).toLowerCase() : str(b);\n out =\n name === \"CONTAINS\"\n ? s.includes(t)\n : name === \"STARTS_WITH\"\n ? s.startsWith(t)\n : s.endsWith(t);\n break;\n }\n case \"REGEX_TEST\":\n case \"REGEX_EXTRACT\":\n case \"REGEX_REPLACE\": {\n const flags = vs[name === \"REGEX_TEST\" ? 2 : 3] ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(str(flags)))\n fail(\"Regex flags must be unique i, m, or s.\");\n if (str(b).length > 2000)\n fail(\"Regex pattern exceeds 2,000 characters.\");\n const re = new RegExp(\n str(b),\n `${flags}u${name === \"REGEX_REPLACE\" ? \"g\" : \"\"}`,\n );\n if (name === \"REGEX_TEST\") out = re.test(str(a));\n else if (name === \"REGEX_REPLACE\") {\n let produced = 0;\n out = str(a).replace(re, (...captures: unknown[]) => {\n const replacement = str(c).replace(\n /\\$(\\$|[0-9]{1,2}|&|`|')/g,\n (_token, key: string) => {\n if (key === \"$\") return \"$\";\n if (key === \"&\") return String(captures[0]);\n if (key === \"`\" || key === \"'\")\n return fail(\n \"Regex replacement supports $$, $&, and numbered captures only.\",\n );\n const extra =\n typeof captures[captures.length - 1] === \"object\" ? 3 : 2;\n const i = Number(key);\n return i > 0 && i < captures.length - extra\n ? String(captures[i] ?? \"\")\n : fail(\"Invalid replacement capture.\");\n },\n );\n produced += replacement.length;\n if (produced > 100000) fail(\"Replacement result is too large.\");\n return replacement;\n });\n } else {\n const match = re.exec(str(a));\n const group = vs.length > 2 ? integer(c, 0, 100) : 0;\n out = match?.[group] ?? null;\n if (match)\n inspection = {\n input: str(a),\n start: match.index,\n end: match.index + match[0].length,\n groups: Array.from(match, (v) => v ?? null),\n };\n }\n break;\n }\n case \"ABS\":\n out = Math.abs(num(a));\n break;\n case \"FLOOR\":\n out = Math.floor(num(a));\n break;\n case \"CEIL\":\n out = Math.ceil(num(a));\n break;\n case \"TRUNC\":\n out = Math.trunc(num(a));\n break;\n case \"SQRT\":\n out = Math.sqrt(num(a));\n break;\n case \"ROUND\": {\n const scale = 10 ** (vs.length > 1 ? integer(b, -15, 15) : 0);\n out = Math.round(num(a) * scale) / scale;\n break;\n }\n case \"POWER\":\n out = Math.pow(num(a), num(b));\n break;\n case \"CLAMP\":\n if (num(b) > num(c)) fail(\"Lower bound exceeds upper bound.\");\n out = Math.max(num(b), Math.min(num(c), num(a)));\n break;\n case \"LEAST\":\n out = Math.min(...vs.map(num));\n break;\n case \"GREATEST\":\n out = Math.max(...vs.map(num));\n break;\n case \"TO_TEXT\":\n out = Array.isArray(a) ? JSON.stringify(a) : String(a);\n break;\n case \"TO_NUMBER\":\n if (\n typeof a !== \"number\" &&\n (typeof a !== \"string\" ||\n !/^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/.test(a.trim()))\n )\n fail(\"Cannot convert to number.\");\n out = Number(a);\n break;\n case \"TO_BOOLEAN\":\n if (a === true || a === false) out = a;\n else if (a === \"true\" || a === 1) out = true;\n else if (a === \"false\" || a === 0) out = false;\n else return fail(\"Cannot convert to boolean.\");\n break;\n case \"TO_DATETIME\":\n out = date(a).toISOString();\n break;\n case \"SPLIT\":\n out = str(a).split(str(b));\n break;\n case \"JOIN\":\n out = arr(a).join(str(b));\n break;\n case \"ARRAY_LENGTH\":\n out = arr(a).length;\n break;\n case \"ARRAY_CONTAINS\":\n out = arr(a).includes(str(b));\n break;\n case \"ARRAY_GET\":\n out = arr(a)[integer(b, 1) - 1] ?? null;\n break;\n case \"ARRAY_UNIQUE\":\n out = [...new Set(arr(a))];\n break;\n case \"ARRAY_SORT\":\n out = [...arr(a)].sort((left, right) => {\n const l = Array.from(left),\n r = Array.from(right);\n for (let i = 0; i < Math.min(l.length, r.length); i++) {\n const delta = l[i]!.codePointAt(0)! - r[i]!.codePointAt(0)!;\n if (delta) return delta;\n }\n return l.length - r.length;\n });\n break;\n case \"YEAR\":\n out = date(a).getUTCFullYear();\n break;\n case \"MONTH\":\n out = date(a).getUTCMonth() + 1;\n break;\n case \"DAY\":\n out = date(a).getUTCDate();\n break;\n case \"HOUR\":\n out = date(a).getUTCHours();\n break;\n case \"WEEKDAY\":\n out = ((date(a).getUTCDay() + 6) % 7) + 1;\n break;\n case \"DATE_TRUNC\": {\n const d = date(b),\n unit = str(a).toLowerCase();\n if (\n ![\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n ].includes(unit)\n )\n fail(\"Unsupported date unit.\");\n d.setUTCMilliseconds(0);\n if (unit !== \"second\") d.setUTCSeconds(0);\n if (![\"second\", \"minute\"].includes(unit)) d.setUTCMinutes(0);\n if ([\"year\", \"month\", \"week\", \"day\"].includes(unit)) d.setUTCHours(0);\n if (unit === \"week\")\n d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7));\n if (unit === \"year\" || unit === \"month\") d.setUTCDate(1);\n if (unit === \"year\") d.setUTCMonth(0);\n out = d.toISOString();\n break;\n }\n case \"DATE_ADD\": {\n const d = date(c),\n unit = str(a).toLowerCase(),\n amount = integer(b, -100000, 100000);\n if (unit === \"year\" || unit === \"month\") {\n const day = d.getUTCDate();\n d.setUTCDate(1);\n d.setUTCMonth(d.getUTCMonth() + amount * (unit === \"year\" ? 12 : 1));\n const last = new Date(d.getTime());\n last.setUTCMonth(last.getUTCMonth() + 1, 0);\n d.setUTCDate(Math.min(day, last.getUTCDate()));\n } else {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[unit];\n if (!ms) fail(\"Unsupported date unit.\");\n d.setTime(d.getTime() + amount * ms!);\n }\n out = d.toISOString();\n break;\n }\n case \"DATE_DIFF\": {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[str(a).toLowerCase()];\n if (!ms) fail(\"Unsupported elapsed date unit.\");\n out = Math.trunc((date(c).getTime() - date(b).getTime()) / ms!);\n break;\n }\n case \"FORMAT_DATE\": {\n const d = date(a),\n pad = (n: number) => String(n).padStart(2, \"0\"),\n parts: Record<string, string> = {\n YYYY: String(d.getUTCFullYear()).padStart(4, \"0\"),\n MM: pad(d.getUTCMonth() + 1),\n DD: pad(d.getUTCDate()),\n HH: pad(d.getUTCHours()),\n mm: pad(d.getUTCMinutes()),\n ss: pad(d.getUTCSeconds()),\n };\n out = str(b).replace(/YYYY|MM|DD|HH|mm|ss/g, (t) => parts[t]!);\n break;\n }\n default:\n return fail(`Unknown operation: ${name}`);\n }\n return bound(out);\n }\n try {\n const value = run(ast);\n return inspection ? { value, regex: inspection } : { value };\n } catch (e) {\n return {\n value: null,\n error: e instanceof Error ? e.message : \"Formula evaluation failed.\",\n };\n }\n}\n","import type { FormulaResult } from \"./formula\";\n\n/** Display arithmetic uses doubles, but an integer outside the safe range is\n * never accepted as an exact metric sample or result. This is not decimal math. */\nexport function assertMetricNumber(value: number): void {\n if (\n !Number.isFinite(value) ||\n (Number.isInteger(value) && !Number.isSafeInteger(value))\n ) {\n throw Error(\"Aggregate exceeds finite safe numeric precision.\");\n }\n}\n\nexport function checkedMetricResult(result: FormulaResult): FormulaResult {\n if (result.error || typeof result.value !== \"number\") return result;\n try {\n assertMetricNumber(result.value);\n return result;\n } catch (e) {\n return { value: null, error: (e as Error).message };\n }\n}\n","import { assertMetricNumber } from \"./metricPrecision\";\n// Exact bounded reductions over the complete scoped population.\nexport function percentile(sorted: number[], p: number): number | null {\n if (!Number.isFinite(p) || p < 0 || p > 1)\n throw Error(\"Percentile must be between zero and one.\");\n if (\n sorted.some((v, i) => !Number.isFinite(v) || (i > 0 && v < sorted[i - 1]!))\n )\n throw Error(\"Percentile inputs must be sorted finite numbers.\");\n sorted.forEach(assertMetricNumber);\n if (!sorted.length) return null;\n const position = (sorted.length - 1) * p,\n lower = Math.floor(position),\n fraction = position - lower;\n const a = sorted[lower]!,\n b = sorted[Math.min(lower + 1, sorted.length - 1)]!;\n // Floating underflow/roundoff cannot move an interpolated percentile outside its two samples.\n const raw = (1 - fraction) * a + fraction * b;\n assertMetricNumber(raw);\n const value = Math.min(b, Math.max(a, raw));\n return value;\n}\nexport function boxSummary(\n values: number[],\n whiskers: \"minmax\" | \"tukey\" = \"minmax\",\n) {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Distribution inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n const sorted = [...values].sort((a, b) => a - b),\n n = sorted.length;\n if (!n) return null;\n const min = sorted[0]!,\n max = sorted[n - 1]!,\n q1 = percentile(sorted, 0.25)!,\n median = percentile(sorted, 0.5)!,\n q3 = percentile(sorted, 0.75)!;\n const lowFence = q1 - 1.5 * (q3 - q1),\n highFence = q3 + 1.5 * (q3 - q1);\n const low = whiskers === \"tukey\" ? sorted.find((v) => v >= lowFence)! : min;\n const high =\n whiskers === \"tukey\"\n ? [...sorted].reverse().find((v) => v <= highFence)!\n : max;\n const outside =\n whiskers === \"tukey\" ? sorted.filter((v) => v < low || v > high) : [];\n // Bound the response while retaining both tails. Report the total separately.\n const outliers =\n outside.length <= 20\n ? outside\n : [...outside.slice(0, 10), ...outside.slice(-10)];\n const rawMean = sorted.reduce((sum, value) => sum + value / n, 0);\n // Check the numeric boundary before correcting insignificant range drift.\n assertMetricNumber(rawMean);\n const mean = Math.min(max, Math.max(min, rawMean));\n [min, q1, median, q3, max, mean, low, high].forEach(assertMetricNumber);\n return {\n n,\n min,\n q1,\n median,\n q3,\n max,\n mean,\n low,\n high,\n outliers,\n outlierCount: outside.length,\n whiskers,\n method: \"exact-linear\" as const,\n };\n}\nexport function histogramEdges(values: number[], bins: number): number[] {\n if (!Number.isInteger(bins) || bins < 2 || bins > 30)\n throw Error(\"Choose 2–30 histogram bins.\");\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n if (!values.length) return [];\n let min = Infinity,\n max = -Infinity;\n for (const value of values) {\n min = Math.min(min, value);\n max = Math.max(max, value);\n }\n if (min === max) return [min, max]; // one point interval, not artificial spread\n if (!Number.isFinite(max - min))\n throw Error(\"Histogram range exceeds finite numeric precision.\");\n const edges = Array.from(\n { length: bins + 1 },\n (_, i) => min + (max - min) * (i / bins),\n );\n edges[0] = min;\n edges[bins] = max;\n edges.forEach(assertMetricNumber);\n if (edges.some((value, i) => i > 0 && value <= edges[i - 1]!))\n throw Error(\n \"Histogram bins are finer than numeric precision. Reduce the bin count.\",\n );\n return edges;\n}\nexport function histogramCounts(values: number[], edges: number[]): number[] {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n if (!edges.length) {\n if (values.length) throw Error(\"Histogram values require edges.\");\n return [];\n }\n if (\n edges.length < 2 ||\n edges.some(\n (v, i) =>\n !Number.isFinite(v) ||\n (i > 0 &&\n (v < edges[i - 1]! || (v === edges[i - 1]! && edges.length !== 2))),\n )\n )\n throw Error(\"Histogram edges must be ordered finite boundaries.\");\n values.forEach(assertMetricNumber);\n edges.forEach(assertMetricNumber);\n const counts = Array<number>(edges.length - 1).fill(0);\n for (const value of values) {\n if (value < edges[0]! || value > edges[edges.length - 1]!)\n throw Error(\"Value falls outside shared histogram edges.\");\n // Lower inclusive, upper exclusive; the last bin also includes the maximum.\n let bin = 0;\n while (bin < counts.length - 1 && value >= edges[bin + 1]!) bin++;\n counts[bin] = counts[bin]! + 1;\n }\n return counts;\n}\n","// metricSeries.ts — trailing windows, running values, shares and whole\n// intervals, computed from ordinary metrics so every engine supports them.\n//\n// A window's value is the metric evaluated over every row in the window. Its\n// aggregates are rebuilt from per-interval parts: SUM, COUNT, MIN and MAX merge\n// across intervals and AVG is SUM / COUNT, so SUM([a]) / SUM([b]) pools its\n// parts instead of averaging interval ratios. COUNT_DISTINCT and MEDIAN do not\n// merge and are refused rather than approximated. A share divides by the same\n// measure grouped by fewer keys, so groups beyond `groupLimit` still count.\n// Occurrences of a cyclic slot are the slot's whole hours or days: the metric\n// runs once per occurrence on a calendar interval, then folds into slots.\n\nimport { FormulaError, type FormulaPlan, type FormulaResult } from \"./formula\";\nimport type { AggregationBucket, AggregationResultEntry } from \"./encode\";\nimport {\n compareMetricValues,\n compileMetric,\n evaluateMetricReductions,\n metricExpression,\n occurrenceDistribution,\n metricMinCount,\n metricMinCountKeeps,\n metricMinCountMeasure,\n sortMetricBuckets,\n validateMetric,\n type MetricPlan,\n} from \"./metrics\";\nimport {\n isMetricCycle,\n metricCustomEndTime,\n metricCycleSlot,\n metricCycleSlots,\n metricDateFloor,\n metricDateNext,\n metricDateTime,\n} from \"./metricDates\";\nimport { boxSummary } from \"./metricDistributions\";\nimport { assertMetricNumber } from \"./metricPrecision\";\nimport type { MetricDateGrouping, MetricValue } from \"./metricTypes\";\nimport { coerceValue } from \"./ops\";\nimport {\n isWhereGroup,\n MAX_AGGREGATIONS,\n type AggregationClause,\n type QueryState,\n type WhereTerm,\n} from \"./query\";\nimport { resolveFieldName, type FieldSchema } from \"./schema\";\n\nexport const MAX_METRIC_WINDOW_PERIODS = 1000;\nconst MERGEABLE = [\"SUM\", \"COUNT\", \"MIN\", \"MAX\", \"AVG\"];\ntype Merge = \"SUM\" | \"COUNT\" | \"MIN\" | \"MAX\";\n\n/** Whether a clause needs planMetricSeries before an engine can run it. */\nexport function hasMetricSeries(c: AggregationClause): boolean {\n return (\n c.window !== undefined ||\n c.share !== undefined ||\n c.dateGrouping?.partialIntervals !== undefined ||\n c.dateGrouping?.occurrence !== undefined\n );\n}\n\n// An aggregate cannot nest, so a root aggregate call is the whole metric.\nconst soleAggregate = (plan: MetricPlan): string | undefined =>\n plan.ast.kind === \"call\" && plan.aggregates.includes(plan.ast)\n ? plan.ast.name\n : undefined;\n\n// Engine queries one window or share needs: the expressions each grouping\n// reduces, before identical texts are merged.\nconst partBudget = (c: AggregationClause, plan: MetricPlan) =>\n (c.window && (c.window.reduce ?? \"total\") === \"total\"\n ? plan.aggregates.reduce((n, node) => n + (node.name === \"AVG\" ? 2 : 1), 0)\n : 1) * (c.share ? 2 : 1);\n\n/** Throws when a clause's window or share cannot be computed exactly. */\nexport function validateMetricSeries(\n c: AggregationClause,\n plan: FormulaPlan,\n): void {\n const { window, share } = c;\n if (!window && share === undefined) return;\n if (!(\"aggregates\" in plan) || c.display?.kind === \"scatter\")\n throw new FormulaError(\n \"Windows and shares apply to single-value metrics, not distributions or scatters.\",\n );\n const metric = plan as MetricPlan,\n sole = soleAggregate(metric);\n if (window) {\n if (!c.dateGrouping || isMetricCycle(c.dateGrouping.interval))\n throw new FormulaError(\n \"A window needs a calendar interval on the first grouping field.\",\n );\n if (!c.dateGrouping.includeEmpty)\n throw new FormulaError(\n \"A window spans every interval, including empty ones: include empty dates.\",\n );\n const { periods, reduce = \"total\", partial = \"omit\" } = window;\n if (\n periods !== \"all\" &&\n !(\n Number.isInteger(periods) &&\n periods >= 2 &&\n periods <= MAX_METRIC_WINDOW_PERIODS\n )\n )\n throw new FormulaError(\n \"A window covers 2–1,000 intervals, or all of them.\",\n );\n if (\n ![\"total\", \"mean\"].includes(reduce) ||\n ![\"omit\", \"include\"].includes(partial)\n )\n throw new FormulaError(\"Invalid metric window.\");\n if (reduce === \"mean\") {\n if (!sole || ![\"SUM\", \"COUNT\", \"COUNT_DISTINCT\"].includes(sole))\n throw new FormulaError(\n \"A mean per interval needs a single SUM, COUNT or COUNT_DISTINCT; it would weight each interval's ratio or average equally. A window total pools them instead.\",\n );\n } else\n for (const node of metric.aggregates)\n if (!MERGEABLE.includes(node.name))\n throw new FormulaError(\n node.name === \"COUNT_DISTINCT\"\n ? \"A window total cannot combine COUNT_DISTINCT across intervals, because one value can occur in several. Use a mean per interval.\"\n : `A window total cannot combine ${node.name} across intervals.`,\n node.from,\n node.to,\n );\n }\n if (share !== undefined) {\n if (share !== \"total\" && share !== \"group0\")\n throw new FormulaError(\"Invalid metric share.\");\n if (sole !== \"SUM\" && sole !== \"COUNT\")\n throw new FormulaError(\n \"A share divides additive totals: use a single SUM or COUNT. Distinct counts, averages and ratios do not add up across groups.\",\n );\n if (share === \"group0\" ? c.groupBy.length < 2 : !c.groupBy.length)\n throw new FormulaError(\n share === \"group0\"\n ? \"A share within the first grouping needs a second grouping field.\"\n : \"A share of the total needs a grouping field.\",\n );\n if (share === \"total\" && window)\n throw new FormulaError(\n \"A windowed share divides by each interval's own total: share within the first grouping.\",\n );\n }\n if (partBudget(c, metric) > MAX_AGGREGATIONS)\n throw new FormulaError(\n `A window or share runs one metric per aggregate; this one needs more than ${MAX_AGGREGATIONS}.`,\n );\n}\n\n/** The conjunctive bounds on a date-grouped clause's field, from the query's\n * and the metric's own filters: [lower, upper), infinite where absent. */\nexport function metricDateBounds(\n c: AggregationClause,\n query: QueryState,\n schema: FieldSchema,\n now: number,\n): { lower: number; upper: number } {\n const { field } = c.dateGrouping!;\n const canonical = (name: string) => resolveFieldName(schema, name) ?? name;\n let lower = -Infinity,\n upper = Infinity;\n for (const term of [...query.where, ...(c.where ?? [])]) {\n if (\n isWhereGroup(term) ||\n term.negated ||\n canonical(term.field) !== canonical(field) ||\n ![\"=\", \">\", \">=\", \"<\", \"<=\"].includes(term.op)\n )\n continue;\n // An empty value is no filter yet, and a malformed one fails where the\n // filter runs; neither bounds the intervals.\n if (term.value === \"\") continue;\n let time: number;\n try {\n time = Number(coerceValue(\"datetime\", term.value, now));\n } catch {\n continue;\n }\n if (!Number.isFinite(time)) continue;\n if (term.op === \">\" || term.op === \">=\" || term.op === \"=\")\n lower = Math.max(lower, time + (term.op === \">\" ? 1 : 0));\n if (term.op === \"<\" || term.op === \"<=\" || term.op === \"=\")\n upper = Math.min(upper, time + (term.op === \"<\" ? 0 : 1));\n }\n return { lower, upper };\n}\n\n/** The whole intervals inside the conjunctive bounds on the date field (the\n * query's and the metric's own), ending by `now`: [start, end). A cyclic\n * interval's intervals are its hours or days. */\nexport function wholeIntervalSpan(\n c: AggregationClause,\n query: QueryState,\n schema: FieldSchema,\n now: number,\n): { start?: number; end: number } {\n const { interval, timeZone } = c.dateGrouping!;\n const { lower, upper } = metricDateBounds(c, query, schema, now);\n const floor = (time: number) => metricDateFloor(time, interval, timeZone);\n const end = floor(Math.min(upper, now));\n if (!Number.isFinite(lower)) return { end };\n const first = floor(lower);\n return {\n start: first === lower ? lower : metricDateNext(first, interval, timeZone),\n end,\n };\n}\n\nexport interface MetricSeriesOptions {\n /** The evaluation clock: intervals ending after it are partial. */\n now?: number;\n resolveComputed?: (name: string) => FormulaPlan | undefined;\n}\nexport interface MetricSeriesPlan {\n /** Plain metric queries within the metric budget. A clause's parts always\n * share one query, so they read one population. */\n queries: QueryState[];\n /** The requested clauses' results, in request order, from the metric\n * results of every query. */\n combine(results: readonly AggregationResultEntry[]): AggregationResultEntry[];\n}\n\ntype Reduction =\n | { name: Merge; part: number }\n | { name: \"AVG\"; sum: number; count: number };\ntype Prepared =\n | { kind: \"error\"; clause: AggregationClause; error: string }\n | { kind: \"empty\"; clause: AggregationClause }\n | { kind: \"plain\"; clause: AggregationClause; parts: [AggregationClause] }\n | {\n kind: \"occurrence\";\n clause: AggregationClause;\n parts: [AggregationClause];\n }\n | {\n kind: \"series\";\n clause: AggregationClause;\n plan: MetricPlan;\n parts: AggregationClause[];\n /** Window totals rebuild each aggregate from parts, by position. */\n reductions?: Reduction[];\n size: number;\n /** The part measuring an object minCount: SUM or COUNT_DISTINCT per group. */\n minPart?: number;\n };\n\n/** Expand clauses with a window, a share or whole intervals into plain\n * metrics, or return undefined when no clause has them.\n *\n * - **Window.** Each point is the metric over the rows of its trailing\n * intervals (`reduce: \"total\"`), or the mean of their per-interval values\n * (`reduce: \"mean\"`), with the window's row count. Points whose window starts\n * before the first interval have no value unless `partial: \"include\"`.\n * - **Share.** Each bucket divided by the total of its first grouping key, or\n * of every group. With a window, both are windowed first.\n * - **Whole intervals.** `partialIntervals: \"exclude\"` narrows the metric to\n * the intervals the query bounds and `now` leave whole.\n * - **Occurrences.** A cyclic slot with `dateGrouping.occurrence` runs the\n * metric per whole occurrence (one calendar hour or day), then summarises\n * each slot: the mean of its occurrence values, or a box over them.\n *\n * `sort`, `groupLimit` and `minCount` (counting a window's rows, or summing a\n * field over the window) apply to the combined buckets. Windowed and share\n * results have no Other remainder. */\nexport function planMetricSeries(\n query: QueryState,\n schema: FieldSchema,\n options: MetricSeriesOptions = {},\n): MetricSeriesPlan | undefined {\n const clauses = query.aggregations ?? [];\n if (!clauses.some(hasMetricSeries)) return undefined;\n const now = options.now ?? Date.now();\n const taken = new Set(clauses.map((c) => c.id));\n let next = 0;\n const id = () => {\n let value: string;\n do value = `qt-series-${next++}`;\n while (taken.has(value));\n return value;\n };\n const prepared = clauses.map((c): Prepared => {\n if (!hasMetricSeries(c)) return { kind: \"plain\", clause: c, parts: [c] };\n // A clause that cannot be planned fails alone, never the whole batch.\n try {\n return prepare(c);\n } catch (e) {\n return {\n kind: \"error\",\n clause: c,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n });\n function prepare(c: AggregationClause): Prepared {\n const issue = validateMetric(c, schema, options.resolveComputed)[0];\n if (issue) return { kind: \"error\", clause: c, error: issue.message };\n // Narrow to the intervals the query's bounds and the clock leave whole;\n // undefined when none remain.\n function whole(\n config: MetricDateGrouping,\n ): { where: WhereTerm[]; dateGrouping: MetricDateGrouping } | undefined {\n let where = c.where ?? [],\n dateGrouping = config;\n const span = wholeIntervalSpan(\n { ...c, dateGrouping: config },\n query,\n schema,\n now,\n );\n if (span.start !== undefined && span.end <= span.start) {\n if (!isMetricCycle(config.interval)) return undefined;\n // Nothing is whole, but the engine still lists every slot.\n span.end = span.start;\n }\n const field = resolveFieldName(schema, config.field) ?? config.field;\n const iso = (time: number) => new Date(time).toISOString();\n where = [\n ...where,\n ...(span.start !== undefined\n ? [{ field, op: \">=\", value: iso(span.start) } as WhereTerm]\n : []),\n { field, op: \"<\", value: iso(span.end) },\n ];\n // Completion would otherwise refill the partial intervals as empty.\n // Every slot of a cycle exists anyway.\n if (\n config.includeEmpty &&\n config.range !== \"observed\" &&\n !isMetricCycle(config.interval)\n ) {\n const floor = (time: number) =>\n metricDateFloor(time, config.interval, config.timeZone);\n let from = span.start,\n through = span.end - 1;\n if (config.range === \"custom\") {\n const start = floor(\n metricDateTime(config.start ?? \"\", config.timeZone),\n );\n from = Math.max(from ?? start, start);\n through = Math.min(\n through,\n metricCustomEndTime(config.end ?? \"\", config.timeZone),\n );\n }\n if (from !== undefined) {\n if (through < from) return undefined;\n dateGrouping = {\n ...config,\n range: \"custom\",\n start: iso(from),\n end: iso(through),\n };\n }\n }\n return { where, dateGrouping };\n }\n let where = c.where ?? [];\n let dateGrouping: MetricDateGrouping | undefined;\n if (c.dateGrouping) {\n const { partialIntervals, occurrence, ...config } = c.dateGrouping;\n // An occurrence is one whole calendar hour or day of the slot.\n const narrowed = occurrence\n ? whole({\n ...config,\n interval: occurrence.interval,\n includeEmpty: occurrence.includeEmpty,\n })\n : partialIntervals === \"exclude\"\n ? whole(config)\n : { where, dateGrouping: config };\n if (!narrowed) return { kind: \"empty\", clause: c };\n ({ where, dateGrouping } = narrowed);\n if (occurrence) {\n const {\n dateGrouping: _date,\n where: _where,\n scope: _scope,\n distribution: _distribution,\n display: _display,\n sort: _sort,\n groupLimit: _limit,\n minCount: _min,\n label: _label,\n layout: _layout,\n ...rest\n } = c;\n return {\n kind: \"occurrence\",\n clause: c,\n parts: [\n {\n ...rest,\n id: id(),\n ...(c.scope ? { scope: c.scope } : {}),\n ...(where.length ? { where } : {}),\n dateGrouping,\n },\n ],\n };\n }\n }\n const scoped = (groupBy: string[]): Partial<AggregationClause> => ({\n ...(c.scope ? { scope: c.scope } : {}),\n ...(where.length ? { where } : {}),\n ...(dateGrouping && groupBy.length ? { dateGrouping } : {}),\n });\n if (!c.window && c.share === undefined) {\n const {\n dateGrouping: _date,\n where: _where,\n scope: _scope,\n ...rest\n } = c;\n return {\n kind: \"plain\",\n clause: c,\n parts: [{ ...rest, id: id(), ...scoped(c.groupBy) }],\n };\n }\n const source = metricExpression(\n c.expression === undefined && c.field\n ? { ...c, field: resolveFieldName(schema, c.field) ?? c.field }\n : c,\n );\n const plan = compileMetric(source, schema, options.resolveComputed);\n const texts: string[] = [];\n const at = (text: string) => {\n const index = texts.indexOf(text);\n return index < 0 ? texts.push(text) - 1 : index;\n };\n let reductions: Reduction[] | undefined;\n if (c.window && (c.window.reduce ?? \"total\") === \"total\")\n reductions = plan.aggregates.map((node): Reduction => {\n const text = source.slice(node.from, node.to);\n if (node.name !== \"AVG\") return { name: node.name as Merge, part: at(text) };\n const input = text.slice(text.indexOf(\"(\") + 1, text.lastIndexOf(\")\"));\n return { name: \"AVG\", sum: at(`SUM(${input})`), count: at(`COUNT(${input})`) };\n });\n else at(source);\n const parts = (groupBy: string[]) =>\n texts.map(\n (text): AggregationClause => ({\n id: id(),\n // The whole legacy measure keeps its operation, so v1 servers run it.\n ...(text === source && c.expression === undefined\n ? { op: c.op, ...(c.field ? { field: c.field } : {}) }\n : { op: \"count\" as const, expression: text }),\n groupBy,\n ...scoped(groupBy),\n }),\n );\n const all = [\n ...parts(c.groupBy),\n ...(c.share === \"group0\"\n ? parts(c.groupBy.slice(0, 1))\n : c.share === \"total\"\n ? parts([])\n : []),\n ];\n // An object minCount is one more grouped part; a window sums it.\n const measure = metricMinCountMeasure(c);\n const minPart = measure ? all.length : undefined;\n if (measure)\n all.push({\n id: id(),\n op: \"count\",\n expression: metricExpression({\n id: \"\",\n groupBy: [],\n op: measure.op,\n field: resolveFieldName(schema, measure.field) ?? measure.field,\n }),\n groupBy: c.groupBy,\n ...scoped(c.groupBy),\n });\n return {\n kind: \"series\",\n clause: c,\n plan,\n parts: all,\n ...(reductions ? { reductions } : {}),\n size: texts.length,\n ...(minPart !== undefined ? { minPart } : {}),\n };\n }\n const queries: QueryState[] = [];\n let batch: AggregationClause[] = [];\n for (const item of prepared) {\n if (item.kind === \"error\" || item.kind === \"empty\") continue;\n if (batch.length + item.parts.length > MAX_AGGREGATIONS) {\n queries.push({ ...query, aggregations: batch });\n batch = [];\n }\n batch.push(...item.parts);\n }\n if (batch.length) queries.push({ ...query, aggregations: batch });\n return {\n queries,\n combine(results) {\n const byId = new Map(results.map((r) => [r.id, r]));\n return prepared.map((item): AggregationResultEntry => {\n const c = item.clause;\n if (item.kind === \"error\")\n return { id: c.id, buckets: [], error: item.error };\n if (item.kind === \"empty\") {\n const none: AggregationResultEntry = {\n id: c.id,\n buckets: [],\n scope: c.scope ?? \"allMatching\",\n groupCount: 0,\n coverage: \"exact\",\n };\n // No whole occurrence: every slot is still listed, without a value.\n return c.dateGrouping?.occurrence ? combineOccurrences(c, none) : none;\n }\n const entries = item.parts.map(\n (part) =>\n byId.get(part.id) ?? {\n id: part.id,\n buckets: [],\n error: \"Server omitted this metric.\",\n },\n );\n if (item.kind === \"plain\") return { ...entries[0]!, id: c.id };\n try {\n if (item.kind === \"occurrence\")\n return combineOccurrences(c, entries[0]!);\n return combineSeries(item, entries);\n } catch (e) {\n return {\n id: c.id,\n buckets: [],\n error: e instanceof Error ? e.message : String(e),\n };\n }\n });\n },\n };\n}\n\n// One part's buckets, per series tuple, by interval position.\ntype Track = (AggregationBucket | undefined)[];\n\nclass Accumulator {\n private total = 0;\n private seen = false;\n private best: MetricValue = null;\n error: string | undefined;\n constructor(private readonly name: Merge) {}\n add(bucket: AggregationBucket | undefined): void {\n if (!bucket || this.error) return;\n if (bucket.error) {\n this.error = bucket.error;\n return;\n }\n const value = bucket.value;\n if (value === null) return;\n if (this.name === \"SUM\" || this.name === \"COUNT\") {\n if (typeof value !== \"number\") {\n this.error = `${this.name} returned a non-numeric value.`;\n return;\n }\n this.total += value;\n this.seen = true;\n } else if (\n this.best === null ||\n compareMetricValues(value, this.best) * (this.name === \"MIN\" ? 1 : -1) < 0\n )\n this.best = value;\n }\n result(): FormulaResult {\n if (this.error) return { value: null, error: this.error };\n if (this.name === \"MIN\" || this.name === \"MAX\") return { value: this.best };\n return { value: this.name === \"COUNT\" || this.seen ? this.total : null };\n }\n}\n\nfunction combineSeries(\n item: Extract<Prepared, { kind: \"series\" }>,\n entries: AggregationResultEntry[],\n): AggregationResultEntry {\n const c = item.clause,\n window = c.window;\n for (const entry of entries) {\n if (entry.error) throw Error(entry.error);\n if (\n entry.coverage === \"partial\" ||\n (entry.groupCount ?? entry.buckets.length) > entry.buckets.length\n )\n throw Error(\n \"A window or share needs every group, but the engine returned only some of them.\",\n );\n }\n const numerator = entries.slice(0, item.size),\n denominator = c.share ? entries.slice(item.size, item.minPart) : [],\n threshold =\n item.minPart !== undefined ? entries[item.minPart] : undefined;\n // Calendar positions: includeEmpty supplies every interval of the range.\n // Rows without a date have a null first key and no calendar position.\n const dateOf = (keys: MetricValue[]) =>\n keys[0] === null || keys[0] === undefined ? undefined : keys[0];\n const times = new Map<MetricValue, number>();\n if (window)\n for (const entry of entries)\n for (const bucket of entry.buckets) {\n const date = dateOf(bucket.keys);\n if (date !== undefined && !times.has(date))\n times.set(date, metricDateTime(date));\n }\n const order = [...times.entries()].sort((a, b) => a[1] - b[1]);\n const position = new Map(order.map(([date], index) => [date, index]));\n const positionOf = (keys: MetricValue[]) => {\n const date = dateOf(keys);\n return date === undefined ? undefined : position.get(date);\n };\n const tracks = (part: AggregationResultEntry) => {\n const byTail = new Map<string, Track>();\n for (const bucket of part.buckets) {\n const at = positionOf(bucket.keys);\n if (at === undefined) continue;\n const tail = JSON.stringify(bucket.keys.slice(1));\n const track =\n byTail.get(tail) ?? Array<AggregationBucket | undefined>(order.length);\n track[at] = bucket;\n byTail.set(tail, track);\n }\n return byTail;\n };\n const exact = (part: AggregationResultEntry) =>\n new Map(\n part.buckets.map((bucket) => [JSON.stringify(bucket.keys), bucket]),\n );\n const numeratorTracks = numerator.map(tracks),\n denominatorTracks = denominator.map(tracks);\n const numeratorBuckets = numerator.map(exact),\n denominatorBuckets = denominator.map(exact);\n\n type Point = {\n value: MetricValue;\n count: number;\n error?: string;\n intervals?: number;\n };\n const checked = (result: FormulaResult, count: number): Point => {\n if (!result.error && typeof result.value === \"number\")\n try {\n assertMetricNumber(result.value);\n } catch (e) {\n result = { value: null, error: (e as Error).message };\n }\n return result.error\n ? { value: null, count, error: result.error }\n : { value: result.value as MetricValue, count };\n };\n // The metric over some buckets of each part: one window, or one bucket.\n const evaluate = (\n members: (AggregationBucket | undefined)[][],\n mean: boolean,\n ): Point => {\n const own = members[0]!,\n count = own.reduce((n, bucket) => n + (bucket?.count ?? 0), 0);\n if (item.reductions) {\n const reduce = (name: Merge, part: number) => {\n const accumulator = new Accumulator(name);\n for (const bucket of members[part]!) accumulator.add(bucket);\n return accumulator.result();\n };\n const reductions = item.reductions.map((r): FormulaResult => {\n if (r.name !== \"AVG\") return reduce(r.name, r.part);\n const sum = reduce(\"SUM\", r.sum),\n rows = reduce(\"COUNT\", r.count);\n if (sum.error || rows.error)\n return { value: null, error: (sum.error ?? rows.error)! };\n return {\n value:\n sum.value === null || !rows.value\n ? null\n : Number(sum.value) / Number(rows.value),\n };\n });\n return checked(evaluateMetricReductions(item.plan, reductions), count);\n }\n if (!mean)\n return own[0]?.error\n ? { value: null, count, error: own[0].error }\n : checked({ value: own[0]?.value ?? null }, count);\n // SUM, COUNT and COUNT_DISTINCT of an empty interval are 0.\n let total = 0;\n for (const bucket of own) {\n if (bucket?.error) return { value: null, count, error: bucket.error };\n if (bucket?.value === null || bucket?.value === undefined) continue;\n if (typeof bucket.value !== \"number\")\n return { value: null, count, error: \"Expected a numeric metric value.\" };\n total += bucket.value;\n }\n return checked({ value: total / own.length }, count);\n };\n const periods = window?.periods === \"all\" ? Infinity : (window?.periods ?? 1);\n const point = (\n keys: MetricValue[],\n tracksOf: Map<string, Track>[],\n bucketsOf: Map<string, AggregationBucket>[],\n ): Point => {\n const at = positionOf(keys);\n // Without a window, or for rows without a date, a bucket is its own point.\n if (!window || at === undefined)\n return evaluate(\n bucketsOf.map((parts) => [parts.get(JSON.stringify(keys))]),\n false,\n );\n const from = Math.max(0, at - periods + 1),\n intervals = at - from + 1,\n tail = JSON.stringify(keys.slice(1));\n const members = tracksOf.map((byTail) => {\n const track = byTail.get(tail);\n return Array.from({ length: intervals }, (_, i) => track?.[from + i]);\n });\n const result = evaluate(members, window.reduce === \"mean\");\n return intervals < periods &&\n periods !== Infinity &&\n (window.partial ?? \"omit\") === \"omit\"\n ? { value: null, count: result.count, intervals }\n : { ...result, intervals };\n };\n const keyed = new Map<string, MetricValue[]>();\n for (const entry of numerator)\n for (const bucket of entry.buckets)\n keyed.set(JSON.stringify(bucket.keys), bucket.keys);\n let buckets = [...keyed.values()].map((keys): AggregationBucket => {\n const own = point(keys, numeratorTracks, numeratorBuckets);\n let { value } = own,\n error = own.error;\n if (c.share && !error) {\n const total = c.share === \"group0\" ? keys.slice(0, 1) : [];\n const whole = point(total, denominatorTracks, denominatorBuckets);\n error = whole.error;\n value =\n error ||\n typeof value !== \"number\" ||\n typeof whole.value !== \"number\" ||\n whole.value === 0\n ? null\n : value / whole.value;\n }\n return {\n keys,\n value: error ? null : value,\n count: own.count,\n ...(error ? { error } : {}),\n ...(own.intervals !== undefined ? { intervals: own.intervals } : {}),\n };\n });\n // A minimum's measure over the same rows as the point: its bucket, or the\n // sum over the window (distinct minimums are refused with windows).\n const thresholdTracks = threshold ? tracks(threshold) : undefined,\n thresholdBuckets = threshold ? exact(threshold) : undefined;\n const measureOf = (keys: MetricValue[]): FormulaResult => {\n const at = positionOf(keys);\n let members: (AggregationBucket | undefined)[];\n if (!window || at === undefined)\n members = [thresholdBuckets!.get(JSON.stringify(keys))];\n else {\n const from = Math.max(0, at - periods + 1),\n track = thresholdTracks!.get(JSON.stringify(keys.slice(1)));\n members = Array.from(\n { length: at - from + 1 },\n (_, i) => track?.[from + i],\n );\n }\n const sum = new Accumulator(\"SUM\");\n for (const bucket of members) sum.add(bucket);\n return sum.result();\n };\n let hiddenGroups: number | undefined;\n const min = metricMinCount(c);\n if (min !== undefined) {\n const kept = buckets.filter((b) =>\n metricMinCountKeeps(\n min,\n b.count,\n threshold ? measureOf(b.keys) : undefined,\n ),\n );\n hiddenGroups = buckets.length - kept.length;\n buckets = kept;\n }\n sortMetricBuckets(buckets, c);\n const groupCount = buckets.length;\n if (c.groupLimit) buckets = buckets.slice(0, c.groupLimit);\n const first = entries[0]!;\n return {\n id: c.id,\n buckets,\n scope: first.scope ?? c.scope ?? \"allMatching\",\n ...(first.processedRows !== undefined\n ? { processedRows: first.processedRows }\n : {}),\n groupCount,\n coverage: \"exact\",\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n };\n}\n\n/** Fold per-occurrence buckets (keyed by an hour or day start) into cyclic\n * slots. Each slot's value is the mean of its occurrences' values, or the\n * median of a box over them; occurrences without a value are not samples. */\nfunction combineOccurrences(\n c: AggregationClause,\n entry: AggregationResultEntry,\n): AggregationResultEntry {\n const config = c.dateGrouping!,\n cycle = config.interval;\n if (!isMetricCycle(cycle)) throw Error(\"Invalid date grouping occurrence.\");\n if (entry.error) throw Error(entry.error);\n if (\n entry.coverage === \"partial\" ||\n (entry.groupCount ?? entry.buckets.length) > entry.buckets.length\n )\n throw Error(\n \"Occurrences need every interval, but the engine returned only some of them.\",\n );\n type Slot = {\n keys: MetricValue[];\n count: number;\n values: number[];\n error?: string;\n };\n const slots = new Map<string, Slot>();\n const slotOf = (keys: MetricValue[]) => {\n const key = JSON.stringify(keys);\n let slot = slots.get(key);\n if (!slot) slots.set(key, (slot = { keys, count: 0, values: [] }));\n return slot;\n };\n for (const bucket of entry.buckets) {\n // Whole-occurrence bounds keep rows without a date out of the metric.\n if (bucket.keys[0] === null || bucket.keys[0] === undefined) continue;\n const slot = slotOf([\n metricCycleSlot(metricDateTime(bucket.keys[0]), cycle, config.timeZone),\n ...bucket.keys.slice(1),\n ]);\n slot.count += bucket.count;\n if (slot.error) continue;\n if (bucket.error) slot.error = bucket.error;\n else if (typeof bucket.value === \"number\") slot.values.push(bucket.value);\n else if (bucket.value !== null)\n slot.error = \"Occurrence values must be numeric.\";\n }\n if (config.includeEmpty) {\n const tails = new Map<string, MetricValue[]>();\n for (const slot of slots.values())\n tails.set(JSON.stringify(slot.keys.slice(1)), slot.keys.slice(1));\n if (c.groupBy.length === 1 && !tails.size) tails.set(\"[]\", []);\n for (const number of metricCycleSlots(cycle))\n for (const tail of tails.values()) slotOf([number, ...tail]);\n }\n // Validation allows only a box over occurrences.\n const box = occurrenceDistribution(c);\n let buckets = [...slots.values()].map((slot): AggregationBucket => {\n const bucket: AggregationBucket = {\n keys: slot.keys,\n count: slot.count,\n value: null,\n occurrences: slot.values.length,\n };\n if (slot.error) return { ...bucket, error: slot.error };\n try {\n if (box) {\n const summary = boxSummary(slot.values, c.distribution!.whiskers);\n bucket.distribution = { kind: \"box\", summary };\n bucket.value = summary?.median ?? null;\n } else if (slot.values.length) {\n const mean =\n slot.values.reduce((sum, value) => sum + value, 0) /\n slot.values.length;\n assertMetricNumber(mean);\n bucket.value = mean;\n }\n } catch (e) {\n return { ...bucket, value: null, error: (e as Error).message };\n }\n return bucket;\n });\n let hiddenGroups: number | undefined;\n // Occurrence slots take row minimums only (validation refuses measures).\n const min = metricMinCount(c);\n if (min !== undefined) {\n const kept = buckets.filter(\n (b) => b.count === 0 || b.count >= min,\n );\n hiddenGroups = buckets.length - kept.length;\n buckets = kept;\n }\n sortMetricBuckets(buckets, c);\n const groupCount = buckets.length;\n if (c.groupLimit) buckets = buckets.slice(0, c.groupLimit);\n return {\n id: c.id,\n buckets,\n scope: entry.scope ?? c.scope ?? \"allMatching\",\n ...(entry.processedRows !== undefined\n ? { processedRows: entry.processedRows }\n : {}),\n groupCount,\n coverage: \"exact\",\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n };\n}\n","import { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n compileMetric,\n metricAggregatePlans,\n reduceMetricValues,\n evaluateMetricReductions,\n metricPlans,\n hasRegex,\n selectMetricShownRows,\n} from \"./metrics\";\nimport { formulaRuntime, type FormulaNode, type FormulaValue } from \"./formula\";\nimport { isComputedCellError, isComputedField } from \"./computed\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport {\n calendarKeyReader,\n datetimeValue,\n GROUP_KEY_INTERVALS,\n groupKeyField,\n groupKeyFields,\n groupKeyTerms,\n isCalendarGroupKey,\n type GroupKey,\n} from \"./groupKeys\";\nimport { isGroupingTimeZone, isMetricCycle } from \"./metricDates\";\nimport { fillUrlTemplate, templateFields, urlTemplateProblem } from \"./itemPage\";\nimport type { QueryPatch } from \"./queryPatch\";\nimport { type QueryEvaluationOptions } from \"./relativeTime\";\nimport type { MetricPlan } from \"./metrics\";\nimport {\n isFilterable,\n isSortable,\n isSelectable,\n readFieldValue,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n MAX_GROUP_BY_FIELDS,\n normalizeQueryState,\n predicatesOf,\n type AggOp,\n type QueryState,\n type WhereClause,\n} from \"./query\";\n\nexport type GroupedRow = Record<string, unknown>;\ntype Row = GroupedRow;\nexport type SummaryOp = AggOp | \"row\" | \"formula\" | \"link\";\nexport interface RepresentativeOrder {\n field: string;\n dir: \"asc\" | \"desc\";\n nulls: \"first\" | \"last\";\n}\nexport interface RepresentativeRow {\n orderBy: RepresentativeOrder[];\n}\nexport interface SummaryColumn {\n id: string;\n op: SummaryOp;\n field?: string;\n expression?: string;\n label?: string;\n /** Cell format for this output column (for example `{ kind: \"percent\" }` for\n * a weighted rate). Replaces any render/display inherited from the source\n * field; metrics measuring the column default their value format from it. */\n display?: CellDisplay;\n /** Required for `op: \"link\"`; ignored otherwise. */\n link?: LinkSpec;\n}\n\n/** Where a link column points. Placeholders and key filters read the group\n * row: its keys and non-link summaries. */\nexport type LinkDestination =\n /** `{field:name}` placeholders over keys and summaries; values are\n * percent-encoded. The result must be an HTTP(S) or relative URL. */\n | { kind: \"template\"; template: string }\n /** A query composed by query-table and routed by the host's\n * `linkTargets[target](query, params)`. */\n | {\n kind: \"query\";\n target: string;\n /** \"source\" (default) starts from `grouping.source`, keeping its\n * filters, columns and order; \"empty\" starts from `EMPTY_QUERY`. */\n base?: \"source\" | \"empty\";\n /** Add `=`/`is_null` per group key, as `groupSourceQuery` does. Default true. */\n keyFilters?: boolean;\n /** Applied last, with `applyPatch`. */\n patch?: QueryPatch;\n /** Static parameters passed to the host target. */\n params?: Record<string, string>;\n };\n\n/** A group-grain link column (`SummaryColumn` with `op: \"link\"`). Computed on\n * the client from the returned group row; never sent to a server. */\nexport interface LinkSpec {\n /** Static text, or the value of a group key or summary column. */\n label: string | { column: string };\n to: LinkDestination;\n}\n\n/** The value of a link column for one group row: everything that depends on\n * the row. `resolveGroupLink` combines it with the current query and the\n * host's link targets. */\nexport interface GroupLinkValue {\n kind: \"group-link\";\n label: string;\n to: LinkDestination | null;\n /** Template links: the substituted, not yet safety-checked href. */\n href?: string;\n /** Query links with key filters: the group's key predicates. */\n terms?: WhereClause[];\n /** Why the link cannot be followed for this row. */\n problem?: string;\n}\nexport const GROUP_LINK_RENDER = \"qt_group_link\";\nexport function isGroupLinkValue(value: unknown): value is GroupLinkValue {\n return value != null && typeof value === \"object\" && (value as GroupLinkValue).kind === \"group-link\";\n}\nexport function isGroupLinkField(field: Pick<FieldDef, \"render\"> | undefined): boolean {\n return field?.render === GROUP_LINK_RENDER;\n}\nexport interface GroupingView {\n version: 2;\n mode: \"rows\" | \"groups\";\n /** Result key columns: the field each key reads, in key order. */\n keys: string[];\n /** The keys as defined, including calendar intervals; absent means `keys`. */\n groupKeys?: GroupKey[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n input: QueryState;\n result: QueryState;\n}\n\n/** One grouping stage over the complete source population. QueryState.where is\n * HAVING in this mode; source.where is the pre-group WHERE. The source snapshot\n * also restores the record layout, paging, metrics and item details on exit. */\nexport interface GroupingDefinition {\n /** Field names, or calendar keys (`{ field, interval, timeZone }`) that\n * group a datetime field by interval. Each field appears once; its result\n * column is named after the field. */\n keys: GroupKey[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n diagnostics?: string[];\n}\nexport interface GroupingState extends GroupingDefinition {\n source: QueryState;\n}\nexport const GROUP_ID_FIELD = \"__qt_group_id__\";\nexport const MAX_REPRESENTATIVE_SORTS = 8;\nexport const MAX_SUMMARY_COLUMNS = 64;\nexport const MAX_RESULT_GROUPS = 10000;\nexport function withoutGrouping(query: QueryState): QueryState {\n const { grouping: _grouping, ...result } = query;\n return result;\n}\n\n/** Leave the grouping stage: the source snapshot restores the record WHERE,\n * layout, ordering, paging, metrics and item details, and keeps the host\n * state of the grouped query. Ungrouped queries are returned unchanged. */\nexport function exitGrouping(query: QueryState): QueryState {\n if (!query.grouping) return query;\n if (!query.hostState && !query.grouping.source.hostState) return query.grouping.source;\n const { hostState: _source, ...source } = query.grouping.source;\n return query.hostState ? { ...source, hostState: query.hostState } : source;\n}\n\n/** The grouping-key transition behind the grouping controls. Empty keys exit\n * the stage; an ungrouped query becomes the source of a new stage that shows\n * only its keys; a grouped query swaps keys, dropping result columns, HAVING\n * terms and sorts on removed keys and clearing group metrics. */\nexport function withGroupingKeys(query: QueryState, keys: GroupKey[]): QueryState {\n const before = query.grouping;\n if (!keys.length) return exitGrouping(query);\n const names = groupKeyFields(keys);\n if (!before) {\n // Host state stays on the grouped query, which owns the whole definition.\n const { hostState, ...source } = query;\n return {\n select: names.map((field) => ({ field })),\n where: [],\n orderBy: [],\n limit: query.limit,\n offset: 0,\n grouping: { keys, summaries: [], representative: null, source },\n ...(hostState ? { hostState } : {}),\n };\n }\n // A key keeps its column when only its interval changes.\n const previous = groupKeyFields(before.keys);\n const removed = new Set(previous.filter((key) => !names.includes(key)));\n // An empty SELECT shows the existing keys by default. Materialize them\n // before adding keys so introducing an explicit SELECT keeps those columns.\n const columns = query.select.length\n ? query.select\n : previous.map((field) => ({ field }));\n return {\n ...query,\n grouping: { ...before, keys },\n offset: 0,\n aggregations: [],\n select: [\n ...names\n .filter((key) => !previous.includes(key))\n .map((field) => ({ field })),\n ...columns.filter((c) => !removed.has(c.field)),\n ],\n where: query.where.filter(\n (term) => !predicatesOf(term).some((p) => removed.has(p.field)),\n ),\n orderBy: query.orderBy.filter((term) => !removed.has(term.field)),\n };\n}\nexport const OP_LABEL: Record<SummaryOp, string> = {\n count: \"COUNT\",\n count_distinct: \"DISTINCT\",\n sum: \"SUM\",\n avg: \"AVG\",\n min: \"MIN\",\n max: \"MAX\",\n row: \"ROW\",\n formula: \"ƒx\",\n link: \"LINK\",\n};\n\n/** Bind aggregation helpers to this instance's source catalogue. */\nexport function createGroupingModel<InputRow>(\n inputSchema: FieldSchema<InputRow>,\n) {\n const sourceField = (name: string) =>\n inputSchema.fields.find((f) => f.name === name);\n const groupableFields = inputSchema.fields.filter(\n (field) => isGroupable(field) && isSelectable(field),\n );\n const summaryFields = inputSchema.fields.filter(\n (f) => f.type !== \"textarray\" && isSelectable(f),\n );\n const representativeFields = inputSchema.fields.filter(\n (field) => isSortable(field) && field.type !== \"textarray\",\n );\n\n function representativeLabel(rule: RepresentativeRow): string {\n return rule.orderBy\n .map(\n (term) =>\n `${sourceField(term.field)?.label ?? term.field} ${term.dir === \"asc\" ? \"↑\" : \"↓\"}${term.nulls === \"first\" ? \" (empty first)\" : \"\"}`,\n )\n .join(\", \");\n }\n\n function allowedOps(field?: string): SummaryOp[] {\n if (!field) return [\"count\"];\n const f = sourceField(field);\n return f && isSelectable(f)\n ? [...(isMeasurable(f) ? aggOpsForField(f) : []), \"row\"]\n : [];\n }\n function summaryExpression(column: SummaryColumn): string {\n if (column.op === \"formula\") return column.expression ?? \"\";\n if (column.op === \"link\") return \"\";\n const field = column.field ? `[${column.field.replace(/\\]/g, \"]]\")}]` : \"\";\n return `${column.op === \"row\" ? \"COUNT\" : column.op.toUpperCase()}(${field})`;\n }\n function summaryProblem(column: SummaryColumn): string | null {\n if (column.op !== \"formula\") return null;\n try {\n const plan = compileMetric(summaryExpression(column), inputSchema);\n if (plan.dependencies.some((name) => !isSelectable(sourceField(name)!)))\n throw new Error(\"Aggregate fields must be selectable.\");\n if (hasRegex(plan))\n throw new Error(\n \"Regex aggregate formulas require isolated execution and are not supported in grouped columns.\",\n );\n return null;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n }\n function summaryLabel(column: SummaryColumn): string {\n if (column.op === \"formula\")\n return column.label?.trim() || \"Custom aggregate\";\n if (column.op === \"link\")\n return column.label?.trim() || (typeof column.link?.label === \"string\" && column.link.label.trim()) || \"Link\";\n if (!column.field) return \"Row count\";\n const label = sourceField(column.field)?.label ?? column.field;\n const prefix: Record<SummaryOp, string> = {\n count: \"Count of\",\n count_distinct: \"Distinct\",\n sum: \"Total\",\n avg: \"Average\",\n min: \"Min\",\n max: \"Max\",\n row: \"Representative ·\",\n formula: \"\",\n link: \"\",\n };\n return `${prefix[column.op]} ${label}`;\n }\n\n /** Group-row fields a link column reads, in a stable order. */\n function linkReferences(column: SummaryColumn, keys: GroupKey[]): string[] {\n const link = column.link;\n if (!link) return [];\n const names = new Set<string>();\n if (typeof link.label === \"object\") names.add(link.label.column);\n if (link.to.kind === \"template\")\n for (const name of templateFields(link.to.template)) names.add(name);\n else if (link.to.keyFilters !== false)\n for (const key of keys) names.add(groupKeyField(key));\n return [...names];\n }\n\n /** Why a link column is invalid for this definition, or null. Problems are\n * diagnostics: the column renders as plain text and the rest of the grouped\n * table runs. Host target registration is checked when rendering. */\n function linkProblem(\n column: SummaryColumn,\n keys: GroupKey[],\n summaries: SummaryColumn[],\n ): string | null {\n const link = column.link;\n if (column.op !== \"link\") return null;\n if (!link) return \"Invalid link definition.\";\n const names = groupKeyFields(keys);\n const readable = (name: string) =>\n names.includes(name) ||\n summaries.some((other) => other.id === name && other.op !== \"link\");\n if (typeof link.label === \"object\" && !readable(link.label.column))\n return `Unknown link label column: ${link.label.column}.`;\n if (link.to.kind === \"template\") {\n if (!link.to.template.trim()) return \"Enter a link URL template.\";\n return urlTemplateProblem(link.to.template, [], readable);\n }\n if (link.to.keyFilters !== false)\n for (const key of names) {\n const field = sourceField(key);\n if (field?.type === \"textarray\")\n return `Key filters cannot match the textarray key ${field.label}.`;\n if (!field || !isFilterable(field))\n return `Key filters cannot match the key ${field?.label ?? key}.`;\n }\n return null;\n }\n\n /** One message per invalid link column, prefixed with its label. */\n function linkDiagnostics(definition: Pick<GroupingDefinition, \"keys\" | \"summaries\">): string[] {\n return definition.summaries.flatMap((column) => {\n const problem = linkProblem(column, definition.keys, definition.summaries);\n return problem ? [`${summaryLabel(column)}: ${problem}`] : [];\n });\n }\n\n function linkValue(\n column: SummaryColumn,\n problem: string | null,\n keys: GroupKey[],\n schema: FieldSchema<Row>,\n row: Row,\n ): GroupLinkValue {\n const link = column.link;\n const read = (name: string): unknown => {\n const field = schema.fields.find((f) => f.name === name);\n const value = field ? readFieldValue(field, row) : undefined;\n if (value == null || isComputedCellError(value)) return null;\n if (field?.type === \"datetime\" || value instanceof Date)\n return datetimeValue(value) ?? value;\n return Array.isArray(value) ? value.join(\", \") : value;\n };\n const label = !link\n ? summaryLabel(column)\n : typeof link.label === \"string\"\n ? link.label\n : String(read(link.label.column) ?? \"\");\n const value: GroupLinkValue = { kind: \"group-link\", label, to: link?.to ?? null };\n if (problem || !link) return { ...value, problem: problem ?? \"Invalid link definition.\" };\n if (link.to.kind === \"template\") {\n const href = fillUrlTemplate(link.to.template, [], (token) => read(token.slice(6)));\n return href === null ? { ...value, problem: \"A value in this link is empty.\" } : { ...value, href };\n }\n if (link.to.keyFilters === false) return value;\n const terms = groupKeyTerms(keys, row, inputSchema);\n return terms ? { ...value, terms } : { ...value, problem: \"This group cannot be matched exactly.\" };\n }\n\n function resultSchema(\n keys: GroupKey[],\n summaries: SummaryColumn[],\n ): FieldSchema<Row> {\n const fields: FieldDef<Row>[] = [\n {\n name: GROUP_ID_FIELD,\n label: \"Group identity\",\n type: \"text\",\n source: { kind: \"backend\" },\n select: { enabled: false },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n },\n ...keys.flatMap((key): FieldDef<Row>[] => {\n const field = sourceField(groupKeyField(key));\n // Draft/saved views may contain fields removed by the host. Leave\n // them in query state for repair; validate() still rejects execution.\n if (!field) return [];\n return [{\n // A calendar key's column holds each interval's start instant.\n name: field.name,\n label: isCalendarGroupKey(key) ? `${field.label} (${key.interval})` : field.label,\n type: field.type,\n source: { kind: \"backend\" },\n ...(field.select ? { select: { ...field.select } } : {}),\n ...(field.filter ? { filter: { ...field.filter } } : {}),\n ...(field.aggregate ? { aggregate: { ...field.aggregate } } : {}),\n ...(field.sort?.enabled !== undefined\n ? { sort: { enabled: field.sort.enabled } }\n : {}),\n ...(typeof field.render === \"string\" ? { render: field.render } : {}),\n ...(field.display ? { display: field.display } : {}),\n group: \"Group keys\",\n }];\n }),\n ];\n let schema: FieldSchema<Row>;\n for (const column of summaries) {\n if (column.op === \"link\") {\n const problem = linkProblem(column, keys, summaries);\n // Client-only: toServerQuery requests the dependencies instead.\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type: \"text\",\n source: {\n kind: \"derived\",\n dependencies: linkReferences(column, keys),\n accessor: (row) => linkValue(column, problem, keys, schema, row),\n },\n select: { align: \"left\" },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n render: GROUP_LINK_RENDER,\n group: \"Links\",\n });\n continue;\n }\n if (column.op === \"formula\") {\n let type: FieldDef<Row>[\"type\"] = \"number\";\n try {\n const compiled = compileMetric(\n summaryExpression(column),\n inputSchema,\n );\n type = compiled.type === \"null\" ? \"number\" : compiled.type;\n } catch {\n /* Invalid drafts show diagnostics in the editor. */\n }\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type,\n source: { kind: \"backend\" },\n group: \"Aggregates\",\n select: { align: type === \"number\" ? \"right\" : \"left\" },\n ...(column.display ? { display: column.display } : {}),\n });\n continue;\n }\n const input = column.field ? sourceField(column.field) : undefined;\n const counting = column.op === \"count\" || column.op === \"count_distinct\";\n const numeric = counting || column.op === \"sum\" || column.op === \"avg\";\n const example = column.op === \"row\";\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type: numeric ? \"number\" : (input?.type ?? \"number\"),\n source: { kind: \"backend\" },\n select: {\n align: numeric || input?.type === \"number\" ? \"right\" : \"left\",\n },\n group: example ? \"Representative row\" : \"Summaries\",\n ...(!numeric && input?.aggregate?.groupable !== undefined\n ? { aggregate: { groupable: input.aggregate.groupable } }\n : {}),\n // An explicit summary format replaces the inherited source presentation.\n ...(column.display\n ? { display: column.display }\n : {\n ...(typeof input?.render === \"string\" && !counting\n ? { render: input.render }\n : {}),\n ...(input?.display && !counting ? { display: input.display } : {}),\n }),\n });\n }\n schema = {\n name: `${inputSchema.name}:groups`,\n idField: GROUP_ID_FIELD,\n fields,\n defaultSelect: groupKeyFields(keys).filter(key => sourceField(key)).map((field) => ({ field })),\n defaultLimit: 25,\n };\n return schema;\n }\n\n // Typed tuples distinguish NULL, empty string, booleans and numbers. Key field\n // names are part of identity; key order and row arrival order are not.\n function keyValue(value: unknown): FormulaValue {\n if (value == null) return null;\n if (value instanceof Date) return value.toISOString();\n if (\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n return value;\n throw new Error(\"Group keys must be finite scalar values.\");\n }\n function groupId(values: readonly (readonly [string, unknown])[]): string {\n const tuple = [...values]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([key, value]) => [key, keyValue(value)]);\n // Bound source strings before JSON escaping can multiply their allocation.\n if (\n tuple.some(\n ([key, value]) => String(key).length + String(value).length > 10000,\n )\n )\n throw new Error(\"Grouping key length budget exceeded.\");\n const id = JSON.stringify(tuple);\n if (id.length > 65536)\n throw new Error(\"Grouping key length budget exceeded.\");\n return id;\n }\n function compare(a: unknown, b: unknown): number {\n if (a === b) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n return a < b ? -1 : 1;\n }\n function representative(\n rows: InputRow[],\n rule: RepresentativeRow,\n schema: FieldSchema<InputRow>,\n ): InputRow {\n const identityField = schema.fields.find(\n (field) => field.name === schema.idField,\n );\n const identities = new Set<string | number>();\n for (const row of rows) {\n const id = identityField\n ? readFieldValue(identityField, row)\n : (row as Record<string, unknown>)[schema.idField];\n if (\n !(\n typeof id === \"string\" ||\n (typeof id === \"number\" && Number.isFinite(id))\n ) ||\n identities.has(id)\n )\n throw new Error(\n \"Representative rows require unique string or finite numeric source IDs.\",\n );\n identities.add(id);\n }\n // The same stable identity tie-break is used for every projection. Explicit\n // ordering by ID takes precedence; no arrival-order fallback is needed.\n const order = rule.orderBy.some((term) => term.field === schema.idField)\n ? rule.orderBy\n : [\n ...rule.orderBy,\n { field: schema.idField, dir: \"desc\", nulls: \"last\" } as const,\n ];\n const terms = order.map((term) => ({\n ...term,\n def: schema.fields.find((field) => field.name === term.field)!,\n }));\n return rows.reduce((best, row) => {\n for (const term of terms) {\n const value = (record: InputRow) => {\n const raw = term.def\n ? readFieldValue(term.def, record)\n : (record as Record<string, unknown>)[schema.idField];\n if (raw == null || term.def?.type !== \"datetime\") return raw;\n const instant = Date.parse(String(raw));\n return Number.isFinite(instant) ? instant : null;\n };\n const a = value(row),\n b = value(best);\n if (a == null || b == null) {\n if (a == null && b == null) continue;\n return (a == null) === (term.nulls === \"first\") ? row : best;\n }\n const rank = compare(a, b);\n if (rank !== 0)\n return (term.dir === \"asc\" ? rank < 0 : rank > 0) ? row : best;\n }\n return best;\n });\n }\n function groupRows(\n rows: InputRow[],\n schema: FieldSchema<InputRow>,\n keys: GroupKey[],\n summaries: SummaryColumn[],\n rule: RepresentativeRow | null = null,\n ): Row[] {\n if (!rule && summaries.some((column) => column.op === \"row\"))\n throw new Error(\n \"Configure representative-row ordering before selecting row values.\",\n );\n if (keys.length === 0) return [];\n if (keys.length > MAX_GROUP_BY_FIELDS || summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Grouping definition exceeds column limits.\");\n if (rows.length > 1_000_000)\n throw new Error(\"Grouping row budget exceeded.\");\n let bytes = rows.length * 16;\n let operations = 0;\n // A key reads its field's value, or the start of its calendar interval.\n const readers = keys.map((key) => {\n const name = groupKeyField(key);\n const field = schema.fields.find((f) => f.name === name)!;\n const calendar = isCalendarGroupKey(key) ? calendarKeyReader(key) : null;\n return [\n name,\n (row: InputRow) =>\n calendar\n ? calendar(readFieldValue(field, row))\n : readFieldValue(field, row),\n ] as const;\n });\n const groups = new Map<string, { keys: unknown[]; rows: InputRow[] }>();\n for (const row of rows) {\n const values = readers.map(([, read]) => read(row));\n const id = groupId(readers.map(([name], i) => [name, values[i]] as const));\n const bucket = groups.get(id);\n if (bucket) bucket.rows.push(row);\n else {\n if (groups.size >= MAX_RESULT_GROUPS)\n throw new Error(\n `Grouping exceeds ${MAX_RESULT_GROUPS.toLocaleString()} groups.`,\n );\n bytes += id.length * 2 + 256;\n if (bytes > 16_000_000)\n throw new Error(\"Grouping retained-memory budget exceeded.\");\n groups.set(id, { keys: values, rows: [row] });\n }\n }\n const formulas = new Map<string, { plan?: MetricPlan; error?: string }>(\n summaries\n .filter((c) => c.op !== \"row\" && c.op !== \"link\")\n .map((column) => {\n try {\n const problem = summaryProblem(column);\n if (problem) throw new Error(problem);\n return [\n column.id,\n { plan: compileMetric(summaryExpression(column), schema) },\n ] as const;\n } catch (error) {\n return [\n column.id,\n { error: error instanceof Error ? error.message : String(error) },\n ] as const;\n }\n }),\n );\n const nodeCost = (node: FormulaNode): number =>\n 1 +\n (node.kind === \"call\"\n ? node.args.reduce((cost, child) => cost + nodeCost(child), 0)\n : 0);\n const costs = new Map(\n [...formulas].map(([id, compiled]) => [\n id,\n compiled.plan?.aggregates.map(nodeCost) ?? [],\n ]),\n );\n return [...groups].map(([id, { keys: values, rows: members }]) => {\n const output: Row = Object.assign(Object.create(null), {\n [GROUP_ID_FIELD]: id,\n });\n readers.forEach(([name], i) => {\n output[name] = values[i];\n });\n const chosen =\n rule && summaries.some((column) => column.op === \"row\")\n ? representative(members, rule, schema)\n : null;\n for (const column of summaries) {\n if (column.op === \"link\") continue;\n if (column.op !== \"row\") {\n const compiled = formulas.get(column.id)!;\n if (!compiled.plan) {\n output[column.id] = { computedError: compiled.error };\n continue;\n }\n const plan = compiled.plan;\n const rowPlans = metricAggregatePlans(plan);\n const reductions = plan.aggregates.map((node, i) =>\n reduceMetricValues(\n node,\n members.map((row) => {\n if ((operations += costs.get(column.id)?.[i] ?? 1) > 10_000_000)\n throw new Error(\"Grouping operation budget exceeded.\");\n const rowPlan = rowPlans[i];\n if (!rowPlan) return { value: 1 };\n const values = Object.fromEntries(\n rowPlan.dependencies.map((name) => {\n const value = readFieldValue(\n schema.fields.find((f) => f.name === name)!,\n row,\n );\n return [\n name,\n (value instanceof Date\n ? value.toISOString()\n : (value ?? null)) as FormulaValue,\n ];\n }),\n );\n return formulaRuntime(rowPlan.ast, values);\n }),\n ),\n );\n const result = evaluateMetricReductions(plan, reductions);\n output[column.id] = result.error\n ? { computedError: result.error }\n : result.value;\n continue;\n }\n const field = schema.fields.find((f) => f.name === column.field);\n if (column.op === \"row\") {\n output[column.id] =\n field && chosen ? readFieldValue(field, chosen) : null;\n continue;\n }\n }\n return output;\n });\n }\n function filteredInput(\n rows: InputRow[],\n query: QueryState,\n schema: FieldSchema<InputRow>,\n options: QueryEvaluationOptions = {},\n ): InputRow[] {\n // GROUP BY operates on all matching source records, never on a displayed page.\n return selectMetricShownRows(\n rows,\n {\n ...withoutGrouping(query),\n aggregations: [],\n orderBy: [],\n offset: 0,\n limit: Math.max(1, rows.length),\n },\n { ...schema, defaultSort: [] },\n options,\n );\n }\n\n /** Reconcile only consumers of row values when the shared selection changes.\n * Aggregate outputs and metrics over them keep their meaning. */\n function reconcileRepresentative(\n query: QueryState,\n summaries: SummaryColumn[],\n schema: FieldSchema<Row>,\n remove: boolean,\n ): QueryState {\n const affected = new Set(\n summaries.filter((s) => s.op === \"row\").map((s) => s.id),\n );\n if (!affected.size) return query;\n // Computed columns can depend on representative fields transitively.\n let grew = true;\n while (grew) {\n grew = false;\n for (const f of schema.fields) {\n if (\n !affected.has(f.name) &&\n f.source.kind === \"derived\" &&\n f.source.dependencies?.some((name) => affected.has(name))\n ) {\n affected.add(f.name);\n grew = true;\n }\n }\n }\n return {\n ...query,\n offset: 0,\n select: remove\n ? query.select.filter((c) => !affected.has(c.field))\n : query.select,\n where: query.where.filter(\n (term) => !predicatesOf(term).some((p) => affected.has(p.field)),\n ),\n orderBy: query.orderBy.filter((term) => !affected.has(term.field)),\n aggregations: (query.aggregations ?? []).filter((metric) => {\n if (metric.groupBy.some((name) => affected.has(name))) return false;\n try {\n return !metricPlans(metric, schema).some((plan) =>\n plan.dependencies.some((name) => affected.has(name)),\n );\n } catch {\n // A broken expression cannot be proven independent of the changed values.\n return false;\n }\n }),\n };\n }\n\n function validate(definition: GroupingDefinition): void {\n if (definition.diagnostics?.length)\n throw new Error(definition.diagnostics.join(\" \"));\n const names = definition.keys.map((key) =>\n typeof key === \"string\" || isCalendarGroupKey(key) ? groupKeyField(key) : \"\",\n );\n if (\n !definition.keys.length ||\n definition.keys.length > MAX_GROUP_BY_FIELDS ||\n new Set(names).size !== names.length ||\n names.some(\n (key) =>\n typeof key !== \"string\" ||\n key === GROUP_ID_FIELD ||\n !groupableFields.some((f) => f.name === key),\n )\n )\n throw new Error(\"Choose valid group keys from the source schema.\");\n for (const key of definition.keys) {\n if (!isCalendarGroupKey(key)) continue;\n const field = sourceField(key.field)!;\n if (isMetricCycle(key.interval))\n throw new Error(\n `Group key ${field.label}: hour-of-day and day-of-week are metric intervals (dateGrouping); a group key takes hour, day, week, month or year.`,\n );\n if (!GROUP_KEY_INTERVALS.includes(key.interval))\n throw new Error(\n `Group key ${field.label}: choose an hour, day, week, month or year interval.`,\n );\n if (field.type !== \"datetime\")\n throw new Error(\n `Group key ${field.label}: a calendar interval needs a datetime field.`,\n );\n if (key.timeZone !== undefined && !isGroupingTimeZone(key.timeZone))\n throw new Error(\n `Group key ${field.label}: use a valid IANA timezone, such as America/Denver or UTC.`,\n );\n }\n if (definition.summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Too many aggregate columns.\");\n const ids = new Set([\n GROUP_ID_FIELD,\n ...inputSchema.fields.map((field) => field.name),\n ]);\n const sourceNames = new Set(inputSchema.fields.map((field) => field.name));\n for (const column of definition.summaries) {\n if (sourceNames.has(column.id))\n throw new Error(\n `Aggregate column ID \"${column.id}\" is already a source field name. Choose a different id, such as \"${column.op === \"formula\" || column.op === \"row\" ? \"summary\" : column.op}_${column.id}\".`,\n );\n if (ids.has(column.id) && column.id !== GROUP_ID_FIELD)\n throw new Error(\n `Aggregate column ID \"${column.id}\" is used by more than one column.`,\n );\n if (\n !column.id ||\n column.id.length > 256 ||\n ids.has(column.id) ||\n isComputedField(column.id) ||\n [\"__proto__\", \"constructor\", \"prototype\"].includes(column.id)\n )\n throw new Error(\n \"Aggregate column IDs must be 1–256 characters and cannot be reserved names or @computed/ references.\",\n );\n ids.add(column.id);\n // Link problems are diagnostics (linkDiagnostics), never execution errors.\n if (column.op === \"link\") continue;\n if (column.op === \"formula\") {\n const error = summaryProblem(column);\n if (error) throw new Error(error);\n } else if (\n !allowedOps(column.field).includes(column.op) ||\n (column.op === \"row\" && (!column.field || !definition.representative))\n )\n throw new Error(\"Invalid aggregate or representative column.\");\n }\n const rule = definition.representative;\n if (\n rule &&\n (!rule.orderBy.length ||\n rule.orderBy.length > MAX_REPRESENTATIVE_SORTS ||\n new Set(rule.orderBy.map((t) => t.field)).size !==\n rule.orderBy.length ||\n rule.orderBy.some(\n (t) =>\n !representativeFields.some((f) => f.name === t.field) ||\n ![\"asc\", \"desc\"].includes(t.dir) ||\n ![\"first\", \"last\"].includes(t.nulls),\n ))\n )\n throw new Error(\"Choose valid representative-row ordering.\");\n }\n\n return {\n inputSchema,\n sourceField,\n groupableFields,\n summaryFields,\n representativeFields,\n representativeLabel,\n allowedOps,\n summaryExpression,\n summaryProblem,\n summaryLabel,\n linkProblem,\n linkDiagnostics,\n resultSchema,\n groupRows,\n filteredInput,\n reconcileRepresentative,\n validate,\n };\n}\nexport type GroupingModel<Row> = ReturnType<typeof createGroupingModel<Row>>;\n\n/** Evaluate the WHERE and grouping stages once; callers apply HAVING and paging\n * with the resulting schema and withoutGrouping(query). Never accepts a page\n * fetched by a transport as a complete source dataset. */\nexport function prepareGrouping<Row>(\n rows: Row[],\n schema: FieldSchema<Row>,\n grouping: GroupingState,\n options: QueryEvaluationOptions = {},\n) {\n const model = createGroupingModel(schema);\n if (grouping.source.grouping)\n throw new Error(\"Only one grouping stage is supported.\");\n model.validate(grouping);\n const inputs = model.filteredInput(rows, grouping.source, schema, options);\n return {\n inputs,\n rows: model.groupRows(\n inputs,\n schema,\n grouping.keys,\n grouping.summaries,\n grouping.representative,\n ),\n schema: model.resultSchema(grouping.keys, grouping.summaries),\n };\n}\n","import {\n predicatesOf,\n normalizeQueryState,\n type QueryState,\n type RowId,\n} from \"./query\";\nimport { toServerQuery, type ServerQuery } from \"./encode\";\nimport {\n isComputedField,\n type ComputedExecution,\n type RowComputedValues,\n} from \"./computed\";\nimport { selectedFields, type FieldSchema } from \"./schema\";\nimport type { MetricDiagnostic } from \"./metricTypes\";\n/** Versioned row projection keeps server-computed payload separate from host row fields. */\nexport interface ServerQueryV2 extends ServerQuery {\n version: 2;\n profile: string;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n /** Host must enforce this binding against the row response. */\n snapshot?: string;\n diagnostics: MetricDiagnostic[];\n}\nexport interface FetchRowsResultV2<Row> {\n version: 2;\n rows: Row[];\n total: number;\n computed: { id: RowId; values: RowComputedValues }[];\n execution: ComputedExecution;\n}\n/** Project with a previously resolved server capability envelope. This does not\n * authorize definitions or upload their source; the backend revalidates revisions. */\nexport function toServerQueryV2<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution: ComputedExecution,\n): ServerQueryV2 {\n const normalized = normalizeQueryState(q),\n legacy = toServerQuery(normalized, schema);\n const diagnostics: MetricDiagnostic[] = [];\n const expectedRevisions = Object.create(null) as Record<string, string>;\n const requireField = (\n name: string,\n operation: \"select\" | \"sort\",\n ): boolean => {\n const cap = execution.fields[name];\n const revision =\n execution.resolvedRevisions[name] ??\n execution.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (!cap?.[operation] || !revision) {\n diagnostics.push({\n code: \"unsupported_computed\",\n message: `Computed field ${name} is unavailable for ${operation}.`,\n from: 0,\n to: 1,\n });\n return false;\n }\n return true;\n };\n for (const [key, value] of Object.entries(execution.resolvedRevisions)) {\n if (\n key.length > 256 ||\n typeof value !== \"string\" ||\n !value ||\n value.length > 256\n )\n throw Error(\"Invalid computed revision envelope.\");\n expectedRevisions[key] = value;\n }\n const select = [...legacy.select];\n for (const c of normalized.select.length\n ? normalized.select\n : selectedFields(schema, normalized).map((f) => ({ field: f.name })))\n if (\n isComputedField(c.field) &&\n execution.fields[c.field]?.select &&\n requireField(c.field, \"select\")\n )\n select.push(c.field);\n // Retain unsupported clauses in state; gate execution using the server envelope.\n const orderBy: ServerQuery[\"orderBy\"] = [];\n for (const term of normalized.orderBy.length\n ? normalized.orderBy\n : (schema.defaultSort ?? [])) {\n if (isComputedField(term.field)) {\n if (requireField(term.field, \"sort\")) {\n if ((term.dir !== \"asc\" && term.dir !== \"desc\") || term.extract) {\n diagnostics.push({\n code: \"unsupported_computed_sort\",\n message: \"Invalid computed sort or extraction.\",\n from: 0,\n to: 1,\n });\n continue;\n }\n orderBy.push({\n field: term.field,\n dir: term.dir,\n ...(term.nulls === \"first\" || term.nulls === \"last\"\n ? { nulls: term.nulls }\n : {}),\n });\n }\n } else {\n const projected = toServerQuery(\n { ...normalized, orderBy: [term] },\n schema,\n ).orderBy;\n if (!projected.length)\n diagnostics.push({\n code: \"unsupported_sort\",\n message: `Unavailable server sort: ${term.field}.`,\n from: 0,\n to: 1,\n });\n orderBy.push(...projected);\n }\n }\n // The host appends its configured tie-break terms and stable identity. An\n // identity term here would take precedence over the host's ordering.\n if (\n legacy.where.length !== normalized.where.length ||\n q.where.reduce((n, t) => n + predicatesOf(t).length, 0) !==\n normalized.where.reduce((n, t) => n + predicatesOf(t).length, 0)\n )\n diagnostics.push({\n code: \"residual_filter\",\n message:\n \"Global execution is unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n });\n return {\n ...legacy,\n select: [...new Set(select)].sort(),\n orderBy,\n version: 2,\n profile: execution.profile,\n expectedRevisions,\n ...(execution.planToken ? { planToken: execution.planToken } : {}),\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n diagnostics,\n };\n}\n","import type { ComputedExecution } from \"./computed\";\nimport { isComputedField } from \"./computed\";\nimport {\n compileFormula,\n formulaRuntime,\n FormulaError,\n type FormulaNode,\n type FormulaPlan,\n type FormulaType,\n type FormulaValue,\n type FormulaDiagnostic,\n type FormulaResult,\n type FormulaFunction,\n} from \"./formula\";\nimport { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n indexFields,\n isFilterable,\n readFieldValue,\n resolveFieldName,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n EMPTY_QUERY,\n MAX_WHERE_CLAUSES,\n normalizeQueryState,\n predicatesOf,\n type AggregationClause,\n type AggOp,\n type QueryState,\n type WhereTerm,\n} from \"./query\";\nimport { opsForField } from \"./ops\";\nimport { hasMetricSeries, planMetricSeries, validateMetricSeries } from \"./metricSeries\";\nimport { applyQuery } from \"./apply\";\nimport { prepareGrouping, withoutGrouping, type GroupedRow } from \"./grouping\";\nimport { computedInputAllowed } from \"./apply\";\nimport { toServerQueryV2 } from \"./execution\";\nimport {\n toServerQuery,\n type AggregationResult,\n type AggregationBucket,\n} from \"./encode\";\nimport type { MetricQuery, MetricValue, MetricSort } from \"./metricTypes\";\nimport {\n boxSummary,\n histogramEdges,\n histogramCounts,\n} from \"./metricDistributions\";\nimport { assertMetricNumber, checkedMetricResult } from \"./metricPrecision\";\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport {\n metricDateTime,\n metricDateFloor,\n metricDateNext,\n metricDateRange,\n isMetricCycle,\n metricCycleSlot,\n metricCycleSlots,\n validateDateGrouping,\n} from \"./metricDates\";\nconst aggregates = new Set([\n \"COUNT\",\n \"COUNT_DISTINCT\",\n \"SUM\",\n \"AVG\",\n \"MIN\",\n \"MAX\",\n \"MEDIAN\",\n]);\n/** Functions available only in aggregate expressions, separate from row formulas. */\nexport const METRIC_FUNCTIONS: FormulaFunction[] = [\n [\"COUNT\", \"Count rows, or non-empty values.\"],\n [\"COUNT_DISTINCT\", \"Count distinct non-empty values.\"],\n [\"SUM\", \"Total numeric values in each group.\"],\n [\"AVG\", \"Average numeric values in each group.\"],\n [\"MIN\", \"Smallest non-empty value in each group.\"],\n [\"MAX\", \"Largest non-empty value in each group.\"],\n [\n \"MEDIAN\",\n \"Middle numeric value; averages the middle pair. Ignores empty values.\",\n ],\n].map(([name, description]) => ({\n name: name!,\n description: description!,\n signature: `${name}(row expression${name === \"COUNT\" ? \"?\" : \"\"})`,\n min: name === \"COUNT\" ? 0 : 1,\n max: 1,\n result: name === \"MIN\" || name === \"MAX\" ? \"branch\" : \"number\",\n args: [\"SUM\", \"AVG\", \"MEDIAN\"].includes(name!) ? [\"number\"] : \"any\",\n}));\nexport interface MetricPlan extends FormulaPlan {\n aggregates: Extract<FormulaNode, { kind: \"call\" }>[];\n aggregateTypes: FormulaType[];\n}\nexport function compileMetric(\n expression: string,\n schema: FieldSchema | readonly FieldDef[],\n resolve?: (name: string) => FormulaPlan | undefined,\n): MetricPlan {\n const fields: readonly FieldDef[] = Array.isArray(schema)\n ? schema\n : (schema as FieldSchema).fields;\n const nodes: MetricPlan[\"aggregates\"] = [];\n const aggregateTypes: FormulaType[] = [];\n let inAggregate = false;\n const plan = compileFormula(\n expression,\n resolve\n ? fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : fields,\n resolve,\n (node, check) => {\n if (node.kind !== \"call\" || !aggregates.has(node.name)) return undefined;\n if (inAggregate)\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n node.from,\n node.to,\n );\n if (\n node.args.length > 1 ||\n (node.name !== \"COUNT\" && node.args.length !== 1)\n )\n throw new FormulaError(\n `${node.name} requires ${node.name === \"COUNT\" ? \"zero or one argument\" : \"one argument\"}.`,\n node.from,\n node.to,\n );\n inAggregate = true;\n let type: FormulaType;\n try {\n type = node.args[0] ? check(node.args[0]) : \"number\";\n } finally {\n inAggregate = false;\n }\n const visit = (n: FormulaNode) => {\n if (n.kind === \"field\") {\n const field = fields.find((f) => f.name === n.name);\n if (!field)\n throw new FormulaError(\n `Unresolved dependency ${n.name}.`,\n n.from,\n n.to,\n );\n // MEDIAN is formula-only, so it is absent from the default AggOp\n // list. Explicit field restrictions still apply to every reduction.\n if (\n !isMeasurable(field) ||\n ((field.aggregate?.ops !== undefined ||\n (node.args[0] === n && node.name !== \"MEDIAN\")) &&\n !aggOpsForField(field).includes(node.name.toLowerCase() as AggOp))\n )\n throw new FormulaError(\n `Field ${n.name} does not allow ${node.name}.`,\n n.from,\n n.to,\n );\n } else if (n.kind === \"call\") {\n if (aggregates.has(n.name))\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n n.from,\n n.to,\n );\n n.args.forEach(visit);\n }\n };\n node.args.forEach(visit);\n if (\n [\"SUM\", \"AVG\", \"MEDIAN\"].includes(node.name) &&\n ![\"number\", \"null\"].includes(type)\n )\n throw new FormulaError(\n `${node.name} requires numeric input.`,\n node.from,\n node.to,\n );\n if (\n [\"MIN\", \"MAX\", \"COUNT_DISTINCT\"].includes(node.name) &&\n (type === \"textarray\" ||\n (type === \"bool\" && node.name !== \"COUNT_DISTINCT\"))\n )\n throw new FormulaError(\n `Unsupported ${node.name} input type.`,\n node.from,\n node.to,\n );\n nodes.push(node);\n aggregateTypes.push(type);\n return [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\", \"AVG\", \"MEDIAN\"].includes(\n node.name,\n )\n ? \"number\"\n : type;\n },\n );\n const groupCheck = (node: FormulaNode) => {\n if (node.kind === \"field\")\n throw new FormulaError(\n \"Row fields must be inside an aggregate.\",\n node.from,\n node.to,\n );\n if (node.kind === \"call\" && !aggregates.has(node.name)) {\n if (node.name.startsWith(\"REGEX_\"))\n throw new FormulaError(\n \"Regex is supported only inside aggregate row expressions.\",\n node.from,\n node.to,\n );\n node.args.forEach(groupCheck);\n }\n };\n groupCheck(plan.ast);\n if (!nodes.length)\n throw new FormulaError(\"A metric must contain an aggregate.\");\n if (plan.type === \"textarray\")\n throw new FormulaError(\"Metrics must return scalar values.\");\n return { ...plan, aggregates: nodes, aggregateTypes };\n}\n/** Row plans for worker evaluation. Null denotes COUNT(), which requires only row count. */\nexport function metricAggregatePlans(plan: MetricPlan): (FormulaPlan | null)[] {\n return plan.aggregates.map((node) => {\n if (!node.args[0]) return null;\n const dependencies = new Set<string>();\n const visit = (n: FormulaNode): void => {\n if (n.kind === \"field\") dependencies.add(n.name);\n else if (n.kind === \"call\") n.args.forEach(visit);\n };\n visit(node.args[0]);\n // Aggregate argument type is retained by the compiler in aggregateTypes.\n return {\n ast: node.args[0],\n dependencies: [...dependencies].sort(),\n type: plan.aggregateTypes[plan.aggregates.indexOf(node)]!,\n };\n });\n}\n/** Reduce exact per-row worker results; errors are not silently treated as NULL. */\nexport interface MetricReductionOptions {\n /** Retained distinct entries, independently bounded from row count. */\n maxDistinctValues?: number;\n /** Conservative UTF-16 payload plus per-entry storage estimate. */\n maxDistinctBytes?: number;\n}\nfunction distinctAccumulator(options: MetricReductionOptions) {\n const values = new Set<string | number | boolean>();\n let bytes = 0;\n const cardinality = options.maxDistinctValues ?? 100000;\n const byteLimit = options.maxDistinctBytes ?? 16000000;\n if (\n !Number.isSafeInteger(cardinality) ||\n cardinality < 0 ||\n !Number.isSafeInteger(byteLimit) ||\n byteLimit < 0\n )\n throw Error(\"Invalid distinct budget.\");\n return {\n add(value: FormulaValue) {\n const v = scalar(value);\n if (typeof v === \"number\") assertMetricNumber(v);\n if (v === null || values.has(v)) return;\n const size = 64 + (typeof v === \"string\" ? v.length * 2 : 8);\n if (values.size >= cardinality || size > byteLimit - bytes)\n throw Error(\"Metric distinct retained-memory budget exceeded.\");\n values.add(v);\n bytes += size;\n },\n result: () => ({ value: values.size }),\n };\n}\nexport function reduceMetricValues(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: readonly FormulaResult[],\n options: MetricReductionOptions = {},\n): FormulaResult {\n return reduceResults(node, results, options);\n}\nfunction reduceResults(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: Iterable<FormulaResult>,\n options: MetricReductionOptions,\n): FormulaResult {\n try {\n if (!aggregates.has(node.name)) throw Error(\"Expected an aggregate node.\");\n const distinct =\n node.name === \"COUNT_DISTINCT\" ? distinctAccumulator(options) : undefined;\n const values: FormulaValue[] = [];\n let count = 0,\n nonnull = 0,\n error: string | undefined;\n for (const r of results) {\n count++;\n if (r.error) {\n error ??= r.error;\n continue;\n }\n if (r.value === null) continue;\n if (node.name !== \"COUNT\" && !distinct && typeof r.value === \"number\")\n assertMetricNumber(r.value);\n nonnull++;\n if (distinct) distinct.add(r.value);\n else if (node.name !== \"COUNT\") values.push(r.value);\n }\n if (error) return { value: null, error };\n if (distinct) return distinct.result();\n if (node.name === \"COUNT\")\n return { value: node.args.length ? nonnull : count };\n if (!values.length) return { value: null };\n if (node.name === \"MEDIAN\") {\n const sorted = values\n .map((value) => {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw Error(\"Expected a finite number.\");\n return value;\n })\n .sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n const value =\n sorted.length % 2\n ? sorted[mid]!\n : sorted[mid - 1]! / 2 + sorted[mid]! / 2;\n assertMetricNumber(value);\n return { value };\n }\n if (node.name === \"SUM\" || node.name === \"AVG\") {\n let sum = 0;\n for (const v of values) {\n if (typeof v !== \"number\" || !Number.isFinite(v))\n throw Error(\"Expected a finite number.\");\n sum += v / (node.name === \"AVG\" ? values.length : 1);\n assertMetricNumber(sum);\n }\n return { value: sum };\n }\n return {\n value: values.reduce((a, b) =>\n compareMetricValues(scalar(a), scalar(b)) *\n (node.name === \"MIN\" ? 1 : -1) <=\n 0\n ? a\n : b,\n ),\n };\n } catch (e) {\n return { value: null, error: e instanceof Error ? e.message : String(e) };\n }\n}\n/** Evaluate the group AST lazily from reductions indexed like plan.aggregates.\n * A dead IF/COALESCE branch does not observe a failed aggregate in that branch. */\nexport function evaluateMetricReductions(\n plan: MetricPlan,\n reductions: readonly FormulaResult[],\n): FormulaResult {\n const key = (n: FormulaNode) =>\n `${n.from}:${n.to}:${n.kind === \"call\" ? n.name : n.kind}`;\n const byNode = new Map(\n plan.aggregates.map((n, i) => [key(n), reductions[i]]),\n );\n return checkedMetricResult(\n formulaRuntime(plan.ast, {}, (node) =>\n byNode.has(key(node))\n ? checkedMetricResult(\n byNode.get(key(node)) ?? {\n value: null,\n error: \"Missing aggregate reduction.\",\n },\n )\n : undefined,\n ),\n );\n}\nexport function metricExpression(clause: AggregationClause): string {\n return (\n clause.expression ??\n `${clause.op.toUpperCase()}(${clause.field ? `[${clause.field.replace(/]/g, \"]]\")}]` : \"\"})`\n );\n}\nexport function hasRegex(plan: FormulaPlan): boolean {\n const visit = (n: FormulaNode): boolean =>\n n.kind === \"call\" && (n.name.startsWith(\"REGEX_\") || n.args.some(visit));\n return visit(plan.ast);\n}\nfunction distributionActive(c: AggregationClause): boolean {\n return (\n !!c.distribution &&\n (!c.display || c.display.kind === \"box\" || c.display.kind === \"histogram\")\n );\n}\n/** A box over a cyclic slot's per-occurrence values: its input is the\n * metric itself, evaluated once per occurrence. */\nexport function occurrenceDistribution(c: AggregationClause): boolean {\n return distributionActive(c) && !!c.dateGrouping?.occurrence;\n}\nexport function metricPlans(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaPlan[] {\n if (distributionActive(c) && !occurrenceDistribution(c)) {\n const p = compileFormula(\n c.distribution!.input,\n resolve\n ? schema.fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : schema.fields,\n resolve,\n );\n if (p.type !== \"number\" && p.type !== \"null\")\n throw new FormulaError(\"Distribution input must be numeric.\");\n if (![\"box\", \"histogram\"].includes(c.distribution!.kind))\n throw new FormulaError(\"Invalid distribution kind.\");\n if (\n c.distribution!.kind === \"histogram\" &&\n (!Number.isInteger(c.distribution!.bins ?? 10) ||\n (c.distribution!.bins ?? 10) < 2 ||\n (c.distribution!.bins ?? 10) > 30)\n )\n throw new FormulaError(\"Choose 2–30 histogram bins.\");\n for (const name of p.dependencies) {\n const field = schema.fields.find((f) => f.name === name)!;\n if (!isMeasurable(field))\n throw new FormulaError(`Field ${name} cannot be a distribution input.`);\n }\n if (c.scope !== \"shownRows\" && hasRegex(p))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return [p];\n }\n const out = [\n compileMetric(\n metricExpression(\n c.expression === undefined && c.field\n ? { ...c, field: resolveFieldName(schema, c.field) ?? c.field }\n : c,\n ),\n schema,\n resolve,\n ),\n ];\n if (c.display?.kind === \"scatter\") {\n out.push(compileMetric(c.expressionY ?? \"\", schema, resolve));\n if (out.some((p) => p.type !== \"number\" && p.type !== \"null\"))\n throw new FormulaError(\"Scatter expressions must be numeric.\");\n }\n if (c.scope !== \"shownRows\" && out.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return out;\n}\nexport function validateMetric(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaDiagnostic[] {\n try {\n if (c.diagnostics?.length) throw new FormulaError(c.diagnostics.join(\" \"));\n if (c.groupBy.length > 20)\n throw new FormulaError(\"At most 20 grouping fields are allowed.\");\n for (const key of c.groupBy) {\n const f = schema.fields.find(\n (f) => f.name === (resolveFieldName(schema, key) ?? key),\n );\n if (!f || !isGroupable(f))\n throw new FormulaError(`Field ${key} cannot group metrics.`);\n }\n if (c.dateGrouping) {\n validateDateGrouping(c.dateGrouping);\n const field =\n resolveFieldName(schema, c.dateGrouping.field) ?? c.dateGrouping.field;\n if (\n field !==\n (resolveFieldName(schema, c.groupBy[0] ?? \"\") ?? c.groupBy[0]) ||\n schema.fields.find((f) => f.name === field)?.type !== \"datetime\"\n )\n throw new FormulaError(\n \"Date grouping must use the first grouping field, with a datetime type.\",\n );\n const { occurrence } = c.dateGrouping;\n if (occurrence) {\n if (distributionActive(c) && c.distribution!.kind !== \"box\")\n throw new FormulaError(\n \"Occurrences summarise as a mean or a box plot, not a histogram.\",\n );\n if (c.display?.kind === \"scatter\")\n throw new FormulaError(\n \"Occurrences summarise single-value metrics, not scatters.\",\n );\n if (c.window || c.share !== undefined)\n throw new FormulaError(\n \"Windows and shares do not apply to occurrences of a slot.\",\n );\n } else if (distributionActive(c))\n throw new FormulaError(\n \"Date grouping currently supports scalar metrics, not distributions.\",\n );\n }\n if (\n c.groupLimit !== undefined &&\n (!Number.isInteger(c.groupLimit) ||\n c.groupLimit < 1 ||\n c.groupLimit > 10000)\n )\n throw new FormulaError(\"Group limit must be 1–10,000.\");\n if (c.minCount !== undefined) validateMinCount(c, schema);\n validateMetricWhere(c.where, schema);\n for (const s of c.sort ?? []) {\n if (s.key === \"y\" && c.display?.kind !== \"scatter\")\n throw new FormulaError(\"Y sorting requires a scatter metric.\");\n if (s.key === \"samples\" && !distributionActive(c))\n throw new FormulaError(\n \"Sample sorting requires a distribution metric.\",\n );\n if (\n s.key.startsWith(\"group\") &&\n Number(s.key.slice(5)) >= c.groupBy.length\n )\n throw new FormulaError(\"Sort refers to an unavailable grouping key.\");\n }\n const compiled = metricPlans(c, schema, resolve);\n if (c.scope !== \"shownRows\" && compiled.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n validateMetricSeries(c, compiled[0]!);\n return [];\n } catch (e) {\n return [\n {\n message: e instanceof Error ? e.message : String(e),\n from: e instanceof FormulaError ? e.from : 0,\n to: e instanceof FormulaError ? e.to : 1,\n },\n ];\n }\n}\n/** The threshold of `AggregationClause.minCount` in either form. */\nexport function metricMinCount(\n c: { minCount?: AggregationClause[\"minCount\"] | undefined },\n): number | undefined {\n const m = c.minCount;\n return m === undefined ? undefined : typeof m === \"number\" ? m : m?.min;\n}\n/** What an object `minCount` measures: the aggregate whose value per group\n * must reach `min`. Undefined when `minCount` counts rows. */\nexport function metricMinCountMeasure(\n c: { minCount?: AggregationClause[\"minCount\"] | undefined },\n): { op: \"count_distinct\" | \"sum\"; field: string } | undefined {\n const m = c.minCount;\n if (m === undefined || m === null || typeof m !== \"object\") return undefined;\n return m.distinct !== undefined\n ? { op: \"count_distinct\", field: m.distinct }\n : { op: \"sum\", field: m.sum! };\n}\n/** A minimum in words: \"3 rows\", \"5 distinct Conversation values\" or\n * \"10 total Calls\". `label` names a field (default: its name). */\nexport function metricMinCountText(\n c: { minCount?: AggregationClause[\"minCount\"] | undefined },\n label: (field: string) => string = (field) => field,\n): string | undefined {\n const min = metricMinCount(c),\n measure = metricMinCountMeasure(c);\n if (min === undefined) return undefined;\n const n = min.toLocaleString();\n if (!measure) return `${n} ${min === 1 ? \"row\" : \"rows\"}`;\n return measure.op === \"sum\"\n ? `${n} total ${label(measure.field)}`\n : `${n} distinct ${label(measure.field)} ${min === 1 ? \"value\" : \"values\"}`;\n}\n/** The aggregate plan of an object `minCount`, such as SUM([calls]). */\nexport function metricMinCountPlan(\n c: { minCount?: AggregationClause[\"minCount\"] | undefined },\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): MetricPlan | undefined {\n const measure = metricMinCountMeasure(c);\n return measure\n ? compileMetric(\n metricExpression({\n id: \"\",\n groupBy: [],\n op: measure.op,\n field: resolveFieldName(schema, measure.field) ?? measure.field,\n }),\n schema,\n resolve,\n )\n : undefined;\n}\n/** Whether a group survives `minCount`. Calendar fill-ins (no rows) always do.\n * Otherwise the row count, or for an object `minCount` the group's measure\n * (null counts as 0), must reach `min`. A measure that is an error keeps its\n * group, so the error stays visible. */\nexport function metricMinCountKeeps(\n min: number,\n count: number,\n measure?: { value: unknown; error?: string | undefined },\n): boolean {\n if (count === 0) return true;\n if (!measure) return count >= min;\n return measure.error !== undefined || Number(measure.value ?? 0) >= min;\n}\n/** A row-count minimum, or exactly one of a distinct or summed schema field. */\nfunction validateMinCount(c: AggregationClause, schema: FieldSchema): void {\n const m = c.minCount as unknown;\n const measured = m !== null && typeof m === \"object\";\n const min = measured ? (m as { min?: unknown }).min : m;\n const label = measured ? \"Minimum per group\" : \"Minimum rows per group\";\n if (\n typeof min !== \"number\" ||\n !Number.isInteger(min) ||\n min < 1 ||\n min > 1000000\n )\n throw new FormulaError(`${label} must be 1–1,000,000.`);\n if (measured) {\n const o = m as Record<string, unknown>;\n if (\n Object.keys(o).some((k) => ![\"min\", \"distinct\", \"sum\"].includes(k)) ||\n (o.distinct === undefined) === (o.sum === undefined)\n )\n throw new FormulaError(\n \"A minimum per group needs exactly one of distinct and sum.\",\n );\n const name = o.distinct ?? o.sum;\n const op = o.distinct !== undefined ? \"count_distinct\" : \"sum\";\n const resolved =\n typeof name === \"string\" ? (resolveFieldName(schema, name) ?? name) : \"\";\n const field = schema.fields.find((f) => f.name === resolved);\n if (op === \"sum\" && field && field.type !== \"number\")\n throw new FormulaError(\n `A summed minimum requires a numeric field, not ${resolved}.`,\n );\n if (\n !field ||\n isComputedField(resolved) ||\n !isMeasurable(field) ||\n !aggOpsForField(field).includes(op)\n )\n throw new FormulaError(\n op === \"sum\"\n ? `Field ${String(name)} cannot be summed for a minimum per group.`\n : `Field ${String(name)} cannot count distinct values for a minimum per group.`,\n );\n if (distributionActive(c))\n throw new FormulaError(\n \"A distinct or summed minimum currently supports scalar metrics, not distributions.\",\n );\n if (c.window && op === \"count_distinct\")\n throw new FormulaError(\n \"A distinct minimum cannot be combined across a window's intervals.\",\n );\n if (c.dateGrouping?.occurrence)\n throw new FormulaError(\n \"A distinct or summed minimum does not apply to occurrences of a slot; use a minimum of rows.\",\n );\n }\n if (!c.groupBy.length)\n throw new FormulaError(`${label} requires at least one grouping field.`);\n}\n/** A metric WHERE follows the table WHERE's allowlist and operators. Regex is\n * refused on every engine; local computed inputs need filter authority. */\nfunction validateMetricWhere(\n where: readonly WhereTerm[] | undefined,\n schema: FieldSchema,\n): void {\n if (where === undefined) return;\n if (!Array.isArray(where)) throw new FormulaError(\"Invalid metric filter.\");\n const predicates = where.flatMap((term) => predicatesOf(term));\n if (predicates.length > MAX_WHERE_CLAUSES)\n throw new FormulaError(\n `A metric filter allows at most ${MAX_WHERE_CLAUSES} predicates.`,\n );\n const fields = indexFields(schema);\n for (const p of predicates) {\n const name = resolveFieldName(schema, p.field) ?? p.field;\n const field = fields.get(name);\n if (\n !field ||\n !isFilterable(field) ||\n (isComputedField(name) && !computedInputAllowed(schema, name, \"filter\"))\n )\n throw new FormulaError(`Field ${p.field} cannot filter metrics.`);\n if (p.op === \"matches_regex\" || p.op === \"not_matches_regex\")\n throw new FormulaError(\"Regex is unavailable in metric filters.\");\n if (!opsForField(field).includes(p.op))\n throw new FormulaError(\n `Field ${p.field} does not support the ${p.op} filter.`,\n );\n }\n}\n/** Executor support for population controls, from either capability handshake. */\nexport interface MetricPopulationSupport {\n filters?: boolean | undefined;\n minCount?: boolean | undefined;\n /** A `minCount` object: distinct values or a sum of a field. */\n minCountMeasures?: boolean | undefined;\n}\n/** A clause the executor cannot run exactly gets its own error; it is never\n * sent with `where`/`minCount` silently dropped. */\nexport function metricPopulationError(\n clause: Pick<AggregationClause, \"where\" | \"minCount\">,\n support: MetricPopulationSupport,\n): string | undefined {\n if (clause.where?.length && !support.filters)\n return \"This server does not support metric filters.\";\n if (clause.minCount !== undefined && !support.minCount)\n return \"This server does not support a minimum rows per group.\";\n if (metricMinCountMeasure(clause) && !support.minCountMeasures)\n return \"This server does not support a minimum of distinct values or a sum per group.\";\n return undefined;\n}\nexport function metricDependencies(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): string[] {\n return [\n ...new Set([\n ...c.groupBy.map((name) => resolveFieldName(schema, name) ?? name),\n ...metricPlans(c, schema, resolve).flatMap((p) => p.dependencies),\n // An invalid minimum fails validation, not dependency discovery.\n ...((() => {\n try {\n return metricMinCountPlan(c, schema, resolve)?.dependencies;\n } catch {\n return undefined;\n }\n })() ?? []),\n ]),\n ].sort();\n}\nexport function metricComputationKey(\n clauses: readonly AggregationClause[],\n): string {\n return JSON.stringify(\n clauses\n .map((c) => ({\n id: c.id,\n diagnostics: c.diagnostics,\n unsupportedOp: c.unsupportedOp,\n expression:\n distributionActive(c) && !occurrenceDistribution(c)\n ? undefined\n : metricExpression(c),\n expressionY: c.display?.kind === \"scatter\" ? c.expressionY : undefined,\n scope: c.scope ?? \"allMatching\",\n groupBy: c.groupBy,\n dateGrouping: c.dateGrouping,\n sort: c.sort,\n groupLimit: c.groupLimit,\n where: c.where,\n minCount: c.minCount,\n window: c.window,\n share: c.share,\n distribution: distributionActive(c) ? c.distribution : undefined,\n }))\n .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)),\n );\n}\nexport function toMetricQuery<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution?: ComputedExecution,\n): MetricQuery {\n const originalSchema = schema;\n const fields = new Map(schema.fields.map((f) => [f.name, f]));\n // A local computed field never establishes remote authority.\n for (const [name, prior] of fields)\n if (isComputedField(name))\n fields.set(name, {\n ...prior,\n aggregate: { measure: false, groupable: false },\n });\n for (const [name, cap] of Object.entries(execution?.fields ?? {}))\n if (isComputedField(name)) {\n const prior = fields.get(name);\n fields.set(name, {\n ...prior,\n name,\n label: prior?.label ?? name,\n type: cap.type,\n source: { kind: \"backend\" },\n filter: { enabled: false },\n sort: { enabled: cap.sort },\n aggregate: {\n ...prior?.aggregate,\n measure: cap.measure,\n groupable: cap.group,\n },\n });\n }\n schema = { ...schema, fields: [...fields.values()] };\n const raw = q;\n q = normalizeQueryState(q);\n const server = toServerQuery(q, schema);\n const metricWhere = new Map<string, WhereTerm[]>();\n for (const c of q.aggregations ?? [])\n if (c.where?.length) {\n const pushed = toServerQuery({ ...EMPTY_QUERY, where: c.where }, schema)\n .where;\n metricWhere.set(c.id, pushed);\n }\n const metrics = (q.aggregations ?? []).map((c) => {\n const {\n label,\n layout,\n display,\n distribution,\n expression,\n expressionY,\n dateGrouping,\n where,\n window: _window,\n share: _share,\n ...rest\n } = c;\n return {\n ...rest,\n ...(where?.length ? { where: metricWhere.get(c.id) ?? [] } : {}),\n ...(!distributionActive(c) && expression !== undefined\n ? { expression }\n : {}),\n ...(display?.kind === \"scatter\"\n ? {\n display: { kind: \"scatter\" as const },\n ...(expressionY !== undefined ? { expressionY } : {}),\n }\n : {}),\n ...(distributionActive(c) && distribution ? { distribution } : {}),\n };\n });\n const diagnostics = (q.aggregations ?? []).flatMap((c) =>\n validateMetric(c, schema).map((d) => ({\n ...d,\n metricId: c.id,\n code: \"invalid_metric\",\n })),\n );\n for (const c of q.aggregations ?? [])\n if (c.where?.length && metricWhere.get(c.id)?.length !== c.where.length)\n diagnostics.push({\n metricId: c.id,\n code: \"residual_metric_filter\",\n from: 0,\n to: 1,\n message: \"Metric filters must use server-filterable fields.\",\n });\n // Servers never compute windows, shares, whole intervals or occurrences; sending the\n // clause unexpanded would silently return the plain metric.\n for (const c of q.aggregations ?? [])\n if (hasMetricSeries(c))\n diagnostics.push({\n metricId: c.id,\n code: \"unexpanded_series\",\n from: 0,\n to: 1,\n message:\n \"Windows, shares, whole intervals and occurrences are computed from plain metrics; expand the query with planMetricSeries first.\",\n });\n for (const c of q.aggregations ?? [])\n if (c.dateGrouping)\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_date_grouping\",\n from: 0,\n to: 1,\n message: \"Date grouping currently requires local metric execution.\",\n });\n try {\n assertMetricQueryState(raw, originalSchema);\n } catch (e) {\n diagnostics.push({\n message: String(e),\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"invalid_query\",\n });\n }\n const ids = new Set<string>();\n for (const c of q.aggregations ?? []) {\n if (ids.has(c.id))\n diagnostics.push({\n message: \"Duplicate metric ID.\",\n from: 0,\n to: 1,\n metricId: c.id,\n code: \"duplicate_metric\",\n });\n ids.add(c.id);\n }\n if (\n server.where.length !== q.where.length ||\n queryStateKey(raw.where) !== queryStateKey(q.where)\n )\n diagnostics.push({\n message: \"Metrics unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"residual_filter\",\n });\n for (const c of q.aggregations ?? []) {\n try {\n for (const name of metricDependencies(c, schema))\n if (isComputedField(name)) {\n const revision =\n execution?.resolvedRevisions[name] ??\n execution?.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (\n typeof revision !== \"string\" ||\n !revision ||\n revision.length > 256\n )\n diagnostics.push({\n metricId: c.id,\n code: \"definition_revision\",\n message: `Missing expected revision for ${name}.`,\n from: 0,\n to: 1,\n });\n if (!execution?.fields[name])\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_computed\",\n message: `Missing server capability for ${name}.`,\n from: 0,\n to: 1,\n });\n }\n } catch {\n /* compilation diagnostic already included */\n }\n }\n // Row and metric page membership share effective defaults and v2 gates.\n const rowProjection = toServerQueryV2(\n { ...q, select: [{ field: schema.idField }] },\n originalSchema,\n execution ?? {\n profile: \"\",\n planToken: \"\",\n fields: {},\n resolvedRevisions: {},\n },\n );\n if (q.aggregations?.some((c) => c.scope === \"shownRows\"))\n diagnostics.push(\n ...rowProjection.diagnostics.map((d) => ({\n ...d,\n metricId: \"\",\n code: d.code ?? \"residual_order\",\n })),\n );\n return {\n version: 2,\n where: server.where,\n orderBy: rowProjection.orderBy,\n limit: q.limit,\n offset: q.offset,\n metrics,\n diagnostics,\n ...(execution\n ? {\n profile: execution.profile,\n expectedRevisions: { ...execution.resolvedRevisions },\n planToken: execution.planToken,\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n }\n : {}),\n };\n}\nfunction queryStateKey(value: unknown): string | undefined {\n return JSON.stringify(value, (_key, item: unknown) =>\n item && typeof item === \"object\" && !Array.isArray(item)\n ? Object.fromEntries(\n Object.entries(item).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n )\n : item,\n );\n}\n/** Reject normalization losses before claiming an exact population. */\nfunction assertMetricQueryState<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n): void {\n const normalized = normalizeQueryState(q);\n if ((q.aggregations?.length ?? 0) !== (normalized.aggregations?.length ?? 0))\n throw Error(\"Malformed metric definitions cannot be dropped.\");\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n const normalizedOrder = normalizeQueryState({ ...q, orderBy }).orderBy;\n if (\n queryStateKey(q.where) !== queryStateKey(normalized.where) ||\n queryStateKey(orderBy) !== queryStateKey(normalizedOrder) ||\n q.limit !== normalized.limit ||\n q.offset !== normalized.offset\n )\n throw Error(\"Malformed metric query state cannot be executed exactly.\");\n}\n/** Safe pre-worker page selection. A supplied committed page needs no query execution.\n * Query regex is never executed here; all-matching regex filtering is unsupported. */\nexport function selectMetricShownRows<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): Row[] {\n if (options.signal?.aborted) throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if (options.shownRows) return options.shownRows;\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n assertMetricPopulation(q, schema, orderBy);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n if ((options.maxOperations ?? 10000000) <= 0)\n throw Error(\"Metric operation budget exceeded.\");\n return applyQuery(\n rows,\n // Local tables use a stable sort: ties retain input order. An extra ID\n // sort here would choose a different page than the one the table shows.\n { ...q, orderBy },\n schema,\n options,\n ).rows;\n}\nfunction assertMetricPopulation<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n orderBy: QueryState[\"orderBy\"],\n): void {\n const fields = indexFields(schema);\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n ) ||\n orderBy.some((s) => s.extract !== undefined)\n )\n throw Error(\n \"Query regex requires isolated execution; unavailable for metric population selection.\",\n );\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) =>\n isComputedField(p.field) && !computedInputAllowed(schema, p.field, \"filter\") ||\n !fields.has(resolveFieldName(schema, p.field) ?? p.field),\n ),\n )\n )\n throw Error(\"Metric filter references an unavailable field.\");\n if (\n orderBy.some(\n (s) =>\n isComputedField(s.field) && !computedInputAllowed(schema, s.field, \"sort\") ||\n !fields.has(resolveFieldName(schema, s.field) ?? s.field),\n )\n )\n throw Error(\"Shown-row ordering requires an authoritative committed page.\");\n}\nexport interface MetricEvaluationOptions<Row = unknown>\n extends QueryEvaluationOptions,\n MetricReductionOptions {\n resolveComputed?: (name: string) => FormulaPlan | undefined;\n /** Called only for regex row ASTs, using cached results from a terminable worker. */\n evaluateInput?: (\n node: FormulaNode,\n row: Row,\n plan: FormulaPlan,\n ) => FormulaResult;\n /** Exact committed page supplied by the host after filters/order/window. */\n /** Escaped tuple length bound, in UTF-16 code units (default 65,536). */\n maxGroupKeyLength?: number;\n /** Retained group keys, map/bucket overhead and row references, plus key scratch space (default 16 MB). */\n maxGroupBytes?: number;\n shownRows?: Row[];\n maxRows?: number;\n maxGroups?: number;\n /** Per-metric operation budget (default 10,000,000, allowing simple paired\n * aggregates across the default one-million-row population limit). */\n maxOperations?: number;\n /** @deprecated Regex requires cached evaluateInput; this flag grants no execution permission. */ allowRegex?: boolean;\n signal?: AbortSignal;\n}\nconst scalar = (v: unknown): MetricValue => {\n if (v instanceof Date) return v.toISOString();\n if (v == null) return null;\n if (\n typeof v === \"string\" ||\n typeof v === \"boolean\" ||\n (typeof v === \"number\" && Number.isFinite(v))\n )\n return v;\n throw Error(\"Metric keys and values must be finite scalars.\");\n};\n/** JSON string length without allocating escaped text; scan only bounded input. */\nfunction groupStringLength(value: string, limit: number): number {\n let length = value.length + 2;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (\n code === 34 ||\n code === 92 ||\n code === 8 ||\n code === 9 ||\n code === 10 ||\n code === 12 ||\n code === 13\n )\n length++;\n else if (code < 32) length += 5;\n else if (\n code >= 0xd800 &&\n code <= 0xdbff &&\n i + 1 < value.length &&\n value.charCodeAt(i + 1) >= 0xdc00 &&\n value.charCodeAt(i + 1) <= 0xdfff\n )\n i++;\n else if (code >= 0xd800 && code <= 0xdfff) length += 5;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n return length;\n}\n/** Typed lexicographic ordering with null placement independent of direction. */\nexport function compareMetricValues(a: MetricValue, b: MetricValue): number {\n if (a === b) return 0;\n if (a === null) return 1;\n if (b === null) return -1;\n if (typeof a !== typeof b) return typeof a < typeof b ? -1 : 1;\n if (typeof a === \"string\" && typeof b === \"string\") {\n const ac = Array.from(a),\n bc = Array.from(b);\n for (let i = 0; i < Math.min(ac.length, bc.length); i++) {\n const diff = ac[i]!.codePointAt(0)! - bc[i]!.codePointAt(0)!;\n if (diff) return Math.sign(diff);\n }\n return Math.sign(ac.length - bc.length);\n }\n return a < b ? -1 : 1;\n}\n/** Order buckets as a metric result: errors last, then `clause.sort`\n * (chronological for calendar groups, largest value first otherwise), then keys. */\nexport function sortMetricBuckets(\n buckets: AggregationBucket[],\n c: Pick<AggregationClause, \"sort\" | \"dateGrouping\">,\n): AggregationBucket[] {\n const ordering: MetricSort[] = c.sort?.length\n ? c.sort\n : c.dateGrouping\n ? [{ key: \"group0\", dir: \"asc\", nulls: \"last\" }]\n : [{ key: \"value\", dir: \"desc\", nulls: \"last\" }];\n const target = (b: AggregationBucket, s: MetricSort): MetricValue =>\n s.key === \"samples\"\n ? b.count - (b.nullCount ?? 0) - (b.inputErrorCount ?? 0)\n : s.key.startsWith(\"group\")\n ? (b.keys[Number(s.key.slice(5))] ?? null)\n : s.key === \"count\"\n ? b.count\n : s.key === \"y\"\n ? (b.y ?? null)\n : b.value;\n return buckets.sort((a, b) => {\n if (!!(a.error || a.yError) !== !!(b.error || b.yError))\n return a.error || a.yError ? 1 : -1;\n for (const s of ordering) {\n const av = target(a, s),\n bv = target(b, s);\n const cmp =\n av === null || bv === null\n ? av === bv\n ? 0\n : (av === null ? 1 : -1) * (s.nulls === \"first\" ? -1 : 1)\n : compareMetricValues(av, bv) * (s.dir === \"asc\" ? 1 : -1);\n if (cmp) return cmp;\n }\n for (let i = 0; i < a.keys.length; i++) {\n const cmp = compareMetricValues(a.keys[i]!, b.keys[i]!);\n if (cmp) return cmp;\n }\n return 0;\n });\n}\nexport function evaluateMetrics<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) {\n try {\n if (options.signal?.aborted) throw new Error(\"Metric evaluation cancelled.\");\n if (rows.length > (options.maxRows ?? 1_000_000)) throw new Error(\"Metric row budget exceeded.\");\n const now = evaluationTime(options);\n const prepared = prepareGrouping(rows, schema, q.grouping, { now });\n return evaluateMetrics(prepared.rows, withoutGrouping(q), prepared.schema, {\n ...options, now,\n } as unknown as MetricEvaluationOptions<GroupedRow>);\n } catch (error) {\n return { metrics: (q.aggregations ?? []).map(metric => ({ id: metric.id, buckets: [], error: error instanceof Error ? error.message : String(error) })) };\n }\n }\n const now = evaluationTime(options),\n fields = indexFields(schema);\n const series = planMetricSeries(q, schema, {\n now,\n ...(options.resolveComputed ? { resolveComputed: options.resolveComputed } : {}),\n });\n if (series)\n return {\n metrics: series.combine(\n series.queries.flatMap(\n (part) => evaluateMetrics(rows, part, schema, { ...options, now }).metrics,\n ),\n ),\n };\n let matching: Row[] | undefined;\n let shown: Row[] | undefined;\n return {\n metrics: (q.aggregations ?? []).map((c) => {\n let budget = options.maxOperations ?? 10000000;\n const tick = () => {\n if (--budget < 0) throw Error(\"Metric operation budget exceeded.\");\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n };\n try {\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if ((q.aggregations?.length ?? 0) > 20)\n throw Error(\"At most 20 metrics are allowed.\");\n const diagnostics = validateMetric(c, schema, options.resolveComputed);\n if (diagnostics.length)\n throw Error(diagnostics.map((d) => d.message).join(\" \"));\n const ps = metricPlans(c, schema, options.resolveComputed);\n if (ps.some(hasRegex) && !options.evaluateInput)\n throw Error(\n \"Regex metrics require an isolated worker with a watchdog.\",\n );\n let inputRows: Row[];\n if (c.scope === \"shownRows\")\n inputRows = shown ??= selectMetricShownRows(rows, q, schema, options);\n else {\n if (!matching) {\n assertMetricPopulation(q, schema, []);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n matching = applyQuery(\n rows,\n { ...q, orderBy: [], offset: 0, limit: Number.MAX_SAFE_INTEGER },\n schema,\n { now },\n ).rows;\n }\n inputRows = matching;\n }\n if (inputRows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n // processedRows retains the scope population; this metric's own\n // predicate narrows the rows it reduces, inside a shown page as well.\n const population = inputRows.length;\n if (c.where?.length)\n inputRows = applyQuery(\n inputRows,\n {\n ...EMPTY_QUERY,\n where: c.where,\n limit: Number.MAX_SAFE_INTEGER,\n },\n schema,\n { now },\n ).rows;\n const groups = new Map<string, { keys: MetricValue[]; rows: Row[] }>();\n const keyLimit = options.maxGroupKeyLength ?? 65536,\n byteLimit = options.maxGroupBytes ?? 16000000;\n if (\n ![keyLimit, byteLimit].every((v) => Number.isSafeInteger(v) && v >= 0)\n )\n throw Error(\"Invalid grouping budget.\");\n let groupBytes = 0;\n const reserve = (bytes: number) => {\n if (bytes > byteLimit - groupBytes)\n throw Error(\"Metric grouping retained-memory budget exceeded.\");\n };\n if (!c.groupBy.length) {\n if (keyLimit < 2)\n throw Error(\"Metric grouping key length budget exceeded.\");\n reserve(256);\n groupBytes = 256;\n groups.set(\"[]\", { keys: [], rows: [] });\n }\n // Retain only the most recent calendar interval. Dense timestamp rows\n // share its boundaries and ISO key without repeating timezone work.\n // The half-open interval also separates repeated/partial DST hours;\n // out-of-order rows outside it always recompute the correct bucket.\n let dateStart = Infinity,\n dateEnd = -Infinity,\n dateKey: MetricValue = \"\";\n let dateInput: MetricValue | undefined,\n dateTime = NaN;\n for (const row of inputRows) {\n tick();\n if (!c.groupBy.length) {\n reserve(16);\n groupBytes += 16;\n groups.get(\"[]\")!.rows.push(row);\n continue;\n }\n const keys = c.groupBy.map((k) =>\n scalar(\n readFieldValue(\n fields.get(resolveFieldName(schema, k) ?? k)!,\n row,\n ),\n ),\n );\n if (c.dateGrouping && keys[0] !== null) {\n const config = c.dateGrouping;\n // Repeated date-only values would otherwise resolve local midnight\n // through Temporal for every row as well.\n if (keys[0] !== dateInput) {\n dateTime = metricDateTime(keys[0]!, config.timeZone);\n dateInput = keys[0];\n }\n if (dateTime < dateStart || dateTime >= dateEnd) {\n dateStart = metricDateFloor(\n dateTime,\n config.interval,\n config.timeZone,\n );\n dateEnd = metricDateNext(\n dateStart,\n config.interval,\n config.timeZone,\n );\n // A cyclic slot is the local hour or weekday of the interval\n // its record falls in; a calendar key is the interval start.\n dateKey = isMetricCycle(config.interval)\n ? metricCycleSlot(dateStart, config.interval, config.timeZone)\n : new Date(dateStart).toISOString();\n }\n keys[0] = dateKey;\n }\n // Measure escaping without allocating a serialized key. Check BEFORE\n // stringify: shared source strings must not amplify into unbounded map keys. Charge source payload again\n // per group, even if shared, plus tuple slots, buckets and map overhead.\n let keyLength = 1,\n payloadBytes = 0;\n for (const value of keys) {\n keyLength +=\n 1 +\n (typeof value === \"string\"\n ? groupStringLength(value, keyLimit - keyLength - 1)\n : value === null\n ? 4\n : typeof value === \"boolean\"\n ? value\n ? 4\n : 5\n : String(value).length);\n payloadBytes += typeof value === \"string\" ? 2 * value.length : 8;\n if (keyLength > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n const retainedBytes =\n 256 + 16 * keys.length + payloadBytes + 2 * keyLength;\n // Reserve a candidate group plus serialization scratch, even for a\n // duplicate; this deliberately conservative check needs no large key.\n reserve(retainedBytes + 2 * keyLength + 16);\n const key = JSON.stringify(keys);\n let g = groups.get(key);\n if (!g) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n g = { keys, rows: [] };\n groups.set(key, g);\n groupBytes += retainedBytes;\n }\n groupBytes += 16;\n g.rows.push(row);\n }\n if (c.dateGrouping?.includeEmpty) {\n const config = c.dateGrouping;\n const observed: number[] = [];\n const series = new Map<string, MetricValue[]>();\n for (const group of groups.values())\n if (group.keys[0] !== null) {\n tick();\n reserve(8);\n groupBytes += 8;\n if (!isMetricCycle(config.interval))\n observed.push(metricDateTime(group.keys[0]!));\n const tuple = group.keys.slice(1);\n const key = JSON.stringify(tuple);\n if (!series.has(key)) {\n const bytes = 128 + 16 * tuple.length + 2 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n series.set(key, tuple);\n }\n }\n if (c.groupBy.length === 1 && !series.size) {\n reserve(132);\n groupBytes += 132;\n series.set(\"[]\", []);\n }\n // Every slot of a cycle exists, whatever the date range.\n const slots = isMetricCycle(config.interval)\n ? metricCycleSlots(config.interval)\n : undefined;\n for (const slot of slots ?? [])\n for (const tuple of series.values()) {\n tick();\n const keys: MetricValue[] = [slot, ...tuple];\n const key = JSON.stringify(keys);\n if (key.length > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n if (!groups.has(key)) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n const bytes = 256 + 16 * keys.length + 4 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n groups.set(key, { keys, rows: [] });\n }\n }\n const range = slots\n ? undefined\n : metricDateRange(\n config,\n q,\n observed,\n now,\n (name) => resolveFieldName(schema, name) ?? name,\n );\n if (range)\n for (let time = range[0]; time <= range[1]; ) {\n tick();\n for (const tuple of series.values()) {\n tick();\n const keys: MetricValue[] = [\n new Date(time).toISOString(),\n ...tuple,\n ];\n const key = JSON.stringify(keys);\n if (key.length > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n if (!groups.has(key)) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n const bytes = 256 + 16 * keys.length + 4 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n groups.set(key, { keys, rows: [] });\n }\n }\n const next = metricDateNext(\n time,\n config.interval,\n config.timeZone,\n );\n if (!Number.isFinite(next) || next <= time)\n throw Error(\"Date grouping exceeds calendar limits.\");\n time = next;\n }\n }\n const inputs = (\n row: Row,\n p: FormulaPlan,\n ): Record<string, FormulaValue> =>\n Object.fromEntries(\n p.dependencies.map((name) => [\n name,\n (() => {\n const value = readFieldValue(fields.get(name)!, row);\n return value instanceof Date\n ? value.toISOString()\n : (value ?? null);\n })(),\n ]),\n ) as Record<string, FormulaValue>;\n const nodeCosts = new Map<FormulaNode, number>();\n const cost = (n: FormulaNode): number => {\n const known = nodeCosts.get(n);\n if (known !== undefined) return known;\n const value =\n 1 +\n (n.kind === \"call\" ? n.args.reduce((s, a) => s + cost(a), 0) : 0);\n nodeCosts.set(n, value);\n return value;\n };\n const rowEval = (node: FormulaNode, row: Row, p: FormulaPlan) => {\n budget -= cost(node);\n tick();\n // A direct aggregate input needs only its own binding, even when the\n // composed metric reaches many other fields. Keep runtime validation.\n if (node.kind === \"field\") {\n const value = readFieldValue(fields.get(node.name)!, row);\n return formulaRuntime(node, {\n [node.name]:\n value instanceof Date\n ? value.toISOString()\n : ((value ?? null) as FormulaValue),\n });\n }\n return options.evaluateInput && hasRegex({ ...p, ast: node })\n ? options.evaluateInput(node, row, p)\n : formulaRuntime(node, inputs(row, p));\n };\n const reduce = (\n p: FormulaPlan,\n rs: Row[],\n inputErrors: Set<number>,\n ): FormulaResult => {\n const cache = new Map<FormulaNode, FormulaResult>();\n return checkedMetricResult(\n formulaRuntime(p.ast, {}, (node) => {\n if (!aggregates.has(node.name)) return undefined;\n if (cache.has(node)) return cache.get(node)!;\n let result: FormulaResult;\n try {\n function* results(): Generator<FormulaResult> {\n for (let i = 0; i < rs.length; i++) {\n tick();\n const v = node.args[0]\n ? rowEval(node.args[0], rs[i]!, p)\n : { value: 1 };\n if (v.error) inputErrors.add(i);\n yield v;\n }\n }\n result = reduceResults(node, results(), options);\n } catch (e) {\n result = {\n value: null,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n cache.set(node, result);\n return result;\n }),\n );\n };\n const populations = new Map<AggregationBucket, number[]>();\n // An object minCount measures each group with its own aggregate, with\n // the same semantics as that aggregate in a metric expression.\n const minPlan = metricMinCountPlan(c, schema, options.resolveComputed);\n const measures = new Map<AggregationBucket, FormulaResult>();\n let buckets: AggregationBucket[] = [...groups.values()].map((g) => {\n const bucket: AggregationBucket = {\n keys: g.keys,\n count: g.rows.length,\n value: null,\n };\n if (minPlan && g.rows.length)\n measures.set(bucket, reduce(minPlan, g.rows, new Set()));\n if (distributionActive(c)) {\n const values: number[] = [];\n bucket.nullCount = 0;\n bucket.inputErrorCount = 0;\n for (const row of g.rows) {\n const r = checkedMetricResult(rowEval(ps[0]!.ast, row, ps[0]!));\n if (r.error) {\n bucket.inputErrorCount++;\n bucket.error = r.error;\n } else if (r.value === null) bucket.nullCount++;\n else values.push(Number(r.value));\n }\n populations.set(bucket, values);\n } else {\n if (c.dateGrouping && !g.rows.length) {\n const empty = (p: FormulaPlan) =>\n p.ast.kind === \"call\" &&\n [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\"].includes(p.ast.name)\n ? 0\n : null;\n bucket.value = empty(ps[0]!);\n if (ps[1]) bucket.y = empty(ps[1]);\n return bucket;\n }\n const inputErrors = new Set<number>();\n const x = reduce(ps[0]!, g.rows, inputErrors);\n bucket.value = scalar(x.value);\n if (x.error) bucket.error = x.error;\n if (ps[1]) {\n const y = reduce(ps[1], g.rows, inputErrors);\n bucket.y = scalar(y.value);\n if (y.error) bucket.yError = y.error;\n }\n if (inputErrors.size) bucket.inputErrorCount = inputErrors.size;\n }\n return bucket;\n });\n if (distributionActive(c)) {\n const d = c.distribution!;\n if (d.kind === \"histogram\" && buckets.some((b) => b.error))\n throw Error(\n \"Histogram input errors prevent an exact shared extent.\",\n );\n const all: number[] = [];\n for (const values of populations.values())\n for (const v of values) all.push(v);\n const edges =\n d.kind === \"histogram\" ? histogramEdges(all, d.bins ?? 10) : [];\n for (const b of buckets) {\n const vs = populations.get(b)!;\n if (b.error) continue;\n if (d.kind === \"box\") {\n const summary = boxSummary(vs, d.whiskers);\n b.distribution = { kind: \"box\", summary };\n b.value = summary?.median ?? null;\n } else {\n b.distribution = {\n kind: \"histogram\",\n edges: [...edges],\n counts: histogramCounts(vs, edges),\n n: vs.length,\n };\n b.value = vs.length;\n }\n }\n }\n // Calendar fill-ins are the only empty groups; they are never hidden.\n // Hidden groups leave the ranking, the result limit and Other.\n let hiddenGroups: number | undefined;\n const min = metricMinCount(c);\n if (min !== undefined) {\n const kept = buckets.filter((b) =>\n metricMinCountKeeps(min, b.count, minPlan ? measures.get(b) : undefined),\n );\n hiddenGroups = buckets.length - kept.length;\n buckets = kept;\n }\n sortMetricBuckets(buckets, c);\n tick();\n const groupCount = buckets.length;\n let other: AggregationBucket | undefined;\n if (c.groupLimit && buckets.length > c.groupLimit) {\n const omitted = buckets.slice(c.groupLimit),\n ast = ps[0]!.ast;\n if (\n !distributionActive(c) &&\n ast.kind === \"call\" &&\n [\"SUM\", \"COUNT\"].includes(ast.name) &&\n omitted.every(\n (b) =>\n !b.error &&\n (typeof b.value === \"number\" ||\n (ast.name === \"SUM\" && b.value === null)),\n )\n ) {\n const value = omitted.reduce((s, b) => s + Number(b.value), 0);\n if (\n Number.isFinite(value) &&\n (!Number.isInteger(value) || Number.isSafeInteger(value))\n )\n other = {\n keys: [],\n value,\n count: omitted.reduce((s, b) => s + b.count, 0),\n };\n }\n buckets = buckets.slice(0, c.groupLimit);\n }\n return {\n id: c.id,\n buckets,\n scope: c.scope ?? \"allMatching\",\n processedRows: population,\n groupCount,\n coverage: \"exact\" as const,\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n ...(other ? { other } : {}),\n };\n } catch (e) {\n return {\n id: c.id,\n buckets: [],\n error: e instanceof Error ? e.message : String(e),\n };\n }\n }),\n };\n}\n","import { aggOpsForField, isMeasurable } from \"./agg\";\nimport type { MetricKey } from \"./metricTypes\";\nimport { evaluateMetrics, type MetricEvaluationOptions } from \"./metrics\";\nimport { hasMetricSeries } from \"./metricSeries\";\n// apply.ts — client-side filter + multi-sort + paginate.\n//\n// applyQuery is the client mirror of the backend compiler. Three jobs:\n// 1. The executor for purely client-side datasets (no backend at all).\n// 2. The executor for derived / non-pushdown columns the backend can't filter.\n// 3. Idempotent defense-in-depth over server-filtered fields (re-applying a\n// server-handled clause must not change the result).\n//\n// It must agree with backends/go's Compile on operator semantics:\n// - `contains`/`starts_with`/`ends_with` are case-insensitive\n// - textarray `is_null` = empty-or-missing; `is_not_null` = any element;\n// `includes` = case-insensitive membership\n// - NULLs sort per OrderByClause.nulls (default \"last\")\n// - multi-sort is a stable lexicographic fold over orderBy in priority order\n\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport { isComputedField } from \"./computed\";\nimport type {\n AggOp,\n AggregationClause,\n QueryState,\n WhereClause,\n WhereTerm,\n} from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { AggregationBucket, AggregationResult } from \"./encode\";\nimport { indexFields, readFieldValue, resolveFieldName } from \"./schema\";\nimport { branchesOf, predicatesOf, normalizeQueryState } from \"./query\";\nimport { coerceValue } from \"./ops\";\nimport { prepareGrouping, withoutGrouping } from \"./grouping\";\n\nexport interface ApplyResult<Row> {\n /** The page slice (after filter + sort + offset/limit). */\n rows: Row[];\n /** Total matching rows *before* pagination — powers \"showing N of M\". */\n total: number;\n}\n\n/** Filter + multi-sort + paginate `rows` per `q`, resolving field types/paths\n * from `schema`. Never mutates `rows`. Relative predicates use options.now or\n * one captured Date.now(). Clauses/sorts on unknown fields are\n * ignored (the backend already enforced its own allowlist). */\nexport function applyQuery<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): ApplyResult<Row> {\n const now = evaluationTime(options);\n if (q.grouping) {\n const grouped = prepareGrouping(rows, schema, q.grouping, { now });\n // Grouped results are projections described by grouped.schema; they do not\n // retain source-row accessors or identities.\n return applyQuery(grouped.rows, withoutGrouping(q), grouped.schema, { now }) as ApplyResult<Row>;\n }\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n // Terms touching a computed column are dropped here (the formula engine\n // evaluates those separately; `byName` has no opinion on them anyway). An OR\n // group is all-or-nothing, so a single computed member drops the whole term.\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field) && !computedInputAllowed(schema, c.field, \"filter\")))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const orderBy = q.orderBy\n .filter((term) => !isComputedField(term.field) || computedInputAllowed(schema, term.field, \"sort\"))\n .map((term) => ({ ...term, field: resolveField(term.field) }));\n\n let out = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const total = out.length;\n\n if (orderBy.length) {\n const terms = orderBy\n .map((t) => ({\n field: byName.get(t.field),\n dir: t.dir,\n nullsLast: (t.nulls ?? \"last\") === \"last\",\n extract: compileRegex(t.extract?.regex),\n }))\n .filter(\n (\n t,\n ): t is {\n field: FieldDef<Row>;\n dir: \"asc\" | \"desc\";\n nullsLast: boolean;\n extract: RegExp | null | undefined;\n } => t.field != null,\n );\n out = [...out].sort((a, b) => {\n for (const t of terms) {\n const av = extractSortValue(readFieldValue(t.field, a), t.extract);\n const bv = extractSortValue(readFieldValue(t.field, b), t.extract);\n const aNull = av == null;\n const bNull = bv == null;\n if (aNull || bNull) {\n if (aNull && bNull) continue;\n return (aNull ? 1 : -1) * (t.nullsLast ? 1 : -1);\n }\n const cmp = compare(av, bv);\n if (cmp !== 0) return t.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const start = q.offset > 0 ? q.offset : 0;\n const end = q.limit > 0 ? start + q.limit : out.length;\n return { rows: out.slice(start, end), total };\n}\n\n/** Explicit host bindings or approved evaluated accessors can participate in\n * local source stages. Ordinary unapproved computed controls stay disabled. */\nexport function computedInputAllowed(schema: FieldSchema, name: string, operation: \"filter\" | \"sort\"): boolean {\n const field = schema.fields.find(field => field.name === name);\n return !!field && (field.source.kind === \"backend\" && field[operation]?.enabled !== false || field[operation]?.enabled === true);\n}\n\n/** Does one row satisfy one clause? Exposed for the CellMenu preview + tests. */\nexport function matchesClause<Row>(\n row: Row,\n clause: WhereClause,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): boolean {\n const field = resolveFieldName(schema, clause.field) ?? clause.field;\n const byName = indexFields(schema);\n const prepared = prepareWhereClause(\n { ...clause, field },\n evaluationTime(options),\n );\n prepareDatetimePredicates([{ branches: [[prepared]] }], byName);\n return matchesWith(byName, row, prepared);\n}\n\n/** Client-side mirror of the backend GROUP BY (the executor for `clientRows`\n * mode / the demo). Scope matches the server contract: the WHERE-filtered set\n * only — ORDER BY / LIMIT / OFFSET are intentionally ignored, so a metric\n * reflects every matching row, not the visible page. Must agree with\n * backends/go's aggregate compile on op semantics. */\nexport function applyAggregations<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) return evaluateMetrics(rows, q, schema, options);\n if (\n options.signal?.aborted ||\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n )\n )\n return evaluateMetrics(rows, q, schema, options);\n const advanced = (q.aggregations ?? []).filter(\n (a) =>\n a.dateGrouping ||\n a.diagnostics?.length ||\n a.expression !== undefined ||\n a.expressionY !== undefined ||\n a.scope !== undefined ||\n a.distribution ||\n a.sort ||\n a.groupLimit !== undefined ||\n a.where !== undefined ||\n a.minCount !== undefined ||\n hasMetricSeries(a),\n );\n if (advanced.length) {\n // Partitioning must not hide invalid IDs/shapes or the query-wide card cap.\n if (\n (q.aggregations?.length ?? 0) > 20 ||\n normalizeQueryState(q).aggregations?.length !== q.aggregations?.length\n )\n return evaluateMetrics(rows, q, schema, options);\n const legacy = (q.aggregations ?? []).filter((a) => !advanced.includes(a));\n const results = [\n ...evaluateMetrics(\n rows,\n { ...q, aggregations: advanced },\n schema,\n options,\n ).metrics,\n ...(legacy.length\n ? applyAggregations(\n rows,\n { ...q, aggregations: legacy },\n schema,\n options,\n ).metrics\n : []),\n ];\n const byId = new Map(results.map((result) => [result.id, result]));\n return {\n metrics: (q.aggregations ?? []).flatMap((a) => byId.get(a.id) ?? []),\n };\n }\n const now = evaluationTime(options);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field)))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const filtered = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const metrics = (q.aggregations ?? [])\n .filter(\n (a) =>\n !isComputedField(a.field ?? \"\") && !a.groupBy.some(isComputedField),\n )\n .map((agg) => {\n const field = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n if (\n field &&\n (!isMeasurable(field) || !aggOpsForField(field).includes(agg.op))\n )\n return {\n id: agg.id,\n buckets: [],\n error: `Field ${field.name} does not allow ${agg.op}.`,\n };\n return {\n id: agg.id,\n buckets: computeBuckets(filtered, agg, byName, resolveField),\n };\n });\n return { metrics };\n}\n\nfunction computeBuckets<Row>(\n rows: Row[],\n agg: AggregationClause,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (field: string) => string,\n): AggregationBucket[] {\n // One slot per groupBy entry, preserving position. An unresolved field stays\n // in the array as `undefined` so every bucket's `keys` has exactly one element\n // per requested group field — the panel renders keys positionally against\n // `clause.groupBy`, so dropping an entry here would shift every later column.\n const groupFields = agg.groupBy.map((n) => byName.get(resolveField(n)));\n const measure = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n\n const groups = new Map<string, { keys: MetricKey[]; rows: Row[] }>();\n if (!agg.groupBy.length) groups.set(\"[]\", { keys: [], rows: [] });\n for (const row of rows) {\n const keys = groupFields.map((f) => {\n if (!f) return null; // unresolved group field → NULL bucket, never a missing column\n const v = readFieldValue(f, row);\n return v == null || v === \"\"\n ? null\n : typeof v === \"number\" ||\n typeof v === \"boolean\" ||\n typeof v === \"string\"\n ? v\n : String(v);\n });\n const k = JSON.stringify(keys);\n let g = groups.get(k);\n if (!g) {\n g = { keys, rows: [] };\n groups.set(k, g);\n }\n g.rows.push(row);\n }\n\n const buckets = [...groups.values()].map((g) => ({\n keys: g.keys,\n count: g.rows.length,\n value: aggValue(agg.op, measure, g.rows),\n }));\n return sortBuckets(buckets);\n}\n\nfunction aggValue<Row>(\n op: AggOp,\n measure: FieldDef<Row> | undefined,\n rows: Row[],\n): number | string | null {\n if (op === \"count\") {\n if (!measure) return rows.length; // COUNT(*)\n let n = 0;\n for (const r of rows) if (readFieldValue(measure, r) != null) n++; // COUNT(expr) = non-null\n return n;\n }\n if (!measure) return null;\n const values = rows\n .map((r) => readFieldValue(measure, r))\n .filter((v) => v != null);\n\n switch (op) {\n case \"count_distinct\":\n return new Set(values.map((v) => String(v))).size;\n case \"sum\":\n case \"avg\": {\n let sum = 0;\n let n = 0;\n for (const v of values) {\n const num = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(num)) {\n sum += num;\n n++;\n }\n }\n if (op === \"avg\") return n ? sum / n : null;\n return n ? sum : null;\n }\n case \"min\":\n case \"max\": {\n let best: unknown;\n for (const v of values) {\n if (best === undefined) {\n best = v;\n continue;\n }\n const cmp = compare(v, best);\n if (op === \"min\" ? cmp < 0 : cmp > 0) best = v;\n }\n return (best as number | string | undefined) ?? null;\n }\n default:\n return null;\n }\n}\n\n/** Stable display order: descending by the metric (or group size when the metric\n * isn't numeric), then by group key. The 2D pivot ignores this; the 1D bar list\n * and the flat N-column table read top-to-bottom from it. */\nfunction sortBuckets(buckets: AggregationBucket[]): AggregationBucket[] {\n return [...buckets].sort((a, b) => {\n const av = typeof a.value === \"number\" ? a.value : a.count;\n const bv = typeof b.value === \"number\" ? b.value : b.count;\n if (av !== bv) return bv - av;\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n}\n\ninterface PreparedWhereClause {\n clause: WhereClause;\n now: number;\n datetime?: number;\n regex: RegExp | null | undefined;\n}\n\n/** A term as a disjunction of conjunctions (see `branchesOf`). A literal is one\n * single-predicate branch; an OR group has one per member. */\ntype PreparedWhereTerm = { branches: PreparedWhereClause[][] };\n\nfunction prepareWhereClause(\n clause: WhereClause,\n now: number,\n): PreparedWhereClause {\n const usesRegex =\n clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\";\n return {\n clause,\n now,\n regex: usesRegex ? compileRegex(clause.value) : undefined,\n };\n}\n\nfunction prepareWhereTerm(\n term: WhereTerm,\n resolveField: (name: string) => string,\n now: number,\n): PreparedWhereTerm {\n return {\n branches: branchesOf(term).map((branch) =>\n branch.map((c) => prepareWhereClause({ ...c, field: resolveField(c.field) }, now)),\n ),\n };\n}\n\nfunction prepareDatetimePredicates<Row>(\n terms: PreparedWhereTerm[],\n fields: Map<string, FieldDef<Row>>,\n): void {\n for (const term of terms)\n for (const p of term.branches.flat()) {\n const field = fields.get(p.clause.field);\n if (\n field?.type !== \"datetime\" ||\n p.clause.value === \"\" ||\n p.clause.op === \"is_null\" ||\n p.clause.op === \"is_not_null\"\n )\n continue;\n p.datetime = coerceValue(\"datetime\", p.clause.value, p.now) as number;\n }\n}\n\n/** A row satisfies the WHERE when every term matches (AND); a term matches when\n * every predicate of one of its branches does — its sole predicate, any member\n * of an OR group, or every member of one conjunction of an OR of ANDs. */\nfunction matchesTerm<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n term: PreparedWhereTerm,\n): boolean {\n // Normalization never yields an empty group or conjunction, so `some` over\n // non-empty branches is the OR and `every` within one is the AND.\n return term.branches.some((branch) => branch.every((p) => matchesWith(byName, row, p)));\n}\n\nfunction matchesWith<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause } = prepared;\n const field = byName.get(clause.field);\n if (!field) return true; // unknown field → no client opinion\n const v = readFieldValue(field, row);\n\n // Empty value on a non-equality, value-taking op is a \"no filter\" signal —\n // true for BOTH the predicate and its negation (matches the UI + the Go\n // compiler, which skip such clauses). Nullary ops legitimately use value \"\".\n if (\n clause.value === \"\" &&\n clause.op !== \"=\" &&\n clause.op !== \"!=\" &&\n clause.op !== \"is_null\" &&\n clause.op !== \"is_not_null\"\n ) {\n return true;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (\n !/^(0|[1-9]\\d*)$/.test(clause.value) ||\n !Number.isSafeInteger(Number(clause.value))\n )\n return false;\n }\n\n let base: boolean;\n if (prepared.datetime !== undefined) {\n const timestamp =\n v instanceof Date\n ? v.getTime()\n : typeof v === \"number\"\n ? v\n : typeof v === \"string\"\n ? Date.parse(v)\n : NaN;\n if (v === \"\" || !Number.isFinite(timestamp)) return false;\n base = matchesDatetime(timestamp, prepared.datetime, clause.op);\n } else {\n base = matchesBase(field, v, prepared);\n }\n if (!clause.negated) return base;\n // Null-exclusive NOT: a NULL/empty value satisfies neither the predicate nor\n // its negation (mirrors `not_matches_regex` and the server's trailing\n // `AND <expr> IS NOT NULL`).\n const isNull = Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n return !isNull && !base;\n}\n\nfunction matchesDatetime(\n timestamp: number,\n rhs: number,\n op: WhereClause[\"op\"],\n): boolean {\n switch (op) {\n case \"=\":\n return timestamp === rhs;\n case \"!=\":\n return timestamp !== rhs;\n case \">\":\n return timestamp > rhs;\n case \">=\":\n return timestamp >= rhs;\n case \"<\":\n return timestamp < rhs;\n case \"<=\":\n return timestamp <= rhs;\n default:\n return false;\n }\n}\n\n/** The bare predicate result, ignoring `negated` and the empty-value skip\n * (both handled by `matchesWith`). */\nfunction matchesBase<Row>(\n field: FieldDef<Row>,\n v: unknown,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause, regex } = prepared;\n\n // Nullity, with array-aware semantics.\n if (clause.op === \"is_null\")\n return Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n if (clause.op === \"is_not_null\")\n return Array.isArray(v) ? v.length > 0 : v != null && v !== \"\";\n\n const arrayText = (value: unknown) =>\n field.filter?.arrayCaseSensitive\n ? String(value)\n : String(value).toLowerCase();\n\n // `includes` is array membership (ARRAY_HAS): a null/missing array contains\n // nothing. Handle before the array/scalar split so null can't fall through.\n if (clause.op === \"includes\") {\n const arr = Array.isArray(v) ? v : [];\n const needle = arrayText(clause.value);\n return arr.some((x) => arrayText(x) === needle);\n }\n\n if (clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\") {\n if (v == null || Array.isArray(v)) return false;\n if (!regex) return false;\n const matches = regex.test(String(v));\n return clause.op === \"matches_regex\" ? matches : !matches;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (typeof v !== \"string\" || !/^(0|[1-9]\\d*)$/.test(clause.value))\n return false;\n const limit = Number(clause.value);\n if (!Number.isSafeInteger(limit)) return false;\n const length = Array.from(v).length;\n return clause.op === \"length_gt\"\n ? length > limit\n : clause.op === \"length_lt\"\n ? length < limit\n : length === limit;\n }\n\n if (Array.isArray(v)) {\n const needle = arrayText(clause.value);\n const hay = v.map(arrayText);\n switch (clause.op) {\n case \"contains\":\n return hay.some((s) => s.includes(needle));\n case \"=\":\n return hay.includes(needle);\n case \"!=\":\n return !hay.includes(needle);\n default:\n return true;\n }\n }\n\n switch (clause.op) {\n case \"=\":\n return String(v ?? \"\") === String(coerceSafe(field, clause.value));\n case \"!=\":\n return String(v ?? \"\") !== String(coerceSafe(field, clause.value));\n case \">\":\n return compare(v, coerceSafe(field, clause.value)) > 0;\n case \">=\":\n return compare(v, coerceSafe(field, clause.value)) >= 0;\n case \"<\":\n return compare(v, coerceSafe(field, clause.value)) < 0;\n case \"<=\":\n return compare(v, coerceSafe(field, clause.value)) <= 0;\n case \"contains\":\n return String(v ?? \"\")\n .toLowerCase()\n .includes(clause.value.toLowerCase());\n case \"starts_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .startsWith(clause.value.toLowerCase());\n case \"ends_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .endsWith(clause.value.toLowerCase());\n default:\n return true;\n }\n}\n\n/** `null` means an invalid pattern; `undefined` means no regex was requested. */\nfunction compileRegex(pattern: string | undefined): RegExp | null | undefined {\n if (pattern === undefined) return undefined;\n try {\n return new RegExp(pattern);\n } catch {\n return null;\n }\n}\n\nfunction extractSortValue(\n value: unknown,\n regex: RegExp | null | undefined,\n): unknown {\n if (regex === undefined) return value;\n if (regex === null || value == null) return null;\n const match = regex.exec(String(value));\n if (!match) return null;\n return match.length > 1 ? (match[1] ?? null) : match[0];\n}\n\n/** Coerce per the field type, falling back to the raw string if coercion fails\n * (so a malformed value degrades to a string compare rather than throwing). */\nfunction coerceSafe(field: FieldDef, raw: string): string | number | boolean {\n try {\n return coerceValue(field.type, raw);\n } catch {\n return raw;\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\")\n return a === b ? 0 : a ? 1 : -1;\n return String(a).localeCompare(String(b));\n}\n","import type { ServerQueryV2, FetchRowsResultV2 } from \"./execution\";\nimport type { QueryCapabilitiesV3, QueryRequestV3, QueryResultV3 } from \"./queryV3\";\nimport type { MetricQuery, MetricCapabilities } from \"./metricTypes\";\n// adapters.ts — the pluggable seams. Everything project-specific is injected\n// here so the package core stays generic.\n//\n// - Transport : how rows + filter-value suggestions are fetched.\n// - StorageAdapter: where saved/last queries live (in-memory by default in\n// the React hook; explicitly durable when callers opt in).\n\nimport { normalizeQueryState } from \"./query\";\nimport type { HostQueryState, QueryState, RowId } from \"./query\";\nimport type { QuerySnapshotStore } from \"./queryLinks\";\nimport type { ServerQuery, AggregationRequest, AggregationResult } from \"./encode\";\n\n// ---- Transport ------------------------------------------------------------\n\nexport interface FetchRowsResult<Row> {\n rows: Row[];\n /** Total matching rows before pagination (for \"N of M\" + paging bounds). */\n total: number;\n}\n\n/** A keystroke-driven distinct-value lookup. Autocomplete is the DEFAULT value\n * source for every field (design feedback), so this is how the filter combobox\n * finds options. `search` is the user's current input; the backend returns the\n * best matches and whether it truncated (so the UI can prompt \"keep typing\"). */\nexport interface DistinctValuesQuery {\n field: string;\n /** Current substring/prefix the user has typed (empty = top values). */\n search: string;\n /** Max suggestions to return (default chosen by the adapter, ~50). */\n limit?: number;\n /** The table's host-owned state when `hostQuery` is configured. */\n hostState?: HostQueryState;\n}\n\nexport interface DistinctValuesResult {\n values: string[];\n /** true when more matches exist than were returned — refine by typing. */\n hasMore: boolean;\n /** True if the selected field has at least one NULL in the source dataset.\n * False if that field is guaranteed non-null. Omitted when the backend does\n * not compute this metadata. */\n hasNull?: boolean;\n}\n\n/** Per-field metadata for the field picker. */\nexport interface FieldStats {\n distinct?: number;\n min?: string | number;\n max?: string | number;\n}\n\nexport interface Transport<Row = any> {\n queryCapabilities?: QueryCapabilitiesV3;\n fetchQueryV3?(query: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;\n fetchRowsV2?(query: ServerQueryV2, signal?: AbortSignal): Promise<FetchRowsResultV2<Row>>;\n metricCapabilities?: MetricCapabilities;\n fetchMetrics?(query: MetricQuery, signal?: AbortSignal): Promise<AggregationResult>;\n /** Legacy row execution. A remote table needs this, fetchRowsV2 with a\n * computedExecution handshake, or fetchQueryV3 with queryCapabilities.\n * Modern hosts may omit the legacy endpoint, including for draft previews. */\n fetchRows?(query: ServerQuery, signal?: AbortSignal): Promise<FetchRowsResult<Row>>;\n\n /** Distinct values for filter autocomplete. Strongly recommended: without it,\n * fields fall back to freeform input. The backend should match `search`\n * server-side (e.g. ILIKE prefix) and cap at `limit` so large domains stay\n * fast and refine per keystroke. */\n fetchDistinctValues?(q: DistinctValuesQuery, signal?: AbortSignal): Promise<DistinctValuesResult>;\n\n /** Run the metric panel's GROUP BY queries (one per requested aggregation),\n * scoped to the WHERE-filtered set with no paging. Optional: without it, the\n * metric panel falls back to applyAggregations over local rows (client mode).\n * Implementations compile each AggSpec with backends/go CompileAggregation,\n * sharing the same WHERE as fetchRows. */\n fetchAggregations?(q: AggregationRequest, signal?: AbortSignal): Promise<AggregationResult>;\n\n /** Re-fetch a single row by id, for in-place updates without a full re-query\n * after a mutation. Optional. */\n fetchRow?(id: RowId, signal?: AbortSignal): Promise<Row | null>;\n\n /** Stats for the field picker. Optional. */\n fetchFieldStats?(fields: string[], signal?: AbortSignal): Promise<Record<string, FieldStats>>;\n}\n\n// ---- Saved queries --------------------------------------------------------\n\nexport interface SavedQuery {\n snapshotCode?: string;\n id: string;\n name: string;\n /** Epoch millis; injected by the caller so core stays deterministic/testable. */\n savedAt: number;\n query: QueryState;\n}\n\n/** Persistence for the \"last\" query (auto-restored) and named saved queries. All\n * methods are namespaced by `key` (the schema/dataset name) so multiple tables\n * on one origin don't collide. Async to allow backend implementations; the\n * browser adapters can still resolve synchronously. */\nexport interface StorageAdapter {\n /** Optional authenticated server store. Ordinary URL sync never calls it. */\n snapshots?: QuerySnapshotStore;\n /** True when last-used and named queries keep `QueryState.hostState`\n * exactly. A table with `hostQuery` refuses to save through an adapter\n * without it rather than store a table-only query. */\n storesHostState?: boolean;\n loadLast(key: string): Promise<QueryState | null>;\n saveLast(key: string, query: QueryState): Promise<void>;\n\n listSaved(key: string): Promise<SavedQuery[]>;\n /** Load the saved query selected as the default view for this key. Optional so\n * existing backend adapters keep working until they add first-class support. */\n loadDefaultSaved?(key: string): Promise<SavedQuery | null>;\n /** Set or clear the saved query used as the default view for this key. */\n setDefaultSaved?(key: string, id: string | null): Promise<void>;\n /** Persist a named query snapshot. Rejects when a saved query with the same\n * name already exists in the key namespace. */\n saveNamed(key: string, name: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n /** Atomically replace a named query's state, preserving its id, name and default\n * selection. On rejection the original entry must remain unchanged. */\n updateNamed?(key: string, id: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n deleteSaved(key: string, id: string): Promise<void>;\n}\n\nconst LAST_PREFIX = \"query-table:last:\";\nconst SAVED_PREFIX = \"query-table:saved:\";\nconst DEFAULT_PREFIX = \"query-table:default:\";\nconst MAX_SAVED_QUERIES = 100;\nconst MAX_SAVED_NAME_LENGTH = 200;\n\nfunction normalizeSavedQuery(value: unknown): SavedQuery | null {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) return null;\n const raw = value as Record<string, unknown>;\n if (\n typeof raw.id !== \"string\" ||\n !raw.id ||\n raw.id.length > 256 ||\n typeof raw.name !== \"string\" ||\n !raw.name ||\n raw.name.length > MAX_SAVED_NAME_LENGTH ||\n typeof raw.savedAt !== \"number\" ||\n !Number.isFinite(raw.savedAt) ||\n raw.query == null ||\n typeof raw.query !== \"object\"\n ) {\n return null;\n }\n return { id: raw.id, name: raw.name, savedAt: raw.savedAt, query: normalizeQueryState(raw.query),\n ...(typeof raw.snapshotCode === \"string\" ? { snapshotCode: raw.snapshotCode } : {}) };\n}\n\nfunction normalizeSavedQueries(value: unknown): SavedQuery[] {\n if (!Array.isArray(value)) return [];\n return value\n .slice(0, MAX_SAVED_QUERIES)\n .map(normalizeSavedQuery)\n .filter((item): item is SavedQuery => item != null);\n}\n\n/** In-memory persistence used by default by the React package. It supports the\n * full saved-query UI for the lifetime of a mounted table without writing\n * filter values to durable browser storage. */\nexport function memoryStorageAdapter(): StorageAdapter {\n const last = new Map<string, QueryState>();\n const saved = new Map<string, SavedQuery[]>();\n const defaults = new Map<string, string>();\n\n return {\n storesHostState: true,\n async loadLast(key) {\n const query = last.get(key);\n return query ? normalizeQueryState(query) : null;\n },\n async saveLast(key, query) {\n last.set(key, normalizeQueryState(query));\n },\n async listSaved(key) {\n return (saved.get(key) ?? []).map((item) => ({ ...item, query: normalizeQueryState(item.query) }));\n },\n async loadDefaultSaved(key) {\n const id = defaults.get(key);\n return id ? (saved.get(key) ?? []).find((item) => item.id === id) ?? null : null;\n },\n async setDefaultSaved(key, id) {\n if (id == null) {\n defaults.delete(key);\n return;\n }\n if (!(saved.get(key) ?? []).some((item) => item.id === id)) throw new Error(`Saved query \"${id}\" does not exist.`);\n defaults.set(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = saved.get(key) ?? [];\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((item) => item.name === normalizedName)) throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n saved.set(key, [...items, item]);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = saved.get(key) ?? [];\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n saved.set(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n saved.set(key, (saved.get(key) ?? []).filter((item) => item.id !== id));\n if (defaults.get(key) === id) defaults.delete(key);\n },\n };\n}\n\n/** Opt-in StorageAdapter over window.localStorage. Query state includes raw\n * filter values and is stored as cleartext JSON; do not use it for sensitive\n * datasets. Falls back to no persistence when storage is unavailable. */\nexport function localStorageAdapter(): StorageAdapter {\n const ls: Storage | null = (() => {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null; // access can throw in some sandboxes\n }\n })();\n\n const readSaved = (key: string): SavedQuery[] => {\n if (!ls) return [];\n try {\n const raw = ls.getItem(SAVED_PREFIX + key);\n return normalizeSavedQueries(raw ? JSON.parse(raw) : []);\n } catch {\n return [];\n }\n };\n const writeSaved = (key: string, items: SavedQuery[]): void => {\n if (ls) ls.setItem(SAVED_PREFIX + key, JSON.stringify(items));\n };\n const readDefaultId = (key: string): string | null => {\n if (!ls) return null;\n return ls.getItem(DEFAULT_PREFIX + key);\n };\n const writeDefaultId = (key: string, id: string | null): void => {\n if (!ls) return;\n if (id) ls.setItem(DEFAULT_PREFIX + key, id);\n else ls.removeItem(DEFAULT_PREFIX + key);\n };\n\n return {\n storesHostState: true,\n async loadLast(key) {\n if (!ls) return null;\n try {\n const raw = ls.getItem(LAST_PREFIX + key);\n return raw ? normalizeQueryState(JSON.parse(raw)) : null;\n } catch {\n return null;\n }\n },\n async saveLast(key, query) {\n if (ls) ls.setItem(LAST_PREFIX + key, JSON.stringify(normalizeQueryState(query)));\n },\n async listSaved(key) {\n return readSaved(key).sort((a, b) => b.savedAt - a.savedAt);\n },\n async loadDefaultSaved(key) {\n const id = readDefaultId(key);\n if (!id) return null;\n const found = readSaved(key).find((q) => q.id === id);\n if (!found) writeDefaultId(key, null);\n return found ?? null;\n },\n async setDefaultSaved(key, id) {\n if (id && !readSaved(key).some((q) => q.id === id)) {\n throw new Error(`Saved query \"${id}\" does not exist.`);\n }\n writeDefaultId(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = readSaved(key);\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((q) => q.name === normalizedName)) {\n throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n }\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n items.push(item);\n writeSaved(key, items);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = readSaved(key);\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n writeSaved(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n writeSaved(\n key,\n readSaved(key).filter((q) => q.id !== id),\n );\n if (readDefaultId(key) === id) writeDefaultId(key, null);\n },\n };\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\n\nexport interface SavedPropertyView {\n id: string;\n name: string;\n savedAt: number;\n view: PropertyViewState;\n}\nexport interface PropertyViewStorage {\n loadLast(objectType: string): Promise<PropertyViewState | null>;\n saveLast(objectType: string, view: PropertyViewState): Promise<void>;\n listSaved(objectType: string): Promise<SavedPropertyView[]>;\n saveNamed(\n objectType: string,\n name: string,\n view: PropertyViewState,\n savedAt: number,\n ): Promise<SavedPropertyView>;\n deleteSaved(objectType: string, id: string): Promise<void>;\n loadDefaultSaved(objectType: string): Promise<SavedPropertyView | null>;\n setDefaultSaved(objectType: string, id: string | null): Promise<void>;\n}\ninterface StoredViews {\n last: PropertyViewState | null;\n saved: SavedPropertyView[];\n defaultId: string | null;\n}\nconst empty = (): StoredViews => ({ last: null, saved: [], defaultId: null });\nconst clone = (saved: SavedPropertyView): SavedPropertyView => ({\n ...saved,\n view: normalizePropertyView(saved.view),\n});\n\n/** The JSON-backed factory also supports application-owned synchronous preferences. */\nexport function jsonPropertyViewStorage(\n read: (key: string) => string | null,\n write: (key: string, value: string) => void,\n): PropertyViewStorage {\n const keyFor = (type: string) => `query-table:properties:${type}`;\n function load(type: string): StoredViews {\n const value = read(keyFor(type));\n if (value === null) return empty();\n const raw = JSON.parse(value) as StoredViews;\n if (\n !raw ||\n !Array.isArray(raw.saved) ||\n raw.saved.length > 100 ||\n !(raw.defaultId === null || typeof raw.defaultId === \"string\")\n )\n throw new Error(\"Invalid saved property views.\");\n const saved = raw.saved.map((item) => {\n if (\n !item ||\n typeof item.id !== \"string\" ||\n !item.id ||\n typeof item.name !== \"string\" ||\n !item.name.trim() ||\n item.name.length > 200 ||\n !Number.isFinite(item.savedAt)\n )\n throw new Error(\"Invalid saved property view.\");\n return clone(item);\n });\n return {\n last: raw.last === null ? null : normalizePropertyView(raw.last),\n saved,\n defaultId: raw.defaultId,\n };\n }\n const store = (type: string, value: StoredViews) =>\n write(keyFor(type), JSON.stringify(value));\n return {\n async loadLast(type) {\n return load(type).last;\n },\n async saveLast(type, view) {\n const data = load(type);\n data.last = normalizePropertyView(view);\n store(type, data);\n },\n async listSaved(type) {\n return load(type).saved;\n },\n async saveNamed(type, name, view, savedAt) {\n name = name.trim();\n if (!name || name.length > 200 || !Number.isFinite(savedAt))\n throw new Error(\n \"A view name (1–200 characters) and valid save time are required.\",\n );\n const data = load(type);\n if (data.saved.some((v) => v.name === name))\n throw new Error(`A property view named “${name}” already exists.`);\n if (data.saved.length >= 100)\n throw new Error(\"At most 100 saved property views are allowed.\");\n let suffix = 0;\n while (data.saved.some((v) => v.id === `${savedAt}-${suffix}`)) suffix++;\n const saved = {\n id: `${savedAt}-${suffix}`,\n name,\n savedAt,\n view: normalizePropertyView(view),\n };\n data.saved.push(saved);\n store(type, data);\n return clone(saved);\n },\n async deleteSaved(type, id) {\n const data = load(type);\n data.saved = data.saved.filter((v) => v.id !== id);\n if (data.defaultId === id) data.defaultId = null;\n store(type, data);\n },\n async loadDefaultSaved(type) {\n const data = load(type);\n return data.saved.find((v) => v.id === data.defaultId) ?? null;\n },\n async setDefaultSaved(type, id) {\n const data = load(type);\n if (id !== null && !data.saved.some((v) => v.id === id))\n throw new Error(\"Unknown property view.\");\n data.defaultId = id;\n store(type, data);\n },\n };\n}\nexport function memoryPropertyViewStorage(): PropertyViewStorage {\n const values = new Map<string, string>();\n return jsonPropertyViewStorage(\n (key) => values.get(key) ?? null,\n (key, value) => {\n values.set(key, value);\n },\n );\n}\n/** Durable browser persistence is explicitly opt-in, independently of table storage. */\nexport function localPropertyViewStorage(): PropertyViewStorage {\n return jsonPropertyViewStorage(\n (key) => localStorage.getItem(key),\n (key, value) => localStorage.setItem(key, value),\n );\n}\n","import { predicatesOf, ITEM_DETAILS_COLUMN, type QueryState } from \"./query\";\nimport { metricDependencies, compileMetric } from \"./metrics\";\nimport { createGroupingModel } from \"./grouping\";\nimport { groupKeyFields } from \"./groupKeys\";\nimport type { FieldSchema } from \"./schema\";\nimport type { FormulaPlan } from \"./formula\";\n\nexport interface SourceDependencies {\n fields: string[];\n baseFields: string[];\n identity: string;\n paths: Record<string, string>;\n}\n/** Source inputs are distinct from result/HAVING aliases. Includes hidden ROW\n * inputs and transitive computed/derived dependencies, even when not selected. */\nexport function sourceDependencies<Row>(query: QueryState, schema: FieldSchema<Row>, resolveComputed?: (name: string) => FormulaPlan | undefined): SourceDependencies {\n const fields = new Set<string>([schema.idField]);\n const addSort = (name: string) => {\n fields.add(name);\n const sortField = schema.fields.find(field => field.name === name)?.sort?.field;\n if (sortField) fields.add(sortField);\n };\n const source = query.grouping?.source ?? query;\n for (const term of source.where) for (const predicate of predicatesOf(term)) fields.add(predicate.field);\n if (query.grouping) {\n const model = createGroupingModel(schema);\n model.validate(query.grouping);\n for (const key of groupKeyFields(query.grouping.keys)) fields.add(key);\n for (const summary of query.grouping.summaries) {\n // Link columns read result fields only; they have no source inputs.\n if (summary.op === \"link\") continue;\n if (summary.op === \"row\") fields.add(summary.field!);\n else for (const dependency of compileMetric(model.summaryExpression(summary), schema, resolveComputed).dependencies) fields.add(dependency);\n }\n for (const term of query.grouping.representative?.orderBy ?? []) addSort(term.field);\n } else {\n for (const column of source.select) if (column.field !== ITEM_DETAILS_COLUMN) fields.add(column.field);\n for (const term of source.orderBy) addSort(term.field);\n for (const metric of source.aggregations ?? []) for (const dependency of metricDependencies(metric, schema, resolveComputed)) fields.add(dependency);\n }\n const base = new Set<string>();\n const visiting = new Set<string>();\n const visit = (name: string) => {\n if (visiting.has(name)) throw Error(\"Source dependency cycle.\");\n const field = schema.fields.find(field => field.name === name);\n if (!field && name === schema.idField) { base.add(name); return; }\n const dependencies = field?.source.kind === \"derived\" ? field.source.dependencies : resolveComputed?.(name)?.dependencies;\n if (!field && !dependencies) throw Error(`Unavailable source dependency: ${name}.`);\n if (dependencies?.length) {\n visiting.add(name);\n for (const dependency of dependencies) visit(dependency);\n visiting.delete(name);\n } else base.add(name);\n };\n for (const name of fields) visit(name);\n const paths = Object.fromEntries([...base].map(name => {\n const field = schema.fields.find(field => field.name === name);\n return [name, field?.source.kind === \"backend\" ? field.source.path ?? name : name];\n }));\n return { fields: [...fields].sort(), baseFields: [...base].sort(), identity: schema.idField, paths };\n}\n","// queryPatch.ts — apply, recognise and remove partial queries (\"patches\").\n//\n// A host keeps reusable presets (a saved filter set, a column layout, a\n// grouped report) as patches. Each patch owns some facets of a QueryState and\n// leaves the others alone. Filters are additive and identified structurally:\n// there is no provenance on WHERE terms, so a term the user typed that is\n// structurally identical to a patch term is indistinguishable from it. See\n// docs/query-patches.md for the full contract.\n\nimport { exitGrouping, withGroupingKeys, type GroupingState, type SummaryColumn } from \"./grouping\";\nimport type { GroupKey } from \"./groupKeys\";\nimport { NULLARY_OPS } from \"./ops\";\nimport {\n isWhereConjunction,\n isWhereGroup,\n normalizeQueryState,\n type AggregationClause,\n type QueryState,\n type WhereBranch,\n type WhereClause,\n type WhereTerm,\n} from \"./query\";\n\nexport type QueryFacet = \"filters\" | \"columns\" | \"order\" | \"grouping\" | \"metrics\" | \"limit\";\n\nexport interface QueryPatch {\n /** Host identity for the patch; not interpreted. */\n id: string;\n /** Facets this patch controls. Facets not listed are never touched. */\n owns: QueryFacet[];\n /** Values for the owned facets. A `grouping` value makes this a group-stage\n * patch: its `where` is HAVING and its filters are `grouping.source.where`. */\n query: Partial<QueryState>;\n}\n\nexport interface QueryPatchMatch {\n status: \"active\" | \"modified\" | \"inactive\";\n /** Owned facets that differ; only populated when `status` is \"modified\". */\n modified: QueryFacet[];\n}\n\nexport interface ApplyPatchOptions {\n /** A previously applied patch to remove first (see `removePatch`). */\n replacing?: QueryPatch;\n}\n\n// ---- structural WHERE helpers (shared with drilldown) -----------------------\n\nfunction clauseKey(clause: WhereClause): string {\n return JSON.stringify([\n clause.field,\n clause.op,\n NULLARY_OPS.has(clause.op) ? \"\" : clause.value,\n clause.negated === true,\n ]);\n}\n\n/** Structural identity of one WHERE term. OR-group members and the literals\n * of a conjunction branch are unordered, and presentation metadata (set-filter\n * identity) is ignored. */\nexport function whereTermKey(term: WhereTerm): string {\n if (!isWhereGroup(term)) return clauseKey(term);\n const branchKey = (member: WhereBranch) =>\n isWhereConjunction(member) ? `all:${JSON.stringify(member.all.map(clauseKey).sort())}` : clauseKey(member);\n return `any:${JSON.stringify(term.any.map(branchKey).sort())}`;\n}\n\n/** Append terms that are not already structurally present. */\nexport function appendWhereTerms(where: readonly WhereTerm[], terms: readonly WhereTerm[]): WhereTerm[] {\n const present = new Set(where.map(whereTermKey));\n const out = [...where];\n for (const term of terms) {\n const key = whereTermKey(term);\n if (present.has(key)) continue;\n present.add(key);\n out.push(term);\n }\n return out;\n}\n\n/** Owned units: each OR group (of literals or conjunctions) or literal alone, except that a run of\n * consecutive `!=` literals on one field (an exclusion list) is one unit. */\nfunction filterUnits(where: readonly WhereTerm[]): WhereTerm[][] {\n const units: WhereTerm[][] = [];\n for (const term of where) {\n const last = units[units.length - 1];\n const previous = last?.[last.length - 1];\n if (\n last && previous && !isWhereGroup(term) && !isWhereGroup(previous) &&\n term.op === \"!=\" && previous.op === \"!=\" && term.field === previous.field\n )\n last.push(term);\n else units.push([term]);\n }\n return units;\n}\n\nfunction unitPresent(unit: readonly WhereTerm[], present: ReadonlySet<string>): boolean {\n return unit.every((term) => present.has(whereTermKey(term)));\n}\n\nfunction removeUnits(where: readonly WhereTerm[], units: readonly WhereTerm[][]): WhereTerm[] {\n const present = new Set(where.map(whereTermKey));\n const remove = new Set(\n units.filter((unit) => unitPresent(unit, present)).flatMap((unit) => unit.map(whereTermKey)),\n );\n return where.filter((term) => !remove.has(whereTermKey(term)));\n}\n\nfunction sameTermSet(a: readonly WhereTerm[], b: readonly WhereTerm[]): boolean {\n const keys = (where: readonly WhereTerm[]) => JSON.stringify(where.map(whereTermKey).sort());\n return keys(a) === keys(b);\n}\n\n// ---- patch interpretation ---------------------------------------------------\n\ninterface PatchGrouping {\n keys: GroupKey[];\n summaries: SummaryColumn[];\n representative: GroupingState[\"representative\"];\n having: WhereTerm[];\n}\n\ninterface PatchParts {\n owns: Set<QueryFacet>;\n stage: \"records\" | \"groups\";\n filters: WhereTerm[];\n units: WhereTerm[][];\n grouping: PatchGrouping | null;\n select: QueryState[\"select\"];\n orderBy: QueryState[\"orderBy\"];\n limit: number | undefined;\n aggregations: AggregationClause[];\n}\n\nfunction patchParts(patch: QueryPatch): PatchParts {\n const raw = patch.query ?? {};\n const normalized = normalizeQueryState(raw);\n const stage = normalized.grouping ? \"groups\" : \"records\";\n const filters = normalized.grouping ? normalized.grouping.source.where : normalized.where;\n const owns = new Set(patch.owns);\n // A limit has no neutral value without the schema; an absent one is not owned.\n if (typeof raw.limit !== \"number\") owns.delete(\"limit\");\n return {\n owns,\n stage,\n filters,\n units: filterUnits(filters),\n grouping: normalized.grouping\n ? {\n keys: normalized.grouping.keys,\n summaries: normalized.grouping.summaries,\n representative: normalized.grouping.representative,\n having: normalized.where,\n }\n : null,\n select: normalized.select,\n orderBy: normalized.orderBy,\n limit: typeof raw.limit === \"number\" ? normalized.limit : undefined,\n aggregations: normalized.aggregations ?? [],\n };\n}\n\nconst recordStage = (query: QueryState): QueryState => query.grouping?.source ?? query;\n\nfunction withRecordStage(query: QueryState, next: QueryState): QueryState {\n return query.grouping ? { ...query, grouping: { ...query.grouping, source: next } } : next;\n}\n\n/** Columns, order, limit and metrics address the stage the patch was written\n * for: the record query (the source snapshot while grouped) for record-stage\n * patches, the grouped result for group-stage patches. */\nfunction stageOf(query: QueryState, stage: PatchParts[\"stage\"]): QueryState | undefined {\n if (stage === \"records\") return recordStage(query);\n return query.grouping ? query : undefined;\n}\n\nfunction withStage(query: QueryState, stage: PatchParts[\"stage\"], update: (stage: QueryState) => QueryState): QueryState {\n if (stage === \"records\") return withRecordStage(query, update(recordStage(query)));\n return query.grouping ? update(query) : query;\n}\n\nfunction withAggregations(query: QueryState, aggregations: AggregationClause[]): QueryState {\n const { aggregations: _previous, ...rest } = query;\n return aggregations.length ? { ...rest, aggregations } : rest;\n}\n\nconst clone = <T>(value: T): T => structuredClone(value);\n\n// ---- comparison -------------------------------------------------------------\n\nconst summaryMeaning = ({ id, op, field, expression, link }: SummaryColumn) =>\n JSON.stringify(op === \"link\" ? [id, op, link ?? null] : [id, op, field, expression]);\n\nfunction summarySignature(summaries: readonly SummaryColumn[]): string {\n return JSON.stringify(summaries.map(summaryMeaning));\n}\n\n/** JSON with object keys sorted at every depth; array order is kept. */\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, (_key, item: unknown) =>\n item && typeof item === \"object\" && !Array.isArray(item)\n ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)))\n : item,\n );\n}\n\nfunction metricSignature(metric: AggregationClause): string {\n const { id: _id, label: _label, display: _display, layout: _layout, ...rest } = metric;\n return canonicalJson(rest);\n}\n\nfunction facetMatches(query: QueryState, parts: PatchParts, facet: QueryFacet): boolean {\n switch (facet) {\n case \"filters\": {\n const present = new Set(recordStage(query).where.map(whereTermKey));\n return parts.units.every((unit) => unitPresent(unit, present));\n }\n case \"grouping\": {\n const grouping = query.grouping;\n if (!parts.grouping || !grouping) return !parts.grouping && !grouping;\n return (\n JSON.stringify(grouping.keys) === JSON.stringify(parts.grouping.keys) &&\n summarySignature(grouping.summaries) === summarySignature(parts.grouping.summaries) &&\n JSON.stringify(grouping.representative) === JSON.stringify(parts.grouping.representative) &&\n sameTermSet(query.where, parts.grouping.having)\n );\n }\n case \"columns\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && JSON.stringify(stage.select.map((c) => c.field)) === JSON.stringify(parts.select.map((c) => c.field));\n }\n case \"order\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && JSON.stringify(stage.orderBy) === JSON.stringify(parts.orderBy);\n }\n case \"limit\": {\n const stage = stageOf(query, parts.stage);\n return !!stage && stage.limit === parts.limit;\n }\n case \"metrics\": {\n const stage = stageOf(query, parts.stage);\n const signatures = (metrics: readonly AggregationClause[]) => JSON.stringify(metrics.map(metricSignature).sort());\n return !!stage && signatures(stage.aggregations ?? []) === signatures(parts.aggregations);\n }\n }\n}\n\n/** Compare a query with a patch. Both are normalized first; column widths,\n * `fitToScreen`, labels, metric display/layout and metric IDs are ignored.\n *\n * - `active`: every owned facet matches.\n * - `modified`: some owned facet differs, but the patch is still recognizable:\n * at least one owned facet matches (an owned `filters` facet with no terms\n * does not count), or at least one of its filter units is still present.\n * - `inactive`: otherwise. */\nexport function matchPatch(query: QueryState, patch: QueryPatch): QueryPatchMatch {\n const normalized = normalizeQueryState(query);\n const parts = patchParts(patch);\n const owned = [...parts.owns];\n const modified = owned.filter((facet) => !facetMatches(normalized, parts, facet));\n if (!modified.length) return { status: \"active\", modified: [] };\n const present = new Set(recordStage(normalized).where.map(whereTermKey));\n const recognizable =\n owned.some((facet) => !modified.includes(facet) && (facet !== \"filters\" || parts.units.length > 0)) ||\n (parts.owns.has(\"filters\") && parts.units.some((unit) => unitPresent(unit, present)));\n return recognizable ? { status: \"modified\", modified } : { status: \"inactive\", modified: [] };\n}\n\n// ---- application ------------------------------------------------------------\n\nfunction resetOffsets(query: QueryState): QueryState {\n return query.grouping\n ? { ...query, offset: 0, grouping: { ...query.grouping, source: { ...query.grouping.source, offset: 0 } } }\n : { ...query, offset: 0 };\n}\n\nfunction applyGrouping(query: QueryState, grouping: PatchGrouping | null): QueryState {\n if (!grouping) return exitGrouping(query);\n const before = query.grouping;\n // Enter or re-key through the same transition the grouping controls use.\n const keyed = before && JSON.stringify(before.keys) === JSON.stringify(grouping.keys)\n ? query\n : withGroupingKeys(query, grouping.keys);\n const previous = keyed.grouping!;\n const summaries = clone(grouping.summaries);\n // Result columns, sorts and metrics over replaced aggregates lose their meaning.\n const kept = new Set(summaries.map(summaryMeaning));\n const changed = new Set(previous.summaries.filter((column) => !kept.has(summaryMeaning(column))).map((column) => column.id));\n const next: QueryState = {\n ...keyed,\n grouping: { ...previous, summaries, representative: clone(grouping.representative) },\n where: clone(grouping.having),\n select: keyed.select.filter((c) => !changed.has(c.field)),\n orderBy: keyed.orderBy.filter((term) => !changed.has(term.field)),\n };\n return changed.size ? withAggregations(next, []) : next;\n}\n\n/** Remove a patch: its filter units that are still fully present are removed;\n * each other owned facet that still matches the patch is reset (columns and\n * order to the schema defaults, metrics to none, grouping exited). Facets the\n * user has since changed, and `limit`, are left alone. Resets offsets to 0. */\nexport function removePatch(query: QueryState, patch: QueryPatch): QueryState {\n const parts = patchParts(patch);\n const matches = (facet: QueryFacet) => parts.owns.has(facet) && facetMatches(normalizeQueryState(query), parts, facet);\n const reset = {\n columns: matches(\"columns\"),\n order: matches(\"order\"),\n metrics: matches(\"metrics\"),\n grouping: matches(\"grouping\"),\n };\n let next = query;\n if (parts.owns.has(\"filters\")) {\n const records = recordStage(next);\n next = withRecordStage(next, { ...records, where: removeUnits(records.where, parts.units) });\n }\n next = withStage(next, parts.stage, (stage) => {\n let out = stage;\n if (reset.columns) out = { ...out, select: [] };\n if (reset.order) out = { ...out, orderBy: [] };\n if (reset.metrics) out = withAggregations(out, []);\n return out;\n });\n if (reset.grouping) next = exitGrouping(next);\n return resetOffsets(next);\n}\n\n/** Apply a patch. Facets it does not own are untouched. Owned non-filter\n * facets are replaced; owned filters are additive: units already present are\n * not duplicated and user-authored terms are never removed. With `replacing`,\n * that patch is first removed with `removePatch`. Resets offsets to 0. */\nexport function applyPatch(query: QueryState, patch: QueryPatch, options: ApplyPatchOptions = {}): QueryState {\n let next = options.replacing ? removePatch(query, options.replacing) : query;\n const parts = patchParts(patch);\n if (parts.owns.has(\"grouping\")) next = applyGrouping(next, parts.grouping);\n if (parts.owns.has(\"filters\")) {\n const records = recordStage(next);\n next = withRecordStage(next, { ...records, where: appendWhereTerms(records.where, clone(parts.filters)) });\n }\n next = withStage(next, parts.stage, (stage) => {\n let out = stage;\n if (parts.owns.has(\"columns\")) out = { ...out, select: clone(parts.select) };\n if (parts.owns.has(\"order\")) out = { ...out, orderBy: clone(parts.orderBy) };\n if (parts.owns.has(\"limit\")) out = { ...out, limit: parts.limit ?? out.limit };\n if (parts.owns.has(\"metrics\")) out = withAggregations(out, clone(parts.aggregations));\n return out;\n });\n return resetOffsets(next);\n}\n","// groupLinks.ts — compose and route group-grain link columns.\n//\n// A link column's cell value (`GroupLinkValue`) carries everything that\n// depends on the group row. These helpers combine it with the current query\n// and the host's routes. Query-table owns composing the query; the host owns\n// turning it into a URL.\n\nimport { exitGrouping, type GroupLinkValue, type SummaryColumn } from \"./grouping\";\nimport { EMPTY_QUERY, type QueryState } from \"./query\";\nimport { appendWhereTerms, applyPatch } from \"./queryPatch\";\n\n/** Host routes for query-kind links, keyed by `LinkSpec.to.target`. Each\n * returns an href; it is safety-checked before rendering. */\nexport type LinkTargets = Record<string, (query: QueryState, params: Record<string, string>) => string>;\n\nexport interface ResolvedGroupLink {\n label: string;\n /** Not yet safety-checked; null when the link cannot be followed. */\n href: string | null;\n problem?: string;\n}\n\n/** Link columns are computed on the client. Server requests carry only the\n * keys and summaries they read. */\nexport function withoutLinkSummaries(summaries: readonly SummaryColumn[]): SummaryColumn[] {\n return summaries.filter((column) => column.op !== \"link\");\n}\n\n/** The query a query-kind link opens, or null for template links, invalid\n * links and ungrouped queries.\n *\n * Starts from `grouping.source` (or `EMPTY_QUERY` for `base: \"empty\"`), adds\n * the group's key predicates unless `keyFilters` is false, resets the offset\n * and finally applies the link's patch. With the defaults this is\n * `groupSourceQuery` followed by the patch. */\nexport function groupLinkQuery(query: QueryState, value: GroupLinkValue): QueryState | null {\n const to = value.to;\n if (!query.grouping || to?.kind !== \"query\" || value.problem) return null;\n const base = to.base === \"empty\" ? structuredClone(EMPTY_QUERY) : exitGrouping(query);\n if (to.keyFilters !== false && !value.terms) return null;\n const filtered: QueryState = { ...base, where: appendWhereTerms(base.where, value.terms ?? []), offset: 0 };\n return to.patch ? applyPatch(filtered, to.patch) : filtered;\n}\n\n/** Resolve a link cell to its label and href. Unregistered targets, failing\n * routes and unresolvable values return `href: null` with a `problem`. */\nexport function resolveGroupLink(query: QueryState, value: GroupLinkValue, targets: LinkTargets = {}): ResolvedGroupLink {\n const unresolved = (problem: string): ResolvedGroupLink => ({ label: value.label, href: null, problem });\n if (value.problem) return unresolved(value.problem);\n if (value.to?.kind === \"template\") return value.href ? { label: value.label, href: value.href } : unresolved(\"Invalid link.\");\n if (value.to?.kind !== \"query\") return unresolved(\"Invalid link definition.\");\n const route = Object.prototype.hasOwnProperty.call(targets, value.to.target) ? targets[value.to.target] : undefined;\n if (typeof route !== \"function\") return unresolved(`Link target \"${value.to.target}\" is not registered.`);\n const destination = groupLinkQuery(query, value);\n if (!destination) return unresolved(\"This group cannot be matched exactly.\");\n try {\n const href = route(destination, { ...value.to.params });\n return typeof href === \"string\" && href.trim() ? { label: value.label, href } : unresolved(`Link target \"${value.to.target}\" returned no URL.`);\n } catch (error) {\n return unresolved(`Link target \"${value.to.target}\" failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n","import { createGroupingModel, withoutGrouping, type GroupingDefinition } from \"./grouping\";\nimport { normalizeQueryState, predicatesOf, type QueryState, type AggregationClause } from \"./query\";\nimport { toServerQuery, type ServerQuery, type AggregationResult } from \"./encode\";\nimport { validateMetric, toMetricQuery } from \"./metrics\";\nimport { isMetricCycle } from \"./metricDates\";\nimport type { ComputedExecution } from \"./computed\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport { evaluationTime } from \"./relativeTime\";\nimport { withoutLinkSummaries } from \"./groupLinks\";\nimport { isCalendarGroupKey } from \"./groupKeys\";\n\nexport interface QueryCapabilitiesV3 {\n version: 3;\n groupedRows: boolean;\n calendarGrouping: boolean;\n /** Executes the cyclic `hourOfDay` and `dayOfWeek` date intervals. */\n calendarCycles?: boolean;\n /** Executes calendar grouping keys (`{ field, interval, timeZone }`) in a\n * grouping stage. Requests using them are refused otherwise. */\n calendarGroupKeys?: boolean;\n computedSourceFilters: boolean;\n regex: boolean;\n regexSourceFilters?: boolean;\n regexAggregateExpressions?: boolean;\n /** Executes AggregationClause.where; clauses using it are refused otherwise. */\n metricFilters?: boolean;\n /** Executes AggregationClause.minCount and reports hiddenGroups. */\n metricMinCount?: boolean;\n /** Also executes an object minCount: distinct values or a sum per group. */\n metricMinCountMeasures?: boolean;\n maxRows: number;\n maxGroups: number;\n maxPopulation: number;\n profile: string;\n}\nexport interface QueryRequestV3 {\n /** The table's host-owned state when `hostQuery` is configured. */\n hostState?: import(\"./query\").HostQueryState;\n version: 3;\n profile: string;\n now: number;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n snapshot?: string;\n source: ServerQuery;\n result: ServerQuery;\n grouping?: GroupingDefinition;\n rows: boolean;\n metrics: AggregationClause[];\n diagnostics: string[];\n}\nexport interface QueryResultV3 {\n version: 3;\n now: number;\n sourceTotal: number;\n rows: Record<string, unknown>[];\n total: number;\n schema: { name: string; idField: string; fields: { name: string; type: string }[] };\n metrics: AggregationResult[\"metrics\"];\n execution: ComputedExecution;\n}\n/** The handshake supplies authority, including capabilities for computed keys\n * absent from the base schema. Labels may be supplied by the editable catalogue. */\nexport function sourceExecutionSchema<Row>(schema: FieldSchema<Row>, execution?: ComputedExecution, catalogue: readonly { id: string; label: string; revision: string }[] = []): FieldSchema<Row> {\n const fields = new Map(schema.fields.map(field => [field.name, field]));\n for (const [name, capability] of Object.entries(execution?.fields ?? {})) {\n const definition = catalogue.find(definition => name === `@computed/${definition.id}`);\n const revision = execution?.resolvedRevisions[name] ?? execution?.resolvedRevisions[name.slice(10)];\n const current = !!revision && (!definition || definition.revision === revision);\n fields.set(name, { ...fields.get(name), name, label: definition?.label ?? fields.get(name)?.label ?? name,\n type: capability.type, source: { kind: \"backend\" },\n select: { enabled: current && capability.select }, filter: { enabled: current && capability.filter === true },\n sort: { enabled: current && capability.sort }, aggregate: { measure: current && capability.measure, groupable: current && capability.group } } as FieldDef<Row>);\n }\n return { ...schema, fields: [...fields.values()] };\n}\nexport function toQueryRequestV3<Row>(query: QueryState, baseSchema: FieldSchema<Row>, capabilities: QueryCapabilitiesV3,\n execution?: ComputedExecution, options: { now?: number; rows?: boolean } = {}): QueryRequestV3 {\n const now = evaluationTime(options), q = normalizeQueryState(query);\n const sourceSchema = sourceExecutionSchema(baseSchema, execution);\n const source = q.grouping?.source ?? withoutGrouping(q);\n const diagnostics: string[] = [];\n if ((query.aggregations?.length ?? 0) !== (q.aggregations?.length ?? 0)) diagnostics.push(\"The query exceeds its metric budget or contains malformed metric state.\");\n if (capabilities.version !== 3 || execution && execution.profile !== capabilities.profile) diagnostics.push(\"The negotiated query profile is unavailable.\");\n let resultSchema = sourceSchema as FieldSchema<any>;\n if (q.grouping) {\n if (!capabilities.groupedRows) diagnostics.push(\"This server does not support grouped rows.\");\n else if (q.grouping.keys.some(isCalendarGroupKey) && !capabilities.calendarGroupKeys)\n diagnostics.push(\"This server does not support grouping keys by calendar interval.\");\n try { const model = createGroupingModel(sourceSchema); model.validate(q.grouping); resultSchema = model.resultSchema(q.grouping.keys, q.grouping.summaries); }\n catch (error) { diagnostics.push(error instanceof Error ? error.message : String(error)); }\n }\n const sourceRequest = toServerQuery(withoutGrouping(source), sourceSchema);\n for (const term of source.where) for (const predicate of predicatesOf(term)) if ([\"matches_regex\", \"not_matches_regex\"].includes(predicate.op) && !capabilities.regexSourceFilters)\n diagnostics.push(\"This server profile does not support isolated regex source filtering.\");\n const result = toServerQuery(withoutGrouping(q), resultSchema);\n if (sourceRequest.where.length !== source.where.length || result.where.length !== q.where.length) diagnostics.push(\"The query contains unsupported source or result predicates.\");\n if (result.orderBy.length !== q.orderBy.length) diagnostics.push(\"The query contains unsupported result ordering.\");\n if (q.grouping) for (const term of q.grouping.source.where) for (const predicate of predicatesOf(term))\n if (predicate.field.startsWith(\"@computed/\") && !capabilities.computedSourceFilters) diagnostics.push(\"This server does not support computed source predicates.\");\n const metricQuery = toMetricQuery(withoutGrouping(q), resultSchema, execution);\n // The projection keeps only pushdown metric-filter terms; never send the\n // narrowed population silently. (Its other diagnostics, such as calendar\n // grouping, describe the v2 transport and do not apply here.)\n diagnostics.push(...metricQuery.diagnostics.filter(issue => issue.code === \"residual_metric_filter\" || issue.code === \"unexpanded_series\").map(issue => issue.message));\n const metrics = metricQuery.metrics.map(metric => {\n const dateGrouping = q.aggregations?.find(clause => clause.id === metric.id)?.dateGrouping;\n return dateGrouping ? { ...metric, dateGrouping } : metric;\n });\n for (const metric of metrics) {\n diagnostics.push(...validateMetric(metric, resultSchema).map(issue => issue.message));\n if (metric.dateGrouping && !capabilities.calendarGrouping) diagnostics.push(\"This server does not support calendar grouping.\");\n else if (isMetricCycle(metric.dateGrouping?.interval) && !capabilities.calendarCycles)\n diagnostics.push(\"This server does not support hour-of-day or day-of-week grouping.\");\n }\n const revisions: Record<string, string> = Object.create(null);\n for (const [id, revision] of Object.entries(execution?.resolvedRevisions ?? {})) {\n if (!revision || id.length > 256 || revision.length > 256) diagnostics.push(\"Invalid computed revision envelope.\");\n else revisions[id.startsWith(\"@computed/\") ? id.slice(10) : id] = revision;\n }\n return { version: 3, profile: capabilities.profile, now, expectedRevisions: revisions,\n ...(execution?.planToken ? { planToken: execution.planToken } : {}), ...(execution?.snapshot !== undefined ? { snapshot: execution.snapshot } : {}),\n source: sourceRequest, result, ...(q.grouping ? { grouping: { keys: q.grouping.keys,\n // Summary display is presentation only and link columns are computed on\n // the client; the wire contract is unchanged.\n summaries: withoutLinkSummaries(q.grouping.summaries).map(({ display: _display, ...summary }) => summary), representative: q.grouping.representative,\n ...(q.grouping.diagnostics ? { diagnostics: q.grouping.diagnostics } : {}) } } : {}), rows: options.rows !== false, metrics, diagnostics: [...new Set(diagnostics)] };\n}\nexport function validateQueryResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): void {\n if (!result || result.version !== 3 || result.now !== request.now || !Number.isSafeInteger(result.total) || result.total < 0 ||\n !Number.isSafeInteger(result.sourceTotal) || result.sourceTotal < 0 || !Array.isArray(result.rows) || !Array.isArray(result.metrics) ||\n result.execution?.profile !== request.profile || (result.execution.planToken ?? \"\") !== (request.planToken ?? \"\") ||\n (result.execution.snapshot ?? \"\") !== (request.snapshot ?? \"\") || result.schema?.idField !== schema.idField)\n throw Error(\"Invalid or mismatched query execution response.\");\n const expected = new Map(schema.fields.map(field => [field.name, field.type]));\n if (!Array.isArray(result.schema.fields) || result.schema.fields.some(field => expected.get(field.name) !== field.type) ||\n request.rows && request.result.select.some(name => !result.schema.fields.some(field => field.name === name))) throw Error(\"The server returned a different projected schema.\");\n for (const [id, revision] of Object.entries(request.expectedRevisions)) if (result.execution.resolvedRevisions[id] !== revision)\n throw Error(\"Computed definitions changed. Refresh the server execution handshake.\");\n const seen = new Set<unknown>();\n for (const row of result.rows) { const id = row[schema.idField]; if (typeof id !== \"string\" && typeof id !== \"number\" || seen.has(id)) throw Error(\"The server returned invalid or duplicate group identities.\"); seen.add(id); }\n}\n","// drilldown.ts — the query behind one metric bucket or one grouped row.\n//\n// Both helpers return a QueryState that selects exactly the records behind\n// what the user clicked, or null when no exact query exists. They never return\n// an approximate query: shown-row scopes and synthetic remainders are null.\n\nimport { compileFormula } from \"./formula\";\nimport { createGroupingModel, exitGrouping, GROUP_ID_FIELD, type GroupedRow } from \"./grouping\";\nimport {\n isMetricCycle,\n metricCalendarUnit,\n metricCycleSlot,\n metricCycleSlots,\n metricDateFloor,\n metricDateNext,\n metricDateTime,\n} from \"./metricDates\";\nimport { MAX_METRIC_WINDOW_PERIODS, metricDateBounds, wholeIntervalSpan } from \"./metricSeries\";\nimport { isFilterable, resolveField, type FieldSchema } from \"./schema\";\nimport { groupKeyTerms, keyClause } from \"./groupKeys\";\nimport type { AggregationBucket } from \"./encode\";\nimport { MAX_WHERE_CLAUSES, predicatesOf, type AggregationClause, type QueryState, type WhereTerm } from \"./query\";\nimport { appendWhereTerms } from \"./queryPatch\";\n\n/** Metrics over a grouped query read the group schema. Accept either that\n * schema or the source schema it is derived from. */\nfunction metricSchema(query: QueryState, schema: FieldSchema): FieldSchema {\n if (!query.grouping || schema.idField === GROUP_ID_FIELD) return schema;\n return createGroupingModel(schema).resultSchema(query.grouping.keys, query.grouping.summaries);\n}\n\nfunction distributionActive(clause: AggregationClause): boolean {\n return !!clause.distribution && (!clause.display || clause.display.kind === \"box\" || clause.display.kind === \"histogram\");\n}\n\n/** The query selecting the records behind one metric bucket, or null when no\n * exact query exists.\n *\n * - Each `clause.groupBy` key adds `=`; a null key adds `is_null` (legacy\n * aggregates already place empty text in that bucket).\n * - A date-grouped key becomes `>= start` and `< next`, using the clause's\n * interval and timezone. A windowed point starts at its window's first\n * interval, or has no lower bound for a running value.\n * - An hour-of-day or day-of-week slot selects its occurrences inside the\n * date field's bounds (whole ones with `occurrence` or whole intervals):\n * `>= first`, `< last end` and, for each gap between occurrences, an OR\n * group `< gap start` or `>= gap end`. Without a lower and an upper bound on\n * the date field, or when the filter would exceed the query's predicate\n * budget (about 48 occurrences), the result is null.\n * - A histogram bin (`bucket.bin`) adds `>= min` and `< max` (`<= max` for\n * the final bin) on the distribution input, which must be a field reference.\n * Box cohorts are their group keys.\n * - The clause's own `where` is added first, so the records match the metric's\n * population. Groups hidden by `minCount` have no bucket to inspect.\n * - Over a grouped query the filters are HAVING terms on the group rows.\n * - `scope: \"shownRows\"`, a remainder bucket (keys that do not match the\n * grouping) and keys on fields that cannot be filtered return null.\n *\n * Existing terms are kept, duplicates are not added and the offset resets. */\nexport function inspectBucketQuery(\n query: QueryState,\n bucket: AggregationBucket,\n clause: AggregationClause,\n schema: FieldSchema,\n): QueryState | null {\n if (clause.scope === \"shownRows\" || bucket.keys.length !== clause.groupBy.length) return null;\n const fields = metricSchema(query, schema);\n const terms: WhereTerm[] = [...(clause.where ?? [])];\n for (const [index, name] of clause.groupBy.entries()) {\n const field = resolveField(fields, name);\n const key = bucket.keys[index] ?? null;\n if (clause.dateGrouping && index === 0 && key !== null && isMetricCycle(clause.dateGrouping.interval)) {\n if (!field || field.type !== \"datetime\" || !isFilterable(field)) return null;\n const slot = cycleSlotTerms(query, clause, fields, field.name, key);\n if (!slot) return null;\n terms.push(...slot);\n continue;\n }\n if (clause.dateGrouping && index === 0 && key !== null) {\n if (!field || field.type !== \"datetime\" || !isFilterable(field)) return null;\n let start: number;\n try {\n start = metricDateTime(key);\n } catch {\n return null;\n }\n const { interval, timeZone, partialIntervals } = clause.dateGrouping;\n const next = metricDateNext(start, interval, timeZone);\n // A windowed point reads its trailing intervals; a running one, every\n // interval from the start of the range.\n let from: number | undefined = start;\n const periods = clause.window?.periods;\n if (periods === \"all\") from = undefined;\n else if (periods !== undefined) {\n if (!Number.isInteger(periods) || periods < 2 || periods > MAX_METRIC_WINDOW_PERIODS) return null;\n for (let i = 1; i < periods; i++) from = metricDateFloor(from! - 1, interval, timeZone);\n }\n if (partialIntervals === \"exclude\") {\n const whole = wholeIntervalSpan(clause, query, fields, Date.now()).start;\n if (whole !== undefined) from = Math.max(from ?? whole, whole);\n }\n if (from !== undefined) terms.push({ field: field.name, op: \">=\", value: new Date(from).toISOString() });\n terms.push({ field: field.name, op: \"<\", value: new Date(next).toISOString() });\n continue;\n }\n const term = keyClause(field, key);\n if (!term) return null;\n terms.push(term);\n }\n if (bucket.bin) {\n const { min, max, inclusiveMax } = bucket.bin;\n if (!distributionActive(clause) || clause.distribution!.kind !== \"histogram\" || !Number.isFinite(min) || !Number.isFinite(max) || max < min)\n return null;\n let input;\n try {\n input = compileFormula(clause.distribution!.input, fields.fields).ast;\n } catch {\n return null;\n }\n const field = input.kind === \"field\" ? resolveField(fields, input.name) : undefined;\n if (!field || field.type !== \"number\" || !isFilterable(field)) return null;\n terms.push(\n { field: field.name, op: \">=\", value: String(min) },\n { field: field.name, op: inclusiveMax ? \"<=\" : \"<\", value: String(max) },\n );\n }\n const where = appendWhereTerms(query.where, terms);\n // A slot's occurrence ranges must fit the query's predicate budget.\n if (isMetricCycle(clause.dateGrouping?.interval) &&\n where.reduce((n, term) => n + predicatesOf(term).length, 0) > MAX_WHERE_CLAUSES) return null;\n return { ...query, where, offset: 0 };\n}\n\n/** The records of one cyclic slot as CNF over the date field: the slot's\n * occurrences, clipped to the field's bounds, are disjoint ranges r1…rk, and\n * their union is `>= r1.start`, `< rk.end` and, for each gap, `< ri.end` OR\n * `>= ri+1.start`. Null when unbounded or too many occurrences. */\nfunction cycleSlotTerms(\n query: QueryState,\n clause: AggregationClause,\n schema: FieldSchema,\n field: string,\n key: unknown,\n): WhereTerm[] | null {\n const config = clause.dateGrouping!,\n cycle = config.interval;\n if (!isMetricCycle(cycle) || typeof key !== \"number\" || !metricCycleSlots(cycle).includes(key)) return null;\n const now = Date.now();\n let { lower, upper } = metricDateBounds(clause, query, schema, now);\n // The metric read whole occurrences (or whole intervals) only.\n const whole = config.occurrence\n ? { ...clause, dateGrouping: { ...config, interval: config.occurrence.interval } }\n : config.partialIntervals === \"exclude\" ? clause : undefined;\n if (whole) {\n const span = wholeIntervalSpan(whole, query, schema, now);\n lower = span.start ?? -Infinity;\n upper = span.end;\n }\n if (!Number.isFinite(lower) || !Number.isFinite(upper)) return null;\n // Gaps cost two predicates each; leave room for the query's own.\n const budget = Math.floor(MAX_WHERE_CLAUSES / 2);\n const ranges: [number, number][] = [];\n const unit = metricCalendarUnit(cycle);\n for (let start = metricDateFloor(lower, unit, config.timeZone); start < upper; ) {\n const next = metricDateNext(start, unit, config.timeZone);\n if (!Number.isFinite(next) || next <= start) return null;\n if (metricCycleSlot(start, cycle, config.timeZone) === key) {\n const from = Math.max(start, lower), to = Math.min(next, upper);\n const last = ranges[ranges.length - 1];\n if (from < to) {\n // Adjacent intervals of one slot (a repeated DST hour) merge.\n if (last && last[1] === from) last[1] = to;\n else if (ranges.push([from, to]) > budget) return null;\n }\n }\n start = next;\n }\n const iso = (time: number) => new Date(time).toISOString();\n if (!ranges.length)\n return [\n { field, op: \">=\", value: iso(lower) },\n { field, op: \"<\", value: iso(lower) },\n ];\n const terms: WhereTerm[] = [\n { field, op: \">=\", value: iso(ranges[0]![0]) },\n { field, op: \"<\", value: iso(ranges[ranges.length - 1]![1]) },\n ];\n for (let i = 0; i + 1 < ranges.length; i++)\n terms.push({ any: [\n { field, op: \"<\", value: iso(ranges[i]![1]) },\n { field, op: \">=\", value: iso(ranges[i + 1]![0]) },\n ] });\n return terms;\n}\n\n/** The record query behind one grouped row, or null when the query is not\n * grouped or a key cannot be matched exactly (textarray, unknown or\n * unfilterable fields, unparseable datetimes).\n *\n * Starts from the grouping source, as leaving the grouping stage does, so its\n * WHERE, columns, order and item details are kept. Each key adds `=` (or\n * `is_null` for a null key), a calendar key `>= start` and `< end` of its\n * interval, and the offset resets. */\nexport function groupSourceQuery(query: QueryState, group: GroupedRow, schema: FieldSchema): QueryState | null {\n if (!query.grouping) return null;\n const terms = groupKeyTerms(query.grouping.keys, group, schema);\n if (!terms) return null;\n const source = exitGrouping(query);\n return { ...source, where: appendWhereTerms(source.where, terms), offset: 0 };\n}\n"],"mappings":"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","names":["record","f","f","record","options","next","date","start","end","clause","field","resolveField","f","options","text","code","snapshot","a","b","n","parts","options","where","dateGrouping","f","value","compare","record","values","options","f","f","options","value","now","series","empty","options","resolveField","field","f","item","field","clone","options","definition","options","distributionActive"]}