@ryuzaki13/react-foundation-lib 2.31.0 → 2.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytical-table/index.js +8 -7
- package/dist/analytical-table/index.js.map +1 -1
- package/dist/chunks/formatDate-BUvpRI7H.js +133 -0
- package/dist/chunks/formatDate-BUvpRI7H.js.map +1 -0
- package/dist/chunks/{formatters-CZnnbdud.js → formatters-rxriDRPk.js} +14 -13
- package/dist/chunks/{formatters-CZnnbdud.js.map → formatters-rxriDRPk.js.map} +1 -1
- package/dist/chunks/scalarTypeClassification-BZcFmIyR.js +764 -0
- package/dist/chunks/scalarTypeClassification-BZcFmIyR.js.map +1 -0
- package/dist/chunks/{validate-CEQHqevt.js → validate-DsUR-bFF.js} +2 -2
- package/dist/chunks/{validate-CEQHqevt.js.map → validate-DsUR-bFF.js.map} +1 -1
- package/dist/error-report/index.js +2 -2
- package/dist/excel/index.js +20 -20
- package/dist/excel/index.js.map +1 -1
- package/dist/excel/tableExport.d.ts +2 -2
- package/dist/excel/tableExport.d.ts.map +1 -1
- package/dist/formatters/index.js +5 -4
- package/dist/formatters/pipeline/types.d.ts +4 -4
- package/dist/formatters/pipeline/types.d.ts.map +1 -1
- package/dist/hooks/useFloatingListbox.d.ts +1 -1
- package/dist/metadata/baseMetaTypes.d.ts +7 -0
- package/dist/metadata/baseMetaTypes.d.ts.map +1 -0
- package/dist/metadata/metadataTypes.d.ts +16 -0
- package/dist/metadata/metadataTypes.d.ts.map +1 -0
- package/dist/metadata/scalarTypeClassification.d.ts +8 -0
- package/dist/metadata/scalarTypeClassification.d.ts.map +1 -0
- package/dist/odata-service/baseTypes.d.ts +1 -5
- package/dist/odata-service/baseTypes.d.ts.map +1 -1
- package/dist/odata-service/formatters.d.ts +1 -2
- package/dist/odata-service/formatters.d.ts.map +1 -1
- package/dist/odata-service/index.js +1311 -2
- package/dist/odata-service/index.js.map +1 -0
- package/dist/odata-service/types.d.ts +8 -11
- package/dist/odata-service/types.d.ts.map +1 -1
- package/dist/odata-service/typesValidation.d.ts +1 -5
- package/dist/odata-service/typesValidation.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/formatters/README.mdx +5 -0
- package/src/foundationLib.mdx +8 -0
- package/src/metadata/README.md +35 -0
- package/src/odata-service/README.mdx +36 -1
- package/dist/chunks/odata-service-tp2U5yIr.js +0 -2211
- package/dist/chunks/odata-service-tp2U5yIr.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ct as e, dt as t, ft as n, lt as r, mt as i, ot as a, pt as o, st as s } from "../chunks/formatters-
|
|
1
|
+
import { ct as e, dt as t, ft as n, lt as r, mt as i, ot as a, pt as o, st as s } from "../chunks/formatters-rxriDRPk.js";
|
|
2
2
|
import { a as c, y as l } from "../chunks/array-D-_yMMUK.js";
|
|
3
3
|
import { r as u } from "../chunks/formulas-BXT_XBWI.js";
|
|
4
4
|
import { stableStringify as d } from "../utils/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { o as f, y as p } from "../chunks/formatDate-BUvpRI7H.js";
|
|
6
|
+
import { c as m, o as h } from "../chunks/scalarTypeClassification-BZcFmIyR.js";
|
|
6
7
|
import { t as g } from "../chunks/string-comparison-BKT7PXmq.js";
|
|
7
8
|
import { buildTreeTableRows as _ } from "../tree-table/index.js";
|
|
8
9
|
//#region src/analytical-table/runtime/aggregation.ts
|
|
@@ -394,7 +395,7 @@ function V(e) {
|
|
|
394
395
|
//#region src/analytical-table/dynamic-columns/dateColumns.ts
|
|
395
396
|
function H(e) {
|
|
396
397
|
if (typeof e != "string" || e.length !== 10) return null;
|
|
397
|
-
let t =
|
|
398
|
+
let t = m(e, "yyyy-MM-dd");
|
|
398
399
|
return t?.kind === "date-time" ? t.date : null;
|
|
399
400
|
}
|
|
400
401
|
function U(e, a) {
|
|
@@ -417,14 +418,14 @@ function W(t, n) {
|
|
|
417
418
|
}
|
|
418
419
|
function G(e) {
|
|
419
420
|
let t = H(e.from), n = H(e.to);
|
|
420
|
-
if (!t || !n ||
|
|
421
|
+
if (!t || !n || p(t) !== e.from || p(n) !== e.to || e.from > e.to) throw Error("Некорректный календарный диапазон аналитических столбцов.");
|
|
421
422
|
let r = e.maxColumns ?? 366;
|
|
422
423
|
if (!Number.isSafeInteger(r) || r < 1) throw Error("Лимит динамических столбцов должен быть положительным целым числом.");
|
|
423
424
|
if (!e.id || e.identityColumnIds.length === 0) throw Error("Динамическим столбцам нужны идентификатор и ключи сопоставления фактов.");
|
|
424
425
|
let i = [], o = U(t, e.granularity);
|
|
425
426
|
for (; o <= n;) {
|
|
426
427
|
if (i.length >= r) throw Error(`Превышен лимит динамических столбцов: ${r}`);
|
|
427
|
-
let t = W(o, e.granularity), n =
|
|
428
|
+
let t = W(o, e.granularity), n = p(o), s = p(a(t, -1));
|
|
428
429
|
i.push({
|
|
429
430
|
id: `${e.id}:${e.granularity}:${n}`,
|
|
430
431
|
label: e.granularity === "day" ? f(o) : `${n} — ${s}`,
|
|
@@ -444,8 +445,8 @@ function K(e, t) {
|
|
|
444
445
|
if (t.options.identityColumnIds.some((t) => e[t] === void 0 || e[t] === null)) return;
|
|
445
446
|
let n = H(e[t.options.dateColumnId]);
|
|
446
447
|
if (!n) return;
|
|
447
|
-
let r =
|
|
448
|
-
if (!(r < t.options.from || r > t.options.to)) return `${t.options.id}:${t.options.granularity}:${
|
|
448
|
+
let r = p(n);
|
|
449
|
+
if (!(r < t.options.from || r > t.options.to)) return `${t.options.id}:${t.options.granularity}:${p(U(n, t.options.granularity))}`;
|
|
449
450
|
}
|
|
450
451
|
function q(e, t) {
|
|
451
452
|
let n = /* @__PURE__ */ new Map();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/analytical-table/runtime/aggregation.ts","../../src/analytical-table/definition/calculations.ts","../../src/analytical-table/definition/compileAnalyticalTableDefinition.ts","../../src/analytical-table/definition/validateAnalyticalView.ts","../../src/analytical-table/projections/indexAnalyticalRows.ts","../../src/analytical-table/projections/resolveRowsProjection.ts","../../src/analytical-table/projections/expansion.ts","../../src/analytical-table/runtime/totals.ts","../../src/analytical-table/runtime/valueComparison.ts","../../src/analytical-table/runtime/grouping.ts","../../src/analytical-table/runtime/buildGroupedModel.ts","../../src/analytical-table/runtime/filtering.ts","../../src/analytical-table/runtime/hierarchy.ts","../../src/analytical-table/runtime/sorting.ts","../../src/analytical-table/runtime/createAnalyticalTableRuntime.ts","../../src/analytical-table/buildAnalyticalTableModel.ts","../../src/analytical-table/dynamic-columns/dateColumns.ts","../../src/analytical-table/projections/exportProjection.ts"],"sourcesContent":["import { type AnalyticalAggregation } from \"../types\";\n\n/** null/пустые/нечисловые значения не превращаются в ноль; count считает непустые факты. */\nexport function aggregateAnalyticalValues(values: readonly unknown[], aggregation: AnalyticalAggregation): number | null {\n\tconst present = values.filter((value) => value !== null && value !== undefined && value !== \"\");\n\tif (aggregation === \"count\") return present.length;\n\n\tlet count = 0;\n\tlet sum = 0;\n\tlet minimum = Infinity;\n\tlet maximum = -Infinity;\n\n\tfor (const value of present) {\n\t\tif (typeof value !== \"number\" || !Number.isFinite(value)) continue;\n\t\tcount += 1;\n\t\tsum += value;\n\t\tminimum = Math.min(minimum, value);\n\t\tmaximum = Math.max(maximum, value);\n\t}\n\n\tif (count === 0) return null;\n\n\tswitch (aggregation) {\n\t\tcase \"sum\":\n\t\t\treturn sum;\n\t\tcase \"min\":\n\t\t\treturn minimum;\n\t\tcase \"max\":\n\t\t\treturn maximum;\n\t\tcase \"avg\":\n\t\t\treturn sum / count;\n\t}\n}\n","import { arrayDeduplicate } from \"../../array\";\nimport { compileTableFormula } from \"../../formulas\";\nimport { type AnalyticalCalculationPlan, type AnalyticalCalculationStep, type AnalyticalColumn, type AnalyticalValues } from \"../types\";\n\n/** Проверяет граф зависимостей до расчёта строк и компилирует каждую формулу один раз. */\nexport function createAnalyticalCalculationPlan<T>(\n\tcolumns: readonly AnalyticalColumn<T>[],\n\trequiredColumnIds: readonly string[] = columns.map((column) => column.id)\n): AnalyticalCalculationPlan {\n\tconst byId = new Map(columns.map((column) => [column.id, column]));\n\tif (byId.size !== columns.length) throw new Error(\"Идентификаторы аналитических столбцов должны быть уникальны.\");\n\tconst visited = new Set<string>();\n\tconst visiting = new Set<string>();\n\tconst required: string[] = [];\n\tconst steps: AnalyticalCalculationStep[] = [];\n\tconst visit = (id: string): void => {\n\t\tif (visited.has(id)) return;\n\t\tif (visiting.has(id)) throw new Error(`Циклическая зависимость аналитического столбца: ${id}`);\n\t\tconst column = byId.get(id);\n\t\tif (!column) throw new Error(`Неизвестная зависимость аналитического столбца: ${id}`);\n\t\tif (column.formula && column.calculate) throw new Error(`Столбец ${id} содержит два способа вычисления.`);\n\t\tvisiting.add(id);\n\t\tconst dependencies = arrayDeduplicate(column.formula?.dependencies ?? column.calculate?.dependencies ?? []);\n\t\tfor (const dependency of dependencies) visit(dependency);\n\t\tif (column.formula) {\n\t\t\t// Порядок и повторы аргументов формулы сохраняются; уникален лишь граф зависимостей.\n\t\t\tconst compiled = compileTableFormula({ formulaId: column.formula.formulaId, keys: column.formula.dependencies });\n\t\t\tif (!compiled.ok) throw new Error(`Формула столбца ${id} не зарегистрирована: ${column.formula.formulaId}`);\n\t\t\tsteps.push({\n\t\t\t\tcolumnId: id,\n\t\t\t\tdependencies,\n\t\t\t\tcompute: (values) => {\n\t\t\t\t\tconst result = compiled.execute(values);\n\t\t\t\t\tif (!result.ok) throw new Error(`Ошибка формулы столбца ${id}: ${result.reason}`);\n\t\t\t\t\treturn result.value;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (column.calculate) {\n\t\t\tsteps.push({ columnId: id, dependencies, compute: column.calculate.compute });\n\t\t}\n\t\tvisiting.delete(id);\n\t\tvisited.add(id);\n\t\trequired.push(id);\n\t};\n\tfor (const id of requiredColumnIds) visit(id);\n\treturn { steps, requiredColumnIds: required };\n}\n\n/** Возвращает отдельный набор значений; исходный DTO и значения Query не мутируются. */\nexport function calculateAnalyticalValues(values: AnalyticalValues, plan: AnalyticalCalculationPlan): AnalyticalValues {\n\tconst result: Record<string, unknown> = { ...values };\n\tfor (const step of plan.steps) result[step.columnId] = step.compute(result);\n\treturn result;\n}\n","import { createAnalyticalCalculationPlan } from \"./calculations\";\nimport { type AnalyticalTableDefinition, type CompiledAnalyticalTableDefinition } from \"./types\";\n\n/** Проверяет единый каталог полей, включая служебные зависимости невидимых вычислений. */\nexport function compileAnalyticalTableDefinition<T>(definition: AnalyticalTableDefinition<T>): CompiledAnalyticalTableDefinition<T> {\n\tconst fields = [...definition.columns, ...(definition.dataFields ?? [])];\n\tconst calculations = createAnalyticalCalculationPlan(fields);\n\n\treturn {\n\t\tcolumns: definition.columns,\n\t\tfieldsById: new Map(fields.map((field) => [field.id, field])),\n\t\tcalculations,\n\t\taggregateFields: fields.filter((field) => field.aggregate !== undefined),\n\t\tisAggregateRow: definition.isAggregateRow,\n\t\taggregate: definition.aggregate,\n\t\tgrandTotals: definition.grandTotals !== false,\n\t\tgrandTotalsScope: definition.grandTotalsScope ?? \"filtered\"\n\t};\n}\n","import { type AnalyticalViewState } from \"../runtime/types\";\n\nimport { type CompiledAnalyticalTableDefinition } from \"./types\";\n\n/** Состояние ссылается на проверенное описание; grouping keys могут быть служебными полями values. */\nexport function validateAnalyticalView<T>(definition: CompiledAnalyticalTableDefinition<T>, state: AnalyticalViewState): void {\n\tfor (const entry of [...(state.sorting ?? []), ...(state.filters ?? [])]) {\n\t\tif (!definition.fieldsById.has(entry.id)) {\n\t\t\tthrow new Error(`Неизвестный аналитический столбец: ${entry.id}`);\n\t\t}\n\t}\n\n\tconst levelIds = new Set<string>();\n\tfor (const level of state.grouping ?? []) {\n\t\tif (levelIds.has(level.id)) {\n\t\t\tthrow new Error(\"Идентификаторы уровней группировки должны быть уникальны.\");\n\t\t}\n\t\tif (level.keyColumnIds.length === 0) {\n\t\t\tthrow new Error(`Уровень ${level.id} не содержит ключей группировки.`);\n\t\t}\n\t\tlevelIds.add(level.id);\n\t}\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\ntype RowTraversalFrame<T> = {\n\treadonly rows: readonly AnalyticalModelRow<T>[];\n\treadonly visible: boolean;\n\tnextIndex: number;\n};\n\n/** Строит согласованные индексы за один проход, не расходуя стек вызовов на глубину дерева. */\nexport function indexAnalyticalRows<T>(\n\trows: readonly AnalyticalModelRow<T>[]\n): Pick<AnalyticalTableModel<T>, \"flatRows\" | \"visibleRows\" | \"rowById\"> {\n\tconst flatRows: AnalyticalModelRow<T>[] = [];\n\tconst visibleRows: AnalyticalModelRow<T>[] = [];\n\tconst rowById = new Map<string, AnalyticalModelRow<T>>();\n\tconst stack: RowTraversalFrame<T>[] = [{ rows, visible: true, nextIndex: 0 }];\n\n\twhile (stack.length > 0) {\n\t\tconst frame = stack[stack.length - 1];\n\t\tif (frame.nextIndex === frame.rows.length) {\n\t\t\tstack.pop();\n\t\t\tcontinue;\n\t\t}\n\t\tconst row = frame.rows[frame.nextIndex++];\n\t\tflatRows.push(row);\n\t\trowById.set(row.id, row);\n\t\tif (frame.visible) visibleRows.push(row);\n\t\tif (row.children.length > 0) {\n\t\t\tstack.push({ rows: row.children, visible: frame.visible && row.isExpanded, nextIndex: 0 });\n\t\t}\n\t}\n\treturn { flatRows, visibleRows, rowById };\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\nimport { indexAnalyticalRows } from \"./indexAnalyticalRows\";\n\n/** Любая проекция дерева заменяет индексы вместе с узлами, сохраняя уже рассчитанные итоги. */\nexport function resolveRowsProjection<T>(model: AnalyticalTableModel<T>, rows: readonly AnalyticalModelRow<T>[]): AnalyticalTableModel<T> {\n\tif (rows === model.rows) return model;\n\treturn { ...model, rows, ...indexAnalyticalRows(rows) };\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\nimport { resolveRowsProjection } from \"./resolveRowsProjection\";\n\n/** Копирует массив только при замене его непосредственного ребёнка. */\nfunction replaceExpandedRows<T>(\n\trows: readonly AnalyticalModelRow<T>[],\n\treplacements: ReadonlyMap<AnalyticalModelRow<T>, AnalyticalModelRow<T>>\n): readonly AnalyticalModelRow<T>[] {\n\tlet projected: AnalyticalModelRow<T>[] | undefined;\n\tfor (let index = 0; index < rows.length; index++) {\n\t\tconst replacement = replacements.get(rows[index]);\n\t\tif (!replacement) continue;\n\t\tprojected ??= rows.slice();\n\t\tprojected[index] = replacement;\n\t}\n\treturn projected ?? rows;\n}\n\n/** Раскрытие меняет только затронутые ветви; формулы и итоги остаются результатом базовой модели. */\nexport function projectAnalyticalTableExpansion<T>(\n\tmodel: AnalyticalTableModel<T>,\n\texpandedRowIds: readonly string[] | \"all\"\n): AnalyticalTableModel<T> {\n\tconst expandAll = expandedRowIds === \"all\";\n\tconst expanded = new Set(expandAll ? [] : expandedRowIds);\n\tconst replacements = new Map<AnalyticalModelRow<T>, AnalyticalModelRow<T>>();\n\n\t// flatRows уже содержит обход родитель → дети. Обратный проход позволяет\n\t// заменить ребёнка до родителя без рекурсии и сохранить ссылки остальных ветвей.\n\tfor (let index = model.flatRows.length - 1; index >= 0; index--) {\n\t\tconst row = model.flatRows[index];\n\t\tconst children = replaceExpandedRows(row.children, replacements);\n\t\tconst isExpanded = row.isExpandable && (expandAll || expanded.has(row.id));\n\t\tif (isExpanded !== row.isExpanded || children !== row.children) {\n\t\t\treplacements.set(row, { ...row, isExpanded, children });\n\t\t}\n\t}\n\n\t// Неизвестные ID и листья не меняют эффективное раскрытие и не сбрасывают memo потребителей.\n\tif (replacements.size === 0) return model;\n\treturn resolveRowsProjection(model, replaceExpandedRows(model.rows, replacements));\n}\n","import { calculateAnalyticalValues } from \"../definition/calculations\";\nimport { type AnalyticalAggregateContext, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { aggregateAnalyticalValues } from \"./aggregation\";\nimport { type AnalyticalHierarchyNode } from \"./hierarchy\";\nimport { type AnalyticalDataRow, type AnalyticalValues } from \"./types\";\n\n/** Отбирает исходные строки выбранной зернистости; синтетические группы в итоги не попадают. */\nfunction collectAggregateRows<T>(\n\tnodes: readonly AnalyticalHierarchyNode<T>[],\n\taggregateRowIds: ReadonlySet<string>\n): AnalyticalDataRow<T>[] {\n\tconst rows: AnalyticalDataRow<T>[] = [];\n\tconst visit = (node: AnalyticalHierarchyNode<T>): void => {\n\t\tif (node.sourceRow && aggregateRowIds.has(node.id)) {\n\t\t\trows.push(node.sourceRow);\n\t\t}\n\n\t\tfor (const child of node.children) {\n\t\t\tvisit(child);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\tvisit(node);\n\t}\n\n\treturn rows;\n}\n\n/** Один порядок для групповых и общих итогов: агрегации → callback → зависимые формулы. */\nexport function calculateAnalyticalTotals<T>(args: {\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tnodes: readonly AnalyticalHierarchyNode<T>[];\n\taggregateRowIds: ReadonlySet<string>;\n\tscope: \"group\" | \"grand\";\n\tgroupingPath?: AnalyticalValues;\n}): AnalyticalValues {\n\tconst { definition, nodes, aggregateRowIds, scope, groupingPath = {} } = args;\n\tconst context: AnalyticalAggregateContext<T> = {\n\t\tscope,\n\t\trows: collectAggregateRows(nodes, aggregateRowIds),\n\t\tgroupingPath\n\t};\n\tconst values: Record<string, unknown> = { ...groupingPath };\n\n\tfor (const field of definition.aggregateFields) {\n\t\tconst aggregate = field.aggregate;\n\t\tif (aggregate === undefined) continue;\n\n\t\tvalues[field.id] =\n\t\t\ttypeof aggregate === \"function\"\n\t\t\t\t? aggregate(context)\n\t\t\t\t: aggregateAnalyticalValues(\n\t\t\t\t\t\tcontext.rows.map((row) => row.values[field.id]),\n\t\t\t\t\t\taggregate\n\t\t\t\t\t);\n\t}\n\n\tObject.assign(values, definition.aggregate?.(context));\n\n\t// Явные итоги и ключи пути сохраняются. Остальные формулы читают уже готовые\n\t// суммы: процент считается из сумм, а сумма произведений не заменяется произведением сумм.\n\tconst calculations = {\n\t\t...definition.calculations,\n\t\tsteps: definition.calculations.steps.filter((step) => !Object.hasOwn(values, step.columnId))\n\t};\n\n\treturn calculateAnalyticalValues(values, calculations);\n}\n","import { parseDate } from \"../../formatters\";\nimport { compareStrings } from \"../../string-comparison\";\nimport { stableStringify } from \"../../utils\";\nimport { type AnalyticalColumn, type AnalyticalValues } from \"../types\";\n\n/** Тип входит в ключ: null, undefined, строка и число не склеивают разные группы. */\nexport function analyticalIdentity(values: AnalyticalValues, ids: readonly string[]): string {\n\treturn stableStringify(\n\t\tids.map((id) => {\n\t\t\tconst value = values[id];\n\t\t\treturn [id, value === null ? \"null\" : typeof value, value];\n\t\t})\n\t);\n}\n\nexport function compareAnalyticalValues<T>(left: unknown, right: unknown, column?: AnalyticalColumn<T>): number {\n\tif (Object.is(left, right)) return 0;\n\tif (left === null || left === undefined) return 1;\n\tif (right === null || right === undefined) return -1;\n\tif (column?.compare) return column.compare(left, right);\n\tif (column?.valueType === \"date\") {\n\t\tconst leftDate = parseDate(left);\n\t\tconst rightDate = parseDate(right);\n\t\tif (leftDate && rightDate) return leftDate.getTime() - rightDate.getTime();\n\t}\n\tif (typeof left === \"number\" && typeof right === \"number\") return left - right;\n\tif (typeof left === \"boolean\" && typeof right === \"boolean\") return Number(left) - Number(right);\n\treturn compareStrings(String(left), String(right));\n}\n","import { stableStringify } from \"../../utils\";\nimport { type AnalyticalGroupingLevel, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { type AnalyticalHierarchyNode, type AnalyticalSourceHierarchy } from \"./hierarchy\";\nimport { calculateAnalyticalTotals } from \"./totals\";\nimport { type AnalyticalValues } from \"./types\";\nimport { analyticalIdentity } from \"./valueComparison\";\n\n/** Группировка добавляет уровни над предметными корнями и сохраняет их дочернюю детализацию. */\nexport function groupAnalyticalHierarchy<T>(args: {\n\trows: readonly AnalyticalHierarchyNode<T>[];\n\tgrouping: readonly AnalyticalGroupingLevel[];\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tsource: AnalyticalSourceHierarchy<T>;\n}): readonly AnalyticalHierarchyNode<T>[] {\n\tconst { grouping, definition, source } = args;\n\tconst groupLevel = (\n\t\trows: readonly AnalyticalHierarchyNode<T>[],\n\t\tlevelIndex: number,\n\t\tpath: AnalyticalValues,\n\t\tidentityPath: readonly string[]\n\t): readonly AnalyticalHierarchyNode<T>[] => {\n\t\tconst level = grouping[levelIndex];\n\t\tif (!level) return rows;\n\n\t\tconst buckets = new Map<string, AnalyticalHierarchyNode<T>[]>();\n\t\tfor (const row of rows) {\n\t\t\tconst key = analyticalIdentity(row.values, level.keyColumnIds);\n\t\t\tconst bucket = buckets.get(key);\n\t\t\tif (bucket) bucket.push(row);\n\t\t\telse buckets.set(key, [row]);\n\t\t}\n\n\t\treturn Array.from(buckets, ([key, members]) => {\n\t\t\tconst identity = [...identityPath, level.id, key];\n\t\t\tconst id = `analytical-group:${stableStringify(identity)}`;\n\t\t\tif (source.sourceRowIds.has(id)) {\n\t\t\t\tthrow new Error(`Идентификатор исходной строки совпал с группой: ${id}`);\n\t\t\t}\n\n\t\t\tconst groupingPath: Record<string, unknown> = { ...path };\n\t\t\tfor (const fieldId of [...level.keyColumnIds, ...(level.displayColumnIds ?? [])]) {\n\t\t\t\tgroupingPath[fieldId] = members[0].values[fieldId];\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tkind: \"group\",\n\t\t\t\tgroupingLevelId: level.id,\n\t\t\t\tvalues: calculateAnalyticalTotals({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tnodes: members,\n\t\t\t\t\taggregateRowIds: source.aggregateRowIds,\n\t\t\t\t\tscope: \"group\",\n\t\t\t\t\tgroupingPath\n\t\t\t\t}),\n\t\t\t\tchildren: groupLevel(members, levelIndex + 1, groupingPath, identity)\n\t\t\t};\n\t\t});\n\t};\n\n\treturn groupLevel(args.rows, 0, {}, []);\n}\n","import { type AnalyticalGroupingLevel, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\nimport { indexAnalyticalRows } from \"../projections/indexAnalyticalRows\";\n\nimport { groupAnalyticalHierarchy } from \"./grouping\";\nimport { type AnalyticalHierarchyNode, type AnalyticalSourceHierarchy } from \"./hierarchy\";\nimport { calculateAnalyticalTotals } from \"./totals\";\nimport { type AnalyticalModelRow, type AnalyticalTableModel } from \"./types\";\n\n/** Назначает конечные уровни и родителей после добавления всех группировок. */\nfunction materializeRows<T>(\n\tnodes: readonly AnalyticalHierarchyNode<T>[],\n\tparentId: string | null = null,\n\tlevel = 0\n): AnalyticalModelRow<T>[] {\n\treturn nodes.map((node) => ({\n\t\tid: node.id,\n\t\tparentId,\n\t\tkind: node.kind,\n\t\tsourceRow: node.sourceRow,\n\t\toriginal: node.sourceRow?.original,\n\t\tvalues: node.values,\n\t\tlevel,\n\t\tchildren: materializeRows(node.children, node.id, level + 1),\n\t\tisExpandable: node.children.length > 0,\n\t\tisExpanded: false,\n\t\tgroupingLevelId: node.groupingLevelId\n\t}));\n}\n\n/** Базовая модель содержит все отобранные строки и итоги; порядок и раскрытие задаются позже. */\nexport function buildGroupedAnalyticalModel<T>(args: {\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tsource: AnalyticalSourceHierarchy<T>;\n\tfilteredRows: readonly AnalyticalHierarchyNode<T>[];\n\tgrouping: readonly AnalyticalGroupingLevel[];\n}): AnalyticalTableModel<T> {\n\tconst { definition, source, filteredRows, grouping } = args;\n\tconst hierarchy = groupAnalyticalHierarchy({ rows: filteredRows, grouping, definition, source });\n\tconst rows = materializeRows(hierarchy);\n\tconst grandTotals = definition.grandTotals\n\t\t? calculateAnalyticalTotals({\n\t\t\t\tdefinition,\n\t\t\t\tnodes: definition.grandTotalsScope === \"all\" ? source.rows : filteredRows,\n\t\t\t\taggregateRowIds: source.aggregateRowIds,\n\t\t\t\tscope: \"grand\"\n\t\t\t})\n\t\t: null;\n\n\treturn {\n\t\tcolumns: definition.columns,\n\t\trows,\n\t\t...indexAnalyticalRows(rows),\n\t\tgrandTotals,\n\t\tdiagnostics: source.diagnostics\n\t};\n}\n","import { normalizeTextToLower } from \"../../formatters\";\nimport { type AnalyticalColumn, type AnalyticalDataRow, type AnalyticalFilter } from \"../types\";\n\nimport { type AnalyticalHierarchyNode } from \"./hierarchy\";\nimport { compareAnalyticalValues } from \"./valueComparison\";\n\n/** Операции фильтра относятся к данным, поэтому одинаково работают при SSR и в браузере. */\nexport function matchesAnalyticalFilter<T>(row: AnalyticalDataRow<T>, filter: AnalyticalFilter, column?: AnalyticalColumn<T>): boolean {\n\tconst value = row.values[filter.id];\n\tif (column?.filter) return column.filter(value, filter, row);\n\tconst expected = filter.value;\n\tconst compare = (other: unknown) => compareAnalyticalValues(value, other, column);\n\tconst empty = value === null || value === undefined || value === \"\";\n\tswitch (filter.operator ?? \"equals\") {\n\t\tcase \"equals\":\n\t\t\treturn compare(expected) === 0;\n\t\tcase \"notEquals\":\n\t\t\treturn compare(expected) !== 0;\n\t\tcase \"contains\":\n\t\t\treturn normalizeTextToLower(String(value ?? \"\")).includes(normalizeTextToLower(String(expected ?? \"\")));\n\t\tcase \"startsWith\":\n\t\t\treturn normalizeTextToLower(String(value ?? \"\")).startsWith(normalizeTextToLower(String(expected ?? \"\")));\n\t\tcase \"in\":\n\t\t\treturn Array.isArray(expected) && expected.some((item: unknown) => compare(item) === 0);\n\t\tcase \"between\":\n\t\t\treturn Array.isArray(expected) && expected.length === 2 && !empty && compare(expected[0]) >= 0 && compare(expected[1]) <= 0;\n\t\tcase \"gt\":\n\t\t\treturn !empty && compare(expected) > 0;\n\t\tcase \"gte\":\n\t\t\treturn !empty && compare(expected) >= 0;\n\t\tcase \"lt\":\n\t\t\treturn !empty && compare(expected) < 0;\n\t\tcase \"lte\":\n\t\t\treturn !empty && compare(expected) <= 0;\n\t\tcase \"empty\":\n\t\t\treturn empty;\n\t\tcase \"notEmpty\":\n\t\t\treturn !empty;\n\t}\n}\n\n/** Совпавший родитель оставляет всю ветвь; совпавший ребёнок сохраняет путь к нему. */\nexport function filterAnalyticalHierarchy<T>(\n\trows: readonly AnalyticalHierarchyNode<T>[],\n\tfilters: readonly AnalyticalFilter[],\n\tfieldsById: ReadonlyMap<string, AnalyticalColumn<T>>\n): readonly AnalyticalHierarchyNode<T>[] {\n\tif (filters.length === 0) return rows;\n\n\tconst filtered: AnalyticalHierarchyNode<T>[] = [];\n\tfor (const row of rows) {\n\t\tconst sourceRow = row.sourceRow;\n\t\tconst matches = sourceRow && filters.every((filter) => matchesAnalyticalFilter(sourceRow, filter, fieldsById.get(filter.id)));\n\t\tif (matches) {\n\t\t\tfiltered.push(row);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst children = filterAnalyticalHierarchy(row.children, filters, fieldsById);\n\t\tif (children.length > 0) {\n\t\t\tfiltered.push({ ...row, children });\n\t\t}\n\t}\n\n\treturn filtered;\n}\n","import { buildTreeTableRows, type TreeTableRowNode } from \"../../tree-table\";\nimport { calculateAnalyticalValues } from \"../definition/calculations\";\nimport { type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { type AnalyticalDataRow, type AnalyticalDiagnostics, type AnalyticalSnapshot, type AnalyticalValues } from \"./types\";\n\n/** Узел до назначения итогового parentId/level: группировка ещё может добавить предков. */\nexport type AnalyticalHierarchyNode<T> = Readonly<{\n\tid: string;\n\tkind: \"data\" | \"group\";\n\tsourceRow?: AnalyticalDataRow<T>;\n\tvalues: AnalyticalValues;\n\tchildren: readonly AnalyticalHierarchyNode<T>[];\n\tgroupingLevelId?: string;\n}>;\n\nexport type AnalyticalSourceHierarchy<T> = Readonly<{\n\trows: readonly AnalyticalHierarchyNode<T>[];\n\tsourceRowIds: ReadonlySet<string>;\n\taggregateRowIds: ReadonlySet<string>;\n\tdiagnostics: AnalyticalDiagnostics;\n}>;\n\n/** Формулы исходных строк и предметная иерархия зависят только от определения и снимка. */\nexport function prepareAnalyticalHierarchy<T>(\n\tsnapshot: AnalyticalSnapshot<T>,\n\tdefinition: CompiledAnalyticalTableDefinition<T>\n): AnalyticalSourceHierarchy<T> {\n\tif (snapshot.rows.some((row) => row.id.length === 0)) {\n\t\tthrow new Error(\"Идентификатор аналитической строки не может быть пустым.\");\n\t}\n\n\tconst calculatedRows = snapshot.rows.map((row) => ({\n\t\t...row,\n\t\tvalues: calculateAnalyticalValues(row.values, definition.calculations)\n\t}));\n\tconst tree = buildTreeTableRows(calculatedRows, {\n\t\tgetRowId: (row) => row.id,\n\t\tgetParentRowId: (row) => row.parentId\n\t});\n\n\tconst prepareNode = (node: TreeTableRowNode<AnalyticalDataRow<T>>): AnalyticalHierarchyNode<T> => ({\n\t\tid: node.id,\n\t\tkind: \"data\",\n\t\tsourceRow: tree.rowById.get(node.id),\n\t\tvalues: node.values,\n\t\tchildren: (node.children ?? []).map(prepareNode)\n\t});\n\tconst aggregateRowIds = definition.isAggregateRow\n\t\t? Array.from(tree.rowById.values())\n\t\t\t\t.filter(definition.isAggregateRow)\n\t\t\t\t.map((row) => row.id)\n\t\t: tree.rootRowIds;\n\n\treturn {\n\t\trows: tree.rows.map(prepareNode),\n\t\tsourceRowIds: new Set(tree.allRowIds),\n\t\taggregateRowIds: new Set(aggregateRowIds),\n\t\tdiagnostics: {\n\t\t\torphanRowIds: tree.orphanRowIds,\n\t\t\tduplicateRowIds: tree.duplicateRowIds,\n\t\t\tcyclicRowIds: tree.cyclicRowIds\n\t\t}\n\t};\n}\n","import { type AnalyticalColumn } from \"../definition/types\";\nimport { resolveRowsProjection } from \"../projections/resolveRowsProjection\";\n\nimport { type AnalyticalModelRow, type AnalyticalSorting, type AnalyticalTableModel } from \"./types\";\nimport { compareAnalyticalValues } from \"./valueComparison\";\n\n/** Меняет только порядок соседей: вычисленные значения, итоги и связи parent/child сохраняются. */\nexport function sortAnalyticalModel<T>(\n\tmodel: AnalyticalTableModel<T>,\n\tsorting: readonly AnalyticalSorting[],\n\tfieldsById: ReadonlyMap<string, AnalyticalColumn<T>>\n): AnalyticalTableModel<T> {\n\tif (sorting.length === 0) return model;\n\n\tconst compareRows = (left: AnalyticalModelRow<T>, right: AnalyticalModelRow<T>): number => {\n\t\tfor (const sort of sorting) {\n\t\t\tconst comparison = compareAnalyticalValues(left.values[sort.id], right.values[sort.id], fieldsById.get(sort.id));\n\t\t\tif (comparison !== 0) return sort.desc ? -comparison : comparison;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst sortBranch = (rows: readonly AnalyticalModelRow<T>[]): readonly AnalyticalModelRow<T>[] => {\n\t\tif (rows.length === 0) return rows;\n\n\t\tconst projected = rows.map((row) => {\n\t\t\tconst children = sortBranch(row.children);\n\t\t\treturn children === row.children ? row : { ...row, children };\n\t\t});\n\t\tprojected.sort(compareRows);\n\n\t\treturn projected.every((row, index) => row === rows[index]) ? rows : projected;\n\t};\n\n\treturn resolveRowsProjection(model, sortBranch(model.rows));\n}\n","import { validateAnalyticalView } from \"../definition/validateAnalyticalView\";\nimport { projectAnalyticalTableExpansion } from \"../projections/expansion\";\n\nimport { buildGroupedAnalyticalModel } from \"./buildGroupedModel\";\nimport { filterAnalyticalHierarchy } from \"./filtering\";\nimport { prepareAnalyticalHierarchy } from \"./hierarchy\";\nimport { sortAnalyticalModel } from \"./sorting\";\nimport {\n\ttype AnalyticalTableModel,\n\ttype AnalyticalTableRuntime,\n\ttype AnalyticalViewState,\n\ttype CreateAnalyticalTableRuntimeOptions\n} from \"./types\";\n\nconst EMPTY_STATE: AnalyticalViewState = {};\nconst EMPTY_ITEMS = Object.freeze([]);\n\n/**\n * Создаёт вычислительный runtime для одного снимка.\n *\n * Хранится только последний результат каждого этапа. Исходные строки рассчитываются\n * один раз; фильтры/группировки меняют итоги, сортировка — порядок, раскрытие — видимость.\n * Входные определения, снимки и массивы состояния должны оставаться неизменяемыми.\n */\nexport function createAnalyticalTableRuntime<T>(options: CreateAnalyticalTableRuntimeOptions<T>): AnalyticalTableRuntime<T> {\n\tconst { definition, snapshot } = options;\n\tconst source = prepareAnalyticalHierarchy(snapshot, definition);\n\tlet previousState: AnalyticalViewState = EMPTY_STATE;\n\tlet filteredRows = source.rows;\n\tlet groupedModel: AnalyticalTableModel<T> | undefined;\n\tlet sortedModel: AnalyticalTableModel<T> | undefined;\n\tlet expandedModel: AnalyticalTableModel<T> | undefined;\n\n\treturn {\n\t\tgetModel(state = EMPTY_STATE) {\n\t\t\tvalidateAnalyticalView(definition, state);\n\t\t\tconst filters = state.filters ?? EMPTY_ITEMS;\n\t\t\tconst grouping = state.grouping ?? EMPTY_ITEMS;\n\t\t\tconst sorting = state.sorting ?? EMPTY_ITEMS;\n\t\t\tconst expandedRowIds = state.expandedRowIds ?? EMPTY_ITEMS;\n\t\t\tconst filtersChanged = !groupedModel || filters !== (previousState.filters ?? EMPTY_ITEMS);\n\t\t\tconst groupingChanged = !groupedModel || grouping !== (previousState.grouping ?? EMPTY_ITEMS);\n\t\t\tconst sortingChanged = sorting !== (previousState.sorting ?? EMPTY_ITEMS);\n\t\t\tconst expansionChanged = expandedRowIds !== (previousState.expandedRowIds ?? EMPTY_ITEMS);\n\n\t\t\tconst nextFilteredRows = filtersChanged ? filterAnalyticalHierarchy(source.rows, filters, definition.fieldsById) : filteredRows;\n\n\t\t\tconst rebuildGroups = !groupedModel || filtersChanged || groupingChanged;\n\t\t\tconst nextGroupedModel = rebuildGroups\n\t\t\t\t? buildGroupedAnalyticalModel({ definition, source, filteredRows: nextFilteredRows, grouping })\n\t\t\t\t: groupedModel!;\n\n\t\t\tconst rebuildSorting = !sortedModel || rebuildGroups || sortingChanged;\n\t\t\tconst nextSortedModel = rebuildSorting ? sortAnalyticalModel(nextGroupedModel, sorting, definition.fieldsById) : sortedModel!;\n\n\t\t\tconst nextExpandedModel =\n\t\t\t\t!expandedModel || rebuildSorting || expansionChanged\n\t\t\t\t\t? projectAnalyticalTableExpansion(rebuildSorting ? nextSortedModel : (expandedModel ?? nextSortedModel), expandedRowIds)\n\t\t\t\t\t: expandedModel;\n\n\t\t\t// Ошибка callback не должна оставлять стадии от разных состояний в одном runtime.\n\t\t\tfilteredRows = nextFilteredRows;\n\t\t\tgroupedModel = nextGroupedModel;\n\t\t\tsortedModel = nextSortedModel;\n\t\t\texpandedModel = nextExpandedModel;\n\t\t\tpreviousState = { filters, grouping, sorting, expandedRowIds };\n\t\t\treturn expandedModel;\n\t\t}\n\t};\n}\n","import { compileAnalyticalTableDefinition } from \"./definition/compileAnalyticalTableDefinition\";\nimport { createAnalyticalTableRuntime } from \"./runtime/createAnalyticalTableRuntime\";\nimport { type AnalyticalTableModel, type BuildAnalyticalTableModelOptions } from \"./runtime/types\";\n\n/**\n * Строит таблицу за один вызов: описание → runtime снимка → модель представления.\n * Для последовательных изменений состояния сохраняйте определение и runtime отдельно.\n */\nexport function buildAnalyticalTableModel<T>(options: BuildAnalyticalTableModelOptions<T>): AnalyticalTableModel<T> {\n\tconst definition = compileAnalyticalTableDefinition(options);\n\tconst runtime = createAnalyticalTableRuntime({ definition, snapshot: options.snapshot });\n\n\treturn runtime.getModel(options.state);\n}\n","import {\n\taddCalendarDays,\n\taddCalendarMonths,\n\taddCalendarYears,\n\tcreateCalendarDate,\n\tformatDateAsDate,\n\tformatDateAsODataDate,\n\tgetStartOfDay,\n\tgetStartOfMonth,\n\tgetStartOfWeek,\n\tgetStartOfYear,\n\tparseDateByPattern\n} from \"../../formatters\";\nimport { aggregateAnalyticalValues } from \"../runtime/aggregation\";\nimport { type AnalyticalDataRow, type AnalyticalValues } from \"../runtime/types\";\nimport { analyticalIdentity } from \"../runtime/valueComparison\";\n\nimport {\n\ttype AnalyticalDateColumn,\n\ttype AnalyticalDateColumnsOptions,\n\ttype AnalyticalDateColumnsPlan,\n\ttype ProjectAnalyticalDateFactsOptions\n} from \"./types\";\n\n/** Принимает только календарный контракт; преобразование timestamp принадлежит transport/domain адаптеру. */\nfunction readCalendarDate(value: unknown): Date | null {\n\tif (typeof value !== \"string\" || value.length !== 10) return null;\n\tconst parsed = parseDateByPattern(value, \"yyyy-MM-dd\");\n\treturn parsed?.kind === \"date-time\" ? parsed.date : null;\n}\n\nfunction getDateBucketStart(date: Date, granularity: AnalyticalDateColumnsOptions[\"granularity\"]): Date {\n\tswitch (granularity) {\n\t\tcase \"day\":\n\t\t\treturn getStartOfDay(date);\n\t\tcase \"week\":\n\t\t\treturn getStartOfWeek(date, 1);\n\t\tcase \"month\":\n\t\t\treturn getStartOfMonth(date);\n\t\tcase \"quarter\":\n\t\t\treturn createCalendarDate(date.getFullYear(), Math.floor(date.getMonth() / 3) * 3, 1);\n\t\tcase \"year\":\n\t\t\treturn getStartOfYear(date);\n\t}\n}\n\nfunction getNextDateBucketStart(date: Date, granularity: AnalyticalDateColumnsOptions[\"granularity\"]): Date {\n\tswitch (granularity) {\n\t\tcase \"day\":\n\t\t\treturn addCalendarDays(date, 1);\n\t\tcase \"week\":\n\t\t\treturn addCalendarDays(date, 7);\n\t\tcase \"month\":\n\t\t\treturn addCalendarMonths(date, 1);\n\t\tcase \"quarter\":\n\t\t\treturn addCalendarMonths(date, 3);\n\t\tcase \"year\":\n\t\t\treturn addCalendarYears(date, 1);\n\t}\n}\n\n/** Строит ограниченный календарный план; ISO-моменты времени сюда не передаются. */\nexport function createAnalyticalDateColumnsPlan(options: AnalyticalDateColumnsOptions): AnalyticalDateColumnsPlan {\n\tconst from = readCalendarDate(options.from);\n\tconst to = readCalendarDate(options.to);\n\tif (\n\t\t!from ||\n\t\t!to ||\n\t\tformatDateAsODataDate(from) !== options.from ||\n\t\tformatDateAsODataDate(to) !== options.to ||\n\t\toptions.from > options.to\n\t)\n\t\tthrow new Error(\"Некорректный календарный диапазон аналитических столбцов.\");\n\tconst maxColumns = options.maxColumns ?? 366;\n\tif (!Number.isSafeInteger(maxColumns) || maxColumns < 1)\n\t\tthrow new Error(\"Лимит динамических столбцов должен быть положительным целым числом.\");\n\tif (!options.id || options.identityColumnIds.length === 0)\n\t\tthrow new Error(\"Динамическим столбцам нужны идентификатор и ключи сопоставления фактов.\");\n\n\t// Идентификатор относится ко всему календарному периоду, границы отбора — только к запрошенной части периода.\n\tconst columns: AnalyticalDateColumn[] = [];\n\tlet start = getDateBucketStart(from, options.granularity);\n\twhile (start <= to) {\n\t\tif (columns.length >= maxColumns) throw new Error(`Превышен лимит динамических столбцов: ${maxColumns}`);\n\t\tconst nextStart = getNextDateBucketStart(start, options.granularity);\n\t\tconst key = formatDateAsODataDate(start);\n\t\tconst end = formatDateAsODataDate(addCalendarDays(nextStart, -1));\n\t\tcolumns.push({\n\t\t\tid: `${options.id}:${options.granularity}:${key}`,\n\t\t\t// Подпись дня следует общей настройке date; машинные даты используют штатный odata-date.\n\t\t\tlabel: options.granularity === \"day\" ? formatDateAsDate(start) : `${key} — ${end}`,\n\t\t\tfrom: key < options.from ? options.from : key,\n\t\t\tto: end > options.to ? options.to : end\n\t\t});\n\t\tstart = nextStart;\n\t}\n\treturn { options: { ...options, identityColumnIds: [...options.identityColumnIds] }, columns };\n}\n\nfunction resolveFactColumnId(fact: AnalyticalValues, plan: AnalyticalDateColumnsPlan): string | undefined {\n\t// Факт без полного ключа нельзя сопоставить строке; общий итог использует ту же область допустимых фактов.\n\tif (plan.options.identityColumnIds.some((id) => fact[id] === undefined || fact[id] === null)) return undefined;\n\tconst date = readCalendarDate(fact[plan.options.dateColumnId]);\n\tif (!date) return undefined;\n\tconst day = formatDateAsODataDate(date);\n\tif (day < plan.options.from || day > plan.options.to) return undefined;\n\treturn `${plan.options.id}:${plan.options.granularity}:${formatDateAsODataDate(getDateBucketStart(date, plan.options.granularity))}`;\n}\n\n/** Индекс содержит исходные значения мер: выбор способа агрегации происходит после сопоставления фактов. */\nfunction indexFactMeasuresByIdentity(\n\tfacts: readonly AnalyticalValues[],\n\tplan: AnalyticalDateColumnsPlan\n): ReadonlyMap<string, ReadonlyMap<string, readonly unknown[]>> {\n\tconst byIdentity = new Map<string, Map<string, unknown[]>>();\n\tfor (const fact of facts) {\n\t\tconst columnId = resolveFactColumnId(fact, plan);\n\t\tif (!columnId) continue;\n\t\tconst identity = analyticalIdentity(fact, plan.options.identityColumnIds);\n\t\tlet buckets = byIdentity.get(identity);\n\t\tif (!buckets) {\n\t\t\tbuckets = new Map();\n\t\t\tbyIdentity.set(identity, buckets);\n\t\t}\n\t\tconst bucket = buckets.get(columnId);\n\t\tif (bucket) bucket.push(fact[plan.options.measureColumnId]);\n\t\telse buckets.set(columnId, [fact[plan.options.measureColumnId]]);\n\t}\n\treturn byIdentity;\n}\n\n/** Сопоставляет отдельные facts составному ключу строки; порядок и количество base rows неизменны. */\nexport function projectAnalyticalDateFacts<T>(args: ProjectAnalyticalDateFactsOptions<T>): readonly AnalyticalDataRow<T>[] {\n\tconst { rows, facts, plan } = args;\n\tconst byIdentity = indexFactMeasuresByIdentity(facts, plan);\n\treturn rows.map((row) => {\n\t\tconst buckets = byIdentity.get(analyticalIdentity(row.values, plan.options.identityColumnIds));\n\t\tconst values: Record<string, unknown> = { ...row.values };\n\t\tfor (const column of plan.columns) {\n\t\t\tif (Object.hasOwn(values, column.id)) throw new Error(`Динамический столбец перезаписывает исходное поле: ${column.id}`);\n\t\t\tconst bucket = buckets?.get(column.id);\n\t\t\tvalues[column.id] = bucket ? aggregateAnalyticalValues(bucket, plan.options.aggregation) : null;\n\t\t}\n\t\treturn { ...row, values };\n\t});\n}\n\n/**\n * Общие итоги считаются по исходным facts с полным ключом: среднее от средних не подменяет взвешенный результат.\n * Отбор допустимых непустых identities по области доступа и фильтрам выполняет вызывающий адаптер.\n */\nexport function aggregateAnalyticalDateFacts(facts: readonly AnalyticalValues[], plan: AnalyticalDateColumnsPlan): AnalyticalValues {\n\tconst buckets = new Map<string, unknown[]>();\n\tfor (const fact of facts) {\n\t\tconst id = resolveFactColumnId(fact, plan);\n\t\tif (!id) continue;\n\t\tconst bucket = buckets.get(id);\n\t\tif (bucket) bucket.push(fact[plan.options.measureColumnId]);\n\t\telse buckets.set(id, [fact[plan.options.measureColumnId]]);\n\t}\n\treturn Object.fromEntries(\n\t\tplan.columns.map((column) => {\n\t\t\tconst bucket = buckets.get(column.id);\n\t\t\treturn [column.id, bucket ? aggregateAnalyticalValues(bucket, plan.options.aggregation) : null];\n\t\t})\n\t);\n}\n","import {\n\ttype AnalyticalExportColumn,\n\ttype AnalyticalExportProjection,\n\ttype AnalyticalTableModel,\n\ttype ProjectAnalyticalTableExportOptions\n} from \"../types\";\n\n/** ID итога устойчив между областями экспорта и не конфликтует даже со скрытой строкой модели. */\nfunction resolveGrandTotalId<T>(model: AnalyticalTableModel<T>): string {\n\tconst baseId = \"analytical-grand-total\";\n\tlet id = baseId;\n\tlet suffix = 1;\n\twhile (model.rowById.has(id)) id = `${baseId}:${suffix++}`;\n\treturn id;\n}\n\n/** Проекция для /excel или /table-document; сам runtime не скачивает файлы и не читает DOM. */\nexport function projectAnalyticalTableExport<T>(args: ProjectAnalyticalTableExportOptions<T>): AnalyticalExportProjection {\n\tconst { model, scope = \"all\", includeGroups = true, includeGrandTotals = false } = args;\n\tconst columns: readonly AnalyticalExportColumn<T>[] = args.columns ?? model.columns;\n\tconst selected = new Set(args.selectedRowIds ?? []);\n\tconst source = scope === \"visible\" ? model.visibleRows : model.flatRows;\n\tconst rows: AnalyticalExportProjection[\"rows\"][number][] = [];\n\n\tfor (const row of source) {\n\t\tif (!includeGroups && row.kind === \"group\") continue;\n\t\tif (scope === \"selected\" && !selected.has(row.id)) continue;\n\t\trows.push({\n\t\t\tid: row.id,\n\t\t\tlevel: row.level,\n\t\t\tkind: row.kind,\n\t\t\tvalues: columns.map((column) => (column.format ? column.format(row.values[column.id], row) : row.values[column.id]))\n\t\t});\n\t}\n\n\tif (includeGrandTotals && model.grandTotals) {\n\t\tconst totals = model.grandTotals;\n\t\trows.push({\n\t\t\tid: resolveGrandTotalId(model),\n\t\t\tlevel: 0,\n\t\t\tkind: \"grand\",\n\t\t\tvalues: columns.map((column) => (column.formatTotal ? column.formatTotal(totals[column.id]) : totals[column.id]))\n\t\t});\n\t}\n\treturn { columns: columns.map((column) => ({ id: column.id, label: column.label ?? column.id })), rows };\n}\n"],"mappings":";;;;;;;;AAGA,SAAgB,EAA0B,GAA4B,GAAmD;CACxH,IAAM,IAAU,EAAO,QAAQ,MAAU,KAAU,QAA+B,MAAU,EAAE;CAC9F,IAAI,MAAgB,SAAS,OAAO,EAAQ;CAE5C,IAAI,IAAQ,GACR,IAAM,GACN,IAAU,UACV,IAAU;CAEd,KAAK,IAAM,KAAS,GACf,OAAO,KAAU,YAAY,CAAC,OAAO,SAAS,CAAK,MACvD,KAAS,GACT,KAAO,GACP,IAAU,KAAK,IAAI,GAAS,CAAK,GACjC,IAAU,KAAK,IAAI,GAAS,CAAK;CAGlC,IAAI,MAAU,GAAG,OAAO;CAExB,QAAQ,GAAR;EACC,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO;EACR,KAAK,OACJ,OAAO,IAAM;CACf;AACD;;;AC3BA,SAAgB,EACf,GACA,IAAuC,EAAQ,KAAK,MAAW,EAAO,EAAE,GAC5C;CAC5B,IAAM,IAAO,IAAI,IAAI,EAAQ,KAAK,MAAW,CAAC,EAAO,IAAI,CAAM,CAAC,CAAC;CACjE,IAAI,EAAK,SAAS,EAAQ,QAAQ,MAAU,MAAM,8DAA8D;CAChH,IAAM,oBAAU,IAAI,IAAY,GAC1B,oBAAW,IAAI,IAAY,GAC3B,IAAqB,CAAC,GACtB,IAAqC,CAAC,GACtC,KAAS,MAAqB;EACnC,IAAI,EAAQ,IAAI,CAAE,GAAG;EACrB,IAAI,EAAS,IAAI,CAAE,GAAG,MAAU,MAAM,mDAAmD,GAAI;EAC7F,IAAM,IAAS,EAAK,IAAI,CAAE;EAC1B,IAAI,CAAC,GAAQ,MAAU,MAAM,mDAAmD,GAAI;EACpF,IAAI,EAAO,WAAW,EAAO,WAAW,MAAU,MAAM,WAAW,EAAG,kCAAkC;EACxG,EAAS,IAAI,CAAE;EACf,IAAM,IAAe,EAAiB,EAAO,SAAS,gBAAgB,EAAO,WAAW,gBAAgB,CAAC,CAAC;EAC1G,KAAK,IAAM,KAAc,GAAc,EAAM,CAAU;EACvD,IAAI,EAAO,SAAS;GAEnB,IAAM,IAAW,EAAoB;IAAE,WAAW,EAAO,QAAQ;IAAW,MAAM,EAAO,QAAQ;GAAa,CAAC;GAC/G,IAAI,CAAC,EAAS,IAAI,MAAU,MAAM,mBAAmB,EAAG,wBAAwB,EAAO,QAAQ,WAAW;GAC1G,EAAM,KAAK;IACV,UAAU;IACV;IACA,UAAU,MAAW;KACpB,IAAM,IAAS,EAAS,QAAQ,CAAM;KACtC,IAAI,CAAC,EAAO,IAAI,MAAU,MAAM,0BAA0B,EAAG,IAAI,EAAO,QAAQ;KAChF,OAAO,EAAO;IACf;GACD,CAAC;EACF,OAAO,AAAI,EAAO,aACjB,EAAM,KAAK;GAAE,UAAU;GAAI;GAAc,SAAS,EAAO,UAAU;EAAQ,CAAC;EAI7E,AAFA,EAAS,OAAO,CAAE,GAClB,EAAQ,IAAI,CAAE,GACd,EAAS,KAAK,CAAE;CACjB;CACA,KAAK,IAAM,KAAM,GAAmB,EAAM,CAAE;CAC5C,OAAO;EAAE;EAAO,mBAAmB;CAAS;AAC7C;AAGA,SAAgB,EAA0B,GAA0B,GAAmD;CACtH,IAAM,IAAkC,EAAE,GAAG,EAAO;CACpD,KAAK,IAAM,KAAQ,EAAK,OAAO,EAAO,EAAK,YAAY,EAAK,QAAQ,CAAM;CAC1E,OAAO;AACR;;;ACjDA,SAAgB,EAAoC,GAAgF;CACnI,IAAM,IAAS,CAAC,GAAG,EAAW,SAAS,GAAI,EAAW,cAAc,CAAC,CAAE,GACjE,IAAe,EAAgC,CAAM;CAE3D,OAAO;EACN,SAAS,EAAW;EACpB,YAAY,IAAI,IAAI,EAAO,KAAK,MAAU,CAAC,EAAM,IAAI,CAAK,CAAC,CAAC;EAC5D;EACA,iBAAiB,EAAO,QAAQ,MAAU,EAAM,cAAc,KAAA,CAAS;EACvE,gBAAgB,EAAW;EAC3B,WAAW,EAAW;EACtB,aAAa,EAAW,gBAAgB;EACxC,kBAAkB,EAAW,oBAAoB;CAClD;AACD;;;ACbA,SAAgB,EAA0B,GAAkD,GAAkC;CAC7H,KAAK,IAAM,KAAS,CAAC,GAAI,EAAM,WAAW,CAAC,GAAI,GAAI,EAAM,WAAW,CAAC,CAAE,GACtE,IAAI,CAAC,EAAW,WAAW,IAAI,EAAM,EAAE,GACtC,MAAU,MAAM,sCAAsC,EAAM,IAAI;CAIlE,IAAM,oBAAW,IAAI,IAAY;CACjC,KAAK,IAAM,KAAS,EAAM,YAAY,CAAC,GAAG;EACzC,IAAI,EAAS,IAAI,EAAM,EAAE,GACxB,MAAU,MAAM,2DAA2D;EAE5E,IAAI,EAAM,aAAa,WAAW,GACjC,MAAU,MAAM,WAAW,EAAM,GAAG,iCAAiC;EAEtE,EAAS,IAAI,EAAM,EAAE;CACtB;AACD;;;ACbA,SAAgB,EACf,GACwE;CACxE,IAAM,IAAoC,CAAC,GACrC,IAAuC,CAAC,GACxC,oBAAU,IAAI,IAAmC,GACjD,IAAgC,CAAC;EAAE;EAAM,SAAS;EAAM,WAAW;CAAE,CAAC;CAE5E,OAAO,EAAM,SAAS,IAAG;EACxB,IAAM,IAAQ,EAAM,EAAM,SAAS;EACnC,IAAI,EAAM,cAAc,EAAM,KAAK,QAAQ;GAC1C,EAAM,IAAI;GACV;EACD;EACA,IAAM,IAAM,EAAM,KAAK,EAAM;EAI7B,AAHA,EAAS,KAAK,CAAG,GACjB,EAAQ,IAAI,EAAI,IAAI,CAAG,GACnB,EAAM,WAAS,EAAY,KAAK,CAAG,GACnC,EAAI,SAAS,SAAS,KACzB,EAAM,KAAK;GAAE,MAAM,EAAI;GAAU,SAAS,EAAM,WAAW,EAAI;GAAY,WAAW;EAAE,CAAC;CAE3F;CACA,OAAO;EAAE;EAAU;EAAa;CAAQ;AACzC;;;AC3BA,SAAgB,EAAyB,GAAgC,GAAiE;CAEzI,OADI,MAAS,EAAM,OAAa,IACzB;EAAE,GAAG;EAAO;EAAM,GAAG,EAAoB,CAAI;CAAE;AACvD;;;ACHA,SAAS,EACR,GACA,GACmC;CACnC,IAAI;CACJ,KAAK,IAAI,IAAQ,GAAG,IAAQ,EAAK,QAAQ,KAAS;EACjD,IAAM,IAAc,EAAa,IAAI,EAAK,EAAM;EAC3C,MACL,MAAc,EAAK,MAAM,GACzB,EAAU,KAAS;CACpB;CACA,OAAO,KAAa;AACrB;AAGA,SAAgB,EACf,GACA,GAC0B;CAC1B,IAAM,IAAY,MAAmB,OAC/B,IAAW,IAAI,IAAI,IAAY,CAAC,IAAI,CAAc,GAClD,oBAAe,IAAI,IAAkD;CAI3E,KAAK,IAAI,IAAQ,EAAM,SAAS,SAAS,GAAG,KAAS,GAAG,KAAS;EAChE,IAAM,IAAM,EAAM,SAAS,IACrB,IAAW,EAAoB,EAAI,UAAU,CAAY,GACzD,IAAa,EAAI,iBAAiB,KAAa,EAAS,IAAI,EAAI,EAAE;EACxE,CAAI,MAAe,EAAI,cAAc,MAAa,EAAI,aACrD,EAAa,IAAI,GAAK;GAAE,GAAG;GAAK;GAAY;EAAS,CAAC;CAExD;CAIA,OADI,EAAa,SAAS,IAAU,IAC7B,EAAsB,GAAO,EAAoB,EAAM,MAAM,CAAY,CAAC;AAClF;;;AClCA,SAAS,EACR,GACA,GACyB;CACzB,IAAM,IAA+B,CAAC,GAChC,KAAS,MAA2C;EACzD,AAAI,EAAK,aAAa,EAAgB,IAAI,EAAK,EAAE,KAChD,EAAK,KAAK,EAAK,SAAS;EAGzB,KAAK,IAAM,KAAS,EAAK,UACxB,EAAM,CAAK;CAEb;CAEA,KAAK,IAAM,KAAQ,GAClB,EAAM,CAAI;CAGX,OAAO;AACR;AAGA,SAAgB,EAA6B,GAMxB;CACpB,IAAM,EAAE,eAAY,UAAO,oBAAiB,UAAO,kBAAe,CAAC,MAAM,GACnE,IAAyC;EAC9C;EACA,MAAM,EAAqB,GAAO,CAAe;EACjD;CACD,GACM,IAAkC,EAAE,GAAG,EAAa;CAE1D,KAAK,IAAM,KAAS,EAAW,iBAAiB;EAC/C,IAAM,IAAY,EAAM;EACpB,MAAc,KAAA,MAElB,EAAO,EAAM,MACZ,OAAO,KAAc,aAClB,EAAU,CAAO,IACjB,EACA,EAAQ,KAAK,KAAK,MAAQ,EAAI,OAAO,EAAM,GAAG,GAC9C,CACD;CACJ;CAWA,OATA,OAAO,OAAO,GAAQ,EAAW,YAAY,CAAO,CAAC,GAS9C,EAA0B,GAAQ;EAJxC,GAAG,EAAW;EACd,OAAO,EAAW,aAAa,MAAM,QAAQ,MAAS,CAAC,OAAO,OAAO,GAAQ,EAAK,QAAQ,CAAC;CAGnD,CAAY;AACtD;;;AC/DA,SAAgB,EAAmB,GAA0B,GAAgC;CAC5F,OAAO,EACN,EAAI,KAAK,MAAO;EACf,IAAM,IAAQ,EAAO;EACrB,OAAO;GAAC;GAAI,MAAU,OAAO,SAAS,OAAO;GAAO;EAAK;CAC1D,CAAC,CACF;AACD;AAEA,SAAgB,EAA2B,GAAe,GAAgB,GAAsC;CAC/G,IAAI,OAAO,GAAG,GAAM,CAAK,GAAG,OAAO;CACnC,IAAI,KAAS,MAA4B,OAAO;CAChD,IAAI,KAAU,MAA6B,OAAO;CAClD,IAAI,GAAQ,SAAS,OAAO,EAAO,QAAQ,GAAM,CAAK;CACtD,IAAI,GAAQ,cAAc,QAAQ;EACjC,IAAM,IAAW,EAAU,CAAI,GACzB,IAAY,EAAU,CAAK;EACjC,IAAI,KAAY,GAAW,OAAO,EAAS,QAAQ,IAAI,EAAU,QAAQ;CAC1E;CAGA,OAFI,OAAO,KAAS,YAAY,OAAO,KAAU,WAAiB,IAAO,IACrE,OAAO,KAAS,aAAa,OAAO,KAAU,YAAkB,OAAO,CAAI,IAAI,OAAO,CAAK,IACxF,EAAe,OAAO,CAAI,GAAG,OAAO,CAAK,CAAC;AAClD;;;ACnBA,SAAgB,EAA4B,GAKF;CACzC,IAAM,EAAE,aAAU,eAAY,cAAW,GACnC,KACL,GACA,GACA,GACA,MAC2C;EAC3C,IAAM,IAAQ,EAAS;EACvB,IAAI,CAAC,GAAO,OAAO;EAEnB,IAAM,oBAAU,IAAI,IAA0C;EAC9D,KAAK,IAAM,KAAO,GAAM;GACvB,IAAM,IAAM,EAAmB,EAAI,QAAQ,EAAM,YAAY,GACvD,IAAS,EAAQ,IAAI,CAAG;GAC9B,AAAI,IAAQ,EAAO,KAAK,CAAG,IACtB,EAAQ,IAAI,GAAK,CAAC,CAAG,CAAC;EAC5B;EAEA,OAAO,MAAM,KAAK,IAAU,CAAC,GAAK,OAAa;GAC9C,IAAM,IAAW;IAAC,GAAG;IAAc,EAAM;IAAI;GAAG,GAC1C,IAAK,oBAAoB,EAAgB,CAAQ;GACvD,IAAI,EAAO,aAAa,IAAI,CAAE,GAC7B,MAAU,MAAM,mDAAmD,GAAI;GAGxE,IAAM,IAAwC,EAAE,GAAG,EAAK;GACxD,KAAK,IAAM,KAAW,CAAC,GAAG,EAAM,cAAc,GAAI,EAAM,oBAAoB,CAAC,CAAE,GAC9E,EAAa,KAAW,EAAQ,EAAE,CAAC,OAAO;GAG3C,OAAO;IACN;IACA,MAAM;IACN,iBAAiB,EAAM;IACvB,QAAQ,EAA0B;KACjC;KACA,OAAO;KACP,iBAAiB,EAAO;KACxB,OAAO;KACP;IACD,CAAC;IACD,UAAU,EAAW,GAAS,IAAa,GAAG,GAAc,CAAQ;GACrE;EACD,CAAC;CACF;CAEA,OAAO,EAAW,EAAK,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;AACvC;;;ACrDA,SAAS,EACR,GACA,IAA0B,MAC1B,IAAQ,GACkB;CAC1B,OAAO,EAAM,KAAK,OAAU;EAC3B,IAAI,EAAK;EACT;EACA,MAAM,EAAK;EACX,WAAW,EAAK;EAChB,UAAU,EAAK,WAAW;EAC1B,QAAQ,EAAK;EACb;EACA,UAAU,EAAgB,EAAK,UAAU,EAAK,IAAI,IAAQ,CAAC;EAC3D,cAAc,EAAK,SAAS,SAAS;EACrC,YAAY;EACZ,iBAAiB,EAAK;CACvB,EAAE;AACH;AAGA,SAAgB,EAA+B,GAKnB;CAC3B,IAAM,EAAE,eAAY,WAAQ,iBAAc,gBAAa,GAEjD,IAAO,EADK,EAAyB;EAAE,MAAM;EAAc;EAAU;EAAY;CAAO,CACjE,CAAS,GAChC,IAAc,EAAW,cAC5B,EAA0B;EAC1B;EACA,OAAO,EAAW,qBAAqB,QAAQ,EAAO,OAAO;EAC7D,iBAAiB,EAAO;EACxB,OAAO;CACR,CAAC,IACA;CAEH,OAAO;EACN,SAAS,EAAW;EACpB;EACA,GAAG,EAAoB,CAAI;EAC3B;EACA,aAAa,EAAO;CACrB;AACD;;;AChDA,SAAgB,EAA2B,GAA2B,GAA0B,GAAuC;CACtI,IAAM,IAAQ,EAAI,OAAO,EAAO;CAChC,IAAI,GAAQ,QAAQ,OAAO,EAAO,OAAO,GAAO,GAAQ,CAAG;CAC3D,IAAM,IAAW,EAAO,OAClB,KAAW,MAAmB,EAAwB,GAAO,GAAO,CAAM,GAC1E,IAAQ,KAAU,QAA+B,MAAU;CACjE,QAAQ,EAAO,YAAY,UAA3B;EACC,KAAK,UACJ,OAAO,EAAQ,CAAQ,MAAM;EAC9B,KAAK,aACJ,OAAO,EAAQ,CAAQ,MAAM;EAC9B,KAAK,YACJ,OAAO,EAAqB,OAAO,KAAS,EAAE,CAAC,CAAC,CAAC,SAAS,EAAqB,OAAO,KAAY,EAAE,CAAC,CAAC;EACvG,KAAK,cACJ,OAAO,EAAqB,OAAO,KAAS,EAAE,CAAC,CAAC,CAAC,WAAW,EAAqB,OAAO,KAAY,EAAE,CAAC,CAAC;EACzG,KAAK,MACJ,OAAO,MAAM,QAAQ,CAAQ,KAAK,EAAS,MAAM,MAAkB,EAAQ,CAAI,MAAM,CAAC;EACvF,KAAK,WACJ,OAAO,MAAM,QAAQ,CAAQ,KAAK,EAAS,WAAW,KAAK,CAAC,KAAS,EAAQ,EAAS,EAAE,KAAK,KAAK,EAAQ,EAAS,EAAE,KAAK;EAC3H,KAAK,MACJ,OAAO,CAAC,KAAS,EAAQ,CAAQ,IAAI;EACtC,KAAK,OACJ,OAAO,CAAC,KAAS,EAAQ,CAAQ,KAAK;EACvC,KAAK,MACJ,OAAO,CAAC,KAAS,EAAQ,CAAQ,IAAI;EACtC,KAAK,OACJ,OAAO,CAAC,KAAS,EAAQ,CAAQ,KAAK;EACvC,KAAK,SACJ,OAAO;EACR,KAAK,YACJ,OAAO,CAAC;CACV;AACD;AAGA,SAAgB,EACf,GACA,GACA,GACwC;CACxC,IAAI,EAAQ,WAAW,GAAG,OAAO;CAEjC,IAAM,IAAyC,CAAC;CAChD,KAAK,IAAM,KAAO,GAAM;EACvB,IAAM,IAAY,EAAI;EAEtB,IADgB,KAAa,EAAQ,OAAO,MAAW,EAAwB,GAAW,GAAQ,EAAW,IAAI,EAAO,EAAE,CAAC,CAAC,GAC/G;GACZ,EAAS,KAAK,CAAG;GACjB;EACD;EAEA,IAAM,IAAW,EAA0B,EAAI,UAAU,GAAS,CAAU;EAC5E,AAAI,EAAS,SAAS,KACrB,EAAS,KAAK;GAAE,GAAG;GAAK;EAAS,CAAC;CAEpC;CAEA,OAAO;AACR;;;ACzCA,SAAgB,EACf,GACA,GAC+B;CAC/B,IAAI,EAAS,KAAK,MAAM,MAAQ,EAAI,GAAG,WAAW,CAAC,GAClD,MAAU,MAAM,0DAA0D;CAG3E,IAAM,IAAiB,EAAS,KAAK,KAAK,OAAS;EAClD,GAAG;EACH,QAAQ,EAA0B,EAAI,QAAQ,EAAW,YAAY;CACtE,EAAE,GACI,IAAO,EAAmB,GAAgB;EAC/C,WAAW,MAAQ,EAAI;EACvB,iBAAiB,MAAQ,EAAI;CAC9B,CAAC,GAEK,KAAe,OAA8E;EAClG,IAAI,EAAK;EACT,MAAM;EACN,WAAW,EAAK,QAAQ,IAAI,EAAK,EAAE;EACnC,QAAQ,EAAK;EACb,WAAW,EAAK,YAAY,CAAC,EAAA,CAAG,IAAI,CAAW;CAChD,IACM,IAAkB,EAAW,iBAChC,MAAM,KAAK,EAAK,QAAQ,OAAO,CAAC,CAAC,CAChC,OAAO,EAAW,cAAc,CAAC,CACjC,KAAK,MAAQ,EAAI,EAAE,IACpB,EAAK;CAER,OAAO;EACN,MAAM,EAAK,KAAK,IAAI,CAAW;EAC/B,cAAc,IAAI,IAAI,EAAK,SAAS;EACpC,iBAAiB,IAAI,IAAI,CAAe;EACxC,aAAa;GACZ,cAAc,EAAK;GACnB,iBAAiB,EAAK;GACtB,cAAc,EAAK;EACpB;CACD;AACD;;;ACzDA,SAAgB,EACf,GACA,GACA,GAC0B;CAC1B,IAAI,EAAQ,WAAW,GAAG,OAAO;CAEjC,IAAM,KAAe,GAA6B,MAAyC;EAC1F,KAAK,IAAM,KAAQ,GAAS;GAC3B,IAAM,IAAa,EAAwB,EAAK,OAAO,EAAK,KAAK,EAAM,OAAO,EAAK,KAAK,EAAW,IAAI,EAAK,EAAE,CAAC;GAC/G,IAAI,MAAe,GAAG,OAAO,EAAK,OAAO,CAAC,IAAa;EACxD;EACA,OAAO;CACR,GACM,KAAc,MAA6E;EAChG,IAAI,EAAK,WAAW,GAAG,OAAO;EAE9B,IAAM,IAAY,EAAK,KAAK,MAAQ;GACnC,IAAM,IAAW,EAAW,EAAI,QAAQ;GACxC,OAAO,MAAa,EAAI,WAAW,IAAM;IAAE,GAAG;IAAK;GAAS;EAC7D,CAAC;EAGD,OAFA,EAAU,KAAK,CAAW,GAEnB,EAAU,OAAO,GAAK,MAAU,MAAQ,EAAK,EAAM,IAAI,IAAO;CACtE;CAEA,OAAO,EAAsB,GAAO,EAAW,EAAM,IAAI,CAAC;AAC3D;;;ACpBA,IAAM,IAAmC,CAAC,GACpC,IAAc,OAAO,OAAO,CAAC,CAAC;AASpC,SAAgB,EAAgC,GAA4E;CAC3H,IAAM,EAAE,eAAY,gBAAa,GAC3B,IAAS,EAA2B,GAAU,CAAU,GAC1D,IAAqC,GACrC,IAAe,EAAO,MACtB,GACA,GACA;CAEJ,OAAO,EACN,SAAS,IAAQ,GAAa;EAC7B,EAAuB,GAAY,CAAK;EACxC,IAAM,IAAU,EAAM,WAAW,GAC3B,IAAW,EAAM,YAAY,GAC7B,IAAU,EAAM,WAAW,GAC3B,IAAiB,EAAM,kBAAkB,GACzC,IAAiB,CAAC,KAAgB,OAAa,EAAc,WAAW,IACxE,IAAkB,CAAC,KAAgB,OAAc,EAAc,YAAY,IAC3E,IAAiB,OAAa,EAAc,WAAW,IACvD,IAAmB,OAAoB,EAAc,kBAAkB,IAEvE,IAAmB,IAAiB,EAA0B,EAAO,MAAM,GAAS,EAAW,UAAU,IAAI,GAE7G,IAAgB,CAAC,KAAgB,KAAkB,GACnD,IAAmB,IACtB,EAA4B;GAAE;GAAY;GAAQ,cAAc;GAAkB;EAAS,CAAC,IAC5F,GAEG,IAAiB,CAAC,KAAe,KAAiB,GAClD,IAAkB,IAAiB,EAAoB,GAAkB,GAAS,EAAW,UAAU,IAAI,GAE3G,IACL,CAAC,KAAiB,KAAkB,IACjC,EAAgC,IAAiB,IAAmB,KAAiB,GAAkB,CAAc,IACrH;EAQJ,OALA,IAAe,GACf,IAAe,GACf,IAAc,GACd,IAAgB,GAChB,IAAgB;GAAE;GAAS;GAAU;GAAS;EAAe,GACtD;CACR,EACD;AACD;;;AC7DA,SAAgB,EAA6B,GAAuE;CAInH,OAFgB,EAA6B;EAAE,YAD5B,EAAiC,CACL;EAAY,UAAU,EAAQ;CAAS,CAE/E,CAAA,CAAQ,SAAS,EAAQ,KAAK;AACtC;;;ACYA,SAAS,EAAiB,GAA6B;CACtD,IAAI,OAAO,KAAU,YAAY,EAAM,WAAW,IAAI,OAAO;CAC7D,IAAM,IAAS,EAAmB,GAAO,YAAY;CACrD,OAAO,GAAQ,SAAS,cAAc,EAAO,OAAO;AACrD;AAEA,SAAS,EAAmB,GAAY,GAAgE;CACvG,QAAQ,GAAR;EACC,KAAK,OACJ,OAAO,EAAc,CAAI;EAC1B,KAAK,QACJ,OAAO,EAAe,GAAM,CAAC;EAC9B,KAAK,SACJ,OAAO,EAAgB,CAAI;EAC5B,KAAK,WACJ,OAAO,EAAmB,EAAK,YAAY,GAAG,KAAK,MAAM,EAAK,SAAS,IAAI,CAAC,IAAI,GAAG,CAAC;EACrF,KAAK,QACJ,OAAO,EAAe,CAAI;CAC5B;AACD;AAEA,SAAS,EAAuB,GAAY,GAAgE;CAC3G,QAAQ,GAAR;EACC,KAAK,OACJ,OAAO,EAAgB,GAAM,CAAC;EAC/B,KAAK,QACJ,OAAO,EAAgB,GAAM,CAAC;EAC/B,KAAK,SACJ,OAAO,EAAkB,GAAM,CAAC;EACjC,KAAK,WACJ,OAAO,EAAkB,GAAM,CAAC;EACjC,KAAK,QACJ,OAAO,EAAiB,GAAM,CAAC;CACjC;AACD;AAGA,SAAgB,EAAgC,GAAkE;CACjH,IAAM,IAAO,EAAiB,EAAQ,IAAI,GACpC,IAAK,EAAiB,EAAQ,EAAE;CACtC,IACC,CAAC,KACD,CAAC,KACD,EAAsB,CAAI,MAAM,EAAQ,QACxC,EAAsB,CAAE,MAAM,EAAQ,MACtC,EAAQ,OAAO,EAAQ,IAEvB,MAAU,MAAM,2DAA2D;CAC5E,IAAM,IAAa,EAAQ,cAAc;CACzC,IAAI,CAAC,OAAO,cAAc,CAAU,KAAK,IAAa,GACrD,MAAU,MAAM,qEAAqE;CACtF,IAAI,CAAC,EAAQ,MAAM,EAAQ,kBAAkB,WAAW,GACvD,MAAU,MAAM,yEAAyE;CAG1F,IAAM,IAAkC,CAAC,GACrC,IAAQ,EAAmB,GAAM,EAAQ,WAAW;CACxD,OAAO,KAAS,IAAI;EACnB,IAAI,EAAQ,UAAU,GAAY,MAAU,MAAM,yCAAyC,GAAY;EACvG,IAAM,IAAY,EAAuB,GAAO,EAAQ,WAAW,GAC7D,IAAM,EAAsB,CAAK,GACjC,IAAM,EAAsB,EAAgB,GAAW,EAAE,CAAC;EAQhE,AAPA,EAAQ,KAAK;GACZ,IAAI,GAAG,EAAQ,GAAG,GAAG,EAAQ,YAAY,GAAG;GAE5C,OAAO,EAAQ,gBAAgB,QAAQ,EAAiB,CAAK,IAAI,GAAG,EAAI,KAAK;GAC7E,MAAM,IAAM,EAAQ,OAAO,EAAQ,OAAO;GAC1C,IAAI,IAAM,EAAQ,KAAK,EAAQ,KAAK;EACrC,CAAC,GACD,IAAQ;CACT;CACA,OAAO;EAAE,SAAS;GAAE,GAAG;GAAS,mBAAmB,CAAC,GAAG,EAAQ,iBAAiB;EAAE;EAAG;CAAQ;AAC9F;AAEA,SAAS,EAAoB,GAAwB,GAAqD;CAEzG,IAAI,EAAK,QAAQ,kBAAkB,MAAM,MAAO,EAAK,OAAQ,KAAA,KAAa,EAAK,OAAQ,IAAI,GAAG;CAC9F,IAAM,IAAO,EAAiB,EAAK,EAAK,QAAQ,aAAa;CAC7D,IAAI,CAAC,GAAM;CACX,IAAM,IAAM,EAAsB,CAAI;CAClC,UAAM,EAAK,QAAQ,QAAQ,IAAM,EAAK,QAAQ,KAClD,OAAO,GAAG,EAAK,QAAQ,GAAG,GAAG,EAAK,QAAQ,YAAY,GAAG,EAAsB,EAAmB,GAAM,EAAK,QAAQ,WAAW,CAAC;AAClI;AAGA,SAAS,EACR,GACA,GAC+D;CAC/D,IAAM,oBAAa,IAAI,IAAoC;CAC3D,KAAK,IAAM,KAAQ,GAAO;EACzB,IAAM,IAAW,EAAoB,GAAM,CAAI;EAC/C,IAAI,CAAC,GAAU;EACf,IAAM,IAAW,EAAmB,GAAM,EAAK,QAAQ,iBAAiB,GACpE,IAAU,EAAW,IAAI,CAAQ;EACrC,AAAK,MACJ,oBAAU,IAAI,IAAI,GAClB,EAAW,IAAI,GAAU,CAAO;EAEjC,IAAM,IAAS,EAAQ,IAAI,CAAQ;EACnC,AAAI,IAAQ,EAAO,KAAK,EAAK,EAAK,QAAQ,gBAAgB,IACrD,EAAQ,IAAI,GAAU,CAAC,EAAK,EAAK,QAAQ,gBAAgB,CAAC;CAChE;CACA,OAAO;AACR;AAGA,SAAgB,EAA8B,GAA6E;CAC1H,IAAM,EAAE,SAAM,UAAO,YAAS,GACxB,IAAa,EAA4B,GAAO,CAAI;CAC1D,OAAO,EAAK,KAAK,MAAQ;EACxB,IAAM,IAAU,EAAW,IAAI,EAAmB,EAAI,QAAQ,EAAK,QAAQ,iBAAiB,CAAC,GACvF,IAAkC,EAAE,GAAG,EAAI,OAAO;EACxD,KAAK,IAAM,KAAU,EAAK,SAAS;GAClC,IAAI,OAAO,OAAO,GAAQ,EAAO,EAAE,GAAG,MAAU,MAAM,sDAAsD,EAAO,IAAI;GACvH,IAAM,IAAS,GAAS,IAAI,EAAO,EAAE;GACrC,EAAO,EAAO,MAAM,IAAS,EAA0B,GAAQ,EAAK,QAAQ,WAAW,IAAI;EAC5F;EACA,OAAO;GAAE,GAAG;GAAK;EAAO;CACzB,CAAC;AACF;AAMA,SAAgB,EAA6B,GAAoC,GAAmD;CACnI,IAAM,oBAAU,IAAI,IAAuB;CAC3C,KAAK,IAAM,KAAQ,GAAO;EACzB,IAAM,IAAK,EAAoB,GAAM,CAAI;EACzC,IAAI,CAAC,GAAI;EACT,IAAM,IAAS,EAAQ,IAAI,CAAE;EAC7B,AAAI,IAAQ,EAAO,KAAK,EAAK,EAAK,QAAQ,gBAAgB,IACrD,EAAQ,IAAI,GAAI,CAAC,EAAK,EAAK,QAAQ,gBAAgB,CAAC;CAC1D;CACA,OAAO,OAAO,YACb,EAAK,QAAQ,KAAK,MAAW;EAC5B,IAAM,IAAS,EAAQ,IAAI,EAAO,EAAE;EACpC,OAAO,CAAC,EAAO,IAAI,IAAS,EAA0B,GAAQ,EAAK,QAAQ,WAAW,IAAI,IAAI;CAC/F,CAAC,CACF;AACD;;;AC9JA,SAAS,EAAuB,GAAwC;CACvE,IAAM,IAAS,0BACX,IAAK,GACL,IAAS;CACb,OAAO,EAAM,QAAQ,IAAI,CAAE,IAAG,IAAK,GAAG,EAAO,GAAG;CAChD,OAAO;AACR;AAGA,SAAgB,EAAgC,GAA0E;CACzH,IAAM,EAAE,UAAO,WAAQ,OAAO,mBAAgB,IAAM,wBAAqB,OAAU,GAC7E,IAAgD,EAAK,WAAW,EAAM,SACtE,IAAW,IAAI,IAAI,EAAK,kBAAkB,CAAC,CAAC,GAC5C,IAAS,MAAU,YAAY,EAAM,cAAc,EAAM,UACzD,IAAqD,CAAC;CAE5D,KAAK,IAAM,KAAO,GACb,CAAC,KAAiB,EAAI,SAAS,WAC/B,MAAU,cAAc,CAAC,EAAS,IAAI,EAAI,EAAE,KAChD,EAAK,KAAK;EACT,IAAI,EAAI;EACR,OAAO,EAAI;EACX,MAAM,EAAI;EACV,QAAQ,EAAQ,KAAK,MAAY,EAAO,SAAS,EAAO,OAAO,EAAI,OAAO,EAAO,KAAK,CAAG,IAAI,EAAI,OAAO,EAAO,GAAI;CACpH,CAAC;CAGF,IAAI,KAAsB,EAAM,aAAa;EAC5C,IAAM,IAAS,EAAM;EACrB,EAAK,KAAK;GACT,IAAI,EAAoB,CAAK;GAC7B,OAAO;GACP,MAAM;GACN,QAAQ,EAAQ,KAAK,MAAY,EAAO,cAAc,EAAO,YAAY,EAAO,EAAO,GAAG,IAAI,EAAO,EAAO,GAAI;EACjH,CAAC;CACF;CACA,OAAO;EAAE,SAAS,EAAQ,KAAK,OAAY;GAAE,IAAI,EAAO;GAAI,OAAO,EAAO,SAAS,EAAO;EAAG,EAAE;EAAG;CAAK;AACxG"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/analytical-table/runtime/aggregation.ts","../../src/analytical-table/definition/calculations.ts","../../src/analytical-table/definition/compileAnalyticalTableDefinition.ts","../../src/analytical-table/definition/validateAnalyticalView.ts","../../src/analytical-table/projections/indexAnalyticalRows.ts","../../src/analytical-table/projections/resolveRowsProjection.ts","../../src/analytical-table/projections/expansion.ts","../../src/analytical-table/runtime/totals.ts","../../src/analytical-table/runtime/valueComparison.ts","../../src/analytical-table/runtime/grouping.ts","../../src/analytical-table/runtime/buildGroupedModel.ts","../../src/analytical-table/runtime/filtering.ts","../../src/analytical-table/runtime/hierarchy.ts","../../src/analytical-table/runtime/sorting.ts","../../src/analytical-table/runtime/createAnalyticalTableRuntime.ts","../../src/analytical-table/buildAnalyticalTableModel.ts","../../src/analytical-table/dynamic-columns/dateColumns.ts","../../src/analytical-table/projections/exportProjection.ts"],"sourcesContent":["import { type AnalyticalAggregation } from \"../types\";\n\n/** null/пустые/нечисловые значения не превращаются в ноль; count считает непустые факты. */\nexport function aggregateAnalyticalValues(values: readonly unknown[], aggregation: AnalyticalAggregation): number | null {\n\tconst present = values.filter((value) => value !== null && value !== undefined && value !== \"\");\n\tif (aggregation === \"count\") return present.length;\n\n\tlet count = 0;\n\tlet sum = 0;\n\tlet minimum = Infinity;\n\tlet maximum = -Infinity;\n\n\tfor (const value of present) {\n\t\tif (typeof value !== \"number\" || !Number.isFinite(value)) continue;\n\t\tcount += 1;\n\t\tsum += value;\n\t\tminimum = Math.min(minimum, value);\n\t\tmaximum = Math.max(maximum, value);\n\t}\n\n\tif (count === 0) return null;\n\n\tswitch (aggregation) {\n\t\tcase \"sum\":\n\t\t\treturn sum;\n\t\tcase \"min\":\n\t\t\treturn minimum;\n\t\tcase \"max\":\n\t\t\treturn maximum;\n\t\tcase \"avg\":\n\t\t\treturn sum / count;\n\t}\n}\n","import { arrayDeduplicate } from \"../../array\";\nimport { compileTableFormula } from \"../../formulas\";\nimport { type AnalyticalCalculationPlan, type AnalyticalCalculationStep, type AnalyticalColumn, type AnalyticalValues } from \"../types\";\n\n/** Проверяет граф зависимостей до расчёта строк и компилирует каждую формулу один раз. */\nexport function createAnalyticalCalculationPlan<T>(\n\tcolumns: readonly AnalyticalColumn<T>[],\n\trequiredColumnIds: readonly string[] = columns.map((column) => column.id)\n): AnalyticalCalculationPlan {\n\tconst byId = new Map(columns.map((column) => [column.id, column]));\n\tif (byId.size !== columns.length) throw new Error(\"Идентификаторы аналитических столбцов должны быть уникальны.\");\n\tconst visited = new Set<string>();\n\tconst visiting = new Set<string>();\n\tconst required: string[] = [];\n\tconst steps: AnalyticalCalculationStep[] = [];\n\tconst visit = (id: string): void => {\n\t\tif (visited.has(id)) return;\n\t\tif (visiting.has(id)) throw new Error(`Циклическая зависимость аналитического столбца: ${id}`);\n\t\tconst column = byId.get(id);\n\t\tif (!column) throw new Error(`Неизвестная зависимость аналитического столбца: ${id}`);\n\t\tif (column.formula && column.calculate) throw new Error(`Столбец ${id} содержит два способа вычисления.`);\n\t\tvisiting.add(id);\n\t\tconst dependencies = arrayDeduplicate(column.formula?.dependencies ?? column.calculate?.dependencies ?? []);\n\t\tfor (const dependency of dependencies) visit(dependency);\n\t\tif (column.formula) {\n\t\t\t// Порядок и повторы аргументов формулы сохраняются; уникален лишь граф зависимостей.\n\t\t\tconst compiled = compileTableFormula({ formulaId: column.formula.formulaId, keys: column.formula.dependencies });\n\t\t\tif (!compiled.ok) throw new Error(`Формула столбца ${id} не зарегистрирована: ${column.formula.formulaId}`);\n\t\t\tsteps.push({\n\t\t\t\tcolumnId: id,\n\t\t\t\tdependencies,\n\t\t\t\tcompute: (values) => {\n\t\t\t\t\tconst result = compiled.execute(values);\n\t\t\t\t\tif (!result.ok) throw new Error(`Ошибка формулы столбца ${id}: ${result.reason}`);\n\t\t\t\t\treturn result.value;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (column.calculate) {\n\t\t\tsteps.push({ columnId: id, dependencies, compute: column.calculate.compute });\n\t\t}\n\t\tvisiting.delete(id);\n\t\tvisited.add(id);\n\t\trequired.push(id);\n\t};\n\tfor (const id of requiredColumnIds) visit(id);\n\treturn { steps, requiredColumnIds: required };\n}\n\n/** Возвращает отдельный набор значений; исходный DTO и значения Query не мутируются. */\nexport function calculateAnalyticalValues(values: AnalyticalValues, plan: AnalyticalCalculationPlan): AnalyticalValues {\n\tconst result: Record<string, unknown> = { ...values };\n\tfor (const step of plan.steps) result[step.columnId] = step.compute(result);\n\treturn result;\n}\n","import { createAnalyticalCalculationPlan } from \"./calculations\";\nimport { type AnalyticalTableDefinition, type CompiledAnalyticalTableDefinition } from \"./types\";\n\n/** Проверяет единый каталог полей, включая служебные зависимости невидимых вычислений. */\nexport function compileAnalyticalTableDefinition<T>(definition: AnalyticalTableDefinition<T>): CompiledAnalyticalTableDefinition<T> {\n\tconst fields = [...definition.columns, ...(definition.dataFields ?? [])];\n\tconst calculations = createAnalyticalCalculationPlan(fields);\n\n\treturn {\n\t\tcolumns: definition.columns,\n\t\tfieldsById: new Map(fields.map((field) => [field.id, field])),\n\t\tcalculations,\n\t\taggregateFields: fields.filter((field) => field.aggregate !== undefined),\n\t\tisAggregateRow: definition.isAggregateRow,\n\t\taggregate: definition.aggregate,\n\t\tgrandTotals: definition.grandTotals !== false,\n\t\tgrandTotalsScope: definition.grandTotalsScope ?? \"filtered\"\n\t};\n}\n","import { type AnalyticalViewState } from \"../runtime/types\";\n\nimport { type CompiledAnalyticalTableDefinition } from \"./types\";\n\n/** Состояние ссылается на проверенное описание; grouping keys могут быть служебными полями values. */\nexport function validateAnalyticalView<T>(definition: CompiledAnalyticalTableDefinition<T>, state: AnalyticalViewState): void {\n\tfor (const entry of [...(state.sorting ?? []), ...(state.filters ?? [])]) {\n\t\tif (!definition.fieldsById.has(entry.id)) {\n\t\t\tthrow new Error(`Неизвестный аналитический столбец: ${entry.id}`);\n\t\t}\n\t}\n\n\tconst levelIds = new Set<string>();\n\tfor (const level of state.grouping ?? []) {\n\t\tif (levelIds.has(level.id)) {\n\t\t\tthrow new Error(\"Идентификаторы уровней группировки должны быть уникальны.\");\n\t\t}\n\t\tif (level.keyColumnIds.length === 0) {\n\t\t\tthrow new Error(`Уровень ${level.id} не содержит ключей группировки.`);\n\t\t}\n\t\tlevelIds.add(level.id);\n\t}\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\ntype RowTraversalFrame<T> = {\n\treadonly rows: readonly AnalyticalModelRow<T>[];\n\treadonly visible: boolean;\n\tnextIndex: number;\n};\n\n/** Строит согласованные индексы за один проход, не расходуя стек вызовов на глубину дерева. */\nexport function indexAnalyticalRows<T>(\n\trows: readonly AnalyticalModelRow<T>[]\n): Pick<AnalyticalTableModel<T>, \"flatRows\" | \"visibleRows\" | \"rowById\"> {\n\tconst flatRows: AnalyticalModelRow<T>[] = [];\n\tconst visibleRows: AnalyticalModelRow<T>[] = [];\n\tconst rowById = new Map<string, AnalyticalModelRow<T>>();\n\tconst stack: RowTraversalFrame<T>[] = [{ rows, visible: true, nextIndex: 0 }];\n\n\twhile (stack.length > 0) {\n\t\tconst frame = stack[stack.length - 1];\n\t\tif (frame.nextIndex === frame.rows.length) {\n\t\t\tstack.pop();\n\t\t\tcontinue;\n\t\t}\n\t\tconst row = frame.rows[frame.nextIndex++];\n\t\tflatRows.push(row);\n\t\trowById.set(row.id, row);\n\t\tif (frame.visible) visibleRows.push(row);\n\t\tif (row.children.length > 0) {\n\t\t\tstack.push({ rows: row.children, visible: frame.visible && row.isExpanded, nextIndex: 0 });\n\t\t}\n\t}\n\treturn { flatRows, visibleRows, rowById };\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\nimport { indexAnalyticalRows } from \"./indexAnalyticalRows\";\n\n/** Любая проекция дерева заменяет индексы вместе с узлами, сохраняя уже рассчитанные итоги. */\nexport function resolveRowsProjection<T>(model: AnalyticalTableModel<T>, rows: readonly AnalyticalModelRow<T>[]): AnalyticalTableModel<T> {\n\tif (rows === model.rows) return model;\n\treturn { ...model, rows, ...indexAnalyticalRows(rows) };\n}\n","import { type AnalyticalModelRow, type AnalyticalTableModel } from \"../types\";\n\nimport { resolveRowsProjection } from \"./resolveRowsProjection\";\n\n/** Копирует массив только при замене его непосредственного ребёнка. */\nfunction replaceExpandedRows<T>(\n\trows: readonly AnalyticalModelRow<T>[],\n\treplacements: ReadonlyMap<AnalyticalModelRow<T>, AnalyticalModelRow<T>>\n): readonly AnalyticalModelRow<T>[] {\n\tlet projected: AnalyticalModelRow<T>[] | undefined;\n\tfor (let index = 0; index < rows.length; index++) {\n\t\tconst replacement = replacements.get(rows[index]);\n\t\tif (!replacement) continue;\n\t\tprojected ??= rows.slice();\n\t\tprojected[index] = replacement;\n\t}\n\treturn projected ?? rows;\n}\n\n/** Раскрытие меняет только затронутые ветви; формулы и итоги остаются результатом базовой модели. */\nexport function projectAnalyticalTableExpansion<T>(\n\tmodel: AnalyticalTableModel<T>,\n\texpandedRowIds: readonly string[] | \"all\"\n): AnalyticalTableModel<T> {\n\tconst expandAll = expandedRowIds === \"all\";\n\tconst expanded = new Set(expandAll ? [] : expandedRowIds);\n\tconst replacements = new Map<AnalyticalModelRow<T>, AnalyticalModelRow<T>>();\n\n\t// flatRows уже содержит обход родитель → дети. Обратный проход позволяет\n\t// заменить ребёнка до родителя без рекурсии и сохранить ссылки остальных ветвей.\n\tfor (let index = model.flatRows.length - 1; index >= 0; index--) {\n\t\tconst row = model.flatRows[index];\n\t\tconst children = replaceExpandedRows(row.children, replacements);\n\t\tconst isExpanded = row.isExpandable && (expandAll || expanded.has(row.id));\n\t\tif (isExpanded !== row.isExpanded || children !== row.children) {\n\t\t\treplacements.set(row, { ...row, isExpanded, children });\n\t\t}\n\t}\n\n\t// Неизвестные ID и листья не меняют эффективное раскрытие и не сбрасывают memo потребителей.\n\tif (replacements.size === 0) return model;\n\treturn resolveRowsProjection(model, replaceExpandedRows(model.rows, replacements));\n}\n","import { calculateAnalyticalValues } from \"../definition/calculations\";\nimport { type AnalyticalAggregateContext, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { aggregateAnalyticalValues } from \"./aggregation\";\nimport { type AnalyticalHierarchyNode } from \"./hierarchy\";\nimport { type AnalyticalDataRow, type AnalyticalValues } from \"./types\";\n\n/** Отбирает исходные строки выбранной зернистости; синтетические группы в итоги не попадают. */\nfunction collectAggregateRows<T>(\n\tnodes: readonly AnalyticalHierarchyNode<T>[],\n\taggregateRowIds: ReadonlySet<string>\n): AnalyticalDataRow<T>[] {\n\tconst rows: AnalyticalDataRow<T>[] = [];\n\tconst visit = (node: AnalyticalHierarchyNode<T>): void => {\n\t\tif (node.sourceRow && aggregateRowIds.has(node.id)) {\n\t\t\trows.push(node.sourceRow);\n\t\t}\n\n\t\tfor (const child of node.children) {\n\t\t\tvisit(child);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\tvisit(node);\n\t}\n\n\treturn rows;\n}\n\n/** Один порядок для групповых и общих итогов: агрегации → callback → зависимые формулы. */\nexport function calculateAnalyticalTotals<T>(args: {\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tnodes: readonly AnalyticalHierarchyNode<T>[];\n\taggregateRowIds: ReadonlySet<string>;\n\tscope: \"group\" | \"grand\";\n\tgroupingPath?: AnalyticalValues;\n}): AnalyticalValues {\n\tconst { definition, nodes, aggregateRowIds, scope, groupingPath = {} } = args;\n\tconst context: AnalyticalAggregateContext<T> = {\n\t\tscope,\n\t\trows: collectAggregateRows(nodes, aggregateRowIds),\n\t\tgroupingPath\n\t};\n\tconst values: Record<string, unknown> = { ...groupingPath };\n\n\tfor (const field of definition.aggregateFields) {\n\t\tconst aggregate = field.aggregate;\n\t\tif (aggregate === undefined) continue;\n\n\t\tvalues[field.id] =\n\t\t\ttypeof aggregate === \"function\"\n\t\t\t\t? aggregate(context)\n\t\t\t\t: aggregateAnalyticalValues(\n\t\t\t\t\t\tcontext.rows.map((row) => row.values[field.id]),\n\t\t\t\t\t\taggregate\n\t\t\t\t\t);\n\t}\n\n\tObject.assign(values, definition.aggregate?.(context));\n\n\t// Явные итоги и ключи пути сохраняются. Остальные формулы читают уже готовые\n\t// суммы: процент считается из сумм, а сумма произведений не заменяется произведением сумм.\n\tconst calculations = {\n\t\t...definition.calculations,\n\t\tsteps: definition.calculations.steps.filter((step) => !Object.hasOwn(values, step.columnId))\n\t};\n\n\treturn calculateAnalyticalValues(values, calculations);\n}\n","import { parseDate } from \"../../formatters\";\nimport { compareStrings } from \"../../string-comparison\";\nimport { stableStringify } from \"../../utils\";\nimport { type AnalyticalColumn, type AnalyticalValues } from \"../types\";\n\n/** Тип входит в ключ: null, undefined, строка и число не склеивают разные группы. */\nexport function analyticalIdentity(values: AnalyticalValues, ids: readonly string[]): string {\n\treturn stableStringify(\n\t\tids.map((id) => {\n\t\t\tconst value = values[id];\n\t\t\treturn [id, value === null ? \"null\" : typeof value, value];\n\t\t})\n\t);\n}\n\nexport function compareAnalyticalValues<T>(left: unknown, right: unknown, column?: AnalyticalColumn<T>): number {\n\tif (Object.is(left, right)) return 0;\n\tif (left === null || left === undefined) return 1;\n\tif (right === null || right === undefined) return -1;\n\tif (column?.compare) return column.compare(left, right);\n\tif (column?.valueType === \"date\") {\n\t\tconst leftDate = parseDate(left);\n\t\tconst rightDate = parseDate(right);\n\t\tif (leftDate && rightDate) return leftDate.getTime() - rightDate.getTime();\n\t}\n\tif (typeof left === \"number\" && typeof right === \"number\") return left - right;\n\tif (typeof left === \"boolean\" && typeof right === \"boolean\") return Number(left) - Number(right);\n\treturn compareStrings(String(left), String(right));\n}\n","import { stableStringify } from \"../../utils\";\nimport { type AnalyticalGroupingLevel, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { type AnalyticalHierarchyNode, type AnalyticalSourceHierarchy } from \"./hierarchy\";\nimport { calculateAnalyticalTotals } from \"./totals\";\nimport { type AnalyticalValues } from \"./types\";\nimport { analyticalIdentity } from \"./valueComparison\";\n\n/** Группировка добавляет уровни над предметными корнями и сохраняет их дочернюю детализацию. */\nexport function groupAnalyticalHierarchy<T>(args: {\n\trows: readonly AnalyticalHierarchyNode<T>[];\n\tgrouping: readonly AnalyticalGroupingLevel[];\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tsource: AnalyticalSourceHierarchy<T>;\n}): readonly AnalyticalHierarchyNode<T>[] {\n\tconst { grouping, definition, source } = args;\n\tconst groupLevel = (\n\t\trows: readonly AnalyticalHierarchyNode<T>[],\n\t\tlevelIndex: number,\n\t\tpath: AnalyticalValues,\n\t\tidentityPath: readonly string[]\n\t): readonly AnalyticalHierarchyNode<T>[] => {\n\t\tconst level = grouping[levelIndex];\n\t\tif (!level) return rows;\n\n\t\tconst buckets = new Map<string, AnalyticalHierarchyNode<T>[]>();\n\t\tfor (const row of rows) {\n\t\t\tconst key = analyticalIdentity(row.values, level.keyColumnIds);\n\t\t\tconst bucket = buckets.get(key);\n\t\t\tif (bucket) bucket.push(row);\n\t\t\telse buckets.set(key, [row]);\n\t\t}\n\n\t\treturn Array.from(buckets, ([key, members]) => {\n\t\t\tconst identity = [...identityPath, level.id, key];\n\t\t\tconst id = `analytical-group:${stableStringify(identity)}`;\n\t\t\tif (source.sourceRowIds.has(id)) {\n\t\t\t\tthrow new Error(`Идентификатор исходной строки совпал с группой: ${id}`);\n\t\t\t}\n\n\t\t\tconst groupingPath: Record<string, unknown> = { ...path };\n\t\t\tfor (const fieldId of [...level.keyColumnIds, ...(level.displayColumnIds ?? [])]) {\n\t\t\t\tgroupingPath[fieldId] = members[0].values[fieldId];\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tkind: \"group\",\n\t\t\t\tgroupingLevelId: level.id,\n\t\t\t\tvalues: calculateAnalyticalTotals({\n\t\t\t\t\tdefinition,\n\t\t\t\t\tnodes: members,\n\t\t\t\t\taggregateRowIds: source.aggregateRowIds,\n\t\t\t\t\tscope: \"group\",\n\t\t\t\t\tgroupingPath\n\t\t\t\t}),\n\t\t\t\tchildren: groupLevel(members, levelIndex + 1, groupingPath, identity)\n\t\t\t};\n\t\t});\n\t};\n\n\treturn groupLevel(args.rows, 0, {}, []);\n}\n","import { type AnalyticalGroupingLevel, type CompiledAnalyticalTableDefinition } from \"../definition/types\";\nimport { indexAnalyticalRows } from \"../projections/indexAnalyticalRows\";\n\nimport { groupAnalyticalHierarchy } from \"./grouping\";\nimport { type AnalyticalHierarchyNode, type AnalyticalSourceHierarchy } from \"./hierarchy\";\nimport { calculateAnalyticalTotals } from \"./totals\";\nimport { type AnalyticalModelRow, type AnalyticalTableModel } from \"./types\";\n\n/** Назначает конечные уровни и родителей после добавления всех группировок. */\nfunction materializeRows<T>(\n\tnodes: readonly AnalyticalHierarchyNode<T>[],\n\tparentId: string | null = null,\n\tlevel = 0\n): AnalyticalModelRow<T>[] {\n\treturn nodes.map((node) => ({\n\t\tid: node.id,\n\t\tparentId,\n\t\tkind: node.kind,\n\t\tsourceRow: node.sourceRow,\n\t\toriginal: node.sourceRow?.original,\n\t\tvalues: node.values,\n\t\tlevel,\n\t\tchildren: materializeRows(node.children, node.id, level + 1),\n\t\tisExpandable: node.children.length > 0,\n\t\tisExpanded: false,\n\t\tgroupingLevelId: node.groupingLevelId\n\t}));\n}\n\n/** Базовая модель содержит все отобранные строки и итоги; порядок и раскрытие задаются позже. */\nexport function buildGroupedAnalyticalModel<T>(args: {\n\tdefinition: CompiledAnalyticalTableDefinition<T>;\n\tsource: AnalyticalSourceHierarchy<T>;\n\tfilteredRows: readonly AnalyticalHierarchyNode<T>[];\n\tgrouping: readonly AnalyticalGroupingLevel[];\n}): AnalyticalTableModel<T> {\n\tconst { definition, source, filteredRows, grouping } = args;\n\tconst hierarchy = groupAnalyticalHierarchy({ rows: filteredRows, grouping, definition, source });\n\tconst rows = materializeRows(hierarchy);\n\tconst grandTotals = definition.grandTotals\n\t\t? calculateAnalyticalTotals({\n\t\t\t\tdefinition,\n\t\t\t\tnodes: definition.grandTotalsScope === \"all\" ? source.rows : filteredRows,\n\t\t\t\taggregateRowIds: source.aggregateRowIds,\n\t\t\t\tscope: \"grand\"\n\t\t\t})\n\t\t: null;\n\n\treturn {\n\t\tcolumns: definition.columns,\n\t\trows,\n\t\t...indexAnalyticalRows(rows),\n\t\tgrandTotals,\n\t\tdiagnostics: source.diagnostics\n\t};\n}\n","import { normalizeTextToLower } from \"../../formatters\";\nimport { type AnalyticalColumn, type AnalyticalDataRow, type AnalyticalFilter } from \"../types\";\n\nimport { type AnalyticalHierarchyNode } from \"./hierarchy\";\nimport { compareAnalyticalValues } from \"./valueComparison\";\n\n/** Операции фильтра относятся к данным, поэтому одинаково работают при SSR и в браузере. */\nexport function matchesAnalyticalFilter<T>(row: AnalyticalDataRow<T>, filter: AnalyticalFilter, column?: AnalyticalColumn<T>): boolean {\n\tconst value = row.values[filter.id];\n\tif (column?.filter) return column.filter(value, filter, row);\n\tconst expected = filter.value;\n\tconst compare = (other: unknown) => compareAnalyticalValues(value, other, column);\n\tconst empty = value === null || value === undefined || value === \"\";\n\tswitch (filter.operator ?? \"equals\") {\n\t\tcase \"equals\":\n\t\t\treturn compare(expected) === 0;\n\t\tcase \"notEquals\":\n\t\t\treturn compare(expected) !== 0;\n\t\tcase \"contains\":\n\t\t\treturn normalizeTextToLower(String(value ?? \"\")).includes(normalizeTextToLower(String(expected ?? \"\")));\n\t\tcase \"startsWith\":\n\t\t\treturn normalizeTextToLower(String(value ?? \"\")).startsWith(normalizeTextToLower(String(expected ?? \"\")));\n\t\tcase \"in\":\n\t\t\treturn Array.isArray(expected) && expected.some((item: unknown) => compare(item) === 0);\n\t\tcase \"between\":\n\t\t\treturn Array.isArray(expected) && expected.length === 2 && !empty && compare(expected[0]) >= 0 && compare(expected[1]) <= 0;\n\t\tcase \"gt\":\n\t\t\treturn !empty && compare(expected) > 0;\n\t\tcase \"gte\":\n\t\t\treturn !empty && compare(expected) >= 0;\n\t\tcase \"lt\":\n\t\t\treturn !empty && compare(expected) < 0;\n\t\tcase \"lte\":\n\t\t\treturn !empty && compare(expected) <= 0;\n\t\tcase \"empty\":\n\t\t\treturn empty;\n\t\tcase \"notEmpty\":\n\t\t\treturn !empty;\n\t}\n}\n\n/** Совпавший родитель оставляет всю ветвь; совпавший ребёнок сохраняет путь к нему. */\nexport function filterAnalyticalHierarchy<T>(\n\trows: readonly AnalyticalHierarchyNode<T>[],\n\tfilters: readonly AnalyticalFilter[],\n\tfieldsById: ReadonlyMap<string, AnalyticalColumn<T>>\n): readonly AnalyticalHierarchyNode<T>[] {\n\tif (filters.length === 0) return rows;\n\n\tconst filtered: AnalyticalHierarchyNode<T>[] = [];\n\tfor (const row of rows) {\n\t\tconst sourceRow = row.sourceRow;\n\t\tconst matches = sourceRow && filters.every((filter) => matchesAnalyticalFilter(sourceRow, filter, fieldsById.get(filter.id)));\n\t\tif (matches) {\n\t\t\tfiltered.push(row);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst children = filterAnalyticalHierarchy(row.children, filters, fieldsById);\n\t\tif (children.length > 0) {\n\t\t\tfiltered.push({ ...row, children });\n\t\t}\n\t}\n\n\treturn filtered;\n}\n","import { buildTreeTableRows, type TreeTableRowNode } from \"../../tree-table\";\nimport { calculateAnalyticalValues } from \"../definition/calculations\";\nimport { type CompiledAnalyticalTableDefinition } from \"../definition/types\";\n\nimport { type AnalyticalDataRow, type AnalyticalDiagnostics, type AnalyticalSnapshot, type AnalyticalValues } from \"./types\";\n\n/** Узел до назначения итогового parentId/level: группировка ещё может добавить предков. */\nexport type AnalyticalHierarchyNode<T> = Readonly<{\n\tid: string;\n\tkind: \"data\" | \"group\";\n\tsourceRow?: AnalyticalDataRow<T>;\n\tvalues: AnalyticalValues;\n\tchildren: readonly AnalyticalHierarchyNode<T>[];\n\tgroupingLevelId?: string;\n}>;\n\nexport type AnalyticalSourceHierarchy<T> = Readonly<{\n\trows: readonly AnalyticalHierarchyNode<T>[];\n\tsourceRowIds: ReadonlySet<string>;\n\taggregateRowIds: ReadonlySet<string>;\n\tdiagnostics: AnalyticalDiagnostics;\n}>;\n\n/** Формулы исходных строк и предметная иерархия зависят только от определения и снимка. */\nexport function prepareAnalyticalHierarchy<T>(\n\tsnapshot: AnalyticalSnapshot<T>,\n\tdefinition: CompiledAnalyticalTableDefinition<T>\n): AnalyticalSourceHierarchy<T> {\n\tif (snapshot.rows.some((row) => row.id.length === 0)) {\n\t\tthrow new Error(\"Идентификатор аналитической строки не может быть пустым.\");\n\t}\n\n\tconst calculatedRows = snapshot.rows.map((row) => ({\n\t\t...row,\n\t\tvalues: calculateAnalyticalValues(row.values, definition.calculations)\n\t}));\n\tconst tree = buildTreeTableRows(calculatedRows, {\n\t\tgetRowId: (row) => row.id,\n\t\tgetParentRowId: (row) => row.parentId\n\t});\n\n\tconst prepareNode = (node: TreeTableRowNode<AnalyticalDataRow<T>>): AnalyticalHierarchyNode<T> => ({\n\t\tid: node.id,\n\t\tkind: \"data\",\n\t\tsourceRow: tree.rowById.get(node.id),\n\t\tvalues: node.values,\n\t\tchildren: (node.children ?? []).map(prepareNode)\n\t});\n\tconst aggregateRowIds = definition.isAggregateRow\n\t\t? Array.from(tree.rowById.values())\n\t\t\t\t.filter(definition.isAggregateRow)\n\t\t\t\t.map((row) => row.id)\n\t\t: tree.rootRowIds;\n\n\treturn {\n\t\trows: tree.rows.map(prepareNode),\n\t\tsourceRowIds: new Set(tree.allRowIds),\n\t\taggregateRowIds: new Set(aggregateRowIds),\n\t\tdiagnostics: {\n\t\t\torphanRowIds: tree.orphanRowIds,\n\t\t\tduplicateRowIds: tree.duplicateRowIds,\n\t\t\tcyclicRowIds: tree.cyclicRowIds\n\t\t}\n\t};\n}\n","import { type AnalyticalColumn } from \"../definition/types\";\nimport { resolveRowsProjection } from \"../projections/resolveRowsProjection\";\n\nimport { type AnalyticalModelRow, type AnalyticalSorting, type AnalyticalTableModel } from \"./types\";\nimport { compareAnalyticalValues } from \"./valueComparison\";\n\n/** Меняет только порядок соседей: вычисленные значения, итоги и связи parent/child сохраняются. */\nexport function sortAnalyticalModel<T>(\n\tmodel: AnalyticalTableModel<T>,\n\tsorting: readonly AnalyticalSorting[],\n\tfieldsById: ReadonlyMap<string, AnalyticalColumn<T>>\n): AnalyticalTableModel<T> {\n\tif (sorting.length === 0) return model;\n\n\tconst compareRows = (left: AnalyticalModelRow<T>, right: AnalyticalModelRow<T>): number => {\n\t\tfor (const sort of sorting) {\n\t\t\tconst comparison = compareAnalyticalValues(left.values[sort.id], right.values[sort.id], fieldsById.get(sort.id));\n\t\t\tif (comparison !== 0) return sort.desc ? -comparison : comparison;\n\t\t}\n\t\treturn 0;\n\t};\n\tconst sortBranch = (rows: readonly AnalyticalModelRow<T>[]): readonly AnalyticalModelRow<T>[] => {\n\t\tif (rows.length === 0) return rows;\n\n\t\tconst projected = rows.map((row) => {\n\t\t\tconst children = sortBranch(row.children);\n\t\t\treturn children === row.children ? row : { ...row, children };\n\t\t});\n\t\tprojected.sort(compareRows);\n\n\t\treturn projected.every((row, index) => row === rows[index]) ? rows : projected;\n\t};\n\n\treturn resolveRowsProjection(model, sortBranch(model.rows));\n}\n","import { validateAnalyticalView } from \"../definition/validateAnalyticalView\";\nimport { projectAnalyticalTableExpansion } from \"../projections/expansion\";\n\nimport { buildGroupedAnalyticalModel } from \"./buildGroupedModel\";\nimport { filterAnalyticalHierarchy } from \"./filtering\";\nimport { prepareAnalyticalHierarchy } from \"./hierarchy\";\nimport { sortAnalyticalModel } from \"./sorting\";\nimport {\n\ttype AnalyticalTableModel,\n\ttype AnalyticalTableRuntime,\n\ttype AnalyticalViewState,\n\ttype CreateAnalyticalTableRuntimeOptions\n} from \"./types\";\n\nconst EMPTY_STATE: AnalyticalViewState = {};\nconst EMPTY_ITEMS = Object.freeze([]);\n\n/**\n * Создаёт вычислительный runtime для одного снимка.\n *\n * Хранится только последний результат каждого этапа. Исходные строки рассчитываются\n * один раз; фильтры/группировки меняют итоги, сортировка — порядок, раскрытие — видимость.\n * Входные определения, снимки и массивы состояния должны оставаться неизменяемыми.\n */\nexport function createAnalyticalTableRuntime<T>(options: CreateAnalyticalTableRuntimeOptions<T>): AnalyticalTableRuntime<T> {\n\tconst { definition, snapshot } = options;\n\tconst source = prepareAnalyticalHierarchy(snapshot, definition);\n\tlet previousState: AnalyticalViewState = EMPTY_STATE;\n\tlet filteredRows = source.rows;\n\tlet groupedModel: AnalyticalTableModel<T> | undefined;\n\tlet sortedModel: AnalyticalTableModel<T> | undefined;\n\tlet expandedModel: AnalyticalTableModel<T> | undefined;\n\n\treturn {\n\t\tgetModel(state = EMPTY_STATE) {\n\t\t\tvalidateAnalyticalView(definition, state);\n\t\t\tconst filters = state.filters ?? EMPTY_ITEMS;\n\t\t\tconst grouping = state.grouping ?? EMPTY_ITEMS;\n\t\t\tconst sorting = state.sorting ?? EMPTY_ITEMS;\n\t\t\tconst expandedRowIds = state.expandedRowIds ?? EMPTY_ITEMS;\n\t\t\tconst filtersChanged = !groupedModel || filters !== (previousState.filters ?? EMPTY_ITEMS);\n\t\t\tconst groupingChanged = !groupedModel || grouping !== (previousState.grouping ?? EMPTY_ITEMS);\n\t\t\tconst sortingChanged = sorting !== (previousState.sorting ?? EMPTY_ITEMS);\n\t\t\tconst expansionChanged = expandedRowIds !== (previousState.expandedRowIds ?? EMPTY_ITEMS);\n\n\t\t\tconst nextFilteredRows = filtersChanged ? filterAnalyticalHierarchy(source.rows, filters, definition.fieldsById) : filteredRows;\n\n\t\t\tconst rebuildGroups = !groupedModel || filtersChanged || groupingChanged;\n\t\t\tconst nextGroupedModel = rebuildGroups\n\t\t\t\t? buildGroupedAnalyticalModel({ definition, source, filteredRows: nextFilteredRows, grouping })\n\t\t\t\t: groupedModel!;\n\n\t\t\tconst rebuildSorting = !sortedModel || rebuildGroups || sortingChanged;\n\t\t\tconst nextSortedModel = rebuildSorting ? sortAnalyticalModel(nextGroupedModel, sorting, definition.fieldsById) : sortedModel!;\n\n\t\t\tconst nextExpandedModel =\n\t\t\t\t!expandedModel || rebuildSorting || expansionChanged\n\t\t\t\t\t? projectAnalyticalTableExpansion(rebuildSorting ? nextSortedModel : (expandedModel ?? nextSortedModel), expandedRowIds)\n\t\t\t\t\t: expandedModel;\n\n\t\t\t// Ошибка callback не должна оставлять стадии от разных состояний в одном runtime.\n\t\t\tfilteredRows = nextFilteredRows;\n\t\t\tgroupedModel = nextGroupedModel;\n\t\t\tsortedModel = nextSortedModel;\n\t\t\texpandedModel = nextExpandedModel;\n\t\t\tpreviousState = { filters, grouping, sorting, expandedRowIds };\n\t\t\treturn expandedModel;\n\t\t}\n\t};\n}\n","import { compileAnalyticalTableDefinition } from \"./definition/compileAnalyticalTableDefinition\";\nimport { createAnalyticalTableRuntime } from \"./runtime/createAnalyticalTableRuntime\";\nimport { type AnalyticalTableModel, type BuildAnalyticalTableModelOptions } from \"./runtime/types\";\n\n/**\n * Строит таблицу за один вызов: описание → runtime снимка → модель представления.\n * Для последовательных изменений состояния сохраняйте определение и runtime отдельно.\n */\nexport function buildAnalyticalTableModel<T>(options: BuildAnalyticalTableModelOptions<T>): AnalyticalTableModel<T> {\n\tconst definition = compileAnalyticalTableDefinition(options);\n\tconst runtime = createAnalyticalTableRuntime({ definition, snapshot: options.snapshot });\n\n\treturn runtime.getModel(options.state);\n}\n","import {\n\taddCalendarDays,\n\taddCalendarMonths,\n\taddCalendarYears,\n\tcreateCalendarDate,\n\tformatDateAsDate,\n\tformatDateAsODataDate,\n\tgetStartOfDay,\n\tgetStartOfMonth,\n\tgetStartOfWeek,\n\tgetStartOfYear,\n\tparseDateByPattern\n} from \"../../formatters\";\nimport { aggregateAnalyticalValues } from \"../runtime/aggregation\";\nimport { type AnalyticalDataRow, type AnalyticalValues } from \"../runtime/types\";\nimport { analyticalIdentity } from \"../runtime/valueComparison\";\n\nimport {\n\ttype AnalyticalDateColumn,\n\ttype AnalyticalDateColumnsOptions,\n\ttype AnalyticalDateColumnsPlan,\n\ttype ProjectAnalyticalDateFactsOptions\n} from \"./types\";\n\n/** Принимает только календарный контракт; преобразование timestamp принадлежит transport/domain адаптеру. */\nfunction readCalendarDate(value: unknown): Date | null {\n\tif (typeof value !== \"string\" || value.length !== 10) return null;\n\tconst parsed = parseDateByPattern(value, \"yyyy-MM-dd\");\n\treturn parsed?.kind === \"date-time\" ? parsed.date : null;\n}\n\nfunction getDateBucketStart(date: Date, granularity: AnalyticalDateColumnsOptions[\"granularity\"]): Date {\n\tswitch (granularity) {\n\t\tcase \"day\":\n\t\t\treturn getStartOfDay(date);\n\t\tcase \"week\":\n\t\t\treturn getStartOfWeek(date, 1);\n\t\tcase \"month\":\n\t\t\treturn getStartOfMonth(date);\n\t\tcase \"quarter\":\n\t\t\treturn createCalendarDate(date.getFullYear(), Math.floor(date.getMonth() / 3) * 3, 1);\n\t\tcase \"year\":\n\t\t\treturn getStartOfYear(date);\n\t}\n}\n\nfunction getNextDateBucketStart(date: Date, granularity: AnalyticalDateColumnsOptions[\"granularity\"]): Date {\n\tswitch (granularity) {\n\t\tcase \"day\":\n\t\t\treturn addCalendarDays(date, 1);\n\t\tcase \"week\":\n\t\t\treturn addCalendarDays(date, 7);\n\t\tcase \"month\":\n\t\t\treturn addCalendarMonths(date, 1);\n\t\tcase \"quarter\":\n\t\t\treturn addCalendarMonths(date, 3);\n\t\tcase \"year\":\n\t\t\treturn addCalendarYears(date, 1);\n\t}\n}\n\n/** Строит ограниченный календарный план; ISO-моменты времени сюда не передаются. */\nexport function createAnalyticalDateColumnsPlan(options: AnalyticalDateColumnsOptions): AnalyticalDateColumnsPlan {\n\tconst from = readCalendarDate(options.from);\n\tconst to = readCalendarDate(options.to);\n\tif (\n\t\t!from ||\n\t\t!to ||\n\t\tformatDateAsODataDate(from) !== options.from ||\n\t\tformatDateAsODataDate(to) !== options.to ||\n\t\toptions.from > options.to\n\t)\n\t\tthrow new Error(\"Некорректный календарный диапазон аналитических столбцов.\");\n\tconst maxColumns = options.maxColumns ?? 366;\n\tif (!Number.isSafeInteger(maxColumns) || maxColumns < 1)\n\t\tthrow new Error(\"Лимит динамических столбцов должен быть положительным целым числом.\");\n\tif (!options.id || options.identityColumnIds.length === 0)\n\t\tthrow new Error(\"Динамическим столбцам нужны идентификатор и ключи сопоставления фактов.\");\n\n\t// Идентификатор относится ко всему календарному периоду, границы отбора — только к запрошенной части периода.\n\tconst columns: AnalyticalDateColumn[] = [];\n\tlet start = getDateBucketStart(from, options.granularity);\n\twhile (start <= to) {\n\t\tif (columns.length >= maxColumns) throw new Error(`Превышен лимит динамических столбцов: ${maxColumns}`);\n\t\tconst nextStart = getNextDateBucketStart(start, options.granularity);\n\t\tconst key = formatDateAsODataDate(start);\n\t\tconst end = formatDateAsODataDate(addCalendarDays(nextStart, -1));\n\t\tcolumns.push({\n\t\t\tid: `${options.id}:${options.granularity}:${key}`,\n\t\t\t// Подпись дня следует общей настройке date; машинные даты используют штатный odata-date.\n\t\t\tlabel: options.granularity === \"day\" ? formatDateAsDate(start) : `${key} — ${end}`,\n\t\t\tfrom: key < options.from ? options.from : key,\n\t\t\tto: end > options.to ? options.to : end\n\t\t});\n\t\tstart = nextStart;\n\t}\n\treturn { options: { ...options, identityColumnIds: [...options.identityColumnIds] }, columns };\n}\n\nfunction resolveFactColumnId(fact: AnalyticalValues, plan: AnalyticalDateColumnsPlan): string | undefined {\n\t// Факт без полного ключа нельзя сопоставить строке; общий итог использует ту же область допустимых фактов.\n\tif (plan.options.identityColumnIds.some((id) => fact[id] === undefined || fact[id] === null)) return undefined;\n\tconst date = readCalendarDate(fact[plan.options.dateColumnId]);\n\tif (!date) return undefined;\n\tconst day = formatDateAsODataDate(date);\n\tif (day < plan.options.from || day > plan.options.to) return undefined;\n\treturn `${plan.options.id}:${plan.options.granularity}:${formatDateAsODataDate(getDateBucketStart(date, plan.options.granularity))}`;\n}\n\n/** Индекс содержит исходные значения мер: выбор способа агрегации происходит после сопоставления фактов. */\nfunction indexFactMeasuresByIdentity(\n\tfacts: readonly AnalyticalValues[],\n\tplan: AnalyticalDateColumnsPlan\n): ReadonlyMap<string, ReadonlyMap<string, readonly unknown[]>> {\n\tconst byIdentity = new Map<string, Map<string, unknown[]>>();\n\tfor (const fact of facts) {\n\t\tconst columnId = resolveFactColumnId(fact, plan);\n\t\tif (!columnId) continue;\n\t\tconst identity = analyticalIdentity(fact, plan.options.identityColumnIds);\n\t\tlet buckets = byIdentity.get(identity);\n\t\tif (!buckets) {\n\t\t\tbuckets = new Map();\n\t\t\tbyIdentity.set(identity, buckets);\n\t\t}\n\t\tconst bucket = buckets.get(columnId);\n\t\tif (bucket) bucket.push(fact[plan.options.measureColumnId]);\n\t\telse buckets.set(columnId, [fact[plan.options.measureColumnId]]);\n\t}\n\treturn byIdentity;\n}\n\n/** Сопоставляет отдельные facts составному ключу строки; порядок и количество base rows неизменны. */\nexport function projectAnalyticalDateFacts<T>(args: ProjectAnalyticalDateFactsOptions<T>): readonly AnalyticalDataRow<T>[] {\n\tconst { rows, facts, plan } = args;\n\tconst byIdentity = indexFactMeasuresByIdentity(facts, plan);\n\treturn rows.map((row) => {\n\t\tconst buckets = byIdentity.get(analyticalIdentity(row.values, plan.options.identityColumnIds));\n\t\tconst values: Record<string, unknown> = { ...row.values };\n\t\tfor (const column of plan.columns) {\n\t\t\tif (Object.hasOwn(values, column.id)) throw new Error(`Динамический столбец перезаписывает исходное поле: ${column.id}`);\n\t\t\tconst bucket = buckets?.get(column.id);\n\t\t\tvalues[column.id] = bucket ? aggregateAnalyticalValues(bucket, plan.options.aggregation) : null;\n\t\t}\n\t\treturn { ...row, values };\n\t});\n}\n\n/**\n * Общие итоги считаются по исходным facts с полным ключом: среднее от средних не подменяет взвешенный результат.\n * Отбор допустимых непустых identities по области доступа и фильтрам выполняет вызывающий адаптер.\n */\nexport function aggregateAnalyticalDateFacts(facts: readonly AnalyticalValues[], plan: AnalyticalDateColumnsPlan): AnalyticalValues {\n\tconst buckets = new Map<string, unknown[]>();\n\tfor (const fact of facts) {\n\t\tconst id = resolveFactColumnId(fact, plan);\n\t\tif (!id) continue;\n\t\tconst bucket = buckets.get(id);\n\t\tif (bucket) bucket.push(fact[plan.options.measureColumnId]);\n\t\telse buckets.set(id, [fact[plan.options.measureColumnId]]);\n\t}\n\treturn Object.fromEntries(\n\t\tplan.columns.map((column) => {\n\t\t\tconst bucket = buckets.get(column.id);\n\t\t\treturn [column.id, bucket ? aggregateAnalyticalValues(bucket, plan.options.aggregation) : null];\n\t\t})\n\t);\n}\n","import {\n\ttype AnalyticalExportColumn,\n\ttype AnalyticalExportProjection,\n\ttype AnalyticalTableModel,\n\ttype ProjectAnalyticalTableExportOptions\n} from \"../types\";\n\n/** ID итога устойчив между областями экспорта и не конфликтует даже со скрытой строкой модели. */\nfunction resolveGrandTotalId<T>(model: AnalyticalTableModel<T>): string {\n\tconst baseId = \"analytical-grand-total\";\n\tlet id = baseId;\n\tlet suffix = 1;\n\twhile (model.rowById.has(id)) id = `${baseId}:${suffix++}`;\n\treturn id;\n}\n\n/** Проекция для /excel или /table-document; сам runtime не скачивает файлы и не читает DOM. */\nexport function projectAnalyticalTableExport<T>(args: ProjectAnalyticalTableExportOptions<T>): AnalyticalExportProjection {\n\tconst { model, scope = \"all\", includeGroups = true, includeGrandTotals = false } = args;\n\tconst columns: readonly AnalyticalExportColumn<T>[] = args.columns ?? model.columns;\n\tconst selected = new Set(args.selectedRowIds ?? []);\n\tconst source = scope === \"visible\" ? model.visibleRows : model.flatRows;\n\tconst rows: AnalyticalExportProjection[\"rows\"][number][] = [];\n\n\tfor (const row of source) {\n\t\tif (!includeGroups && row.kind === \"group\") continue;\n\t\tif (scope === \"selected\" && !selected.has(row.id)) continue;\n\t\trows.push({\n\t\t\tid: row.id,\n\t\t\tlevel: row.level,\n\t\t\tkind: row.kind,\n\t\t\tvalues: columns.map((column) => (column.format ? column.format(row.values[column.id], row) : row.values[column.id]))\n\t\t});\n\t}\n\n\tif (includeGrandTotals && model.grandTotals) {\n\t\tconst totals = model.grandTotals;\n\t\trows.push({\n\t\t\tid: resolveGrandTotalId(model),\n\t\t\tlevel: 0,\n\t\t\tkind: \"grand\",\n\t\t\tvalues: columns.map((column) => (column.formatTotal ? column.formatTotal(totals[column.id]) : totals[column.id]))\n\t\t});\n\t}\n\treturn { columns: columns.map((column) => ({ id: column.id, label: column.label ?? column.id })), rows };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { g as e, h as t, m as n, u as r } from "./scalarTypeClassification-BZcFmIyR.js";
|
|
2
|
+
//#region src/formatters/boolean/parseAbapBoolean.ts
|
|
3
|
+
function i(e) {
|
|
4
|
+
return !!(e && typeof e == "string" && e === "X");
|
|
5
|
+
}
|
|
6
|
+
function a(e) {
|
|
7
|
+
return e ? typeof e == "string" ? [
|
|
8
|
+
"true",
|
|
9
|
+
"x",
|
|
10
|
+
"1"
|
|
11
|
+
].includes(e.toLowerCase()) : !!e : !1;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/formatters/date/formatDate.ts
|
|
15
|
+
var o = /* @__PURE__ */ new WeakMap();
|
|
16
|
+
function s(e) {
|
|
17
|
+
return String(e).padStart(2, "0");
|
|
18
|
+
}
|
|
19
|
+
function c(n) {
|
|
20
|
+
if (typeof n != "string") {
|
|
21
|
+
let e = o.get(n);
|
|
22
|
+
if (e) return e;
|
|
23
|
+
let r = t(n);
|
|
24
|
+
return o.set(n, r), r;
|
|
25
|
+
}
|
|
26
|
+
let r = e(n);
|
|
27
|
+
if (!r) throw Error(`Предустановка даты "${n}" не найдена`);
|
|
28
|
+
return r;
|
|
29
|
+
}
|
|
30
|
+
function l(e, t) {
|
|
31
|
+
return t?.fallback ?? e.invalidFallback;
|
|
32
|
+
}
|
|
33
|
+
function u(e, t, n, r) {
|
|
34
|
+
return e.kind === "duration" ? t.formatDuration ? t.formatDuration(e.durationMs, n) : n : t.formatDateTime(e.date, r);
|
|
35
|
+
}
|
|
36
|
+
function d(e, t = n.date, i) {
|
|
37
|
+
let a = c(t), o = l(a, i), s = i?.precision ?? "day", d = r(e);
|
|
38
|
+
return d ? u(d, a, o, s) : o;
|
|
39
|
+
}
|
|
40
|
+
function f(e, t) {
|
|
41
|
+
return d(e, n.date, t);
|
|
42
|
+
}
|
|
43
|
+
function p(e, t) {
|
|
44
|
+
return d(e, n.datetime, t);
|
|
45
|
+
}
|
|
46
|
+
function m(e, t) {
|
|
47
|
+
return d(e, n.time, t);
|
|
48
|
+
}
|
|
49
|
+
function h(e, t) {
|
|
50
|
+
return d(e, n.timeSeconds, t);
|
|
51
|
+
}
|
|
52
|
+
function g(e, t) {
|
|
53
|
+
return d(e, n.dateShort, t);
|
|
54
|
+
}
|
|
55
|
+
function _(e, t) {
|
|
56
|
+
return d(e, n.dateMedium, t);
|
|
57
|
+
}
|
|
58
|
+
function v(e, t) {
|
|
59
|
+
return d(e, n.dateLong, t);
|
|
60
|
+
}
|
|
61
|
+
function y(e, t) {
|
|
62
|
+
return d(e, n.monthShort, t);
|
|
63
|
+
}
|
|
64
|
+
function b(e, t) {
|
|
65
|
+
return d(e, n.monthMedium, t);
|
|
66
|
+
}
|
|
67
|
+
function x(e, t) {
|
|
68
|
+
return d(e, n.monthLong, t);
|
|
69
|
+
}
|
|
70
|
+
function S(e, t) {
|
|
71
|
+
return d(e, n.monthYearMedium, t);
|
|
72
|
+
}
|
|
73
|
+
function C(e, t) {
|
|
74
|
+
return d(e, n.monthYearLong, t);
|
|
75
|
+
}
|
|
76
|
+
function w(e, t) {
|
|
77
|
+
return d(e, n.timeShort, t);
|
|
78
|
+
}
|
|
79
|
+
function T(e, t) {
|
|
80
|
+
return d(e, n.timeMedium, t);
|
|
81
|
+
}
|
|
82
|
+
function E(e, t) {
|
|
83
|
+
return d(e, n.timeLong, t);
|
|
84
|
+
}
|
|
85
|
+
function D(e, t) {
|
|
86
|
+
return d(e, n.datetimeShort, t);
|
|
87
|
+
}
|
|
88
|
+
function O(e, t) {
|
|
89
|
+
return d(e, n.datetimeMedium, t);
|
|
90
|
+
}
|
|
91
|
+
function k(e, t) {
|
|
92
|
+
return d(e, n.datetimeLong, t);
|
|
93
|
+
}
|
|
94
|
+
function A(e, t, i = n.date, a) {
|
|
95
|
+
let o = c(i), s = l(o, a), d = a?.precision ?? "day", f = r(e), p = r(t);
|
|
96
|
+
if (!f || !p) return s;
|
|
97
|
+
let m = u(f, o, s, d), h = u(p, o, s, d);
|
|
98
|
+
return !m || !h ? s : `${m} - ${h}`;
|
|
99
|
+
}
|
|
100
|
+
function j(e, t) {
|
|
101
|
+
return d(e, n.abapYear, t);
|
|
102
|
+
}
|
|
103
|
+
function M(e, t) {
|
|
104
|
+
return d(e, n.abapMonth, t);
|
|
105
|
+
}
|
|
106
|
+
function N(e, t) {
|
|
107
|
+
return d(e, n.abapDate, t);
|
|
108
|
+
}
|
|
109
|
+
function P(e, t) {
|
|
110
|
+
return d(e, n.abapDatetime, t);
|
|
111
|
+
}
|
|
112
|
+
function F(e, t) {
|
|
113
|
+
return d(e, n.odataDate, t);
|
|
114
|
+
}
|
|
115
|
+
function I(e, t) {
|
|
116
|
+
return d(e, n.odataDatetime, t);
|
|
117
|
+
}
|
|
118
|
+
function L(e, t) {
|
|
119
|
+
let i = t?.fallback ?? "", a = r(e);
|
|
120
|
+
if (!a) return i;
|
|
121
|
+
if (a.kind === "duration") {
|
|
122
|
+
let e = c(n.timeSeconds).formatDuration?.(a.durationMs, i) ?? i;
|
|
123
|
+
if (e === i) return i;
|
|
124
|
+
let [t = "00", r = "00", o = "00"] = e.split(":");
|
|
125
|
+
return `PT${t}H${r}M${o}S`;
|
|
126
|
+
}
|
|
127
|
+
let o = a.date;
|
|
128
|
+
return `PT${s(o.getHours())}H${s(o.getMinutes())}M${s(o.getSeconds())}S`;
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { E as C, A as D, w as E, i as O, m as S, h as T, C as _, j as a, I as b, _ as c, k as d, O as f, y as g, b as h, M as i, a as k, g as l, x as m, N as n, f as o, D as p, P as r, v as s, d as t, p as u, S as v, T as w, L as x, F as y };
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=formatDate-BUvpRI7H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatDate-BUvpRI7H.js","names":[],"sources":["../../src/formatters/boolean/parseAbapBoolean.ts","../../src/formatters/date/formatDate.ts"],"sourcesContent":["export function parseAbapBoolean(value: unknown): boolean {\n\tif (value && typeof value === \"string\" && value === \"X\") return true;\n\treturn false;\n}\n\nexport function parseBoolean(value: unknown): boolean {\n\tif (!value) return false;\n\tif (typeof value === \"string\") {\n\t\treturn [\"true\", \"x\", \"1\"].includes(value.toLowerCase());\n\t}\n\treturn Boolean(value);\n}\n","import { parseDateValue } from \"./parseDate\";\nimport { compileDatePreset, CompiledDateFormatPreset, DEFAULT_DATE_PRESET_NAMES, getCompiledDatePreset } from \"./presets\";\nimport { DateFormatPrecision, DateFormatPreset, FormatDateOptions, ParsedDateValue } from \"./types\";\n\n/**\n * Кеш скомпилированных объектных предустановок.\n *\n * Именованные предустановки компилируются в реестре, а объектные могут\n * передаваться напрямую в горячем пути таблиц. WeakMap сохраняет готовый\n * Intl.DateTimeFormat на время жизни объекта и не мешает сборке мусора.\n */\nconst objectPresetCache = new WeakMap<DateFormatPreset, CompiledDateFormatPreset>();\n\n/**\n * Дополняет числовую часть даты ведущим нулём.\n */\nfunction padDatePart(value: number): string {\n\treturn String(value).padStart(2, \"0\");\n}\n\n/**\n * Разрешает предустановку по имени или объекту.\n */\nfunction resolvePreset(presetOrName: string | DateFormatPreset): CompiledDateFormatPreset {\n\tif (typeof presetOrName !== \"string\") {\n\t\tconst cachedPreset = objectPresetCache.get(presetOrName);\n\t\tif (cachedPreset) return cachedPreset;\n\n\t\tconst compiledPreset = compileDatePreset(presetOrName);\n\t\tobjectPresetCache.set(presetOrName, compiledPreset);\n\t\treturn compiledPreset;\n\t}\n\n\tconst preset = getCompiledDatePreset(presetOrName);\n\tif (!preset) {\n\t\tthrow new Error(`Предустановка даты \"${presetOrName}\" не найдена`);\n\t}\n\treturn preset;\n}\n\n/**\n * Определяет fallback с учётом опций вызова и предустановки.\n */\nfunction resolveFallback(preset: CompiledDateFormatPreset, options?: FormatDateOptions): string {\n\treturn options?.fallback ?? preset.invalidFallback;\n}\n\n/**\n * Форматирует уже распарсенное значение.\n */\nfunction formatParsedValue(\n\tparsed: ParsedDateValue,\n\tpreset: CompiledDateFormatPreset,\n\tfallback: string,\n\tprecision: DateFormatPrecision\n): string {\n\tif (parsed.kind === \"duration\") {\n\t\treturn preset.formatDuration ? preset.formatDuration(parsed.durationMs, fallback) : fallback;\n\t}\n\n\treturn preset.formatDateTime(parsed.date, precision);\n}\n\n/**\n * Универсально форматирует дату/время по предустановке или её имени.\n */\nexport function formatDate(\n\tvalue: unknown,\n\tpresetOrName: string | DateFormatPreset = DEFAULT_DATE_PRESET_NAMES.date,\n\toptions?: FormatDateOptions\n): string {\n\tconst preset = resolvePreset(presetOrName);\n\tconst fallback = resolveFallback(preset, options);\n\tconst precision = options?.precision ?? \"day\";\n\tconst parsed = parseDateValue(value);\n\n\tif (!parsed) return fallback;\n\treturn formatParsedValue(parsed, preset, fallback, precision);\n}\n\n/**\n * Форматирует значение как дату `dd.MM.yyyy`.\n */\nexport function formatDateAsDate(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.date, options);\n}\n\n/**\n * Форматирует значение как дату и время `dd.MM.yyyy HH:mm`.\n */\nexport function formatDateAsDateTime(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.datetime, options);\n}\n\n/**\n * Форматирует значение как время `HH:mm`.\n */\nexport function formatDateAsTime(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.time, options);\n}\n\n/**\n * Форматирует значение как время `HH:mm:ss`.\n */\nexport function formatDateAsTimeSeconds(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.timeSeconds, options);\n}\n\n/**\n * Форматирует значение как короткую дату `03.03.2026`.\n */\nexport function formatDateAsDateShort(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.dateShort, options);\n}\n\n/**\n * Форматирует значение как среднюю дату `3 мар. 2026 г.`.\n */\nexport function formatDateAsDateMedium(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.dateMedium, options);\n}\n\n/**\n * Форматирует значение как длинную дату `3 марта 2026 г.`.\n */\nexport function formatDateAsDateLong(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.dateLong, options);\n}\n\n/**\n * Форматирует значение как короткую дату без года `03.03`.\n */\nexport function formatDateAsMonthShort(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.monthShort, options);\n}\n\n/**\n * Форматирует значение как среднюю дату без года `3 мар.`.\n */\nexport function formatDateAsMonthMedium(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.monthMedium, options);\n}\n\n/**\n * Форматирует значение как длинную дату без года `3 марта`.\n */\nexport function formatDateAsMonthLong(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.monthLong, options);\n}\n\n/**\n * Форматирует значение как сокращённый месяц и год `мар. 2026`.\n */\nexport function formatDateAsMonthYearMedium(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.monthYearMedium, options);\n}\n\n/**\n * Форматирует значение как полный месяц и год `март 2026`.\n */\nexport function formatDateAsMonthYearLong(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.monthYearLong, options);\n}\n\n/**\n * Форматирует значение как короткое время `18:03`.\n */\nexport function formatDateAsTimeShort(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.timeShort, options);\n}\n\n/**\n * Форматирует значение как среднее время `18:03:50`.\n */\nexport function formatDateAsTimeMedium(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.timeMedium, options);\n}\n\n/**\n * Форматирует значение как длинное время `18:03:50`.\n */\nexport function formatDateAsTimeLong(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.timeLong, options);\n}\n\n/**\n * Форматирует значение как короткую дату и время `03.03.2026 18:03`.\n */\nexport function formatDateAsDatetimeShort(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.datetimeShort, options);\n}\n\n/**\n * Форматирует значение как среднюю дату и время `3 мар. 2026 г. 18:03:50`.\n */\nexport function formatDateAsDatetimeMedium(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.datetimeMedium, options);\n}\n\n/**\n * Форматирует значение как длинную дату и время `3 марта 2026 г. 18:03:50`.\n */\nexport function formatDateAsDatetimeLong(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.datetimeLong, options);\n}\n\n/**\n * Форматирует диапазон дат через разделитель ` - `.\n */\nexport function formatDateRange(\n\tstartValue: unknown,\n\tendValue: unknown,\n\tpresetOrName: string | DateFormatPreset = DEFAULT_DATE_PRESET_NAMES.date,\n\toptions?: FormatDateOptions\n): string {\n\tconst preset = resolvePreset(presetOrName);\n\tconst fallback = resolveFallback(preset, options);\n\tconst precision = options?.precision ?? \"day\";\n\n\tconst startParsed = parseDateValue(startValue);\n\tconst endParsed = parseDateValue(endValue);\n\tif (!startParsed || !endParsed) return fallback;\n\n\tconst start = formatParsedValue(startParsed, preset, fallback, precision);\n\tconst end = formatParsedValue(endParsed, preset, fallback, precision);\n\tif (!start || !end) return fallback;\n\n\treturn `${start} - ${end}`;\n}\n\n/**\n * Форматирует значение как год `yyyy`.\n */\nexport function formatDateAsAbapYear(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.abapYear, options);\n}\n\n/**\n * Форматирует значение как календарный месяц `yyyyMM`.\n */\nexport function formatDateAsAbapMonth(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.abapMonth, options);\n}\n\n/**\n * Форматирует значение как дату `yyyyMMdd`.\n */\nexport function formatDateAsAbapDate(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.abapDate, options);\n}\n\n/**\n * Форматирует значение как дату `yyyyMMddHHmmss`.\n */\nexport function formatDateAsAbapDatetime(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.abapDatetime, options);\n}\n\n/**\n * Форматирует значение как дату `yyyy-MM-dd`.\n */\nexport function formatDateAsODataDate(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.odataDate, options);\n}\n\n/**\n * Форматирует значение как дату и время `yyyy-MM-ddTHH:mm:ss`.\n */\nexport function formatDateAsODataDatetime(value: unknown, options?: FormatDateOptions): string {\n\treturn formatDate(value, DEFAULT_DATE_PRESET_NAMES.odataDatetime, options);\n}\n\n/**\n * Форматирует значение как время `PT00H00M00S`.\n */\nexport function formatDateAsODataTime(value: unknown, options?: FormatDateOptions): string {\n\tconst fallback = options?.fallback ?? \"\";\n\tconst parsed = parseDateValue(value);\n\tif (!parsed) return fallback;\n\n\tif (parsed.kind === \"duration\") {\n\t\tconst timePreset = resolvePreset(DEFAULT_DATE_PRESET_NAMES.timeSeconds);\n\t\tconst formattedDuration = timePreset.formatDuration?.(parsed.durationMs, fallback) ?? fallback;\n\t\tif (formattedDuration === fallback) return fallback;\n\n\t\tconst [hours = \"00\", minutes = \"00\", seconds = \"00\"] = formattedDuration.split(\":\");\n\t\treturn `PT${hours}H${minutes}M${seconds}S`;\n\t}\n\n\tconst date = parsed.date;\n\treturn `PT${padDatePart(date.getHours())}H${padDatePart(date.getMinutes())}M${padDatePart(date.getSeconds())}S`;\n}\n"],"mappings":";;AAAA,SAAgB,EAAiB,GAAyB;CAEzD,OADA,GAAI,KAAS,OAAO,KAAU,YAAY,MAAU;AAErD;AAEA,SAAgB,EAAa,GAAyB;CAKrD,OAJK,IACD,OAAO,KAAU,WACb;EAAC;EAAQ;EAAK;CAAG,CAAC,CAAC,SAAS,EAAM,YAAY,CAAC,IAEhD,EAAQ,IAJI;AAKpB;;;ACAA,IAAM,oBAAoB,IAAI,QAAoD;AAKlF,SAAS,EAAY,GAAuB;CAC3C,OAAO,OAAO,CAAK,CAAC,CAAC,SAAS,GAAG,GAAG;AACrC;AAKA,SAAS,EAAc,GAAmE;CACzF,IAAI,OAAO,KAAiB,UAAU;EACrC,IAAM,IAAe,EAAkB,IAAI,CAAY;EACvD,IAAI,GAAc,OAAO;EAEzB,IAAM,IAAiB,EAAkB,CAAY;EAErD,OADA,EAAkB,IAAI,GAAc,CAAc,GAC3C;CACR;CAEA,IAAM,IAAS,EAAsB,CAAY;CACjD,IAAI,CAAC,GACJ,MAAU,MAAM,uBAAuB,EAAa,aAAa;CAElE,OAAO;AACR;AAKA,SAAS,EAAgB,GAAkC,GAAqC;CAC/F,OAAO,GAAS,YAAY,EAAO;AACpC;AAKA,SAAS,EACR,GACA,GACA,GACA,GACS;CAKT,OAJI,EAAO,SAAS,aACZ,EAAO,iBAAiB,EAAO,eAAe,EAAO,YAAY,CAAQ,IAAI,IAG9E,EAAO,eAAe,EAAO,MAAM,CAAS;AACpD;AAKA,SAAgB,EACf,GACA,IAA0C,EAA0B,MACpE,GACS;CACT,IAAM,IAAS,EAAc,CAAY,GACnC,IAAW,EAAgB,GAAQ,CAAO,GAC1C,IAAY,GAAS,aAAa,OAClC,IAAS,EAAe,CAAK;CAGnC,OADK,IACE,EAAkB,GAAQ,GAAQ,GAAU,CAAS,IADxC;AAErB;AAKA,SAAgB,EAAiB,GAAgB,GAAqC;CACrF,OAAO,EAAW,GAAO,EAA0B,MAAM,CAAO;AACjE;AAKA,SAAgB,EAAqB,GAAgB,GAAqC;CACzF,OAAO,EAAW,GAAO,EAA0B,UAAU,CAAO;AACrE;AAKA,SAAgB,EAAiB,GAAgB,GAAqC;CACrF,OAAO,EAAW,GAAO,EAA0B,MAAM,CAAO;AACjE;AAKA,SAAgB,EAAwB,GAAgB,GAAqC;CAC5F,OAAO,EAAW,GAAO,EAA0B,aAAa,CAAO;AACxE;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,OAAO,EAAW,GAAO,EAA0B,WAAW,CAAO;AACtE;AAKA,SAAgB,EAAuB,GAAgB,GAAqC;CAC3F,OAAO,EAAW,GAAO,EAA0B,YAAY,CAAO;AACvE;AAKA,SAAgB,EAAqB,GAAgB,GAAqC;CACzF,OAAO,EAAW,GAAO,EAA0B,UAAU,CAAO;AACrE;AAKA,SAAgB,EAAuB,GAAgB,GAAqC;CAC3F,OAAO,EAAW,GAAO,EAA0B,YAAY,CAAO;AACvE;AAKA,SAAgB,EAAwB,GAAgB,GAAqC;CAC5F,OAAO,EAAW,GAAO,EAA0B,aAAa,CAAO;AACxE;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,OAAO,EAAW,GAAO,EAA0B,WAAW,CAAO;AACtE;AAKA,SAAgB,EAA4B,GAAgB,GAAqC;CAChG,OAAO,EAAW,GAAO,EAA0B,iBAAiB,CAAO;AAC5E;AAKA,SAAgB,EAA0B,GAAgB,GAAqC;CAC9F,OAAO,EAAW,GAAO,EAA0B,eAAe,CAAO;AAC1E;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,OAAO,EAAW,GAAO,EAA0B,WAAW,CAAO;AACtE;AAKA,SAAgB,EAAuB,GAAgB,GAAqC;CAC3F,OAAO,EAAW,GAAO,EAA0B,YAAY,CAAO;AACvE;AAKA,SAAgB,EAAqB,GAAgB,GAAqC;CACzF,OAAO,EAAW,GAAO,EAA0B,UAAU,CAAO;AACrE;AAKA,SAAgB,EAA0B,GAAgB,GAAqC;CAC9F,OAAO,EAAW,GAAO,EAA0B,eAAe,CAAO;AAC1E;AAKA,SAAgB,EAA2B,GAAgB,GAAqC;CAC/F,OAAO,EAAW,GAAO,EAA0B,gBAAgB,CAAO;AAC3E;AAKA,SAAgB,EAAyB,GAAgB,GAAqC;CAC7F,OAAO,EAAW,GAAO,EAA0B,cAAc,CAAO;AACzE;AAKA,SAAgB,EACf,GACA,GACA,IAA0C,EAA0B,MACpE,GACS;CACT,IAAM,IAAS,EAAc,CAAY,GACnC,IAAW,EAAgB,GAAQ,CAAO,GAC1C,IAAY,GAAS,aAAa,OAElC,IAAc,EAAe,CAAU,GACvC,IAAY,EAAe,CAAQ;CACzC,IAAI,CAAC,KAAe,CAAC,GAAW,OAAO;CAEvC,IAAM,IAAQ,EAAkB,GAAa,GAAQ,GAAU,CAAS,GAClE,IAAM,EAAkB,GAAW,GAAQ,GAAU,CAAS;CAGpE,OAFI,CAAC,KAAS,CAAC,IAAY,IAEpB,GAAG,EAAM,KAAK;AACtB;AAKA,SAAgB,EAAqB,GAAgB,GAAqC;CACzF,OAAO,EAAW,GAAO,EAA0B,UAAU,CAAO;AACrE;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,OAAO,EAAW,GAAO,EAA0B,WAAW,CAAO;AACtE;AAKA,SAAgB,EAAqB,GAAgB,GAAqC;CACzF,OAAO,EAAW,GAAO,EAA0B,UAAU,CAAO;AACrE;AAKA,SAAgB,EAAyB,GAAgB,GAAqC;CAC7F,OAAO,EAAW,GAAO,EAA0B,cAAc,CAAO;AACzE;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,OAAO,EAAW,GAAO,EAA0B,WAAW,CAAO;AACtE;AAKA,SAAgB,EAA0B,GAAgB,GAAqC;CAC9F,OAAO,EAAW,GAAO,EAA0B,eAAe,CAAO;AAC1E;AAKA,SAAgB,EAAsB,GAAgB,GAAqC;CAC1F,IAAM,IAAW,GAAS,YAAY,IAChC,IAAS,EAAe,CAAK;CACnC,IAAI,CAAC,GAAQ,OAAO;CAEpB,IAAI,EAAO,SAAS,YAAY;EAE/B,IAAM,IADa,EAAc,EAA0B,WACjC,CAAA,CAAW,iBAAiB,EAAO,YAAY,CAAQ,KAAK;EACtF,IAAI,MAAsB,GAAU,OAAO;EAE3C,IAAM,CAAC,IAAQ,MAAM,IAAU,MAAM,IAAU,QAAQ,EAAkB,MAAM,GAAG;EAClF,OAAO,KAAK,EAAM,GAAG,EAAQ,GAAG,EAAQ;CACzC;CAEA,IAAM,IAAO,EAAO;CACpB,OAAO,KAAK,EAAY,EAAK,SAAS,CAAC,EAAE,GAAG,EAAY,EAAK,WAAW,CAAC,EAAE,GAAG,EAAY,EAAK,WAAW,CAAC,EAAE;AAC9G"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { _ as e, r as t, x as n } from "./array-D-_yMMUK.js";
|
|
2
2
|
import { r } from "./formulas-BXT_XBWI.js";
|
|
3
3
|
import { i } from "./isRecord-DXDTW-jA.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
7
|
-
import { isSafe as
|
|
4
|
+
import { t as a } from "./formatDate-BUvpRI7H.js";
|
|
5
|
+
import { _ as o, d as s, j as c, o as l, t as u } from "./scalarTypeClassification-BZcFmIyR.js";
|
|
6
|
+
import { S as d, _ as f, c as ee, d as p, g as m, n as te, o as ne, p as re, t as h, v as ie } from "./validate-DsUR-bFF.js";
|
|
7
|
+
import { isSafe as ae } from "../validators/index.js";
|
|
8
|
+
import { t as oe } from "./string-comparison-BKT7PXmq.js";
|
|
8
9
|
import { t as se } from "./uuid-CUJPAbRY.js";
|
|
9
10
|
//#region src/formatters/strings/formatRussianPlural.ts
|
|
10
11
|
var ce = new Intl.PluralRules("ru-RU");
|
|
@@ -168,7 +169,7 @@ function De(e) {
|
|
|
168
169
|
//#endregion
|
|
169
170
|
//#region src/formatters/number/isZeroValue.ts
|
|
170
171
|
function y(e) {
|
|
171
|
-
let t =
|
|
172
|
+
let t = c(e);
|
|
172
173
|
return typeof t == "number" ? t === 0 : typeof t == "bigint" && t === 0n;
|
|
173
174
|
}
|
|
174
175
|
//#endregion
|
|
@@ -535,7 +536,7 @@ function jt(e, t = /* @__PURE__ */ new Date()) {
|
|
|
535
536
|
//#endregion
|
|
536
537
|
//#region src/formatters/date/formatInstantDateTime.ts
|
|
537
538
|
function Mt(e, t) {
|
|
538
|
-
let n =
|
|
539
|
+
let n = s(e), r = t.fallback ?? "";
|
|
539
540
|
if (!n || n.kind !== "date-time") return r;
|
|
540
541
|
try {
|
|
541
542
|
return new Intl.DateTimeFormat(t.locale ?? "ru-RU", {
|
|
@@ -604,7 +605,7 @@ function zt(e, t) {
|
|
|
604
605
|
break;
|
|
605
606
|
}
|
|
606
607
|
}
|
|
607
|
-
return !n ||
|
|
608
|
+
return !n || c(e) === void 0 ? e : Bt(e, t);
|
|
608
609
|
}
|
|
609
610
|
return e;
|
|
610
611
|
}
|
|
@@ -729,7 +730,7 @@ function Jt(e, t) {
|
|
|
729
730
|
};
|
|
730
731
|
}
|
|
731
732
|
function Yt(e) {
|
|
732
|
-
let t = e.fallbackState ?? "none", n = qt(Object.entries(e.entries).sort(([e], [t]) =>
|
|
733
|
+
let t = e.fallbackState ?? "none", n = qt(Object.entries(e.entries).sort(([e], [t]) => oe(e, t)), t);
|
|
733
734
|
return {
|
|
734
735
|
entries: e.entries,
|
|
735
736
|
fallbackState: t,
|
|
@@ -797,15 +798,15 @@ var on = Object.freeze({
|
|
|
797
798
|
date: "date"
|
|
798
799
|
});
|
|
799
800
|
function Z(e, t, r) {
|
|
800
|
-
if (!
|
|
801
|
-
let i =
|
|
801
|
+
if (!ae(e)) return "";
|
|
802
|
+
let i = u(t.type);
|
|
802
803
|
if (i === "number") {
|
|
803
804
|
let t = r?.numberPresetName?.trim();
|
|
804
805
|
return C(e, t && ie(t) ? t : on.number);
|
|
805
806
|
}
|
|
806
807
|
if (i === "date") {
|
|
807
|
-
let t = r?.datePresetName?.trim(), n = t &&
|
|
808
|
-
return a(
|
|
808
|
+
let t = r?.datePresetName?.trim(), n = t && o(t) ? t : on.date;
|
|
809
|
+
return a(l(e), n);
|
|
809
810
|
}
|
|
810
811
|
return n(e);
|
|
811
812
|
}
|
|
@@ -1212,4 +1213,4 @@ function Gn(e, t) {
|
|
|
1212
1213
|
//#endregion
|
|
1213
1214
|
export { L as $, Pt as A, w as At, Dt as B, he as Bt, X as C, Ve as Ct, zt as D, Ie as Dt, Rt as E, Ue as Et, Tt as F, Ke as Ft, H as G, de as Gt, V as H, me as Ht, B as I, ze as It, At as J, g as Jt, kt as K, ue as Kt, wt as L, qe as Lt, Ft as M, Le as Mt, It as N, Ge as Nt, G as O, We as Ot, Mt as P, Re as Pt, F as Q, W as R, Oe as Rt, Kt as S, Ne as St, Ht as T, Fe as Tt, Et as U, pe as Ut, U as V, ge as Vt, jt as W, fe as Wt, gt as X, I as Y, dt as Z, Ut as _, Ze as _t, Vn as a, ct as at, Gt as b, Je as bt, Dn as c, tt as ct, ln as d, j as dt, ft as et, Z as f, N as ft, Xt as g, k as gt, Zt as h, nt as ht, Bn as i, lt as it, Nt as j, Be as jt, Lt as k, He as kt, En as l, A as lt, rn as m, Qe as mt, Un as n, pt as nt, Hn as o, P as ot, an as p, $e as pt, z as q, le as qt, Wn as r, st as rt, Mn as s, et as st, Gn as t, mt as tt, Cn as u, M as ut, Y as v, Xe as vt, Vt as w, Pe as wt, J as x, C as xt, Wt as y, Ye as yt, Ot as z, y as zt };
|
|
1214
1215
|
|
|
1215
|
-
//# sourceMappingURL=formatters-
|
|
1216
|
+
//# sourceMappingURL=formatters-rxriDRPk.js.map
|