@firestitch/report 18.17.4 → 18.18.0
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/app/reports/api-error-message.d.ts +1 -0
- package/app/reports/data/report.data.d.ts +8 -0
- package/app/reports/dialogs/report-package-import/report-package-import.component.d.ts +37 -0
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +2 -0
- package/app/reports/interfaces/report-package-check.interface.d.ts +21 -0
- package/app/reports/interfaces/report-package-finding-severity.type.d.ts +1 -0
- package/app/reports/interfaces/report-package-finding.interface.d.ts +7 -0
- package/app/reports/interfaces/report-package-import-response.interface.d.ts +6 -0
- package/app/reports/interfaces/report-package-imported-report.interface.d.ts +4 -0
- package/app/reports/views/reports/fs-ai-reports.component.d.ts +4 -0
- package/esm2022/app/reports/api-error-message.mjs +8 -0
- package/esm2022/app/reports/data/report.data.mjs +37 -1
- package/esm2022/app/reports/dialogs/report-package-import/report-package-import.component.mjs +144 -0
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +13 -11
- package/esm2022/app/reports/interfaces/report-package-check.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-package-finding-severity.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-package-finding.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-package-import-response.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-package-imported-report.interface.mjs +2 -0
- package/esm2022/app/reports/tile-loads.mjs +6 -9
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
- package/esm2022/app/reports/views/reports/fs-ai-reports.component.mjs +56 -9
- package/esm2022/public_api.mjs +6 -1
- package/fesm2022/{firestitch-report-echarts-BxAcubsP.mjs → firestitch-report-echarts-qh_mqik9.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-BxAcubsP.mjs.map → firestitch-report-echarts-qh_mqik9.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-BtC-wiNZ.mjs → firestitch-report-firestitch-report-D-WG_G5d.mjs} +264 -59
- package/fesm2022/firestitch-report-firestitch-report-D-WG_G5d.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +5 -0
- package/fesm2022/firestitch-report-firestitch-report-BtC-wiNZ.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"firestitch-report-firestitch-report-BtC-wiNZ.mjs","sources":["../../src/app/reports/report-viewer-features.ts","../../src/app/reports/data/report.data.ts","../../src/app/reports/dialogs/instruction-history/instruction-history.component.ts","../../src/app/reports/dialogs/instruction-history/instruction-history.component.html","../../src/app/reports/dialogs/global-settings/components/ai-knowledge/ai-knowledge.component.ts","../../src/app/reports/dialogs/global-settings/components/ai-knowledge/ai-knowledge.component.html","../../src/app/reports/dialogs/global-settings/components/general/general.component.ts","../../src/app/reports/dialogs/global-settings/components/general/general.component.html","../../src/app/reports/dialogs/entity-functions/entity-functions.component.ts","../../src/app/reports/dialogs/entity-functions/entity-functions.component.html","../../src/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.ts","../../src/app/reports/dialogs/global-settings/components/semantic-database/semantic-database.component.html","../../src/app/reports/dialogs/global-settings/global-settings.component.ts","../../src/app/reports/dialogs/global-settings/global-settings.component.html","../../src/app/reports/interfaces/report.interface.ts","../../src/app/reports/views/reports/fs-ai-reports.component.ts","../../src/app/reports/views/reports/fs-ai-reports.component.html","../../src/app/reports/canvas-landing-page.ts","../../src/app/reports/enums/report-chart-date-label.enum.ts","../../src/app/reports/enums/report-chart-color.enum.ts","../../src/app/reports/enums/report-chart-data-labels.enum.ts","../../src/app/reports/enums/report-chart-line-style.enum.ts","../../src/app/reports/enums/report-chart-mark-stat.enum.ts","../../src/app/reports/enums/report-list-column-format.enum.ts","../../src/app/reports/enums/report-number-units.enum.ts","../../src/app/reports/enums/report-value-format.enum.ts","../../src/app/reports/format.ts","../../src/app/reports/text.ts","../../src/app/reports/enums/report-change-polarity.enum.ts","../../src/app/reports/theme/palette.ts","../../src/app/reports/theme/typography.ts","../../src/app/reports/option-builder.ts","../../src/app/reports/drill-crumbs.ts","../../src/app/reports/group-by.ts","../../src/app/reports/report-filter-items.ts","../../src/app/reports/report-tile.ts","../../src/app/reports/report-state.ts","../../src/app/reports/export/report-filter-lines.ts","../../src/app/reports/filter-text.ts","../../src/app/reports/layout.ts","../../src/app/reports/tile-data-state.ts","../../src/app/reports/enums/report-value-formula.enum.ts","../../src/app/reports/values.ts","../../src/app/reports/consts/report-week.const.ts","../../src/app/reports/list-config.ts","../../src/app/reports/report-grid-layout.ts","../../src/app/reports/services/report-filter-state.service.ts","../../src/app/reports/services/report-filter-options.service.ts","../../src/app/reports/anchor-at-point.ts","../../src/app/reports/dialogs/list-columns/list-columns.component.ts","../../src/app/reports/dialogs/list-columns/list-columns.component.html","../../src/app/reports/enums/report-kpi-trend.enum.ts","../../src/app/reports/kpi-card.ts","../../src/app/reports/mark-click.ts","../../src/app/reports/tile-loads.ts","../../src/app/reports/output-notes.ts","../../src/app/reports/components/component-note/component-note.component.ts","../../src/app/reports/components/component-note/component-note.component.html","../../src/app/reports/components/component-chart/component-chart.component.ts","../../src/app/reports/components/component-chart/component-chart.component.html","../../src/app/reports/data/report-grid-source.ts","../../src/app/reports/components/component-grid/report-grid-cell.pipe.ts","../../src/app/reports/components/component-grid/report-grid-formatter.ts","../../src/app/reports/components/component-grid/component-grid.component.ts","../../src/app/reports/components/component-grid/component-grid.component.html","../../src/app/reports/components/component-kpi/components/sparkline/sparkline.component.ts","../../src/app/reports/components/component-kpi/components/sparkline/sparkline.component.html","../../src/app/reports/components/component-kpi/component-kpi.component.ts","../../src/app/reports/components/component-kpi/component-kpi.component.html","../../src/app/reports/pipes/report-date.pipe.ts","../../src/app/reports/pipes/report-number.pipe.ts","../../src/app/reports/pipes/report-output.pipe.ts","../../src/app/reports/components/component-list/component-list.component.ts","../../src/app/reports/components/component-list/component-list.component.html","../../src/app/reports/components/component-text/value-embed.plugin.ts","../../src/app/reports/components/component-text/component-text.component.ts","../../src/app/reports/components/component-text/component-text.component.html","../../src/app/reports/components/report-component/report-component.component.ts","../../src/app/reports/components/report-component/report-component.component.html","../../src/app/reports/components/report-canvas/report-canvas.component.ts","../../src/app/reports/components/report-canvas/report-canvas.component.html","../../src/app/reports/data/report-ai-chat.data.ts","../../src/app/reports/filter-settings-rules.ts","../../src/app/reports/dialogs/component-settings/component-settings.component.ts","../../src/app/reports/dialogs/component-settings/component-settings.component.html","../../src/app/reports/components/timezone-select/timezone-select.component.ts","../../src/app/reports/components/timezone-select/timezone-select.component.html","../../src/app/reports/dialogs/report-settings/report-locale-patch.ts","../../src/app/reports/dialogs/report-settings/report-settings.component.ts","../../src/app/reports/dialogs/report-settings/report-settings.component.html","../../src/app/reports/export/report-grid-export.ts","../../src/app/reports/export/report-export-collector.service.ts","../../src/app/reports/export/offscreen-chart.ts","../../src/app/reports/export/report-text-layout.service.ts","../../src/app/reports/export/report-pdf.service.ts","../../src/app/reports/export/report-pptx.service.ts","../../src/app/reports/export/report-export.service.ts","../../src/app/reports/report-chat-viewer-state.ts","../../src/app/reports/report-date-presets.ts","../../src/app/reports/report-saved-filters.ts","../../src/app/reports/views/report/fs-ai-report.component.ts","../../src/app/reports/views/report/fs-ai-report.component.html","../../src/app/reports/services/report.service.ts","../../src/public_api.ts","../../src/firestitch-report.ts"],"sourcesContent":["import { ReportViewerFeature } from './interfaces/report-viewer-feature.type';\nimport { ReportFilterGroup } from './interfaces/report.interface';\n\n\n// The viewer features this viewer implements: the report GET names them\n// (features=<comma list>), and the server assembles the report for exactly\n// these. A feature joins the list in the change that builds its control, never\n// before: the server sends a group only in a shape the viewer says it can show\n// and clear, and a listed feature without its control would get a filter the\n// viewer can neither show nor clear.\n//\n// scopeFilters needs no control of its own: a scope member is an ordinary\n// filter row on its tile. excludeValues is a select's 'Exclude these' row,\n// numberRange its min/max control, matchAny the report bar's Match select,\n// and pageScope shows a page's groups in the report bar of that page.\n// cascadingOptions narrows a select's list by the other filters of its tile\n// (ReportFilterOptionsService). drill is a time chart's click down, with\n// the tile header's breadcrumb and its menu's Drill up and Back to top as the\n// way back. grid is a table tile drawn by fs-grid: a server that serves it\n// sends a table only to a viewer that names it.\nexport const VIEWER_FEATURES: readonly ReportViewerFeature[] = [\n 'scopeFilters',\n 'excludeValues',\n 'numberRange',\n 'matchAny',\n 'pageScope',\n 'cascadingOptions',\n 'drill',\n 'grid',\n];\n\n// The features a report offers on this screen: the ones its server serves\n// (Report.viewerFeatures) that this viewer also implements.\nexport function offeredViewerFeatures(served: readonly ReportViewerFeature[] | null | undefined): ReportViewerFeature[] {\n return (served ?? []).filter((feature) => VIEWER_FEATURES.includes(feature));\n}\n\n// Whether a select group offers 'Exclude these': the one rule the report bar,\n// the tile headers and the report settings' default row share. The server\n// must serve excludeValues, and no enabled member may bind several columns\n// (multiColumn), since the server cannot leave values out there (an older\n// server sends no multiColumn, and the toggle shows as before).\nexport function offersExclude(\n group: Pick<ReportFilterGroup, 'type' | 'multiColumn'>,\n features: readonly ReportViewerFeature[] | null | undefined,\n): boolean {\n return group.type === 'select'\n && !group.multiColumn\n && (features ?? []).includes('excludeValues');\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { FsApi, RequestConfig, RequestMethod, StreamEvent } from '@firestitch/api';\nimport { GridRequest } from '@firestitch/grid';\n\nimport { Observable } from 'rxjs';\n\nimport { ReportExportLine } from '../interfaces/report-export-line.interface';\nimport { ReportFilterGroupChanges } from '../interfaces/report-filter-group-changes.interface';\nimport { ReportFilterOptionsRequest } from '../interfaces/report-filter-options-request.interface';\nimport { ReportFilterOptions } from '../interfaces/report-filter-options.interface';\nimport { ReportSavedFilterChanges } from '../interfaces/report-saved-filter-changes.interface';\nimport { ReportSavedFilter } from '../interfaces/report-saved-filter.interface';\nimport {\n ChartGranularity,\n ComponentDataState,\n ComponentExportResponse,\n ReportComponentSql,\n ReportLocales,\n ReportPageValue,\n ReportTree,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { ReportExportFormat } from '../interfaces/report-export-format.type';\nimport { VIEWER_FEATURES } from '../report-viewer-features';\n\n\n// API gateway for the Reports module. Every endpoint hangs off [basePath],\n// which defaults to \"reports\" (the framework reports backend at /api/reports)\n// and can be repointed by the host so the package stays self-contained and portable.\n@Injectable({\n providedIn: 'root',\n})\nexport class ReportData<T = any> {\n private _api = inject(FsApi);\n\n // The API root for every reports endpoint. Defaults to the framework reports\n // context; set it once (e.g. from the host's report page) to mount elsewhere.\n public basePath = 'reports';\n\n // Build an endpoint path under the configured base, e.g. _path() => \"ai/reports\",\n // _path(`${id}/pages`) => \"ai/reports/123/pages\".\n private _path(suffix = ''): string {\n return suffix ? `${this.basePath}/${suffix}` : this.basePath;\n }\n\n public reports(query: any = {}, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(),\n query,\n {\n key: 'reports',\n ...config,\n },\n );\n }\n\n // Both halves of the listing — reports AND the folders they are filed into —\n // from the one GET. No `key`, because the whole payload is the answer here;\n // reports() keeps its 'reports' key for callers that only want the flat list.\n public tree(query: any = {}, config: RequestConfig = {}): Observable<ReportTree> {\n return this._api.get(\n this._path(),\n query,\n config,\n );\n }\n\n public create(name: string, reportFolderId: number = null, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(),\n { name, reportFolderId },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // File a report under a folder, or pass null to move it to the root. Sent\n // explicitly (never omitted) so the backend can tell \"move to root\" from\n // \"leave the folder alone\".\n public moveReport(reportId: number, reportFolderId: number | null, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n { reportFolderId },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n public createFolder(\n name: string,\n parentReportFolderId: number = null,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path('folders'),\n { name, parentReportFolderId },\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n // Rename and/or move a folder. Only the keys passed are acted on server-side,\n // so a rename never disturbs the parent and a drag never disturbs the name.\n public updateFolder(\n reportFolderId: number,\n folder: Record<string, unknown>,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`folders/${reportFolderId}`),\n folder,\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n // Soft-delete, whatever the folder holds: its contents leave the listing with\n // it, and undeleteFolder() brings the lot back.\n public deleteFolder(reportFolderId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`folders/${reportFolderId}`),\n {},\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n // Restore a soft-deleted folder through its own action endpoint — the folder\n // PUT does not accept `state`. Any deleted folder above it is restored too, so\n // it lands back where it was.\n public undeleteFolder(reportFolderId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`folders/${reportFolderId}/undelete`),\n {},\n {\n key: 'folder',\n ...config,\n },\n );\n }\n\n public rename(reportId: number, name: string, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n { name },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Report settings: any subset of { name, pageWidth, pageHeight, timezone,\n // locale, currency, styles, headerFooter } — styles carry the\n // report's typographic config (e.g. heading size), headerFooter the\n // header/footer band depths in inches. The page size is in inches and\n // width/height go together. locale (a BCP 47 tag) and currency (an ISO 4217\n // code) are each sent only to change them; '' returns the report to the\n // default, and the currency only names what the amounts are in.\n public update(reportId: number, settings: Record<string, unknown>, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path(`${reportId}`),\n settings,\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Append a blank page to the report; resolves to the new page.\n public addPage(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/pages`),\n {},\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Any subset of { name, masterHidden }. An empty name is stored as null\n // server-side, which puts the tab back on its positional \"Page N\" label;\n // masterHidden hides the report's header and footer on this page.\n public updatePage(\n reportId: number,\n pageId: number,\n page: { name?: string; masterHidden?: boolean },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/pages/${pageId}`),\n page,\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Delete a page and everything on it. Refused server-side for the last\n // remaining page — a report with no canvas is a deleted report, not a page\n // operation.\n public deletePage(reportId: number, pageId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/pages/${pageId}`),\n {},\n {\n key: 'page',\n ...config,\n },\n );\n }\n\n // Persist the tab order after a drag — the whole list, in its new order, so\n // the sequence stays gapless without the server inferring the move.\n public savePagePositions(\n reportId: number,\n positions: { pageId: number; order: number }[],\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/pages/positions`),\n { positions },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Component settings: any subset of { title, padding } — the human-facing\n // dialog edits — or a text block's { html } from its inline editor; geometry\n // (x/y/w/h) is persisted via savePositions from the canvas instead.\n public updateComponent(\n reportId: number,\n componentId: number,\n settings: Record<string, unknown>,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/components/${componentId}/settings`),\n settings,\n {\n key: 'component',\n ...config,\n },\n );\n }\n\n // Place a text block — on a page, or in the header/footer when pageId is\n // omitted. The only component the UI creates itself: charts, lists and KPIs\n // need a query and come from the chat. Resolves to { id }.\n public addText(\n reportId: number,\n text: { pageId?: number; html?: string; x: number; y: number; w: number; h: number },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components`),\n text,\n {\n key: 'component',\n ...config,\n },\n );\n }\n\n // Delete one component from the canvas, together with its filters and any\n // filter group they leave empty. Soft server-side, but there is no restore\n // anywhere in the UI, so the dialog's confirm presents it as permanent.\n public deleteComponent(\n reportId: number,\n componentId: number,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/components/${componentId}`),\n {},\n {\n key: 'component',\n ...config,\n },\n );\n }\n\n // Soft-delete: the report leaves the listing but keeps its pages and\n // components, so undelete() brings back the same document.\n public delete(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}`),\n {},\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Restore a soft-deleted report through its own action endpoint — the report\n // PUT does not accept `state`. Its folder is restored too when it is deleted,\n // or inside one that is, so the report lands back where it was.\n public undelete(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/undelete`),\n {},\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // The assembled structure: pages → components (+ their filters) and the\n // report's filter groups. `features` names what this viewer implements\n // (VIEWER_FEATURES), so the server sends every group in a shape the viewer\n // can show and clear.\n public get(reportId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}`),\n { features: VIEWER_FEATURES.join(',') },\n {\n key: 'report',\n ...config,\n },\n );\n }\n\n // Persist geometry for the moved components only — any subset of\n // { x, y, w, h } (inches).\n public savePositions(\n reportId: number,\n positions: ({ componentId: number } & Partial<{ x: number; y: number; w: number; h: number }>)[],\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/components/positions`),\n { positions },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // One component's data. The body carries everything session-scoped: the\n // resolved filter values and the component's own interaction state.\n //\n // `isExport` marks the read as part of a PDF/PowerPoint render. The server\n // gives those a longer per-statement ceiling than an on-screen tile, because\n // a reader watching an export progress bar can wait for a query nobody would\n // tolerate waiting for on a dashboard.\n public componentData(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[] = [],\n state: ComponentDataState = {},\n isExport = false,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/data`),\n { filters, state, export: isExport },\n {\n key: 'data',\n ...config,\n },\n );\n }\n\n // One grid tile's read (ReportGridSource): the same route as componentData,\n // its body's `grid` the grid's request. The answer streams as\n // newline-delimited JSON, one event per line: {report} first, then\n // {grid: part} for each part of the read, a heartbeat {at} between\n // statements, and the envelope with the read's summary last. The body's\n // filters and state narrow the rows as they narrow any tile's; the grid's\n // own column filters travel inside grid.layout. `isExport` is\n // componentData's.\n public componentGrid(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[],\n state: ComponentDataState,\n grid: GridRequest,\n isExport = false,\n config: RequestConfig = {},\n ): Observable<StreamEvent> {\n return this._api.stream(\n RequestMethod.Post,\n this._path(`${reportId}/components/${componentId}/data`),\n { filters, state, export: isExport, grid },\n config,\n );\n }\n\n // The numbers of a page's values — or the master's, for the header and\n // footer — in one request: a row per value that page reads, shown by some\n // text or read by a formula it shows (ReportPageValue). `filters` carries\n // the resolved values for every value of the layer together; each value the\n // server reads picks out its own. `isExport` is componentData's.\n //\n // The server reads one statement per distinct query (values sharing a\n // query and its filters are folded into one; a formula runs none) and may\n // stream a keepAlive pulse before each, so a slow page never sits silent\n // until the connection drops. The body stays one JSON with the rows at data.values,\n // which FsApi reads with the 'values' key, as exportComponent's streamed\n // response is read.\n //\n // `matchAnyGroupIds` is a tile's (ComponentDataState): while the groups\n // match 'any', the groups that combine (valuesMatchAnyGroupIds). Sent only\n // when it lists any; the server checks each value against it as it checks\n // a tile.\n public pageValues(\n reportId: number,\n pageId: number,\n filters: ResolvedFilterValue[] = [],\n isExport = false,\n config: RequestConfig = {},\n matchAnyGroupIds: number[] = [],\n ): Observable<ReportPageValue[]> {\n return this._api.post(\n this._path(`${reportId}/pages/${pageId}/values`),\n { filters, export: isExport, ...(matchAnyGroupIds.length ? { matchAnyGroupIds } : {}) },\n {\n key: 'values',\n ...config,\n },\n );\n }\n\n // Exports one component to CSV server-side: the file is what the screen\n // shows (a chart or KPI as rendered, a list in full in the screen's order).\n // The backend streams percentage progress while it writes.\n //\n // key: null on purpose, unlike the key: 'url' presigned-export pattern: the\n // response also carries `notes`, the sentences saying how the file falls\n // short of the full result, and the caller has to show them before it hands\n // the url to FsProcess.download. `title` is the component's title as the\n // viewer reads it, its tokens filled ('Sign-ups — September 2026'), which\n // the server names the file after. `format` 'xlsx' asks for an Excel file\n // (ReportExportFormat); an older server ignores it and sends the CSV.\n public exportComponent(\n reportId: number,\n componentId: number,\n filters: ResolvedFilterValue[] = [],\n state: ComponentDataState = {},\n title = '',\n config: RequestConfig = {},\n format: ReportExportFormat = 'csv',\n ): Observable<ComponentExportResponse> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/export`),\n { filters, state, title, ...(format !== 'csv' ? { format } : {}) },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Exports EVERY component on the report — or on one page — server-side and\n // resolves to a presigned URL for a zip of one CSV per component, foldered by\n // page, plus an 'Export Notes.txt'. `filters` carries the resolved values for\n // every component together; each one picks out its own. `frequency` is the\n // report's group-by grain (the server re-buckets only the tiles that follow\n // it: time-series charts and tables over a time axis), and `filterLines` is the filter bar as the viewer reads it\n // (exportLines), which the notes file writes. Their text goes as\n // filterSummary too, for a server that does not read filterLines; the\n // lines are left out when there are none. `states` is each tile's own\n // state by component id (zipExportStates), so each file holds what its\n // tile shows; it is left out when no tile has any. `titles` holds each component's title as the viewer reads it, its tokens\n // filled, by component id, which the server names the component's file\n // after; left out when there are none. `format` 'xlsx' asks for one Excel\n // workbook instead of the zip: a Notes sheet, then a sheet per tile. Same\n // keep-alive contract as exportComponent, over a longer run; consume\n // through FsProcess.download.\n public exportReport(\n reportId: number,\n filters: ResolvedFilterValue[] = [],\n pageId: number | null = null,\n frequency: ChartGranularity | null = null,\n filterLines: ReportExportLine[] = [],\n states: Record<number, ComponentDataState> = {},\n titles: Record<number, string> = {},\n config: RequestConfig = {},\n format: ReportExportFormat = 'csv',\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/export`),\n {\n filters,\n ...(pageId ? { pageId } : {}),\n ...(frequency ? { frequency } : {}),\n filterSummary: filterLines.map((line) => line.text),\n ...(filterLines.length ? { filterLines } : {}),\n ...(Object.keys(states).length ? { states } : {}),\n ...(Object.keys(titles).length ? { titles } : {}),\n ...(format !== 'csv' ? { format } : {}),\n },\n {\n key: 'url',\n ...config,\n },\n );\n }\n\n // Distinct options for a select filter (drives multiselect controls).\n public filterOptions(reportId: number, filterId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}/filters/${filterId}/options`),\n {},\n {\n key: 'options',\n ...config,\n },\n );\n }\n\n // The statement a component runs, for the SQL tab.\n //\n // Fetched rather than read off the component, because a DERIVED component has\n // no stored SQL — it stores a document, and its statement only exists once\n // the backend compiles that document. Compiled per request, for the one\n // component being looked at, so opening a report never pays for it.\n //\n // `key: null` because the whole envelope is the answer here: a stale document\n // comes back as { sql: null, error, errorType } and unwrapping one field\n // would throw the diagnosis away.\n public componentSql(\n reportId: number,\n componentId: number,\n config: RequestConfig = {},\n ): Observable<ReportComponentSql> {\n return this._api.get(\n this._path(`${reportId}/components/${componentId}/sql`),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // The component SQL's filterable output columns — drives the column picker\n // in the filter UI so a column name is never typed by hand.\n public componentColumns(reportId: number, componentId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`${reportId}/components/${componentId}/columns`),\n {},\n {\n key: 'columns',\n ...config,\n },\n );\n }\n\n // Make one column filterable. `level` (component | report) places a new\n // group; `groupId` instead links into an existing group. A select filter's\n // options are derived from the component's own query.\n public addFilter(\n reportId: number,\n componentId: number,\n filter: { filterColumn: string; type?: string; label?: string; level?: string; groupId?: number },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.post(\n this._path(`${reportId}/components/${componentId}/filters`),\n filter,\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // Update a filter — any subset of { label, enabled }.\n public updateFilter(\n reportId: number,\n filterId: number,\n changes: { label?: string; enabled?: boolean },\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/filters/${filterId}`),\n changes,\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // Remove a filter (its group goes too when nothing else uses it).\n public deleteFilter(reportId: number, filterId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.delete(\n this._path(`${reportId}/filters/${filterId}`),\n {},\n {\n key: 'filter',\n ...config,\n },\n );\n }\n\n // The global AI knowledge document (operator-authored agent instructions)\n // and its full version history: { instructions, versions }.\n public instructions(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('instructions'),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Save a new version of the document (append-only; an unchanged save is a\n // no-op server-side). Resolves to the same { instructions, versions } shape.\n public saveInstructions(content: string, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path('instructions'),\n { content },\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Make an earlier version of the document current (no new row is created).\n public restoreInstruction(instructionId: number, config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path(`instructions/${instructionId}/restore`),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Run a semantic-database build, streamed: emits an event per NDJSON frame\n // ({ kind: 'log', line, percent } feed lines and { kind: 'section' } phase\n // markers) and completes when the build ends. Feed the lines into FsProcess.\n public semanticBuild(config: RequestConfig = {}): Observable<any> {\n return this._api.stream(\n 'POST',\n this._path('semantic/build'),\n { stream: true },\n config,\n );\n }\n\n // Latest build status + entity scoreboard: { build, detail }.\n public semanticBuildStatus(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('semantic/build'),\n {},\n {\n key: null,\n ...config,\n },\n );\n }\n\n // Stop the running build (the current semantic database stays in place).\n public semanticBuildStop(config: RequestConfig = {}): Observable<T> {\n return this._api.post(\n this._path('semantic/build/stop'),\n {},\n {\n key: 'build',\n ...config,\n },\n );\n }\n\n // One entity's cached AI-classified code functions — loaded on expand, one\n // entity at a time, because the full set across all entities is far too big\n // to ship inside the scoreboard call.\n public semanticEntityFunctions(entity: string, config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path(`semantic/entities/${entity}/functions`),\n {},\n {\n key: 'entityFunctions',\n ...config,\n },\n );\n }\n\n // The report module's General settings (semantic-build concurrency + its bounds).\n public settings(config: RequestConfig = {}): Observable<T> {\n return this._api.get(\n this._path('settings'),\n {},\n {\n key: 'settings',\n ...config,\n },\n );\n }\n\n // The locales and currencies a report can be written in, for the report\n // settings' Locale and Currency selects: the default locale, each offered\n // locale with the currency a report in it uses when it names none, and every\n // currency code. Only a server that sends effectiveLocale has this route.\n public locales(config: RequestConfig = {}): Observable<ReportLocales> {\n return this._api.get(\n this._path('locales'),\n {},\n {\n key: 'locales',\n ...config,\n },\n );\n }\n\n // Save the General settings; resolves to the same { settings } shape.\n public saveSettings(settings: { semanticBuildConcurrency: number }, config: RequestConfig = {}): Observable<T> {\n return this._api.put(\n this._path('settings'),\n settings,\n {\n key: 'settings',\n ...config,\n },\n );\n }\n\n // Update a filter group — its exposure level ('component' | 'report' | 'both'),\n // its name (an identifier, unique in the report; the server refuses one that\n // breaks the rule, with a message naming the problem), its label (never\n // changes the name) and/or its default value (the value seeding the report\n // bar on open). Send `default: null` (or an empty default) to clear it. Only\n // the keys provided are changed, in the order name, label, level, default,\n // so a refused name leaves the rest unwritten.\n public updateFilterGroup(\n reportId: number,\n groupId: number,\n changes: ReportFilterGroupChanges,\n config: RequestConfig = {},\n ): Observable<T> {\n return this._api.put(\n this._path(`${reportId}/filtergroups/${groupId}`),\n changes,\n {\n key: 'filterGroup',\n ...config,\n },\n );\n }\n\n // A select filter's options narrowed by the other entries of its tile\n // (ReportFilterOptionsRequest), with the picks it names labeled. Only for\n // a report whose server lists cascadingOptions; any other reads the full\n // list through filterOptions().\n public filterOptionsNarrowed(\n reportId: number,\n filterId: number,\n body: ReportFilterOptionsRequest,\n config: RequestConfig = {},\n ): Observable<ReportFilterOptions> {\n return this._api.post(\n this._path(`${reportId}/filters/${filterId}/options`),\n body,\n {\n key: 'options',\n ...config,\n },\n );\n }\n\n // The report's saved filters, in their order. Shared by everyone who may\n // open the report.\n public savedFilters(reportId: number, config: RequestConfig = {}): Observable<ReportSavedFilter[]> {\n return this._api.get(\n this._path(`${reportId}/savedfilters`),\n {},\n {\n key: 'savedFilters',\n ...config,\n },\n );\n }\n\n // A new saved filter: its name and the report-wide filter values it holds.\n public createSavedFilter(\n reportId: number,\n savedFilter: Required<ReportSavedFilterChanges>,\n config: RequestConfig = {},\n ): Observable<ReportSavedFilter> {\n return this._api.post(\n this._path(`${reportId}/savedfilters`),\n savedFilter,\n {\n key: 'savedFilter',\n ...config,\n },\n );\n }\n\n // Renames a saved filter or replaces its values; only the keys given change.\n public updateSavedFilter(\n reportId: number,\n reportSavedFilterId: number,\n changes: ReportSavedFilterChanges,\n config: RequestConfig = {},\n ): Observable<ReportSavedFilter> {\n return this._api.put(\n this._path(`${reportId}/savedfilters/${reportSavedFilterId}`),\n changes,\n {\n key: 'savedFilter',\n ...config,\n },\n );\n }\n\n public deleteSavedFilter(\n reportId: number,\n reportSavedFilterId: number,\n config: RequestConfig = {},\n ): Observable<ReportSavedFilter> {\n return this._api.delete(\n this._path(`${reportId}/savedfilters/${reportSavedFilterId}`),\n {},\n {\n key: 'savedFilter',\n ...config,\n },\n );\n }\n\n // Persist the saved filters' order after a drag: every id, in its new\n // order. Resolves to the list in that order.\n public saveSavedFilterPositions(\n reportId: number,\n reportSavedFilterIds: number[],\n config: RequestConfig = {},\n ): Observable<ReportSavedFilter[]> {\n return this._api.put(\n this._path(`${reportId}/savedfilters/positions`),\n { reportSavedFilterIds },\n {\n key: 'savedFilters',\n ...config,\n },\n );\n }\n}\n","import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog';\n\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsMarkdownRendererComponent } from '@firestitch/markdown-editor';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { switchMap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportInstruction, ReportInstructions } from '../../interfaces/report.interface';\n\n\nexport interface InstructionHistoryDialogData {\n versions: ReportInstruction[];\n}\n\n\n// The AI Knowledge document's version history (append-only), each version\n// previewed and restorable — opened from the Report Settings footer's View\n// History button. Restores happen here (confirm, then flip the current flag —\n// no new version is created); the opener refreshes its instructions after this\n// dialog closes, so a restore made here reseeds the editor there.\n@Component({\n templateUrl: './instruction-history.component.html',\n styleUrls: ['./instruction-history.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n FsChipModule,\n FsDateModule,\n FsDialogModule,\n FsMarkdownRendererComponent,\n FsMessageModule,\n ],\n})\nexport class InstructionHistoryComponent {\n\n private readonly _data = inject<InstructionHistoryDialogData>(MAT_DIALOG_DATA);\n\n public readonly versions = signal<ReportInstruction[]>(this._data.versions);\n\n private readonly _reportData = inject(ReportData);\n private readonly _prompt = inject(FsPrompt);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n // Make an earlier version current — flips the flag, creates no new version.\n public restore(version: ReportInstruction): void {\n this._prompt.confirm({\n title: 'Restore version',\n template: 'Make this version the current AI knowledge? The newer versions stay in the history.',\n commitLabel: 'Restore',\n })\n .pipe(\n switchMap(() => this._reportData.restoreInstruction(version.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((instructions: ReportInstructions) => {\n this.versions.set(instructions.versions);\n this._message.success('Version restored');\n });\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n AI Knowledge History\n </fs-dialog-title>\n <mat-dialog-content>\n @if (versions().length) {\n <div class=\"versions\">\n @for (version of versions(); track version.id) {\n <div class=\"version\">\n <div class=\"version-header\">\n <fs-date\n [date]=\"version.createDate\"\n format=\"date-time\">\n </fs-date>\n @if (version.accountName) {\n <span class=\"author\">{{ version.accountName }}</span>\n }\n <span class=\"spacer\"></span>\n @if (version.current) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"'#2e7d32'\"\n color=\"#ffffff\">\n Current\n </fs-chip>\n } @else {\n <button\n type=\"button\"\n mat-stroked-button\n (click)=\"restore(version)\">\n Restore\n </button>\n }\n </div>\n <div class=\"version-preview\">\n <fs-markdown-renderer [markdown]=\"version.content\"></fs-markdown-renderer>\n </div>\n </div>\n }\n </div>\n } @else {\n <fs-message-info>\n No versions yet — every save of the AI Knowledge document lands here, and\n any version can be restored.\n </fs-message-info>\n }\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Close\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\n\nimport { FsFormModule } from '@firestitch/form';\nimport { FsMarkdownEditorComponent, FsMarkdownEditorConfig } from '@firestitch/markdown-editor';\n\n\n// The AI Knowledge tab: the operator-authored markdown document appended to the\n// report agent's system instructions on every chat turn — the lever for\n// terminology, business rules and special cases no code deploy can cover.\n//\n// A field-level child of the settings dialog form: the editor registers with\n// the parent <form fsForm> via the ControlContainer view provider, so the\n// dialog's Save button submits and validates this content. The draft itself\n// lives on the parent (bound through `content`), so switching tabs never loses\n// an edit.\n@Component({\n selector: 'fs-ai-report-global-settings-ai-knowledge',\n templateUrl: './ai-knowledge.component.html',\n styleUrls: ['./ai-knowledge.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsMarkdownEditorComponent,\n ],\n})\nexport class AiKnowledgeComponent {\n\n public readonly content = model<string>('');\n public readonly config = input.required<FsMarkdownEditorConfig>();\n}\n","<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n This document is given to the report AI on every chat message. Use it for\n terminology, business rules and special cases the AI can't work out from the\n data on its own — it takes effect immediately, no deploy needed.\n </p>\n <fs-markdown-editor\n [ngModel]=\"content()\"\n (ngModelChange)=\"content.set($event)\"\n [config]=\"config()\"\n name=\"content\">\n </fs-markdown-editor>\n</div>\n","import { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\n\nimport { MatFormField, MatHint, MatLabel } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\n\nimport { FsFormModule } from '@firestitch/form';\n\n\n// The General tab: report-module settings that aren't the AI knowledge document.\n// Currently just the semantic-build concurrency — how many summary calls the\n// build runs at once. A field-level child of the settings dialog form (its input\n// registers with the parent <form fsForm> via the ControlContainer view\n// provider), so the dialog's Save button submits and validates it. The value\n// itself is held on the shell (bound through `concurrency`), and the safe band\n// (`min`/`max`) comes from the backend so the field can't be set out of range.\n@Component({\n selector: 'fs-ai-report-global-settings-general',\n templateUrl: './general.component.html',\n styleUrls: ['./general.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n MatFormField,\n MatLabel,\n MatHint,\n MatInput,\n ],\n})\nexport class GeneralComponent {\n\n public readonly concurrency = model<number>(0);\n public readonly min = input.required<number>();\n public readonly max = input.required<number>();\n}\n","<div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>Semantic build concurrency</mat-label>\n <input\n matInput\n type=\"number\"\n [ngModel]=\"concurrency()\"\n (ngModelChange)=\"concurrency.set($event)\"\n name=\"semanticBuildConcurrency\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"min()\"\n [fsFormMax]=\"max()\">\n <mat-hint>\n How many AI calls the semantic-database build runs at once ({{ min() }}–{{ max() }}).\n Higher is faster but more likely to hit the AI provider's rate limit. Default is 8.\n </mat-hint>\n </mat-form-field>\n</div>\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent } from '@angular/material/dialog';\n\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\n\nimport { ReportData } from '../../data/report.data';\nimport {\n SemanticEntityFunction,\n SemanticEntityFunctions,\n SemanticFunctionSource,\n} from '../../interfaces/report.interface';\n\n\nexport interface EntityFunctionsDialogData {\n entityKey: string;\n source: SemanticFunctionSource;\n}\n\n\n// One group of a unit's AI-classified cached code functions — an entity's model\n// or handler class, or the single group of a standalone code class. Fetched on\n// open from the shared per-key endpoint (one payload carries every group, each\n// row tagged with its source) and filtered client-side.\n@Component({\n templateUrl: './entity-functions.component.html',\n styleUrls: ['./entity-functions.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n FsChipModule,\n FsDateModule,\n FsDialogModule,\n FsSkeletonModule,\n ],\n})\nexport class EntityFunctionsComponent {\n\n // One color per AI classification kind, so a function's nature reads at a glance.\n private static readonly KIND_COLORS: Record<string, string> = {\n 'calculation': '#1565c0',\n 'business-rule': '#6a1b9a',\n 'query': '#00695c',\n 'mutation': '#e65100',\n 'accessor': '#546e7a',\n 'other': '#757575',\n };\n\n // Interesting logic first: derived values and rules, then data access, then the rest.\n private static readonly KIND_ORDER = ['calculation', 'business-rule', 'query', 'mutation', 'accessor', 'other'];\n\n // The dialog title per group. A standalone class has no model/handler split,\n // so its one group is just the code the build read.\n private static readonly SOURCE_LABELS: Record<SemanticFunctionSource, string> = {\n model: 'Model functions',\n handler: 'Handler functions',\n class: 'Code functions',\n };\n\n private readonly _data = inject<EntityFunctionsDialogData>(MAT_DIALOG_DATA);\n\n public readonly entityKey = this._data.entityKey;\n public readonly sourceLabel = EntityFunctionsComponent.SOURCE_LABELS[this._data.source];\n\n // null until loaded — gates the list behind the skeleton.\n public readonly entityFunctions = signal<SemanticEntityFunctions | null>(null);\n\n // The class this group's functions were discovered from. A standalone code\n // class has no handler, so its group reads the model slot like 'model' does.\n public readonly discoveredClass = computed<string | null>(() => {\n const loaded = this.entityFunctions();\n\n return this._data.source === 'handler' ? loaded?.handlerClass : loaded?.modelClass;\n });\n\n // This group's functions, ordered by kind priority then method name.\n public readonly functions = computed<SemanticEntityFunction[]>(() =>\n this._sortFunctions(\n (this.entityFunctions()?.functions ?? [])\n .filter((fn) => fn.source === this._data.source),\n ),\n );\n\n constructor() {\n inject(ReportData).semanticEntityFunctions(this._data.entityKey)\n .pipe(takeUntilDestroyed())\n .subscribe((entityFunctions: SemanticEntityFunctions) => {\n this.entityFunctions.set(entityFunctions);\n });\n }\n\n public kindColor(kind: string): string {\n return EntityFunctionsComponent.KIND_COLORS[kind] ?? EntityFunctionsComponent.KIND_COLORS.other;\n }\n\n private _sortFunctions(functions: SemanticEntityFunction[]): SemanticEntityFunction[] {\n return [...functions]\n .sort((a, b) => {\n const kindDiff = this._kindRank(a.kind) - this._kindRank(b.kind);\n\n return kindDiff !== 0 ? kindDiff : a.method.localeCompare(b.method);\n });\n }\n\n private _kindRank(kind: string): number {\n const rank = EntityFunctionsComponent.KIND_ORDER.indexOf(kind);\n\n return rank === -1 ? EntityFunctionsComponent.KIND_ORDER.length : rank;\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n {{ entityKey }} — {{ sourceLabel }}\n </fs-dialog-title>\n <mat-dialog-content>\n <div *fsSkeleton=\"entityFunctions()\">\n @if (entityFunctions(); as fns) {\n @if (functions().length) {\n @if (fns.generatedAt) {\n <div class=\"hint functions-generated\">\n Discovered from {{ discoveredClass() }} ·\n <fs-date\n [date]=\"fns.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n }\n <div class=\"functions-list\">\n @for (fn of functions(); track fn.class + '::' + fn.method) {\n <div class=\"function-row\">\n <div class=\"function-head\">\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"kindColor(fn.kind)\"\n color=\"#ffffff\">\n {{ fn.kind }}\n </fs-chip>\n <code class=\"function-method\">{{ fn.method }}</code>\n </div>\n <div class=\"function-summary\">{{ fn.summary }}</div>\n @if (fn.produces) {\n <div class=\"function-produces hint\">Produces: {{ fn.produces }}</div>\n }\n </div>\n }\n </div>\n } @else {\n <div class=\"hint\">\n No functions cached for this entity yet — run a build to discover its code.\n </div>\n }\n }\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Close\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatExpansionModule } from '@angular/material/expansion';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { StreamEventType } from '@firestitch/api';\nimport { FsChipModule } from '@firestitch/chip';\nimport { FsDateModule } from '@firestitch/date';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsProcess } from '@firestitch/process';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\n\nimport { EMPTY, Observable } from 'rxjs';\nimport { catchError, filter, map, switchMap, take, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../../../data/report.data';\nimport {\n SemanticBuildClass,\n SemanticBuildEntity,\n SemanticBuildStatus,\n SemanticBuildTable,\n SemanticFunctionSource,\n} from '../../../../interfaces/report.interface';\nimport { EntityFunctionsComponent } from '../../../entity-functions/entity-functions.component';\n\n\n// One row of the scoreboard. The build caches two kinds of unit and the report\n// AI reads code from both, so they belong in ONE list: an entity (a table plus\n// its model and handler) and a standalone code class (domain logic with no\n// table — a summary model, a calculation service). A class row simply has no\n// table, columns or relationships to show.\ninterface SemanticUnitView {\n key: string;\n name: string;\n hasTable: boolean;\n entity: SemanticBuildEntity | null;\n model: string | null;\n functionCount: number;\n}\n\n\n// The Semantic Database tab: the scoreboard of everything the report AI was\n// built from. Shows the last build's status, runs (or stops) a build — streamed\n// into the FsProcess dock so it survives the dialog closing — and drills into\n// every unit to reveal its shape, inlined enum values, computed fields and its\n// cached function counts, whose links open the functions dialog (the full\n// function set is far too big to ship with the scoreboard).\n//\n// It also reports the other half of the picture: the tables the AI CANNOT see —\n// excluded ones (no model) and junctions that bridged nothing. Those are\n// invisible by omission otherwise: nothing errors, the capability just isn't\n// there, and the first anyone learns is a wrong answer or a refusal.\n@Component({\n selector: 'fs-ai-report-global-settings-semantic-database',\n templateUrl: './semantic-database.component.html',\n styleUrls: ['./semantic-database.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatExpansionModule,\n MatTooltipModule,\n FsChipModule,\n FsDateModule,\n FsMessageModule,\n FsSkeletonModule,\n ],\n})\nexport class SemanticDatabaseComponent {\n\n // The build-in-flight states of the ff_processes row (queued/running/stopping).\n private static readonly ACTIVE_STATES = ['Q', 'R', 'X'];\n\n private static readonly STATE_LABELS: Record<string, string> = {\n Q: 'Queued',\n R: 'Running',\n X: 'Stopping',\n C: 'Completed',\n K: 'Stopped',\n F: 'Failed',\n };\n\n // The streamed frames that carry a line for the feed: progress, and the final\n // frame the backend sends when a run ends badly. Without the error kind the\n // feed stops on the last progress line and never says what went wrong.\n private static readonly LOG_KINDS = ['log', 'error'];\n\n // A row that is still owed content says so; a built one says nothing. On a\n // finished build every stage is done on every row, so chipping them all was\n // noise that buried the one row that mattered.\n private static readonly PENDING_COLOR = '#b26500';\n\n // Class-name suffix stripped for display: `BudgetSummaryModel` reads as\n // `BudgetSummary`. Only `Model` — stripping `Handler` too would collide\n // `WorkOrderOneTimeHandler` with `WorkOrderOneTimeModel`, which are two\n // separate units.\n private static readonly NAME_SUFFIX = 'Model';\n\n // null until loaded — gates the tab behind the skeleton.\n public readonly status = signal<SemanticBuildStatus | null>(null);\n\n // The status request failed. Settles the skeleton and shows why; the Build\n // action never depends on the status, so a build can still be started.\n public readonly statusError = signal(false);\n\n // Free-text filter over the unit list — at a few hundred rows the accordion\n // is only usable if you can narrow it.\n public readonly filter = signal<string>('');\n\n // True while a build started from this tab is streaming into the dock.\n public readonly building = signal(false);\n\n public readonly buildActive = computed<boolean>(() =>\n this.building()\n || SemanticDatabaseComponent.ACTIVE_STATES.includes(this.status()?.build?.state),\n );\n\n // A semantic database has been published before, so a build replaces it.\n // False while the status is unloaded or failed to load.\n public readonly rebuild = computed<boolean>(() => !!this.status()?.detail?.generatedAt);\n\n public readonly buildStateLabel = computed<string>(() =>\n SemanticDatabaseComponent.STATE_LABELS[this.status()?.build?.state] ?? '',\n );\n\n // Whether the published semantic database came from a build that finished.\n //\n // A failed or stopped build still leaves a dated, fully counted artifact\n // behind, because the structural half publishes BEFORE the AI function pass\n // and it is the AI pass that fails. So \"Last built\" and Coverage both filled\n // in and read as a clean success, and the only dissenting word on the whole\n // panel was one line of \"Last build run\" text (RE-T1302).\n //\n // Reads as complete while the status is still loading, so the warning cannot\n // flash on open before there is anything to warn about.\n public readonly buildComplete = computed<boolean>(() => this.status()?.detail?.complete !== false);\n\n // Entities the build never reached — those still owed the AI function pass.\n // The number the incomplete warning quotes, and the same rows the scoreboard\n // below already chips one at a time.\n public readonly incompleteEntityCount = computed<number>(() =>\n (this.status()?.detail?.entities ?? [])\n .filter((entity) => entity.stages.functions !== 'done')\n .length,\n );\n\n // An artifact built before the catalog existed carries no tables. Everything\n // catalog-driven stays hidden rather than claiming \"0 excluded\", which would\n // be a lie — a rebuild fills it in.\n public readonly hasCatalog = computed<boolean>(() => !!this.status()?.detail?.tables?.length);\n\n // Tables with no model: the report AI can't see them at all. Add a model to\n // promote one to an entity.\n public readonly excludedTables = computed<SemanticBuildTable[]>(() =>\n this._tables().filter((table) => table.classification === 'excluded'),\n );\n\n // Link tables that bridged nothing — a composite primary key made them a\n // junction, but they were folded into no relationship, so neither they nor\n // what they link are reachable.\n public readonly unlinkedJunctions = computed<SemanticBuildTable[]>(() =>\n this._tables().filter((table) => table.classification === 'junction' && !!table.reason),\n );\n\n // Everything the build cached, entities and standalone code classes together,\n // in one list ordered by the name a reader recognizes. Two arrays on the wire\n // because they are genuinely different shapes; one list on screen because\n // \"what did the build read?\" is a single question.\n public readonly units = computed<SemanticUnitView[]>(() => {\n const detail = this.status()?.detail;\n if (!detail) {\n return [];\n }\n\n const entities = (detail.entities ?? []).map((entity) => ({\n key: entity.key,\n name: this._displayName(entity.model, entity.key),\n hasTable: true,\n entity,\n model: entity.model,\n functionCount: entity.functionCount,\n }));\n\n const classes = (detail.classes ?? []).map((unit: SemanticBuildClass) => ({\n key: unit.key,\n name: this._displayName(unit.model, unit.key),\n hasTable: false,\n entity: null,\n model: unit.model,\n functionCount: unit.functionCount,\n }));\n\n return [...entities, ...classes]\n .sort((a, b) => a.name.localeCompare(b.name));\n });\n\n // The filter matches the display name, the class and the entity key, so\n // hunting by any of the three works.\n public readonly filteredUnits = computed<SemanticUnitView[]>(() => {\n const filter = this.filter().trim().toLowerCase();\n if (!filter) {\n return this.units();\n }\n\n return this.units().filter((unit) =>\n `${unit.name} ${unit.model ?? ''} ${unit.key}`.toLowerCase().includes(filter));\n });\n\n // The Coverage line. Assembled here because the catalog parts drop out\n // entirely on a pre-catalog artifact, which reads badly as template branches.\n public readonly coverage = computed<string>(() => {\n const detail = this.status()?.detail;\n if (!detail) {\n return '';\n }\n\n const parts = [`${detail.entityCount} entities`, `${detail.classCount} code classes`];\n\n if (this.hasCatalog()) {\n parts.push(detail.unlinkedJunctionCount\n ? `${detail.junctionCount} junctions (${detail.unlinkedJunctionCount} not linked)`\n : `${detail.junctionCount} junctions`);\n }\n\n parts.push(`${detail.functionCount} code functions`);\n\n if (this.hasCatalog()) {\n parts.push(`${detail.excludedCount} tables excluded`);\n }\n\n return parts.join(' · ');\n });\n\n // The table catalog, or [] when the status hasn't loaded or the artifact\n // predates it.\n private readonly _tables = computed<SemanticBuildTable[]>(() => this.status()?.detail?.tables ?? []);\n\n // Guards the outcome message to fire exactly once per run — whether the stream\n // completes (build finished, possibly failed) or errors outright.\n private _buildFinalized = false;\n\n private readonly _dialog = inject(MatDialog);\n private readonly _reportData = inject(ReportData);\n private readonly _process = inject(FsProcess);\n private readonly _prompt = inject(FsPrompt);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n constructor() {\n this._init();\n }\n\n // Confirm before kicking off a build — a rebuild replaces the current\n // semantic database, so it should never fire on a stray click.\n public build(): void {\n const rebuild = this.rebuild();\n\n this._prompt.confirm({\n title: rebuild ? 'Rebuild semantic database' : 'Build semantic database',\n template: rebuild\n ? 'Rebuild the semantic database? It runs in the background and replaces the current one when it finishes.'\n : 'Build the semantic database? It runs in the background.',\n commitLabel: rebuild ? 'Rebuild' : 'Build',\n })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._runBuild());\n }\n\n public stopBuild(): void {\n this._prompt.confirm({\n title: 'Stop build',\n template: 'Stop the running build? The current semantic database stays in place until a build finishes.',\n commitLabel: 'Stop',\n })\n .pipe(\n switchMap(() => this._reportData.semanticBuildStop()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this.building.set(false);\n this._message.success('Stopping the build…');\n this._refreshStatus();\n });\n }\n\n // Run the semantic-database build. The live feed streams into the FsProcess\n // dock (bottom-right), whose subscription survives this dialog closing — so\n // dismissing the dialog never interrupts a running build.\n private _runBuild(): void {\n this.building.set(true);\n this._buildFinalized = false;\n\n const target$ = this._reportData.semanticBuild()\n .pipe(\n // A hard stream/transport failure (the build couldn't even start)\n // finalizes here — completed$ won't fire in that case.\n tap({ error: (error) => this._finalizeBuild(error) }),\n filter((event) =>\n event?.type === StreamEventType.Data\n && SemanticDatabaseComponent.LOG_KINDS.includes(event.data?.kind)\n && typeof event.data.line === 'string'),\n map((event) => event.data.line as string),\n );\n\n this._process\n .run('Semantic database build', target$)\n .completed$\n .pipe(\n take(1),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => this._finalizeBuild(null));\n }\n\n /**\n * Wrap up one build run exactly once. On a hard stream error, surface the\n * actual server-side reason pulled off the broken stream — the generic\n * \"could not run\" line only when the failure carried no server text at all;\n * otherwise refresh the status and announce how the build actually ended. A\n * failed build always names its reason on the row (the backend records one for\n * every way a run can die, fatals included), and that reason must surface\n * instead of the run silently doing nothing.\n */\n private _finalizeBuild(streamError: unknown): void {\n if (this._buildFinalized) {\n return;\n }\n this._buildFinalized = true;\n\n this.building.set(false);\n\n if (streamError) {\n const detail = this._streamErrorDetail(streamError);\n\n this._message.error(detail\n ? `The semantic database build failed — ${detail}`\n : 'The semantic database build could not run — the connection to the server was lost.');\n this._refreshStatus();\n\n return;\n }\n\n this._loadStatus()\n .subscribe((status: SemanticBuildStatus) => this._announceOutcome(status));\n }\n\n /**\n * The real reason a broken build stream broke, from what the server actually\n * sent. A structured error frame arrives as {message} on the error body; a\n * mid-stream crash dumps raw text into the stream (the stream interceptor\n * hands it back as statusText), where the frames are JSON lines and the\n * first non-JSON lines are the error and its location. '' when the failure\n * carried no server text at all (transport down / server unreachable).\n */\n private _streamErrorDetail(streamError: unknown): string {\n const error = streamError as { error?: { message?: string }; statusText?: string };\n\n if (error?.error?.message) {\n return error.error.message;\n }\n\n const statusText = error?.statusText;\n if (!statusText || statusText === 'Unknown Error') {\n return '';\n }\n\n const lines = statusText.split('\\n')\n .map((line) => line.trim())\n .filter((line) => {\n if (!line) {\n return false;\n }\n\n try {\n JSON.parse(line);\n\n return false;\n } catch {\n return true;\n }\n });\n\n return lines.slice(0, 2).join(' — ').substring(0, 300);\n }\n\n /**\n * Tell the operator how the build ended: a failed/stopped build surfaces its\n * reason (so an AI connection problem is never silent), a completed one\n * confirms success.\n */\n private _announceOutcome(status: SemanticBuildStatus): void {\n const build = status?.build;\n if (build?.state === 'F' || build?.state === 'K') {\n this._message.error(build.message || 'The semantic database build did not finish.');\n } else if (build?.state === 'C') {\n this._message.success('Semantic database build complete.');\n }\n }\n\n public pendingColor(): string {\n return SemanticDatabaseComponent.PENDING_COLOR;\n }\n\n /**\n * The build stages this row is still owed, or [] when it is fully built. A\n * stopped or interrupted build is the only way to get a non-empty list.\n */\n public pendingStages(unit: SemanticUnitView): string[] {\n const stages = unit.entity?.stages;\n\n return stages\n ? Object.keys(stages).filter((stage) => stages[stage] !== 'done')\n : [];\n }\n\n public setFilter(value: string): void {\n this.filter.set(value);\n }\n\n /**\n * Open the child dialog listing one group of a unit's cached functions — an\n * entity's model or handler class, or a standalone class's code. The dialog\n * fetches fresh on open, so the tab never holds function payloads.\n */\n public openFunctions(unit: SemanticUnitView, source: SemanticFunctionSource): void {\n this._dialog.open(EntityFunctionsComponent, {\n width: '700px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n autoFocus: false,\n data: { entityKey: unit.key, source },\n });\n }\n\n private _init(): void {\n this._refreshStatus();\n }\n\n /**\n * What a reader recognizes the unit by: its class's short name, minus the\n * `Model` suffix that every model carries and none of them are distinguished\n * by. Falls back to the cache key for a unit whose class could not be\n * resolved, so a row never renders nameless.\n */\n private _displayName(model: string | null, key: string): string {\n if (!model) {\n return key;\n }\n\n const shortName = model.split('\\\\').pop();\n\n return shortName.length > SemanticDatabaseComponent.NAME_SUFFIX.length\n && shortName.endsWith(SemanticDatabaseComponent.NAME_SUFFIX)\n ? shortName.slice(0, -SemanticDatabaseComponent.NAME_SUFFIX.length)\n : shortName;\n }\n\n private _refreshStatus(): void {\n this._loadStatus()\n .subscribe();\n }\n\n // Fetch the status into the tab. A failure flags statusError and completes\n // quietly, so the tab settles and callers never see the error.\n private _loadStatus(): Observable<SemanticBuildStatus> {\n return this._reportData.semanticBuildStatus()\n .pipe(\n tap((status: SemanticBuildStatus) => {\n this.statusError.set(false);\n this.status.set(status);\n }),\n catchError(() => {\n this.statusError.set(true);\n\n return EMPTY;\n }),\n takeUntilDestroyed(this._destroyRef),\n );\n }\n}\n","<div class=\"fs-column tab-body\">\n <p class=\"hint\">\n The semantic database is what the report AI uses to understand your data —\n tables, relationships and the calculations in code. Rebuild it after\n significant application updates. The build runs in the background; progress\n appears in the dock at the bottom right and this dialog can be closed while\n it runs.\n </p>\n\n <!-- A failed status load settles the skeleton too, so the tab says what\n happened instead of loading forever. -->\n @if (statusError()) {\n <fs-message-warning>\n The build status could not be loaded, so the last build and its coverage\n can't be shown. You can still run a build.\n </fs-message-warning>\n }\n\n <div *fsSkeleton=\"status() || statusError()\">\n @if (status(); as buildStatus) {\n <div class=\"build-status\">\n @if (buildStatus.detail.generatedAt) {\n <div class=\"stat\">\n <span class=\"label\">Last built</span>\n <fs-date\n [date]=\"buildStatus.detail.generatedAt\"\n format=\"date-time\">\n </fs-date>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Coverage</span>\n <span>{{ coverage() }}</span>\n </div>\n } @else {\n <fs-message-warning>\n The semantic database has not been built yet — the report AI can't\n answer data questions until it is. Run the first build.\n </fs-message-warning>\n }\n @if (buildStatus.build) {\n <div class=\"stat\">\n <span class=\"label\">Last build run</span>\n <span>\n {{ buildStateLabel() }}\n @if (buildStatus.build.message) {\n — {{ buildStatus.build.message }}\n }\n </span>\n </div>\n }\n\n <!-- Everything above is true about what was published, and on its own it\n reads as a finished build: the structural half publishes BEFORE the\n AI function pass, so a run that died in that pass still stamps a\n date and still fills in the whole coverage line. This is the only\n line that says the build never got to the end. -->\n @if (buildStatus.detail.generatedAt && !buildComplete()) {\n <fs-message-warning>\n The last build did not finish, so this semantic database is incomplete —\n {{ incompleteEntityCount() }} of {{ buildStatus.detail.entityCount }}\n entities have no code-function knowledge. The report AI answers from what\n is here and cannot see the rest. Rebuild to complete it.\n </fs-message-warning>\n }\n </div>\n\n <!-- Everything the build read, in one list: entities (a table + a model +\n a handler) and standalone code classes (domain logic with no table).\n The AI reads code from both, so splitting them into two sections\n would hide half of what was built. Each row drills into its shape,\n enum values, computed fields and cached function counts — the counts\n link into the functions dialog. -->\n @if (units().length) {\n <h2>Included ({{ units().length }})</h2>\n <div class=\"subheading\">\n Everything the report AI was built from. Entities can be queried;\n code classes are logic it reads and translates into SQL.\n </div>\n\n <input\n class=\"unit-filter\"\n type=\"search\"\n placeholder=\"Filter by name, class or key…\"\n [value]=\"filter()\"\n (input)=\"setFilter($any($event.target).value)\">\n\n <mat-accordion class=\"entities\">\n @for (unit of filteredUnits(); track unit.key) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>{{ unit.name }}</mat-panel-title>\n <mat-panel-description>\n <div class=\"stage-chips\">\n @if (!unit.hasTable) {\n <fs-chip size=\"tiny\" matTooltip=\"Domain logic with no table — read, never queried\">\n code\n </fs-chip>\n }\n <!-- Silence means built. A chip here means an interrupted\n build left this row owing content. -->\n @for (stage of pendingStages(unit); track stage) {\n <fs-chip\n size=\"tiny\"\n [backgroundColor]=\"pendingColor()\"\n color=\"#ffffff\"\n matTooltip=\"Needs building\">\n {{ stage }}\n </fs-chip>\n }\n </div>\n </mat-panel-description>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"entity-detail\">\n @if (unit.model) {\n <div class=\"stat\">\n <span class=\"label\">Class</span>\n <span>{{ unit.model }}</span>\n </div>\n }\n @if (unit.entity; as entity) {\n <div class=\"stat\">\n <span class=\"label\">Table</span>\n <span>{{ entity.table }}</span>\n </div>\n <!-- The handle the report AI addresses this entity by in\n describe_entity / compile_query. -->\n <div class=\"stat\">\n <span class=\"label\">Entity key</span>\n <span>{{ entity.key }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Columns</span>\n <span>{{ entity.columns }}</span>\n </div>\n <div class=\"stat\">\n <span class=\"label\">Relationships</span>\n <span>{{ entity.relationships }}</span>\n </div>\n @if (entity.enums.length) {\n <div class=\"stat\">\n <span class=\"label\">Enumeration values</span>\n <div class=\"pair-list\">\n @for (enumColumn of entity.enums; track enumColumn.column) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ enumColumn.column }}</span>\n <span>{{ enumColumn.values.join(', ') }}</span>\n </div>\n }\n </div>\n </div>\n }\n @if (entity.computedFields.length) {\n <div class=\"stat\">\n <span class=\"label\">Computed fields</span>\n <span>{{ entity.computedFields.join(', ') }}</span>\n </div>\n }\n <div class=\"stat\">\n <span class=\"label\">Model functions</span>\n @if (entity.modelFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'model')\">\n {{ entity.modelFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n <div class=\"stat\">\n <span class=\"label\">Handler functions</span>\n @if (entity.handlerFunctionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'handler')\">\n {{ entity.handlerFunctionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n } @else {\n <div class=\"stat\">\n <span class=\"label\">Code functions</span>\n @if (unit.functionCount) {\n <a\n class=\"count-link\"\n (click)=\"openFunctions(unit, 'class')\">\n {{ unit.functionCount }}\n </a>\n } @else {\n <span>0</span>\n }\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n\n @if (!filteredUnits().length) {\n <div class=\"subheading\">Nothing matches “{{ filter() }}”.</div>\n }\n }\n\n <!-- The other half of the picture: tables the AI can't reach. Excluded\n ones have no model; unlinked junctions have a composite primary key\n but were folded into no relationship, so nothing can navigate to\n them. Both are invisible by omission — no error, just a capability\n that silently isn't there. Collapsed by default: the excluded list is\n long and mostly framework plumbing. -->\n @if (hasCatalog()) {\n <h2>Not in the semantic database</h2>\n <div class=\"subheading\">\n Tables the report AI can't see. Give one a model to promote it to an\n entity, then rebuild.\n </div>\n <mat-accordion class=\"catalog\">\n @if (excludedTables().length) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n Tables excluded ({{ excludedTables().length }})\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <!-- Deferred: the body only exists once expanded. -->\n <ng-template matExpansionPanelContent>\n <div class=\"pair-list\">\n @for (table of excludedTables(); track table.table) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ table.table }}</span>\n <span>{{ table.reason }}</span>\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n @if (unlinkedJunctions().length) {\n <mat-expansion-panel>\n <mat-expansion-panel-header>\n <mat-panel-title>\n Junctions not linked ({{ unlinkedJunctions().length }})\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <ng-template matExpansionPanelContent>\n <p class=\"small\">\n Link tables the build couldn't fold into a relationship — so\n neither they nor what they link can be reported on.\n </p>\n <div class=\"pair-list\">\n @for (table of unlinkedJunctions(); track table.table) {\n <div class=\"pair-row\">\n <span class=\"pair-name\">{{ table.table }}</span>\n <span>{{ table.reason }}</span>\n </div>\n }\n </div>\n </ng-template>\n </mat-expansion-panel>\n }\n </mat-accordion>\n }\n }\n </div>\n</div>\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, signal, viewChild } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { FormsModule } from '@angular/forms';\n\nimport { MatButton } from '@angular/material/button';\nimport { MatDialog, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef } from '@angular/material/dialog';\nimport { MatTabsModule } from '@angular/material/tabs';\n\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsMarkdownEditorConfig } from '@firestitch/markdown-editor';\nimport { FsMessage } from '@firestitch/message';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportInstructions, ReportSettings } from '../../interfaces/report.interface';\nimport { InstructionHistoryComponent } from '../instruction-history/instruction-history.component';\nimport { AiKnowledgeComponent } from './components/ai-knowledge/ai-knowledge.component';\nimport { GeneralComponent } from './components/general/general.component';\nimport { SemanticDatabaseComponent } from './components/semantic-database/semantic-database.component';\n\n\n// Matches the backend cap (ReportsView::INSTRUCTIONS_MAX_LENGTH) — the document\n// rides along on every agent turn, so it is a prompt-budget guard.\nconst MAX_LENGTH = 50000;\n\n// Seeded into the editor (client-side, unsaved) when no version exists yet, so\n// the operator sees the intended shape of the document.\nconst SCAFFOLD = [\n '# Glossary',\n '',\n '*Terms your team uses and what they mean in the data — e.g. \"active accounts\" are accounts with an order in the last 90 days.*',\n '',\n '# Business rules',\n '',\n '*Rules the AI should apply when building or explaining reports.*',\n '',\n '# Special cases',\n '',\n '*Known exceptions and data quirks the AI cannot infer on its own.*',\n '',\n].join('\\n');\n\n\n// Global report settings, opened from the reports listing's gear. A thin shell:\n// the dialog frame, the tab group, and a per-tab footer. Each tab is its own\n// component —\n// AI Knowledge — the operator-authored markdown document appended to the\n// report agent's system instructions on every chat turn. Its footer carries a\n// View History button opening the version-history dialog (restores happen\n// there; the shell refreshes on close).\n// Semantic Database — the build scoreboard the AI is built from, with a\n// self-contained Build action.\n// General — report-module settings (the semantic-build concurrency).\n// The shell owns the shared data (the instructions document, the settings for\n// General) plus the tab-aware save; everything else lives in the children.\n@Component({\n templateUrl: './global-settings.component.html',\n styleUrls: ['./global-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsDialogModule,\n FsFormModule,\n FsSkeletonModule,\n FsTabsModule,\n MatButton,\n MatDialogActions,\n MatDialogClose,\n MatDialogContent,\n MatTabsModule,\n AiKnowledgeComponent,\n GeneralComponent,\n SemanticDatabaseComponent,\n ],\n})\nexport class GlobalSettingsComponent {\n\n public selectedTab = 'knowledge';\n\n // The Semantic Database tab component, so the shared footer can drive its\n // Build/Rebuild/Stop action inline next to Close (the build state lives there).\n public readonly semanticDatabase = viewChild(SemanticDatabaseComponent);\n\n // The editor's draft, held on the shell so switching tabs never loses an edit\n // — seeded from the current version (or the scaffold).\n public readonly content = signal<string>('');\n\n public readonly editorConfig: FsMarkdownEditorConfig = {\n maxLength: MAX_LENGTH,\n placeholder: 'Terminology, business rules and special cases the report AI should know…',\n };\n\n // Both null until loaded — the form waits behind the skeleton until each is in.\n public readonly instructions = signal<ReportInstructions | null>(null);\n public readonly settings = signal<ReportSettings | null>(null);\n\n // The General tab's concurrency draft (bound to its field), seeded from settings.\n public readonly concurrency = signal<number>(0);\n\n // Gate the whole form on both loads, so every tab's fields are ready to render.\n public readonly loaded = computed<boolean>(() => !!this.instructions() && !!this.settings());\n\n private readonly _dialogRef = inject<MatDialogRef<GlobalSettingsComponent>>(MatDialogRef);\n private readonly _dialog = inject(MatDialog);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _destroyRef = inject(DestroyRef);\n\n constructor() {\n this._init();\n }\n\n // The footer Save is shared, so it saves whatever the current tab owns: the\n // General tab persists its settings (and stays open); AI Knowledge saves a new\n // document version and closes.\n public save = () => {\n if (this.selectedTab === 'general') {\n return this._reportData.saveSettings({ semanticBuildConcurrency: this.concurrency() })\n .pipe(\n tap((settings: ReportSettings) => {\n this._applySettings(settings);\n this._message.success('Settings saved');\n }),\n );\n }\n\n return this._reportData.saveInstructions(this.content())\n .pipe(\n tap((instructions: ReportInstructions) => {\n this._message.success('AI knowledge saved');\n this._dialogRef.close(instructions);\n }),\n );\n };\n\n // Open the version-history dialog. Restores happen inside it, so when it\n // closes (however it closes) re-fetch the document: a restore changed the\n // current version and must reseed the editor; otherwise just refresh the\n // version list without touching an unsaved draft.\n public openHistory(): void {\n const currentId = this.instructions()?.instructions?.id;\n\n this._dialog.open(InstructionHistoryComponent, {\n width: '800px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n autoFocus: false,\n data: { versions: this.instructions()?.versions ?? [] },\n })\n .afterClosed()\n .pipe(\n switchMap(() => this._reportData.instructions()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((instructions: ReportInstructions) => {\n if (instructions.instructions?.id !== currentId) {\n this._applyInstructions(instructions);\n } else {\n this.instructions.set(instructions);\n }\n });\n }\n\n private _init(): void {\n this._reportData.instructions()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((instructions: ReportInstructions) => this._applyInstructions(instructions));\n\n this._reportData.settings()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((settings: ReportSettings) => this._applySettings(settings));\n }\n\n private _applyInstructions(instructions: ReportInstructions): void {\n this.instructions.set(instructions);\n this.content.set(instructions.instructions?.content ?? SCAFFOLD);\n }\n\n private _applySettings(settings: ReportSettings): void {\n this.settings.set(settings);\n this.concurrency.set(settings.semanticBuildConcurrency);\n }\n}\n","<form\n *fsSkeletonForm=\"loaded()\"\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <fs-dialog-title>\n Report Settings\n </fs-dialog-title>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"AI Knowledge\"\n name=\"knowledge\">\n <fs-ai-report-global-settings-ai-knowledge\n [content]=\"content()\"\n (contentChange)=\"content.set($event)\"\n [config]=\"editorConfig\">\n </fs-ai-report-global-settings-ai-knowledge>\n </mat-tab>\n <mat-tab\n label=\"Semantic Database\"\n name=\"build\">\n <fs-ai-report-global-settings-semantic-database>\n </fs-ai-report-global-settings-semantic-database>\n </mat-tab>\n <mat-tab\n label=\"General\"\n name=\"general\">\n <fs-ai-report-global-settings-general\n [concurrency]=\"concurrency()\"\n (concurrencyChange)=\"concurrency.set($event)\"\n [min]=\"settings()!.semanticBuildConcurrencyMin\"\n [max]=\"settings()!.semanticBuildConcurrencyMax\">\n </fs-ai-report-global-settings-general>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- The footer follows the selected tab. AI Knowledge projects its own\n Save | View History | Cancel row (fs-form-dialog-actions renders\n projected content after Save/Cancel, so the default pair can't keep\n View History beside Save); General uses the default Save/Cancel; the\n Semantic Database tab is a read/run surface, so it gets a primary\n Close plus its Build/Rebuild/Stop action. -->\n <fs-form-dialog-actions [save]=\"selectedTab === 'general'\">\n @if (selectedTab === 'knowledge') {\n <button\n type=\"submit\"\n mat-button\n color=\"primary\">\n Save\n </button>\n <button\n type=\"button\"\n mat-button\n (click)=\"openHistory()\">\n View History\n </button>\n <button\n type=\"button\"\n mat-button\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n }\n @if (selectedTab === 'build') {\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n [mat-dialog-close]=\"undefined\">\n Close\n </button>\n }\n @if (selectedTab === 'build' && semanticDatabase(); as db) {\n @if (db.buildActive()) {\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"db.stopBuild()\">\n Stop Build\n </button>\n } @else {\n <!-- Never gated on the status load: a status response that fails\n must not take the Build action away with it. -->\n <button\n type=\"button\"\n mat-button\n (click)=\"db.build()\">\n {{ db.rebuild() ? 'Rebuild' : 'Build' }}\n </button>\n }\n }\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>\n","// The assembled report structure returned by GET /api/reports/:id — composed\n// server-side from the normalized tables (reports → report_pages →\n// report_components + report_filters, plus report_filter_groups). All keys are\n// camelCase; component `config` is the standard format the renderer maps to\n// ECharts options / FsList config.\n\nimport { GridLayout } from '@firestitch/grid';\n\nimport { ReportChangePolarity } from '../enums/report-change-polarity.enum';\nimport { ReportChartColor } from '../enums/report-chart-color.enum';\nimport { ReportChartDataLabels } from '../enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from '../enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from '../enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from '../enums/report-chart-mark-stat.enum';\nimport { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from '../enums/report-number-units.enum';\nimport { ReportValueFormat } from '../enums/report-value-format.enum';\nimport { ReportValueFormula } from '../enums/report-value-formula.enum';\n\nimport { ComponentDataApplied } from './component-data-applied.interface';\nimport { ComponentDataDrill } from './component-data-drill.interface';\nimport { ReportDrillStep } from './report-drill-step.interface';\nimport { GridConfig } from './report-grid-config.interface';\nimport { ReportViewerFeature } from './report-viewer-feature.type';\n\n// A BCP 47 language tag naming how numbers and dates are written, e.g. 'fr-CA'.\n// The set is open (the server's provider decides which it offers), so this is a\n// named alias rather than a union.\nexport type ReportLocaleTag = string;\n\n// An ISO 4217 currency code, e.g. 'CAD'. Open for the same reason.\nexport type ReportCurrencyCode = string;\n\nexport interface Report {\n id: number;\n name: string;\n // The report's own stored IANA zone (e.g. America/New_York). null = the\n // report follows the application's default reporting zone.\n timezone: string | null;\n // The zone every date filter, time bucket and date cell of this report uses.\n // Resolved server-side; the same for every viewer, export and the assistant.\n // Optional only because older servers omit it; resolveReportTimezone() then\n // falls back to the report's own `timezone`, then the browser's zone. Resolve\n // the zone for rendering through resolveReportTimezone() (format.ts); read the\n // field directly only to check whether the server sent it.\n effectiveTimezone?: string;\n // The report's own stored locale. null = the report follows the default.\n locale?: ReportLocaleTag | null;\n // The locale every number and date of this report is written in, resolved\n // server-side (the report's own, else the application's default, else\n // en-US). Absent on older servers, whose reports then read en-US. Resolve it\n // for rendering through resolveFormatContext() (format.ts), never directly.\n effectiveLocale?: ReportLocaleTag;\n // The report's own stored currency. null = the report follows the default.\n currency?: ReportCurrencyCode | null;\n // The currency money amounts are labeled in, resolved like effectiveLocale\n // (falling back to the locale's own currency, then USD). A label only:\n // amounts are never converted.\n effectiveCurrency?: ReportCurrencyCode;\n // How the server sends a percent measure: 'ratio' = a 0-1 ratio (0.385 reads\n // 38.5%). Absent on older servers, whose percent values are already x100\n // (38.5 reads 38.5%).\n percentFormat?: 'ratio';\n // Report-level config: typographic styles, etc. (camelCase JSON column).\n config: ReportConfig;\n // The page in INCHES (the report's native unit — PDFs and PowerPoint are\n // inch-based, so exports are dimensionally exact). Orientation is not a field\n // of its own: a page wider than it is tall IS landscape.\n pageWidth: number;\n pageHeight: number;\n pages: ReportPage[];\n // The header and footer: the report's master page, whose components draw\n // under every page that does not hide them (PowerPoint's slide master). Null\n // until anything has been placed in them.\n master: ReportMaster | null;\n filterGroups: ReportFilterGroup[];\n // The viewer features this server serves for the report. The viewer offers\n // a control only when its feature is listed. Absent on older servers, which\n // serve none.\n viewerFeatures?: ReportViewerFeature[];\n // Whether the viewer shows the AI chat beside the report (the server's\n // Reports > AI chat setting). Absent on older servers, which keep the chat.\n chatEnabled?: boolean;\n}\n\nexport interface ReportMaster {\n id: number;\n components: ReportComponent[];\n // The values the header and footer text shows, as ReportPage.values.\n values?: ReportComponent[];\n}\n\n// How the open report writes its numbers and dates, resolved once per report\n// (resolveFormatContext) and read by the viewer, the PDF and PowerPoint alike.\n// Never the browser's locale.\nexport interface ReportFormatContext {\n locale: ReportLocaleTag;\n currency: ReportCurrencyCode;\n // Whether a percent measure arrives as a 0-1 ratio (the report's\n // percentFormat). An older server sends it already x100.\n ratioPercent: boolean;\n}\n\n// One locale the server offers, with the currency a report in it uses when it\n// names none of its own.\nexport interface ReportLocaleOption {\n locale: ReportLocaleTag;\n defaultCurrency: ReportCurrencyCode;\n}\n\n// GET reports/locales: what the report settings' Locale and Currency selects\n// offer.\nexport interface ReportLocales {\n defaultLocale: ReportLocaleTag;\n options: ReportLocaleOption[];\n currencies: ReportCurrencyCode[];\n}\n\n// The depth of the header band (top of every page) and the footer band (bottom\n// of every page), in INCHES. The bands hold no content of their own — the\n// master's components sit in them — they are the reserved margins the editor\n// draws as guides and snaps to. Always arrives resolved (0 = no band).\nexport interface ReportHeaderFooter {\n headerHeight: number;\n footerHeight: number;\n}\n\n// Report-level styling. Sizes are in POINTS (1/72\") — the report's typography\n// maps 1:1 to PDF (72pt/in) and PowerPoint (point font sizes), so a point\n// value is dimensionally exact on screen and in every export.\nexport interface ReportConfig {\n styles?: ReportStyles;\n // The report's group-by control. Optional on the type because a ReportConfig\n // literal need not carry it; the API always sends it, resolved.\n groupBy?: ReportGroupBy;\n // Resolved by the API like groupBy.\n headerFooter?: ReportHeaderFooter;\n}\n\n// The report's group-by control — the one switch that re-buckets every\n// time-series chart and every table that follows it (followsGroupBy) on the\n// report between day, week, month, quarter and year.\n//\n// It is NOT a filter: a filter narrows which rows are counted, this changes how\n// the surviving rows are bucketed. It shares the report's filter bar because\n// that is the one row of controls a viewer reads a report through — the\n// separation that matters is in the model, not in where the control is painted.\n//\n// Always arrives RESOLVED (the backend fills an absent or partial stored block\n// in from its own defaults), so there is nothing to default here — render what\n// you are given.\nexport interface ReportGroupBy {\n enabled: boolean;\n label: string;\n granularities: ChartGranularity[];\n}\n\nexport interface ReportStyles {\n heading?: { size?: number };\n}\n\n// Content padding around a component's body, in INCHES (the geometry unit).\nexport interface ComponentPadding {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface ReportPage {\n id: number;\n name: string | null;\n order: number;\n // The page opts out of the report's header and footer (a title page).\n masterHidden: boolean;\n components: ReportComponent[];\n // Every active value of the page, in id order: those its text shows and\n // those no text shows any more (kept until a text, value or page delete, so\n // a chip pasted back still names one). Never drawn, and never in\n // `components`. Optional because older servers omit it.\n values?: ReportComponent[];\n}\n\n// 'text' is authored rich text with no query behind it — it never fetches data.\n// 'value' is one number shown inside a text block's words ({{value.key}}); it\n// has a query but no place of its own on the page. 'grid' is a table drawn by\n// fs-grid, which reads its own rows through ReportGridSource.\nexport type ReportComponentType = 'chart' | 'list' | 'grid' | 'kpi' | 'text' | 'value';\n\nexport interface ReportComponent {\n id: number;\n type: ReportComponentType;\n title: string | null;\n // Geometry in INCHES: absolute position on the page canvas.\n x: number;\n y: number;\n w: number;\n h: number;\n // Height mode, DERIVED from type server-side (not stored, read-only): lists\n // and KPI tiles are auto (the box sizes to its content, `h` ignored); charts\n // are always fixed (use `h`) so they fit the box and never overflow.\n autoHeight: boolean;\n // The stored SQL of a legacy sql-mode component. NULL for a derived one,\n // whose statement does not exist until its document is compiled — the SQL tab\n // fetches that separately (see ReportComponentSql).\n sql: string | null;\n config: ChartConfig & ListConfig & GridConfig & KpiConfig & TextConfig & ValueConfig & ComponentLayoutConfig\n & Record<string, unknown>;\n filters: ReportFilter[];\n // The field the report's group-by re-buckets on this tile, named by the\n // server; null on a tile that keeps its own grain. Absent from a server that\n // predates tables following the group-by (followsGroupBy()).\n followsGroupBy?: ReportGroupByField | null;\n}\n\n// The field the report's group-by re-buckets on a tile — a time-series\n// chart's x-axis, a table's time axis as its fields name it — and the grain\n// the tile is authored at, which it reads at while the group-by picks none.\nexport interface ReportGroupByField {\n field: string;\n granularity: ChartGranularity | null;\n}\n\n// What the SQL tab fetches: the statement a component runs.\n//\n// For a derived component `baseline` is true and `sql` is what its document\n// compiles to with NO viewer state — no filters, the authored grain. The\n// numbers on screen come from that statement plus whatever the viewer picked,\n// so the two can legitimately differ and the tab says so rather than implying\n// they match.\n//\n// `timezone` is the IANA zone the statement was compiled in: the report's\n// effective zone. Optional because older servers omit it; they compiled in UTC.\n//\n// `error` is not a failure of the request: a document that no longer compiles\n// is precisely what someone opens this tab to discover, so it arrives as a\n// message to render with `errorType` naming which kind ('stale-query' or\n// 'sensitive-column'), and `sql` null.\nexport interface ReportComponentSql {\n sql: string | null;\n origin: 'sql' | 'dbq' | 'derived';\n baseline: boolean;\n timezone?: string;\n error: string | null;\n errorType: string | null;\n}\n\n// A text block's content: an html fragment the server has already rebuilt from\n// an allowlist, which may carry {{page.number}}, {{page.name}} and\n// {{report.name}} tokens (see text.ts).\nexport interface TextConfig {\n html?: string;\n}\n\n// A value's key: what its token in a text block's html names, unique within\n// the page. Its number is formatted by config.measure (KpiConfig), as on a KPI.\n// A formula value has no query: `formula` names what it works out of the\n// page's query values, and its measure holds only the format keys its author\n// gave (format, precision, units).\nexport interface ValueConfig {\n key?: string;\n formula?: ValueFormulaConfig | null;\n}\n\n// A formula value's operation and operands: `of` names query values on the\n// same page (the master for a header or footer) by key, 2 of them, or 2 to 10\n// for a sum. `signed` absent reads true for a change and a percent change,\n// false for a ratio and a sum.\nexport interface ValueFormulaConfig {\n op: ReportValueFormula;\n of: string[];\n signed?: boolean | null;\n}\n\n// One row of POST pages/:id/values: a value's number for the filters sent.\n// There is one row per value the layer reads, in id order: one some text on\n// that page shows, or an operand of a formula some text shows. `value` is\n// raw, as the query returned it or the server worked it out (null when there\n// is no row or the result is null); formatting is the viewer's, through the\n// value's measure. `error` is that value's own failure, and the page's other\n// values are read regardless.\n// `role` is the comparison role the number plays: a query value's comparison\n// output's, change or percent_change for those formulas, else null.\nexport interface ReportPageValue {\n id: number;\n key: string;\n value: number | string | null;\n error: string | null;\n role?: OutputRole | null;\n}\n\n// Cross-type layout/style keys carried in a component's config (alongside the\n// type-specific chart/list/kpi keys).\nexport interface ComponentLayoutConfig {\n padding?: ComponentPadding;\n}\n\n// The presentation settings a component's settings dialog edits. Title and\n// padding are not part of what the component queries, so a change to them\n// repaints without re-running anything. A derived KPI's card keys are sent\n// too: the server computes the target's progress and the sparkline's points\n// with the data, so a change to them reloads it.\nexport interface ComponentSettings {\n title: string;\n padding: ComponentPadding;\n kpi?: KpiCardSettings;\n}\n\n// A KPI's card keys. The dialog sends them (null removes a key, increaseIs\n// null reads good), and ComponentSettings.kpi carries them as the server\n// saved them, read back from the config it returns.\nexport interface KpiCardSettings {\n increaseIs: ReportChangePolarity | null;\n target: KpiTargetConfig | null;\n sparkline: KpiSparklineConfig | null;\n}\n\n// Where a chart's legend sits relative to the plot, or 'hidden' to drop it.\nexport type LegendPosition = 'top' | 'bottom' | 'left' | 'right' | 'hidden';\n\nexport type ChartGranularity = 'day' | 'week' | 'month' | 'quarter' | 'year';\n\n// How each granularity reads in the group-by control and on an export cover\n// sheet. WHICH of them a given report offers comes from its ReportGroupBy;\n// this is only the naming. 'year' reads as \"Annually\".\nexport const GRANULARITY_OPTIONS: { value: ChartGranularity; name: string }[] = [\n { value: 'day', name: 'Day' },\n { value: 'week', name: 'Week' },\n { value: 'month', name: 'Month' },\n { value: 'quarter', name: 'Quarter' },\n { value: 'year', name: 'Annually' },\n];\n\n// The chart types that plot series against a category and a value axis, and so\n// the types a measure's own series can be drawn as. A waterfall has the same\n// axes but is not one of them: it draws its one measure as floating steps.\nexport type AxisChartType = 'bar' | 'line' | 'area';\n\n// What one bar of a waterfall does to the running total — each is drawn in its\n// own color. The closing total is the last bar, standing on zero.\nexport type WaterfallStepKind = 'rise' | 'fall' | 'total';\n\nexport interface ChartConfig {\n // A waterfall takes ONE measure whose value per category is how far the\n // running total moves there: each bar starts where the one before it ended,\n // and a closing Total bar shows the sum.\n chartType?: AxisChartType | 'waterfall' | 'pie' | 'donut';\n // For kind 'time', the server buckets the raw datetime column to `granularity`\n // in the report's timezone (the SQL exposes the raw column, unbucketed).\n // dateLabel writes a time axis's period labels short ('May', the default),\n // long ('May 2026') or numeric ('2026-05'); a category axis ignores it.\n xAxis?: {\n column: string;\n kind?: 'category' | 'time';\n granularity?: ChartGranularity;\n label?: string;\n dateLabel?: ReportChartDateLabel;\n };\n measures?: ChartMeasure[];\n // Each value of this column becomes its own series. It carries no label: the\n // legend names the values themselves.\n splitBy?: { column: string };\n // Single-dimension bar charts only: color each bar by its own category and\n // show a legend, WITHOUT splitting into multiple series (which slivers the\n // bars). v1 expects colorBy.column === xAxis.column. Ignored when splitBy is\n // set or the chart isn't a bar chart.\n colorBy?: { column: string; label?: string };\n orientation?: 'vertical' | 'horizontal';\n stacked?: boolean;\n // Stacks the primary axis's bar and area series as shares of each\n // category's total, so every stack reaches 100%. The viewer computes the\n // shares from the rows it receives, after the filters ran; the rows and the\n // CSV keep the raw values. The value axis then always runs 0 to 100% (from\n // -100% when a share is negative).\n percentStacked?: boolean;\n // Values printed beside the points of a bar, line or area series: every\n // point (all), each series' latest point (last), or every point whose label\n // fits without overlapping another (auto). Omitted or none, no labels. A\n // pie, a donut and a waterfall never print them.\n dataLabels?: ReportChartDataLabels;\n // The primary value axis's title and range. Every series is plotted against\n // it unless its measure is secondary.\n valueAxis?: ChartValueAxis;\n // The second value axis, on the right, that secondary measures plot against.\n secondaryAxis?: ChartValueAxis;\n // Labeled lines across the plot at a constant value, or bands between two\n // values, at most 5. Vertical axis charts and waterfalls only.\n references?: ChartReference[];\n legend?: LegendPosition;\n sort?: ReportSort;\n limit?: number;\n}\n\n// A value axis's title and range. Each bound left out is picked from the data,\n// and the tick step without an interval. Its ticks take the number format of\n// the measures plotted against it.\nexport interface ChartValueAxis {\n label?: string;\n min?: number;\n max?: number;\n interval?: number;\n}\n\n// A reference drawn across a chart's plot: a line at `value`, or with `to` a\n// band between the two, labeled with `label`. The value is one the user or\n// the model states, never one read off the data. secondary plots it against\n// the second value axis, when the chart has one.\nexport interface ChartReference {\n value: number;\n label: string;\n to?: number;\n secondary?: boolean;\n}\n\n// How one numeric slot is shown: a chart measure, a KPI measure, a list column\n// or a cross-tab's cells. The data stays raw (it sorts and exports as a\n// number); only the renderers format it, the same way on screen, in the PDF\n// and in PowerPoint (format.ts). All three keys are optional, and precision or\n// units without a format mean number.\n//\n// Formatting is opt-in: a list column or cross-tab cell without these keys\n// prints its value as it came, and a chart without them keeps its plain\n// locale-grouped axis and tooltips. A KPI without them prints a plain number.\nexport interface NumberFormatSpec {\n // percent takes a 0-1 ratio (0.3 reads 30%) when the report's percentFormat\n // is 'ratio'; an older server leaves it out and sends x100. currency labels\n // the amount in the report's currency, written in its locale.\n format?: ReportValueFormat | ReportListColumnFormat;\n // How many decimal places the value is shown to (0-6). Fixed rather than\n // maximum: a column of rates is unreadable when each one shows a different\n // number of decimals. For percent it counts the decimals of the percentage\n // (precision 1 shows 0.3 as 30.0%). Omitted leaves the format's own default:\n // at most one decimal for percent (and for an abbreviated 1.2K), whole units\n // for currency, the locale's default for a number.\n //\n // It cannot be applied in the SQL: the value is aggregated after the report's\n // filters run, so pre-rounding would break live re-filtering.\n precision?: number;\n // Abbreviates to thousands (1.2K) or millions (3.4M), or picks by size.\n units?: ReportNumberUnits;\n}\n\nexport interface ChartMeasure extends NumberFormatSpec {\n column: string;\n aggregation?: 'sum' | 'count' | 'avg' | 'min' | 'max';\n label?: string;\n // Draws this measure's series as a different type from the chart's own\n // chartType — counts as bars with a rate as a line over them is a combo\n // chart. Omitted, the series takes the chart's type. Axis charts only (a pie\n // ignores it).\n type?: AxisChartType;\n // A chart measure's format shows on its tooltips, and on the value axis\n // when every measure sharing the axis agrees on it. A KPI's measure formats\n // its one value.\n format?: ReportValueFormat;\n // Plots this measure against the second value axis, on the right, for a\n // quantity on another scale. Omitted or false, it shares the primary axis.\n // A vertical axis chart only, with at least one measure left on the primary\n // axis.\n secondary?: boolean;\n // The palette color this measure's series is drawn in. Omitted, the series\n // takes the palette color of its position. A color on the first measure\n // turns off a category bar chart's default color per bar (isColorBy).\n color?: ReportChartColor;\n // How a line series' line is drawn. Omitted, solid.\n line?: ReportChartLineStyle;\n // Whether a line or area series draws a dot on each point. Omitted, true.\n markers?: boolean;\n // A line across the plot at this series' average, median, lowest or highest\n // value over the points on screen. Vertical axis charts only.\n markLine?: ReportChartMarkStat;\n}\n\n// One authored column of a plain list.\nexport interface ListColumn extends NumberFormatSpec {\n column: string;\n label?: string;\n // date keeps the column a RAW timestamp, so the report timezone and its\n // dateRange filters keep working, and the viewer renders it as a day in the\n // report's zone and locale. number, percent and currency format the value as\n // a KPI measure does. Without a format the value prints as it came.\n format?: ReportListColumnFormat;\n // A column the SQL already formatted is text, so it names `sortColumn`: the\n // raw numeric alias the query also outputs, which the server orders by\n // instead.\n sortColumn?: string;\n // false keeps the cell on one line. Omitted, a long value wraps.\n wrap?: boolean;\n}\n\nexport interface ListConfig {\n columns?: ListColumn[];\n // A cross-tab: `rowBy` stays down the side and every value of `pivotBy`\n // becomes a column. The two are set together, `columns` is omitted (the\n // backend rejects authoring both), and the column set arrives with the rows\n // in ComponentData.columns because only the result knows the pivot values.\n // rowBy.label heads the side column on screen and in every export, and\n // defaults to the column name. pivotBy carries no label: its values are the\n // headings.\n rowBy?: { column: string; label?: string };\n pivotBy?: { column: string };\n // The authored order, most important first. A list saved before multi-key\n // sorting stores one object, so read it through listSortTerms() only.\n sort?: ReportSort | ReportSort[];\n // How many leading columns stay in view while the list scrolls sideways\n // (0-3). Unset, a cross-tab pins its row-key column and a plain list none.\n pinnedColumns?: number | null;\n pageSize?: number;\n // true adds a totals row under the list: the server runs the measures again\n // over every row the filters keep, without grouping, and a cross-tab totals\n // each column.\n totals?: boolean;\n // A cross-tab only: how every cell of the grid is formatted, with a KPI\n // measure's keys. The row key column stays as it came.\n cellFormat?: NumberFormatSpec & { format?: ReportValueFormat };\n}\n\nexport interface KpiConfig {\n measure?: ChartMeasure;\n // Whether a rise in the value is good news, bad news or neither: it picks\n // the delta's color and decides when a target is met (good: at or above it;\n // bad: at or below it; neutral: never judged). Omitted or null reads good.\n increaseIs?: ReportChangePolarity | null;\n // A number the user gave for the value to reach, never one read off the\n // data. The server sends the progress toward it with the data.\n target?: KpiTargetConfig | null;\n // A small trend line of the value over its last periods, drawn under it.\n sparkline?: KpiSparklineConfig | null;\n}\n\n// A KPI's target: the value, and an optional caption for it ('Goal').\nexport interface KpiTargetConfig {\n value: number;\n label?: string | null;\n}\n\n// A KPI's sparkline: how wide each point's period is (null reads month) and\n// how many periods it draws, 2 to 60 (null reads 12).\nexport interface KpiSparklineConfig {\n granularity?: ChartGranularity | null;\n periods?: number | null;\n}\n\nexport interface ReportSort {\n column: string;\n direction?: 'asc' | 'desc';\n}\n\nexport type ReportFilterType = 'dateRange' | 'select' | 'keyword' | 'numberRange';\n\n// Where a filter group's control is exposed. A group can be shown on its\n// components, in the report bar, or BOTH at once (the two are independent\n// toggles in the UI); a column with neither exposed simply has no filter.\n// 'page' shows it in the report bar of one page only (ReportFilterGroup.pageId).\nexport type ReportFilterLevel = 'component' | 'report' | 'both' | 'page';\n\n// One filterable output column of a component's SQL, with the filter interface\n// INFERRED from its data (the human never picks the interface — it follows the\n// column's type). Drives the Filters tab listing.\nexport interface ReportFilterableColumn {\n column: string;\n type: ReportFilterType;\n // Every interface the column can take, the inferred one (type) first: a\n // numeric column takes ['select', 'numberRange']. Absent on older servers.\n types?: ReportFilterType[];\n}\n\n// Ground truth: one filterable output column ON one component's SQL. Always a\n// member of a filter group — the unit that links equivalent filters across\n// components and decides where the control renders (component vs report bar).\nexport interface ReportFilter {\n id: number;\n componentId: number;\n filterGroupId: number;\n filterColumn: string;\n label: string | null;\n enabled: boolean;\n hasOptions: boolean;\n config: Record<string, unknown>;\n}\n\n// One choice in a select filter's option list. The value is what the filter\n// matches on and gets stored in a saved default — for an entity that is its\n// stable id, never its name, so renaming the entity moves the label without\n// breaking the default. The label is only ever what the viewer reads.\nexport interface ReportFilterOption {\n value: unknown;\n label: string;\n}\n\nexport interface ReportFilterGroup {\n id: number;\n // The group's identifier, unique in the report: camelCase, a letter first,\n // then letters and digits. Set apart from the label: a new label never\n // changes it, and it is edited on its own (Report settings > Filters).\n // Tiles and saved filters bind the group by id, never by name. Optional\n // because an older server sends none.\n name?: string;\n label: string | null;\n type: ReportFilterType;\n level: ReportFilterLevel;\n order: number;\n config: { default?: FilterGroupDefault } & Record<string, unknown>;\n filters: ReportFilter[];\n // The page whose report bar shows the group: set only when level is 'page',\n // null otherwise. Absent on older servers.\n pageId?: number | null;\n // The components of the group's active, enabled members that are tiles\n // (chart, list, KPI). Absent on older servers.\n componentIds?: number[];\n // True when an enabled member binds several columns, where values cannot\n // be left out: the group offers no 'Exclude these' (offersExclude). Absent\n // on older servers.\n multiColumn?: boolean;\n // A select group's label for a blank row, null when blank rows have none:\n // an exclude line says whether the blank rows are kept. Sent for select\n // groups only, and absent on older servers.\n blankLabel?: string | null;\n}\n\n// A filter group's value in its stored shape: its authored default (the value\n// that seeds the report bar on every open), and a value the assistant runs it at. Shape follows the group's type: dateRange\n// uses start/end (a fixed calendar-day range) or a relative preset; select\n// uses values or excludeValues, never both; keyword uses value; numberRange\n// uses min and max.\nexport interface FilterGroupDefault {\n // dateRange relative preset, resolved on every open against today in the\n // report's effective zone (Report.effectiveTimezone). One of: thisWeek,\n // lastWeek, last7Days, last30Days, last3Months, last6Months, last12Months,\n // thisMonth, thisQuarter, thisYear/yearToDate. Weeks run Monday to Sunday,\n // the same weeks the server's weekly time buckets use.\n relative?: string;\n start?: string; // dateRange fixed start (yyyy-MM-dd)\n end?: string; // dateRange fixed end (yyyy-MM-dd)\n values?: unknown[]; // select default picked values\n value?: string; // keyword default text\n // select: the values to leave out (rows with a blank value are kept).\n excludeValues?: unknown[];\n // numberRange: the low and high ends, either one open (absent). 0 is an\n // end like any other.\n min?: number;\n max?: number;\n}\n\n// The session value of a filter group: shape depends on the group's type. Not\n// stored on the server: it lives in the open report's state\n// (ReportFilterStateService).\nexport interface FilterGroupValue {\n start?: Date | string | null; // dateRange\n end?: Date | string | null; // dateRange\n values?: unknown[]; // select\n value?: string; // keyword\n // dateRange only: the relative preset name these dates were resolved from\n // (a FilterGroupDefault.relative name). Set only when the value was seeded\n // from the group's relative default, so the range keeps rolling\n // ('last30Days') instead of freezing two dates, and the data request names the\n // period it covers (see\n // ResolvedFilterValue.preset). Any date picked by the viewer, a date picker\n // preset included, is stored without it.\n preset?: string;\n // select: the values to leave out. Switching a select between keeping and\n // leaving out moves its list from values to excludeValues.\n excludeValues?: unknown[];\n // numberRange: the low and high ends; null or absent = open.\n min?: number | null;\n max?: number | null;\n}\n\n// A relative date range the server resolves against today in the report's\n// zone: the names a FilterGroupDefault.relative and a timeframe's range take.\n// Mirrors the server's ReportRelativeRangeEnum value for value\n// (ReportRelativeRangeEnumTest pins the days each one covers).\nexport type ReportRelativeRange =\n | 'thisWeek'\n | 'lastWeek'\n | 'last7Days'\n | 'last30Days'\n | 'last3Months'\n | 'last6Months'\n | 'last12Months'\n | 'thisMonth'\n | 'thisQuarter'\n | 'thisYear'\n | 'yearToDate';\n\n// One resolved filter sent with a component's data request.\nexport interface ResolvedFilterValue {\n filterId: number;\n start?: string;\n end?: string;\n values?: unknown[];\n value?: string;\n // dateRange only: the relative range start and end still are, sent only\n // while they are exactly that range resolved today in the report's zone. It\n // tells the server which period the days cover (on the first days of a\n // quarter, thisMonth and thisQuarter are the same days), so a comparison\n // shifts by the right unit. start and end stay the window; a server that\n // does not know the key ignores it.\n preset?: ReportRelativeRange;\n // select: the values to leave out (sent instead of values).\n excludeValues?: unknown[];\n // numberRange: the low and high ends; an open end is left out, 0 is sent.\n min?: number;\n max?: number;\n}\n\n// Per-component interaction state sent with the data request: lists send\n// sort/paging and the text in their search box; the tiles that follow the\n// group-by (followsGroupBy) send the grain picked on the report's group-by control, which overrides the authored\n// granularity for that request only. The wire key stays `frequency` — it is the\n// bucketing frequency the server applies.\nexport interface ComponentDataState {\n sort?: ReportSort;\n page?: number;\n pageSize?: number;\n frequency?: ChartGranularity;\n // A list's search box text. The server trims it, cuts it to its own maximum\n // length and matches it against every text column the list shows.\n search?: string;\n // The config column names a viewer hid on a plain list. Sent with a CSV\n // export only (the screen hides them itself): the file leaves them out. The\n // server ignores it on a cross-tab, and when it would hide every column.\n hiddenColumns?: string[];\n // A chart's drill path, top first. The drilled level wins over frequency\n // for this tile.\n drill?: ReportDrillStep[];\n // While match is any: the eligible groups that have a value.\n matchAnyGroupIds?: number[];\n // A table's layout as the viewer changed it, sent with a file (the CSV,\n // the zip) so it holds what the screen shows. Absent: the stored layout.\n layout?: GridLayout;\n // Set only on a request sent because the cross-filter changed, for a tile\n // whose last read applied no cross entry: the server may answer\n // unchanged instead of reading the rows again. Exports never set it.\n unchangedIfUnreached?: true;\n}\n\nexport interface ComponentData {\n columns: string[];\n rows: Record<string, unknown>[];\n paging?: { total: number; page: number; pageSize: number };\n truncated: boolean;\n // The effective time bucket the rows were grouped into (after any group-by\n // override), or null for a non-time axis. Drives the compact x-axis labels.\n granularity?: ChartGranularity | null;\n // Page 1 of a searched list whose search could not apply (the list has no\n // text column to search): why the rows are not narrowed. Absent otherwise.\n searchNote?: string | null;\n // Page 1 of a list with config.totals on: its totals row, as raw values\n // keyed like the columns (a plain list's measure aliases; a cross-tab's\n // pivot cell columns, the row-key column absent), or null with totalsNote\n // saying why there is none. Absent on every other page and list.\n totals?: Record<string, unknown> | null;\n totalsNote?: string | null;\n // The window of days the component reads, when its query has a timeframe.\n // Absent otherwise, and from older servers.\n timeframe?: ComponentTimeframe | null;\n // The current and prior windows of a component whose measures compare\n // against an earlier period. Absent when no measure compares. Sent on every\n // list page and on chart and KPI data.\n comparison?: ComponentComparison | null;\n // What each compared, windowed, ranked or shared output column is, by alias.\n // Plain measure columns are left out.\n outputs?: Record<string, OutputMeta>;\n // A cross-tab only: the measure alias each pivot cell column holds, so a\n // cell takes its measure's output meaning. Never sent for a sql-mode list.\n cellMeasures?: Record<string, string>;\n // How each windowed output column (running, to-date or rolling) was\n // computed, by alias.\n windows?: Record<string, WindowMeta>;\n // A KPI with a comparison, a target or a sparkline: every number the card\n // shows beside its value, decided by the server.\n kpi?: ComponentKpi | null;\n // The time-axis value of the bucket containing today, written as the rows\n // write it, when that bucket is not finished yet; null otherwise. A chart\n // marks it as partial.\n partialPeriod?: string | null;\n // Which filters the read applied. Absent from older servers.\n applied?: ComponentDataApplied;\n // A drillable chart's drill state. Absent on every other tile and from\n // older servers.\n drill?: ComponentDataDrill;\n}\n\n// Where a component's timeframe window came from: a viewer dateRange bound to\n// the timeframe column (which replaces the authored range, never narrows\n// it), the authored relative range, the authored fixed days, or nothing (an\n// open window).\nexport type TimeframeSource = 'filter' | 'range' | 'fixed' | 'none';\n\n// The window a component's timeframe resolved to. start and end are\n// inclusive 'yyyy-MM-dd' days in the report's zone, written without a zone.\n// through is the UTC 'yyyy-MM-dd HH:mm:ss' instant a window on a datetime\n// column is cut at; it reads as a time in the report zone. It is set only when\n// a comparison cuts a window that ends today: a timeframe on its own reads\n// whole days, so a window ending today without a comparison sends null.\nexport interface ComponentTimeframe {\n column: string;\n start: string | null;\n end: string | null;\n through: string | null;\n range: ReportRelativeRange | null;\n source: TimeframeSource;\n}\n\n// How a comparison is laid out: one value per window (range), a prior series\n// beside a time axis (series), or each period's value read at its end, set\n// against the value at the end of an earlier period (period_end).\nexport type ComparisonMode = 'range' | 'series' | 'period_end';\n\n// to_date compares like with like (the first 2 days of a month against the\n// first 2 days of the one before); full compares whole periods.\nexport type ComparisonAlign = 'to_date' | 'full';\n\n// What a measure is compared against. Mirrors the server's\n// ComparisonAgainstEnum value for value.\nexport type ComparisonAgainst =\n | 'previous_period'\n | 'previous_week'\n | 'previous_month'\n | 'previous_quarter'\n | 'previous_year'\n | 'range';\n\n// Why a comparison reads as it does. The server sends codes, never\n// sentences; the viewer words them.\n// - no_window: no date range to compare yet;\n// - unit_inferred: the period unit was inferred from the days, not named;\n// - window_in_future: the window starts after today;\n// - other_date_filter: a date filter on another column also applies;\n// - grain_followed: the prior follows the group-by grain picked on the report.\nexport type ComparisonNoteCode =\n | 'no_window'\n | 'unit_inferred'\n | 'window_in_future'\n | 'other_date_filter'\n | 'grain_followed';\n\n// One comparison window: inclusive 'yyyy-MM-dd' days in the report's zone,\n// and the UTC instant it is cut at when it ends today on a datetime column.\n// In series mode it is the span the chart shows.\nexport interface ComparisonWindow {\n start: string;\n end: string;\n through: string | null;\n}\n\n// How far back one prior lane sits. A custom range has no unit or count, and\n// neither does previous_period when there is no current window to measure\n// (no_window, window_in_future); a shift by the window's length is unit day\n// with the length as the count; a previous year is 364 days on a day axis and\n// 52 weeks on a week axis.\nexport interface ComparisonOffset {\n against: ComparisonAgainst;\n unit: ChartGranularity | null;\n count: number | null;\n}\n\n// A component's comparison: the zone its days are in, the current window\n// (null when there is no window to compare yet, or when a time axis runs\n// over all the data, which has no first day to name) and up to 2 prior\n// lanes: offsets[i] describes lane i + 1, and priors[i] its window. With no\n// current window priors is empty, while offsets still names every lane.\n// floor is the 'yyyy-MM-dd' day of the first row the query's own conditions\n// keep (viewer filters aside): a prior window wholly before it has no data\n// rather than a zero.\nexport interface ComponentComparison {\n mode: ComparisonMode;\n timezone: string;\n align: ComparisonAlign;\n current: ComparisonWindow | null;\n priors: ComparisonWindow[];\n offsets: ComparisonOffset[];\n floor: string | null;\n notes: ComparisonNoteCode[];\n}\n\n// What an output column holds: a measure's value, its rank or its share.\nexport type OutputKind = 'value' | 'rank' | 'share';\n\n// Which side of a comparison an output column is: the current value, the\n// prior one, their difference, or the difference as a 0-1 fraction of the\n// prior. null for an output that is not compared.\nexport type OutputRole = 'current' | 'prior' | 'change' | 'percent_change';\n\n// How tied values rank: 1, 1, 3 (competition) or 1, 1, 2 (dense).\nexport type OutputRankMethod = 'competition' | 'dense';\n\n// A rank output: how ties rank, which end ranks 1 (desc: the largest), and\n// the dimension outputs it restarts within (none: the whole result).\nexport interface OutputRank {\n method: OutputRankMethod;\n direction: 'asc' | 'desc';\n within: string[];\n}\n\n// A share output: the dimension outputs whose total it is a share of (none:\n// the whole result).\nexport interface OutputShare {\n within: string[];\n}\n\n// The meaning of one compared, windowed, ranked or shared output column.\n// measure is the source measure's alias, whose format the column inherits;\n// offset is the prior lane a prior, change or percent change belongs to (its\n// window is comparison.priors[offset - 1]). Unless the config formats it, a\n// share prints as a percent to 1 decimal and a rank as a whole number.\nexport interface OutputMeta {\n measure: string;\n kind: OutputKind;\n role: OutputRole | null;\n offset: number | null;\n window: boolean;\n rank: OutputRank | null;\n share: OutputShare | null;\n}\n\n// A window over the rows: a running total, a total to date within each\n// period (month to date), or a rolling span of periods.\nexport type WindowKind = 'running' | 'to_date' | 'rolling';\n\n// Why a window reads as it does. Codes only; the viewer words them.\nexport type WindowNoteCode =\n | 'snapped_start'\n | 'span_converted'\n | 'grain_too_coarse'\n | 'equal_grain_plain'\n | 'own_filter_caps_lead_in'\n | 'week_by_monday'\n | 'incomplete_head';\n\n// How one windowed output column was computed. periods and unit size a\n// rolling window (drawnPeriods is that span counted in the grain the rows\n// are drawn at); resetEvery restarts a to-date window; average makes the\n// window an average rather than a total; fromBeginning\n// runs a total from the first row ever rather than from the first row shown.\n// start, end and leadIn are 'yyyy-MM-dd' report-zone days: the rows shown,\n// and the earlier day the window reads from so its first rows are whole.\n// description is the server's English for the agent and the exports; the\n// viewer composes its own words from the fields.\nexport interface WindowMeta {\n kind: WindowKind;\n periods: number | null;\n unit: ChartGranularity | null;\n drawnPeriods: number | null;\n resetEvery: ChartGranularity | null;\n average: boolean;\n fromBeginning: boolean;\n dateColumn: string | null;\n start: string | null;\n end: string | null;\n leadIn: string | null;\n notes: WindowNoteCode[];\n description: string;\n}\n\n// Which delta a KPI card shows: the difference, or the percent change.\nexport type KpiDeltaShow = 'change' | 'percent_change';\n\n// Why a KPI's delta reads as it does:\n// - no_prior_data: the prior window has no value;\n// - up_from_zero: the prior was 0, so there is no percent change;\n// - no_change: both are 0;\n// - no_data_either: neither window has a value;\n// - sign_change: the value crossed zero, so there is no percent change.\nexport type KpiNoteCode =\n | 'no_prior_data'\n | 'up_from_zero'\n | 'no_change'\n | 'no_data_either'\n | 'sign_change';\n\n// A KPI's progress toward its configured target. progress is value / target\n// (null when the target is 0); met follows the config's increaseIs (null\n// when it is neutral).\nexport interface ComponentKpiTarget {\n value: number;\n label: string | null;\n progress: number | null;\n met: boolean | null;\n}\n\n// One sparkline point: the period, written as a time-axis value, and the\n// value in it (null when a non-additive measure has no rows there).\nexport interface ComponentKpiSparklinePoint {\n period: string;\n value: number | null;\n}\n\n// A KPI's sparkline points, oldest first. partial says the last period is\n// not finished yet.\nexport interface ComponentKpiSparkline {\n granularity: ChartGranularity;\n partial: boolean;\n points: ComponentKpiSparklinePoint[];\n}\n\n// Every number a KPI card shows beside its value. show names the delta to\n// print, decided by the server. When value is null the card shows a dash and\n// no comparison.\nexport interface ComponentKpi {\n value: number | null;\n prior: number | null;\n change: number | null;\n percentChange: number | null;\n show: KpiDeltaShow;\n note: KpiNoteCode | null;\n target: ComponentKpiTarget | null;\n sparkline: ComponentKpiSparkline | null;\n}\n\n// A component's CSV export: the presigned download URL, plus one sentence per\n// way the file falls short of the full result (cut at the export ceiling, or\n// cut as the chart itself is). Empty when the file is complete. Optional\n// because a server on an older framework answers with the url alone.\nexport interface ComponentExportResponse {\n url: string;\n notes?: string[];\n}\n\nexport interface ReportListItem {\n id: number;\n name: string;\n modifyDate: string;\n state?: ReportState;\n // The folder the report is filed under. null is a real, common value — the\n // report sits at the root of the listing tree alongside the folders.\n //\n // Optional like `state` beside it: the backend always sends it, but making it\n // required is a breaking type change for every consumer holding a\n // ReportListItem literal (fixtures, mocks) and buys nothing — the listing\n // reads it as `?? null` either way.\n reportFolderId?: number | null;\n}\n\n// One folder in the listing tree — an audience bucket (\"Management\",\n// \"Operations\") reports are filed into. Folders nest via parentReportFolderId;\n// reports never do, so the tree's only branch nodes are folders.\n//\n// `state` is the folder's OWN state. Deleting a folder writes only that, and\n// everything below it counts as deleted by position — see ReportNode.deleted.\nexport interface ReportFolder {\n id: number;\n name: string;\n parentReportFolderId: number | null;\n state?: ReportState;\n}\n\n// GET /api/reports returns both halves flat; the listing nests them itself.\nexport interface ReportTree {\n reports: ReportListItem[];\n folders: ReportFolder[];\n}\n\nexport enum ReportNodeType {\n Folder = 'folder',\n Report = 'report',\n}\n\n// One node as fs-tree sees it. Folders and reports share one id space in the\n// view, so the ids are prefixed ('f:12' / 'r:34') — `id` is the original,\n// per-table id that the API endpoints take.\nexport interface ReportNode {\n key: string;\n id: number;\n name: string;\n type: ReportNodeType;\n // Only ever populated on a folder; a report is always a leaf.\n children: ReportNode[];\n // Present on report nodes only.\n report?: ReportListItem;\n // The node's own row is deleted. What earns the \"Deleted\" chip — this is\n // what somebody actually deleted.\n stateDeleted: boolean;\n // Deleted itself OR anywhere below a deleted folder. Only ever true in Show\n // Deleted mode (the default listing never returns such a node), and it is what\n // swaps the row's actions for Restore.\n deleted: boolean;\n}\n\n// Reports and folders are both soft-deletable. A deleted report keeps its pages\n// and components; a deleted folder keeps everything filed under it, which leaves\n// the listing with it and comes back with it. \"Show Deleted\" shows the whole\n// tree, live and deleted together, so any of it can be restored in place.\nexport enum ReportState {\n Active = 'active',\n Deleted = 'deleted',\n}\n\n// The chat turn flags this context's backend adds (Reports\\AiView).\nexport interface ReportChatResponse {\n reportChanged?: boolean;\n reportRenamed?: boolean;\n}\n\n// One version of the global AI knowledge document — the operator-authored\n// markdown appended to the report agent's system instructions on every turn.\nexport interface ReportInstruction {\n id: number;\n content: string;\n current: boolean;\n createDate: Date;\n modifyDate: Date;\n accountId: number | null;\n accountName: string | null;\n}\n\n// GET/PUT instructions payload: the current version (null until one is\n// authored) plus the full history, newest first.\nexport interface ReportInstructions {\n instructions: ReportInstruction | null;\n versions: ReportInstruction[];\n}\n\n// The latest semantic-database build (an ff_processes row) — enough for the\n// settings dialog to say what state the build is in and when it last ran.\nexport interface SemanticBuild {\n id: number;\n state: string;\n percent: number | string;\n message: string;\n duration: number;\n createDate: Date;\n startDate: Date;\n endDate: Date;\n}\n\n// A build stage's state on the entity scoreboard: 'done' = built, 'missing' =\n// still needs building (a missing stage is unbuilt content, never an error).\nexport type SemanticBuildStage = 'done' | 'missing';\n\n// One enum column of an entity, with the allowed values the build inlined.\nexport interface SemanticBuildEnum {\n column: string;\n values: string[];\n}\n\n// One entity row of the scoreboard (an entity = a table + a model + a\n// handler): its table/shape counts, inlined enum values, computed fields, how\n// many code functions were cached (split model vs handler), and the per-stage\n// built/missing state.\n//\n// `model`/`handler` are the classes the functions were read from — what a\n// reader recognizes the row by, where `key` is what the report AI addresses it\n// by in describe_entity / compile_query.\nexport interface SemanticBuildEntity {\n key: string;\n table: string;\n model: string | null;\n handler: string | null;\n columns: number;\n relationships: number;\n enums: SemanticBuildEnum[];\n computedFields: string[];\n functionCount: number;\n modelFunctionCount: number;\n handlerFunctionCount: number;\n stages: Record<string, SemanticBuildStage>;\n}\n\n// One standalone code class the build read: domain logic with no table of its\n// own (a summary model, a calculation service). The report AI reads its code\n// exactly like an entity's, but it can never be queried — there is nothing to\n// select from — so it carries no table, columns or relationships.\nexport interface SemanticBuildClass {\n key: string;\n model: string | null;\n functionCount: number;\n}\n\n// What the build decided a physical table is. Entity and junction are both\n// reachable by the report AI — an entity directly, a junction through the\n// many-to-many it bridges. Excluded is not reachable at all.\nexport type SemanticTableClassification = 'entity' | 'junction' | 'excluded';\n\n// One physical table as the build classified it. `reason` answers a single\n// question — why can't the report AI see this table? — and is null when it can.\n// A junction with a reason bridged nothing, so it is just as invisible as an\n// excluded table.\nexport interface SemanticBuildTable {\n table: string;\n classification: SemanticTableClassification;\n model: string | null;\n reason: string | null;\n}\n\n// The build scoreboard shipped alongside the build status: the summary counts,\n// the full breakdown the settings dialog drills into — BOTH kinds of unit the\n// build caches, table-backed entities and standalone code classes — and the\n// catalog of every table the build saw, so the tab can show what the report AI\n// can't see, not just what it can.\n//\n// `functionCount` spans entities and classes alike: it is the same total the\n// build itself reports when it finishes.\n//\n// `tables` is empty for an artifact built before the catalog existed. Read that\n// as \"no catalog\", never as \"nothing was excluded\".\nexport interface SemanticBuildDetail {\n // Whether the artifact was produced by a build that ran to the end. Read it\n // beside `generatedAt`, never instead of it: the structural artifact is\n // published BEFORE the AI function pass, so a build whose AI pass failed still\n // carries a date and a full set of counts. The date says something was\n // written; only this says the build finished writing it.\n complete: boolean;\n generatedAt: Date | null;\n entityCount: number;\n classCount: number;\n functionCount: number;\n entities: SemanticBuildEntity[];\n classes: SemanticBuildClass[];\n tableCount: number;\n junctionCount: number;\n unlinkedJunctionCount: number;\n excludedCount: number;\n tables: SemanticBuildTable[];\n}\n\n// Which class a cached function was read from. An entity's cache splits into\n// 'model' and 'handler'; a standalone code class has one group, 'class'.\nexport type SemanticFunctionSource = 'model' | 'handler' | 'class';\n\n// One AI-classified code function from a model, handler or standalone class:\n// what kind of logic it is, what it does, and what it produces — the build's\n// cached \"what the code does\" knowledge shown in the functions dialog.\nexport interface SemanticEntityFunction {\n class: string;\n method: string;\n signature: string;\n kind: string;\n summary: string;\n produces: string;\n source: SemanticFunctionSource;\n}\n\n// One entity's cached code-function knowledge, fetched when a functions dialog\n// opens (the full set across all entities is too big to ship with the\n// scoreboard). One payload serves both dialogs — consumers filter by source.\nexport interface SemanticEntityFunctions {\n entity: string;\n generatedAt: Date | null;\n modelClass: string | null;\n handlerClass: string | null;\n functions: SemanticEntityFunction[];\n}\n\nexport interface SemanticBuildStatus {\n build: SemanticBuild | null;\n detail: SemanticBuildDetail;\n}\n\n// The report module's General settings (a small global key/value store, the\n// reporting counterpart of the app-wide settings). Each value ships with the\n// safe band its editor field is bounded to.\nexport interface ReportSettings {\n // How many summary calls the semantic build runs at once.\n semanticBuildConcurrency: number;\n semanticBuildConcurrencyMin: number;\n semanticBuildConcurrencyMax: number;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n OnInit,\n effect,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router, RouterLink } from '@angular/router';\n\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIconModule } from '@angular/material/icon';\n\nimport { FsChipModule } from '@firestitch/chip';\nimport { FilterConfig, FsFilterModule, ItemType } from '@firestitch/filter';\nimport { FsMessage } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\nimport {\n FlatItemNode,\n FsTreeComponent,\n FsTreeModule,\n ITreeChangeReorder,\n ITreeConfig,\n TreeActionType,\n TreeDragMode,\n} from '@firestitch/tree';\n\nimport { Observable, switchMap } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport { GlobalSettingsComponent } from '../../dialogs/global-settings/global-settings.component';\nimport {\n ReportFolder,\n ReportListItem,\n ReportNode,\n ReportNodeType,\n ReportState,\n ReportTree,\n} from '../../interfaces/report.interface';\n\n\n// The reports listing — an fs-tree of folders and the reports filed into them.\n// Rows link out through a URL pattern (a ':id' token → the report id; a leading\n// '/' makes it absolute, otherwise it's relative to this component's route).\n// Create prompts for a title, creates the report, then routes to it. The gear\n// opens the global Report Settings dialog (AI knowledge document +\n// semantic-database build), which lives in this package. No routing is\n// hard-coded here.\n//\n// Folders nest; reports are always leaves — canDrop enforces it here, and the\n// backend enforces it structurally by keeping the tree in its own table. A\n// report in no folder is a root node, which is where every report sat before\n// folders existed, so nothing had to be migrated or bucketed as \"uncategorized\".\n//\n// Folders and reports are both soft-deletable, and a folder deletes whatever it\n// holds. Only the folder's own row is written: everything under it drops out of\n// the listing because it sits under a deleted folder, and comes back with it.\n// \"Show Deleted\" shows the WHOLE tree — live and deleted together, each deleted\n// row where it was filed — and on anything deleted the kebab offers Restore\n// instead. Restoring also restores any deleted folder above the row, so it lands\n// back where it was rather than at the root.\n//\n// Every folder starts collapsed; the tree remembers what was opened across its\n// own reloads (a rename, a move, the Show Deleted toggle) and across a search.\n@Component({\n selector: 'fs-ai-reports',\n templateUrl: './fs-ai-reports.component.html',\n styleUrls: ['./fs-ai-reports.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FsChipModule,\n FsFilterModule,\n FsSkeletonModule,\n FsTreeModule,\n MatIconModule,\n RouterLink,\n ],\n})\nexport class FsAiReportsComponent implements OnInit {\n\n // API base for the reports endpoints; override to mount elsewhere.\n public readonly basePath = input<string>('reports');\n\n // Where a row links to; ':id' is replaced with the report id. Default takes\n // you to <current route>/:id. Absolute when it starts with '/'.\n public readonly openPattern = input<string>(':id');\n\n // Where a freshly-created report routes to; same ':id' pattern rules.\n public readonly createPattern = input<string>(':id');\n\n // Null until the first load resolves — that is what gates *fsSkeleton.\n public readonly nodes = signal<ReportNode[]>(null);\n\n public treeConfig: ITreeConfig<ReportNode[]>;\n public filterConfig: FilterConfig;\n\n // Template-side handle on the enum, so a row can tell a folder from a report.\n public readonly nodeType = ReportNodeType;\n\n private readonly _tree = viewChild(FsTreeComponent);\n\n private _reportData = inject(ReportData);\n private _router = inject(Router);\n private _route = inject(ActivatedRoute);\n private _prompt = inject(FsPrompt);\n private _message = inject(FsMessage);\n private _dialog = inject(MatDialog);\n private _destroyRef = inject(DestroyRef);\n\n // The filter bar's current query — carries `state` when Show Deleted is on.\n private _query: Record<string, unknown> = {};\n\n // The folders that were open when a search started; null while no search is\n // running. The search opens every match's path over the top of them, and\n // clearing it puts these back.\n private _expandedBeforeSearch: string[] | null = null;\n\n constructor() {\n effect(() => {\n this._reportData.basePath = this.basePath();\n });\n }\n\n public ngOnInit(): void {\n // Set before the first fetch rather than waiting on the effect above, which\n // does not run until after the initial change detection pass.\n this._reportData.basePath = this.basePath();\n\n this._initFilterConfig();\n this._initTreeConfig();\n this._load();\n }\n\n // routerLink commands for a report row (built from openPattern).\n public openLink(report: ReportListItem): unknown[] {\n return this._patternCommands(this.openPattern(), report.id);\n }\n\n // Prompt for a title, create the report — filed under reportFolderId when a\n // folder's kebab asked, at the root otherwise — then route to it (createPattern).\n public createReport(reportFolderId: number = null): void {\n this._prompt.input({\n title: 'Create Report',\n label: 'Title',\n commitLabel: 'Create',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData.create(name, reportFolderId)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((report: ReportListItem) => {\n const pattern = this.createPattern();\n this._router.navigate(\n this._patternCommands(pattern, report.id),\n pattern.startsWith('/') ? {} : { relativeTo: this._route },\n );\n });\n }\n\n // The global Report Settings dialog: the AI knowledge document and the\n // semantic-database build. A running build streams into the FsProcess dock,\n // which survives the dialog closing.\n public openSettings(): void {\n this._dialog.open(GlobalSettingsComponent, {\n width: '900px',\n maxWidth: '95vw',\n maxHeight: '90vh',\n autoFocus: false,\n });\n }\n\n private _initFilterConfig(): void {\n this.filterConfig = {\n items: [\n {\n name: 'keyword',\n type: ItemType.Keyword,\n label: 'Search',\n },\n // A checkbox rather than the usual Status select with a \"Show Deleted\"\n // isolate. Isolating the deleted rows would strand them: a deleted\n // report in a live folder arrives without the folder it sits in, and a\n // tree cannot place a node whose parent it never received. So the\n // toggle asks for everything, and the rows mark what is deleted.\n {\n name: 'state',\n type: ItemType.Checkbox,\n label: 'Show Deleted',\n checked: [ReportState.Active, ReportState.Deleted].join(','),\n },\n ],\n actions: [\n {\n icon: 'unfold_more',\n tooltip: 'Expand all',\n primary: false,\n click: () => this._tree()?.expandAll(),\n },\n {\n icon: 'unfold_less',\n tooltip: 'Collapse all',\n primary: false,\n click: () => this._tree()?.collapseAll(),\n },\n {\n icon: 'settings',\n tooltip: 'Report settings',\n primary: false,\n click: () => this.openSettings(),\n },\n {\n label: 'New Folder',\n primary: false,\n click: () => this._createFolder(null),\n },\n {\n label: 'Create',\n primary: true,\n click: () => this.createReport(),\n },\n ],\n // The two items are answered in different places, and each only when it\n // changed. The keyword drives the tree's own search, which is the whole\n // point of searching a tree — it reveals a match nested inside collapsed\n // folders rather than only filtering what is already on screen. `state` is\n // the Show Deleted toggle, and only the server can answer that. Running the\n // search on a toggle would clear it, and clearing collapses the tree.\n change: (query) => {\n const keywordChanged = String(query?.keyword ?? '') !== String(this._query.keyword ?? '');\n const stateChanged = String(query?.state ?? '') !== String(this._query.state ?? '');\n this._query = { ...query };\n\n if (keywordChanged) {\n this._search(query?.keyword);\n }\n\n if (stateChanged) {\n this._load();\n }\n },\n };\n }\n\n private _initTreeConfig(): void {\n // No expandLevel: every folder starts collapsed.\n this.treeConfig = {\n data: [],\n childrenName: 'children',\n draggable: true,\n // The whole row is the grip and the handle stays hidden; a press only\n // becomes a drag once the pointer moves, so the kebab, the chevron and the\n // report link all stay clickable.\n dragMode: TreeDragMode.Node,\n // Anything deleted is restored before it is moved — the backend refuses\n // to edit a deleted row, and a drag would only snap back.\n canDrag: (node: FlatItemNode) => !this._isDeletedNode(node),\n // canDrop is asked about the node being DRAGGED, so only `toParent`\n // describes the destination — reading node.level/node.parent here would\n // describe where it came from. A report can never be a parent because its\n // type says so, and that single test is the whole \"folders nest, reports\n // are leaves\" rule on this side. A deleted folder is no destination\n // either: whatever landed in it would vanish from the live listing.\n canDrop: (node: FlatItemNode, fromParent: FlatItemNode, toParent: FlatItemNode) => {\n return !toParent || (this._isFolderNode(toParent) && !this._isDeletedNode(toParent));\n },\n changeReorder: (event: ITreeChangeReorder) => this._move(event),\n nodeClass: (node: FlatItemNode) => node.data?.type,\n // Match on the name only. The library's default matcher stringifies the\n // whole node, so it would hit ids, the literal type word, and everything\n // else riding on the row.\n filterItem: (node, query) => {\n return String(node.data?.name ?? '')\n .toLowerCase()\n .includes(String(query ?? '').toLowerCase());\n },\n actions: [\n {\n type: TreeActionType.Menu,\n icon: 'more_vert',\n items: [\n {\n label: 'Rename',\n show: (node: FlatItemNode) => !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._rename(node),\n },\n {\n label: 'New report',\n show: (node: FlatItemNode) => this._isFolderNode(node) && !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this.createReport(node.data?.id),\n },\n {\n label: 'New folder',\n show: (node: FlatItemNode) => this._isFolderNode(node) && !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._createFolder(node.data?.id),\n },\n {\n label: 'Delete',\n show: (node: FlatItemNode) => !this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._delete(node),\n },\n // On every deleted row, including a live one that is only hidden by\n // a deleted folder above it — restoring that brings the folder back.\n {\n label: 'Restore',\n show: (node: FlatItemNode) => this._isDeletedNode(node),\n click: (node: FlatItemNode) => this._restore(node),\n },\n ],\n },\n ],\n };\n }\n\n private _isFolderNode(node: FlatItemNode): boolean {\n return node?.data?.type === ReportNodeType.Folder;\n }\n\n private _isDeletedNode(node: FlatItemNode): boolean {\n return !!node?.data?.deleted;\n }\n\n // Drive the tree's built-in search: it collapses everything, hides every node,\n // then unhides each match and walks its ancestors open, so a report several\n // folders deep surfaces with its path expanded. Clearing collapses everything\n // again, so the folders that were open before the search are put back.\n private _search(keyword: string): void {\n const tree = this._tree();\n if (!tree) {\n return;\n }\n\n if (keyword) {\n this._expandedBeforeSearch ??= this._expandedKeys();\n tree.search(keyword);\n return;\n }\n\n tree.clearSearch();\n this._expandKeys(this._expandedBeforeSearch ?? []);\n this._expandedBeforeSearch = null;\n }\n\n private _load(): void {\n // Only the Show Deleted toggle is the server's to answer — the keyword is\n // the tree's own search — and an unchecked toggle sends nothing, leaving the\n // backend's active-only default in charge.\n const query = this._query.state ? { state: this._query.state } : {};\n\n this._reportData.tree(query)\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((reportTree: ReportTree) => {\n const nodes = this._buildNodes(reportTree);\n this.nodes.set(nodes);\n\n // The tree reads `config` once, in its own ngOnInit. The first load\n // lands before it exists, so the data has to arrive through the config;\n // every later one has to go through the instance or nothing changes.\n this.treeConfig = { ...this.treeConfig, data: nodes };\n\n const tree = this._tree();\n if (!tree) {\n return;\n }\n\n // setData() rebuilds every node collapsed, so a rename or a move would\n // otherwise slam shut every folder somebody had opened. Keys are stable\n // across loads ('f:12'), so what was open is reopened by key — and a\n // folder that no longer comes back simply is not.\n const expandedKeys = this._expandedKeys();\n tree.setData(nodes);\n this._expandKeys(expandedKeys);\n\n const keyword = String(this._query.keyword ?? '');\n if (keyword) {\n tree.search(keyword);\n }\n });\n }\n\n // The keys of every open folder, walked through the tree's public node API.\n private _expandedKeys(): string[] {\n const tree = this._tree();\n if (!tree) {\n return [];\n }\n\n const walk = (parent: FlatItemNode): string[] => tree.getNodes(parent)\n .filter((node: FlatItemNode) => node.isExpanded())\n .flatMap((node: FlatItemNode) => [node.data?.key, ...walk(node)]);\n\n return walk(null);\n }\n\n private _expandKeys(keys: string[]): void {\n const tree = this._tree();\n if (!tree || !keys.length) {\n return;\n }\n\n const open = new Set(keys);\n const walk = (parent: FlatItemNode): void => {\n tree.getNodes(parent)\n .filter((node: FlatItemNode) => open.has(node.data?.key))\n .forEach((node: FlatItemNode) => {\n node.expand();\n walk(node);\n });\n };\n\n walk(null);\n }\n\n // Flat API rows → the nested shape fs-tree renders. Folders come before\n // reports at every level, each already name-ordered by the backend.\n //\n // `deleted` is inherited downward: a deleted folder hides everything below it\n // without the rows below being deleted themselves, and that is only visible\n // from here, where the parent is in hand. The backend applies the same rule\n // when it filters (ReportFolderModel::getDeletedFolderIds()).\n private _buildNodes(reportTree: ReportTree): ReportNode[] {\n const folders = reportTree?.folders ?? [];\n const reports = reportTree?.reports ?? [];\n\n const build = (parentId: number | null, parentDeleted: boolean): ReportNode[] => {\n const folderNodes: ReportNode[] = folders\n .filter((folder: ReportFolder) => (folder.parentReportFolderId ?? null) === parentId)\n .map((folder: ReportFolder) => {\n const stateDeleted = folder.state === ReportState.Deleted;\n const deleted = parentDeleted || stateDeleted;\n\n return {\n key: `f:${folder.id}`,\n id: folder.id,\n name: folder.name,\n type: ReportNodeType.Folder,\n children: build(folder.id, deleted),\n stateDeleted,\n deleted,\n };\n });\n\n const reportNodes: ReportNode[] = reports\n .filter((report: ReportListItem) => (report.reportFolderId ?? null) === parentId)\n .map((report: ReportListItem) => {\n const stateDeleted = report.state === ReportState.Deleted;\n\n return {\n key: `r:${report.id}`,\n id: report.id,\n name: report.name,\n type: ReportNodeType.Report,\n children: [],\n report,\n stateDeleted,\n deleted: parentDeleted || stateDeleted,\n };\n });\n\n return [...folderNodes, ...reportNodes];\n };\n\n return build(null, false);\n }\n\n // A drop moved a node under a new parent, or out to the root. The tree has\n // already moved it on screen, so both outcomes reload: a success to pick up\n // the server's ordering, a failure to put the row back where it really is.\n private _move(event: ITreeChangeReorder): void {\n const node: ReportNode = event.node?.data;\n if (!node) {\n return;\n }\n\n const parentReportFolderId: number = event.toParent?.data?.id ?? null;\n\n if (event.toParent && !event.toParent.isExpanded()) {\n event.toParent.expand();\n }\n\n const save$: Observable<unknown> = node.type === ReportNodeType.Folder\n ? this._reportData.updateFolder(node.id, { parentReportFolderId })\n : this._reportData.moveReport(node.id, parentReportFolderId);\n\n save$\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe({\n next: () => {\n this._message.success('Saved changes');\n this._load();\n },\n error: () => this._load(),\n });\n }\n\n private _createFolder(parentReportFolderId: number): void {\n this._prompt.input({\n title: 'New Folder',\n label: 'Name',\n commitLabel: 'Create',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData.createFolder(name, parentReportFolderId)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Created folder');\n this._load();\n });\n }\n\n private _rename(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n const folder = data.type === ReportNodeType.Folder;\n\n this._prompt.input({\n title: folder ? 'Rename Folder' : 'Rename Report',\n label: 'Name',\n default: data.name,\n commitLabel: 'Save',\n required: true,\n })\n .pipe(\n switchMap((name: string) => (folder\n ? this._reportData.updateFolder(data.id, { name })\n : this._reportData.rename(data.id, name))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Saved changes');\n this._load();\n });\n }\n\n // A folder deletes with everything in it, so the confirm says what that is —\n // and that it all comes back from Show Deleted, which is what makes it safe to\n // offer.\n private _delete(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n const folder = data.type === ReportNodeType.Folder;\n\n this._prompt.confirm({\n title: 'Confirm',\n template: folder\n ? this._deleteFolderMessage(data)\n : 'Are you sure you would like to delete this report?',\n })\n .pipe(\n switchMap(() => (folder\n ? this._reportData.deleteFolder(data.id)\n : this._reportData.delete(data.id))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success(folder ? 'Deleted folder' : 'Deleted report');\n this._load();\n });\n }\n\n // Counted from the node already on screen, live rows only: in Show Deleted\n // mode the folder can also hold rows that are gone already, and those are not\n // leaving with it.\n private _deleteFolderMessage(folder: ReportNode): string {\n const count = (node: ReportNode): { folders: number; reports: number } => node.children\n .filter((child) => !child.deleted)\n .reduce((total, child) => {\n const below = count(child);\n\n return {\n folders: total.folders + below.folders + (child.type === ReportNodeType.Folder ? 1 : 0),\n reports: total.reports + below.reports + (child.type === ReportNodeType.Report ? 1 : 0),\n };\n }, { folders: 0, reports: 0 });\n\n const { folders, reports } = count(folder);\n const contents = [\n folders ? `${folders} ${folders === 1 ? 'folder' : 'folders'}` : '',\n reports ? `${reports} ${reports === 1 ? 'report' : 'reports'}` : '',\n ].filter(Boolean);\n\n const inside = contents.length ? ` and the ${contents.join(' and ')} inside it` : '';\n\n return `Are you sure you would like to delete the folder \"${folder.name}\"${inside}? It can be restored from Show Deleted.`;\n }\n\n // Both endpoints also restore any deleted folder above the row, so a row that\n // is live itself but hidden by a deleted folder is restored by the same call.\n private _restore(node: FlatItemNode): void {\n const data: ReportNode = node?.data;\n if (!data) {\n return;\n }\n\n const folder = data.type === ReportNodeType.Folder;\n\n (folder\n ? this._reportData.undeleteFolder(data.id)\n : this._reportData.undelete(data.id))\n .pipe(\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success(folder ? 'Restored folder' : 'Restored report');\n this._load();\n });\n }\n\n // Turn a ':id' pattern into router commands. Relative unless it starts\n // with '/', in which case the first segment carries the leading slash.\n private _patternCommands(pattern: string, id: number): unknown[] {\n const absolute = pattern.startsWith('/');\n const segments: unknown[] = pattern.split('/')\n .filter((segment) => segment.length > 0)\n .map((segment) => (segment === ':id' ? id : segment));\n\n if (!segments.length) {\n return [id];\n }\n\n if (absolute) {\n segments[0] = `/${segments[0]}`;\n }\n\n return segments;\n }\n}\n","<fs-filter [config]=\"filterConfig\"></fs-filter>\n\n<ng-container *fsSkeleton=\"nodes()\">\n <fs-tree [config]=\"treeConfig\">\n <ng-template\n fsTreeNode\n let-data=\"data\">\n <div\n class=\"fs-row.gap-sm.align-center node-row\"\n [class.deleted]=\"data.deleted\">\n <mat-icon class=\"node-icon\">\n {{ data.type === nodeType.Folder ? 'folder' : 'insert_chart_outlined' }}\n </mat-icon>\n\n @if (data.type === nodeType.Folder || data.deleted) {\n <!-- A deleted report can't be opened (the backend only assembles\n live ones, and one under a deleted folder is not on the live\n listing), so in Show Deleted mode the name is plain text —\n restore it from the row menu first. -->\n <span class=\"node-name\">{{ data.name }}</span>\n } @else {\n <a\n class=\"node-name\"\n [routerLink]=\"openLink(data.report)\">\n {{ data.name }}\n </a>\n }\n\n <!-- Only on the row somebody deleted. Everything under a deleted\n folder is muted with it, but was not deleted itself. -->\n @if (data.stateDeleted) {\n <fs-chip size=\"tiny\">Deleted</fs-chip>\n }\n </div>\n </ng-template>\n </fs-tree>\n\n @if (!nodes().length) {\n <p class=\"small tree-empty\">\n No reports yet. Create one, or add a folder to group them.\n </p>\n }\n</ng-container>\n","import { CanvasLandingInput } from './interfaces/canvas-landing-input.interface';\n\n\n// Which page the canvas opens when its report input changes.\n//\n// - The same report with more pages than before: a page was just added in\n// this tab, so the canvas lands on the last page. The asked-for page does\n// not beat it: that is a stale value the host still holds.\n// - Otherwise the asked-for page (a ?page= the report opened with), when the\n// report has it.\n// - Another report that asks for no page it has opens on its first page:\n// the old report's page number means nothing there.\n// - The same report keeps the page it shows when the asked-for page does not\n// resolve (it may still be loading); an index past the last page falls\n// back to the first.\nexport function canvasLandingPage(input: CanvasLandingInput): number {\n const pageCount = input.pageIds.length;\n const sameReport = input.reportId === input.previousReportId;\n\n if (sameReport && input.previousPageCount > 0 && pageCount > input.previousPageCount) {\n return pageCount - 1;\n }\n\n const linked = input.pageId == null ? -1 : input.pageIds.indexOf(input.pageId);\n if (linked > -1) {\n return linked;\n }\n\n const index = sameReport ? input.activePageIndex : 0;\n\n return index < pageCount ? index : 0;\n}\n","// How a time axis writes its period labels: short ('May', with the year on a\n// second line when the data spans years), long ('May 2026', in the report's\n// locale) or numeric ('2026-05', the same in every locale). A category axis\n// prints its values as they are.\n//\n// Mirrors the server's ChartDateLabelEnum value for value.\nexport enum ReportChartDateLabel {\n Short = 'short',\n Long = 'long',\n Numeric = 'numeric',\n}\n","// A chart measure's named color. The names follow the report chart palette in\n// order (REPORT_CHART_COLOR_BY_NAME), so blue is the first series' default\n// color and gray the tenth's.\n//\n// Mirrors the server's ChartColorEnum value for value, in the same order.\nexport enum ReportChartColor {\n Blue = 'blue',\n Orange = 'orange',\n Red = 'red',\n Teal = 'teal',\n Green = 'green',\n Yellow = 'yellow',\n Purple = 'purple',\n Pink = 'pink',\n Brown = 'brown',\n Gray = 'gray',\n}\n","// Which points of a chart's series print their value beside them: none, every\n// point, only each series' last point, or every point with the overlapping\n// labels hidden (auto). Axis charts only.\n//\n// Mirrors the server's ChartDataLabelsEnum value for value.\nexport enum ReportChartDataLabels {\n None = 'none',\n All = 'all',\n Last = 'last',\n Auto = 'auto',\n}\n","// How a line series' line is drawn; the server refuses a non-solid line on\n// an area series. The values are ECharts'\n// lineStyle.type values, so the screen takes them as they are.\n//\n// Mirrors the server's ChartLineStyleEnum value for value.\nexport enum ReportChartLineStyle {\n Solid = 'solid',\n Dashed = 'dashed',\n Dotted = 'dotted',\n}\n","// The statistic of a series a chart measure draws as a horizontal line across\n// the plot: its average, median, lowest or highest value.\n//\n// Mirrors the server's ChartMarkStatEnum value for value.\nexport enum ReportChartMarkStat {\n Average = 'average',\n Median = 'median',\n Min = 'min',\n Max = 'max',\n}\n","// How a list column's cells are shown: a list column's `format`. date renders\n// a raw timestamp as a day in the report's zone and locale; number, percent\n// and currency format the value as a KPI measure does (ReportValueFormat). A\n// column without a format prints its value as it came.\n//\n// Mirrors the server's ListColumnFormatEnum value for value.\nexport enum ReportListColumnFormat {\n Date = 'date',\n Number = 'number',\n Percent = 'percent',\n Currency = 'currency',\n}\n","// How a formatted number is abbreviated: a number slot's `units`. thousands\n// writes 1,200 as 1.2K and millions 3,400,000 as 3.4M; auto picks by size\n// (once per chart on a value axis, per value everywhere else); none, like no\n// units at all, writes the full number. Units never apply to a percent.\n//\n// Mirrors the server's NumberUnitsEnum value for value.\nexport enum ReportNumberUnits {\n None = 'none',\n Thousands = 'thousands',\n Millions = 'millions',\n Auto = 'auto',\n}\n","// How a measure's value is shown: a chart measure's and a KPI measure's\n// `format`. The data stays raw; only the renderers format it. percent takes a\n// 0-1 ratio (0.3 reads 30%) when the report's percentFormat is 'ratio', and\n// currency labels the amount in the report's currency (nothing is converted).\n//\n// Mirrors the server's ValueFormatEnum value for value.\nexport enum ReportValueFormat {\n Number = 'number',\n Percent = 'percent',\n Currency = 'currency',\n}\n","import { addDays, isValid, parseISO } from 'date-fns';\nimport { toZonedTime } from 'date-fns-tz';\n\nimport { ReportListColumnFormat } from './enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from './enums/report-number-units.enum';\nimport { ReportValueFormat } from './enums/report-value-format.enum';\nimport {\n ChartGranularity,\n ChartMeasure,\n ComparisonAgainst,\n ComparisonNoteCode,\n ComparisonOffset,\n ComparisonWindow,\n ComponentComparison,\n KpiNoteCode,\n NumberFormatSpec,\n OutputMeta,\n OutputRole,\n Report,\n ReportCurrencyCode,\n ReportFormatContext,\n ReportLocaleTag,\n WindowMeta,\n WindowNoteCode,\n} from './interfaces/report.interface';\n\n\n// What a report reads when the server names no usable locale or currency: an\n// older server that sends neither, or a value this browser's Intl cannot use.\n// Never the browser's own locale, so every viewer of a report sees the same text.\nexport const REPORT_FALLBACK_LOCALE: ReportLocaleTag = 'en-US';\nexport const REPORT_FALLBACK_CURRENCY: ReportCurrencyCode = 'USD';\n\nexport const DEFAULT_FORMAT_CONTEXT: Readonly<ReportFormatContext> = Object.freeze({\n locale: REPORT_FALLBACK_LOCALE,\n currency: REPORT_FALLBACK_CURRENCY,\n ratioPercent: true,\n});\n\nconst CURRENCY_PATTERN = /^[A-Z]{3}$/;\n\n\n// The server's resolved locale as one this browser can format in. A malformed\n// tag ('en_CA') makes supportedLocalesOf throw, and one Intl has no data for\n// ('xx-YY') comes back empty; both read the fallback.\nexport function resolveReportLocale(tag: string | null | undefined): ReportLocaleTag {\n if (!tag) {\n return REPORT_FALLBACK_LOCALE;\n }\n\n try {\n return Intl.NumberFormat.supportedLocalesOf([tag])[0] ?? REPORT_FALLBACK_LOCALE;\n } catch {\n return REPORT_FALLBACK_LOCALE;\n }\n}\n\n// The server's resolved currency as one Intl can label. The server decides\n// which codes name money; this only guards against a code Intl cannot take at\n// all. It is never checked against the runtime's own currency list, which\n// differs between browsers and leaves out codes the server offers (VEF, MRO),\n// so every viewer labels a report's money the same way.\nexport function resolveReportCurrency(code: string | null | undefined): ReportCurrencyCode {\n if (!code || !CURRENCY_PATTERN.test(code)) {\n return REPORT_FALLBACK_CURRENCY;\n }\n\n try {\n numberFormat(REPORT_FALLBACK_LOCALE, { style: 'currency', currency: code });\n\n return code;\n } catch {\n return REPORT_FALLBACK_CURRENCY;\n }\n}\n\n// The one place a report's format context is built: the server's effective\n// locale and currency (absent on an older server, which then reads en-US/USD)\n// and whether its percent measures arrive as 0-1 ratios.\nexport function resolveFormatContext(\n report: Pick<Report, 'effectiveLocale' | 'effectiveCurrency' | 'percentFormat'>,\n): ReportFormatContext {\n return {\n locale: resolveReportLocale(report.effectiveLocale),\n currency: resolveReportCurrency(report.effectiveCurrency),\n ratioPercent: report.percentFormat === 'ratio',\n };\n}\n\n\n// Building an Intl formatter is far slower than using one, and a chart formats\n// every tick and tooltip value, so each distinct locale + options (+ zone) is\n// built once and reused.\nconst NUMBER_FORMATS = new Map<string, Intl.NumberFormat>();\nconst DATE_FORMATS = new Map<string, Intl.DateTimeFormat>();\n\nexport function numberFormat(locale: string, options: Intl.NumberFormatOptions): Intl.NumberFormat {\n const key = `${locale}|${JSON.stringify(options)}`;\n let formatter = NUMBER_FORMATS.get(key);\n\n if (!formatter) {\n formatter = new Intl.NumberFormat(locale, options);\n NUMBER_FORMATS.set(key, formatter);\n }\n\n return formatter;\n}\n\n// No zone formats in the browser's own zone, which is right for a calendar day\n// parsed as local midnight: the day printed is the day stored.\nexport function dateFormat(\n locale: string,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): Intl.DateTimeFormat {\n const key = `${locale}|${JSON.stringify(options)}|${timeZone ?? ''}`;\n let formatter = DATE_FORMATS.get(key);\n\n if (!formatter) {\n formatter = new Intl.DateTimeFormat(locale, { ...options, timeZone });\n DATE_FORMATS.set(key, formatter);\n }\n\n return formatter;\n}\n\n\n// Number formatting: the one engine behind every numeric slot (a chart\n// measure, a KPI measure, a list column, a cross-tab's cells), so a format\n// means the same thing on screen, in the PDF and in PowerPoint. The data stays\n// raw; only what is shown changes. The rules:\n// - Empty: null, undefined, '', '-' and a non-finite number print the caller's\n// `empty` ('—' unless it names another).\n// - Numeric: a finite number, or a string that spells one plainly ('1234.50',\n// '-3e2'). Anything else ('$1,234', an id with letters, ' ') prints as it\n// came, since a column the SQL already formatted is text.\n// - Styles: number is a plain decimal; currency is the report's currency\n// written in its locale with its symbol (USD reads '$1,235' in en-US and\n// 'US$1,235' in en-CA; EUR reads '1 235 €' in fr-FR); percent takes a 0-1\n// ratio (0.3 reads 30%), or, from an older server that sends percent values\n// already x100, a decimal with a % sign. Precision or units without a format\n// mean number.\n// - Decimals: a precision pins both the minimum and the maximum, so a column\n// of rates lines up. Without one: at most one for a percent and for an\n// abbreviated value (1.2K), whole units for currency, the locale's default\n// for a number.\n// - Units: thousands and millions divide and add a K or M after the digits\n// ('$1.2K', '1,2K $'); auto picks per value by size, and a value that would\n// round to 1000K reads 1M. Units never apply to a percent.\n// - Negatives keep the locale's leading minus. A negative that rounds to zero\n// prints as zero, never '-0'.\n// - Rounding is Intl's, on the digits shown. Every value is written in the\n// context's locale, never the browser's.\n\n// The most decimals a precision pins: the server's schema bound.\nconst MAX_PRECISION = 6;\n// At most one decimal for a percent, and for an abbreviated value (1.2K).\nconst PERCENT_DECIMALS = 1;\nconst SCALED_DECIMALS = 1;\n// Money shows whole units unless a precision asks for decimals.\nconst CURRENCY_DECIMALS = 0;\n// A currency axis whose ticks need decimals shows cents, not tenths.\nconst CURRENCY_AXIS_DECIMALS = 2;\n// What a missing value prints unless the caller names its own.\nconst EMPTY_VALUE = '—';\n// The tick count a value axis aims for, as ECharts' splitNumber default.\nconst AXIS_TICKS = 5;\n\n// A change's sign: a plus on a positive value, nothing on zero.\nconst SIGNED: Intl.NumberFormatOptions = { signDisplay: 'exceptZero' };\n\nconst NUMERIC_PATTERN = /^\\s*[-+]?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?\\s*$/;\n// The formatToParts types that carry a number's digits and separators.\nconst NUMBER_PARTS = new Set<Intl.NumberFormatPartTypes>(['integer', 'group', 'decimal', 'fraction']);\nconst DIGIT_PARTS = new Set<Intl.NumberFormatPartTypes>(['integer', 'fraction']);\n\n// A numeric format's units once decided: auto is resolved to one of these.\nexport type ResolvedUnits = ReportNumberUnits.None | ReportNumberUnits.Thousands | ReportNumberUnits.Millions;\n\ninterface UnitScale {\n divisor: number;\n suffix: string;\n // The PowerPoint/Excel scaling commas: each one divides by 1,000.\n commas: string;\n}\n\nconst UNIT_SCALES = new Map<ResolvedUnits, UnitScale>([\n [ReportNumberUnits.Thousands, { divisor: 1e3, suffix: 'K', commas: ',' }],\n [ReportNumberUnits.Millions, { divisor: 1e6, suffix: 'M', commas: ',,' }],\n]);\n\nexport interface FormatNumberOptions {\n // What an empty value prints: '—' for a KPI or a tooltip, '' for a cell.\n empty?: string;\n // Units already decided for the whole chart, in place of the spec's own.\n units?: ResolvedUnits;\n // Decimals already decided for the whole chart, pinned as min and max. null\n // leaves the spec's own.\n decimals?: number | null;\n // Writes a plus before a positive value, as a change reads ('+12%'). Zero,\n // and a value whose shown digits are all zero, stays unsigned.\n signed?: boolean;\n}\n\n// How a chart's value axis writes its ticks, decided once per chart.\nexport interface ChartNumberFormat {\n units: ResolvedUnits;\n // Pinned decimals, or null for a plain number whose ticks keep their own.\n decimals: number | null;\n}\n\n// The value as a finite number when it is one or plainly spells one, else\n// null.\nexport function toFiniteNumber(value: unknown): number | null {\n if (typeof value === 'number') {\n return Number.isFinite(value) ? value : null;\n }\n\n if (typeof value !== 'string' || !NUMERIC_PATTERN.test(value)) {\n return null;\n }\n\n const numeric = Number(value);\n\n return Number.isFinite(numeric) ? numeric : null;\n}\n\n// Whether a slot asks to be formatted at all. A slot without these keys, or a\n// list column whose format is date, keeps its own rendering. Units none is the\n// same as no units key, as it is on the server.\nexport function hasNumberFormat(spec?: NumberFormatSpec | null): boolean {\n if (!spec || spec.format === ReportListColumnFormat.Date) {\n return false;\n }\n\n return valueFormat(spec) !== null\n || (spec.precision ?? null) !== null\n || ((spec.units ?? ReportNumberUnits.None) !== ReportNumberUnits.None);\n}\n\n// The units a value is written in. auto decides by the magnitude: a million\n// and up reads M, a thousand and up K, unless the value would then round to\n// 1000K at these decimals, which reads 1M instead.\nexport function resolveUnits(\n units: ReportNumberUnits | null | undefined,\n magnitude: number,\n decimals: number,\n): ResolvedUnits {\n switch (units) {\n case ReportNumberUnits.Thousands:\n case ReportNumberUnits.Millions:\n return units;\n case ReportNumberUnits.Auto:\n return autoUnits(Math.abs(magnitude), decimals);\n default:\n return ReportNumberUnits.None;\n }\n}\n\nfunction autoUnits(magnitude: number, decimals: number): ResolvedUnits {\n if (magnitude >= 1e6) {\n return ReportNumberUnits.Millions;\n }\n\n if (magnitude < 1e3) {\n return ReportNumberUnits.None;\n }\n\n return roundTo(magnitude / 1e3, decimals) >= 1000\n ? ReportNumberUnits.Millions\n : ReportNumberUnits.Thousands;\n}\n\n// The value rounded as Intl rounds it for display, so the K-to-M promotion\n// agrees with the digits actually shown.\nfunction roundTo(value: number, decimals: number): number {\n const digits = clampDecimals(decimals) ?? 0;\n\n // A fixed locale only so Number() can parse the rounded digits back.\n return Number(numberFormat(REPORT_FALLBACK_LOCALE, {\n useGrouping: false,\n minimumFractionDigits: 0,\n maximumFractionDigits: digits,\n }).format(value));\n}\n\n// One value, written by the rules above.\nexport function formatNumber(\n value: unknown,\n spec: NumberFormatSpec | null | undefined,\n context: ReportFormatContext,\n options: FormatNumberOptions = {},\n): string {\n if (isEmptyValue(value)) {\n return options.empty ?? EMPTY_VALUE;\n }\n\n const numeric = toFiniteNumber(value);\n if (numeric === null) {\n return String(value);\n }\n\n const style = resolveStyle(spec);\n const precision = clampDecimals(spec?.precision);\n const units = style === ReportValueFormat.Percent\n ? ReportNumberUnits.None\n : options.units ?? resolveUnits(spec?.units, numeric, precision ?? SCALED_DECIMALS);\n const scale = UNIT_SCALES.get(units);\n const decimals = clampDecimals(options.decimals) ?? precision;\n const formatter = numberFormat(context.locale, {\n ...styleOptions(style, context, decimals, !!scale),\n ...(options.signed ? SIGNED : {}),\n });\n const text = writeNumber(formatter, (numeric === 0 ? 0 : numeric) / (scale?.divisor ?? 1), scale?.suffix);\n\n return style === ReportValueFormat.Percent && !context.ratioPercent ? `${text}%` : text;\n}\n\nfunction isEmptyValue(value: unknown): boolean {\n return value === null\n || value === undefined\n || value === ''\n || value === '-'\n || (typeof value === 'number' && !Number.isFinite(value));\n}\n\n// The value format a slot names, or null when it names none (or only date).\nfunction valueFormat(spec: NumberFormatSpec | null | undefined): ReportValueFormat | null {\n return Object.values(ReportValueFormat).find((format) => format === spec?.format) ?? null;\n}\n\nfunction resolveStyle(spec: NumberFormatSpec | null | undefined): ReportValueFormat {\n return valueFormat(spec) ?? ReportValueFormat.Number;\n}\n\n// A usable decimal count, or null. A stored value outside the schema's bounds\n// is brought inside them rather than thrown on by Intl.\nfunction clampDecimals(decimals: number | null | undefined): number | null {\n return typeof decimals === 'number' && Number.isFinite(decimals)\n ? Math.min(MAX_PRECISION, Math.max(0, Math.round(decimals)))\n : null;\n}\n\nfunction styleOptions(\n style: ReportValueFormat,\n context: ReportFormatContext,\n decimals: number | null,\n scaled: boolean,\n): Intl.NumberFormatOptions {\n const fractionDigits = fractionDigitOptions(decimals, defaultDecimals(style, scaled));\n\n switch (style) {\n case ReportValueFormat.Currency:\n return { ...currencyOptions(context.currency), ...fractionDigits };\n case ReportValueFormat.Percent:\n return context.ratioPercent ? { style: 'percent', ...fractionDigits } : fractionDigits;\n default:\n return fractionDigits;\n }\n}\n\nfunction currencyOptions(currency: ReportCurrencyCode): Intl.NumberFormatOptions {\n return { style: 'currency', currency, currencyDisplay: 'symbol' };\n}\n\n// The most decimals a style shows when nothing pins them; null leaves Intl's\n// own default.\nfunction defaultDecimals(style: ReportValueFormat, scaled: boolean): number | null {\n if (scaled) {\n return SCALED_DECIMALS;\n }\n\n switch (style) {\n case ReportValueFormat.Percent:\n return PERCENT_DECIMALS;\n case ReportValueFormat.Currency:\n return CURRENCY_DECIMALS;\n default:\n return null;\n }\n}\n\n// Pinned decimals set both bounds. Otherwise a maximum also sets the minimum\n// to zero, so no engine throws on a maximum below a currency's own minimum.\nfunction fractionDigitOptions(pinned: number | null, maximum: number | null): Intl.NumberFormatOptions {\n if (pinned !== null) {\n return { minimumFractionDigits: pinned, maximumFractionDigits: pinned };\n }\n\n return maximum === null ? {} : { minimumFractionDigits: 0, maximumFractionDigits: maximum };\n}\n\n// The formatted value, with the units letter after its digits. A negative\n// whose shown digits are all zero is written as zero, so no '-0' appears.\nfunction writeNumber(formatter: Intl.NumberFormat, value: number, suffix?: string): string {\n if (value >= 0 && !suffix) {\n return formatter.format(value);\n }\n\n const parts = formatter.formatToParts(value);\n\n if (value < 0 && !hasNonZeroDigit(formatter, parts)) {\n return writeNumber(formatter, 0, suffix);\n }\n\n if (!suffix) {\n return parts.map((part) => part.value).join('');\n }\n\n const last = parts.reduce((found, part, index) => NUMBER_PARTS.has(part.type) ? index : found, -1);\n\n return [\n ...parts.slice(0, last + 1).map((part) => part.value),\n suffix,\n ...parts.slice(last + 1).map((part) => part.value),\n ].join('');\n}\n\n// Compared with the locale's own zero, so a numbering system other than\n// 0-9 is read correctly.\nfunction hasNonZeroDigit(formatter: Intl.NumberFormat, parts: Intl.NumberFormatPart[]): boolean {\n const zero = formatter.formatToParts(0).find((part) => part.type === 'integer')?.value ?? '0';\n\n return parts.some((part) => DIGIT_PARTS.has(part.type)\n && Array.from(part.value).some((character) => character !== zero));\n}\n\n\n// Output values: a column the server marks in ComponentData.outputs (a\n// compared value, a rank, a share) written by what it is. The data stays raw;\n// every number still goes through formatNumber. The rules:\n// - The format: a slot's own explicit format always wins. Otherwise a current,\n// prior or change column takes its source measure's format; a percent change\n// is a percent; a rank is a whole number; a share is a percent to 1 decimal.\n// An own precision or units still applies over those defaults.\n// - Signs: a change and a percent change are signed ('+579', '-31.1%'),\n// unless the caller's `signed` says otherwise.\n// - Points: a change of a percent-format value, and any share change, is a\n// difference of two rates, so it prints in percentage points, signed and to\n// 1 decimal unless a precision pins others: 0.1 reads '+10.0 pp' ('+10.0'\n// when the caller's `pointsUnit` is false).\n// - Missing: a missing prior, or a change or percent change left empty by\n// one, prints '—' titled with the floor ('No baseline: no data before\n// Mar 3, 2026'), or for a rank or a share with the period the row was\n// absent from ('No rank in the prior period'); a percent change over a prior of 0 prints 'n/a' titled\n// 'Prior was 0'. Any other missing value prints '—' (or the caller's empty).\n// - Rank change: prior minus current, so a rise is positive: '▲ 2', '▼ 1',\n// '–' for none, and 'new' for an empty change whose prior rank is missing\n// or not passed (a row always has a current rank, so only the prior lacks).\n// A percent change and a share are 0-1 fractions whatever the report's\n// percentFormat: the server computes them, never a stored value.\n\n// A missing comparison value prints EMPTY_VALUE whatever the caller's empty.\nconst NOT_APPLICABLE_VALUE = 'n/a';\nconst NEW_RANK_VALUE = 'new';\nconst RANK_UNCHANGED_VALUE = '–';\nconst RANK_UP_MARK = '▲';\nconst RANK_DOWN_MARK = '▼';\nconst POINTS_SUFFIX = 'pp';\nconst NO_PRIOR_RANK_TITLE = 'No rank in the prior period';\nconst NO_PRIOR_SHARE_TITLE = 'No share in the prior period';\n// Percentage points and a share are written to one decimal unless pinned.\nconst POINTS_DECIMALS = 1;\nconst SHARE_DECIMALS = 1;\n\nconst RANK_DEFAULT_SPEC: Readonly<NumberFormatSpec> = Object.freeze({ format: ReportValueFormat.Number, precision: 0 });\nconst SHARE_DEFAULT_SPEC: Readonly<NumberFormatSpec> = Object.freeze({\n format: ReportValueFormat.Percent,\n precision: SHARE_DECIMALS,\n});\nconst PERCENT_CHANGE_DEFAULT_SPEC: Readonly<NumberFormatSpec> = Object.freeze({ format: ReportValueFormat.Percent });\n\nexport interface OutputValueOptions {\n // The source measure's format (OutputMeta.measure's slot), which a current,\n // prior or change column takes when its own slot names none.\n measureSpec?: NumberFormatSpec | null;\n // The row's prior value in the same lane (see laneOutputAlias), for a change\n // or a percent change: it tells a missing baseline ('—') from a zero one\n // ('n/a'), and a new rank from an unranked row. Leave it out when unknown.\n prior?: unknown;\n // ComponentData.comparison.floor: the first day with data, named in the\n // no-baseline title.\n floor?: string | null;\n // What a missing current or plain value prints ('' for a cell). A missing\n // comparison value always prints '—'.\n empty?: string;\n // Whether the value prints a plus when positive, over its role's default (a\n // change and a percent change are signed, nothing else is). A formula value\n // sets it from its own `signed`, so it can drop a change's sign or ask a\n // plain output for one.\n signed?: boolean;\n // Whether a change in percentage points ends in ' pp'. Omitted reads true.\n // A value inside text passes false: the words around its token carry the\n // unit ('pts', 'days faster').\n pointsUnit?: boolean;\n}\n\n// An output value as shown, and why it reads so when that is not obvious\n// (null otherwise): for a tooltip or a title attribute.\nexport interface FormattedOutputValue {\n text: string;\n title: string | null;\n}\n\n// One output value, written by the rules above. Without output metadata (a\n// plain measure column, an older server) it is formatNumber with the slot's\n// own format.\nexport function formatOutputValue(\n value: unknown,\n output: OutputMeta | null | undefined,\n spec: NumberFormatSpec | null | undefined,\n context: ReportFormatContext,\n options: OutputValueOptions = {},\n): FormattedOutputValue {\n if (!output) {\n return plainOutput(formatNumber(value, spec, context, { empty: options.empty }));\n }\n\n if (output.kind === 'rank' && output.role === 'change') {\n return formatRankChange(value, spec, context, options);\n }\n\n const role = output.role;\n const effective = outputFormatSpec(output, spec, options.measureSpec);\n\n if (isEmptyValue(value)) {\n return missingOutput(output, context, options);\n }\n\n const signed = options.signed ?? (role === 'change' || role === 'percent_change');\n\n if (role === 'change' && isPointsChange(output, effective)) {\n return plainOutput(formatPoints(value, output, effective, context, options.pointsUnit ?? true, signed));\n }\n\n const ratioContext = role === 'percent_change' || output.kind === 'share'\n ? { ...context, ratioPercent: true }\n : context;\n\n return plainOutput(formatNumber(value, effective, ratioContext, { signed }));\n}\n\n// The alias of the output that plays `role` in the same lane as `alias`: the\n// same measure and kind, and (for a prior, change or percent change) the same\n// prior lane. A measure compares against one lane only (two compares on one\n// value are two measures), so a current value's lane is whichever one its\n// measure's prior columns carry, lane 2 as readily as lane 1. A change column\n// finds its prior this way to pass as OutputValueOptions.prior. null when the\n// server sends no such column.\nexport function laneOutputAlias(\n outputs: Record<string, OutputMeta> | null | undefined,\n alias: string,\n role: OutputRole,\n): string | null {\n const source = outputs?.[alias];\n\n if (!source) {\n return null;\n }\n\n const anyLane = source.role === 'current' || source.offset === null;\n const found = Object.entries(outputs ?? {}).find(([, meta]) => meta.measure === source.measure\n && meta.kind === source.kind\n && meta.role === role\n && (role === 'current' || (anyLane ? meta.offset !== null : meta.offset === source.offset)));\n\n return found ? found[0] : null;\n}\n\nfunction plainOutput(text: string): FormattedOutputValue {\n return { text, title: null };\n}\n\n// The format an output is written in: the slot's own explicit format, else\n// the default for what it holds, with any own precision or units over it.\nfunction outputFormatSpec(\n output: OutputMeta,\n own: NumberFormatSpec | null | undefined,\n measureSpec: NumberFormatSpec | null | undefined,\n): NumberFormatSpec | null {\n if (valueFormat(own) !== null) {\n return own;\n }\n\n if (output.kind === 'rank') {\n return withOwnDigits(RANK_DEFAULT_SPEC, own);\n }\n\n if (output.kind === 'share') {\n return withOwnDigits(SHARE_DEFAULT_SPEC, own);\n }\n\n if (output.role === 'percent_change') {\n return withOwnDigits(PERCENT_CHANGE_DEFAULT_SPEC, own);\n }\n\n return measureSpec ? withOwnDigits(measureSpec, own) : own ?? null;\n}\n\n// The base format with the slot's own precision and units over it.\nfunction withOwnDigits(base: NumberFormatSpec, own: NumberFormatSpec | null | undefined): NumberFormatSpec {\n return {\n ...base,\n ...((own?.precision ?? null) !== null ? { precision: own.precision } : {}),\n ...((own?.units ?? null) !== null ? { units: own.units } : {}),\n };\n}\n\n// A change between two rates: a share's, or a percent-format value's.\nfunction isPointsChange(output: OutputMeta, spec: NumberFormatSpec | null): boolean {\n return output.kind === 'share' || resolveStyle(spec) === ReportValueFormat.Percent;\n}\n\n// A rate change in percentage points. A share and a 0-1 percent are scaled\n// x100; an older server's percent values already are. `unit` writes the ' pp'\n// after the digits, and `signed` the plus before a rise.\nfunction formatPoints(\n value: unknown,\n output: OutputMeta,\n spec: NumberFormatSpec | null,\n context: ReportFormatContext,\n unit: boolean,\n signed: boolean,\n): string {\n const numeric = toFiniteNumber(value);\n if (numeric === null) {\n return String(value);\n }\n\n const points = output.kind === 'share' || context.ratioPercent ? numeric * 100 : numeric;\n const decimals = clampDecimals(spec?.precision) ?? POINTS_DECIMALS;\n const text = formatNumber(points, { format: ReportValueFormat.Number }, context, { decimals, signed });\n\n return unit ? `${text} ${POINTS_SUFFIX}` : text;\n}\n\n// A missing output value. A missing prior, or a delta a missing prior left\n// empty, has no baseline; a percent change over a zero prior has none to\n// divide by.\nfunction missingOutput(\n output: OutputMeta,\n context: ReportFormatContext,\n options: OutputValueOptions,\n): FormattedOutputValue {\n const role = output.role;\n\n if (role === 'prior') {\n return { text: EMPTY_VALUE, title: missingPriorTitle(output, options.floor, context.locale) };\n }\n\n if (role === 'change' || role === 'percent_change') {\n const prior = options.prior;\n\n if (role === 'percent_change' && toFiniteNumber(prior) === 0) {\n return { text: NOT_APPLICABLE_VALUE, title: 'Prior was 0' };\n }\n\n return {\n text: EMPTY_VALUE,\n title: prior !== undefined && isEmptyValue(prior)\n ? missingPriorTitle(output, options.floor, context.locale)\n : null,\n };\n }\n\n return plainOutput(options.empty ?? EMPTY_VALUE);\n}\n\n// Why a prior is missing. A value's prior is missing when its window ends\n// before the data starts. A rank's or a share's is missing when the row had\n// no rank or share in the prior period, whatever the floor.\nfunction missingPriorTitle(\n output: OutputMeta,\n floor: string | null | undefined,\n locale: ReportLocaleTag,\n): string {\n if (output.kind === 'rank') {\n return NO_PRIOR_RANK_TITLE;\n }\n\n if (output.kind === 'share') {\n return NO_PRIOR_SHARE_TITLE;\n }\n\n return noBaselineTitle(floor, locale);\n}\n\nfunction noBaselineTitle(floor: string | null | undefined, locale: ReportLocaleTag): string {\n const day = floor ? formatDay(floor, locale) : '';\n\n return day ? `No baseline: no data before ${day}` : 'No baseline';\n}\n\n// A rank change: prior rank minus current, so moving up is positive.\nfunction formatRankChange(\n value: unknown,\n spec: NumberFormatSpec | null | undefined,\n context: ReportFormatContext,\n options: OutputValueOptions,\n): FormattedOutputValue {\n if (isEmptyValue(value)) {\n return isEmptyValue(options.prior)\n ? { text: NEW_RANK_VALUE, title: NO_PRIOR_RANK_TITLE }\n : plainOutput(EMPTY_VALUE);\n }\n\n const numeric = toFiniteNumber(value);\n if (numeric === null) {\n return plainOutput(String(value));\n }\n\n const rankSpec = valueFormat(spec) !== null ? spec : withOwnDigits(RANK_DEFAULT_SPEC, spec);\n const places = formatNumber(Math.abs(numeric), rankSpec, context);\n\n if (places === formatNumber(0, rankSpec, context)) {\n return plainOutput(RANK_UNCHANGED_VALUE);\n }\n\n return plainOutput(`${numeric > 0 ? RANK_UP_MARK : RANK_DOWN_MARK} ${places}`);\n}\n\n\n// A chart's value axis takes a format only when every measure on it agrees on\n// the style (each measure's format, number when it names none) and at least\n// one of them names a format. The first measure that does gives the axis its\n// precision and units. Otherwise null: the axis keeps its default ticks on\n// screen and in PowerPoint, and each series still formats its own tooltips.\nexport function axisNumberFormat(measures: ChartMeasure[]): NumberFormatSpec | null {\n const style = measures.length ? resolveStyle(measures[0]) : null;\n\n if (style === null || measures.some((measure) => resolveStyle(measure) !== style)) {\n return null;\n }\n\n const formatted = measures.find((measure) => hasNumberFormat(measure));\n\n return formatted ? numberFormatSpec(formatted) : null;\n}\n\nfunction numberFormatSpec(spec: NumberFormatSpec): NumberFormatSpec {\n return {\n ...(spec.format !== undefined ? { format: spec.format } : {}),\n ...(spec.precision !== undefined ? { precision: spec.precision } : {}),\n ...(spec.units !== undefined ? { units: spec.units } : {}),\n };\n}\n\n// How a chart's value axis writes its ticks: the units decided once from the\n// axis peak, and the decimals the precision pins, else as many as the axis's\n// tick step needs (a percent axis up to 0.12% steps by 0.02%, two decimals).\n// Pinned decimals keep the ticks distinct, and PowerPoint can only pin them.\nexport function resolveChartNumberFormat(\n spec: NumberFormatSpec,\n peak: number,\n context: ReportFormatContext,\n): ChartNumberFormat {\n const style = resolveStyle(spec);\n const precision = clampDecimals(spec.precision);\n const units = style === ReportValueFormat.Percent\n ? ReportNumberUnits.None\n : resolveUnits(spec.units, peak, precision ?? SCALED_DECIMALS);\n\n return { units, decimals: precision ?? axisDecimals(style, units, peak, context) };\n}\n\n// The decimals the axis's nice tick step needs. A plain, unabbreviated number\n// pins none (null): its ticks keep their own decimals. An unscaled currency\n// axis that needs decimals shows cents, and a K/M axis keeps its step's\n// decimals ('$0.5M', not '$0.50M').\nfunction axisDecimals(\n style: ReportValueFormat,\n units: ResolvedUnits,\n peak: number,\n context: ReportFormatContext,\n): number | null {\n const scale = UNIT_SCALES.get(units);\n\n if (style === ReportValueFormat.Number && !scale) {\n return null;\n }\n\n const shownPeak = style === ReportValueFormat.Percent && context.ratioPercent\n ? Math.abs(peak) * 100\n : Math.abs(peak) / (scale?.divisor ?? 1);\n const step = niceStep(shownPeak / AXIS_TICKS);\n const decimals = step > 0 ? clampDecimals(-Math.floor(Math.log10(step))) ?? 0 : 0;\n\n return style === ReportValueFormat.Currency && decimals > 0 && !scale ? CURRENCY_AXIS_DECIMALS : decimals;\n}\n\n// ECharts' nice(): the round number (1, 2, 3, 5 or 10 times a power of ten) a\n// rough tick step snaps to.\nfunction niceStep(rough: number): number {\n if (!(rough > 0) || !Number.isFinite(rough)) {\n return 0;\n }\n\n const exponent = Math.floor(Math.log10(rough));\n const power = Math.pow(10, exponent);\n const fraction = rough / power;\n let nice = 10;\n if (fraction < 1.5) {\n nice = 1;\n } else if (fraction < 2.5) {\n nice = 2;\n } else if (fraction < 4) {\n nice = 3;\n } else if (fraction < 7) {\n nice = 5;\n }\n\n return nice * power;\n}\n\n// PowerPoint's number format code for a formatted value axis, matching the\n// screen's ticks: '#,##0.0%' (percent), '\"$\"#,##0' (currency),\n// '#,##0.0,\"K\"' (thousands), '#,##0\" $\"' (fr-CA currency). A plain number\n// whose decimals are not pinned keeps chartAxisFormatCode's code. The code's\n// separators follow the opening machine's locale; the currency symbol and its\n// side follow the report's.\nexport function numberFormatCode(\n spec: NumberFormatSpec,\n context: ReportFormatContext,\n chart: ChartNumberFormat,\n series: (number | null)[][],\n stacked: boolean,\n): string {\n const style = resolveStyle(spec);\n const scale = style === ReportValueFormat.Percent ? undefined : UNIT_SCALES.get(chart.units);\n\n if (style === ReportValueFormat.Number && !scale && chart.decimals === null) {\n return chartAxisFormatCode(series, stacked);\n }\n\n const decimals = chart.decimals ?? 0;\n const digits = `#,##0${decimals > 0 ? `.${'0'.repeat(decimals)}` : ''}`;\n\n if (style === ReportValueFormat.Percent) {\n return `${digits}${context.ratioPercent ? '%' : '\"%\"'}`;\n }\n\n const scaled = `${digits}${scale?.commas ?? ''}`;\n const unit = scale?.suffix ?? '';\n\n if (style !== ReportValueFormat.Currency) {\n return unit ? `${scaled}\"${unit}\"` : scaled;\n }\n\n const symbol = currencySymbol(context);\n\n return symbol.prefix\n ? `\"${symbol.text}\"${scaled}${unit ? `\"${unit}\"` : ''}`\n : `${scaled}\"${unit}${symbol.text}\"`;\n}\n\n// The currency symbol as the locale writes it beside a number, with the space\n// between them, and which side it sits on: '$' before in en-US, ' $' after in\n// fr-CA. Quotes are dropped, as a format code cannot hold them.\ninterface CurrencySymbol {\n prefix: boolean;\n text: string;\n}\n\nconst CURRENCY_SYMBOLS = new Map<string, CurrencySymbol>();\n\nfunction currencySymbol(context: ReportFormatContext): CurrencySymbol {\n const key = `${context.locale}|${context.currency}`;\n let symbol = CURRENCY_SYMBOLS.get(key);\n\n if (!symbol) {\n const parts = numberFormat(context.locale, currencyOptions(context.currency)).formatToParts(1);\n const currency = parts.findIndex((part) => part.type === 'currency');\n const first = parts.findIndex((part) => NUMBER_PARTS.has(part.type));\n const last = parts.reduce((found, part, index) => NUMBER_PARTS.has(part.type) ? index : found, -1);\n const prefix = currency < first;\n const text = (prefix ? parts.slice(Math.max(currency, 0), first) : parts.slice(last + 1))\n .map((part) => part.value)\n .join('')\n .replace(/\"/g, '');\n\n symbol = { prefix, text };\n CURRENCY_SYMBOLS.set(key, symbol);\n }\n\n return symbol;\n}\n\n\n// Every decimal a number has, grouped, in the locale: what ECharts prints by\n// default (its addCommas), but in the report's locale, so a chart's axis and\n// tooltip read like the rest of the report. 1234.5 reads 1,234.5 in en-US and\n// 1 234,5 in fr-CA. A non-numeric string is shown as it came, and anything\n// else non-numeric as '-', as ECharts shows it. As there, an infinite value\n// reads 'Infinity' and negative zero (a tick a float error leaves just below\n// zero) reads '0'.\nconst PLAIN_NUMBER: Intl.NumberFormatOptions = { maximumFractionDigits: 20 };\n\nexport function formatPlainNumber(value: unknown, locale: ReportLocaleTag): string {\n const numeric = typeof value === 'number'\n ? value\n : typeof value === 'string' && value.trim() !== '' ? Number(value) : NaN;\n\n if (Number.isNaN(numeric)) {\n return typeof value === 'string' ? value : '-';\n }\n\n if (!Number.isFinite(numeric)) {\n return String(numeric);\n }\n\n return numberFormat(locale, PLAIN_NUMBER).format(numeric === 0 ? 0 : numeric);\n}\n\n\n// The axis peak at which a native chart's value axis gains thousands\n// separators. From here up the ticks are whole numbers in practice; below it\n// neither the screen nor PowerPoint's 'General' shows a separator.\nexport const AXIS_SEPARATOR_THRESHOLD = 1000;\n\n// PowerPoint's number format for a native chart's value axis, matching what the\n// on-screen axis prints by default: thousands separators with each tick's own\n// decimals. Excel has no \"General with separators\", so an axis reaching 1,000\n// (where ticks are whole numbers) gets '#,##0', and a smaller range keeps\n// 'General' so fractional ticks (0.25, 0.5) are not rounded away.\n//\n// The peak is chartValuePeak's.\nexport function chartAxisFormatCode(series: (number | null)[][], stacked: boolean): string {\n return chartValuePeak(series, stacked) >= AXIS_SEPARATOR_THRESHOLD ? '#,##0' : 'General';\n}\n\n// The largest magnitude a chart's value axis has to reach. A missing value\n// counts as 0. A stacked chart's peak is its tallest stack: the largest sum,\n// per category, of every series' absolute value.\nexport function chartValuePeak(series: (number | null)[][], stacked: boolean): number {\n const magnitudes = series.map((values) => values.map((value) => Math.abs(value ?? 0)));\n\n return stacked\n ? Math.max(0, ...(magnitudes[0] ?? []).map((_, index) => magnitudes\n .reduce((sum, values) => sum + (values[index] ?? 0), 0)))\n : Math.max(0, ...magnitudes.flat());\n}\n\n\n// The zone every date in a report is read in. The server resolves it (the\n// report's own zone, else the application's default reporting zone) and sends\n// it as `effectiveTimezone`. A server too old to send the field still used a\n// report's pinned `timezone`, so that comes next; the browser's zone is the last\n// fallback. This is the one place that chain lives, so every date the viewer\n// renders or resolves agrees with every other.\nexport function resolveReportTimezone(report: Pick<Report, 'effectiveTimezone' | 'timezone'>): string {\n return report.effectiveTimezone ?? report.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;\n}\n\n\n// The date shapes a report writes, each in the report's locale.\n// 'Jan 5, 2026' / '5 janv. 2026': a date cell, a filter bound.\nexport const DAY_SHORT: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };\n// 'January 5, 2026' / '5 janvier 2026': an export cover's date line.\nexport const DAY_LONG: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' };\n// 'January' / 'janvier': a monthly period label (its year is added apart).\nexport const MONTH_LONG: Intl.DateTimeFormatOptions = { month: 'long' };\n// 'January 2026' / 'janvier 2026': a monthly period label written in full.\nexport const MONTH_YEAR: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long' };\n// 'Jan 5' / '5 janv.': a daily or weekly period label.\nexport const MONTH_DAY: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric' };\n\n// A date in the locale. With a zone, the day it falls on there; without one,\n// the browser's zone, which keeps a calendar day parsed as local midnight\n// unshifted. It never throws, since a pipe or an export calls it per cell: an\n// invalid Date reads '', a malformed locale ('en_CA') reads the fallback\n// locale, and an unknown zone reads UTC, which still names a real day.\nexport function formatLocalDate(\n date: Date,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): string {\n if (Number.isNaN(date.getTime())) {\n return '';\n }\n\n try {\n return writeDate(dateFormat(locale, options, timeZone), date);\n } catch {\n return formatFallbackDate(date, resolveReportLocale(locale), options, timeZone);\n }\n}\n\nfunction formatFallbackDate(\n date: Date,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions,\n timeZone?: string,\n): string {\n try {\n return writeDate(dateFormat(locale, options, timeZone), date);\n } catch {\n return writeDate(dateFormat(locale, options, 'UTC'), date);\n }\n}\n\n// Intl writes a year below 1000 with only the digits it has ('Jan 1, 1'); a\n// date's year is always written with four ('Jan 1, 0001'), so a sentinel day\n// still reads as a date. Only such a year pays for formatToParts.\nfunction writeDate(formatter: Intl.DateTimeFormat, date: Date): string {\n if (date.getUTCFullYear() > 1000) {\n return formatter.format(date);\n }\n\n return formatter.formatToParts(date)\n .map((part) => part.type === 'year' ? part.value.padStart(4, '0') : part.value)\n .join('');\n}\n\n\nconst DATE_ONLY_PATTERN = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst DATE_TIME_PATTERN = /^(\\d{4}-\\d{2}-\\d{2})[ T](\\d{2}:\\d{2}:\\d{2})(\\.\\d+)?$/;\n\n// A report row's date cell as a calendar day in the report's zone.\n//\n// Report rows are raw database strings, not serialized models, so their shape\n// is the wire contract: a DATE column arrives as 'YYYY-MM-DD' and a\n// date-and-time column as 'YYYY-MM-DD HH:MM:SS' in UTC. Reading that shape\n// here does not re-derive a server rule; it only stops the browser guessing.\n// - A calendar day is never shifted: parseISO reads it as local midnight, so\n// the day printed is the day stored, whatever the zone.\n// - An instant is pinned to UTC with an explicit 'Z', then shown as the day it\n// fell on in the report's zone, the same day the filters and time buckets use.\n// - Anything else is shown as it came, and so is a value that has the shape\n// but names no real day (a zero date '0000-00-00', or '2026-02-30'): one\n// bad cell must not throw out of a pipe or abort an export.\n// The day is written in the report's locale: 'Jan 5, 2026' in en-US, '5 janv.\n// 2026' in fr-CA.\nexport function formatReportDate(\n value: unknown,\n timezone: string,\n locale: ReportLocaleTag,\n): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const text = String(value);\n\n if (DATE_ONLY_PATTERN.test(text)) {\n const day = parseISO(text);\n\n return isValid(day) ? formatLocalDate(day, locale, DAY_SHORT) : text;\n }\n\n const dateTime = DATE_TIME_PATTERN.exec(text);\n if (!dateTime) {\n return text;\n }\n\n const instant = parseISO(`${dateTime[1]}T${dateTime[2]}Z`);\n\n return isValid(instant) ? formatLocalDate(instant, locale, DAY_SHORT, timezone) : text;\n}\n\n\n// The time of day an instant falls at in the report's zone: '2:23 PM' in\n// en-US, '14 h 23' in fr-CA.\nexport const TIME_SHORT: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: '2-digit' };\n\n// A window's inclusive days, as the server sends them: 'yyyy-MM-dd' calendar\n// days already in the report's zone. Like a date cell they are read as local\n// midnight and written with NO zone, so a viewer in any zone sees the days\n// sent. Both days: Intl's range in the locale ('Sep 1 – 30, 2026' in en-US,\n// '1–30 sept. 2026' in fr-CA, one date when they are the same day). One day:\n// an open window ('Since Sep 1, 2026', 'Through Sep 30, 2026'). Neither, or\n// days that are not real ones: ''.\nexport function formatDayRange(\n start: string | null | undefined,\n end: string | null | undefined,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions = DAY_SHORT,\n): string {\n const first = parseDay(start);\n const last = parseDay(end);\n\n if (first && last) {\n return writeDayRange(first, last, locale, options);\n }\n\n if (first) {\n return `Since ${formatLocalDate(first, locale, options)}`;\n }\n\n return last ? `Through ${formatLocalDate(last, locale, options)}` : '';\n}\n\n// The time a window ending today is cut at: the server's UTC\n// 'yyyy-MM-dd HH:mm:ss' instant, as a time of day in the report's zone. ''\n// for none, or for a value of another shape.\nexport function formatThroughTime(\n through: string | null | undefined,\n timezone: string,\n locale: ReportLocaleTag,\n): string {\n const dateTime = through ? DATE_TIME_PATTERN.exec(through) : null;\n const instant = dateTime ? parseISO(`${dateTime[1]}T${dateTime[2]}Z`) : null;\n\n return instant && isValid(instant) ? formatLocalDate(instant, locale, TIME_SHORT, timezone) : '';\n}\n\n// A comparison or timeframe window in one line: its days, and the time it is\n// cut at when it ends today on a date-and-time column ('Oct 1 – 2, 2026,\n// until 2:23 PM').\nexport function formatDayWindow(\n meta: { start: string | null; end: string | null; through?: string | null },\n timezone: string,\n locale: ReportLocaleTag,\n): string {\n const days = formatDayRange(meta.start, meta.end, locale);\n const time = formatThroughTime(meta.through, timezone, locale);\n\n return days && time ? `${days}, until ${time}` : days;\n}\n\n// Whether a comparison is read on one day: a comparison of values read at\n// the end of each period, with no time axis of its own (a KPI, a one-row\n// list), whose value is read today and whose prior is read at the end of\n// the period before. Its two windows are those periods, back to back, and\n// each value is read on its window's last day, so the windows are written as\n// those days (formatReadingDay). A spine of several periods sets each period\n// against an earlier one, and its windows are spans like any other\n// comparison's.\nexport function isReadOnOneDay(comparison: ComponentComparison | null | undefined): boolean {\n const current = comparison?.current;\n const prior = comparison?.priors?.[0];\n\n if (comparison?.mode !== 'period_end' || !current || !prior) {\n return false;\n }\n\n const priorEnd = parseDay(prior.end);\n const currentStart = parseDay(current.start);\n\n return !!priorEnd && !!currentStart && addDays(priorEnd, 1).getTime() === currentStart.getTime();\n}\n\n// The day a value is read on: 'on Sep 15, 2026' ('On …' to open a line), as\n// a chart's tooltip names a prior point read at the end of its period. ''\n// for a day that is not a real one.\nexport function formatReadingDay(\n window: Pick<ComparisonWindow, 'end'>,\n locale: ReportLocaleTag,\n lead = false,\n): string {\n const day = formatDay(window.end, locale);\n\n if (!day) {\n return '';\n }\n\n return lead ? `On ${day}` : `on ${day}`;\n}\n\n// One 'yyyy-MM-dd' day in the locale, written with no zone: 'Sep 1, 2026'.\nfunction formatDay(day: string, locale: ReportLocaleTag): string {\n const date = parseDay(day);\n\n return date ? formatLocalDate(date, locale, DAY_SHORT) : '';\n}\n\n// A 'yyyy-MM-dd' day as local midnight, or null when it is not a real day.\nfunction parseDay(day: string | null | undefined): Date | null {\n if (!day || !DATE_ONLY_PATTERN.test(day)) {\n return null;\n }\n\n const date = parseISO(day);\n\n return isValid(date) ? date : null;\n}\n\n// Intl's range writes the shared month and year once. A malformed locale\n// reads the fallback; a runtime that cannot write ranges joins two dates.\n// Both days are calendar days read as local midnight, written with no zone.\nexport function writeDayRange(\n first: Date,\n last: Date,\n locale: ReportLocaleTag,\n options: Intl.DateTimeFormatOptions,\n): string {\n const [from, to] = first <= last ? [first, last] : [last, first];\n\n for (const tag of [locale, resolveReportLocale(locale)]) {\n try {\n return dateFormat(tag, options).formatRange(from, to);\n } catch {\n // The next locale, then the joined dates.\n }\n }\n\n return `${formatLocalDate(from, locale, options)} – ${formatLocalDate(to, locale, options)}`;\n}\n\n\n// English names for a locale and a currency, for the settings selects. The\n// interface stays English whatever the report's locale: 'fr-CA' reads\n// 'Canadian French', 'CAD' reads 'Canadian Dollar'. A runtime without the\n// names shows the code.\nexport function localeName(tag: ReportLocaleTag): string {\n return displayName('language', tag);\n}\n\nexport function currencyName(code: ReportCurrencyCode): string {\n return displayName('currency', code);\n}\n\nfunction displayName(type: 'language' | 'currency', code: string): string {\n try {\n return new Intl.DisplayNames(['en'], { type }).of(code) ?? code;\n } catch {\n return code;\n }\n}\n\n\n// Comparison, window and KPI wording. The server sends codes and fields,\n// never sentences (a window's description is for the agent and the exports'\n// notes, not the screen); the interface words them here, in English like\n// every other label, with any day written in the report's locale.\n\nconst GRANULARITY_UNITS: Record<ChartGranularity, { one: string; many: string }> = {\n day: { one: 'day', many: 'days' },\n week: { one: 'week', many: 'weeks' },\n month: { one: 'month', many: 'months' },\n quarter: { one: 'quarter', many: 'quarters' },\n year: { one: 'year', many: 'years' },\n};\n\n// What a prior lane is called: always so for a named period, and for the\n// previous period when the server names no unit for it.\nconst AGAINST_PHRASES: Record<ComparisonAgainst, string> = {\n previous_period: 'previous period',\n previous_week: 'previous week',\n previous_month: 'previous month',\n previous_quarter: 'previous quarter',\n previous_year: 'previous year',\n range: 'custom range',\n};\n\n// A prior lane's label, from its offset rather than from the measure, so a\n// chart regrouped by the viewer says what it now compares. A named period\n// reads by its name whatever shift carries it ('vs previous quarter' for 3\n// months, 'vs previous year' for 364 days or 52 weeks, 'vs custom range').\n// Only the previous period is worded from its unit and count: 'vs previous\n// week', 'vs previous 3 months', 'vs previous 8 days' (a day-length shift).\nexport function comparisonOffsetLabel(offset: ComparisonOffset): string {\n return `vs ${offsetPhrase(offset)}`;\n}\n\nfunction offsetPhrase(offset: ComparisonOffset): string {\n if (offset.against !== 'previous_period' || !offset.unit || !offset.count) {\n return AGAINST_PHRASES[offset.against] ?? AGAINST_PHRASES.previous_period;\n }\n\n return offset.count === 1\n ? `previous ${GRANULARITY_UNITS[offset.unit].one}`\n : `previous ${offset.count} ${GRANULARITY_UNITS[offset.unit].many}`;\n}\n\n// One comparison note as a sentence. The comparison, when given, names the\n// period compared with (its first prior lane).\nexport function comparisonNoteText(\n code: ComparisonNoteCode,\n comparison?: ComponentComparison | null,\n): string {\n const offset = comparison?.offsets?.[0] ?? null;\n const compared = offset ? `Compared with the ${offsetPhrase(offset)}` : null;\n\n switch (code) {\n case 'no_window':\n return 'Pick a date range to see the comparison.';\n case 'unit_inferred':\n return compared\n ? `${compared}, judged from the dates picked.`\n : 'The period compared with was judged from the dates picked.';\n case 'window_in_future':\n return 'The date range starts after today, so there is nothing to compare yet.';\n case 'other_date_filter':\n return 'A date filter on another column also applies to both periods.';\n case 'grain_followed':\n return compared\n ? `${compared}, following the grouping picked.`\n : 'The comparison follows the grouping picked.';\n default:\n return '';\n }\n}\n\n// What a windowed value is: 'Rolling 3-month total', 'Month-to-date total',\n// 'Running total since the start of the data', then its days when the server\n// sends them ('Rolling 7-day average, Sep 24 – 30, 2026'). granularity is the\n// grouping the rows are drawn at (ComponentData.granularity), which names a\n// rolling window authored in periods of the axis.\nexport function windowText(\n meta: WindowMeta,\n locale: ReportLocaleTag,\n granularity?: ChartGranularity | null,\n): string {\n const days = formatDayRange(meta.start, meta.end, locale);\n const phrase = windowPhrase(meta, granularity ?? null);\n\n return days ? `${phrase}, ${days}` : phrase;\n}\n\nfunction windowPhrase(meta: WindowMeta, granularity: ChartGranularity | null): string {\n const value = meta.average ? 'average' : 'total';\n\n switch (meta.kind) {\n case 'running':\n return meta.fromBeginning ? `Running ${value} since the start of the data` : `Running ${value}`;\n case 'to_date': {\n const reset = meta.resetEvery ? GRANULARITY_UNITS[meta.resetEvery].one : null;\n\n return reset ? `${capitalize(reset)}-to-date ${value}` : `To-date ${value}`;\n }\n case 'rolling': {\n const unit = meta.unit ?? granularity;\n const span = meta.periods ? `${meta.periods}-${unit ? GRANULARITY_UNITS[unit].one : 'period'} ` : '';\n\n return `Rolling ${span}${value}`;\n }\n default:\n return capitalize(value);\n }\n}\n\n// One window note as a sentence.\nexport function windowNoteText(\n code: WindowNoteCode,\n meta: WindowMeta,\n locale: ReportLocaleTag,\n granularity?: ChartGranularity | null,\n): string {\n switch (code) {\n case 'snapped_start': {\n const start = meta.start ? formatDay(meta.start, locale) : '';\n\n return start\n ? `The start was moved to ${start}, the start of its period, so the first period is whole.`\n : 'The start was moved to the start of its period, so the first period is whole.';\n }\n case 'span_converted':\n return spanConvertedText(meta, granularity ?? null);\n case 'grain_too_coarse':\n return 'The grouping is coarser than the window, so it has no values at this grouping.';\n case 'equal_grain_plain':\n return 'At this grouping each window is a single period, so the values are the plain ones.';\n case 'own_filter_caps_lead_in':\n return 'The query\\'s own date condition starts the window, so earlier rows are not counted.';\n case 'week_by_monday':\n return 'A week that spans two periods counts toward the period its Monday falls in.';\n case 'incomplete_head':\n return 'The first periods are blank because there are not enough earlier rows to fill a whole window.';\n default:\n return '';\n }\n}\n\n// '3 months are shown as 13 weeks at this grouping.'\nfunction spanConvertedText(meta: WindowMeta, granularity: ChartGranularity | null): string {\n if (!meta.periods || !meta.unit || !meta.drawnPeriods) {\n return 'The window\\'s span was converted to the grouping shown.';\n }\n\n const authored = unitCount(meta.periods, meta.unit);\n const drawn = granularity\n ? unitCount(meta.drawnPeriods, granularity)\n : `${meta.drawnPeriods} ${meta.drawnPeriods === 1 ? 'period' : 'periods'}`;\n\n return `${authored} ${meta.periods === 1 ? 'is' : 'are'} shown as ${drawn} at this grouping.`;\n}\n\nfunction unitCount(count: number, unit: ChartGranularity): string {\n return `${count} ${count === 1 ? GRANULARITY_UNITS[unit].one : GRANULARITY_UNITS[unit].many}`;\n}\n\n// Why a KPI's delta reads as it does, as a sentence. The baseline is named\n// by what the value is compared against: the same period last year for a\n// year-on-year comparison, else the period before.\nexport function kpiNoteText(code: KpiNoteCode, against?: ComparisonAgainst | null): string {\n const baseline = kpiBaselineText(against);\n\n switch (code) {\n case 'no_prior_data':\n return `No baseline: ${baseline} has no data.`;\n case 'up_from_zero':\n return `New: ${baseline} was 0.`;\n case 'no_change':\n return `No change from ${baseline}.`;\n case 'no_data_either':\n return 'No data in either period.';\n case 'sign_change':\n return 'The value crossed zero, so there is no percent change.';\n default:\n return '';\n }\n}\n\n// The window a KPI's value is compared with, as a noun phrase. An unknown or\n// missing comparison reads as neutral wording rather than a wrong period.\nfunction kpiBaselineText(against: ComparisonAgainst | null | undefined): string {\n switch (against) {\n case 'previous_period':\n return 'the previous period';\n case 'previous_week':\n return 'the previous week';\n case 'previous_month':\n return 'the previous month';\n case 'previous_quarter':\n return 'the previous quarter';\n case 'previous_year':\n return 'the same period last year';\n default:\n return 'the comparison period';\n }\n}\n\nfunction capitalize(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n\n\n// \"Now\" as a Date whose local fields read the wall clock in the given zone, so\n// date-fns calendar arithmetic (startOfWeek, startOfMonth, ...) and\n// dateBoundString() land on the zone's calendar day rather than the browser's.\n// An unknown zone falls back to the browser's clock.\nexport function getZonedNow(timezone: string): Date {\n const now = new Date();\n\n try {\n const zoned = toZonedTime(now, timezone);\n\n return Number.isNaN(zoned.getTime()) ? now : zoned;\n } catch {\n return now;\n }\n}\n","// Text blocks — shared by the canvas and both exports, so a block reads the\n// same on screen, in the deck and in the PDF.\n//\n// A block's html arrives already rebuilt server-side from a small allowlist\n// (ReportTextHtml): p, h1-h3, strong, em, u, s, ul/ol/li, br, a, and span with\n// color / background-color / font-size / font-weight / font-family, plus\n// text-align on a block. A table may sit at the top level of a block: table,\n// thead, tbody, tfoot, tr, th and td, a width on the table, and on a cell\n// text-align, vertical-align, background-color, a width and a colspan or\n// rowspan. Its grid lines, padding and margin are never stored: every renderer\n// draws them from the TEXT_TABLE_* constants below. Transparent, currentcolor\n// and the CSS-wide keywords (inherit, initial, …) are not colors, so the\n// server drops them and hexColor reads them as no color. Everything here only\n// has to understand that set.\n\n\n// Body text size, points, and the heading sizes — the same numbers the canvas\n// stylesheet uses, so an unstyled paragraph is one size everywhere.\nexport const DEFAULT_TEXT_SIZE = 12;\nexport const HEADING_TEXT_SIZES: Record<number, number> = { 1: 24, 2: 18, 3: 14 };\nexport const DEFAULT_TEXT_COLOR = '#1f2933';\n\n// A table's grid lines: their color, and their width in points (0.75pt is one\n// pixel on the canvas). The html never stores borders or padding\n// (ReportTextHtml drops them), so the canvas, the editor and both exports all\n// draw this one look.\nexport const TEXT_TABLE_BORDER_COLOR = '#cbd2d9';\nexport const TEXT_TABLE_BORDER_WIDTH = 0.75;\n// The space between a cell's grid lines and its words, in points.\nexport const TEXT_TABLE_CELL_PADDING = { vertical: 2, horizontal: 4 };\n// The space above and below a table, between it and the words around it, in\n// points.\nexport const TEXT_TABLE_MARGIN = 4;\n\n// A live value a block shows inline, written {{value.<key>}} in its html: what\n// the value is, and its formatted text once loaded. Values belong to the page\n// the block sits on (the master for a header or footer block), so the key is\n// unique within that page.\nexport interface TextValue {\n name: string;\n // Absent while loading, and when the value's query failed.\n text?: string;\n // Its number has been asked for and has not arrived yet.\n loading?: boolean;\n // A formula's operand keys, lowercase: the values it reads, which the page\n // reads too while the formula is shown.\n reads?: string[];\n}\n\n// A filter of the report a block names, written {{filter.<id>}} in its html\n// with the filter group's id: what the filter is, and what its current value\n// reads as (filterFieldText). A block reads the report's filters, and a page\n// block its own page's page filters too (layerFilterGroups).\nexport interface TextFilterField {\n // The group's label, else its name, else 'Filter' (filterFieldName).\n name: string;\n // Where the filter bar lists the group (ReportFilterGroup.order), which is\n // where the Insert field menus list it too.\n order: number;\n // Absent while loading, and when its value could not be read.\n text?: string;\n // A select's picked names have been asked for and have not arrived yet.\n loading?: boolean;\n}\n\n// What the tokens in a block's html, and in a component's title, are filled\n// with, per page.\nexport interface TextTokenContext {\n pageNumber: number;\n pageName: string;\n reportName: string;\n // The page's values, by lowercase key.\n values?: Record<string, TextValue>;\n // The filters the layer reads (layerFilterGroups), by filter group id. A\n // token of any other group reads the em dash.\n filters?: Record<number, TextFilterField>;\n // The report page whose values the block shows: the page it sits on, or the\n // master for a header or footer block. It is also the editor's clipboard\n // scope, so a copied chip pastes back as a chip only on that page.\n valuePageId?: number | null;\n}\n\n// A value token: {{value.total_visits}}. Keys are lowercase letters, digits and\n// underscores, starting with a letter.\nexport const VALUE_TOKEN_PATTERN = /\\{\\{\\s*value\\.([a-z][a-z0-9_]*)\\s*\\}\\}/gi;\n\n// A field token, anything a block may carry that is not a value:\n// {{page.number}}, {{page.name}}, {{report.name}} and {{filter.<id>}}, the id\n// digits only. Exactly these, so it matches neither a value token nor any\n// other braces the words hold.\nexport const FIELD_TOKEN_PATTERN = /\\{\\{\\s*(page\\.number|page\\.name|report\\.name|filter\\.\\d+)\\s*\\}\\}/gi;\n\n// What a value with no number reads as — it failed, it is not on this page, or\n// its query found nothing — so a block never prints a raw token. A filter\n// token naming no filter of the report reads as it too.\nexport const VALUE_EMPTY_TEXT = '—';\n\n// What a value reads as while its number is on its way (on screen only: an\n// export waits for every number).\nexport const VALUE_LOADING_TEXT = '…';\n\nexport function valueToken(key: string): string {\n return `{{value.${key}}}`;\n}\n\n// What a value reads as in a block, viewed or edited: its formatted number,\n// the ellipsis while that loads, else the em dash.\nexport function valueText(value: TextValue | undefined): string {\n return value?.text ?? (value?.loading ? VALUE_LOADING_TEXT : VALUE_EMPTY_TEXT);\n}\n\n// One styled stretch of text.\nexport interface TextRun {\n text: string;\n bold?: boolean;\n italic?: boolean;\n underline?: boolean;\n strike?: boolean;\n // #rrggbb\n color?: string;\n highlight?: string;\n // points\n fontSize?: number;\n fontFace?: string;\n link?: string;\n}\n\n// One line-starting block: a paragraph, a heading or a list item.\nexport interface TextParagraph {\n runs: TextRun[];\n align?: 'left' | 'center' | 'right' | 'justify';\n bullet?: 'bullet' | 'number';\n heading?: number;\n}\n\n// One cell of a table in a block. Its words are paragraphs like any others: a\n// <br> in a cell starts a new one, and a header cell's runs are bold. Each\n// paragraph carries the cell's alignment unless it has its own, so every\n// renderer reads alignment and weight from the paragraphs.\nexport interface TextTableCell {\n paragraphs: TextParagraph[];\n colSpan: number;\n // Cut at the last row of the cell's section, as a browser draws it.\n rowSpan: number;\n // Where the cell sits in the grid (tableGrid), 0-based: its top row and its\n // left column.\n row: number;\n column: number;\n // Its text-align, else centered for a header cell and left for any other.\n align: 'left' | 'center' | 'right' | 'justify';\n valign?: 'top' | 'middle' | 'bottom';\n // Its background, #rrggbb.\n fill?: string;\n}\n\n// A table's row. Rows come in the order a browser draws them: the head, the\n// body, then the foot.\nexport interface TextTableRow {\n section: 'head' | 'body' | 'foot';\n cells: TextTableCell[];\n}\n\nexport interface TextTable {\n rows: TextTableRow[];\n // How many columns the grid has: the widest right edge of any cell.\n columns: number;\n}\n\n// A block as the exports draw it: its words, split at each table it holds.\nexport type TextBlock =\n | { kind: 'text'; paragraphs: TextParagraph[] }\n | { kind: 'table'; table: TextTable };\n\n// What a table's cells are joined by where it reads as lines of text.\nconst TABLE_CELL_SEPARATOR = ' · ';\n\n// The page and report fields: what each is called where an author picks and\n// sees it (the Insert field menus of the text editor and of a title, and the\n// editor's chips), in those menus' order, and what fills it. {{page.number}}\n// is the page's position among the report's pages (1-based), which is what\n// makes a shared footer number every page correctly.\nconst PAGE_FIELDS: Record<string, { name: string; text: (context: TextTokenContext) => string }> = {\n 'page.number': { name: 'Page number', text: (context) => String(context.pageNumber) },\n 'page.name': { name: 'Page name', text: (context) => context.pageName },\n 'report.name': { name: 'Report name', text: (context) => context.reportName },\n};\n\nconst FILTER_FIELD_PREFIX = 'filter.';\n\n// A field a block can carry, as the editor offers and shows it.\nexport interface TextField {\n // As its token writes it, lowercase: 'page.number', 'filter.12'.\n field: string;\n // What it is called: 'Page number', a filter's label.\n name: string;\n}\n\n// Every field a block or a title of this context can carry, in the order the\n// Insert field menus list them: the page and report fields, then each filter\n// of the report in the filter bar's order.\nexport function textFields(context: TextTokenContext): TextField[] {\n return [\n ...Object.entries(PAGE_FIELDS).map(([field, { name }]) => ({ field, name })),\n ...Object.entries(context.filters ?? {})\n .sort(([, a], [, b]) => a.order - b.order)\n .map(([id, filter]) => ({\n field: `${FILTER_FIELD_PREFIX}${id}`,\n name: filter.name,\n })),\n ];\n}\n\n// A field's token: {{page.number}}, {{filter.12}}.\nexport function fieldToken(field: string): string {\n return `{{${field}}}`;\n}\n\n// Replace every {{token}} in the html. Values are html-escaped: a page named\n// \"R&D <draft>\" must read as that, not as markup. A {{value.<key>}} token reads\n// as its formatted number, the ellipsis while that loads, else the em dash.\nexport function fillTextTokens(html: string, context: TextTokenContext): string {\n return html\n .replace(VALUE_TOKEN_PATTERN, (match, key: string) => escapeHtml(\n valueText(context.values?.[key.toLowerCase()]),\n ))\n .replace(FIELD_TOKEN_PATTERN, (match, field: string) => escapeHtml(fieldText(field, context)));\n}\n\n// A component's title as it reads: its page, report and filter fields filled\n// with the same words as a block's, e.g. 'Sign-ups — {{filter.12}}' reads\n// 'Sign-ups — September 2026'. Never escaped: the canvas binds a title as\n// text, and the exports draw plain strings. A value belongs to a page's text,\n// never a title, so a value token reads as the em dash. '' for no title.\nexport function fillTitleTokens(title: string | null | undefined, context: TextTokenContext): string {\n return (title ?? '')\n .replace(VALUE_TOKEN_PATTERN, VALUE_EMPTY_TEXT)\n .replace(FIELD_TOKEN_PATTERN, (match, field: string) => fieldText(field, context));\n}\n\n// What a field token reads as, its field written as FIELD_TOKEN_PATTERN\n// captures it ('page.name', 'filter.12'). A {{filter.<id>}} token reads as its\n// filter's wording, the ellipsis while a select's names load, else the em\n// dash: the filter could not be read, or the report has no group of that id.\nexport function fieldText(field: string, context: TextTokenContext): string {\n const name = field.toLowerCase();\n\n if (!name.startsWith(FILTER_FIELD_PREFIX)) {\n return PAGE_FIELDS[name]?.text(context) ?? VALUE_EMPTY_TEXT;\n }\n\n const filter = context.filters?.[Number(name.slice(FILTER_FIELD_PREFIX.length))];\n\n return filter?.text ?? (filter?.loading ? VALUE_LOADING_TEXT : VALUE_EMPTY_TEXT);\n}\n\n// Walk a block's html into what the exports draw: the words between its tables\n// as paragraphs of styled runs, and each table as a grid of cells. Tokens are\n// filled first so a page number is just text by then. There is a text part for\n// every run of nodes splitAtTables finds, even one that holds no words, so the\n// nth text part is the nth run the export's DOM measure finds.\nexport function textBlocks(html: string, context: TextTokenContext): TextBlock[] {\n const document = new DOMParser().parseFromString(`<body>${fillTextTokens(html, context)}</body>`, 'text/html');\n const blocks = splitAtTables(document.body).map((part): TextBlock => {\n if (!Array.isArray(part)) {\n return { kind: 'table', table: parseTable(part) };\n }\n\n const fragment = document.createDocumentFragment();\n const paragraphs: TextParagraph[] = [];\n fragment.append(...part);\n walkBlocks(fragment, paragraphs, null);\n\n return { kind: 'text', paragraphs };\n });\n\n trimBlankEnd(blocks);\n\n return blocks;\n}\n\n// The block as paragraphs alone, for anything that draws no grid: a table reads\n// as a line per row, its cells' words joined by ' · '.\nexport function textParagraphs(html: string, context: TextTokenContext): TextParagraph[] {\n return blockParagraphs(textBlocks(html, context));\n}\n\n// Blocks textBlocks already walked, as textParagraphs reads them.\nexport function blockParagraphs(blocks: TextBlock[]): TextParagraph[] {\n return blocks.flatMap((block) => block.kind === 'text'\n ? block.paragraphs\n : block.table.rows.map(rowParagraph));\n}\n\n// The html as plain text — what a block says, for anything that cannot style it.\nexport function textPlain(html: string, context: TextTokenContext): string {\n return textParagraphs(html, context)\n .map((paragraph) => paragraph.runs.map((run) => run.text).join(''))\n .join('\\n');\n}\n\n// A block's top-level nodes split at each table: each table on its own, and\n// each run of the nodes between them as a list. A table sits only at the top\n// level (ReportTextHtml flattens any other), so this is the whole split.\n// textBlocks and the export's measure of the rendered block both split here.\nexport function splitAtTables(parent: Node): (Node[] | HTMLTableElement)[] {\n const parts: (Node[] | HTMLTableElement)[] = [];\n let run: Node[] | null = null;\n\n parent.childNodes.forEach((node) => {\n if (node.nodeName === 'TABLE') {\n parts.push(node as HTMLTableElement);\n run = null;\n } else if (run) {\n run.push(node);\n } else {\n run = [node];\n parts.push(run);\n }\n });\n\n return parts;\n}\n\n// A table as a grid of cells, each holding its words as paragraphs. Rows come\n// as a browser draws them, the head first and the foot last, whatever order the\n// html writes its sections in.\nexport function parseTable(element: HTMLTableElement): TextTable {\n const rows = Array.from(element.rows, (row): TextTableRow => ({\n section: tableSection(row),\n cells: Array.from(row.cells, tableCell),\n }));\n\n return tableGrid({ rows, columns: 0 });\n}\n\n// Where each cell sits, by the HTML table algorithm: a cell takes the first\n// column of its row that no cell spanning down from a row above holds. A rowspan\n// stops at the last row of its section, as a browser draws it, and the grid is\n// as wide as the widest right edge of any cell.\nexport function tableGrid(table: TextTable): TextTable {\n const taken: boolean[][] = table.rows.map(() => []);\n let columns = 0;\n\n const rows = table.rows.map((row, index): TextTableRow => {\n const sectionEnd = rowSectionEnd(table.rows, index);\n let column = 0;\n\n const cells = row.cells.map((cell): TextTableCell => {\n while (taken[index][column]) {\n column++;\n }\n\n const placed = { ...cell, row: index, column, rowSpan: Math.min(cell.rowSpan, sectionEnd - index) };\n occupy(taken, placed);\n column += placed.colSpan;\n columns = Math.max(columns, column);\n\n return placed;\n });\n\n return { ...row, cells };\n });\n\n return { rows, columns };\n}\n\nfunction tableSection(row: HTMLTableRowElement): TextTableRow['section'] {\n const section = row.parentElement?.nodeName;\n\n return section === 'THEAD' ? 'head' : section === 'TFOOT' ? 'foot' : 'body';\n}\n\n// One th or td. A header cell's runs are bold, and every paragraph takes the\n// cell's text-align unless it has its own: the default look centers a header\n// cell and puts any other on the left.\nfunction tableCell(cell: HTMLTableCellElement): TextTableCell {\n const header = cell.nodeName === 'TH';\n const align = cellAlign(cell.style.textAlign) ?? (header ? 'center' : 'left');\n const valign = cell.style.verticalAlign;\n const paragraphs: TextParagraph[] = [];\n\n walkBlocks(cell, paragraphs, null, header ? { bold: true } : {});\n\n return {\n paragraphs: paragraphs.map((paragraph) => ({ ...paragraph, align: paragraph.align ?? align })),\n colSpan: Math.max(1, cell.colSpan),\n rowSpan: Math.max(1, cell.rowSpan),\n row: 0,\n column: 0,\n align,\n valign: valign === 'top' || valign === 'middle' || valign === 'bottom' ? valign : undefined,\n fill: cell.style.backgroundColor ? hexColor(cell.style.backgroundColor) : undefined,\n };\n}\n\nfunction cellAlign(value: string): TextTableCell['align'] | undefined {\n return value === 'left' || value === 'center' || value === 'right' || value === 'justify' ? value : undefined;\n}\n\n// The index just past the last row of the section the row at index sits in.\nfunction rowSectionEnd(rows: TextTableRow[], index: number): number {\n let end = index + 1;\n while (end < rows.length && rows[end].section === rows[index].section) {\n end++;\n }\n\n return end;\n}\n\n// Mark the grid slots a placed cell covers.\nfunction occupy(taken: boolean[][], cell: TextTableCell): void {\n for (let row = cell.row; row < cell.row + cell.rowSpan; row++) {\n for (let column = cell.column; column < cell.column + cell.colSpan; column++) {\n taken[row][column] = true;\n }\n }\n}\n\n// A table row as one line of text: its cells in order, a cell's own lines\n// joined by a space.\nfunction rowParagraph(row: TextTableRow): TextParagraph {\n return {\n runs: row.cells.flatMap((cell, index) => [\n ...(index ? [{ text: TABLE_CELL_SEPARATOR }] : []),\n ...cell.paragraphs.flatMap((paragraph, line) => [...(line ? [{ text: ' ' }] : []), ...paragraph.runs]),\n ]),\n };\n}\n\n// An empty paragraph is a blank line the canvas draws (<p><br></p>, or an empty\n// <p>), so one at the start of the block keeps the words below it where the\n// canvas puts them. At the end of the whole block it draws nothing, and is\n// dropped so it never counts as running past the box. An empty paragraph\n// before a table is not at the end.\nfunction trimBlankEnd(blocks: TextBlock[]): void {\n const last = blocks[blocks.length - 1];\n\n while (last?.kind === 'text' && last.paragraphs.length && !last.paragraphs[last.paragraphs.length - 1].runs.length) {\n last.paragraphs.pop();\n }\n}\n\n// base is the style every run starts from: bold for a header cell's words.\nfunction walkBlocks(\n parent: Node,\n paragraphs: TextParagraph[],\n list: 'bullet' | 'number' | null,\n base: Partial<TextRun> = {},\n): void {\n // Loose inline content between blocks (text straight under the block, an\n // <li> or a cell) is gathered into a paragraph of its own.\n let loose: TextParagraph | null = null;\n const flush = () => {\n if (loose && isShown(loose)) {\n paragraphs.push(loose);\n }\n loose = null;\n };\n\n parent.childNodes.forEach((node) => {\n const name = node.nodeName.toLowerCase();\n\n if (name === 'ul' || name === 'ol' || name === 'li' || name === 'p' || /^h[1-3]$/.test(name)) {\n flush();\n walkBlock(node as HTMLElement, paragraphs, list, base);\n\n return;\n }\n\n loose = loose ?? { runs: [] };\n walkInline(node, base, loose, paragraphs, true);\n });\n\n flush();\n}\n\n// Whether loose content's last line shows anything. Whitespace alone between\n// blocks is not drawn, and a line a <br> ended was pushed when it ended, so a\n// trailing <br> adds no empty line after it.\nfunction isShown(loose: TextParagraph): boolean {\n return loose.runs.some((run) => /[^ \\t\\n\\r\\f]/.test(run.text));\n}\n\nfunction walkBlock(\n element: HTMLElement,\n paragraphs: TextParagraph[],\n list: 'bullet' | 'number' | null,\n base: Partial<TextRun>,\n): void {\n const name = element.nodeName.toLowerCase();\n\n if (name === 'ul' || name === 'ol') {\n walkBlocks(element, paragraphs, name === 'ul' ? 'bullet' : 'number', base);\n } else if (name === 'li') {\n const item: TextParagraph = { runs: [], bullet: list ?? 'bullet' };\n const nested: TextParagraph[] = [];\n // A list item's first paragraph IS the item; anything after it is its own\n // line under the same bullet.\n walkBlocks(element, nested, list, base);\n const [first, ...rest] = nested.length ? nested : [item];\n paragraphs.push({ ...first, bullet: list ?? 'bullet' }, ...rest);\n } else {\n walkParagraph(element, paragraphs, base);\n }\n}\n\n// A p or a heading. A <br> ends a line, so its last line is pushed only when it\n// holds words or no <br> came before it: <p><br></p> is one blank line,\n// <p>a<br></p> one line and <p>a<br>b</p> two, as a browser draws them.\nfunction walkParagraph(element: HTMLElement, paragraphs: TextParagraph[], base: Partial<TextRun>): void {\n const name = element.nodeName.toLowerCase();\n const heading = name.startsWith('h') ? Number(name[1]) : undefined;\n const paragraph: TextParagraph = {\n runs: [],\n align: blockAlign(element),\n bullet: undefined,\n heading,\n };\n const style: Partial<TextRun> = heading\n ? { ...base, bold: true, fontSize: HEADING_TEXT_SIZES[heading] }\n : base;\n\n const breaks = walkInline(element, style, paragraph, paragraphs);\n if (paragraph.runs.length || !breaks) {\n paragraphs.push(paragraph);\n }\n}\n\n// Accumulate inline styles down the tree. A <br> ends the current line: the\n// runs after it start a new paragraph with the same alignment and bullet.\n// Returns how many lines a <br> ended.\nfunction walkInline(\n node: Node,\n style: Partial<TextRun>,\n paragraph: TextParagraph,\n paragraphs: TextParagraph[],\n isSelf = false,\n): number {\n const nodes = isSelf ? [node] : Array.from(node.childNodes);\n\n return nodes.reduce((breaks, child) => breaks + walkInlineNode(child, style, paragraph, paragraphs), 0);\n}\n\nfunction walkInlineNode(\n node: Node,\n style: Partial<TextRun>,\n paragraph: TextParagraph,\n paragraphs: TextParagraph[],\n): number {\n if (node.nodeType === Node.TEXT_NODE) {\n const text = node.textContent ?? '';\n if (text) {\n paragraph.runs.push({ ...style, text });\n }\n\n return 0;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return 0;\n }\n\n const element = node as HTMLElement;\n\n if (element.nodeName.toLowerCase() === 'br') {\n paragraphs.push({ ...paragraph, runs: [...paragraph.runs] });\n paragraph.runs.length = 0;\n\n return 1;\n }\n\n return walkInline(element, { ...style, ...inlineStyle(element) }, paragraph, paragraphs);\n}\n\nfunction inlineStyle(element: HTMLElement): Partial<TextRun> {\n const name = element.nodeName.toLowerCase();\n const style: Partial<TextRun> = {};\n\n if (name === 'strong') {\n style.bold = true;\n }\n if (name === 'em') {\n style.italic = true;\n }\n if (name === 'u') {\n style.underline = true;\n }\n if (name === 's') {\n style.strike = true;\n }\n if (name === 'a') {\n style.link = element.getAttribute('href') ?? undefined;\n style.underline = true;\n }\n\n // What is no color leaves the color the run inherits.\n const css = element.style;\n const color = css.color ? hexColor(css.color) : undefined;\n const highlight = css.backgroundColor ? hexColor(css.backgroundColor) : undefined;\n if (color) {\n style.color = color;\n }\n if (highlight) {\n style.highlight = highlight;\n }\n if (css.fontSize) {\n style.fontSize = points(css.fontSize);\n }\n if (css.fontWeight) {\n style.bold = css.fontWeight === 'bold' || Number(css.fontWeight) >= 600;\n }\n if (css.fontStyle) {\n style.italic = css.fontStyle === 'italic';\n }\n if (css.textDecoration) {\n style.underline = css.textDecoration.includes('underline');\n style.strike = css.textDecoration.includes('line-through');\n }\n if (css.fontFamily) {\n style.fontFace = css.fontFamily.split(',')[0].replace(/[\"']/g, '').trim();\n }\n\n return style;\n}\n\nfunction blockAlign(element: HTMLElement): TextParagraph['align'] {\n const align = element.style.textAlign;\n\n return align === 'center' || align === 'right' || align === 'justify' ? align : undefined;\n}\n\n// A CSS font-size in points. The canvas renders at 96px per inch, so 1px is\n// exactly 0.75pt; em/rem/% are relative to the body size.\nfunction points(value: string): number | undefined {\n const match = /^([\\d.]+)(pt|px|em|rem|%)$/.exec(value.trim());\n if (!match) {\n return undefined;\n }\n\n const size = Number(match[1]);\n switch (match[2]) {\n case 'pt':\n return size;\n case 'px':\n return size * 0.75;\n case '%':\n return (size / 100) * DEFAULT_TEXT_SIZE;\n default:\n return size * DEFAULT_TEXT_SIZE;\n }\n}\n\n// Any CSS color the allowlist lets through (hex, rgb(), a name) as #rrggbb —\n// the one form both exports accept. The browser resolves it, so a named color\n// comes out exactly as the canvas painted it. A value that is no color of its\n// own (inherit, currentcolor, a typo) or paints nothing (transparent, an alpha\n// of 0) is undefined, so an export never paints it black.\nlet colorContext: CanvasRenderingContext2D | null = null;\n\nfunction hexColor(value: string): string | undefined {\n colorContext = colorContext ?? document.createElement('canvas').getContext('2d');\n if (!colorContext || /^\\s*currentcolor\\s*$/i.test(value)) {\n return undefined;\n }\n\n // A value the canvas cannot read leaves the color set before it, so it reads\n // back one way over black and another over white. (currentcolor reads as\n // black over both, hence the check above.)\n const resolved = resolveColor(colorContext, '#000000', value);\n if (resolved !== resolveColor(colorContext, '#ffffff', value)) {\n return undefined;\n }\n\n if (resolved.startsWith('#')) {\n return resolved;\n }\n\n // rgba(...) for a translucent color — drop the alpha, keep the hue.\n const [red, green, blue, alpha] = resolved.match(/[\\d.]+/g)?.map(Number) ?? [];\n\n return blue === undefined || alpha === 0\n ? undefined\n : `#${[red, green, blue].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`;\n}\n\n// What the canvas reads value as, set over seed.\nfunction resolveColor(context: CanvasRenderingContext2D, seed: string, value: string): string {\n context.fillStyle = seed;\n context.fillStyle = value;\n\n return String(context.fillStyle);\n}\n\nexport function escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n","// Whether a rise in a KPI's value is good news (revenue), bad news (refunds)\n// or neither. It colors the delta and judges whether a target is met.\n//\n// Mirrors the server's ChangePolarityEnum value for value.\nexport enum ReportChangePolarity {\n Good = 'good',\n Bad = 'bad',\n Neutral = 'neutral',\n}\n","import { ReportChangePolarity } from '../enums/report-change-polarity.enum';\nimport { ReportChartColor } from '../enums/report-chart-color.enum';\nimport { WaterfallStepKind } from '../interfaces/report.interface';\n\n\n// The report chart palette — one definition shared by the ECharts theme (on\n// screen), the PowerPoint export's native chart colors, and the PDF export,\n// so a series keeps its color across every medium.\nexport const REPORT_CHART_COLORS = [\n '4e79a7', 'f28e2b', 'e15759', '76b7b2', '59a14f',\n 'edc948', 'b07aa1', 'ff9da7', '9c755f', 'bab0ac',\n];\n\n// CSS-hex form for ECharts.\nexport const REPORT_CHART_COLORS_CSS = REPORT_CHART_COLORS.map((color) => `#${color}`);\n\n// A measure's named color is the palette entry at the name's position, so a\n// measure colored blue looks exactly like the first series left to the theme.\nexport const REPORT_CHART_COLOR_BY_NAME: Record<ReportChartColor, string> = {\n [ReportChartColor.Blue]: REPORT_CHART_COLORS[0],\n [ReportChartColor.Orange]: REPORT_CHART_COLORS[1],\n [ReportChartColor.Red]: REPORT_CHART_COLORS[2],\n [ReportChartColor.Teal]: REPORT_CHART_COLORS[3],\n [ReportChartColor.Green]: REPORT_CHART_COLORS[4],\n [ReportChartColor.Yellow]: REPORT_CHART_COLORS[5],\n [ReportChartColor.Purple]: REPORT_CHART_COLORS[6],\n [ReportChartColor.Pink]: REPORT_CHART_COLORS[7],\n [ReportChartColor.Brown]: REPORT_CHART_COLORS[8],\n [ReportChartColor.Gray]: REPORT_CHART_COLORS[9],\n};\n\n// Reference lines and bands are drawn in one neutral slate, apart from every\n// series color, so a target never reads as another series.\nexport const REPORT_REFERENCE_COLOR = '52606d';\n\n// A waterfall colors each bar by what it does to the running total, in the\n// order Excel and PowerPoint use by default: a rise takes the first series\n// color, a fall the second, and the closing total a neutral gray.\nexport const REPORT_WATERFALL_COLORS: Record<WaterfallStepKind, string> = {\n rise: REPORT_CHART_COLORS[0],\n fall: REPORT_CHART_COLORS[1],\n total: REPORT_CHART_COLORS[9],\n};\n\n// The slate of a tile's small print in both exports: a KPI's label, its\n// window and target lines, a component's notes.\nexport const REPORT_MUTED_TEXT_COLOR = '7b8794';\n\n// A KPI's change is colored by what it means rather than by its sign: green\n// when it is good news, red when it is bad news, slate when it is neither (a\n// flat change, or a value whose increaseIs is neutral). The same three colors\n// draw a target's progress (green once met). The card exposes each as a CSS\n// variable a host page can override: --report-kpi-good-color,\n// --report-kpi-bad-color and --report-kpi-neutral-color, set on any element\n// around the report.\nexport const REPORT_KPI_CHANGE_COLORS: Record<ReportChangePolarity, string> = {\n [ReportChangePolarity.Good]: REPORT_CHART_COLORS[4],\n [ReportChangePolarity.Bad]: REPORT_CHART_COLORS[2],\n [ReportChangePolarity.Neutral]: REPORT_MUTED_TEXT_COLOR,\n};\n\n// The track a KPI target's progress bar fills, in both exports.\nexport const REPORT_KPI_TRACK_COLOR = 'e4e7eb';\n\n// A KPI's sparkline takes the first series color, as a one-measure chart of\n// the same values would (--report-kpi-sparkline-color overrides it).\nexport const REPORT_KPI_SPARKLINE_COLOR = REPORT_CHART_COLORS[0];\n","// The report charts' typeface and axis-label size. The ECharts theme draws with\n// them, and the option builder measures axis labels with them, so the room it\n// leaves around the labels matches what is drawn.\nexport const REPORT_CHART_FONT_FAMILY = 'Roboto, \"Helvetica Neue\", sans-serif';\nexport const REPORT_AXIS_LABEL_FONT_SIZE = 11;\n// The size a chart's data labels (the values printed beside its points) are\n// drawn in: a step under the axis labels, so they never outweigh the axes.\nexport const REPORT_DATA_LABEL_FONT_SIZE = 10;\n// The size, in pixels, a KPI card's value is drawn in on screen: the one large\n// number on the tile. Its label, change and other lines take the FsStyle\n// .small text or the body size.\nexport const REPORT_KPI_VALUE_FONT_SIZE = 34;\n","import type {\n EChartsOption,\n LegendComponentOption,\n SeriesOption,\n TooltipComponentFormatterCallbackParams,\n TooltipComponentOption,\n} from 'echarts';\n\nimport {\n addDays,\n addMonths,\n addQuarters,\n addWeeks,\n addYears,\n endOfMonth,\n formatISO,\n isLastDayOfMonth,\n isValid,\n max as latestOf,\n min as earliestOf,\n parseISO,\n startOfDay,\n} from 'date-fns';\n\nimport { ReportChartColor } from './enums/report-chart-color.enum';\nimport { ReportChartDataLabels } from './enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from './enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from './enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from './enums/report-chart-mark-stat.enum';\nimport { ReportListColumnFormat } from './enums/report-list-column-format.enum';\nimport { ReportNumberUnits } from './enums/report-number-units.enum';\nimport { ReportValueFormat } from './enums/report-value-format.enum';\nimport {\n axisNumberFormat,\n ChartNumberFormat,\n chartValuePeak,\n comparisonOffsetLabel,\n DAY_SHORT,\n dateFormat,\n formatDayRange,\n formatDayWindow,\n formatLocalDate,\n FormattedOutputValue,\n formatNumber,\n formatOutputValue,\n formatPlainNumber,\n hasNumberFormat,\n laneOutputAlias,\n MONTH_DAY,\n MONTH_LONG,\n MONTH_YEAR,\n resolveChartNumberFormat,\n windowText,\n} from './format';\nimport {\n AxisChartType,\n ChartConfig,\n ChartGranularity,\n ChartMeasure,\n ChartReference,\n ChartValueAxis,\n ComparisonOffset,\n ComparisonWindow,\n ComponentComparison,\n ComponentData,\n GRANULARITY_OPTIONS,\n LegendPosition,\n ListColumn,\n ListConfig,\n NumberFormatSpec,\n OutputMeta,\n OutputRole,\n ReportComponent,\n ReportFormatContext,\n ReportLocaleTag,\n WaterfallStepKind,\n WindowMeta,\n} from './interfaces/report.interface';\nimport { ReportMarkAction } from './interfaces/report-mark-action.type';\nimport { escapeHtml } from './text';\nimport {\n REPORT_CHART_COLOR_BY_NAME,\n REPORT_CHART_COLORS,\n REPORT_CHART_COLORS_CSS,\n REPORT_REFERENCE_COLOR,\n REPORT_WATERFALL_COLORS,\n} from './theme/palette';\nimport { REPORT_AXIS_LABEL_FONT_SIZE, REPORT_CHART_FONT_FAMILY, REPORT_DATA_LABEL_FONT_SIZE } from './theme/typography';\n\n\n// Room for an axis title. ECharts 5's containLabel keeps the TICK labels inside\n// the grid but not the axis name, so without this a vertical chart's category\n// title runs off the bottom edge or under a bottom legend, and its value title\n// above the plot runs off the top or under a top legend.\nconst AXIS_NAME_ROOM = 20;\n// ECharts' own default gap between the axis line and its tick labels.\nconst AXIS_LABEL_MARGIN = 8;\n// Clearance between the longest tick label and a horizontal chart's rotated\n// title, so the two never touch.\nconst AXIS_NAME_CLEARANCE = 6;\n// A horizontal chart's category labels are cut short with an ellipsis past\n// this width (the tooltip still shows them in full), so one long label cannot\n// squeeze the plot away.\nconst CATEGORY_LABEL_MAX_WIDTH = 160;\nconst LABEL_ELLIPSIS = '…';\n// The font the theme draws axis labels in, as a canvas font string. Labels are\n// measured in it the way ECharts measures them for containLabel, so a\n// horizontal chart's title lands exactly beyond the widest label.\nconst AXIS_LABEL_FONT = `${REPORT_AXIS_LABEL_FONT_SIZE}px ${REPORT_CHART_FONT_FAMILY}`;\n// The letter a quarter label starts with, by language subtag. French writes the\n// second quarter 'T2' (trimestre); every other language reads 'Q2'.\nconst QUARTER_PREFIXES = new Map<string, string>([['fr', 'T']]);\nconst QUARTER_PREFIX = 'Q';\n// A 100% stacked chart's value axis: whole percentages, a gridline every 25%,\n// up to 100%. Its tooltip gives each share to one decimal.\nconst PERCENT_AXIS_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Percent, precision: 0 };\nconst PERCENT_SHARE_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Percent, precision: 1 };\nexport const PERCENT_AXIS_MAX = 1;\nexport const PERCENT_AXIS_INTERVAL = 0.25;\n// A reference band's fill: the reference slate, faint enough that the series\n// drawn across it stay readable.\nconst REFERENCE_BAND_FILL = 'rgba(82, 96, 109, 0.08)';\n// A reference's or statistic line's label sits on a light box, so it stays\n// readable where it crosses a bar or a line.\nconst MARK_LABEL_BOX = { backgroundColor: 'rgba(255, 255, 255, 0.85)', padding: [1, 3], borderRadius: 2 };\n// The room an axis stretched to a reference leaves above it, for its label:\n// the bound is the round number at or past the reference plus this share.\nconst REFERENCE_HEADROOM = 1.05;\n\n// How a chart marks what the server says of its numbers (ComponentData's\n// comparison, outputs, windows and partialPeriod). The words are interface\n// text, English in every report locale.\n// - The heading of a period not over yet ('September 2026 (to date)').\nconst PARTIAL_PERIOD_TEXT = 'to date';\n// - A compared series' name: its measure's, then its role and lane ('Revenue\n// change (vs previous week)'). A prior keeps the measure's name alone.\nconst ROLE_NAME_SUFFIXES: Record<Exclude<OutputRole, 'current'>, string> = {\n prior: '',\n change: ' change',\n percent_change: ' % change',\n};\n// - A prior series' bars: its current series' color, faded, with a dashed\n// edge. Its line is dashed (PRIOR_LINE_STYLE) unless its measure names one.\nconst PRIOR_BAR_OPACITY = 0.45;\nconst PRIOR_LINE_STYLE = ReportChartLineStyle.Dashed;\n// - The period not over yet: its bar hatched in light stripes, its point on a\n// line drawn larger with a dashed edge, and, when it is the last one, the\n// line's last segment dashed.\nconst PARTIAL_LINE_STYLE = ReportChartLineStyle.Dashed;\nconst PARTIAL_BAR_DECAL = {\n symbol: 'none',\n dashArrayX: [1, 0],\n dashArrayY: [3, 5],\n rotation: -Math.PI / 4,\n color: 'rgba(255, 255, 255, 0.6)',\n};\nconst PARTIAL_POINT_MARK = { symbol: 'emptyCircle', symbolSize: 9, itemStyle: { borderType: 'dashed' } };\n// - The last segment's series id: this, then the index of the series it\n// continues (partialSegmentId).\nconst PARTIAL_SEGMENT_ID = 'partial-segment-';\n// - A value axis of ranks only: rank 1 at the top, whole steps, from 1.\nconst RANK_AXIS_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Number, precision: 0 };\n// (Shared with the PowerPoint export, whose rank axes start there too.)\nexport const RANK_AXIS_MIN = 1;\n// - A value axis of 0-1 fractions only (shares, percent changes) is a\n// percent axis, its decimals decided by its peak.\nconst FRACTION_AXIS_FORMAT: NumberFormatSpec = { format: ReportValueFormat.Percent };\n// - Between a tooltip value and what it covers.\nconst TOOLTIP_DETAIL_SEPARATOR = ' · ';\n// - The prior a tooltip value is compared with, when the chart does not plot\n// it ('vs 50% (Sep 1 – 2, 2026)').\nconst COMPARED_PRIOR_PREFIX = 'vs';\n\n// The tooltip's last line on a chart whose marks act on a click\n// (markActionHint): one action by its full name, several by their short\n// names, in this order. Interface text, English in every report locale.\nconst MARK_ACTION_ORDER: readonly ReportMarkAction[] = ['drill', 'crossFilter', 'showRows'];\nconst MARK_ACTION_HINTS: Record<ReportMarkAction, string> = {\n drill: 'drill down',\n crossFilter: 'filter other tiles',\n showRows: 'show rows',\n};\nconst MARK_ACTION_SHORT_HINTS: Record<ReportMarkAction, string> = {\n drill: 'drill down',\n crossFilter: 'filter',\n showRows: 'show rows',\n};\n\n// The words a statistic line's label starts with. They are interface text,\n// English in every report locale; only the value after them follows it.\nexport const STAT_LABEL: Record<ReportChartMarkStat, string> = {\n [ReportChartMarkStat.Average]: 'Average',\n [ReportChartMarkStat.Median]: 'Median',\n [ReportChartMarkStat.Min]: 'Minimum',\n [ReportChartMarkStat.Max]: 'Maximum',\n};\n\n// Which edge of the plot an axis title sits on. The category axis's is below a\n// vertical chart and to the left of a horizontal one; the value axis's is above\n// a vertical chart and below a horizontal one.\ntype AxisTitleSide = 'top' | 'bottom' | 'left';\n\n// Which value axis a series is plotted against: 0 the primary, 1 the second\n// axis on the right.\nexport type ValueAxisIndex = 0 | 1;\n\n// What valueAxisOption adds for one axis. `index` is the axis of a two-axis\n// chart it builds: the second one's title is aligned to read leftward from the\n// right edge. `percentMin` makes it a 100% stacked chart's share axis, from\n// that bound (0, or -1 when a share is negative) up to 100%, whatever range\n// the config pins. `reach` is the span of the references plotted against it,\n// which the axis stretches to when the data falls short of them. `rank`\n// inverts it.\ninterface ValueAxisExtras {\n index?: ValueAxisIndex;\n percentMin?: number;\n reach?: ReferenceReach;\n // Every series on the axis plots a rank: it runs from rank 1 at the top in\n // whole steps.\n rank?: boolean;\n}\n\n// A reference as the chart draws it: its lower and upper edge (the same value\n// for a line), whether it is a band, and the value axis it is plotted against.\n// Shared with the PowerPoint export, which draws each edge as a constant line.\nexport interface DrawnReference {\n label: string;\n low: number;\n high: number;\n band: boolean;\n axisIndex: ValueAxisIndex;\n}\n\n// The lowest and highest edge of the references on one value axis.\ninterface ReferenceReach {\n low: number;\n high: number;\n}\n\n// What ECharts hands a value axis's min and max callbacks: the extent of the\n// data plotted against it.\ninterface AxisExtent {\n min: number;\n max: number;\n}\n\n// One point of a 100% stacked series: its share of the category's total,\n// which ECharts plots and stacks, and the value it came from.\ninterface ShareDataItem {\n value: number | null;\n raw: number | null;\n}\n\n// A point that prints its own data label: a 'last' series' latest point,\n// keeping the raw value a 100% stacked point carries.\ninterface LabeledDataItem<P extends DataLabelPosition> {\n value: number | null;\n raw?: number | null;\n label: DataLabel<P>;\n}\n\ntype SeriesDataItem<P extends DataLabelPosition> = number | null | ShareDataItem | LabeledDataItem<P>;\n\n// What a data label's formatter is handed: the point's plotted value, its\n// data item as given (a number, or an object carrying the raw value), and its\n// index.\ninterface DataLabelParams {\n value?: unknown;\n data?: unknown;\n dataIndex?: number;\n}\n\nexport type DataLabelFormatter = (params: DataLabelParams) => string;\n\n// Where a data label sits: 'outside' past an unstacked bar's end, on the side\n// its sign points to; 'inside' a stacked bar; 'top' above a line or area\n// point. ECharts takes 'outside' on a bar only.\nexport type DataLabelPosition = 'top' | 'inside' | 'outside';\n\n// One ECharts label, as a series or a single point prints it.\nexport interface DataLabel<P extends DataLabelPosition = DataLabelPosition> {\n show: true;\n position: P;\n fontSize: number;\n formatter: DataLabelFormatter;\n}\n\n// A series' data labels as dataLabelOption decides them, before buildSeries\n// places them by what the series draws: the label's text and size, whether\n// labels that would overlap are hidden ('auto'), and whether only the latest\n// point prints one ('last').\nexport interface SeriesDataLabels {\n text: Omit<DataLabel, 'position'>;\n hideOverlap: boolean;\n lastOnly: boolean;\n}\n\n// A series' data labels placed: `series` is spread over the series (its\n// label, and for 'auto' the overlap hiding), and `data` is its points, the\n// latest non-empty one carrying the label for 'last'.\ninterface PlacedDataLabels<P extends DataLabelPosition> {\n series: { label?: DataLabel<P>; labelLayout?: { hideOverlap: boolean } };\n data: SeriesDataItem<P>[];\n}\n\n// A value axis's number format, decided once for the axis: the format the\n// measures plotted against it agree on (axisNumberFormat), with the units and\n// decimals its peak calls for, and the context its ticks are written in (an\n// axis of 0-1 fractions reads them as ratios whatever the report's\n// percentFormat). null is a plain axis. Its ticks and its series' data labels\n// both write in it.\ninterface ValueAxisFormat {\n spec: NumberFormatSpec;\n chart: ChartNumberFormat;\n context: ReportFormatContext;\n}\n\n// The shares a 100% stacked chart draws, by the index of the extracted series\n// they replace.\nexport type PercentShares = Map<number, (number | null)[]>;\n\n// The plot's distance from each edge of the chart, in pixels.\ninterface AxisGridRoom {\n left: number;\n right: number;\n top: number;\n bottom: number;\n containLabel: boolean;\n}\n\n\n// colorBy applies only to single-dimension bar charts, and only when splitBy\n// isn't already driving multiple series: it colors each bar by its category and\n// shows a legend (one series per category, overlapped to full width).\n//\n// It is the DEFAULT for a categorical bar chart rather than something the config\n// has to ask for. A bar chart whose x-axis is a category — regions, statuses,\n// stores — is comparing those categories to each other, and one flat color with\n// no legend is the wrong reading of it in essentially every case. Requiring\n// colorBy to opt in meant every such chart rendered monochrome unless whoever\n// wrote the config remembered an optional property, which is a default set the\n// wrong way round: the common case should not need the flag.\n//\n// A TIME axis is excluded: consecutive periods are one series moving, not\n// categories being compared, and coloring each month differently reads as\n// unrelated groups. Explicitly opting out — colorBy: {column: ''}, a color on\n// the measure or a config.legend of 'hidden' — still wins, so a caller that\n// wants one flat color can say so.\n//\n// \"Bar chart\" is the type the lone measure is actually DRAWN as: its own type\n// when it names one, which can turn a line chart's single series into bars or\n// a bar chart's into a line.\nexport function isColorBy(config: ChartConfig): boolean {\n if (config.splitBy?.column || (config.measures?.[0]?.type ?? config.chartType ?? 'bar') !== 'bar') {\n return false;\n }\n\n if (config.colorBy) {\n return !!config.colorBy.column;\n }\n\n // A measure given its own color asks for one flat color.\n if (measureColorHex(config.measures?.[0])) {\n return false;\n }\n\n return (config.xAxis?.kind ?? 'category') === 'category'\n && !config.xAxis?.granularity\n && (config.measures?.length ?? 1) <= 1;\n}\n\n\n// The column colorBy groups by — its own when the config named one, otherwise\n// the x-axis it defaults to coloring.\nexport function colorByColumn(config: ChartConfig): string | undefined {\n return isColorBy(config)\n ? (config.colorBy?.column || config.xAxis?.column)\n : undefined;\n}\n\n\n// Categories + named series extracted from a chart component's config + rows —\n// the one pivot (splitBy → series, measures → series) shared by the on-screen\n// ECharts option below AND the PowerPoint export's native chart data, so both\n// media plot identical numbers.\n//\n// A series' `type` is the type its measure asks to be drawn as, and is absent\n// when the measure leaves it to the chart's chartType (see seriesTypes). Its\n// `measure` is the one it plots, whose number format its tooltip uses and\n// whose display keys (color, axis) it follows, and `measureIndex` that\n// measure's position: the first measure, 0, for every series of a splitBy or\n// colorBy chart.\n//\n// rawCategories holds each category as data.rows hold it, by position, and\n// rawGroups each split (or colorBy) value by series position, empty when the\n// chart does not split: a click names the raw values, never the drawn text.\n// The PowerPoint export reads only categories and series.\nexport interface ExtractedChartSeries {\n categories: string[];\n series: ExtractedChartSeriesItem[];\n rawCategories: unknown[];\n rawGroups: unknown[];\n}\n\nexport interface ExtractedChartSeriesItem {\n name: string;\n values: (number | null)[];\n type?: AxisChartType;\n measure: ChartMeasure;\n measureIndex: number;\n}\n\nexport function extractChartSeries(component: ReportComponent, data: ComponentData): ExtractedChartSeries {\n const config = component.config as ChartConfig;\n const { xColumn, groupColumn } = chartColumns(config, data);\n const measures = chartMeasures(config, data);\n\n const rawCategories = uniqueValues(data.rows, xColumn);\n const categories = rawCategories.map((category) => String(category ?? '—'));\n const series: ExtractedChartSeries['series'] = [];\n const rawGroups = groupColumn ? uniqueValues(data.rows, groupColumn) : [];\n\n if (groupColumn) {\n // One series per group value (splitBy/colorBy), pivoted over the first measure.\n const measure = measures[0];\n for (const groupValue of rawGroups) {\n series.push({\n name: String(groupValue ?? '—'),\n values: categoryValues(data.rows, xColumn, rawCategories, measure.column, (row) => row[groupColumn] === groupValue),\n type: measure.type,\n measure,\n measureIndex: 0,\n });\n }\n } else {\n for (const [measureIndex, measure] of measures.entries()) {\n series.push({\n name: comparedSeriesName(measure, measures, data) ?? measure.label ?? measure.column,\n values: categoryValues(data.rows, xColumn, rawCategories, measure.column),\n type: measure.type,\n measure,\n measureIndex,\n });\n }\n }\n\n return { categories, series, rawCategories, rawGroups };\n}\n\n// The column a chart's categories come from, and the one that splits its\n// first measure into a series per value, if any. colorBy emits one series per\n// category too (so each bar carries its own color + legend entry), but the\n// bars are overlapped to full width in buildAxisOption rather than laid\n// side-by-side. splitBy wins if both are set.\nexport function chartColumns(config: ChartConfig, data: ComponentData): { xColumn: string; groupColumn: string | undefined } {\n return {\n xColumn: config.xAxis?.column ?? data.columns[0],\n groupColumn: config.splitBy?.column || colorByColumn(config),\n };\n}\n\n// One column's values by category, from the rows `match` keeps (all of them\n// when it is left out). A category with no row has no value.\nfunction categoryValues(\n rows: Record<string, unknown>[],\n xColumn: string,\n rawCategories: unknown[],\n column: string,\n match?: (row: Record<string, unknown>) => boolean,\n): (number | null)[] {\n const byCategory = new Map<unknown, unknown>();\n for (const row of rows) {\n if (!match || match(row)) {\n byCategory.set(row[xColumn], row[column]);\n }\n }\n\n return rawCategories.map((category) => numeric(byCategory.get(category)));\n}\n\n// A compared series' name, worded from its lane's offset rather than from its\n// own label, so a chart the viewer regrouped says what it now compares:\n// 'Revenue (vs previous week)', 'Revenue change (vs previous week)', 'Revenue\n// % change (vs previous year)'. The measure is named as its current value's\n// series is. null for any other series, which keeps its own name, and for\n// data without the comparison keys.\nfunction comparedSeriesName(measure: ChartMeasure, measures: ChartMeasure[], data: ComponentData): string | null {\n const output = data.outputs?.[measure.column];\n const offset = output?.offset ? data.comparison?.offsets?.[output.offset - 1] : undefined;\n\n if (!output || !offset || !output.role || output.role === 'current') {\n return null;\n }\n\n const current = currentOutputAlias(data.outputs, measure.column);\n const label = measures.find((candidate) => candidate.column === current)?.label ?? current;\n\n return `${label}${ROLE_NAME_SUFFIXES[output.role]} (${comparisonOffsetLabel(offset)})`;\n}\n\n// The column an output's current value is in: its lane's current output, else\n// for a rank or a share the uncompared one of the same measure, else the\n// measure's own column (a windowed value's source).\nfunction currentOutputAlias(outputs: Record<string, OutputMeta>, alias: string): string {\n const output = outputs[alias];\n const uncompared = output.kind === 'value'\n ? undefined\n : Object.keys(outputs).find((key) => outputs[key].measure === output.measure\n && outputs[key].kind === output.kind\n && outputs[key].role === null);\n\n return laneOutputAlias(outputs, alias, 'current') ?? uncompared ?? output.measure;\n}\n\n// A series' own color as CSS hex: its measure's named color, or undefined when\n// it names none (or a name the palette does not know) and the theme colors it\n// by its position.\nexport function seriesColor(series: ExtractedChartSeriesItem): string | undefined {\n const hex = namedColorHex(series);\n\n return hex ? `#${hex}` : undefined;\n}\n\n// A series' color as the bare hex PowerPoint takes: its measure's named color,\n// else the palette color of its position, as the screen's theme picks it.\nexport function seriesHex(series: ExtractedChartSeriesItem, index: number): string {\n return namedColorHex(series) ?? REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length];\n}\n\nfunction namedColorHex(series: ExtractedChartSeriesItem): string | undefined {\n return measureColorHex(series.measure);\n}\n\n// A measure's named color as bare hex, or undefined when it names none or a\n// name the palette does not know. The name is read through the enum, so a\n// stored name such as '__proto__' never reaches the lookup object.\nfunction measureColorHex(measure: ChartMeasure | undefined): string | undefined {\n const color = Object.values(ReportChartColor).find((name) => name === measure?.color);\n\n return color ? REPORT_CHART_COLOR_BY_NAME[color] : undefined;\n}\n\n// A measure's line style when it names one ECharts knows, else undefined and\n// the line is solid.\nexport function measureLineStyle(measure: ChartMeasure | undefined): ReportChartLineStyle | undefined {\n return Object.values(ReportChartLineStyle).find((style) => style === measure?.line);\n}\n\n// A measure's statistic line when it names one the viewer knows, else\n// undefined and it draws none.\nexport function measureMarkStat(measure: ChartMeasure | undefined): ReportChartMarkStat | undefined {\n return Object.values(ReportChartMarkStat).find((stat) => stat === measure?.markLine);\n}\n\n// A series' statistic over its points that have a value: their mean, their\n// median (the mean of the two middle values when the count is even), the\n// lowest or the highest. null when no point has a value. Shared with the\n// PowerPoint export so both media draw the line at the same height.\nexport function seriesStat(values: (number | null)[], stat: ReportChartMarkStat): number | null {\n const present = values.filter((value): value is number => typeof value === 'number' && Number.isFinite(value));\n\n if (!present.length) {\n return null;\n }\n\n switch (stat) {\n case ReportChartMarkStat.Average:\n return present.reduce((sum, value) => sum + value, 0) / present.length;\n case ReportChartMarkStat.Median: {\n const sorted = [...present].sort((a, b) => a - b);\n const middle = Math.floor(sorted.length / 2);\n\n return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2;\n }\n case ReportChartMarkStat.Min:\n return Math.min(...present);\n case ReportChartMarkStat.Max:\n return Math.max(...present);\n default:\n return null;\n }\n}\n\n// Whether a chart draws statistic lines. A horizontal chart's values run\n// along x, and PowerPoint cannot draw a line beside horizontal bars, so\n// neither medium draws one there.\nexport function drawsStatLines(config: ChartConfig): boolean {\n return config.orientation !== 'horizontal';\n}\n\n// A colorBy chart's one value per category: series i holds category i's bar.\n// PowerPoint draws these as its one series, and a statistic line is taken\n// over them.\nexport function colorByValues(extracted: ExtractedChartSeries): (number | null)[] {\n return extracted.categories.map((_, index) => extracted.series[index]?.values[index] ?? null);\n}\n\n// The references a chart draws. A vertical axis chart and a waterfall draw\n// them; a pie has no value axis, and a horizontal chart is left without them\n// as PowerPoint cannot draw a line beside horizontal bars. An entry without a\n// finite value is skipped, and one whose `to` is missing or equal to its value\n// is a line. secondary reaches the second value axis only on a chart that has\n// one (twoAxes). Shared with the PowerPoint export.\nexport function chartReferences(config: ChartConfig, twoAxes: boolean): DrawnReference[] {\n const chartType = config.chartType ?? 'bar';\n const references: (ChartReference | null | undefined)[] = Array.isArray(config.references) ? config.references : [];\n\n if (config.orientation === 'horizontal' || chartType === 'pie' || chartType === 'donut') {\n return [];\n }\n\n return references.flatMap((reference): DrawnReference[] => {\n const value = axisNumber(reference?.value);\n\n if (!reference || value === undefined) {\n return [];\n }\n\n const to = axisNumber(reference.to);\n const label = typeof reference.label === 'string' ? reference.label : '';\n const axisIndex: ValueAxisIndex = twoAxes && reference.secondary === true ? 1 : 0;\n\n return [to !== undefined && to !== value\n ? { label, low: Math.min(value, to), high: Math.max(value, to), band: true, axisIndex }\n : { label, low: value, high: value, band: false, axisIndex }];\n });\n}\n\n// Each series as its share of its category's total: per category, the\n// denominator is the sum of every series' absolute value there, so the\n// magnitudes of a category's shares add up to 1. A mixed-sign category's\n// negative values take negative shares, drawn below zero. A missing value\n// stays missing, and a category whose total is zero has no shares. Shared by\n// the screen, the PDF and PowerPoint, so a 100% stack reads the same in each.\nexport function percentShares(values: (number | null)[][]): (number | null)[][] {\n const length = Math.max(0, ...values.map((series) => series.length));\n const totals = Array.from({ length }, (_, index) => values\n .reduce((sum, series) => sum + Math.abs(series[index] ?? 0), 0));\n\n return values.map((series) => series.map((value, index) => (\n value === null || !totals[index] ? null : value / totals[index]\n )));\n}\n\n// The shares a 100% stacked chart draws in place of its values, or null when\n// the chart is not one. The primary axis's bar and area series take them,\n// each type's series sharing among themselves, as each type stacks apart.\n// Lines and secondary-axis series keep their values. A pie, a waterfall and a\n// colorBy chart (one series per category, each of which would be 100%) are\n// never 100% stacked, nor is a chart with no bar or area on its primary axis.\nexport function percentStackedShares(extracted: ExtractedChartSeries, config: ChartConfig): PercentShares | null {\n const chartType = config.chartType ?? 'bar';\n\n if (config.percentStacked !== true\n || chartType === 'pie' || chartType === 'donut' || chartType === 'waterfall'\n || isColorBy(config)) {\n return null;\n }\n\n const types = seriesTypes(extracted, chartType);\n const axisIndexes = seriesAxisIndexes(extracted, config);\n const shares: PercentShares = new Map();\n\n for (const type of ['bar', 'area'] as const) {\n const indexes = types\n .map((seriesType, index) => (seriesType === type && axisIndexes[index] === 0 ? index : -1))\n .filter((index) => index >= 0);\n const typeShares = percentShares(indexes.map((index) => extracted.series[index].values));\n indexes.forEach((seriesIndex, position) => shares.set(seriesIndex, typeShares[position]));\n }\n\n return shares.size ? shares : null;\n}\n\n// Where a 100% stacked chart's value axis starts: at -100% when any share is\n// negative, else at zero.\nexport function percentAxisMin(shares: PercentShares): number {\n return [...shares.values()].some((series) => series.some((share) => (share ?? 0) < 0)) ? -1 : 0;\n}\n\n// The measures a chart plots: its configured ones, else the query's last\n// column, unformatted.\nfunction chartMeasures(config: ChartConfig, data: ComponentData): ChartMeasure[] {\n return config.measures?.length\n ? config.measures\n : [{ column: data.columns[data.columns.length - 1] }];\n}\n\n// The type each extracted series is drawn as: its measure's own type when it\n// names one, the chart's chartType otherwise. More than one distinct type is a\n// combo chart. Shared with the PowerPoint export so both media draw each series\n// the same way.\nexport function seriesTypes(extracted: ExtractedChartSeries, chartType: AxisChartType): AxisChartType[] {\n return extracted.series.map((series) => series.type ?? chartType);\n}\n\n// The value axis each extracted series is plotted against: 1 when its measure\n// is secondary, 0 otherwise. A second axis is drawn only on a vertical chart\n// that keeps at least one series on the primary axis, so a combination the\n// server refuses (a horizontal chart, every measure secondary, the one measure\n// of a splitBy or colorBy chart) plots everything on the primary axis. Shared\n// with the PowerPoint export so both media put each series on the same axis.\nexport function seriesAxisIndexes(extracted: ExtractedChartSeries, config: ChartConfig): ValueAxisIndex[] {\n const secondary = extracted.series.map((series) => !!series.measure.secondary);\n const twoAxes = config.orientation !== 'horizontal' && secondary.includes(true) && secondary.includes(false);\n\n return secondary.map((isSecondary) => (twoAxes && isSecondary ? 1 : 0));\n}\n\n// One bar of a waterfall. `start` is the running total before it, where the bar\n// starts, and `change` its signed height, so it ends at start + change. The\n// closing total starts at zero and its change is the whole running total.\nexport interface WaterfallStep {\n category: string;\n start: number;\n change: number | null;\n kind: WaterfallStepKind;\n}\n\nexport interface ExtractedWaterfall {\n name: string;\n steps: WaterfallStep[];\n}\n\nexport const WATERFALL_TOTAL_LABEL = 'Total';\n\n// A waterfall's bars from its one measure: each category's value is how far the\n// running total moves there, and a last Total bar shows where it ended. A\n// category with no value moves nothing and draws no bar. Shared with the\n// PowerPoint export so both media draw the same steps.\nexport function extractWaterfall(component: ReportComponent, data: ComponentData): ExtractedWaterfall {\n const extracted = extractChartSeries(component, data);\n const values = extracted.series[0]?.values ?? [];\n const steps: WaterfallStep[] = [];\n let total = 0;\n\n extracted.categories.forEach((category, index) => {\n const change = values[index] ?? null;\n steps.push({ category, start: total, change, kind: (change ?? 0) < 0 ? 'fall' : 'rise' });\n total += change ?? 0;\n });\n\n steps.push({ category: WATERFALL_TOTAL_LABEL, start: 0, change: total, kind: 'total' });\n\n return { name: extracted.series[0]?.name ?? '', steps };\n}\n\n// The one pure mapping from our standard camelCase chart config + the data\n// endpoint's rows to an ECharts option. Everything visual that isn't in the\n// registered 'report' theme is decided here, so report standards have exactly\n// two homes.\n//\n// Every number and period the chart writes (value-axis ticks, tooltip values,\n// period labels) is in the context's locale, never the browser's. A measure\n// with number-format keys formats its tooltips, and the value axis when every\n// measure on it agrees (axisNumberFormat); without them the axis and tooltips\n// keep the plain locale-grouped number.\n//\n// legendSelected is the viewer's legend: which entries are on, by series\n// name (legendWithSelected). Without it the option is as it always was.\n//\n// actions are what a click on the chart's marks does (B10.2), for the\n// screen only: the series a click acts on show a hand and answer a click on\n// the line itself, and the tooltip ends with a muted line naming the actions\n// (withClickActions). Without actions the pointer stays an arrow. An export\n// passes none.\nexport function buildChartOption(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n legendSelected: Readonly<Record<string, boolean>> = {},\n actions: readonly ReportMarkAction[] = [],\n): EChartsOption {\n return withClickActions(legendWithSelected(chartOption(component, data, context), legendSelected), actions);\n}\n\n// The tooltip's last line on a chart whose marks act on a click: the one\n// action ('Click to drill down', 'Click to filter other tiles', 'Click to\n// show rows'), or the short names of several ('Click to drill down or\n// filter', 'Click to drill down, filter or show rows'). null without one.\nexport function markActionHint(actions: readonly ReportMarkAction[]): string | null {\n const offered = MARK_ACTION_ORDER.filter((action) => actions.includes(action));\n\n if (offered.length === 1) {\n return `Click to ${MARK_ACTION_HINTS[offered[0]]}`;\n }\n\n const names = offered.map((action) => MARK_ACTION_SHORT_HINTS[action]);\n\n return names.length\n ? `Click to ${names.slice(0, -1).join(', ')} or ${names[names.length - 1]}`\n : null;\n}\n\n// Tells the viewer what a click on the chart does. With actions, every\n// series a click reaches (all but the silent reference carriers and a\n// waterfall's base) shows a hand, a line or area series answers a click on\n// its line too (triggerLineEvent), not only on its points, and the tooltip\n// gains the hint as its last line, muted. Without actions those series keep\n// the arrow and the tooltip is unchanged.\nfunction withClickActions(option: EChartsOption, actions: readonly ReportMarkAction[]): EChartsOption {\n const hint = markActionHint(actions);\n const series = ((option.series ?? []) as SeriesOption[]).map((item) => {\n if ((item as { silent?: boolean }).silent) {\n return item;\n }\n\n return {\n ...item,\n cursor: hint ? 'pointer' : 'default',\n ...(hint && item.type === 'line' ? { triggerLineEvent: true } : {}),\n } as SeriesOption;\n });\n\n return hint\n ? { ...option, series, tooltip: hintedTooltip(option.tooltip as TooltipComponentOption | undefined, series, hint) }\n : { ...option, series };\n}\n\n// The chart's tooltip with the hint as its muted last line. A tooltip that\n// writes its own text keeps it; one ECharts writes by itself is written here\n// as the other tooltips are: the category, then each series' value in its own\n// tooltip format (an item tooltip names the hovered item instead). An item\n// that keeps the arrow (a waterfall's Total) gets no hint.\nfunction hintedTooltip(\n tooltip: TooltipComponentOption | undefined,\n series: SeriesOption[],\n hint: string,\n): TooltipComponentOption {\n const line = `<span style=\"opacity: 0.7\">${escapeHtml(hint)}</span>`;\n const own = typeof tooltip?.formatter === 'function' ? tooltip.formatter : null;\n\n return {\n ...tooltip,\n formatter: (params: TooltipComponentFormatterCallbackParams) => {\n const text = own ? String(own(params, '', () => undefined) ?? '') : plainTooltip(params, series);\n\n if (!answersClick(params)) {\n return text;\n }\n\n return text ? `${text}<br/>${line}` : line;\n },\n };\n}\n\n// Whether the hovered mark acts on a click: every mark of an axis tooltip,\n// and an item unless its data item keeps the arrow.\nfunction answersClick(params: TooltipComponentFormatterCallbackParams): boolean {\n return Array.isArray(params) || (params.data as { cursor?: unknown } | null | undefined)?.cursor !== 'default';\n}\n\n// The tooltip ECharts would write, in this file's form. An axis tooltip: the\n// category (the axis pointer's label, so a period reads as on the axis),\n// then '● Series: value' per series shown. An item tooltip: '● Item: value'.\n// Names come from the data and the config, and ECharts sets the tooltip as\n// HTML, so both are escaped.\nfunction plainTooltip(params: TooltipComponentFormatterCallbackParams, series: SeriesOption[]): string {\n const axis = Array.isArray(params);\n const items = axis ? params : [params];\n const lines = items.map((item) => {\n const write = (series[item.seriesIndex ?? -1]?.tooltip as SeriesTooltip | undefined)?.valueFormatter;\n const marker = typeof item.marker === 'string' ? item.marker : '';\n const name = String((axis ? item.seriesName : item.name) ?? '');\n const value = write ? write(item.value) : String(item.value ?? '');\n\n return `${marker} ${escapeHtml(name)}: ${escapeHtml(value)}`;\n });\n const first = items[0] as { axisValueLabel?: unknown; name?: unknown } | undefined;\n const heading = axis ? String(first?.axisValueLabel ?? first?.name ?? '') : '';\n\n return [...(heading ? [escapeHtml(heading)] : []), ...lines].join('<br/>');\n}\n\n// The option, by chart type.\nfunction chartOption(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n): EChartsOption {\n const config = component.config as ChartConfig;\n const chartType = config.chartType ?? 'bar';\n\n if (chartType === 'pie' || chartType === 'donut') {\n return buildPieOption(component, data, chartType === 'donut', context);\n }\n\n if (chartType === 'waterfall') {\n return buildWaterfallOption(component, data, context);\n }\n\n return buildAxisOption(component, data, chartType, context);\n}\n\nfunction buildAxisOption(\n component: ReportComponent,\n data: ComponentData,\n chartType: AxisChartType,\n context: ReportFormatContext,\n): EChartsOption {\n const config = component.config as ChartConfig;\n const extracted = extractChartSeries(component, data);\n const horizontal = config.orientation === 'horizontal';\n const colorBy = isColorBy(config);\n const types = seriesTypes(extracted, chartType);\n const combo = new Set(types).size > 1;\n\n // colorBy emits one series per category; overlapping them (barGap -100%) makes\n // each render at the full category-band width — one full-width, distinctly\n // colored bar per category — instead of side-by-side slivers. The layout props\n // are read from the first series of the coordinate system.\n //\n // Stacking sums every series that shares a stack name, whatever its type. In\n // a combo each type stacks only with its own kind, so a line of a rate never\n // sits on top of the bars' total, and on a two-axis chart only with the\n // series on its own axis.\n //\n // A 100% stacked chart (percentStackedShares) plots its primary bars and\n // areas as shares, each type in its own stack, and leaves every other series\n // unstacked on its own values.\n //\n // What the server says of the numbers (chartAnnotations) marks them: a\n // prior series dashed in its current series' color, the period not over yet\n // hatched or dashed, ranks on an inverted axis, fractions on a percent axis,\n // and the tooltip naming each prior's days and each window. Data without\n // those keys draws exactly as before.\n const axisIndexes = seriesAxisIndexes(extracted, config);\n const twoAxes = axisIndexes.includes(1);\n const shares = percentStackedShares(extracted, config);\n const references = chartReferences(config, twoAxes);\n const annotations = chartAnnotations(config, data, extracted, colorBy);\n const axisFormats = valueAxisFormats(\n config,\n annotations ? annotatedAxisSeries(extracted, annotations) : extracted,\n axisIndexes,\n annotations && !shares ? annotatedAxisContexts(annotations, axisIndexes, context) : [context, context],\n !!shares,\n references,\n );\n const rankAxes = annotations && !shares ? rankAxisFlags(annotations.outputs, axisIndexes) : [false, false];\n // A series' statistic line is taken over the points it plots. On a colorBy\n // chart each series holds one bar, so the one line is taken over the bars\n // together and hangs off the first series (colorByStatLine).\n const statLines = drawsStatLines(config) && !colorBy;\n const series: SeriesOption[] = extracted.series.map((extractedSeries, index) => {\n const seriesShares = shares?.get(index);\n let stack: string | undefined;\n if (seriesShares) {\n stack = stackKey(types[index], combo, 0);\n } else if (config.stacked && !shares) {\n stack = stackKey(types[index], combo, twoAxes ? axisIndexes[index] : undefined);\n }\n\n // An output series (a compared, windowed, ranked or shared value) writes\n // its tooltip, data labels and statistic line by what it holds.\n const write = annotations && !seriesShares && annotations.outputs[index]\n ? outputWriter(annotations, index, extractedSeries.measure, context)\n : null;\n const stat = statLines ? measureMarkStat(extractedSeries.measure) : undefined;\n const markLine = stat && statMarkLine(\n seriesShares ?? extractedSeries.values,\n stat,\n seriesShares ? shareWriter(context) : write ?? measureWriter(extractedSeries.measure, context),\n );\n const option = buildSeries(\n extractedSeries,\n seriesShares ? shareData(extractedSeries.values, seriesShares) : extractedSeries.values,\n {\n type: types[index],\n stack,\n overlap: colorBy && index === 0,\n combo,\n tooltip: write ? { valueFormatter: write } : seriesTooltip(extractedSeries.measure, context),\n axisIndex: twoAxes ? axisIndexes[index] : undefined,\n // A colorBy chart's bars take the palette by category, as in\n // PowerPoint, whatever color the measure names.\n color: colorBy ? undefined : annotations?.colors?.[index] ?? seriesColor(extractedSeries),\n labels: dataLabelOption(config.dataLabels, write\n ? outputLabelFormatter(write)\n : dataLabelFormatter(\n extractedSeries.measure,\n axisFormats[axisIndexes[index]] ?? null,\n !!seriesShares,\n context,\n )),\n },\n );\n const marked = annotations ? markSeries(option, annotations, index, extractedSeries.measure) : option;\n\n return markLine ? { ...marked, markLine } as SeriesOption : marked;\n });\n\n if (colorBy && drawsStatLines(config) && series.length) {\n series[0] = colorByStatLine(series[0], extracted, context, annotations?.outputs[0]\n ? outputWriter(annotations, 0, extracted.series[0].measure, context)\n : undefined);\n }\n\n // Drawn after the measure series, so a tooltip reads a series by its index.\n const segments = annotations ? partialSegments(series, annotations) : [];\n const percentMin = shares ? percentAxisMin(shares) : undefined;\n const categoryAxis = categoryAxisOption(config, data, extracted.categories, horizontal, context.locale);\n // An axis of rate changes alone reads in percentage points, as its values do.\n const axisLabels = ([0, 1] as const).map((axisIndex) => (annotations && !shares\n ? pointsAxisLabel(annotations, extracted, axisIndexes, axisIndex, context)\n : null) ?? valueAxisLabel(axisFormats[axisIndex] ?? null, context));\n const valueAxis = twoAxes\n ? twoValueAxesOption(config, axisLabels, context, percentMin, references, rankAxes)\n : valueAxisOption(config.valueAxis, horizontal, percentMin === undefined\n ? axisLabels[0]\n : percentAxisLabel(context), { percentMin, reach: referenceReach(references, 0), rank: rankAxes[0] });\n\n const legendPosition = resolveLegendPosition(config, series.length, colorBy);\n const valueTitles = [config.valueAxis, twoAxes ? config.secondaryAxis : undefined];\n const granularity = bucketGranularity(data);\n\n return {\n grid: axisGrid(\n legendPosition,\n categoryTitleSide(config, data, horizontal),\n valueTitleSide(valueTitles, horizontal),\n ),\n legend: referenceLegend(legendOption(legendPosition), series, references),\n // colorBy charts overlap N mostly-null series, so an axis tooltip would list\n // every category; an item tooltip shows just the hovered bar. A 100%\n // stacked chart's tooltip gives each share and the value it came from. A\n // chart with the server's annotations names what each value covers.\n tooltip: shares\n ? {\n trigger: 'axis',\n formatter: (params: TooltipComponentFormatterCallbackParams) => percentTooltip(\n params,\n extracted,\n shares,\n granularity,\n chartDateLabel(config),\n context,\n ),\n }\n : annotatedChartTooltip(annotations && !colorBy ? {\n extracted,\n annotations,\n owners: segments.map((segment) => segment.owner),\n granularity,\n dateLabel: chartDateLabel(config),\n context,\n } : null) ?? { trigger: colorBy ? 'item' : 'axis' },\n xAxis: horizontal ? valueAxis : categoryAxis,\n yAxis: horizontal ? categoryAxis : valueAxis,\n series: [...series, ...segments.map((segment) => segment.series), ...referenceCarriers(references, extracted.categories)],\n };\n}\n\n// What the server says of the series an axis chart plots, read from the\n// data's comparison, outputs, windows and partialPeriod by each series'\n// measure column. chartAnnotations is null when the data carries none of\n// those keys, and the chart draws exactly as before.\ninterface ChartAnnotations {\n outputs: (OutputMeta | null)[];\n windows: (WindowMeta | null)[];\n // The chart measure an output takes its measure's format from: its current\n // value's, when the chart plots it.\n measureSpecs: (ChartMeasure | undefined)[];\n // A change or percent change series' prior values by category, which tell\n // a missing baseline from a zero one; null for any other series.\n priors: ((number | null)[] | null)[];\n // The lane prior a current, change or percent change series is compared\n // with, when the chart does not plot that prior itself: its tooltip line\n // names the prior's value and days. null for any other series.\n lanePriors: (LanePrior | null)[];\n // Every series' own CSS color, so a prior series and a partial segment can\n // share another's; null on a colorBy chart, which colors by category.\n colors: string[] | null;\n priorSeries: boolean[];\n comparison: ComponentComparison | null;\n // The category of the period not over yet, or null.\n partialIndex: number | null;\n}\n\n// A series' lane prior: its output, its values by category, and a key that\n// names it once in a tooltip (the prior column, and on a splitBy chart the\n// group).\ninterface LanePrior {\n key: string;\n output: OutputMeta;\n values: (number | null)[];\n}\n\n// The keys of a built axis series that the annotations read and replace.\ninterface DrawnSeries {\n type?: string;\n stack?: string;\n data?: SeriesDataItem<DataLabelPosition>[];\n itemStyle?: Record<string, unknown>;\n lineStyle?: Record<string, unknown>;\n}\n\n// A dashed last segment (partialSegments), drawn after the measure series,\n// and the index of the series it continues.\ninterface PartialSegment {\n series: SeriesOption;\n owner: number;\n}\n\n// What an annotated chart's axis tooltip reads. owners holds, by position,\n// the series each partial segment continues.\ninterface AnnotatedTooltipSource {\n extracted: ExtractedChartSeries;\n annotations: ChartAnnotations;\n owners: number[];\n granularity: ChartGranularity | null;\n dateLabel: ReportChartDateLabel;\n context: ReportFormatContext;\n}\n\nfunction chartAnnotations(\n config: ChartConfig,\n data: ComponentData,\n extracted: ExtractedChartSeries,\n colorBy: boolean,\n): ChartAnnotations | null {\n if (!data.comparison && !data.outputs && !data.windows && (data.partialPeriod ?? null) === null) {\n return null;\n }\n\n const columns = extracted.series.map((series) => series.measure.column);\n const outputs = columns.map((column) => data.outputs?.[column] ?? null);\n const currents = columns.map((column, index) => (outputs[index] ? currentOutputAlias(data.outputs, column) : null));\n const measures = chartMeasures(config, data);\n // A prior series' current series, by index; -1 for any other.\n const sources = currents.map((current, index) => (outputs[index]?.role === 'prior' ? columns.indexOf(current) : -1));\n const partialIndex = (data.partialPeriod ?? null) === null ? -1 : extracted.categories.indexOf(String(data.partialPeriod));\n const lanes = lanePriorValues(config, data, extracted, outputs);\n\n return {\n outputs,\n windows: columns.map((column) => data.windows?.[column] ?? null),\n measureSpecs: currents.map((current) => measures.find((measure) => measure.column === current)),\n priors: lanes.map((lane, index) => (isDeltaRole(outputs[index]?.role) ? lane?.prior.values ?? null : null)),\n lanePriors: lanes.map((lane) => (lane && !columns.includes(lane.alias) ? lane.prior : null)),\n colors: colorBy ? null : annotatedColors(extracted, sources),\n priorSeries: outputs.map((output) => output?.role === 'prior'),\n comparison: data.comparison ?? null,\n partialIndex: partialIndex < 0 ? null : partialIndex,\n };\n}\n\n// A current, change or percent change series' lane prior, by category: its\n// lane's prior column in the same rows (the same group's on a splitBy chart),\n// and that column's alias.\nfunction lanePriorValues(\n config: ChartConfig,\n data: ComponentData,\n extracted: ExtractedChartSeries,\n outputs: (OutputMeta | null)[],\n): ({ alias: string; prior: LanePrior } | null)[] {\n const { xColumn, groupColumn } = chartColumns(config, data);\n const rawCategories = uniqueValues(data.rows, xColumn);\n const groups = groupColumn ? uniqueValues(data.rows, groupColumn) : [];\n\n return extracted.series.map((series, index) => {\n const role = outputs[index]?.role;\n const alias = role === 'current' || isDeltaRole(role)\n ? laneOutputAlias(data.outputs, series.measure.column, 'prior')\n : null;\n const output = alias ? data.outputs?.[alias] : undefined;\n\n if (!alias || !output) {\n return null;\n }\n\n const match = groupColumn ? (row: Record<string, unknown>) => row[groupColumn] === groups[index] : undefined;\n\n return {\n alias,\n prior: {\n key: groupColumn ? `${alias}\\u0000${index}` : alias,\n output,\n values: categoryValues(data.rows, xColumn, rawCategories, alias, match),\n },\n };\n });\n}\n\nfunction isDeltaRole(role: OutputRole | null | undefined): boolean {\n return role === 'change' || role === 'percent_change';\n}\n\n// Each series' color as the theme would hand it out: its measure's named\n// color, else the next palette color among the series without one. A prior\n// series that names no color takes its current series' color (sources) and\n// no palette color of its own.\nfunction annotatedColors(extracted: ExtractedChartSeries, sources: number[]): string[] {\n let slot = 0;\n const own = extracted.series.map((series, index) => {\n const named = seriesColor(series);\n\n if (named || sources[index] >= 0) {\n return named ?? null;\n }\n\n return REPORT_CHART_COLORS_CSS[slot++ % REPORT_CHART_COLORS_CSS.length];\n });\n\n return own.map((color, index) => color ?? own[sources[index]] as string);\n}\n\n// A series' marks: a prior drawn in its current series' color family, dashed,\n// and the period not over yet hatched (a bar) or ringed (a point).\nfunction markSeries(\n option: SeriesOption,\n annotations: ChartAnnotations,\n index: number,\n measure: ChartMeasure,\n): SeriesOption {\n const prior = annotations.priorSeries[index] ? priorStyle(option, measure, annotations.colors?.[index]) : option;\n\n return annotations.partialIndex === null ? prior : markPartialPoint(prior, annotations.partialIndex);\n}\n\n// A prior's bars are faded with a dashed edge; its line is dashed unless its\n// measure names a line style.\nfunction priorStyle(option: SeriesOption, measure: ChartMeasure, color: string | undefined): SeriesOption {\n const drawn = option as DrawnSeries;\n\n if (drawn.type === 'bar') {\n return {\n ...option,\n itemStyle: {\n ...drawn.itemStyle,\n opacity: PRIOR_BAR_OPACITY,\n borderWidth: 1,\n borderType: 'dashed',\n ...(color ? { borderColor: color } : {}),\n },\n } as SeriesOption;\n }\n\n return { ...option, lineStyle: { ...drawn.lineStyle, type: measureLineStyle(measure) ?? PRIOR_LINE_STYLE } } as SeriesOption;\n}\n\n// The point of the period not over yet, when it has a value.\nfunction markPartialPoint(option: SeriesOption, partialIndex: number): SeriesOption {\n const drawn = option as DrawnSeries;\n const data = [...(drawn.data ?? [])];\n const item = data[partialIndex];\n\n if (item === undefined || pointValue(item) === null) {\n return option;\n }\n\n const mark = drawn.type === 'bar' ? { itemStyle: { decal: PARTIAL_BAR_DECAL } } : PARTIAL_POINT_MARK;\n data[partialIndex] = (typeof item === 'object' ? { ...item, ...mark } : { value: item, ...mark }) as SeriesDataItem<DataLabelPosition>;\n\n return { ...option, data } as SeriesOption;\n}\n\n// A line or area series whose last period is not over yet draws its last\n// segment dashed: the series stops one point short, and a segment series\n// carries its last two points, dashed, in its color and under its name, so\n// the one legend entry toggles both. Its id names the series it continues\n// (partialSegmentId), so a click on it reads as a click on that series. A\n// stacked series keeps its line whole (a segment would stack on top of it),\n// and a gap stays a gap. Replaces each such series in `series` and returns\n// the segments.\nfunction partialSegments(series: SeriesOption[], annotations: ChartAnnotations): PartialSegment[] {\n const last = annotations.partialIndex;\n const segments: PartialSegment[] = [];\n\n series.forEach((option, owner) => {\n const drawn = option as DrawnSeries;\n const data = drawn.data ?? [];\n const color = annotations.colors?.[owner];\n\n if (last === null || last < 1 || last !== data.length - 1 || drawn.type !== 'line' || drawn.stack || !color\n || pointValue(data[last - 1]) === null || pointValue(data[last]) === null) {\n return;\n }\n\n series[owner] = { ...option, data: [...data.slice(0, last), null] } as SeriesOption;\n segments.push({ owner, series: { ...segmentSeries(option, color, last), id: partialSegmentId(owner) } as SeriesOption });\n });\n\n return segments;\n}\n\n// The dashed segment from the point before the last to the last one, which\n// keeps its marks and its data label. The point before it is drawn, and\n// labeled, by the series itself.\nfunction segmentSeries(option: SeriesOption, color: string, last: number): SeriesOption {\n const drawn = option as DrawnSeries;\n const data = drawn.data ?? [];\n\n return {\n ...option,\n markLine: undefined,\n lineStyle: { ...drawn.lineStyle, color, type: PARTIAL_LINE_STYLE },\n data: data.map((item, index) => {\n if (index === last) {\n return item;\n }\n\n return index === last - 1 ? { value: pointValue(item), symbol: 'none', label: { show: false } } : null;\n }),\n } as SeriesOption;\n}\n\n// A partial segment's series id, from the index of the series it continues.\nexport function partialSegmentId(owner: number): string {\n return `${PARTIAL_SEGMENT_ID}${owner}`;\n}\n\n// The index of the series a partial segment continues, read from its id;\n// null for any other id.\nexport function partialSegmentOwner(seriesId: string | null | undefined): number | null {\n if (!seriesId?.startsWith(PARTIAL_SEGMENT_ID)) {\n return null;\n }\n\n const owner = Number(seriesId.slice(PARTIAL_SEGMENT_ID.length));\n\n return Number.isInteger(owner) && owner >= 0 ? owner : null;\n}\n\n// A point's plotted value, whether it is a bare number or an object.\nfunction pointValue(item: SeriesDataItem<DataLabelPosition> | undefined): number | null {\n if (item === null || item === undefined) {\n return null;\n }\n\n return typeof item === 'number' ? item : item.value;\n}\n\n// How an output series writes a value: formatOutputValue's rules (a signed\n// change, points, '—' with the no-baseline title, ranks and shares) with its\n// measure's format and the comparison's floor. Given the point's index (a\n// tooltip, a data label), a change reads its prior there, which tells a\n// missing baseline from a zero one. The title says why a value reads '—' or\n// 'n/a'.\nfunction outputValue(\n annotations: ChartAnnotations,\n index: number,\n measure: ChartMeasure,\n context: ReportFormatContext,\n): (value: unknown, dataIndex?: number) => FormattedOutputValue {\n const output = annotations.outputs[index];\n const priors = annotations.priors[index];\n\n return (value, dataIndex) => formatOutputValue(Array.isArray(value) ? value[0] : value, output, measure, context, {\n measureSpec: annotations.measureSpecs[index],\n floor: annotations.comparison?.floor ?? null,\n ...(priors && dataIndex !== undefined ? { prior: priors[dataIndex] ?? null } : {}),\n });\n}\n\n// An output value's text alone, for a series' own tooltip and its data labels.\nfunction outputWriter(\n annotations: ChartAnnotations,\n index: number,\n measure: ChartMeasure,\n context: ReportFormatContext,\n): (value: unknown, dataIndex?: number) => string {\n const write = outputValue(annotations, index, measure, context);\n\n return (value, dataIndex) => write(value, dataIndex).text;\n}\n\nfunction outputLabelFormatter(write: (value: unknown, dataIndex?: number) => string): DataLabelFormatter {\n return (params) => write(dataLabelValue(params), params.dataIndex);\n}\n\n// The chart's series as its value axes read them: an output series whose\n// slot names no format takes its output's (outputAxisMeasure).\nfunction annotatedAxisSeries(extracted: ExtractedChartSeries, annotations: ChartAnnotations): ExtractedChartSeries {\n return {\n ...extracted,\n series: extracted.series.map((series, index) => ({\n ...series,\n measure: outputAxisMeasure(series.measure, annotations.outputs[index], annotations.measureSpecs[index]),\n })),\n };\n}\n\n// The format an output's axis reads when its slot names none: a rank's whole\n// numbers, a 0-1 fraction's percent, and a compared or windowed value its\n// measure's format. The slot's own precision and units still apply.\nfunction outputAxisMeasure(\n measure: ChartMeasure,\n output: OutputMeta | null,\n measureSpec: ChartMeasure | undefined,\n): ChartMeasure {\n if (!output || namesValueFormat(measure)) {\n return measure;\n }\n\n let base: NumberFormatSpec | null = measureSpec && hasNumberFormat(measureSpec) ? formatKeys(measureSpec) : null;\n if (output.kind === 'rank') {\n base = RANK_AXIS_FORMAT;\n } else if (isFractionOutput(output)) {\n base = FRACTION_AXIS_FORMAT;\n }\n\n return base\n ? { ...measure, ...base, ...formatKeys({ precision: measure.precision, units: measure.units }) } as ChartMeasure\n : measure;\n}\n\nfunction namesValueFormat(spec: NumberFormatSpec): boolean {\n return Object.values(ReportValueFormat).some((format) => format === spec.format);\n}\n\n// A spec's number-format keys that are set.\nfunction formatKeys(spec: NumberFormatSpec): NumberFormatSpec {\n return {\n ...((spec.format ?? null) !== null ? { format: spec.format } : {}),\n ...((spec.precision ?? null) !== null ? { precision: spec.precision } : {}),\n ...((spec.units ?? null) !== null ? { units: spec.units } : {}),\n };\n}\n\n// Each value axis's context: one that plots only 0-1 fractions reads them as\n// ratios, whatever the report's percentFormat says of its stored values.\nfunction annotatedAxisContexts(\n annotations: ChartAnnotations,\n axisIndexes: ValueAxisIndex[],\n context: ReportFormatContext,\n): ReportFormatContext[] {\n return ([0, 1] as const).map((axisIndex) => (everyOnAxis(annotations.outputs, axisIndexes, axisIndex, isFractionOutput)\n ? { ...context, ratioPercent: true }\n : context));\n}\n\n// Which value axes, by index, plot nothing but ranks.\nfunction rankAxisFlags(outputs: (OutputMeta | null)[], axisIndexes: ValueAxisIndex[]): boolean[] {\n return ([0, 1] as const).map((axisIndex) => everyOnAxis(outputs, axisIndexes, axisIndex, isRankPosition));\n}\n\n// How a chart that plots a prior series colors each series, for the\n// PowerPoint export: every series' color as bare hex, a prior taking its\n// current series' color and no palette color of its own (annotatedColors),\n// and which series are priors, which a line draws dashed. null when the chart\n// plots no prior series, and on a colorBy chart; its series keep seriesHex.\nexport function priorSeriesStyles(\n config: ChartConfig,\n data: ComponentData,\n extracted: ExtractedChartSeries,\n): { colors: string[]; priors: boolean[] } | null {\n const annotations = chartAnnotations(config, data, extracted, isColorBy(config));\n\n if (!annotations?.colors || !annotations.priorSeries.some((prior) => prior)) {\n return null;\n }\n\n return {\n colors: annotations.colors.map((color) => color.replace('#', '')),\n priors: annotations.priorSeries,\n };\n}\n\n// Which value axes, by index, plot nothing but ranks, which the chart draws\n// inverted with rank 1 at the top. Shared with the PowerPoint export.\nexport function rankValueAxes(extracted: ExtractedChartSeries, data: ComponentData, config: ChartConfig): boolean[] {\n return rankAxisFlags(\n extracted.series.map((series) => data.outputs?.[series.measure.column] ?? null),\n seriesAxisIndexes(extracted, config),\n );\n}\n\n// Whether an axis has series and every one of them passes the test.\nfunction everyOnAxis(\n outputs: (OutputMeta | null)[],\n axisIndexes: ValueAxisIndex[],\n axisIndex: ValueAxisIndex,\n test: (output: OutputMeta) => boolean,\n): boolean {\n const onAxis = outputs.filter((_, index) => axisIndexes[index] === axisIndex);\n\n return onAxis.length > 0 && onAxis.every((output) => !!output && test(output));\n}\n\n// A share and a percent change are 0-1 fractions, whatever percentFormat says.\nfunction isFractionOutput(output: OutputMeta): boolean {\n return output.kind === 'share' || output.role === 'percent_change';\n}\n\n// A value axis's tick labels when every series on it is a change of a rate\n// (a share's, or a percent-format value's): signed percentage points, as the\n// series' tooltips and data labels write them ('+5.0 pp'). null for any other\n// axis.\nfunction pointsAxisLabel(\n annotations: ChartAnnotations,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n axisIndex: ValueAxisIndex,\n context: ReportFormatContext,\n): ValueAxisLabel | null {\n const onAxis = extracted.series\n .map((_, index) => index)\n .filter((index) => axisIndexes[index] === axisIndex);\n const points = onAxis.length > 0 && onAxis.every((index) => isPointsChange(\n annotations.outputs[index],\n outputAxisMeasure(extracted.series[index].measure, annotations.outputs[index], annotations.measureSpecs[index]),\n ));\n\n if (!points) {\n return null;\n }\n\n const write = outputWriter(annotations, onAxis[0], extracted.series[onAxis[0]].measure, context);\n\n return { formatter: (value: number) => write(value) };\n}\n\n// A change of a rate, which prints in percentage points: a share's change, or\n// the change of a value whose format (its slot's, else its measure's) is a\n// percent.\nfunction isPointsChange(output: OutputMeta | null, axisMeasure: ChartMeasure): boolean {\n return !!output && output.role === 'change' && output.kind !== 'rank'\n && (output.kind === 'share' || axisMeasure.format === ReportValueFormat.Percent);\n}\n\n// A rank, current or prior; a rank change is a difference, not a position.\nfunction isRankPosition(output: OutputMeta): boolean {\n return output.kind === 'rank' && output.role !== 'change';\n}\n\nfunction annotatedChartTooltip(source: AnnotatedTooltipSource | null) {\n return source\n ? {\n trigger: 'axis' as const,\n formatter: (params: TooltipComponentFormatterCallbackParams) => annotatedTooltip(params, source),\n }\n : null;\n}\n\n// The period, with 'to date' when it is not over yet, then each series shown\n// (a legend can hide some): its value written by what it is, and what it\n// covers. A partial segment speaks for its series. Names and values come from\n// the data and the config, and ECharts sets the tooltip as HTML, so both are\n// escaped.\nfunction annotatedTooltip(params: TooltipComponentFormatterCallbackParams, source: AnnotatedTooltipSource): string {\n const items = Array.isArray(params) ? params : [params];\n const dataIndex = items[0]?.dataIndex ?? 0;\n const count = source.extracted.series.length;\n const markers = new Map<number, string>();\n\n for (const item of items) {\n const seriesIndex = item.seriesIndex ?? -1;\n const owner = seriesIndex < count ? seriesIndex : source.owners[seriesIndex - count];\n\n if (owner !== undefined && owner >= 0 && !markers.has(owner)) {\n markers.set(owner, typeof item.marker === 'string' ? item.marker : '');\n }\n }\n\n const namedPriors = new Set<string>();\n const lines = [...markers.entries()]\n .sort(([first], [second]) => first - second)\n .map(([index, marker]) => annotatedTooltipLine(source, index, dataIndex, marker, namedPriors));\n\n return [annotatedTooltipHeading(source, dataIndex), ...lines].join('<br/>');\n}\n\nfunction annotatedTooltipHeading(source: AnnotatedTooltipSource, dataIndex: number): string {\n const category = source.extracted.categories[dataIndex] ?? '';\n const period = source.granularity\n ? formatPeriodLabel(category, source.granularity, true, source.context.locale, source.dateLabel)\n : category;\n\n return escapeHtml(dataIndex === source.annotations.partialIndex ? `${period} (${PARTIAL_PERIOD_TEXT})` : period);\n}\n\n// '● Revenue (vs previous month): $813 · Aug 1 – 15, 2026', and why a value\n// reads '—' or 'n/a' when it does ('No baseline: no data before Jun 10, 2026').\n// A value compared with a prior the chart does not plot names that prior\n// once, on the first line shown that is compared with it: 'Rate % change (vs\n// previous month): -10% · vs 50% (Sep 1 – 2, 2026)'. namedPriors holds the\n// priors already named.\nfunction annotatedTooltipLine(\n source: AnnotatedTooltipSource,\n index: number,\n dataIndex: number,\n marker: string,\n namedPriors: Set<string>,\n): string {\n const series = source.extracted.series[index];\n const value = series.values[dataIndex] ?? null;\n const formatted = source.annotations.outputs[index]\n ? outputValue(source.annotations, index, series.measure, source.context)(value, dataIndex)\n : { text: seriesTooltip(series.measure, source.context).valueFormatter(value), title: null };\n const lanePrior = source.annotations.lanePriors[index];\n const compared = lanePrior && !namedPriors.has(lanePrior.key)\n ? comparedPriorDetail(source, index, lanePrior, dataIndex)\n : '';\n if (lanePrior) {\n namedPriors.add(lanePrior.key);\n }\n\n const parts = [formatted.text, seriesDetail(source, index, dataIndex), compared, formatted.title ?? ''];\n\n return `${marker} ${escapeHtml(series.name)}: ${escapeHtml(parts.filter((part) => !!part).join(TOOLTIP_DETAIL_SEPARATOR))}`;\n}\n\n// The prior a value is compared with, when the chart does not plot it: its\n// value in its measure's format, and its days ('vs 50% (Sep 1 – 2, 2026)').\n// The measure's format is the current series' when the chart plots it, else\n// a change slot's own explicit format (a change is in its measure's units).\nfunction comparedPriorDetail(\n source: AnnotatedTooltipSource,\n index: number,\n lanePrior: LanePrior,\n dataIndex: number,\n): string {\n const annotations = source.annotations;\n const measure = source.extracted.series[index].measure;\n const measureSpec = annotations.measureSpecs[index]\n ?? (annotations.outputs[index]?.role !== 'percent_change' && namesValueFormat(measure) ? measure : null);\n const text = formatOutputValue(lanePrior.values[dataIndex] ?? null, lanePrior.output, null, source.context, {\n measureSpec,\n floor: annotations.comparison?.floor ?? null,\n }).text;\n const window = priorDetail(source, lanePrior.output, dataIndex);\n\n return window ? `${COMPARED_PRIOR_PREFIX} ${text} (${window})` : `${COMPARED_PRIOR_PREFIX} ${text}`;\n}\n\n// What a series' value covers, when the server says: a prior's days, or a\n// windowed value's window ('Rolling 3-month total'), whose days the note\n// under the chart names.\nfunction seriesDetail(source: AnnotatedTooltipSource, index: number, dataIndex: number): string {\n const output = source.annotations.outputs[index];\n const window = source.annotations.windows[index];\n\n if (output?.role === 'prior') {\n return priorDetail(source, output, dataIndex);\n }\n\n return window ? windowText({ ...window, start: null, end: null }, source.context.locale, source.granularity) : '';\n}\n\n// A prior value's days. A range comparison compares every point with the\n// same window. A series comparison compares each period with the period its\n// lane's offset back; a period_end comparison reads the value at the end of that\n// period ('on Aug 31, 2026').\nfunction priorDetail(source: AnnotatedTooltipSource, output: OutputMeta, dataIndex: number): string {\n const comparison = source.annotations.comparison;\n const lane = (output.offset ?? 1) - 1;\n const offset = comparison?.offsets?.[lane];\n const locale = source.context.locale;\n\n if (!comparison || !offset) {\n return '';\n }\n\n if (comparison.mode === 'range' || !source.granularity) {\n const prior = comparison.priors?.[lane];\n\n return prior ? formatDayWindow(prior, comparison.timezone, locale) : '';\n }\n\n const partial = dataIndex === source.annotations.partialIndex && comparison.align === 'to_date';\n const today = partial ? zoneToday(comparison.timezone) : null;\n const window = priorPeriodWindow(source.extracted.categories[dataIndex] ?? '', source.granularity, offset, today);\n\n if (!window) {\n return '';\n }\n\n if (comparison.mode === 'period_end') {\n return `on ${formatDayRange(window.end, window.end, locale)}`;\n }\n\n return formatDayWindow(\n { ...withinLaneSpan(window, comparison.priors?.[lane]), through: partial ? comparison.current?.through ?? null : null },\n comparison.timezone,\n locale,\n );\n}\n\n// A series lane reads the span shown moved back by its offset (the server's\n// comparison.priors[lane]), so the earlier copy of a period the span starts\n// or ends inside holds only the days within it: a span from Mar 15 sets\n// March against Feb 15 – 28, not the whole of February.\nfunction withinLaneSpan(\n window: { start: string; end: string },\n span: ComparisonWindow | undefined,\n): { start: string; end: string } {\n if (!span) {\n return window;\n }\n\n const start = window.start < span.start ? span.start : window.start;\n const end = window.end > span.end ? span.end : window.end;\n\n return start <= end ? { start, end } : window;\n}\n\n// The days one period of the axis is compared with: the period moved back by\n// the lane's offset. A period not over yet, compared to date, runs only to\n// today moved back (priorToDateEnd). null for a category that is not a day,\n// or an offset without a unit (a custom range).\nfunction priorPeriodWindow(\n category: string,\n granularity: ChartGranularity,\n offset: ComparisonOffset,\n today: Date | null,\n): { start: string; end: string } | null {\n const start = parseISO(category);\n const unit = offset.unit;\n const count = offset.count;\n\n if (!isValid(start) || !unit || !count) {\n return null;\n }\n\n const back = (date: Date) => addPeriods(date, unit, -count);\n const fullEnd = addDays(back(addPeriods(start, granularity, 1)), -1);\n const end = today ? earliestOf([fullEnd, priorToDateEnd(today, start, back, unit)]) : fullEnd;\n\n return { start: calendarDay(back(start)), end: calendarDay(latestOf([end, back(start)])) };\n}\n\n// Today, kept inside the period, moved back by the offset; when today is the\n// last day of its month, the last day of the month it lands in (the\n// server's end-of-month rule: Sep 30 compares with Aug 31, not Aug 30).\nfunction priorToDateEnd(\n today: Date,\n periodStart: Date,\n back: (date: Date) => Date,\n unit: ChartGranularity,\n): Date {\n const day = latestOf([startOfDay(today), periodStart]);\n const moved = back(day);\n\n return isLastDayOfMonth(day) && unit !== 'day' && unit !== 'week' ? endOfMonth(moved) : moved;\n}\n\nfunction addPeriods(date: Date, unit: ChartGranularity, count: number): Date {\n switch (unit) {\n case 'day':\n return addDays(date, count);\n case 'week':\n return addWeeks(date, count);\n case 'quarter':\n return addQuarters(date, count);\n case 'year':\n return addYears(date, count);\n default:\n return addMonths(date, count);\n }\n}\n\nfunction calendarDay(date: Date): string {\n return formatISO(date, { representation: 'date' });\n}\n\n// Today's calendar day in the report's zone, as local midnight. The server\n// marks which period holds today (partialPeriod) but not the day itself; the\n// prior of that period is clipped at the same day. An unknown zone reads the\n// browser's own day.\nfunction zoneToday(timezone: string): Date {\n try {\n const parts = dateFormat('en-US', { year: 'numeric', month: 'numeric', day: 'numeric' }, timezone)\n .formatToParts(new Date());\n const part = (type: Intl.DateTimeFormatPartTypes) => Number(parts.find((found) => found.type === type)?.value);\n const today = new Date(part('year'), part('month') - 1, part('day'));\n\n if (isValid(today)) {\n return today;\n }\n } catch {\n // An unknown zone: the browser's day below.\n }\n\n return startOfDay(new Date());\n}\n\n// A colorBy chart's statistic line: one line over every bar, hung off the\n// first series and drawn in the reference slate, as no one category's color\n// speaks for the others.\nfunction colorByStatLine(\n first: SeriesOption,\n extracted: ExtractedChartSeries,\n context: ReportFormatContext,\n write?: (value: number) => string,\n): SeriesOption {\n const measure = extracted.series[0]?.measure;\n const stat = measureMarkStat(measure);\n const markLine = stat && statMarkLine(\n colorByValues(extracted),\n stat,\n write ?? measureWriter(measure, context),\n `#${REPORT_REFERENCE_COLOR}`,\n );\n\n return markLine ? { ...first, markLine } as SeriesOption : first;\n}\n\n// A series' statistic line across the plot, labeled with the statistic and\n// its value ('Average: 1,234.5'), or undefined when no point has a value. It\n// takes the series' color unless it is given one.\nfunction statMarkLine(\n values: (number | null)[],\n stat: ReportChartMarkStat,\n write: (value: number) => string,\n color?: string,\n) {\n const value = seriesStat(values, stat);\n\n if (value === null) {\n return undefined;\n }\n\n const text = `${STAT_LABEL[stat]}: ${write(value)}`;\n\n return {\n silent: true,\n symbol: 'none',\n lineStyle: { type: 'dashed' as const, width: 1, ...(color ? { color } : {}) },\n label: { formatter: () => text, position: 'insideEndTop' as const, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },\n data: [{ yAxis: value }],\n };\n}\n\n// A statistic's value in its measure's number format, in the report locale.\nfunction measureWriter(measure: ChartMeasure | undefined, context: ReportFormatContext): (value: number) => string {\n return (value) => formatNumber(value, measure, context);\n}\n\n// A 100% stacked series' statistic is a share, written as its tooltip writes\n// one.\nfunction shareWriter(context: ReportFormatContext): (value: number) => string {\n const ratioContext = { ...context, ratioPercent: true };\n\n return (value) => formatNumber(value, PERCENT_SHARE_FORMAT, ratioContext);\n}\n\n// The series that carry a chart's references, one per value axis that has\n// any: an empty line (every point null, so it draws nothing and stretches no\n// axis) whose markLine draws the reference lines and whose markArea fills the\n// bands. It is silent, left out of the tooltip and, by referenceLegend, out of\n// the legend. It has no name, so no measure series' legend entry (whatever its\n// name, '' included) toggles it.\n//\n// Labels are functions, as a string formatter is a template that would read\n// '{b}' or '{c}' in a label as a placeholder. ECharts draws a markArea under\n// the bars and a markLine over them, so a band's label rides an invisible\n// markLine on its upper edge, inside its top left corner, where the first bar\n// would otherwise cover it.\nfunction referenceCarriers(references: DrawnReference[], categories: string[]): SeriesOption[] {\n const color = `#${REPORT_REFERENCE_COLOR}`;\n\n return ([0, 1] as const).flatMap((axisIndex): SeriesOption[] => {\n const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);\n const lines = onAxis.filter((reference) => !reference.band);\n const bands = onAxis.filter((reference) => reference.band);\n\n if (!onAxis.length) {\n return [];\n }\n\n return [{\n type: 'line',\n data: categories.map(() => null),\n yAxisIndex: axisIndex,\n silent: true,\n tooltip: { show: false },\n markLine: {\n silent: true,\n symbol: 'none',\n lineStyle: { color, type: 'dashed', width: 1 },\n label: { position: 'insideEndTop', color, fontSize: REPORT_DATA_LABEL_FONT_SIZE, ...MARK_LABEL_BOX },\n data: [\n ...lines.map((reference) => ({ yAxis: reference.low, label: { formatter: () => reference.label } })),\n ...bands.map((reference) => ({\n yAxis: reference.high,\n // Zero width, not zero opacity: a markLine's label takes the\n // line's opacity.\n lineStyle: { width: 0 },\n label: { position: 'insideStartBottom', formatter: () => reference.label },\n })),\n ],\n },\n ...(bands.length ? {\n markArea: {\n silent: true,\n itemStyle: { color: REFERENCE_BAND_FILL },\n data: bands.map((reference) => [{ yAxis: reference.low }, { yAxis: reference.high }]),\n },\n } : {}),\n } as SeriesOption];\n });\n}\n\n// The largest magnitude a value axis's references reach, which its number\n// format counts toward its peak, as the axis stretches to them; 0 when it\n// has none.\nexport function referencePeak(references: DrawnReference[], axisIndex: ValueAxisIndex): number {\n const reach = referenceReach(references, axisIndex);\n\n return reach ? Math.max(Math.abs(reach.low), Math.abs(reach.high)) : 0;\n}\n\n// The legend of a chart with references names its measure series alone, so\n// a carrier never shows as a blank entry. Without references it is left as it\n// was.\nfunction referenceLegend(\n legend: LegendComponentOption,\n series: SeriesOption[],\n references: DrawnReference[],\n): LegendComponentOption {\n return references.length\n ? { ...legend, data: series.map((item) => String(item.name ?? '')) }\n : legend;\n}\n\n// The span of the references on one value axis, or undefined when it has\n// none.\nfunction referenceReach(references: DrawnReference[], axisIndex: ValueAxisIndex): ReferenceReach | undefined {\n const onAxis = references.filter((reference) => reference.axisIndex === axisIndex);\n\n return onAxis.length\n ? { low: Math.min(...onAxis.map((reference) => reference.low)), high: Math.max(...onAxis.map((reference) => reference.high)) }\n : undefined;\n}\n\n// ECharts leaves a markLine or markArea out of an axis's extent, so a\n// reference beyond the data would fall off the plot. An axis bound the config\n// does not pin reaches past the furthest reference, to a round number with\n// room for its label (beyondReference), when the data (and the zero a value\n// axis always shows) falls short of it, and is left to ECharts otherwise: a\n// callback returning undefined keeps the bound automatic. Past the data and\n// zero, a reference beyond the max is above zero and one beyond the min below\n// it.\nfunction reachMin(reach: ReferenceReach | undefined) {\n return reach\n ? (extent: AxisExtent) => (reach.low < Math.min(extent.min, 0) ? -beyondReference(-reach.low) : undefined)\n : undefined;\n}\n\nfunction reachMax(reach: ReferenceReach | undefined) {\n return reach\n ? (extent: AxisExtent) => (reach.high > Math.max(extent.max, 0) ? beyondReference(reach.high) : undefined)\n : undefined;\n}\n\n// The bound an axis takes past a reference of this (positive) magnitude: the\n// smallest round number at or above it plus REFERENCE_HEADROOM. The steps are\n// finer than ECharts' tick steps, so a reference just past the data does not\n// double the axis (110 gives 120, not 200). The tolerance keeps a float error\n// from skipping a round number the value already is.\nconst NICE_STEPS = [1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10];\nconst NICE_TOLERANCE = 1e-9;\n\nfunction beyondReference(magnitude: number): number {\n const target = magnitude * REFERENCE_HEADROOM;\n const power = Math.pow(10, Math.floor(Math.log10(target)));\n const step = NICE_STEPS.find((candidate) => candidate * power >= target * (1 - NICE_TOLERANCE)) ?? 10;\n\n // Rounded back to the power's own digits, so 1.2 x 0.1 reads 0.12, not\n // 0.12000000000000001.\n return Number((step * power).toPrecision(12));\n}\n\n// The category axis of an axis chart or a waterfall: the categories in row\n// order, labeled as periods when the rows were bucketed by time.\n//\n// Horizontal bars read top-down: ECharts draws category 0 at the bottom, so the\n// axis is inverted to put the first row (the largest of a top-N, a waterfall's\n// first step) at the top. The rotated title sits just beyond the longest label\n// rather than at a fixed gap that would put it on top of the labels.\n//\n// A bucketed axis also names its period in the axis tooltip's header: ECharts\n// heads it with the raw category ('2026-01-01') unless the axis pointer's label\n// has a formatter, so it reads 'January 2026' instead, always with its year.\n// The axis's dateLabel style writes both its tick labels and that header.\nfunction categoryAxisOption(\n config: ChartConfig,\n data: ComponentData,\n categories: string[],\n horizontal: boolean,\n locale: ReportLocaleTag,\n) {\n const granularity = bucketGranularity(data);\n const dateLabel = chartDateLabel(config);\n const periodLabel = periodAxisLabel(granularity, categories, locale, dateLabel);\n const axis = {\n type: 'category' as const,\n data: categories,\n inverse: horizontal,\n name: categoryAxisTitle(config, data),\n nameLocation: 'middle' as const,\n ...(granularity ? {\n axisPointer: {\n label: {\n formatter: (params: { value: unknown }) => formatPeriodLabel(\n String(params.value),\n granularity,\n true,\n locale,\n dateLabel,\n ),\n },\n },\n } : {}),\n };\n\n if (!horizontal) {\n // The gap clears the year's second line when the labels print one.\n const secondLine = granularity && dateLabel === ReportChartDateLabel.Short && spansMultipleYears(categories);\n\n return {\n ...axis,\n nameGap: secondLine ? 40 : 28,\n ...periodLabel,\n };\n }\n\n // Period labels, short, long or numeric ('May', 'Q2', 'May 2026'), are\n // bounded in length and never cut; only a plain category is truncated. The labels are cut here rather than by ECharts' own\n // truncation, so the title's gap is measured on exactly the text the axis\n // draws.\n const shown = granularity\n ? null\n : new Map(categories.map((category) => [category, truncateAxisLabel(category)]));\n const labels = shown ? [...shown.values()] : displayedCategoryLabels(categories, granularity, locale, dateLabel);\n\n return {\n ...axis,\n nameGap: widestAxisLabel(labels) + AXIS_LABEL_MARGIN + AXIS_NAME_CLEARANCE,\n ...(shown ? { axisLabel: { formatter: (value: string) => shown.get(value) ?? value } } : periodLabel),\n };\n}\n\n// The category axis's title: the level shown while the chart is drilled\n// below its top (the server names it, 'Month'), else the authored title.\nexport function categoryAxisTitle(config: ChartConfig, data: ComponentData): string | undefined {\n return data.drill?.path?.length ? data.drill.levelLabel : config.xAxis?.label;\n}\n\n// The category axis's title side, or null when the axis has no title to make\n// room for.\nfunction categoryTitleSide(config: ChartConfig, data: ComponentData, horizontal: boolean): AxisTitleSide | null {\n if (!categoryAxisTitle(config, data)) {\n return null;\n }\n\n return horizontal ? 'left' : 'bottom';\n}\n\n// The value axes' title side, or null when none of them has a title. A\n// vertical chart's titles sit above the plot, at the top of each axis line, so\n// room is made once for both; a horizontal chart's sits below.\nfunction valueTitleSide(axes: (ChartValueAxis | undefined)[], horizontal: boolean): AxisTitleSide | null {\n if (!axes.some((axis) => axis?.label)) {\n return null;\n }\n\n return horizontal ? 'bottom' : 'top';\n}\n\n// The tick labels as the axis shows them: a bucket's primary period label\n// ('May', 'Q2', 'May 2026'), otherwise the category itself. The year a\n// multi-year axis prints under a short period is left out, as it is never the\n// wider line.\nfunction displayedCategoryLabels(\n categories: string[],\n granularity: ChartGranularity | null,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): string[] {\n return granularity\n ? categories.map((category) => periodLabelParts(category, granularity, locale, dateLabel)?.primary ?? category)\n : categories;\n}\n\n// The pixel width of the widest label. A label that breaks over several lines\n// is as wide as its longest line.\nfunction widestAxisLabel(labels: string[]): number {\n return labels.reduce((widest, label) => label.split('\\n').reduce(\n (lineWidest, line) => Math.max(lineWidest, axisLabelWidth(line)),\n widest,\n ), 0);\n}\n\n// A category label cut to CATEGORY_LABEL_MAX_WIDTH, line by line: the longest\n// start of each line that still fits with the ellipsis after it.\nfunction truncateAxisLabel(label: string): string {\n return label.split('\\n').map((line) => {\n if (axisLabelWidth(line) <= CATEGORY_LABEL_MAX_WIDTH) {\n return line;\n }\n\n // Code points, so an emoji or other surrogate pair is never split.\n const characters = Array.from(line);\n const cut = (length: number) => `${characters.slice(0, length).join('').trimEnd()}${LABEL_ELLIPSIS}`;\n let fits = 0;\n let tooLong = characters.length;\n while (tooLong - fits > 1) {\n const length = Math.floor((fits + tooLong) / 2);\n if (axisLabelWidth(cut(length)) <= CATEGORY_LABEL_MAX_WIDTH) {\n fits = length;\n } else {\n tooLong = length;\n }\n }\n\n return cut(fits);\n }).join('\\n');\n}\n\n// One line's width in the axis-label font, measured on a canvas the way\n// ECharts measures it for containLabel. Outside a browser there is no canvas\n// to measure with, so the line counts as zero width.\nlet axisLabelContext: CanvasRenderingContext2D | null = null;\n\nfunction axisLabelWidth(line: string): number {\n if (!axisLabelContext && typeof document !== 'undefined') {\n axisLabelContext = document.createElement('canvas').getContext('2d');\n }\n\n if (!axisLabelContext) {\n return 0;\n }\n\n axisLabelContext.font = AXIS_LABEL_FONT;\n\n return axisLabelContext.measureText(line).width;\n}\n\nfunction buildWaterfallOption(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n): EChartsOption {\n const config = component.config as ChartConfig;\n const waterfall = extractWaterfall(component, data);\n const horizontal = config.orientation === 'horizontal';\n const categories = waterfall.steps.map((step) => step.category);\n const categoryAxis = categoryAxisOption(config, data, categories, horizontal, context.locale);\n // The one measure's format writes the axis and the tooltip. The axis has to\n // reach the furthest point the running total gets to, on either side of\n // zero, or the furthest reference.\n const spec = config.measures?.[0];\n const references = chartReferences(config, false);\n const valueAxis = valueAxisOption(config.valueAxis, horizontal, valueAxisLabel(resolveValueAxisFormat(\n spec && hasNumberFormat(spec) ? spec : null,\n () => Math.max(referencePeak(references, 0), ...waterfall.steps.map((step) => Math.abs(step.start + (step.change ?? 0)))),\n context,\n ), context), { reach: referenceReach(references, 0) });\n // One visible series, so the legend is hidden unless the config pins it.\n const legendPosition = resolveLegendPosition(config, 1);\n const granularity = bucketGranularity(data);\n\n return {\n grid: axisGrid(\n legendPosition,\n categoryTitleSide(config, data, horizontal),\n valueTitleSide([config.valueAxis], horizontal),\n ),\n legend: { ...legendOption(legendPosition), data: [waterfall.name] },\n // Per bar: the invisible base is silent, so only a step answers the hover.\n tooltip: {\n trigger: 'item',\n formatter: (params: TooltipComponentFormatterCallbackParams) => waterfallTooltip(\n waterfall,\n (Array.isArray(params) ? params[0] : params).dataIndex,\n granularity,\n chartDateLabel(config),\n spec,\n context,\n ),\n },\n xAxis: horizontal ? valueAxis : categoryAxis,\n yAxis: horizontal ? categoryAxis : valueAxis,\n series: [...waterfallSeries(waterfall), ...referenceCarriers(references, categories)],\n };\n}\n\n// An invisible base series lifts each visible bar to where its step starts.\n// Both stack with the 'all' strategy, which adds signed values in series order,\n// so a fall draws DOWN from the total before it, even across zero. The default\n// same-sign stacking would hang a negative bar below the axis instead.\nfunction waterfallSeries(waterfall: ExtractedWaterfall): SeriesOption[] {\n return [\n {\n type: 'bar',\n stack: 'waterfall',\n stackStrategy: 'all',\n data: waterfall.steps.map((step) => step.start),\n barMaxWidth: 48,\n itemStyle: { color: 'transparent' },\n silent: true,\n },\n {\n name: waterfall.name,\n type: 'bar',\n stack: 'waterfall',\n stackStrategy: 'all',\n barMaxWidth: 48,\n // The series color is the rise color so a pinned legend shows it; each\n // bar is then colored by what it does to the total. A click on the\n // closing Total does nothing, so it keeps the arrow even when the\n // steps show a hand (withClickActions), and its tooltip names no action.\n itemStyle: { color: `#${REPORT_WATERFALL_COLORS.rise}` },\n data: waterfall.steps.map((step) => ({\n value: step.change,\n itemStyle: { color: `#${REPORT_WATERFALL_COLORS[step.kind]}` },\n ...(step.kind === 'total' ? { cursor: 'default' } : {}),\n })),\n },\n ];\n}\n\n// A step's tooltip: its period, how far it moved the running total and where\n// that left it. The closing Total shows the total alone. The category and the\n// measure name come from the data and the config, and ECharts sets the tooltip\n// as HTML, so both are escaped. Periods and amounts are written in the report's\n// locale, amounts in the measure's number format (a plain number without one);\n// the words ('Running total') stay English.\nfunction waterfallTooltip(\n waterfall: ExtractedWaterfall,\n index: number,\n granularity: ChartGranularity | null,\n dateLabel: ReportChartDateLabel,\n spec: NumberFormatSpec | undefined,\n context: ReportFormatContext,\n): string {\n const step = waterfall.steps[index];\n const category = escapeHtml(granularity\n ? formatPeriodLabel(step.category, granularity, true, context.locale, dateLabel)\n : step.category);\n const name = escapeHtml(waterfall.name);\n const amount = (value: number | null) => formatNumber(value, spec ?? {}, context);\n\n if (step.kind === 'total') {\n return `${category}<br/>${name}: ${amount(step.change)}`;\n }\n\n const sign = (step.change ?? 0) > 0 ? '+' : '';\n\n return `${category}<br/>${name}: ${sign}${amount(step.change)}`\n + `<br/>Running total: ${amount(step.start + (step.change ?? 0))}`;\n}\n\n// Default legend placement when the config doesn't pin one: pie charts read\n// best with the slice key beside them (right); axis charts only need a legend\n// to tell multiple series apart, so a single-series chart hides it. An explicit\n// config.legend (including 'hidden') always wins. Shared with the PowerPoint\n// export so both media place the legend identically.\nexport function resolveLegendPosition(config: ChartConfig, seriesCount: number, colorBy = false): LegendPosition {\n if (config.legend) {\n return config.legend;\n }\n\n const pie = config.chartType === 'pie' || config.chartType === 'donut';\n\n // colorBy maps each bar's color to its category, so it needs a legend even\n // though it's a single measure.\n return pie || colorBy || seriesCount > 1 ? (pie ? 'right' : 'top') : 'hidden';\n}\n\n// The viewer's legend picks carried into an option (legend.selected): ECharts\n// reads them by entry name, an entry not named stays on, and a name the\n// chart no longer draws is ignored. A hidden legend takes none, so a series\n// never stays off once its legend is gone and nothing can turn it back on.\nfunction legendWithSelected(option: EChartsOption, selected: Readonly<Record<string, boolean>>): EChartsOption {\n const legend = option.legend;\n\n if (!Object.keys(selected).length || !legend || Array.isArray(legend) || legend.show === false) {\n return option;\n }\n\n return { ...option, legend: { ...legend, selected: { ...selected } } };\n}\n\nfunction legendOption(position: LegendPosition): LegendComponentOption {\n if (position === 'hidden') {\n return { show: false };\n }\n\n const base: LegendComponentOption = { type: 'scroll' };\n\n switch (position) {\n case 'bottom':\n return { ...base, bottom: 0 };\n case 'left':\n return { ...base, orient: 'vertical', left: 0, top: 'middle' };\n case 'right':\n return { ...base, orient: 'vertical', right: 0, top: 'middle' };\n default:\n return { ...base, top: 0 };\n }\n}\n\n// The plot's grid: room on the legend's side so it never overlaps the\n// bars/lines, plus room for the category and value axes' titles on their\n// sides, which containLabel does not reserve (it covers the tick labels only).\nfunction axisGrid(\n position: LegendPosition,\n categoryTitle: AxisTitleSide | null,\n valueTitle: AxisTitleSide | null,\n): EChartsOption['grid'] {\n return [categoryTitle, valueTitle].reduce<AxisGridRoom>(\n (grid, side) => (side ? { ...grid, [side]: grid[side] + AXIS_NAME_ROOM } : grid),\n legendGrid(position),\n );\n}\n\n// Plot-edge room on whichever side the legend occupies; containLabel keeps the\n// tick labels inside what is left.\nfunction legendGrid(position: LegendPosition): AxisGridRoom {\n const base: AxisGridRoom = { left: 8, right: 16, top: 8, bottom: 8, containLabel: true };\n\n switch (position) {\n case 'bottom':\n return { ...base, bottom: 32 };\n case 'left':\n return { ...base, left: 96 };\n case 'right':\n return { ...base, right: 96 };\n case 'hidden':\n return base;\n default:\n return { ...base, top: 32 };\n }\n}\n\n// The stack a stacked series joins. On a two-axis chart (axisIndex set) each\n// type stacks per axis; otherwise a combo stacks per type and a single-type\n// chart stacks everything together.\nfunction stackKey(type: AxisChartType, combo: boolean, axisIndex: ValueAxisIndex | undefined): string {\n if (axisIndex !== undefined) {\n return `total-${type}-${axisIndex}`;\n }\n\n return combo ? `total-${type}` : 'total';\n}\n\n// How buildSeries draws one series: its drawn type, the stack it joins, whether\n// it lays the colorBy overlap, whether the chart is a combo, its tooltip, its\n// value axis on a two-axis chart, its own CSS color (undefined leaves it to\n// the theme's palette by position), and its data labels (null prints none).\ninterface SeriesLayout {\n type: AxisChartType;\n stack: string | undefined;\n overlap: boolean;\n combo: boolean;\n tooltip: SeriesTooltip;\n axisIndex: ValueAxisIndex | undefined;\n color: string | undefined;\n labels: SeriesDataLabels | null;\n}\n\n// One series of an axis chart. A measure's display keys only add what they\n// change, so a series that sets none is drawn by the theme as before: its own\n// color (the bar, the line, the area under it and its legend key all follow\n// itemStyle), its line style and its markers, shown on every point unless\n// markers is false. Data labels come last, on the series or on its latest\n// point.\nfunction buildSeries(\n series: ExtractedChartSeriesItem,\n values: (number | null | ShareDataItem)[],\n layout: SeriesLayout,\n): SeriesOption {\n // On a two-axis chart every series names its value axis.\n const axis = layout.axisIndex === undefined ? {} : { yAxisIndex: layout.axisIndex };\n const color = layout.color;\n const itemStyle = color ? { itemStyle: { color } } : {};\n\n if (layout.type === 'bar') {\n // 'outside' follows each bar's sign: past a positive bar's end and below\n // (or left of) a negative one's, where 'top' would sit at the zero line.\n const { series: labels, data } = placeDataLabels(layout.labels, layout.stack ? 'inside' : 'outside', values);\n\n return {\n name: series.name,\n type: 'bar',\n data,\n stack: layout.stack,\n tooltip: layout.tooltip,\n ...axis,\n ...itemStyle,\n barMaxWidth: 48,\n // colorBy: overlap the per-category series so each bar renders full-width.\n ...(layout.overlap ? { barGap: '-100%', barCategoryGap: '20%' } : {}),\n ...labels,\n };\n }\n\n const lineType = measureLineStyle(series.measure);\n const lineStyle = color || lineType\n ? { lineStyle: { ...(color ? { color } : {}), ...(lineType ? { type: lineType } : {}) } }\n : {};\n const { series: labels, data } = placeDataLabels(layout.labels, 'top', values);\n\n return {\n name: series.name,\n type: 'line',\n data,\n stack: layout.stack,\n tooltip: layout.tooltip,\n ...axis,\n ...itemStyle,\n ...lineStyle,\n ...(series.measure.markers === false ? { showSymbol: false } : {}),\n smooth: true,\n symbolSize: 6,\n areaStyle: layout.type === 'area' ? { opacity: 0.25 } : undefined,\n // In a combo the line is drawn over the bars whatever order the measures\n // come in; at the same z a later bar series would paint across it.\n ...(layout.combo ? { z: 3 } : {}),\n ...labels,\n };\n}\n\n// A 100% stacked series' points: each share, plotted and stacked, with the\n// value it came from.\nfunction shareData(values: (number | null)[], shares: (number | null)[]): ShareDataItem[] {\n return values.map((raw, index) => ({ value: shares[index] ?? null, raw }));\n}\n\n// What a series prints beside its points (A2 data labels): every point\n// ('all'), every point whose label fits without overlapping another ('auto',\n// LabelLayout's hideOverlap), or only its latest point ('last'). none, an\n// absent mode or one the viewer does not know prints nothing, and the series\n// is left as it was. A colorBy chart's series each hold one bar, so 'last'\n// labels every bar there, as 'all' does.\n//\n// Where the label sits depends on what the series draws, so buildSeries\n// places it (placeDataLabels).\nexport function dataLabelOption(\n mode: ReportChartDataLabels | undefined,\n formatter: DataLabelFormatter,\n): SeriesDataLabels | null {\n const text = { show: true as const, fontSize: REPORT_DATA_LABEL_FONT_SIZE, formatter };\n\n switch (mode) {\n case ReportChartDataLabels.All:\n return { text, hideOverlap: false, lastOnly: false };\n case ReportChartDataLabels.Auto:\n return { text, hideOverlap: true, lastOnly: false };\n case ReportChartDataLabels.Last:\n return { text, hideOverlap: false, lastOnly: true };\n default:\n return null;\n }\n}\n\n// A series' data labels at `position`: on the series ('all', and with the\n// overlap hiding 'auto'), or on its latest non-empty point alone ('last').\n// No labels leave the series and its points as they were.\nfunction placeDataLabels<P extends DataLabelPosition>(\n labels: SeriesDataLabels | null,\n position: P,\n values: (number | null | ShareDataItem)[],\n): PlacedDataLabels<P> {\n if (!labels) {\n return { series: {}, data: values };\n }\n\n const label: DataLabel<P> = { ...labels.text, position };\n\n if (labels.lastOnly) {\n return { series: {}, data: labelLastPoint(values, label) };\n }\n\n return {\n series: { label, ...(labels.hideOverlap ? { labelLayout: { hideOverlap: true } } : {}) },\n data: values,\n };\n}\n\n// A series' points with its latest non-empty point carrying the label. A\n// series with no value anywhere is left as it was.\nfunction labelLastPoint<P extends DataLabelPosition>(\n values: (number | null | ShareDataItem)[],\n label: DataLabel<P>,\n): SeriesDataItem<P>[] {\n const last = values.reduce<number>((found, item, index) => (pointValue(item) === null ? found : index), -1);\n\n return values.map((item, index): SeriesDataItem<P> => {\n if (index !== last) {\n return item;\n }\n\n return isShareDataItem(item) ? { ...item, label } : { value: item, label };\n });\n}\n\nfunction isShareDataItem(item: number | null | ShareDataItem): item is ShareDataItem {\n return item !== null && typeof item === 'object';\n}\n\n// How a series' data labels write a value. A 100% stacked series prints its\n// share as a whole percentage, as the share axis's ticks do. A series on an\n// axis with a number format prints its value in its measure's format, at the\n// units and decimals the axis decided, so a label reads like the ticks beside\n// it. Any other prints the plain locale-grouped number its tooltip shows. A\n// share point's raw value is what a label reads when it carries one.\nfunction dataLabelFormatter(\n measure: ChartMeasure,\n axisFormat: ValueAxisFormat | null,\n share: boolean,\n context: ReportFormatContext,\n): DataLabelFormatter {\n if (share) {\n const percent = wholePercentFormatter(context);\n\n return (params) => percent(params.value);\n }\n\n if (axisFormat) {\n const options = { units: axisFormat.chart.units, decimals: axisFormat.chart.decimals };\n\n return (params) => formatNumber(dataLabelValue(params), measure, context, options);\n }\n\n return (params) => formatPlainNumber(dataLabelValue(params), context.locale);\n}\n\n// The value a data label writes: the raw value its point carries, else the\n// plotted one.\nfunction dataLabelValue(params: DataLabelParams): unknown {\n const data = params.data;\n const raw = data !== null && typeof data === 'object' ? (data as { raw?: unknown }).raw : undefined;\n\n return raw ?? params.value;\n}\n\n// A 100% stacked chart's tooltip: the category, then each series on its own\n// line, a share as its percentage to one decimal followed by the value it came\n// from in its measure's format ('25.0% (1)'), and any other series by its own\n// value. The category and the series names come from the data and the config,\n// and ECharts sets the tooltip as HTML, so both are escaped.\nfunction percentTooltip(\n params: TooltipComponentFormatterCallbackParams,\n extracted: ExtractedChartSeries,\n shares: PercentShares,\n granularity: ChartGranularity | null,\n dateLabel: ReportChartDateLabel,\n context: ReportFormatContext,\n): string {\n const items = Array.isArray(params) ? params : [params];\n const dataIndex = items[0]?.dataIndex ?? 0;\n const category = extracted.categories[dataIndex] ?? '';\n const heading = escapeHtml(granularity\n ? formatPeriodLabel(category, granularity, true, context.locale, dateLabel)\n : category);\n const ratioContext = { ...context, ratioPercent: true };\n\n const lines = items.map((item) => {\n const series = extracted.series[item.seriesIndex ?? -1];\n const marker = typeof item.marker === 'string' ? item.marker : '';\n const label = `${marker} ${escapeHtml(item.seriesName ?? series?.name ?? '')}`;\n const value = seriesTooltip(series?.measure, context).valueFormatter(series?.values[item.dataIndex] ?? null);\n const share = shares.get(item.seriesIndex ?? -1)?.[item.dataIndex] ?? null;\n\n return share === null\n ? `${label}: ${value}`\n : `${label}: ${formatNumber(share, PERCENT_SHARE_FORMAT, ratioContext)} (${value})`;\n });\n\n return [heading, ...lines].join('<br/>');\n}\n\n// A value axis: its title and range from the config, its tick labels from\n// valueAxisLabel. A vertical chart's title sits above the axis line, reading\n// away from the plot's edge; a horizontal chart's is centered below the ticks.\n// A bound or interval that is not a usable number is left to ECharts. A 100%\n// stacked chart's share axis (extras.percentMin) has its own fixed range.\nfunction valueAxisOption(\n axis: ChartValueAxis | undefined,\n horizontal: boolean,\n axisLabel: ValueAxisLabel,\n extras: ValueAxisExtras = {},\n) {\n const range = extras.percentMin === undefined\n ? valueAxisRange(axis)\n : { min: extras.percentMin, max: PERCENT_AXIS_MAX, interval: PERCENT_AXIS_INTERVAL };\n\n return {\n type: 'value' as const,\n name: axis?.label || undefined,\n nameLocation: horizontal ? 'middle' as const : 'end' as const,\n nameGap: horizontal ? 28 : 10,\n nameTextStyle: horizontal ? undefined : { align: extras.index === 1 ? 'right' as const : 'left' as const },\n // A pinned bound wins; one left open reaches the references (reachMin),\n // or on a rank axis starts at rank 1.\n min: range.min ?? (extras.rank ? RANK_AXIS_MIN : reachMin(extras.reach)),\n max: range.max ?? reachMax(extras.reach),\n interval: range.interval,\n axisLabel,\n ...(extras.rank ? { inverse: true, minInterval: 1 } : {}),\n };\n}\n\n// The part of a value axis's range the config pins. A bound that is not a\n// finite number, or an interval that is not a positive one, is left out, and\n// the chart picks it from the data. Shared with the PowerPoint export so both\n// media draw the same range.\nexport function valueAxisRange(axis: ChartValueAxis | undefined): { min?: number; max?: number; interval?: number } {\n const interval = axisNumber(axis?.interval);\n\n return {\n min: axisNumber(axis?.min),\n max: axisNumber(axis?.max),\n interval: interval !== undefined && interval > 0 ? interval : undefined,\n };\n}\n\n// A two-axis chart's value axes: the primary on the left, the second on the\n// right without gridlines of its own. Each axis's ticks take the format of the\n// measures plotted against it (axisLabels). Without a range on either axis the\n// second axis aligns its ticks to the primary's gridlines.\n//\n// On a 100% stacked chart (percentMin set) the primary axis is the share axis,\n// whose range is fixed, and the second axis's series are not stacked. An axis\n// of ranks alone (rankAxes) is inverted, and the axes then keep their own\n// ticks, so a rank axis steps by whole ranks.\nfunction twoValueAxesOption(\n config: ChartConfig,\n axisLabels: ValueAxisLabel[],\n context: ReportFormatContext,\n percentMin: number | undefined,\n references: DrawnReference[],\n rankAxes: boolean[],\n) {\n const percent = percentMin !== undefined;\n const label = (axisIndex: ValueAxisIndex) => axisLabels[axisIndex];\n\n return [\n valueAxisOption(config.valueAxis, false, percent ? percentAxisLabel(context) : label(0), {\n index: 0,\n percentMin,\n reach: referenceReach(references, 0),\n rank: rankAxes[0],\n }),\n {\n ...valueAxisOption(config.secondaryAxis, false, label(1), {\n index: 1,\n reach: referenceReach(references, 1),\n rank: rankAxes[1],\n }),\n position: 'right' as const,\n splitLine: { show: false },\n alignTicks: !percent && !rankAxes[0] && !rankAxes[1]\n && !hasAxisRange(config.valueAxis) && !hasAxisRange(config.secondaryAxis),\n },\n ];\n}\n\n// Whether the config pins any of an axis's range: a bound or a tick interval.\nfunction hasAxisRange(axis: ChartValueAxis | undefined): boolean {\n return Object.values(valueAxisRange(axis)).some((value) => value !== undefined);\n}\n\n// A configured bound or interval when it is a finite number, else undefined.\nfunction axisNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n}\n\n// A value axis's tick labels.\ninterface ValueAxisLabel {\n formatter: (value: number) => string;\n}\n\n// Tick labels written in the locale. ECharts' own ticks are grouped en-US\n// whatever the page's language.\n//\n// With a number format, the units and decimals decided once for the whole\n// axis (resolveValueAxisFormat) write every tick alike ('1.5K', '2.0K', never\n// '2K'). Without one, or when it leaves the ticks an unscaled number with no\n// pinned decimals (format 'number', or precision-less units none), each tick\n// is a plain locale-grouped number keeping its own decimals, so a 0.0002 tick\n// never rounds to '0'.\nfunction valueAxisLabel(format: ValueAxisFormat | null, context: ReportFormatContext): ValueAxisLabel {\n if (!format || (format.chart.units === ReportNumberUnits.None && format.chart.decimals === null)) {\n return { formatter: (value: number) => formatPlainNumber(value, context.locale) };\n }\n\n const options = { units: format.chart.units, decimals: format.chart.decimals };\n\n return {\n formatter: (value: number) => formatNumber(value, format.spec, format.context, options),\n };\n}\n\n// An axis's format from the spec its measures agree on, with the units and\n// decimals decided from its peak. Without a spec the axis is plain, and the\n// peak is never computed.\nfunction resolveValueAxisFormat(\n spec: NumberFormatSpec | null,\n peak: () => number,\n context: ReportFormatContext,\n): ValueAxisFormat | null {\n return spec ? { spec, chart: resolveChartNumberFormat(spec, peak(), context), context } : null;\n}\n\n// Each value axis's format, by axis index. A chart with one value axis takes\n// the format the plotted series' measures agree on (a splitBy or colorBy chart\n// plots only its first measure), from the peak of all its series. On a two-axis chart each axis takes the format of the measures\n// plotted against it, from the peak of its own series, which are never\n// stacked with a 100% stacked chart's shares. A reference past the data\n// stretches its axis, so it counts toward the peak (referencePeak); a 100%\n// stacked chart's references are shares, which the raw values' peak leaves\n// out. contexts holds each axis's context (annotatedAxisContexts).\nfunction valueAxisFormats(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n contexts: ReportFormatContext[],\n percent: boolean,\n references: DrawnReference[],\n): (ValueAxisFormat | null)[] {\n const reach = (axisIndex: ValueAxisIndex) => (percent && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));\n\n if (!axisIndexes.includes(1)) {\n return [resolveValueAxisFormat(\n axisNumberFormat(extracted.series.map((series) => series.measure)),\n () => Math.max(chartValuePeak(extracted.series.map((series) => series.values), !!config.stacked), reach(0)),\n contexts[0],\n )];\n }\n\n return ([0, 1] as const).map((axisIndex) => {\n const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);\n\n return resolveValueAxisFormat(\n axisNumberFormat(onAxis.map((series) => series.measure)),\n () => Math.max(chartValuePeak(onAxis.map((series) => series.values), !!config.stacked && !percent), reach(axisIndex)),\n contexts[axisIndex],\n );\n });\n}\n\n// A 100% stacked chart's share axis ticks: whole percentages in the locale\n// ('25%', '25 %' in fr-CA). The shares are ratios whatever the report's\n// percentFormat says of its stored values.\nfunction percentAxisLabel(context: ReportFormatContext): ValueAxisLabel {\n return { formatter: wholePercentFormatter(context) };\n}\n\n// A share as a whole percentage in the locale, for the share axis's ticks and\n// its series' data labels.\nfunction wholePercentFormatter(context: ReportFormatContext): (value: unknown) => string {\n const ratioContext = { ...context, ratioPercent: true };\n\n return (value: unknown) => formatNumber(value, PERCENT_AXIS_FORMAT, ratioContext);\n}\n\n// What a series' tooltip writes beside its name.\ninterface SeriesTooltip {\n valueFormatter: (value: unknown) => string;\n}\n\n// A series' tooltip value in its measure's number format, per value ('—' when\n// empty). A measure without one writes it as the plain value axis does. A\n// value can arrive as an array (a [value, ...] data item), whose first entry\n// is the value.\nfunction seriesTooltip(measure: ChartMeasure | undefined, context: ReportFormatContext): SeriesTooltip {\n if (!hasNumberFormat(measure)) {\n return { valueFormatter: (value: unknown) => formatPlainNumber(value, context.locale) };\n }\n\n return {\n valueFormatter: (value: unknown) => formatNumber(Array.isArray(value) ? value[0] : value, measure, context),\n };\n}\n\nfunction buildPieOption(\n component: ReportComponent,\n data: ComponentData,\n donut: boolean,\n context: ReportFormatContext,\n): EChartsOption {\n const config = component.config as ChartConfig;\n const extracted = extractChartSeries(component, data);\n const values = extracted.series[0]?.values ?? [];\n const legendPosition = resolveLegendPosition(config, extracted.series.length);\n\n return {\n tooltip: { trigger: 'item' },\n legend: legendOption(legendPosition),\n series: [\n {\n type: 'pie',\n radius: donut ? ['45%', '72%'] : '72%',\n center: pieCenter(legendPosition),\n tooltip: seriesTooltip(extracted.series[0]?.measure, context),\n label: { show: false },\n data: extracted.categories.map((category, index) => ({\n name: category,\n value: values[index] ?? 0,\n })),\n },\n ],\n };\n}\n\n// Nudge the pie off-center toward the opposite edge from its legend so the two\n// don't collide; centered when the legend is hidden.\nfunction pieCenter(position: LegendPosition): [string, string] {\n switch (position) {\n case 'left':\n return ['60%', '50%'];\n case 'right':\n return ['40%', '50%'];\n case 'top':\n return ['50%', '58%'];\n case 'bottom':\n return ['50%', '46%'];\n default:\n return ['50%', '50%'];\n }\n}\n\nfunction uniqueValues(rows: Record<string, unknown>[], column: string): unknown[] {\n const seen = new Set<unknown>();\n const values: unknown[] = [];\n for (const row of rows) {\n const value = row[column];\n if (!seen.has(value)) {\n seen.add(value);\n values.push(value);\n }\n }\n\n return values;\n}\n\nfunction numeric(value: unknown): number | null {\n if (value === null || value === undefined || value === '') {\n return null;\n }\n\n const parsed = Number(value);\n\n return Number.isFinite(parsed) ? parsed : null;\n}\n\n// The effective time bucket the rows were grouped into (from the data endpoint),\n// or null when the x-axis isn't a time axis — gates the compact period labels.\nfunction bucketGranularity(data: ComponentData): ChartGranularity | null {\n return data.granularity && GRANULARITY_OPTIONS.some((option) => option.value === data.granularity)\n ? data.granularity\n : null;\n}\n\n// Whether the period-start categories cross a year boundary. When they don't,\n// the year is pure noise on every label, so it's dropped entirely.\nexport function spansMultipleYears(categories: string[]): boolean {\n const years = new Set<number>();\n for (const category of categories) {\n const date = parseISO(category);\n if (isValid(date)) {\n years.add(date.getFullYear());\n }\n }\n\n return years.size > 1;\n}\n\n// A time axis's date label style when its config names one the viewer knows,\n// else short.\nexport function chartDateLabel(config: ChartConfig | undefined): ReportChartDateLabel {\n return Object.values(ReportChartDateLabel).find((style) => style === config?.xAxis?.dateLabel)\n ?? ReportChartDateLabel.Short;\n}\n\n// A bucket's period-start split into its primary label and its year. A year\n// reads \"2025\" in every style. Short, in the locale: day/week read \"May 1\"\n// ('1 mai' in fr-CA), month \"May\" ('mai'), quarter \"Q2\" ('T2' in French).\n// Long carries its year, in the locale: \"May 1, 2026\", \"May 2026\" ('mai\n// 2026'), \"Q2 2026\". Numeric is the same in every locale: \"2026-05-01\",\n// \"2026-05\", \"2026-Q2\". Returns null for a value that isn't a parseable date\n// (left as-is by callers).\nfunction periodLabelParts(\n value: string,\n granularity: ChartGranularity,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel = ReportChartDateLabel.Short,\n): { primary: string; year: string } | null {\n const date = parseISO(value);\n if (!isValid(date)) {\n return null;\n }\n\n const year = String(date.getFullYear());\n if (granularity === 'year') {\n return { primary: year, year };\n }\n\n return { primary: periodPrimaryLabel(date, granularity, locale, dateLabel), year };\n}\n\n// A period's label in the style asked for, the year aside (see\n// periodLabelParts).\nfunction periodPrimaryLabel(\n date: Date,\n granularity: Exclude<ChartGranularity, 'year'>,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): string {\n const year = String(date.getFullYear());\n const quarter = Math.floor(date.getMonth() / 3) + 1;\n\n if (dateLabel === ReportChartDateLabel.Numeric) {\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n switch (granularity) {\n case 'quarter':\n return `${year}-Q${quarter}`;\n case 'month':\n return `${year}-${month}`;\n default: // day, week — the bucket start\n return `${year}-${month}-${day}`;\n }\n }\n\n const long = dateLabel === ReportChartDateLabel.Long;\n switch (granularity) {\n case 'quarter':\n return long\n ? `${quarterPrefix(locale)}${quarter} ${year}`\n : `${quarterPrefix(locale)}${quarter}`;\n case 'month':\n return formatLocalDate(date, locale, long ? MONTH_YEAR : MONTH_LONG);\n default: // day, week — the bucket start as a month and day\n return formatLocalDate(date, locale, long ? DAY_SHORT : MONTH_DAY);\n }\n}\n\n// Whether a period label leaves its year to be added apart: only a short one\n// does, a long or numeric label already carries it.\nfunction periodYearApart(granularity: ChartGranularity, dateLabel: ReportChartDateLabel): boolean {\n return granularity !== 'year' && dateLabel === ReportChartDateLabel.Short;\n}\n\nfunction quarterPrefix(locale: ReportLocaleTag): string {\n return QUARTER_PREFIXES.get(locale.split('-')[0].toLowerCase()) ?? QUARTER_PREFIX;\n}\n\n// A compact single-line period label — for media that can't do a styled\n// second line, e.g. PowerPoint. A short label has its year appended only when\n// the data spans years; a long or numeric one always carries it.\nexport function formatPeriodLabel(\n value: string,\n granularity: ChartGranularity,\n multiYear: boolean,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel = ReportChartDateLabel.Short,\n): string {\n const parts = periodLabelParts(value, granularity, locale, dateLabel);\n if (!parts) {\n return value;\n }\n\n return multiYear && periodYearApart(granularity, dateLabel) ? `${parts.primary} ${parts.year}` : parts.primary;\n}\n\n// A cross-tab's column headings, the one rule the grid and the PDF/PowerPoint\n// exports share. The first is the row key and keeps its authored label; the\n// rest are pivot VALUES. When the pivot axis is a time dimension the server\n// sends the grain it bucketed at, so a period-start like \"2026-01-01\" reads\n// \"January 2026\" ('janvier 2026' in fr-CA), as the chart's x-axis labels it.\nexport function pivotHeadings(\n config: ListConfig,\n data: ComponentData,\n locale: ReportLocaleTag,\n): string[] {\n const columns = data.columns ?? [];\n const multiYear = spansMultipleYears(columns);\n\n return columns.map((column, index) => {\n if (index === 0) {\n return config.rowBy?.label || column;\n }\n\n return data.granularity ? formatPeriodLabel(column, data.granularity, multiYear, locale) : column;\n });\n}\n\n// A cross-tab's columns as the grid and the exports draw them: each headed by\n// pivotHeadings(), and every pivot-value column formatted by the one\n// config.cellFormat. The row key column stays as it came. `numeric` marks the\n// columns whose cells are formatted numbers, which are right-aligned.\nexport function pivotColumnSpecs(\n config: ListConfig,\n data: ComponentData,\n locale: ReportLocaleTag,\n): (ListColumn & { numeric: boolean })[] {\n const headings = pivotHeadings(config, data, locale);\n const cellFormat = config.cellFormat;\n const numeric = hasNumberFormat(cellFormat);\n const cells: Pick<ListColumn, 'format' | 'precision' | 'units'> = numeric && cellFormat\n ? { format: listColumnFormat(cellFormat.format), precision: cellFormat.precision, units: cellFormat.units }\n : {};\n\n return (data.columns ?? []).map((column, index) => index === 0\n ? { column, label: headings[index], numeric: false }\n : { column, label: headings[index], ...cells, numeric });\n}\n\n// A number format's style as a list column's format: the two enums share\n// their number values.\nfunction listColumnFormat(format: NumberFormatSpec['format']): ReportListColumnFormat | undefined {\n return Object.values(ReportListColumnFormat).find((value) => value === format);\n}\n\n// ECharts category-axis label config for a time bucket: the primary label on\n// line one, and — only when the data spans multiple years — the year on a small\n// gray second line, centered under the tick (year granularity needs no second\n// line, it already is the year, and neither does a long or numeric label,\n// which carries its year). Empty for a non-time axis (labels as-is).\nfunction periodAxisLabel(\n granularity: ChartGranularity | null,\n categories: string[],\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n): { axisLabel?: Record<string, unknown> } {\n if (!granularity) {\n return {};\n }\n\n const multiYear = spansMultipleYears(categories);\n\n return {\n axisLabel: {\n formatter: (value: string) => {\n const parts = periodLabelParts(value, granularity, locale, dateLabel);\n if (!parts) {\n return value;\n }\n\n return multiYear && periodYearApart(granularity, dateLabel)\n ? `${parts.primary}\\n{yr|${parts.year}}`\n : parts.primary;\n },\n rich: { yr: { fontSize: 10, color: '#9aa0a6', lineHeight: 14 } },\n },\n };\n}\n","import { ReportChartDateLabel } from './enums/report-chart-date-label.enum';\nimport { ComponentDataDrill } from './interfaces/component-data-drill.interface';\nimport { ReportDrillCrumb } from './interfaces/report-drill-crumb.interface';\nimport { ReportDrillStep } from './interfaces/report-drill-step.interface';\nimport {\n GRANULARITY_OPTIONS,\n ReportFormatContext,\n ReportLocaleTag,\n} from './interfaces/report.interface';\nimport { formatPeriodLabel } from './option-builder';\n\n\n// The words a time drill is shown in. The tile header's breadcrumb, the PDF\n// and PowerPoint titles and the chat all name a path's steps here, so they\n// never word the same step two ways. A step is the period clicked and the\n// level it was clicked at: {level: 'year', value: '2026-01-01'} then\n// {level: 'quarter', value: '2026-07-01'} reads '2026 › Q3', the months of\n// Q3 2026. Pure, so the node harness checks it.\n\n\n// Between the title and each crumb.\nexport const DRILL_CRUMB_SEPARATOR = ' › ';\n\n// Shown once when the server could not apply a chart's whole drill path and\n// the viewer kept the part it applied.\nexport const DRILL_RESET_MESSAGE = 'The drill was reset: this chart changed.';\n\n\n// The breadcrumb's labels for a path, top first, in the report's locale. The\n// first step carries its year ('2026', 'Q3 2026', 'July 2026', 'Jul 1,\n// 2026'), and each later step is read inside the one before it, so it leaves\n// the year out ('Q3', 'July', 'Jul 1'). A crumb the server labeled keeps its\n// label. `drill` is a path as the server echoes it (ComponentDataDrill.path)\n// or as the viewer holds it (a tile's drill steps).\nexport function drillCrumbLabels(\n drill: readonly (ReportDrillStep | ReportDrillCrumb)[],\n formatContext: Pick<ReportFormatContext, 'locale'>,\n): string[] {\n return drill.map((step, index) => crumbLabel(step, formatContext.locale, index === 0));\n}\n\n// A title followed by its breadcrumb ('Revenue by Period › 2026 › Q3'): what\n// an exported tile's title and a file's drill line read. With no crumbs it is\n// the title, and with no title the crumbs alone.\nexport function crumbedTitle(title: string | null | undefined, crumbs: readonly string[] = []): string {\n return [title ?? '', ...crumbs]\n .filter((part) => !!part)\n .join(DRILL_CRUMB_SEPARATOR);\n}\n\n// One step on its own, with its year ('Q3 2026'), in the report's locale. A\n// step that holds no period names its level.\nexport function drillStepLabel(step: ReportDrillStep | ReportDrillCrumb, locale: ReportLocaleTag): string {\n return crumbLabel(step, locale, true);\n}\n\n// The empty chart's note when the drilled period holds none of the days the\n// tile reads ('July 2026 is outside the dates this tile reads.'), or null.\nexport function drillOutsideMessage(\n drill: ComponentDataDrill | null | undefined,\n formatContext: Pick<ReportFormatContext, 'locale'>,\n): string | null {\n const last = drill?.outsideWindow ? drill.path[drill.path.length - 1] : null;\n\n return last ? `${drillStepLabel(last, formatContext.locale)} is outside the dates this tile reads.` : null;\n}\n\n// The path a chart adopts from its answer: the steps the server applied,\n// which are the truth. A server that drills sends no drill state for a chart\n// that cannot drill, so its path is empty.\nexport function adoptedDrillPath(drill: ComponentDataDrill | null | undefined): ReportDrillStep[] {\n return (drill?.path ?? []).map(({ level, value }) => ({ level, value }));\n}\n\n// Whether a chart whose adopted path is shorter than the one it sent tells\n// the viewer: yes when the server dropped steps, or answered with no drill\n// state at all, because the chart changed under the path. Not when the\n// viewer's own group-by change is why the path no longer starts at the\n// chart's top (`grainMoved`, refusal topChanged): the chart simply opens at\n// its new top.\nexport function drillResetNoted(drill: ComponentDataDrill | null | undefined, grainMoved: boolean): boolean {\n if (!drill) {\n return true;\n }\n\n return drill.dropped > 0 && !(grainMoved && drill.refusal === 'topChanged');\n}\n\n// A step's label: the server's own, else the period at its level, written in\n// full (with its year) or short (inside the step before it). A step with no\n// period names its level.\nfunction crumbLabel(step: ReportDrillStep | ReportDrillCrumb, locale: ReportLocaleTag, full: boolean): string {\n if ('label' in step && step.label) {\n return step.label;\n }\n\n if (step.value === null || step.value === '') {\n return GRANULARITY_OPTIONS.find((option) => option.value === step.level)?.name ?? step.level;\n }\n\n return formatPeriodLabel(\n String(step.value),\n step.level,\n false,\n locale,\n full ? ReportChartDateLabel.Long : ReportChartDateLabel.Short,\n );\n}\n","import { ReportComponent } from './interfaces/report.interface';\n\n\n// Whether a component is a chart on a time x-axis.\nexport function isTimeSeriesChart(component: ReportComponent): boolean {\n return component.type === 'chart' && component.config?.xAxis?.kind === 'time';\n}\n\n// Whether the report's group-by grain applies to a tile: the server names the\n// field it re-buckets (followsGroupBy) on a time-series chart and on a table\n// over a time axis, and drops the grain for every other tile. A server that\n// predates tables following the group-by names none, and there a chart on a\n// time x-axis is the only tile that follows it.\nexport function followsGroupBy(component: ReportComponent): boolean {\n return !!component.followsGroupBy || isTimeSeriesChart(component);\n}\n","import { IFilterConfigItem, ItemType, getExcludeName } from '@firestitch/filter';\n\nimport { format, parseISO } from 'date-fns';\n\nimport { Observable, of } from 'rxjs';\nimport { catchError, map, shareReplay } from 'rxjs/operators';\n\nimport { ReportData } from './data/report.data';\nimport { followsGroupBy } from './group-by';\nimport { filterLineText, matchLineText } from './export/report-filter-lines';\nimport { DAY_SHORT, formatLocalDate, resolveFormatContext } from './format';\nimport { ReportFilterMatch } from './interfaces/report-filter-match.type';\nimport { ReportFilterOptionPair } from './interfaces/report-filter-option-pair.interface';\nimport { ReportViewerFeature } from './interfaces/report-viewer-feature.type';\nimport {\n ChartGranularity, FilterGroupValue, GRANULARITY_OPTIONS, Report, ReportFilterGroup, ReportFilterLevel,\n ReportFilterOption, ReportFilterType, ReportLocaleTag,\n} from './interfaces/report.interface';\nimport { offersExclude } from './report-viewer-features';\nimport { ReportFilterOptionsService } from './services/report-filter-options.service';\n\n\n// A date-range boundary as the picked LOCAL calendar day (no time, no tz).\n// Date-range filters are calendar-day semantics, so the boundary must carry\n// only Y-M-D — never a timezone-bearing instant the backend would shift.\nexport function dateBoundString(value: Date | string | null | undefined): string | undefined {\n if (value instanceof Date) {\n return format(value, 'yyyy-MM-dd');\n }\n\n // Authored/relative defaults arrive as strings already in Y-M-D form;\n // keep just the date portion.\n return value ? String(value).slice(0, 10) : undefined;\n}\n\n\n// A date-range boundary as it should READ on a cover page — the same calendar\n// day dateBoundString() hands the server, so a printed period can never name a\n// different day than the numbers under it were filtered by. Returns null when\n// there is no boundary; the caller supplies its own placeholder.\n//\n// The parse has to be parseISO, not `new Date`: `new Date('2026-05-01')` is UTC\n// midnight, so formatting it anywhere west of UTC prints Apr 30. parseISO reads\n// a bare Y-M-D as LOCAL midnight, which no offset can shift.\n//\n// The day is written in the report's locale, as its date cells are: 'Jan 5,\n// 2026' in en-US, '5 janv. 2026' in fr-CA.\nexport function dateBoundLabel(value: Date | string | null | undefined, locale: ReportLocaleTag): string | null {\n const bound = dateBoundString(value);\n\n if (!bound) {\n return null;\n }\n\n const date = parseISO(bound);\n\n return Number.isNaN(date.getTime()) ? String(value) : formatLocalDate(date, locale, DAY_SHORT);\n}\n\n\n// A stored yyyy-MM-dd boundary as a local Date for a date picker, or null.\n// parseISO reads a bare Y-M-D as LOCAL midnight, so the picker shows the day\n// that was stored, whatever the browser's zone.\nexport function dateFromBound(value: string | null | undefined): Date | null {\n if (!value) {\n return null;\n }\n\n const date = parseISO(value.slice(0, 10));\n\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\n\n// A picked Date as a yyyy-MM-dd boundary for storage, or null. Uses the local\n// calendar day (format, not toISOString) so the boundary is the day that was\n// picked, regardless of the browser's zone.\nexport function dateToBound(value: Date | null | undefined): string | null {\n return value instanceof Date && !Number.isNaN(value.getTime())\n ? format(value, 'yyyy-MM-dd')\n : null;\n}\n\n\n// A relative date-range preset key as a sentence-case label, derived from the\n// camelCase key itself ('last12Months' reads 'Last 12 months', 'thisWeek'\n// reads 'This week'), so no list of presets is mirrored here and a key the\n// server adds later still reads sensibly.\nexport function relativeLabel(relative: string): string {\n const words = relative\n .replace(/([a-z])([A-Z0-9])/g, '$1 $2')\n .replace(/(\\d)([A-Z])/g, '$1 $2')\n .toLowerCase();\n\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n\n// Maps a report filter GROUP to an fs-filter config item, and reads fs-filter\n// query values back into per-group FilterGroupValues. Shared by the report-bar\n// fs-filter and the per-component fs-filter so both render through the same\n// library and write into ReportFilterStateService identically. Items are named\n// by the group's id (groupItemName), so the query keys map straight back to\n// the group. A report never puts these keys in the browser URL: fs-filter's\n// own query-param syncing is off in every report bar.\n\n// The query key for the report's group-by control. Fixed rather than derived\n// from an id because a report has exactly one — and it is NOT a filter group,\n// so it is read straight off the change query instead of through\n// groupValuesFromQuery. The grain travels to the server as the data request's\n// `state.frequency`.\nexport const GROUP_BY_ITEM = 'groupBy';\n\n// The word before a group's id in the name of its fs-filter item (filter12).\nconst ITEM_NAME_WORD = 'filter';\n\n// The ends of an fs-filter range item: Range writes <name>Min and <name>Max,\n// DateRange <name>From and <name>To.\nexport type ItemRangeEnd = 'min' | 'max' | 'from' | 'to';\n\n// The query key of one end of an fs-filter range item: the item's name and\n// the end with its first letter upper-cased (fs-filter's getRangeName), so\n// filter12 gives filter12Min and filter12From.\nexport function itemRangeName(name: string, end: ItemRangeEnd): string {\n return `${name}${end.charAt(0).toUpperCase()}${end.slice(1)}`;\n}\n\n// The name of a group's fs-filter item: 'filter' and the group's id. The id\n// never changes, so neither a new label nor a new name moves a bar's keys,\n// and no item name can take another item's (groupBy, match, listSearch).\nexport function groupItemName(group: Pick<ReportFilterGroup, 'id'>): string {\n return `${ITEM_NAME_WORD}${group.id}`;\n}\n\n// The label a group's chip shows: its own, else its first member's column.\nfunction groupLabel(group: Pick<ReportFilterGroup, 'label' | 'filters'>): string {\n return group.label || group.filters?.[0]?.filterColumn || '';\n}\n\n// A select group's distinct options, as { name, value } pairs. The server sends\n// { value, label }: the value is what the filter matches on (an entity's stable\n// id) and the label is what the viewer reads — so a renamed entity keeps its id\n// and simply shows its new name here. Options come from the first member filter\n// that declares them — members are the same data point, so any member's list\n// serves the group. The list is fetched once (the server caps it) and replayed\n// (shareReplay), so repeated reads never refetch. This is the full list, never\n// narrowed by other filters: the report-settings default picker reads it (an\n// author sets a default against the whole list), and so does the export's\n// filter wording for a pick the bar has not named. The bars read\n// ReportFilterOptionsService instead. Returns an empty list when no member\n// provides options.\nexport function loadGroupOptions(\n group: ReportFilterGroup,\n reportData: ReportData,\n reportId: number,\n): Observable<ReportFilterOptionPair[]> {\n const optionFilter = (group.filters ?? []).find((member) => member.hasOptions);\n if (!optionFilter) {\n return of([]);\n }\n\n return reportData.filterOptions(reportId, optionFilter.id)\n .pipe(\n map((options: ReportFilterOption[]) => (options ?? [])\n .map((option) => ({ name: option.label, value: option.value }))),\n shareReplay({ bufferSize: 1, refCount: false }),\n );\n}\n\n// Stored filter values (ids) paired back with the labels to show for them.\n// A saved default holds only values, so the names have to be read back off the\n// option list — that indirection is exactly what survives a rename. `label`\n// names a value first: a name already learned (ReportFilterOptionsService.label)\n// holds for a pick a narrowed list leaves out, and when it names every value\n// the list is not read at all. A value with no name and no matching option\n// (its entity was deleted, so it is no longer listed) falls back to showing\n// the raw value rather than dropping the chip, which would silently widen the\n// filter.\nexport function resolveOptionValues(\n options$: Observable<ReportFilterOptionPair[]>,\n values: unknown[],\n label: (value: unknown) => string | null = () => null,\n): Observable<ReportFilterOptionPair[]> {\n const named = (options: ReportFilterOptionPair[]) => values.map((value) => {\n const option = options.find((candidate) => String(candidate.value) === String(value));\n\n return { name: label(value) ?? option?.name ?? String(value), value };\n });\n\n return values.every((value) => label(value) !== null)\n ? of(named([]))\n : options$.pipe(map(named));\n}\n\n// Reads a group's option list; see groupOptionsReader().\nexport type GroupOptionsReader = (\n group: ReportFilterGroup,\n reportId: number,\n) => Observable<{ name: string; value: unknown }[]>;\n\n// A reader of each group's option list (loadGroupOptions) that loads a group's\n// list once and hands every later read of that group the same replayed\n// request, so everything that names one group's picks — the cover's filter\n// line, its {{filter.<id>}} token, the next pick — shares one fetch. A read\n// that failed is fetched again by the next one (shareReplay drops an error).\nexport function groupOptionsReader(reportData: ReportData): GroupOptionsReader {\n const loaded = new Map<number, Observable<{ name: string; value: unknown }[]>>();\n\n return (group, reportId) => {\n const options$ = loaded.get(group.id) ?? loadGroupOptions(group, reportData, reportId);\n loaded.set(group.id, options$);\n\n return options$;\n };\n}\n\n// The names of a select group's picks (kept or left out), as its chips in\n// the filter bar name them, for a {{filter.<id>}} token: a name the bar's\n// lists taught (`label`, ReportFilterOptionsService.label) first, else the\n// group's option list. null when the list could not be read: the token then\n// reads the em dash rather than a row of ids.\nexport function pickedOptionNames(\n options$: Observable<{ name: string; value: unknown }[]>,\n values: unknown[],\n label: (value: unknown) => string | null = () => null,\n): Observable<string[] | null> {\n return resolveOptionValues(options$, values, label)\n .pipe(\n map((options): string[] | null => options.map((option) => option.name)),\n catchError(() => of(null)),\n );\n}\n\n// Case-insensitive name filter applied to a loaded option list — the typed\n// keyword has to be matched here because fs-autocomplete renders what we return\n// verbatim.\nexport function matchOptions(\n options$: Observable<ReportFilterOptionPair[]>,\n keyword?: string,\n): Observable<ReportFilterOptionPair[]> {\n const term = (keyword ?? '').trim().toLowerCase();\n\n return options$.pipe(map((options) => term\n ? options.filter((option) => option.name.toLowerCase().includes(term))\n : options));\n}\n\n// The panel row of a select whose list the server cut at 500.\nexport const OPTIONS_TRUNCATED_NOTE = 'Showing the first 500. Type to narrow.';\n\n// The panel row of a select whose list could not be read. The next focus or\n// keystroke asks again.\nexport const OPTIONS_FAILED_NOTE = 'Could not load the list.';\n\n// Build the fs-filter config item for a group, seeding its default from the\n// current session value so authored/relative defaults show selected on open.\n// A select lists what `options` offers for it in `report`. `features` is the\n// report's viewerFeatures: a select offers 'Exclude these' by the rule of\n// offersExclude (the server lists excludeValues and no member binds several\n// columns), and a number range is a min/max control only when it lists\n// numberRange.\nexport function filterItemForGroup(\n group: ReportFilterGroup,\n options: ReportFilterOptionsService,\n report: Report | null,\n initial?: FilterGroupValue,\n features: readonly ReportViewerFeature[] = [],\n): IFilterConfigItem {\n const name = groupItemName(group);\n const label = groupLabel(group);\n\n switch (group.type) {\n case 'dateRange':\n return dateRangeFilterItem(name, label, initial);\n\n case 'select':\n return selectFilterItem(group, label, options, report, initial, offersExclude(group, features));\n\n case 'numberRange':\n return features.includes('numberRange')\n ? numberRangeFilterItem(group, label, report, initial)\n : keywordFilterItem(name, label, initial);\n\n case 'keyword':\n default:\n return keywordFilterItem(name, label, initial);\n }\n}\n\n// A date range opens on its days, and its chip shows them. A preset picked in\n// the date picker only sets the days.\nfunction dateRangeFilterItem(name: string, label: string, initial?: FilterGroupValue): IFilterConfigItem {\n const hasDays = !!(initial?.start || initial?.end);\n\n return {\n name,\n type: ItemType.DateRange,\n label: { from: `${label} From`, to: `${label} To` },\n default: hasDays\n ? { from: initial.start ?? undefined, to: initial.end ?? undefined }\n : undefined,\n };\n}\n\n// A select's picks, kept or left out. With `exclude` the list has the\n// 'Exclude these' row, and a value that leaves out opens with it on. Its list\n// is read on focus and on each keystroke: the options service fetches it when\n// the other filters changed since and replays it otherwise, and typing\n// filters it here. A list the server cut, or one that could not be read,\n// says so in a panel row.\nfunction selectFilterItem(\n group: ReportFilterGroup,\n label: string,\n options: ReportFilterOptionsService,\n report: Report | null,\n initial: FilterGroupValue | undefined,\n exclude: boolean,\n): IFilterConfigItem {\n const excluding = exclude && !initial?.values?.length && !!initial?.excludeValues?.length;\n const picks = excluding ? initial.excludeValues : initial?.values;\n const options$ = options.options(group, report);\n\n return {\n name: groupItemName(group),\n type: ItemType.AutoCompleteChips,\n label,\n fetchOnFocus: true,\n exclude: exclude ? {} : undefined,\n values: (keyword?: string) => matchOptions(options$, keyword),\n panelNote: () => optionsNote(options, group.id),\n // Stored values are ids, so a chip is named by a name already learned or\n // once the option list has loaded — hence the observable form of `default`.\n default: picks?.length\n ? () => resolveOptionValues(options$, picks, (value) => options.label(group.id, value))\n .pipe(map((selected) => (excluding ? { exclude: true, selected } : selected)))\n : undefined,\n };\n}\n\n// The panel row of a select's latest list: a failure first, then a cut list.\nfunction optionsNote(options: ReportFilterOptionsService, groupId: number): string | null {\n if (options.failed(groupId)) {\n return OPTIONS_FAILED_NOTE;\n }\n\n return options.truncated(groupId) ? OPTIONS_TRUNCATED_NOTE : null;\n}\n\n// A number range's low and high ends, either one open. 0 is an end like any\n// other. Its chip reads as the export lines do ('Amount: 0 or more',\n// 'Amount: 0 to 10'): the ends are read off the item's query the way the\n// bar's change reads them, and worded in the report's locale.\nfunction numberRangeFilterItem(\n group: ReportFilterGroup,\n label: string,\n report: Report | null,\n initial?: FilterGroupValue,\n): IFilterConfigItem {\n const name = groupItemName(group);\n const min = initial?.min ?? undefined;\n const max = initial?.max ?? undefined;\n const locale = resolveFormatContext(report ?? {}).locale;\n\n return {\n name,\n type: ItemType.Range,\n label,\n default: min !== undefined || max !== undefined ? { min, max } : undefined,\n chipText: (item) => filterLineText(\n { label, level: group.level },\n numberRangeFromQuery(item.query, name),\n { locale },\n 'chip',\n ),\n };\n}\n\nfunction keywordFilterItem(name: string, label: string, initial?: FilterGroupValue): IFilterConfigItem {\n return {\n name,\n type: ItemType.Keyword,\n label,\n default: initial?.value,\n };\n}\n\n// The groups a match of 'any' combines: report bar groups (a page group on\n// its own page only) that a viewer picks values, text or a number range in.\n// Dates, tile-only groups and the cross-filter always narrow on their own.\n// The server holds the same rule and checks every id it is sent.\nconst MATCH_ANY_LEVELS: readonly ReportFilterLevel[] = ['report', 'both', 'page'];\nconst MATCH_ANY_TYPES: readonly ReportFilterType[] = ['select', 'keyword', 'numberRange'];\n\n// Whether a group joins a match of 'any' on page `pageId`.\nexport function isMatchAnyGroup(group: ReportFilterGroup, pageId: number | null): boolean {\n return MATCH_ANY_LEVELS.includes(group.level)\n && MATCH_ANY_TYPES.includes(group.type)\n && (group.level !== 'page' || (!!pageId && group.pageId === pageId));\n}\n\n// The report bar's groups in their saved order: the report and both groups,\n// and the page groups of the page on screen (`pageId`).\nexport function reportBarGroups(report: Report | null, pageId: number | null): ReportFilterGroup[] {\n return (report?.filterGroups ?? [])\n .filter((group) => group.level === 'report' || group.level === 'both'\n || (group.level === 'page' && !!pageId && group.pageId === pageId))\n .sort((a, b) => a.order - b.order);\n}\n\n// Whether the report has a group shown on one page only, so its report bar\n// changes with the page on screen.\nexport function hasPageGroup(report: Report | null): boolean {\n return (report?.filterGroups ?? []).some((group) => group.level === 'page');\n}\n\n// The query key of the report bar's Match control. Not a filter group: it\n// says how the groups combine, so it is read straight off the change query.\nexport const MATCH_ITEM = 'match';\n\nconst MATCH_OPTIONS: { name: string; value: ReportFilterMatch }[] = [\n { name: 'All filters', value: 'all' },\n { name: 'Any filter', value: 'any' },\n];\n\n// The report bar's Match control, last in the bar, or null when it would do\n// nothing: the server must serve matchAny, and the bar must hold two or more\n// groups that combine (an 'any' over one group is that group).\nexport function matchFilterItem(\n report: Report | null,\n groups: ReportFilterGroup[],\n pageId: number | null,\n match: ReportFilterMatch,\n): IFilterConfigItem | null {\n const eligible = groups.filter((group) => isMatchAnyGroup(group, pageId));\n\n if (!report?.viewerFeatures?.includes('matchAny') || eligible.length < 2) {\n return null;\n }\n\n return {\n name: MATCH_ITEM,\n type: ItemType.Select,\n label: 'Match',\n multiple: false,\n values: () => MATCH_OPTIONS,\n default: match,\n // 'Match: any filter' or 'Match: all filters', in the export lines' words.\n chipText: (item) => matchLineText(matchFromQuery(item.query), 'chip'),\n };\n}\n\n// The match a change query of a bar with the Match control asks for.\nexport function matchFromQuery(query: Record<string, unknown>): ReportFilterMatch {\n return query?.[MATCH_ITEM] === 'any' ? 'any' : 'all';\n}\n\n// The query key of a list's search box in its component header. Fixed rather\n// than derived from an id because a header holds at most one, and it is NOT a\n// filter group: its text narrows that list alone, so it is read straight off\n// the change query and travels as the list's own `state.search`.\nexport const LIST_SEARCH_ITEM = 'listSearch';\n\n// The longest search the server applies (ReportQueryRunner::MAX_SEARCH_LENGTH).\n// The viewer cuts the text to it too, so the state, the request and the export\n// title all carry the text that was actually searched.\nexport const LIST_SEARCH_MAX_LENGTH = 100;\n\n// The fs-filter config item for a list's search box, seeded with the text the\n// viewer last searched. fs-filter shows one search box per bar (its last\n// keyword item), so the caller adds this only to a header with no keyword\n// group of its own.\nexport function listSearchItem(value: string | null): IFilterConfigItem {\n return {\n type: ItemType.Keyword,\n name: LIST_SEARCH_ITEM,\n label: 'Search',\n default: value ?? undefined,\n };\n}\n\n// Whether the report has a tile the group-by control can re-bucket: a chart\n// on a time x-axis or a table over a time axis (followsGroupBy). A time axis\n// is the whole qualification: the control changes its grain, and a category\n// axis has no grain to change.\nexport function hasGroupByTile(report: Report | null): boolean {\n return (report?.pages ?? []).some((page) => (page.components ?? []).some(followsGroupBy));\n}\n\n// The grains the report's group-by control offers, named for the viewer. WHICH\n// of them comes from the report; how they read comes from GRANULARITY_OPTIONS.\n// An empty stored list means every grain — the same rule the backend applies.\nfunction groupByOptions(report: Report): { value: ChartGranularity; name: string }[] {\n const granularities = report.config?.groupBy?.granularities ?? [];\n\n return granularities.length\n ? GRANULARITY_OPTIONS.filter((option) => granularities.includes(option.value))\n : GRANULARITY_OPTIONS;\n}\n\n// Whether a grain is one the report's control still offers. A grain it doesn't\n// cannot stay in effect: the agent can narrow the list at any time, and a chart\n// left bucketing at a dropped grain is one the viewer can neither see nor change.\nexport function isGranularityOffered(report: Report, granularity: ChartGranularity | null): boolean {\n return !granularity || groupByOptions(report).some((option) => option.value === granularity);\n}\n\n// The fs-filter config item for the report's group-by control, or null when the\n// report has none to show.\n//\n// It leads the same bar the filters render in, but it is NOT one: a filter\n// narrows WHICH rows are counted, this changes how the surviving rows are\n// BUCKETED — and it comes first because the grain is what a viewer settles\n// before deciding which rows they want.\n// Picking a grain sets a session-wide override that rides along in each chart's\n// data request, so the charts themselves are never rewritten.\nexport function groupByFilterItem(\n report: Report,\n initial?: ChartGranularity | null,\n): IFilterConfigItem | null {\n const groupBy = report.config?.groupBy;\n\n // Only an EXPLICIT false hides the control. An absent block means a report\n // served by a build that predates the control being stored, and every one of\n // those had one — the backend resolves it the same way (ReportGroupBy).\n if (groupBy?.enabled === false || !hasGroupByTile(report)) {\n return null;\n }\n\n const values = groupByOptions(report);\n\n return {\n name: GROUP_BY_ITEM,\n type: ItemType.Select,\n label: groupBy?.label || 'Group By',\n multiple: false,\n values: () => values,\n default: isGranularityOffered(report, initial ?? null) ? (initial ?? undefined) : undefined,\n };\n}\n\n// The group-by control's contribution to the toolbar's fs-filter key. fs-filter\n// reads its config once at init, and the agent can change the control's label\n// or the grains it offers — without those in the key the bar keeps rendering\n// the control it was created with until a full page reload.\nexport function groupBySignature(report: Report | null): string {\n if (!report || !groupByFilterItem(report)) {\n return '';\n }\n\n const groupBy = report.config?.groupBy;\n\n return ['groupBy', groupBy?.label ?? '', (groupBy?.granularities ?? []).join(',')].join(':');\n}\n\n// Read an fs-filter change query into per-group values. Returns one entry per\n// group with the value to store (or null to clear) — callers feed these to\n// ReportFilterStateService.setValue.\nexport function groupValuesFromQuery(\n query: Record<string, any>,\n groups: ReportFilterGroup[],\n): { groupId: number; value: FilterGroupValue | null }[] {\n return groups.map((group) => {\n const name = groupItemName(group);\n\n switch (group.type) {\n case 'dateRange':\n return { groupId: group.id, value: dateRangeFromQuery(query, name) };\n\n case 'select':\n return { groupId: group.id, value: selectFromQuery(query, name) };\n\n case 'numberRange':\n return { groupId: group.id, value: numberRangeFromQuery(query, name) };\n\n default: {\n const keyword = String(query[name] ?? '').trim();\n\n return { groupId: group.id, value: keyword ? { value: keyword } : null };\n }\n }\n });\n}\n\n// A date range's days (<name>From, <name>To).\nfunction dateRangeFromQuery(query: Record<string, any>, name: string): FilterGroupValue | null {\n const start = query[itemRangeName(name, 'from')];\n const end = query[itemRangeName(name, 'to')];\n\n if (!start && !end) {\n return null;\n }\n\n return { start: start || null, end: end || null };\n}\n\n// A select's picks: kept (<name>), or left out while its exclude row is on\n// (exclude<Name>).\nfunction selectFromQuery(query: Record<string, any>, name: string): FilterGroupValue | null {\n const excludeValues = selectQueryValues(query[getExcludeName(name)]);\n if (excludeValues.length) {\n return { excludeValues };\n }\n\n const values = selectQueryValues(query[name]);\n\n return values.length ? { values } : null;\n}\n\n// A number range's ends (<name>Min, <name>Max). An end left empty is open.\nfunction numberRangeFromQuery(query: Record<string, any>, name: string): FilterGroupValue | null {\n const min = rangeBound(query[itemRangeName(name, 'min')]);\n const max = rangeBound(query[itemRangeName(name, 'max')]);\n\n if (min === null && max === null) {\n return null;\n }\n\n return {\n ...(min !== null ? { min } : {}),\n ...(max !== null ? { max } : {}),\n };\n}\n\n// One end of a number range as fs-filter's Range sends it: the text typed in\n// its input. Number() reads any non-empty text, so '0' is the end 0; empty or\n// unreadable text is an open end.\nfunction rangeBound(raw: unknown): number | null {\n const text = typeof raw === 'number' ? String(raw) : String(raw ?? '').trim();\n const number = text === '' ? NaN : Number(text);\n\n return Number.isFinite(number) ? number : null;\n}\n\n// A group value as text, the same for the same value whatever its source:\n// days as calendar days, picks and ends as text, keyword text trimmed. The\n// value a tile header was built with is keyed on it, so a header is created\n// again when another bar changes a group it shows.\nexport function groupValueSignature(value: FilterGroupValue | null | undefined): string {\n if (!value) {\n return '';\n }\n\n return JSON.stringify([\n dateBoundString(value.start) ?? '',\n dateBoundString(value.end) ?? '',\n (value.values ?? []).map(String),\n (value.excludeValues ?? []).map(String),\n (value.value ?? '').trim(),\n value.min ?? '',\n value.max ?? '',\n ]);\n}\n\n// fs-filter's AutoCompleteChips serialises a multi-select into ONE query value:\n// the selected values joined by \",\" (its `query` getter does `.map(value).join(',')`).\n// So a 2+ selection arrives as the string \"a,b\", not an array — splitting on \",\"\n// reverses that faithfully. Without this, a multi-select was sent as the single\n// value [\"a,b\"], producing `col IN ('a,b')` server-side, which matches nothing.\nfunction selectQueryValues(raw: unknown): unknown[] {\n if (Array.isArray(raw)) {\n return raw;\n }\n\n if (raw === null || raw === undefined || raw === '') {\n return [];\n }\n\n return String(raw).split(',');\n}\n","import { ReportComponent, ReportComponentType } from './interfaces/report.interface';\n\n\n// The component types that are tiles: each is drawn on the page from its own\n// read of the data. The list is positive, so a type added later (or one this\n// viewer does not know) is never taken for a tile. The server's twin is\n// ReportComponentModel::isTile().\nconst TILE_TYPES: readonly ReportComponentType[] = ['chart', 'list', 'grid', 'kpi'];\n\n// Whether a component is a tile: a chart, a list, a grid or a KPI. Only a\n// tile is drawn as one, fetched, exported as a file or counted among a filter\n// group's tiles; every loop over a report's tiles reads this.\nexport function isTile(component: Pick<ReportComponent, 'type'> | null | undefined): boolean {\n return !!component && TILE_TYPES.includes(component.type);\n}\n","// The pure rules of the viewer's state (ReportStateSnapshot): the relative\n// ranges the server resolves, a group value in its stored shape, a chart's\n// drill path, and whether the screen still shows the report's defaults.\n// Pure, so the node harness runs them.\n//\n// - The state service turns its values into the stored shape\n// (toStoredGroupValue) and asks stateDiffers whether the screen differs\n// from the report's authored defaults.\n// - A drill path is kept to what a tile can carry (cleanDrillPath).\nimport { ReportDrillStep } from './interfaces/report-drill-step.interface';\nimport { ReportStateSnapshot } from './interfaces/report-state-snapshot.interface';\nimport { ReportTileState } from './interfaces/report-tile-state.interface';\nimport {\n ChartGranularity,\n FilterGroupDefault,\n FilterGroupValue,\n GRANULARITY_OPTIONS,\n ReportFilterType,\n ReportRelativeRange,\n} from './interfaces/report.interface';\nimport { dateBoundString } from './report-filter-items';\n\n\n// The server's cap on a drill path.\nexport const DRILL_MAX_DEPTH = 5;\n\n// Every relative range name the server knows, in its enum's order. A record\n// rather than a list, so the build fails when ReportRelativeRange gains a\n// name this misses.\nconst RELATIVE_RANGES: Record<ReportRelativeRange, true> = {\n thisWeek: true,\n lastWeek: true,\n last7Days: true,\n last30Days: true,\n last3Months: true,\n last6Months: true,\n last12Months: true,\n thisMonth: true,\n thisQuarter: true,\n thisYear: true,\n yearToDate: true,\n};\n\n// The same names as a list, in the server enum's order (the record's key\n// order): the order the date picker offers them in.\nexport const RELATIVE_RANGE_NAMES = Object.keys(RELATIVE_RANGES) as ReportRelativeRange[];\n\nconst DAY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\n// A number as text: what a masked input sends.\nconst NUMBER_PATTERN = /^[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:e[+-]?\\d+)?$/i;\n\n\n// Whether a name is a relative range the server resolves.\nexport function isRelativeRange(name: unknown): name is ReportRelativeRange {\n return typeof name === 'string' && Object.prototype.hasOwnProperty.call(RELATIVE_RANGES, name);\n}\n\nexport function isChartGranularity(value: unknown): value is ChartGranularity {\n return GRANULARITY_OPTIONS.some((option) => option.value === value);\n}\n\n// Whether text is a real calendar day written 'yyyy-MM-dd' (no 2026-02-30).\nexport function isCalendarDay(text: string): boolean {\n const parts = DAY_PATTERN.exec(text);\n if (!parts) {\n return false;\n }\n\n const [year, month, day] = parts.slice(1).map(Number);\n const date = new Date(Date.UTC(year, month - 1, day));\n\n return date.getUTCFullYear() === year && date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n}\n\n// A number written as text (a masked input's value), or null when the text\n// is not one finite number.\nexport function numberFromText(text: string): number | null {\n const number = NUMBER_PATTERN.test(text) ? Number(text) : NaN;\n\n return Number.isFinite(number) ? number : null;\n}\n\n// A group's value in its stored shape, read for the keys its group's type\n// owns, or null when it holds nothing. A date range that still carries its\n// relative preset is written as that preset whatever today is.\nexport function toStoredGroupValue(\n type: ReportFilterType,\n value: FilterGroupValue | null | undefined,\n): FilterGroupDefault | null {\n if (!value) {\n return null;\n }\n\n switch (type) {\n case 'dateRange':\n return isRelativeRange(value.preset)\n ? { relative: value.preset }\n : storedOrNull({ start: dateBoundString(value.start), end: dateBoundString(value.end) });\n\n case 'select': {\n const excludeValues = keptPicks(value.excludeValues);\n\n return storedOrNull(excludeValues ? { excludeValues } : { values: keptPicks(value.values) });\n }\n\n case 'numberRange':\n return storedOrNull({ min: finiteNumber(value.min), max: finiteNumber(value.max) });\n\n default:\n return storedOrNull({ value: value.value?.trim() || undefined });\n }\n}\n\n// Whether the screen's state (`current`, a snapshot) differs from the\n// report's authored defaults (`defaults`): the match, the grain, a group's\n// value, or a tile's sort, search, hidden columns or drill path. The page is\n// not compared (moving to another page changes no filter). Picks are\n// compared in any order.\nexport function stateDiffers(defaults: ReportStateSnapshot, current: ReportStateSnapshot): boolean {\n return (defaults.match ?? 'all') !== (current.match ?? 'all')\n || (defaults.groupBy ?? null) !== (current.groupBy ?? null)\n || Object.entries(current.groups ?? {})\n .some(([groupId, value]) => storedValueKey(defaults.groups?.[Number(groupId)]) !== storedValueKey(value))\n || tilesDiffer(defaults.tiles ?? {}, current.tiles ?? {});\n}\n\n// Whether two stored group values are the same filter: picks in any order,\n// text trimmed, an empty value read as none.\nexport function sameStoredGroupValue(\n a: FilterGroupDefault | null | undefined,\n b: FilterGroupDefault | null | undefined,\n): boolean {\n return storedValueKey(a) === storedValueKey(b);\n}\n\n// A drill path kept to what a tile can carry: its steps up to the first that\n// is not a time level with a plain value (the steps before it are kept), at\n// most DRILL_MAX_DEPTH of them.\nexport function cleanDrillPath(path: readonly unknown[] | null | undefined): ReportDrillStep[] {\n const kept: ReportDrillStep[] = [];\n\n for (const step of path ?? []) {\n if (!isPlainObject(step) || !isChartGranularity(step.level) || !isDrillValue(step.value)\n || kept.length === DRILL_MAX_DEPTH) {\n break;\n }\n\n kept.push({ level: step.level, value: step.value });\n }\n\n return kept;\n}\n\n// Whether two drill paths are the same steps. A value is compared as text,\n// so 2026 and '2026' are the same step.\nexport function sameDrillPath(\n a: readonly ReportDrillStep[] | null | undefined,\n b: readonly ReportDrillStep[] | null | undefined,\n): boolean {\n return drillKey(a) === drillKey(b);\n}\n\n// A range end as a number. A masked input sends its number as text, so\n// numeric text is read as its number.\nexport function finiteNumber(value: unknown): number | undefined {\n const number = typeof value === 'string' ? numberFromText(value.trim()) : value;\n\n return typeof number === 'number' && Number.isFinite(number) ? number : undefined;\n}\n\nfunction tilesDiffer(base: Record<number, ReportTileState>, current: Record<number, ReportTileState>): boolean {\n const ids = new Set([...Object.keys(base), ...Object.keys(current)].map(Number));\n\n return [...ids].some((componentId) => tileStateKey(base[componentId]) !== tileStateKey(current[componentId]));\n}\n\n// One text for a stored group value, the same for every way of writing the\n// same filter: picks in any order, text trimmed, and an empty value read as\n// none.\nfunction storedValueKey(value: FilterGroupDefault | null | undefined): string {\n const stored = value ?? {};\n const picks = (list: unknown[] | undefined) => [...(keptPicks(list) ?? [])].map(String).sort();\n\n return JSON.stringify([\n stored.relative ?? null,\n stored.start?.slice(0, 10) ?? null,\n stored.end?.slice(0, 10) ?? null,\n picks(stored.values),\n picks(stored.excludeValues),\n (stored.value ?? '').trim(),\n finiteNumber(stored.min) ?? null,\n finiteNumber(stored.max) ?? null,\n ]);\n}\n\n// One text for a tile's state, over the keys this viewer reads. No direction\n// reads as ascending, the way a list applies it.\nfunction tileStateKey(tile: ReportTileState | undefined): string {\n return JSON.stringify([\n tile?.sort?.column ? [tile.sort.column, tile.sort.direction ?? 'asc'] : null,\n tile?.search ?? '',\n [...(tile?.hidden ?? [])].sort(),\n drillKey(tile?.drill),\n ]);\n}\n\nfunction drillKey(path: readonly ReportDrillStep[] | null | undefined): string {\n return JSON.stringify((path ?? [])\n .map((step) => [step.level, step.value === null || step.value === undefined ? null : String(step.value)]));\n}\n\n// The picks of a list with blanks (null, '') left out, or undefined when none\n// is left.\nfunction keptPicks(list: unknown[] | null | undefined): unknown[] | undefined {\n const kept = (list ?? []).filter((pick) => isSet(pick) && pick !== '');\n\n return kept.length ? kept : undefined;\n}\n\n// Only the parts that hold something, or null when none does.\nfunction storedOrNull(value: Record<string, unknown>): FilterGroupDefault | null {\n const stored = Object.fromEntries(Object.entries(value).filter(([, part]) => isSet(part))) as FilterGroupDefault;\n\n return Object.keys(stored).length ? stored : null;\n}\n\nfunction isDrillValue(value: unknown): value is ReportDrillStep['value'] {\n return value === null || typeof value === 'string' || typeof value === 'number';\n}\n\nfunction isSet(value: unknown): boolean {\n return value !== undefined && value !== null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n","import { GridField, GridFieldType, GridFilter, GridGranularity, GridKey } from '@firestitch/grid';\n\nimport { Observable, forkJoin, of } from 'rxjs';\nimport { catchError, map } from 'rxjs/operators';\n\nimport { crumbedTitle, drillCrumbLabels } from '../drill-crumbs';\nimport { formatDayRange, formatPlainNumber } from '../format';\nimport { ReportDrillStep } from '../interfaces/report-drill-step.interface';\nimport { ReportExportLine } from '../interfaces/report-export-line.interface';\nimport { ReportExportLinesInput } from '../interfaces/report-export-lines-input.interface';\nimport { ReportFilterLineContext } from '../interfaces/report-filter-line-context.interface';\nimport { ReportFilterLineForm } from '../interfaces/report-filter-line-form.type';\nimport { ReportFilterMatch } from '../interfaces/report-filter-match.type';\nimport {\n FilterGroupValue,\n GRANULARITY_OPTIONS,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ReportFormatContext,\n} from '../interfaces/report.interface';\nimport { dateBoundLabel, dateBoundString, relativeLabel } from '../report-filter-items';\nimport { isTile } from '../report-tile';\nimport { finiteNumber } from '../report-state';\n\n\n// The words a file uses for what the screen held: each filter's value, the\n// group-by grain, a drilled tile and the match. The PDF and\n// PowerPoint covers print these lines, and the zip sends them (filterLines,\n// with filterSummary as their text for an older server), so every export\n// words one filter one way. Pure, so the node harness checks every wording.\n\n\n// The match while the report bar's filters combine with 'any': the chip's\n// words, and the cover's line. The zip's notes carry the server's own\n// sentence instead.\nexport const MATCH_ANY_CHIP = 'Match: any filter';\nexport const MATCH_ANY_LINE = 'Filters in the report bar: match any';\n\n// The report bar's Match chip while the filters combine with 'all'. A file\n// prints no line for it.\nexport const MATCH_ALL_CHIP = 'Match: all filters';\n\n// A group's label when it has none.\nconst UNLABELED_GROUP = 'Filter';\n\n// How many picks a column filter's line names before 'and N more'.\nconst GRID_FILTER_NAMED = 10;\n\n// What a blank key reads as in a column filter's line.\nconst GRID_BLANK_KEY = '(blank)';\n\n// The label of the group-by line when the report names no control.\nconst GROUP_BY_LABEL = 'Group By';\n\n\n// One filter group's value as text ('Region: West, East'), or null when the\n// value holds nothing. Values left out say so before the label: 'Exclude\n// Region: West, East'. 'chip' is the short form; 'line' adds what a file\n// reader cannot see on screen:\n// - exclude: 'Exclude Region: West, East (rows with no Region are kept)', or\n// '... are left out' when the blank label (context.blankLabel) is one of\n// the values left out. Without a known blank label the line says nothing\n// about the blank rows;\n// - range: 'Amount: 10 to 50 (both included)'; an open end reads '10 or\n// more' or '50 or less' in both forms;\n// - a live preset: 'Report Period: Last 30 days (Sep 3 – Oct 2, 2026)';\n// - a page group: 'Cohort (page \"Retention\" only): 2025'.\n// Numbers and dates are written in the report's locale, and 0 is a number\n// like any other.\nexport function filterLineText(\n group: Pick<ReportFilterGroup, 'label' | 'level'>,\n value: FilterGroupValue | null | undefined,\n context: ReportFilterLineContext,\n form: ReportFilterLineForm,\n): string | null {\n const label = group.label || UNLABELED_GROUP;\n const text = value ? valueText(label, value, context, form) : null;\n\n if (text === null) {\n return null;\n }\n\n const pageOnly = form === 'line' && group.level === 'page' && context.pageName;\n const name = pageOnly ? `${label} (page \"${context.pageName}\" only)` : label;\n\n return `${excludes(value) ? 'Exclude ' : ''}${name}: ${text}`;\n}\n\n// The words of one filter's value as its chip reads them after the label\n// ('West, East', '0 to 10', '0 or more', '50 or less'), or null when the\n// value holds nothing. Values left out read as their names: filterLineText\n// puts 'Exclude' before the label, and a {{filter.<id>}} token reads them as\n// 'All except West'. The one source of these words, so the chip, a file's\n// cover and a token never word a value two ways.\nexport function filterChipValueText(\n value: FilterGroupValue | null | undefined,\n context: ReportFilterLineContext,\n): string | null {\n return value ? valueText('', value, context, 'chip') : null;\n}\n\n// Whether a value is worded as values left out: the same order valueText\n// reads a value in, so a value with days or kept picks is never one.\nexport function excludes(value: FilterGroupValue | null | undefined): boolean {\n return !!value && !value.start && !value.end && !value.values?.length && !!value.excludeValues?.length;\n}\n\n// The picks a value names, kept or left out, in pick order: what a select's\n// names are read for. None for a date range.\nexport function valuePicks(value: FilterGroupValue | null | undefined): unknown[] {\n if (!value || value.start || value.end) {\n return [];\n }\n\n return value.values?.length ? value.values : value.excludeValues ?? [];\n}\n\n// The match as text while it is 'any', else null; the chip also words 'all'.\nexport function matchLineText(match: ReportFilterMatch | null | undefined, form: ReportFilterLineForm): string | null {\n if (match !== 'any') {\n return form === 'chip' && match === 'all' ? MATCH_ALL_CHIP : null;\n }\n\n return form === 'chip' ? MATCH_ANY_CHIP : MATCH_ANY_LINE;\n}\n\n// A drilled tile's line: its title and the breadcrumb of its path, in the\n// report's locale ('Revenue by Period › 2026 › Q3').\nexport function drillLineText(\n component: Pick<ReportComponent, 'title'>,\n path: readonly ReportDrillStep[],\n formatContext: Pick<ReportFormatContext, 'locale'>,\n): string {\n return crumbedTitle(component.title, drillCrumbLabels(path, formatContext));\n}\n\n// The filter lines of an export, in order: one per filter group with a\n// value (the report's group order), the group-by line, then one per drilled\n// chart (page order). A This Page export (input.pageId) lists only the\n// groups that reach a tile of that page, and only that page's drilled\n// charts. A select's names are a request, so the lines arrive together once\n// every name is known; a failed name read writes the picks as they are\n// stored.\nexport function exportLines(input: ReportExportLinesInput): Observable<ReportExportLine[]> {\n const groups$ = exportGroups(input.report, input.pageId)\n .map((group) => groupLine(group, input));\n const rest = [groupByLine(input), ...drillLines(input)]\n .filter((line): line is ReportExportLine => line !== null);\n\n return (groups$.length ? forkJoin(groups$) : of([]))\n .pipe(\n map((lines) => [\n ...lines.filter((line): line is ReportExportLine => line !== null),\n ...rest,\n ]),\n );\n}\n\n// The groups an export's lines may name: every group, or for a This Page\n// export the groups with a member tile on that page. A page group reaches\n// only its own page.\nexport function exportGroups(report: Report, pageId: number | null): ReportFilterGroup[] {\n const groups = report.filterGroups ?? [];\n\n if (!pageId) {\n return groups;\n }\n\n const page = (report.pages ?? []).find((candidate) => candidate.id === pageId);\n const tileIds = (page?.components ?? [])\n .filter((component) => isTile(component))\n .map((component) => component.id);\n\n return groups.filter((group) => (group.level !== 'page' || group.pageId === pageId)\n && groupMemberIds(group).some((componentId) => tileIds.includes(componentId)));\n}\n\n// The text after the label, or null when the value holds nothing.\nfunction valueText(\n label: string,\n value: FilterGroupValue,\n context: ReportFilterLineContext,\n form: ReportFilterLineForm,\n): string | null {\n if (value.start || value.end) {\n return dateText(value, context, form);\n }\n\n if (value.values?.length) {\n return pickNames(value.values, context).join(', ');\n }\n\n if (value.excludeValues?.length) {\n return excludeText(label, value.excludeValues, context, form);\n }\n\n const keyword = typeof value.value === 'string' ? value.value.trim() : '';\n\n return rangeText(value, context, form) ?? (keyword ? `\"${keyword}\"` : null);\n}\n\n// A date range: a live preset by its name (with its days in a line), else\n// its two days ('…' for an open end).\nfunction dateText(value: FilterGroupValue, context: ReportFilterLineContext, form: ReportFilterLineForm): string {\n if (context.preset) {\n const name = relativeLabel(context.preset);\n const days = form === 'line'\n ? formatDayRange(dateBoundString(value.start), dateBoundString(value.end), context.locale)\n : '';\n\n return days ? `${name} (${days})` : name;\n }\n\n return `${dateBoundLabel(value.start, context.locale) ?? '…'} – ${dateBoundLabel(value.end, context.locale) ?? '…'}`;\n}\n\n// The values a select leaves out. A line says what happens to the rows with\n// no value: they stay, unless the group's blank label is one of the values\n// left out. While the blank label is unknown (undefined) the line says\n// nothing about them: a blank label among the picks would make 'are kept'\n// false.\nfunction excludeText(\n label: string,\n values: unknown[],\n context: ReportFilterLineContext,\n form: ReportFilterLineForm,\n): string {\n const text = pickNames(values, context).join(', ');\n const blankLabel = context.blankLabel;\n\n if (form === 'chip' || blankLabel === undefined) {\n return text;\n }\n\n const blank = blankLabel !== null && values.some((value) => String(value) === blankLabel);\n\n return `${text} (rows with no ${label} ${blank ? 'are left out' : 'are kept'})`;\n}\n\n// A number range's ends in the report's locale, or null with neither.\nfunction rangeText(value: FilterGroupValue, context: ReportFilterLineContext, form: ReportFilterLineForm): string | null {\n const min = finiteNumber(value.min);\n const max = finiteNumber(value.max);\n const write = (end: number) => formatPlainNumber(end, context.locale);\n\n if (min !== undefined && max !== undefined) {\n return `${write(min)} to ${write(max)}${form === 'line' ? ' (both included)' : ''}`;\n }\n\n if (min !== undefined) {\n return `${write(min)} or more`;\n }\n\n return max !== undefined ? `${write(max)} or less` : null;\n}\n\n// The picks' names: the ones the caller resolved, else each pick as stored.\nfunction pickNames(values: unknown[], context: ReportFilterLineContext): string[] {\n const names = context.names;\n\n return values.map((value, index) => names?.[index] ?? String(value));\n}\n\n// One group's line, once its picks are named. An exclude line says what\n// happens to the blank rows from the group's blank label, which the server\n// sends on a select group (null: blank rows have none). An older server\n// sends none, and the line then says nothing about them.\nfunction groupLine(group: ReportFilterGroup, input: ReportExportLinesInput): Observable<ReportExportLine | null> {\n const snapshot = input.snapshot;\n const value = snapshot.values[group.id];\n\n if (!value) {\n return of(null);\n }\n\n const picks = valuePicks(value);\n const names$ = picks.length\n ? input.names(group, picks).pipe(catchError(() => of(null)))\n : of(null);\n\n return names$.pipe(\n map((names): ReportExportLine | null => {\n const text = filterLineText(group, value, {\n locale: snapshot.formatContext.locale,\n names,\n preset: snapshot.presets[group.id] ?? null,\n pageName: pageName(input.report, group.pageId),\n blankLabel: group.blankLabel,\n }, 'line');\n\n return text ? { kind: 'group', text, groupId: group.id } : null;\n }),\n );\n}\n\n// The group-by grain under the report's own name for the control, or null\n// while no grain is picked.\nfunction groupByLine(input: ReportExportLinesInput): ReportExportLine | null {\n const frequency = input.snapshot.frequency;\n\n if (!frequency) {\n return null;\n }\n\n const option = GRANULARITY_OPTIONS.find((item) => item.value === frequency);\n const label = input.report.config?.groupBy?.label || GROUP_BY_LABEL;\n\n return { kind: 'groupBy', text: `${label}: ${option?.name ?? frequency}` };\n}\n\n// One line per drilled chart of the export's pages, while the server drills.\nfunction drillLines(input: ReportExportLinesInput): ReportExportLine[] {\n const { report, snapshot, pageId } = input;\n\n if (!snapshot.features.includes('drill')) {\n return [];\n }\n\n return (report.pages ?? [])\n .filter((page) => !pageId || page.id === pageId)\n .flatMap((page) => page.components ?? [])\n .filter((component) => component.type === 'chart' && !!snapshot.state.tiles?.[component.id]?.drill?.length)\n .map((component): ReportExportLine => ({\n kind: 'drill',\n text: drillLineText(\n { title: input.titles?.[component.id] ?? component.title },\n snapshot.state.tiles[component.id].drill,\n snapshot.formatContext,\n ),\n componentId: component.id,\n }));\n}\n\n// The tiles a group's members sit on: the server's list, else the tiles of\n// its enabled members (an older server).\nfunction groupMemberIds(group: ReportFilterGroup): number[] {\n return group.componentIds\n ?? (group.filters ?? []).filter((member) => member.enabled).map((member) => member.componentId);\n}\n\n// A page's name as the export names it ('Page 2' when it has none), or null\n// for no page.\nfunction pageName(report: Report, pageId: number | null | undefined): string | null {\n const index = pageId ? (report.pages ?? []).findIndex((page) => page.id === pageId) : -1;\n\n if (index < 0) {\n return null;\n }\n\n return report.pages[index].name || `Page ${index + 1}`;\n}\n\n\n// One column filter of a table as a file prints it: 'Region: East, West',\n// 'Exclude Region: North (rows with no Region are kept)', 'Customer: contains\n// \"smith\"', 'Amount: 10 to 50 (both included)', 'Ordered: Jan 2026 to Mar\n// 2026'. A key reads as its option's label, a blank key as (blank), known\n// from the null key itself; past GRID_FILTER_NAMED picks the rest are\n// counted. An exclude says what happens to the rows with no value: kept,\n// unless a blank key is among the keys left out. Null for a filter that\n// holds nothing.\nexport function gridFilterLineText(\n label: string,\n filter: GridFilter,\n field: GridField | undefined,\n locale: ReportFormatContext['locale'],\n): string | null {\n const exclude = !!filter.exclude;\n const blanks = (excluded: boolean) => (exclude ? ` (rows with no ${label} ${excluded ? 'are left out' : 'are kept'})` : '');\n const line = (text: string, excluded = false) => `${exclude ? 'Exclude ' : ''}${label}: ${text}${blanks(excluded)}`;\n\n if (filter.keys?.length) {\n const names = filter.keys.slice(0, GRID_FILTER_NAMED).map((key) => gridKeyName(key, field));\n const more = filter.keys.length - names.length;\n\n return line(`${names.join(', ')}${more > 0 ? ` and ${more} more` : ''}`, filter.keys.some((key) => key === null));\n }\n\n const contains = (filter.contains ?? '').trim();\n if (contains) {\n return `${label}: ${exclude ? 'doesn\\'t contain' : 'contains'} \"${contains}\"${blanks(false)}`;\n }\n\n const isDate = field?.type === GridFieldType.Date;\n const write = (end: number | string) => (isDate\n ? gridDateText(String(end), filter.granularity ?? field?.granularities?.[0], locale)\n : formatPlainNumber(Number(end), locale));\n const has = (end: number | string | undefined): end is number | string => end !== undefined && end !== null && end !== '';\n\n if (has(filter.from) && has(filter.to)) {\n return line(`${write(filter.from)} to ${write(filter.to)}${exclude || isDate ? '' : ' (both included)'}`);\n }\n\n if (has(filter.from)) {\n return line(`${write(filter.from)} ${isDate ? 'or later' : 'or more'}`);\n }\n\n return has(filter.to) ? line(`${write(filter.to)} ${isDate ? 'or earlier' : 'or less'}`) : null;\n}\n\n// A key as a column filter's line names it: its option's label, else itself.\nfunction gridKeyName(key: GridKey, field: GridField | undefined): string {\n if (key === null) {\n return GRID_BLANK_KEY;\n }\n\n return field?.options?.find((option) => option.key !== null && String(option.key) === String(key))?.label ?? String(key);\n}\n\n// A date end at the grain the filter reads: 'Jan 2026', 'Q1 2026', '2026',\n// else the day.\nfunction gridDateText(value: string, granularity: GridGranularity | undefined, locale: ReportFormatContext['locale']): string {\n const match = /^(\\d{4})-(\\d{2})/.exec(value);\n if (!match) {\n return value;\n }\n\n const year = Number(match[1]);\n const month = Number(match[2]);\n\n switch (granularity) {\n case GridGranularity.Year:\n return String(year);\n case GridGranularity.Quarter:\n return `Q${Math.ceil(month / 3)} ${year}`;\n case GridGranularity.Month:\n return new Intl.DateTimeFormat(locale, { month: 'short', year: 'numeric', timeZone: 'UTC' })\n .format(new Date(Date.UTC(year, month - 1, 1)));\n default:\n return dateBoundLabel(value, locale) ?? value;\n }\n}\n","import { isLastDayOfMonth } from 'date-fns';\n\nimport { excludes, filterChipValueText, valuePicks } from './export/report-filter-lines';\nimport { DAY_SHORT, MONTH_YEAR, formatLocalDate, writeDayRange } from './format';\nimport { FilterGroupValue, ReportFilterGroup, ReportLocaleTag } from './interfaces/report.interface';\nimport { dateBoundString, dateFromBound } from './report-filter-items';\nimport { TextFilterField } from './text';\n\n\n// Filters inside text blocks: what each {{filter.<id>}} token reads as. The\n// value is the viewer's current one for the group, the one the filter bar\n// shows, so a heading follows a filter the moment it changes. Pure, so the\n// canvas and both exports word a filter the same way.\n\n// What a filter with neither a label nor a name is called.\nconst UNNAMED_FILTER = 'Filter';\n\n// What a date range, or a select or number range with nothing in it, reads as.\nconst ALL_DATES_TEXT = 'All dates';\nconst ALL_TEXT = 'All';\n\n// What a select leaving values out reads as before their names.\nconst ALL_EXCEPT_TEXT = 'All except';\n\n// '2026': a whole calendar year.\nconst YEAR: Intl.DateTimeFormatOptions = { year: 'numeric' };\n\n// The filter groups whose tokens a layer reads: every group but a page\n// group, which belongs to its page (pageId; null for the header and footer,\n// which belong to no page). Elsewhere its token reads the em dash, and the\n// Insert field menus do not list it.\nexport function layerFilterGroups(groups: ReportFilterGroup[], pageId: number | null): ReportFilterGroup[] {\n return groups.filter((group) => group.level !== 'page' || (!!pageId && group.pageId === pageId));\n}\n\n// Out of every group's fields, the ones a layer reads (layerFilterGroups): a\n// file words every filter once and hands each page, and the header and\n// footer, its own.\nexport function layerFilterFields(\n fields: Record<number, TextFilterField>,\n groups: ReportFilterGroup[],\n pageId: number | null,\n): Record<number, TextFilterField> {\n return Object.fromEntries(layerFilterGroups(groups, pageId)\n .filter((group) => !!fields[group.id])\n .map((group) => [group.id, fields[group.id]]));\n}\n\n// What a filter is called where an author picks and sees it (the Insert\n// field menus and the editor's chips): its label, else its name, else\n// 'Filter'.\nexport function filterFieldName(group: Pick<ReportFilterGroup, 'label' | 'name'>): string {\n return group.label || group.name || UNNAMED_FILTER;\n}\n\n// Each of the groups as its token reads, by group id. value is a group's\n// current value; names are the names of a select's picks (kept or left out):\n// undefined while they load, null when they could not be read.\nexport function textFilterFields(\n groups: ReportFilterGroup[],\n value: (groupId: number) => FilterGroupValue | null | undefined,\n locale: ReportLocaleTag,\n names: (group: ReportFilterGroup, values: unknown[]) => readonly string[] | null | undefined,\n): Record<number, TextFilterField> {\n return Object.fromEntries(groups.map((group) => {\n const groupValue = value(group.id);\n const picked = group.type === 'select' ? valuePicks(groupValue) : [];\n\n return [group.id, textFilterField(group, groupValue, locale, picked.length ? names(group, picked) : [])];\n }));\n}\n\n// What one filter token prints for a group's value, in the report's locale.\n// - A date range fits the range: one whole calendar month 'September 2026',\n// one whole quarter 'Q3 2026' (in English only: Intl has no word for a\n// quarter, so another language writes it as its months), one whole year\n// '2026', several whole months 'August – October 2026', any other days the\n// day range ('Sep 1 – 15, 2026', one day that day). Only a start reads\n// 'From Sep 1, 2026', only an end 'Until Sep 30, 2026', neither 'All dates'.\n// The bounds are calendar days, the end the last one included, read as\n// local midnight and written with no zone, so no day shifts.\n// - A select and a number range read as their chip after its label\n// (filterChipValueText): the picked names joined by ', ' (a blank row's\n// pick by its label, 'No region'), '0 to 10', '0 or more', '50 or less'.\n// A select leaving values out reads 'All except West, East'. Nothing\n// picked or no end reads 'All'.\n// - A keyword, its text, trimmed ('' when there is none).\nexport function filterFieldText(\n group: Pick<ReportFilterGroup, 'type'>,\n value: FilterGroupValue | null | undefined,\n locale: ReportLocaleTag,\n names: readonly string[] = [],\n): string {\n switch (group.type) {\n case 'dateRange':\n return periodText(calendarDay(value?.start), calendarDay(value?.end), locale);\n case 'keyword':\n return value?.value?.trim() ?? '';\n default:\n return chosenText(value, locale, names);\n }\n}\n\n// Whether two filter field sets read the same, so a recomputed set that\n// changed nothing a token or an Insert field menu shows does not repaint\n// every block.\nexport function sameFilterFields(\n a: Record<number, TextFilterField> | undefined,\n b: Record<number, TextFilterField> | undefined,\n): boolean {\n if (a === b) {\n return true;\n }\n\n if (!a || !b) {\n return false;\n }\n\n const ids = Object.keys(a).map(Number);\n\n return ids.length === Object.keys(b).length\n && ids.every((id) => {\n const other = b[id];\n\n return !!other\n && a[id].name === other.name\n && a[id].order === other.order\n && a[id].text === other.text\n && !!a[id].loading === !!other.loading;\n });\n}\n\n// One group's token. A select whose picked names have not arrived reads as\n// loading, and one whose names could not be read has no text (the em dash).\nfunction textFilterField(\n group: ReportFilterGroup,\n value: FilterGroupValue | null | undefined,\n locale: ReportLocaleTag,\n names: readonly string[] | null | undefined,\n): TextFilterField {\n const name = filterFieldName(group);\n const order = group.order;\n\n if (names === undefined) {\n return { name, order, loading: true };\n }\n\n return names ? { name, order, text: filterFieldText(group, value, locale, names) } : { name, order };\n}\n\n// A select's picks or a number range's ends, in the chip's words.\nfunction chosenText(\n value: FilterGroupValue | null | undefined,\n locale: ReportLocaleTag,\n names: readonly string[],\n): string {\n const text = filterChipValueText(value, { locale, names });\n\n if (text === null) {\n return ALL_TEXT;\n }\n\n return excludes(value) ? `${ALL_EXCEPT_TEXT} ${text}` : text;\n}\n\n// A date-range bound as the calendar day the filter sends the server\n// (dateBoundString), read as local midnight, or null for none.\nfunction calendarDay(bound: Date | string | null | undefined): Date | null {\n return dateFromBound(dateBoundString(bound));\n}\n\nfunction periodText(start: Date | null, end: Date | null, locale: ReportLocaleTag): string {\n if (start && end) {\n return start <= end ? rangeText(start, end, locale) : rangeText(end, start, locale);\n }\n\n if (start) {\n return `From ${formatLocalDate(start, locale, DAY_SHORT)}`;\n }\n\n return end ? `Until ${formatLocalDate(end, locale, DAY_SHORT)}` : ALL_DATES_TEXT;\n}\n\n// The days from first to last, both included, first not after last.\nfunction rangeText(first: Date, last: Date, locale: ReportLocaleTag): string {\n const months = wholeMonths(first, last);\n const quarterStart = first.getMonth() % 3 === 0;\n\n if (months === 1) {\n return formatLocalDate(first, locale, MONTH_YEAR);\n }\n\n if (months === 12 && first.getMonth() === 0) {\n return formatLocalDate(first, locale, YEAR);\n }\n\n if (months === 3 && quarterStart && isEnglish(locale)) {\n return `Q${first.getMonth() / 3 + 1} ${formatLocalDate(first, locale, YEAR)}`;\n }\n\n return writeDayRange(first, last, locale, months ? MONTH_YEAR : DAY_SHORT);\n}\n\n// How many whole calendar months the days cover: none unless they start on a\n// month's first day and end on a month's last.\nfunction wholeMonths(first: Date, last: Date): number {\n if (first.getDate() !== 1 || !isLastDayOfMonth(last)) {\n return 0;\n }\n\n return (last.getFullYear() - first.getFullYear()) * 12 + last.getMonth() - first.getMonth() + 1;\n}\n\n// Whether the locale's language is English, the one a quarter is written in.\nfunction isEnglish(locale: ReportLocaleTag): boolean {\n return locale.split('-')[0].toLowerCase() === 'en';\n}\n","import { ReportComponent } from './interfaces/report.interface';\n\n\n// Default content padding around a component's body, inches (1/8\").\nexport const DEFAULT_COMPONENT_PADDING = 0.125;\n\n// A component's content padding as a CSS padding: each edge in inches (a CSS\n// inch is 96px, the canvas's own), DEFAULT_COMPONENT_PADDING unless set. The\n// canvas pads a component's body with it, and the export measure\n// (ReportTextLayoutService) its offscreen copy of a text block, so the two\n// boxes are one.\nexport function componentPaddingCss(component: ReportComponent): string {\n const padding = component.config?.padding;\n const edge = (value: number | undefined) => `${value ?? DEFAULT_COMPONENT_PADDING}in`;\n\n return `${edge(padding?.top)} ${edge(padding?.right)} ${edge(padding?.bottom)} ${edge(padding?.left)}`;\n}\n\n// Default report heading size, points (1/72\"). Applies to component titles.\nexport const DEFAULT_HEADING_SIZE = 16;\n\n// Bounds for a page dimension, in inches. Mirrors ReportModel::PAGE_DIMENSION_MIN\n// / MAX on the server, which is the enforcing side — these drive the field-level\n// message so the operator sees the limit before submitting. The ceiling is set by\n// PowerPoint, not by the canvas: ECMA-376 caps a slide at 56 inches, and a .pptx\n// over that is refused on open, so a page is not allowed to be sized past what it\n// can be exported as.\nexport const PAGE_DIMENSION_MIN = 1;\nexport const PAGE_DIMENSION_MAX = 50;\n\n// The deepest a header or footer band may be, in inches. Mirrors\n// ReportHeaderFooter::MAX_HEIGHT on the server, which clamps.\nexport const HEADER_FOOTER_MAX = 3;\n","import { GridLayout } from '@firestitch/grid';\n\nimport { followsGroupBy } from './group-by';\nimport { ReportStateSnapshot } from './interfaces/report-state-snapshot.interface';\nimport {\n ComponentDataState,\n FilterGroupDefault,\n Report,\n ReportComponent,\n} from './interfaces/report.interface';\nimport { isMatchAnyGroup } from './report-filter-items';\nimport { isTile } from './report-tile';\nimport { isChartGranularity } from './report-state';\n\n\n// The interaction state one tile's data request carries, read off a snapshot\n// of the screen (the state service's snapshot()): the group-by grain for a\n// tile that follows it (followsGroupBy), a list's sort, search and hidden\n// columns, a chart's drill path, and, while the groups match 'any', the groups that\n// combine (matchAnyGroupIds). The tile on screen, its CSV, the PDF and\n// PowerPoint collector and the zip all build their state here, so a file\n// always holds what the screen shows. A list's paging is the caller's. Never\n// sets unchangedIfUnreached: that belongs to an on-screen refetch alone.\n//\n// A drill path and the grain may both be sent: the server lets the drilled\n// level win, and a server that does not drill keeps the grain.\nexport function tileDataState(\n report: Report | null,\n component: ReportComponent,\n snapshot: ReportStateSnapshot,\n): ComponentDataState {\n const state: ComponentDataState = {};\n\n if (!isTile(component)) {\n return state;\n }\n\n const tile = snapshot.tiles?.[component.id];\n\n if (followsGroupBy(component) && isChartGranularity(snapshot.groupBy)) {\n state.frequency = snapshot.groupBy;\n }\n\n if (component.type === 'list') {\n if (tile?.sort?.column) {\n state.sort = { ...tile.sort };\n }\n if (tile?.search) {\n state.search = tile.search;\n }\n if (tile?.hidden?.length) {\n state.hiddenColumns = [...tile.hidden];\n }\n }\n\n if (component.type === 'chart' && tile?.drill?.length) {\n state.drill = tile.drill.map((step) => ({ ...step }));\n }\n\n const matchAnyGroupIds = tileMatchAnyGroupIds(report, component, snapshot);\n if (matchAnyGroupIds.length) {\n state.matchAnyGroupIds = matchAnyGroupIds;\n }\n\n return state;\n}\n\n\n// Each tile's state for the zip export (tileDataState), by component id: the\n// tiles of every page, or of `pageId` alone. The zip holds no header or\n// footer tile. A table adds the layout the viewer put it in (`gridLayout`,\n// null while it shows its stored one). A tile with nothing to send is left\n// out, so an untouched report sends no states at all.\nexport function zipExportStates(\n report: Report,\n snapshot: ReportStateSnapshot,\n pageId: number | null = null,\n gridLayout: (component: ReportComponent) => GridLayout | null = () => null,\n): Record<number, ComponentDataState> {\n const states: Record<number, ComponentDataState> = {};\n\n (report.pages ?? [])\n .filter((page) => !pageId || page.id === pageId)\n .flatMap((page) => page.components ?? [])\n .forEach((component) => {\n const layout = component.type === 'grid' ? gridLayout(component) : null;\n const state = { ...tileDataState(report, component, snapshot), ...(layout ? { layout } : {}) };\n\n if (Object.keys(state).length) {\n states[component.id] = state;\n }\n });\n\n return states;\n}\n\n\n// The groups a tile's 'any' combines, in id order: while the snapshot's\n// match is 'any', every eligible group that holds a value. A group the tile\n// has no member of is listed too, so the server can tell a tile that cannot\n// test every group (it then applies none of them and says so). A page group\n// counts only for the tiles of its own page: it is in the report bar of no\n// other page. A header or footer tile is a tile of the page on screen.\nfunction tileMatchAnyGroupIds(report: Report | null, component: ReportComponent, snapshot: ReportStateSnapshot): number[] {\n if (!report) {\n return [];\n }\n\n return matchAnyGroupIdsOnPage(report, tilePageId(report, component, snapshot), snapshot);\n}\n\n\n// The groups a layer's inline values combine (the page values request's\n// matchAnyGroupIds), by the tile rule (tileDataState): while the snapshot's\n// match is 'any', every eligible group that holds a value, in id order. A\n// value has no member of some of them, and the server then applies none of\n// them to it, as it does for such a tile. `layerId` is the page the values\n// sit on; the header and footer's values (any other id) are values of the\n// page on screen, as a header or footer tile is.\nexport function valuesMatchAnyGroupIds(\n report: Report | null,\n layerId: number | null,\n snapshot: ReportStateSnapshot,\n): number[] {\n if (!report) {\n return [];\n }\n\n const page = (report.pages ?? []).find((candidate) => candidate.id === layerId);\n\n return matchAnyGroupIdsOnPage(report, page?.id ?? snapshot.pageId ?? null, snapshot);\n}\n\n\n// While the snapshot's match is 'any': the eligible groups of the report bar\n// on `pageId` that hold a value, in id order.\nfunction matchAnyGroupIdsOnPage(report: Report, pageId: number | null, snapshot: ReportStateSnapshot): number[] {\n if (snapshot.match !== 'any') {\n return [];\n }\n\n return (report.filterGroups ?? [])\n .filter((group) => isMatchAnyGroup(group, pageId) && holdsValue(snapshot.groups?.[group.id]))\n .map((group) => group.id)\n .sort((a, b) => a - b);\n}\n\n\n// The page a tile is drawn on: its own page, or, for a header or footer\n// tile, the page on screen. Null when neither is known. An inline value's\n// page is the page whose values hold it, the same way.\nexport function tilePageId(report: Report, component: ReportComponent, snapshot: ReportStateSnapshot): number | null {\n const page = (report.pages ?? [])\n .find((candidate) => [...(candidate.components ?? []), ...(candidate.values ?? [])]\n .some((item) => item.id === component.id));\n\n return page?.id ?? snapshot.pageId ?? null;\n}\n\n\n// Whether a group's stored value holds something a request sends: picks to\n// keep or leave out, text, or a number range end (0 is an end).\nfunction holdsValue(value: FilterGroupDefault | null | undefined): boolean {\n if (!value) {\n return false;\n }\n\n return !!value.values?.length\n || !!value.excludeValues?.length\n || (typeof value.value === 'string' && !!value.value.trim())\n || Number.isFinite(value.min)\n || Number.isFinite(value.max);\n}\n","// What a formula value works out of the query values it reads on its page\n// (config.formula.of): change is a - b, percent_change (a - b) / |b| as a 0-1\n// fraction, ratio a / b, and sum adds 2 to 10 values. The server evaluates\n// it; the viewer only formats the number.\n//\n// Mirrors the server's ValueFormulaEnum value for value.\nexport enum ReportValueFormula {\n Change = 'change',\n PercentChange = 'percent_change',\n Ratio = 'ratio',\n Sum = 'sum',\n}\n","import { ReportValueFormula } from './enums/report-value-formula.enum';\nimport { formatOutputValue } from './format';\nimport {\n NumberFormatSpec,\n OutputMeta,\n Report,\n ReportComponent,\n ReportFormatContext,\n ReportPageValue,\n ValueFormulaConfig,\n} from './interfaces/report.interface';\nimport { TextValue, VALUE_EMPTY_TEXT, VALUE_TOKEN_PATTERN } from './text';\n\n\n// Live values inside text blocks: which values a page's text shows, and what\n// each token reads as. A value belongs to a page (the master for a header or\n// footer) and is listed in its `values`, never in its components. Pure, so the\n// canvas and both exports fill a block's tokens the same way.\n\n// No value keys: what a text block is told other blocks show when nothing\n// says otherwise. Shared, and typed read-only so no caller fills it.\nexport const NO_VALUE_KEYS: ReadonlySet<string> = Object.freeze(new Set<string>());\n\n// The keys an html's {{value.<key>}} tokens name: lowercased, each once, in\n// the order they first appear.\nexport function valueKeys(html: string | null | undefined): string[] {\n const keys = Array.from((html ?? '').matchAll(VALUE_TOKEN_PATTERN), (match) => match[1].toLowerCase());\n\n return [...new Set(keys)];\n}\n\n// The key a value's tokens name, as they are compared: lowercase.\nexport function valueKey(component: ReportComponent): string {\n return String(component.config?.key ?? '').toLowerCase();\n}\n\n// The keys a formula value reads (config.formula.of), as they are compared:\n// lowercase. None for a query value.\nexport function operandKeys(value: ReportComponent): string[] {\n const of = value.config?.formula?.of;\n\n return Array.isArray(of) ? of.map((key) => String(key).toLowerCase()) : [];\n}\n\n// The values some text shows, in id order: what the server reads for the\n// page. A key held by two values (a race between two writes) is the newest\n// one's, as server-side.\nexport function shownValues(values: ReportComponent[], texts: ReportComponent[]): ReportComponent[] {\n const shown = new Set(texts.flatMap((text) => valueKeys(text.config?.html)));\n const ordered = byId(values);\n const newest = new Map(ordered.map((value) => [valueKey(value), value]));\n\n return ordered.filter((value) => shown.has(valueKey(value)) && newest.get(valueKey(value)) === value);\n}\n\n// The keys a layer reads when its text shows `shown`: those keys, and the\n// operands of each shown formula, one level deep. It mirrors the server's\n// ReportTextValues::getReadKeys, and is used only for the editor's notice: the\n// server's own read set decides which numbers come back.\nexport function readKeys(shown: Iterable<string>, values: Record<string, TextValue>): Set<string> {\n const keys = new Set(shown);\n\n // Over a copy of the shown keys, so an operand added here is not expanded.\n [...keys].forEach((key) => {\n (values[key]?.reads ?? []).forEach((read) => keys.add(read));\n });\n\n return keys;\n}\n\n// What each of a layer's values reads as, by key, for its text's tokens and\n// chips. Every value is listed, shown or not, so a pasted chip keeps its name.\n// A value reads as loading until the layer's numbers have arrived (`results`\n// is null until then) and while a request still on its way asks for it\n// (`loading`, by id): a number on screen is always the current request's. A\n// value with no row, or whose row failed, has no text (the em dash).\nexport function textValues(\n values: ReportComponent[],\n results: { rows: ReadonlyMap<number, ReportPageValue> } | null,\n format: ReportFormatContext,\n loading: ReadonlySet<number> = new Set(),\n): Record<string, TextValue> {\n const filled: Record<string, TextValue> = {};\n\n byId(values).forEach((value) => {\n const key = valueKey(value);\n const name = value.title || key;\n const row = results?.rows.get(value.id);\n const reads = formulaReads(value);\n\n if (!results || loading.has(value.id)) {\n filled[key] = { name, loading: true, ...reads };\n } else if (row && !row.error) {\n filled[key] = { name, text: formatValueText(value, row, values, format), ...reads };\n } else {\n filled[key] = { name, ...reads };\n }\n });\n\n return filled;\n}\n\n// A value's number as its token reads it, on the canvas and in both exports,\n// through the formatOutputValue KPI cards and list cells use. A query value\n// that shows a comparison output, and a formula, are written by their role: a\n// change or a percent change is signed (unless the formula's `signed` says\n// otherwise), and a change in points carries no ' pp', as the words around\n// the token carry the unit. A change or a sum with no format of its own takes\n// its first operand's, and a ratio reads a percent format as a 0-1 fraction.\n// A row with an error reads as the em dash.\nexport function formatValueText(\n value: ReportComponent,\n row: ReportPageValue,\n layerValues: ReportComponent[],\n ctx: ReportFormatContext,\n): string {\n if (row.error) {\n return VALUE_EMPTY_TEXT;\n }\n\n const formula = value.config?.formula ?? null;\n const output: OutputMeta | null = row.role || formula\n ? {\n measure: valueKey(value),\n kind: 'value',\n role: row.role ?? null,\n offset: null,\n window: false,\n rank: null,\n share: null,\n }\n : null;\n const context = formula?.op === ReportValueFormula.Ratio ? { ...ctx, ratioPercent: true } : ctx;\n\n return formatOutputValue(row.value, output, value.config?.measure, context, {\n empty: VALUE_EMPTY_TEXT,\n measureSpec: operandSpec(formula, layerValues),\n signed: formula?.signed ?? undefined,\n pointsUnit: false,\n }).text;\n}\n\n// The keys of the values that came back without a number to show: no row for\n// them, or a row with an error. What an export's gate names as failed.\nexport function failedValueKeys(\n values: ReportComponent[],\n rows: ReadonlyMap<number, ReportPageValue>,\n): string[] {\n const failed = values\n .filter((value) => {\n const row = rows.get(value.id);\n\n return !row || !!row.error;\n })\n .map(valueKey);\n\n return [...new Set(failed)];\n}\n\n// Whether two token value sets read the same, so a recomputed set that changed\n// nothing a token shows does not repaint every block.\nexport function sameTextValues(\n a: Record<string, TextValue> | undefined,\n b: Record<string, TextValue> | undefined,\n): boolean {\n if (a === b) {\n return true;\n }\n\n if (!a || !b) {\n return false;\n }\n\n const keys = Object.keys(a);\n\n return keys.length === Object.keys(b).length\n && keys.every((key) => {\n const other = b[key];\n\n return !!other\n && a[key].name === other.name\n && a[key].text === other.text\n && !!a[key].loading === !!other.loading\n && (a[key].reads ?? []).join(',') === (other.reads ?? []).join(',');\n });\n}\n\n// Every component of the report, values included: what owns a filter. A value\n// is never drawn, but its filters are the report's like any other.\nexport function reportComponents(report: Report | null): ReportComponent[] {\n if (!report) {\n return [];\n }\n\n return [\n ...(report.pages ?? []).flatMap((page) => [...(page.components ?? []), ...(page.values ?? [])]),\n ...(report.master?.components ?? []),\n ...(report.master?.values ?? []),\n ];\n}\n\n// The value keys each layer holds, by page id and master id. A key that leaves\n// its layer between two loads of the report is a value that was deleted.\nexport function layerValueKeys(report: Report | null): Map<number, Set<string>> {\n const layers = new Map<number, Set<string>>();\n\n (report?.pages ?? []).forEach((page) => {\n layers.set(page.id, new Set((page.values ?? []).map(valueKey)));\n });\n\n if (report?.master) {\n layers.set(report.master.id, new Set((report.master.values ?? []).map(valueKey)));\n }\n\n return layers;\n}\n\n// Whether a component is drawn on the canvas. A value only ever reads inside\n// text, so one that leaks into a layer's components is still never drawn.\nexport function isDrawn(component: ReportComponent): boolean {\n return component.type !== 'value';\n}\n\nfunction byId(values: ReportComponent[]): ReportComponent[] {\n return [...values].sort((a, b) => a.id - b.id);\n}\n\n// A formula value's operand keys, lowercase, as its TextValue carries them.\n// Nothing for a query value.\nfunction formulaReads(value: ReportComponent): Pick<TextValue, 'reads'> {\n return Array.isArray(value.config?.formula?.of) ? { reads: operandKeys(value) } : {};\n}\n\n// The format a change or a sum is written in when it names none of its own:\n// its first operand's measure, from the newest value on the layer holding that\n// key. Nothing for any other value, whose own format is all it reads.\nfunction operandSpec(\n formula: ValueFormulaConfig | null,\n layerValues: ReportComponent[],\n): NumberFormatSpec | undefined {\n if (formula?.op !== ReportValueFormula.Change && formula?.op !== ReportValueFormula.Sum) {\n return undefined;\n }\n\n const first = String(formula.of?.[0] ?? '').toLowerCase();\n\n return byId(layerValues).filter((value) => valueKey(value) === first).pop()?.config?.measure;\n}\n","import { Day } from 'date-fns';\n\n\n// Report weeks start on Monday. This is a rule, not a setting: the server's\n// weekly time buckets (ReportTimeBucket::getPeriodStart() at the Week grain)\n// and its relative date presets (ReportRelativeRangeEnum) both start the week\n// on Monday, so the viewer's thisWeek/lastWeek presets must too, or a weekly\n// chart's buckets would straddle the range its own filter names.\nexport const REPORT_WEEK_STARTS_ON: Day = 1;\n","import { laneOutputAlias } from './format';\nimport {\n ComponentData,\n ListColumn,\n ListConfig,\n NumberFormatSpec,\n OutputMeta,\n ReportSort,\n} from './interfaces/report.interface';\n\n\n// The most leading columns a list can keep in view while it scrolls sideways.\n// Mirrors the server's ListConfig::MAX_PINNED_COLUMNS, which refuses more.\nexport const MAX_PINNED_COLUMNS = 3;\n\n// A list's authored sort, most important first. A list sort is a list of\n// terms, but a list saved before multi-key sorting stores one object and is\n// never rewritten, so both shapes are read here. This is the one reader of a\n// list's config.sort: the config type intersects the chart and list configs,\n// so a direct `config.sort.column` still compiles and silently misreads an\n// array. A term without a column orders nothing and is dropped.\nexport function listSortTerms(config: ListConfig | null | undefined): ReportSort[] {\n const sort = config?.sort;\n\n if (!sort) {\n return [];\n }\n\n return (Array.isArray(sort) ? sort : [sort])\n .filter((term) => !!term?.column);\n}\n\n// The columns a viewer can hide on a list, by name: a plain list's configured\n// columns. A cross-tab offers none, since its columns are pivot values that\n// come and go with the data.\nexport function listHideableColumns(config: ListConfig | null | undefined): string[] {\n return config?.pivotBy?.column\n ? []\n : (config?.columns ?? []).map((column) => column.column);\n}\n\n// The hidden column names a list honors: only columns it can hide, each once,\n// in the list's own order, and none at all when they would hide every column\n// (a list always shows one, and the server ignores such a CSV list too). The\n// filter state, the screen and every export read this one rule.\nexport function listHiddenColumns(config: ListConfig | null | undefined, names: readonly string[]): string[] {\n const hideable = listHideableColumns(config);\n const hidden = hideable.filter((name) => names.includes(name));\n\n return hidden.length < hideable.length ? hidden : [];\n}\n\n// How many leading columns stay in view while a wide list scrolls sideways.\n// Unset, a cross-tab pins its row-key column and a plain list pins none. A\n// cross-tab pins at most that one column, since the rest are pivot values; a\n// stored config that asks for more is clamped here, as the server refuses it\n// only on save.\nexport function listPinnedColumns(config: ListConfig | null | undefined): number {\n const crossTab = !!config?.pivotBy?.column;\n const pinned = config?.pinnedColumns ?? (crossTab ? 1 : 0);\n\n return Math.min(Math.max(Math.floor(Number(pinned) || 0), 0), crossTab ? 1 : MAX_PINNED_COLUMNS);\n}\n\n// The classes a list column carries on its header, cells and footer. fs-list\n// copies a column's classes once, when it builds the column, so they are\n// static: `report-pin-{index}` names the column's place among the pinned ones\n// (its left offset is a CSS variable the list measures), `report-pin-last`\n// draws the separator after the last pinned column, and `report-nowrap` keeps\n// the column's cells on one line.\nexport function columnClasses(column: ListColumn, index: number, pinned: number): string {\n const classes: string[] = [];\n\n if (index < pinned) {\n classes.push('report-pinned', `report-pin-${index}`);\n\n if (index === pinned - 1) {\n classes.push('report-pin-last');\n }\n }\n\n if (column.wrap === false) {\n classes.push('report-nowrap');\n }\n\n return classes.join(' ');\n}\n\n// The label a list's totals row writes, on screen and in the PDF and deck.\nexport const LIST_TOTAL_LABEL = 'Total';\n\n// The column of a totals row that carries LIST_TOTAL_LABEL, among the columns\n// shown, in order: the first one, unless it holds a total itself, in which\n// case the row has no label. A cross-tab's first column is its row key, which\n// never holds one.\nexport function listTotalsLabelColumn(\n columns: readonly ListColumn[],\n totals: Record<string, unknown> | null | undefined,\n): string | null {\n const first = columns[0];\n\n return first && totals?.[first.column] === undefined ? first.column : null;\n}\n\n// How a list column that holds a compared, windowed, ranked or shared output\n// is written (format.ts formatOutputValue): what it holds, the format of its\n// source measure's column, which a prior or a change takes when it names none,\n// the alias of the prior in its lane, whose value in the same row tells a\n// missing baseline from a zero one, and the first day with data.\nexport interface ListOutputColumn {\n output: OutputMeta;\n measureSpec: NumberFormatSpec | null;\n priorAlias: string | null;\n floor: string | null;\n}\n\n// The output columns among a list's columns, by column name, from the\n// metadata its data carries. A cross-tab cell column takes its measure's\n// meaning through cellMeasures; its cells all share the grid's cellFormat and\n// have no prior beside them, since a cross-tab never compares. A column with\n// no output metadata (a plain measure or dimension, an older server) is left\n// out and written as before.\nexport function listOutputColumns(\n columns: readonly ListColumn[],\n data: Pick<ComponentData, 'outputs' | 'cellMeasures' | 'comparison'> | null | undefined,\n authored: readonly ListColumn[],\n): Record<string, ListOutputColumn> {\n const outputs = data?.outputs ?? {};\n const resolved: Record<string, ListOutputColumn> = {};\n\n columns.forEach((column) => {\n const cellMeasure = data?.cellMeasures?.[column.column];\n const alias = cellMeasure ?? column.column;\n const output = outputs[alias];\n\n if (output) {\n resolved[column.column] = {\n output,\n measureSpec: authored.find((source) => source.column === output.measure) ?? null,\n priorAlias: cellMeasure ? null : listPriorAlias(outputs, alias, output),\n floor: data?.comparison?.floor ?? null,\n };\n }\n });\n\n return resolved;\n}\n\n// A change's or a percent change's prior in the same lane; null for any other\n// output.\nfunction listPriorAlias(outputs: Record<string, OutputMeta>, alias: string, output: OutputMeta): string | null {\n return output.role === 'change' || output.role === 'percent_change'\n ? laneOutputAlias(outputs, alias, 'prior')\n : null;\n}\n","// A table tile's layouts: the one its config authors, the canonical key two\n// layouts are compared by, and a viewer's layout moved onto a new authored one.\nimport {\n GridClearedFilter, GridControlState, GridFilter, GridGranularity, GridLayout, GridNote, GridNoteCode,\n canonicalGridLayout, convertDateFilter,\n} from '@firestitch/grid';\n\nimport { ChartGranularity, ReportComponent } from './interfaces/report.interface';\n\n\nconst NO_LAYOUT: GridLayout = {};\n\n// The report's grains by the grid's name for each.\nexport const GRID_GRANULARITIES: Record<ChartGranularity, GridGranularity> = {\n day: GridGranularity.Day,\n week: GridGranularity.Week,\n month: GridGranularity.Month,\n quarter: GridGranularity.Quarter,\n year: GridGranularity.Year,\n};\n\n// The layout a table tile's config authors, or none.\nexport function authoredGridLayout(component: ReportComponent): GridLayout {\n return component.config?.layout ?? NO_LAYOUT;\n}\n\n// A layout's canonical key: two layouts that draw the same table have the\n// same key, whatever order or defaults they were written with.\nexport function gridLayoutKey(layout: GridLayout): string {\n return JSON.stringify(canonicalGridLayout(layout));\n}\n\n// A viewer's layout moved onto the layout authored now, `base` being the key\n// of the authored layout they started from: the new authored layout, with the\n// viewer's own filters and sort (what `base` did not have) kept on the fields\n// it still places. A field the viewer filters takes their filters in place of\n// the authored ones, and a sort they changed replaces the authored sort.\nexport function rebasedGridLayout(session: GridLayout, base: string, authored: GridLayout): GridLayout {\n const started = JSON.parse(base) as GridLayout;\n const viewer = canonicalGridLayout(session);\n const placed = new Set([\n ...(authored.rows ?? []),\n ...(authored.columns ?? []),\n ...(authored.values ?? []),\n ...(authored.details ?? []),\n ].map((placement) => placement.field));\n const startedFilters = new Set((started.filters ?? []).map((filter) => JSON.stringify(filter)));\n const filters = (viewer.filters ?? [])\n .filter((filter) => placed.has(filter.field) && !startedFilters.has(JSON.stringify(filter)));\n const filtered = new Set(filters.map((filter) => filter.field));\n const sorted = JSON.stringify(viewer.sort ?? []) !== JSON.stringify(started.sort ?? []);\n const sort = (viewer.sort ?? []).filter((term) => placed.has(term.field));\n\n return canonicalGridLayout({\n ...authored,\n filters: [...(authored.filters ?? []).filter((filter) => !filtered.has(filter.field)), ...filters],\n sort: sorted && sort.length ? sort : authored.sort,\n });\n}\n\n// A table's layout once the grain `field` reads at moves to `granularity` (the\n// report's group-by changed): its column filter on `field` converts to the\n// same days at the new grain when its edges line up, and is taken out\n// otherwise (convertDateFilter), so the read never sends a filter the field no\n// longer offers. `cleared` names the filter taken out and the grain the table\n// now groups by, as fs-grid's status line reads it. A layout with no filter on\n// the field, or one already at the grain, comes back as it is.\nexport function grainedGridLayout(\n layout: GridLayout,\n field: string,\n granularity: ChartGranularity,\n): { layout: GridLayout; cleared: GridClearedFilter | null } {\n const grain = GRID_GRANULARITIES[granularity];\n const filter = (layout.filters ?? []).find((item) => item.field === field);\n if (!filter || (filter.granularity ?? GridGranularity.Day) === grain) {\n return { layout, cleared: null };\n }\n\n const converted = convertDateFilter(filter, grain);\n const filters = (layout.filters ?? [])\n .map((item) => (item === filter ? converted : item))\n .filter((item): item is GridFilter => !!item);\n\n return { layout: { ...layout, filters }, cleared: converted ? null : { field, granularity: grain } };\n}\n\n// The notes that leave a filter out of a read, by the filter's index (filters.N...)\nconst PRUNED_FILTER_CODES: ReadonlySet<GridNoteCode> = new Set([\n GridNoteCode.FieldMissing,\n GridNoteCode.CannotFilter,\n GridNoteCode.FilterRefused,\n GridNoteCode.GranularityRefused,\n]);\n\n// The notes that leave a sort term out of a read, by the term's index (sort.N...)\nconst PRUNED_SORT_CODES: ReadonlySet<GridNoteCode> = new Set([\n GridNoteCode.FieldMissing,\n GridNoteCode.SortRefused,\n]);\n\n// A viewer's layout of a table once its first read is in: the filters and sort\n// terms that read refused (a field the query no longer has, a filter or grain\n// the field no longer takes) are taken out, so the stored session layout holds\n// only what applies. When the author turned filtering off (`filter`, the\n// tile's controls.filter), the viewer's filters give way to the authored ones\n// (`authored`), which a viewer cannot change. The layout comes back as it is\n// when nothing changes.\nexport function prunedGridLayout(\n layout: GridLayout,\n notes: readonly GridNote[],\n filter?: GridControlState,\n authored: readonly GridFilter[] = [],\n): GridLayout {\n const filters = layout.filters ?? [];\n const sort = layout.sort ?? [];\n const filterIndexes = notedIndexes(notes, 'filters', PRUNED_FILTER_CODES);\n const sortIndexes = notedIndexes(notes, 'sort', PRUNED_SORT_CODES);\n const canFilter = (filter ?? GridControlState.Enabled) === GridControlState.Enabled;\n const keptFilters = canFilter ? filters.filter((_item, index) => !filterIndexes.has(index)) : [...authored];\n const keptSort = sort.filter((_term, index) => !sortIndexes.has(index));\n const isFiltersKept = JSON.stringify(keptFilters) === JSON.stringify(filters);\n\n return isFiltersKept && keptSort.length === sort.length\n ? layout\n : { ...layout, filters: keptFilters, sort: keptSort };\n}\n\n// The indexes under `key` (key.N or key.N.part) the notes of `codes` name\nfunction notedIndexes(notes: readonly GridNote[], key: string, codes: ReadonlySet<GridNoteCode>): ReadonlySet<number> {\n const pattern = new RegExp(`^${key}\\\\.(\\\\d+)(\\\\.|$)`);\n\n return new Set(notes\n .filter((note) => codes.has(note.code))\n .map((note) => pattern.exec(note.path ?? ''))\n .filter((match): match is RegExpExecArray => !!match)\n .map((match) => Number(match[1])));\n}\n","import { Injectable, signal } from '@angular/core';\nimport { computed } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\n\nimport { GridClearedFilter, GridExpansion, GridLayout } from '@firestitch/grid';\n\nimport { Observable, Subject } from 'rxjs';\nimport { map, filter as rxFilter } from 'rxjs/operators';\nimport { scan } from 'rxjs/operators';\n\nimport {\n endOfWeek, startOfMonth, startOfQuarter, startOfWeek, startOfYear,\n subDays, subMonths, subWeeks,\n} from 'date-fns';\n\nimport { REPORT_WEEK_STARTS_ON } from '../consts/report-week.const';\nimport {\n DEFAULT_FORMAT_CONTEXT, getZonedNow, resolveFormatContext, resolveReportTimezone,\n} from '../format';\nimport { ReportChatViewerFilter } from '../interfaces/report-chat-viewer-filter.interface';\nimport { ReportDrillStep } from '../interfaces/report-drill-step.interface';\nimport { ReportFilterMatch } from '../interfaces/report-filter-match.type';\nimport { ReportGridSessionLayout } from '../interfaces/report-grid-session-layout.interface';\nimport { ReportTemporaryState } from '../interfaces/report-temporary-state.interface';\nimport { ReportTileState } from '../interfaces/report-tile-state.interface';\nimport { ReportStateSnapshot } from '../interfaces/report-state-snapshot.interface';\nimport {\n ChartGranularity,\n FilterGroupDefault,\n FilterGroupValue,\n Report,\n ReportComponent,\n ReportFilterGroup,\n ReportFormatContext,\n ReportRelativeRange,\n ReportSort,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { listHiddenColumns, listSortTerms } from '../list-config';\nimport { dateBoundString, LIST_SEARCH_MAX_LENGTH } from '../report-filter-items';\nimport { groupValueSignature } from '../report-filter-items';\nimport {\n GRID_GRANULARITIES, authoredGridLayout, grainedGridLayout, gridLayoutKey, rebasedGridLayout,\n} from '../report-grid-layout';\nimport { isTile } from '../report-tile';\nimport {\n cleanDrillPath, finiteNumber, isRelativeRange, sameDrillPath, sameStoredGroupValue,\n stateDiffers, toStoredGroupValue,\n} from '../report-state';\nimport { ComponentDataState } from '../interfaces/report.interface';\nimport { tileDataState } from '../tile-data-state';\nimport { reportComponents } from '../values';\n\n\n// Whether two stored filter-group defaults are the same. Compared on the fields a\n// default can actually carry, so key order in the payload can't read as a change.\nexport function sameDefault(\n a: FilterGroupDefault | null,\n b: FilterGroupDefault | null,\n): boolean {\n if (!a || !b) {\n return !a && !b;\n }\n\n return a.start === b.start\n && a.end === b.end\n && a.value === b.value\n && a.relative === b.relative\n && sameList(a.values, b.values)\n && sameList(a.excludeValues, b.excludeValues)\n && a.min === b.min\n && a.max === b.max;\n}\n\n\n// Whether two stored lists hold the same values in the same order.\nfunction sameList(a: unknown[] | undefined, b: unknown[] | undefined): boolean {\n return (a ?? []).length === (b ?? []).length\n && (a ?? []).every((value, index) => value === (b ?? [])[index]);\n}\n\n\n// Whether two list sorts order the rows the same way. No direction reads as\n// ascending, the way the list applies it.\nfunction sameSort(a: ReportSort, b: ReportSort | null): boolean {\n return !!b\n && a.column === b.column\n && (a.direction ?? 'asc') === (b.direction ?? 'asc');\n}\n\n\n// Whether a value read off a filter bar is the value already stored for its\n// group: the same calendar days, the same select values kept or left out in\n// the same order, the same trimmed text and the same number range ends. A\n// bar re-reads every group it shows on any change, so this is what tells the\n// group that changed from the ones that did not.\nexport function sameFilterValue(\n a: FilterGroupValue | null | undefined,\n b: FilterGroupValue | null | undefined,\n): boolean {\n return groupValueSignature(a) === groupValueSignature(b);\n}\n\n\n// The groups a bar re-read that it now shows with a value other than the one\n// it last reported, recording each new value in `lastReported`. A bar is\n// compared with itself, never with the stored value: a group shown in two bars\n// (level 'both') can be changed in the other one, and this bar is not\n// repainted, so its stale value must not be set back when the viewer changes\n// another of its items (the list search box, say).\nexport function movedGroupValues(\n lastReported: Map<number, FilterGroupValue | null>,\n reported: { groupId: number; value: FilterGroupValue | null }[],\n): { groupId: number; value: FilterGroupValue | null }[] {\n return reported.filter(({ groupId, value }) => {\n if (sameFilterValue(lastReported.get(groupId), value)) {\n return false;\n }\n\n lastReported.set(groupId, value);\n\n return true;\n });\n}\n\n\n// A list's search text as the server applies it: trimmed, then cut to\n// LIST_SEARCH_MAX_LENGTH characters (code points, as the server counts them).\nexport function listSearchText(text: string): string {\n return [...text.trim()].slice(0, LIST_SEARCH_MAX_LENGTH).join('');\n}\n\n\n// Whether two lists of column names are the same names in the same order.\nfunction sameNames(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((name, index) => name === b[index]);\n}\n\n\n// Whether two hidden-column maps hide the same columns on the same lists.\nfunction sameHidden(\n a: ReadonlyMap<number, readonly string[]>,\n b: ReadonlyMap<number, readonly string[]>,\n): boolean {\n return a.size === b.size\n && [...a].every(([componentId, names]) => sameNames(names, b.get(componentId) ?? []));\n}\n\n\n// Whether two date-range values cover the same calendar days.\nfunction sameDays(a: FilterGroupValue, b: FilterGroupValue): boolean {\n return dateBoundString(a.start) === dateBoundString(b.start)\n && dateBoundString(a.end) === dateBoundString(b.end);\n}\n\n\n// A stable signature for a group's stored default. The report toolbar keys its\n// fs-filter on this, because fs-filter reads its config once at init — without a\n// key change it keeps rendering the values it was created with even after the\n// config behind it has been rebuilt.\nexport function defaultSignature(group: ReportFilterGroup): string {\n const groupDefault = group.config?.default;\n\n if (!groupDefault) {\n return '';\n }\n\n return [\n groupDefault.start ?? '',\n groupDefault.end ?? '',\n groupDefault.value ?? '',\n groupDefault.relative ?? '',\n (groupDefault.values ?? []).join(','),\n (groupDefault.excludeValues ?? []).join(','),\n groupDefault.min ?? '',\n groupDefault.max ?? '',\n ].join('~');\n}\n\n\n// The temporary layer with nothing picked.\nfunction emptyTemporaryState(): ReportTemporaryState {\n return { crossFilters: [], showRows: null };\n}\n\n\n// Viewer filter state for the open report. Filter VALUES are never saved to\n// the report — this service holds them per filter GROUP (the propagation unit),\n// resolves them into per-component member-filter values for each data request,\n// and notifies the components whose groups changed so only they refetch.\n//\n// It is the one place the viewer's state lives while the report is open: the\n// group values, the group-by grain, the match, list sorts, searches and hidden\n// columns, the page, each chart's drill path and each table's layout. None of\n// it is ever written to the browser URL. It outlives a page switch (the canvas\n// changes the page, not this service) and goes with the report view: a reload\n// starts a new service, which opens on the report's authored defaults.\n// changes() fires on every change of it.\n//\n// The durable part reads as one document: snapshot() writes it, and\n// differsFromDefaults says whether the screen still shows the report's\n// authored defaults (resetToDefaults() puts it back on them). The temporary\n// layer (a cross-filter, an open rows panel) is its own section, so a\n// snapshot never carries it.\n//\n// Session-only, never in the snapshot: per-filter enable/disable toggles from\n// a component's filter menu (the `enabled` column is the authored default; a\n// viewer's toggle shouldn't write to the report), and each table's layout,\n// which fs-grid sends with the table's own reads.\n@Injectable()\nexport class ReportFilterStateService {\n\n // The open report's effective zone (resolveReportTimezone). Relative presets\n // resolve against today in it, and date cells render in it.\n public readonly timezone = signal<string>('UTC');\n\n // How the open report writes its numbers and dates (resolveFormatContext):\n // its locale, its currency and whether percents arrive as ratios. Every KPI,\n // chart, date cell and export reads it here. Compared by value, so a reload\n // of an unchanged report re-renders nothing.\n public readonly formatContext = signal<ReportFormatContext>(DEFAULT_FORMAT_CONTEXT, {\n equal: (a, b) => a.locale === b.locale\n && a.currency === b.currency\n && a.ratioPercent === b.ratioPercent,\n });\n\n // The config columns a viewer hid on each plain list (listHiddenColumns),\n // by component id; a list showing every column has no entry. A signal, so a\n // list hides and shows its columns in place: the rows do not change, so\n // nothing refetches. Compared by value, so a reload that keeps every column\n // repaints nothing.\n public readonly listHidden = signal<ReadonlyMap<number, readonly string[]>>(new Map(), {\n equal: sameHidden,\n });\n\n // Moves each time resetToDefaults() replaces the whole durable state. Bars\n // and tiles key on it, so a reset repaints all of them; the tiles refetch\n // in place, so their data stays on screen while they reload.\n public readonly stateVersion = computed(() => this._stateVersion());\n\n // By list component id, how many resets moved that list's sort. FsList\n // reads its sort only when it is created, so a list whose sort a reset\n // moved is drawn again (keyed on its count); every other tile reloads in\n // place.\n public readonly listSortResets = computed(() => this._listSortResets());\n\n // The open page, or null before the host reports one (setPage).\n public readonly page = computed(() => this._pageId());\n\n // How the groups combine: 'all' keeps the rows every group keeps, 'any'\n // the rows at least one eligible group keeps (setMatch).\n public readonly match = computed(() => this._match());\n\n // The viewer features the open report's server serves (Report.viewerFeatures):\n // a filter bar offers a control only when its feature is listed. Empty\n // before a report is open and from an older server.\n public readonly viewerFeatures = computed(() => this._report()?.viewerFeatures ?? []);\n\n // The report init() last read, or null before one is open. A tile header\n // lists its select options from it (ReportFilterOptionsService).\n public readonly report = computed(() => this._report());\n\n // Whether the screen differs from the report's authored defaults\n // (stateDiffers): what the report bar's 'Clear filters' shows for. A switch\n // of page does not count, and the temporary state never does.\n // A table tile in a layout of the viewer's own counts too; it stays out of\n // the snapshot, so no saved filter or link carries it.\n public readonly differsFromDefaults = computed(() => {\n this._revision();\n\n return this._gridLayouts().size > 0 || stateDiffers(this.authoredConfig(), this.snapshot());\n });\n\n private _values = new Map<number, FilterGroupValue>();\n private _groups = new Map<number, ReportFilterGroup>();\n private _sessionDisabled = new Set<number>();\n\n // Groups that have a default the viewer cleared. Without this a reload of the\n // report (a chat edit, a dialog) would find no value for the group and seed\n // its default straight back. A change to the stored default releases it.\n private _cleared = new Set<number>();\n\n // The report's group-by control: a single report-wide bucket override for all\n // the tiles that follow it (followsGroupBy). Unset = each one uses its\n // authored granularity. Never\n // saved to the report, and carried in the data request's\n // `state`, so it propagates through to the PDF/PowerPoint exports too. Named\n // for the `frequency` wire key it travels under, not for the control's label.\n private _frequency: ChartGranularity | null = null;\n private _frequencyChanged$ = new Subject<void>();\n\n // Each list's viewer-chosen sort, by component id. Held here rather than only\n // in the list's FsList so it survives the list being recreated (a page switch,\n // a reload after an edit) and so every consumer of viewer state reads one place.\n private _listSorts = new Map<number, ReportSort>();\n\n // Each list's search box text (listSearchText), by component id. A list with\n // an empty box has no entry. Held here for the same reasons as the sorts, and\n // because the box lives in the component header, not in the list.\n private _listSearches = new Map<number, string>();\n\n // The open report's lists, by component id, so a filter toggle can tell\n // which of them lose their search box (listSearchable).\n private _lists = new Map<number, ReportComponent>();\n\n // Whether the server answers a list search. List search and effectiveLocale\n // ship in the same framework change set, so a server that sends no\n // effectiveLocale has neither, and its lists show no search box.\n private _serverSearches = false;\n\n // Emits the id of the list whose search text changed.\n private _listSearchChanged$ = new Subject<number>();\n\n // Emits the group id that changed; components listen filtered to their own\n // group ids. null = everything changed (re-init).\n private _changed$ = new Subject<number | null>();\n\n // Fires whenever anything in the viewer state may have changed.\n private _stateChanged$ = new Subject<void>();\n\n // Counts the changes changes() reports. The group values, the grain and\n // the list state that differsFromDefaults compares are the plain fields\n // above, which every setter reports through changes() (they are shared\n // with the inline values build, so they stay as they are); this counter is\n // how the computed hears of them. The page, match and drills below are\n // signals and\n // is read directly. The subject is this service's own and is never\n // completed, so the signal listens to it exactly as long as the service\n // lives.\n private _revision = toSignal(this._stateChanged$.pipe(scan((count) => count + 1, 0)), {\n initialValue: 0,\n manualCleanup: true,\n });\n\n private _stateVersion = signal(0);\n\n private _listSortResets = signal<ReadonlyMap<number, number>>(new Map());\n\n // The report init() last read: the tiles and pages the state is checked\n // against.\n private _report = signal<Report | null>(null);\n\n // The open page, set by the host as the viewer moves between pages.\n private _pageId = signal<number | null>(null);\n\n // How the groups combine: 'all' (the default) or 'any'.\n private _match = signal<ReportFilterMatch>('all');\n\n // Each chart's drill path, top first, by component id. A chart at its top\n // has no entry, and only a chart has one.\n private _drills = signal<ReadonlyMap<number, readonly ReportDrillStep[]>>(new Map());\n\n // Emits the id of the chart whose drill path changed.\n private _drillChanged$ = new Subject<number>();\n\n // The layout a viewer put each table tile in, by component id, while it\n // differs from the tile's authored layout, with the authored layout it was\n // changed from (ReportGridSessionLayout.base). A table showing its authored\n // layout has no entry, and only a table has one.\n private _gridLayouts = signal<ReadonlyMap<number, ReportGridSessionLayout>>(new Map());\n\n // The groups a viewer left open in each table tile, by component id, so a\n // tile drawn again (a page switch) opens them. Session only: no Clear\n // resets them, differsFromDefaults never reads them, and fs-grid drops\n // them itself once the row levels change.\n private _gridExpansions = signal<ReadonlyMap<number, GridExpansion>>(new Map());\n\n // By table tile, the column filter a group-by change took out of it and\n // the grain the table now groups by (_grainGridLayouts()), for fs-grid's\n // status line. fs-grid hides it once the field is filtered again; a Clear\n // drops it.\n private _gridClearedFilters = signal<ReadonlyMap<number, GridClearedFilter>>(new Map());\n\n // The temporary layer: kept apart from everything above, so snapshot()\n // and differsFromDefaults never read it.\n private _temporary = signal<ReportTemporaryState>(emptyTemporaryState());\n\n // Seed groups + their defaults when a report loads. Existing session values\n // for still-existing groups survive a structure re-fetch (a chat edit\n // shouldn't reset the viewer's filters), and so does a group the viewer\n // cleared — UNLESS the group's stored default itself changed, which only\n // happens when an operator saved a new default in report settings or the\n // agent set one. That is an explicit instruction to re-seed, so it wins over\n // the surviving session value; without it the bar keeps showing whatever it\n // was first seeded with until a full page reload.\n //\n // A change of the report's zone moves \"today\", so a value still carrying its\n // group default's preset name is resolved again in the new zone. A value the\n // viewer picked, or one carrying another preset name, is kept as it is.\n public init(report: Report): void {\n const previousTimezone = this.timezone();\n\n // Set first: the defaults seeded below resolve their relative presets in it.\n this.timezone.set(resolveReportTimezone(report));\n this.formatContext.set(resolveFormatContext(report));\n // Before the pruning: listSearchable reads it.\n this._serverSearches = report.effectiveLocale !== undefined;\n\n const timezoneChanged = previousTimezone !== this.timezone();\n const previousGroups = this._groups;\n this._groups = new Map<number, ReportFilterGroup>();\n\n for (const group of report.filterGroups ?? []) {\n this._groups.set(group.id, group);\n this._seed(group, previousGroups.get(group.id) ?? null, timezoneChanged);\n }\n\n this._lists = new Map(this._listComponents(report).map((component) => [component.id, component]));\n\n this._prune(report);\n this._prunePageState(report);\n\n this._changed$.next(null);\n this._stateChanged$.next();\n }\n\n public value(groupId: number): FilterGroupValue | undefined {\n return this._values.get(groupId);\n }\n\n // A bar's value for a group. A date range keeps the stored preset name only\n // while its days are still the stored days: the bars re-set every group they\n // show whenever any one of them changes, and an untouched rolling range must\n // keep its name rather than turn into two fixed dates. Any other range, a\n // date picker preset included, is stored as the fixed dates it shows.\n public setValue(groupId: number, value: FilterGroupValue | null): void {\n if (value === null) {\n this._values.delete(groupId);\n\n if (this._groups.get(groupId)?.config?.default) {\n this._cleared.add(groupId);\n }\n } else {\n this._values.set(groupId, this._withPreset(this._values.get(groupId), value));\n this._cleared.delete(groupId);\n }\n\n this._changed$.next(groupId);\n this._stateChanged$.next();\n }\n\n // A relative preset name as today's range in the report's zone, or null for\n // a name it does not know.\n public resolveRelative(name: string): { start: Date; end: Date } | null {\n return this._relativeRange(name);\n }\n\n // The active group-by grain, or null when the viewer hasn't chosen one.\n public frequency(): ChartGranularity | null {\n return this._frequency;\n }\n\n // Each table that follows the group-by has its filter on the group-by's\n // field moved to the new grain first (_grainGridLayouts()), so a table on\n // screen reads once, with both.\n public setFrequency(frequency: ChartGranularity | null): void {\n this._frequency = frequency;\n this._grainGridLayouts();\n this._frequencyChanged$.next();\n this._stateChanged$.next();\n }\n\n // Fires whenever the group-by grain changes — every tile that follows it\n // listens so it refetches and re-buckets (the override isn't scoped to any\n // filter group, so changesFor() can't carry it).\n public frequencyChanges(): Observable<void> {\n return this._frequencyChanged$.asObservable();\n }\n\n // The sort the viewer last fetched a list with, or null when it hasn't sorted\n // (the list then falls back to its authored sort).\n public listSort(componentId: number): ReportSort | null {\n return this._listSorts.get(componentId) ?? null;\n }\n\n // Records a list's sort when it is the viewer's own: a sort that is the\n // list's authored first term is the list's default, not a choice, so it\n // clears the entry instead (the rule snapshot() applies). Otherwise a\n // list's first fetch would record its seeded authored term, and a list the\n // agent re-sorts later in the session would keep sending the old term\n // first. Deliberately emits no change: the list sets this from the fetch\n // that already ran with that sort, so a notification would only make it\n // refetch the same rows. Only changes() hears about it.\n public setListSort(component: ReportComponent, sort: ReportSort | null): void {\n if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {\n this._listSorts.set(component.id, sort);\n } else {\n this._listSorts.delete(component.id);\n }\n\n this._stateChanged$.next();\n }\n\n // The text a list is searched by, or null when its search box is empty.\n public listSearch(componentId: number): string | null {\n return this._listSearches.get(componentId) ?? null;\n }\n\n // Whether a list shows the search box over its text columns: it does when the\n // server answers a list search (see _serverSearches), unless one of its live\n // filters belongs to a keyword group its header shows. A bar shows one search\n // box (its last keyword item), and that one is the author's. The header, the\n // pruning, the data request state and the exports all read\n // this one rule, so no search narrows a list whose screen has no box showing\n // it, and no export titles a search the server did not apply.\n public listSearchable(component: ReportComponent): boolean {\n return this._serverSearches\n && component.type === 'list'\n && !(component.filters ?? []).some((filter) => {\n const group = this._groups.get(filter.filterGroupId);\n\n return filter.enabled\n && !this._sessionDisabled.has(filter.id)\n && group?.type === 'keyword'\n && (group.level === 'component' || group.level === 'both');\n });\n }\n\n // Records a list's search box text (listSearchText); an empty box clears\n // it. The header calls this on every change of any of its items, so the\n // list and changes() hear about it only when the stored text actually changed.\n public setListSearch(componentId: number, text: string): void {\n const search = listSearchText(text);\n\n if (search === (this._listSearches.get(componentId) ?? '')) {\n return;\n }\n\n if (search) {\n this._listSearches.set(componentId, search);\n } else {\n this._listSearches.delete(componentId);\n }\n\n this._listSearchChanged$.next(componentId);\n this._stateChanged$.next();\n }\n\n // The config column names a viewer hid on a list; none when it shows them all.\n public hiddenColumns(componentId: number): readonly string[] {\n return this.listHidden().get(componentId) ?? [];\n }\n\n // Records the columns a viewer hid on a list, kept to listHiddenColumns:\n // names the list cannot hide are dropped, and none (or every column) clears\n // the entry. Only changes() hears about it, and only on a real change.\n public setHiddenColumns(componentId: number, names: readonly string[]): void {\n const hidden = listHiddenColumns(this._lists.get(componentId)?.config, names);\n\n if (sameNames(hidden, this.hiddenColumns(componentId))) {\n return;\n }\n\n const next = new Map(this.listHidden());\n\n if (hidden.length) {\n next.set(componentId, hidden);\n } else {\n next.delete(componentId);\n }\n\n this.listHidden.set(next);\n this._stateChanged$.next();\n }\n\n // Fires whenever one list's search text changes, so that list refetches.\n public listSearchChanges(componentId: number): Observable<void> {\n return this._listSearchChanged$.asObservable()\n .pipe(\n rxFilter((id) => id === componentId),\n map(() => undefined),\n );\n }\n\n // Fires whenever the viewer state may have changed: a group value, the\n // grain, the match, the page, a list sort, search or hidden columns, a\n // drill path, a reset or a (re)load of the report.\n public changes(): Observable<void> {\n return this._stateChanged$.asObservable();\n }\n\n public isFilterDisabled(filterId: number): boolean {\n return this._sessionDisabled.has(filterId);\n }\n\n public toggleFilter(filterId: number, groupId: number): void {\n if (this._sessionDisabled.has(filterId)) {\n this._sessionDisabled.delete(filterId);\n } else {\n this._sessionDisabled.add(filterId);\n }\n\n // Turning a keyword filter back on takes its list's search box away, and\n // the search with it. The list refetches on the group change below.\n this._dropUnsearchable();\n\n this._changed$.next(groupId);\n this._stateChanged$.next();\n }\n\n // Notifications relevant to ONE component: any change to a group one of its\n // filters belongs to (or a full re-init).\n public changesFor(component: ReportComponent): Observable<number | null> {\n const groupIds = new Set((component.filters ?? []).map((filter) => filter.filterGroupId));\n\n return this._changed$.asObservable()\n .pipe(\n rxFilter((groupId) => groupId === null || groupIds.has(groupId)),\n );\n }\n\n // Notifications relevant to ANY of a set of components that comes and goes\n // (a page's values): a change to a group one of their filters belongs to.\n // Unlike changesFor, the set is read on each event rather than captured at\n // subscribe, so one subscription follows the set as the report reloads. A\n // full re-init (null) is not passed on: init() runs on a report\n // (re)load, and a caller of this checks on that reload itself whether the\n // filter values its components are read with moved.\n public changesForAny(components: () => ReportComponent[]): Observable<number> {\n return this._changed$.asObservable()\n .pipe(\n rxFilter((groupId): groupId is number => groupId !== null\n && components().some((component) => (component.filters ?? [])\n .some((filter) => filter.filterGroupId === groupId))),\n );\n }\n\n // The group values resolved into this component's member-filter values —\n // what the data request carries. Disabled filters (authored or session) are\n // skipped entirely.\n public resolveForComponent(component: ReportComponent): ResolvedFilterValue[] {\n const resolved: ResolvedFilterValue[] = [];\n\n for (const filter of component.filters ?? []) {\n if (!filter.enabled || this._sessionDisabled.has(filter.id)) {\n continue;\n }\n\n const value = this._values.get(filter.filterGroupId);\n const fields = value ? this._resolvedFields(value) : null;\n\n if (fields) {\n resolved.push({ filterId: filter.id, ...fields });\n }\n }\n\n return resolved;\n }\n\n // What the viewer has set, one entry per filter group, for the report chat:\n // the agent reads it to know what is on screen. Group order, not the order\n // the values were set in, so the same state always reads the same. A group\n // with nothing in it is left out, and a saved default counts until the\n // viewer changes it. Per-filter toggles are a component's own business, so\n // they are not part of it.\n public viewerFilters(): ReportChatViewerFilter[] {\n return [...this._values.entries()]\n .sort(([a], [b]) => a - b)\n .map(([groupId, value]) => {\n const fields = this._resolvedFields(value);\n\n return fields ? { groupId, ...fields } : null;\n })\n .filter((entry): entry is ReportChatViewerFilter => entry !== null);\n }\n\n // Every tile's resolved values in one array — what a report-level export\n // carries so each file in the archive is filtered exactly as the screen is.\n // Filter ids are unique per component, so the backend picks each component's\n // own out of the pile. Only a tile becomes a file (isTile), so no other\n // component's entries ride along. A page id narrows it to that page.\n public resolveForReport(report: Report, pageId: number | null = null): ResolvedFilterValue[] {\n const pages = (report.pages ?? [])\n .filter((page) => !pageId || page.id === pageId);\n\n return pages\n .flatMap((page) => (page.components ?? [])\n .filter((component) => isTile(component))\n .flatMap((component) => this.resolveForComponent(component)));\n }\n\n public setPage(pageId: number | null): void {\n if (pageId === this._pageId()) {\n return;\n }\n\n this._pageId.set(pageId);\n this._stateChanged$.next();\n }\n\n // A change of match can change every tile a group with a value narrows, so\n // every tile hears about it.\n public setMatch(match: ReportFilterMatch): void {\n const next: ReportFilterMatch = match === 'any' ? 'any' : 'all';\n if (next === this._match()) {\n return;\n }\n\n this._match.set(next);\n this._changed$.next(null);\n this._stateChanged$.next();\n }\n\n // A chart's drill path, top first; empty while the chart is at its top.\n // It reads a signal, so a template that shows it repaints when it moves.\n public drill(componentId: number): readonly ReportDrillStep[] {\n return this._drills().get(componentId) ?? [];\n }\n\n // Records a chart's drill path, kept to cleanDrillPath; an empty path is\n // the chart's top. Only a chart of the open report drills: a path for any\n // other component is ignored. Only that chart and changes() hear about it,\n // and only on a real change.\n public setDrill(componentId: number, path: readonly ReportDrillStep[]): void {\n const kept = cleanDrillPath(path);\n if (!this._isChart(componentId) || sameDrillPath(kept, this.drill(componentId))) {\n return;\n }\n\n this._setDrillPath(componentId, kept);\n this._drillChanged$.next(componentId);\n this._stateChanged$.next();\n }\n\n // Fires whenever one chart's drill path changes, so that chart refetches.\n public drillChanges(componentId: number): Observable<void> {\n return this._drillChanged$.asObservable()\n .pipe(\n rxFilter((id) => id === componentId),\n map(() => undefined),\n );\n }\n\n // Takes the drill path a chart's answer applied as the chart's own: the\n // server keeps the longest part of a sent path it can apply, so a later\n // save holds that part only. The chart has just read that path, so only\n // changes() hears about it. True when the path changed.\n public adoptDrill(componentId: number, path: readonly ReportDrillStep[]): boolean {\n const kept = cleanDrillPath(path);\n if (!this._isChart(componentId) || sameDrillPath(kept, this.drill(componentId))) {\n return false;\n }\n\n this._setDrillPath(componentId, kept);\n this._stateChanged$.next();\n\n return true;\n }\n\n // The layout a table tile is on screen in: the viewer's own while they\n // changed it from the layout authored now, else the authored one. It reads\n // a signal, so a tile that shows it redraws when either moves.\n public gridLayout(component: ReportComponent): GridLayout {\n return this.gridSessionLayout(component) ?? authoredGridLayout(component);\n }\n\n // The viewer's own layout of a table tile while it differs from the layout\n // authored now, else null: the tile shows its stored layout. The chat\n // sends it as the tile's layout.\n public gridSessionLayout(component: ReportComponent): GridLayout | null {\n const session = this._gridLayouts().get(component.id);\n\n return session?.base === gridLayoutKey(authoredGridLayout(component))\n ? session.layout\n : null;\n }\n\n // Records the layout a viewer put a table tile in (a re-pivot, a sort, a\n // column filter). One that draws the authored layout clears the entry, so\n // the tile reads as stored again. fs-grid reads the change itself, so only\n // changes() hears about it, and only on a real change.\n public setGridLayout(component: ReportComponent, layout: GridLayout): void {\n if (this._putGridLayout(component, layout)) {\n this._stateChanged$.next();\n }\n }\n\n // The column filter a group-by change took out of a table tile, or null\n // (_gridClearedFilters).\n public gridClearedFilter(component: ReportComponent): GridClearedFilter | null {\n return this._gridClearedFilters().get(component.id) ?? null;\n }\n\n // The groups a viewer left open in a table tile, or undefined: the tile\n // opens as its layout says.\n public gridExpansion(component: ReportComponent): GridExpansion | undefined {\n return this._gridExpansions().get(component.id);\n }\n\n // Records the groups open in a table tile, as fs-grid writes them out. It\n // changes no read, so nothing hears about it.\n public setGridExpansion(component: ReportComponent, expansion: GridExpansion | undefined): void {\n if (component.type !== 'grid' || !expansion || this._gridExpansions().get(component.id) === expansion) {\n return;\n }\n\n this._gridExpansions.set(new Map(this._gridExpansions()).set(component.id, expansion));\n }\n\n // The durable state on screen as one document: the page, every group the\n // report has (null when it holds nothing, a cleared default included), the\n // match, the grain, and each tile's sort, search, hidden columns and drill\n // path where they differ from the authored tile. A date range that still\n // carries its relative preset is written as that preset, whatever today is\n // (toStoredGroupValue). The temporary layer is never part of it.\n public snapshot(): ReportStateSnapshot {\n const snapshot: ReportStateSnapshot = {};\n\n if (this._pageId()) {\n snapshot.pageId = this._pageId();\n }\n\n if (this._frequency) {\n snapshot.groupBy = this._frequency;\n }\n\n if (this._match() === 'any') {\n snapshot.match = 'any';\n }\n\n snapshot.groups = this._snapshotGroups();\n\n const tiles = this._snapshotTiles();\n if (Object.keys(tiles).length) {\n snapshot.tiles = tiles;\n }\n\n return snapshot;\n }\n\n // The report's authored defaults as a snapshot: every group at its authored\n // default (null when it has none), no match, grain or tile state.\n public authoredConfig(): ReportStateSnapshot {\n const groups: Record<number, FilterGroupDefault | null> = {};\n\n this._groups.forEach((group) => {\n groups[group.id] = toStoredGroupValue(group.type, this._defaultValue(group));\n });\n\n return { groups };\n }\n\n // Puts the screen back on the report's authored defaults on the page it is\n // on: every group at its default, match 'all', no grain, and every tile at\n // its authored sort, search, columns and top. Clears the temporary layer.\n // The tiles stay and reload in place, except a list whose sort this moved\n // (listSortResets). Every change is announced once, at the end.\n public resetToDefaults(): void {\n const frequency = this._frequency;\n const sorts = new Map(this._listSorts);\n\n this._temporary.set(emptyTemporaryState());\n this._groups.forEach((group) => this._seedAuthored(group));\n this._match.set('all');\n this._frequency = null;\n this._clearTiles();\n this._countSortResets(sorts);\n this._notifyReset(frequency);\n }\n\n // Puts only `groupIds` back on their authored defaults. A tile header's\n // 'Clear filters' owns only its own groups; the report bar's calls\n // resetToDefaults(). Each group is announced as a viewer's change to it is,\n // so the tiles in it refetch and a bar showing it with another value is\n // built again.\n public resetGroupsToDefaults(groupIds: readonly number[]): void {\n groupIds.forEach((groupId) => {\n const group = this._groups.get(groupId);\n if (!group) {\n return;\n }\n\n this._seedAuthored(group);\n this._changed$.next(groupId);\n });\n\n this._stateChanged$.next();\n }\n\n // Whether one of `groupIds` shows a value other than its authored default,\n // the value resetGroupsToDefaults() puts back. A tile header's Clear chip\n // shows exactly while one of its own groups does. It reads the revision\n // differsFromDefaults reads, so a caller on each check of an OnPush view\n // stays current.\n public groupsDifferFromDefaults(groupIds: readonly number[]): boolean {\n this._revision();\n\n return groupIds.some((groupId) => {\n const group = this._groups.get(groupId);\n if (!group) {\n return false;\n }\n\n const authored = toStoredGroupValue(group.type, this._defaultValue(group));\n const screen = this._cleared.has(groupId) ? null : toStoredGroupValue(group.type, this._values.get(groupId));\n\n return !sameStoredGroupValue(authored, screen);\n });\n }\n\n // The interaction state a tile's data request carries now: tileDataState\n // over the open report and the screen's snapshot().\n public tileState(component: ReportComponent): ComponentDataState {\n return tileDataState(this._report(), component, this.snapshot());\n }\n\n // The relative range a group's value still is, as a data request names it\n // (its preset while its days are that range resolved today), or null. The\n // export wording names a live preset by it.\n public livePreset(groupId: number): ReportRelativeRange | null {\n const value = this._values.get(groupId);\n\n return value ? this._livePreset(value) : null;\n }\n\n // A group value as the fields a request carries: date bounds as calendar\n // days, select values when any are picked (else the values left out),\n // keyword text trimmed, a number range's ends. Null when all of them are\n // empty. A date range also names the relative range it still is\n // (_livePreset), so the server knows which period the days cover;\n // the days stay the window either way. Component data, the report and page\n // exports and the chat's viewer filters all read their fields here, so all\n // three carry it.\n private _resolvedFields(value: FilterGroupValue): Omit<ResolvedFilterValue, 'filterId'> | null {\n const fields: Omit<ResolvedFilterValue, 'filterId'> = {};\n const preset = this._livePreset(value);\n\n if (value.start) {\n fields.start = dateBoundString(value.start);\n }\n if (value.end) {\n fields.end = dateBoundString(value.end);\n }\n if (preset) {\n fields.preset = preset;\n }\n if (value.values?.length) {\n fields.values = value.values;\n }\n if (value.value?.trim()) {\n fields.value = value.value.trim();\n }\n\n this._resolveExcludeAndRange(value, fields);\n\n return fields.start || fields.end || fields.values || fields.value\n || fields.excludeValues || fields.min !== undefined || fields.max !== undefined\n ? fields\n : null;\n }\n\n // The relative range a date value still is: the preset name it carries,\n // while its days are that range resolved today in the report's zone. A\n // value whose days the viewer changed, or one seeded before midnight that\n // is now a day behind, names none, and the server reads its days alone.\n private _livePreset(value: FilterGroupValue): ReportRelativeRange | null {\n if (!value.preset || !isRelativeRange(value.preset)) {\n return null;\n }\n\n const range = this._relativeRange(value.preset);\n\n return range && sameDays(value, range) ? value.preset : null;\n }\n\n // Seeds one group on (re)load; see init(). `previous` is the group as the\n // last load had it, or null when it is new.\n private _seed(\n group: ReportFilterGroup,\n previous: ReportFilterGroup | null,\n timezoneChanged: boolean,\n ): void {\n const defaultChanged = !sameDefault(previous?.config?.default ?? null, group.config?.default ?? null);\n\n if (defaultChanged) {\n this._cleared.delete(group.id);\n }\n\n if (this._cleared.has(group.id)) {\n return;\n }\n\n const value = this._values.get(group.id);\n const presetToResolve = timezoneChanged\n && !!value?.preset\n && value.preset === group.config?.default?.relative;\n\n if (value && !defaultChanged && !presetToResolve) {\n return;\n }\n\n const defaultValue = this._defaultValue(group);\n\n if (defaultValue) {\n this._values.set(group.id, defaultValue);\n } else if (defaultChanged) {\n // The default was cleared, so the value it seeded goes with it.\n this._values.delete(group.id);\n }\n }\n\n // Drops the search of every list that no longer shows a search box: one\n // the report no longer has, or one whose header now has a keyword group.\n private _dropUnsearchable(): void {\n this._listSearches.forEach((search, componentId) => {\n const component = this._lists.get(componentId);\n\n if (!component || !this.listSearchable(component)) {\n this._listSearches.delete(componentId);\n }\n });\n }\n\n // Drops state kept for groups, lists and filters the report no longer has.\n // A list sort also goes when its column does: the agent can remove or rename\n // it, and the recreated list would send a column the query does not know.\n // A list search goes with its list (or when the component is no longer a\n // list), and when the list gains a keyword group and so loses its box.\n // Hidden columns keep only the names their list still has as columns (the\n // agent can remove or rename one, or turn the list into a cross-tab), and go\n // when what is left would hide every column.\n private _prune(report: Report): void {\n for (const groupId of [...this._values.keys(), ...this._cleared]) {\n if (!this._groups.has(groupId)) {\n this._values.delete(groupId);\n this._cleared.delete(groupId);\n }\n }\n\n this._listSorts.forEach((sort, componentId) => {\n const component = this._lists.get(componentId);\n\n if (!component || !this._sortableColumns(component).includes(sort.column)) {\n this._listSorts.delete(componentId);\n }\n });\n\n // Values included: one is never drawn, but its filters are the report's\n // like any other component's, and so are their session toggles.\n const filterIds = new Set(reportComponents(report)\n .flatMap((component) => (component.filters ?? []).map((filter) => filter.id)));\n\n this._sessionDisabled.forEach((filterId) => {\n if (!filterIds.has(filterId)) {\n this._sessionDisabled.delete(filterId);\n }\n });\n\n this._dropUnsearchable();\n\n const hidden = new Map<number, readonly string[]>();\n\n this.listHidden().forEach((names, componentId) => {\n const kept = listHiddenColumns(this._lists.get(componentId)?.config, names);\n\n if (kept.length) {\n hidden.set(componentId, kept);\n }\n });\n\n this.listHidden.set(hidden);\n }\n\n // The value a bar sets, keeping the stored preset name while the days are\n // still the stored days (see setValue).\n private _withPreset(stored: FilterGroupValue | undefined, value: FilterGroupValue): FilterGroupValue {\n const fixed: FilterGroupValue = { ...value };\n delete fixed.preset;\n\n return stored?.preset && sameDays(stored, fixed)\n ? { ...fixed, preset: stored.preset }\n : fixed;\n }\n\n private _listComponents(report: Report): ReportComponent[] {\n return reportComponents(report)\n .filter((component) => component.type === 'list');\n }\n\n // The columns a list can be sorted by: every authored column, or a\n // cross-tab's row column only (its pivot columns come and go with the data).\n private _sortableColumns(component: ReportComponent): string[] {\n const config = component.config;\n\n if (config?.pivotBy?.column) {\n return config.rowBy?.column ? [config.rowBy.column] : [];\n }\n\n return (config?.columns ?? []).map((column) => column.column);\n }\n\n // A group's authored default, mapped to a session value by type. Relative\n // date presets resolve against \"now\" each time the report opens, so a saved\n // \"last 12 months\" stays relative and carries its preset name; a fixed\n // range, select values and keyword text seed verbatim.\n private _defaultValue(group: ReportFilterGroup): FilterGroupValue | null {\n const groupDefault = group.config?.default;\n if (!groupDefault) {\n return null;\n }\n\n if (groupDefault.relative) {\n const range = this._relativeRange(groupDefault.relative);\n\n return range ? { start: range.start, end: range.end, preset: groupDefault.relative } : null;\n }\n\n if (groupDefault.start || groupDefault.end) {\n return {\n start: groupDefault.start ?? null,\n end: groupDefault.end ?? null,\n };\n }\n\n if (groupDefault.values?.length) {\n return { values: groupDefault.values };\n }\n\n if (groupDefault.value) {\n return { value: groupDefault.value };\n }\n\n return this._excludeOrRangeDefault(groupDefault);\n }\n\n // A relative preset as a calendar-day range. \"Today\" is the day in the\n // report's effective zone, not the browser's, so every viewer seeds the same\n // range. The server twin is ReportRelativeRangeEnum (framework/Report/Enum),\n // and ReportRelativeRangeEnumTest pins the table both sides must produce.\n private _relativeRange(relative: string): { start: Date; end: Date } | null {\n const now = getZonedNow(this.timezone());\n\n switch (relative) {\n // A calendar week, Monday to Sunday (REPORT_WEEK_STARTS_ON, the same week\n // the server's weekly buckets use), in whole days — not the rolling\n // seven days `last7Days` gives, which never lines up with the week a\n // partner has already been sent. `lastWeek` is the one a weekly report\n // wants: it ends on the previous week's Sunday rather than at `now`,\n // because the week it names has closed. `thisWeek` follows every other\n // preset here and runs up to now, so it is deliberately a part-finished\n // week (on a Sunday it is the whole Monday-to-Sunday week).\n case 'thisWeek':\n return { start: startOfWeek(now, { weekStartsOn: REPORT_WEEK_STARTS_ON }), end: now };\n case 'lastWeek': {\n const previous = subWeeks(now, 1);\n\n return {\n start: startOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),\n end: endOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),\n };\n }\n case 'last7Days':\n return { start: subDays(now, 7), end: now };\n case 'last30Days':\n return { start: subDays(now, 30), end: now };\n case 'last3Months':\n return { start: subMonths(now, 3), end: now };\n case 'last6Months':\n return { start: subMonths(now, 6), end: now };\n case 'last12Months':\n return { start: subMonths(now, 12), end: now };\n case 'thisMonth':\n return { start: startOfMonth(now), end: now };\n case 'thisQuarter':\n return { start: startOfQuarter(now), end: now };\n case 'thisYear':\n case 'yearToDate':\n return { start: startOfYear(now), end: now };\n default:\n return null;\n }\n }\n\n // Every group in its stored shape: null when it holds nothing, a default\n // the viewer cleared included.\n private _snapshotGroups(): Record<number, FilterGroupDefault | null> {\n const groups: Record<number, FilterGroupDefault | null> = {};\n\n this._groups.forEach((group) => {\n groups[group.id] = this._cleared.has(group.id)\n ? null\n : toStoredGroupValue(group.type, this._values.get(group.id));\n });\n\n return groups;\n }\n\n // Each tile's state where it differs from the authored tile. A list sort\n // that is the list's authored first term is its default, not a choice.\n private _snapshotTiles(): Record<number, ReportTileState> {\n const tiles: Record<number, ReportTileState> = {};\n\n for (const component of this._tiles()) {\n const tile: ReportTileState = {};\n const sort = this._listSorts.get(component.id);\n const search = this._listSearches.get(component.id);\n const hidden = this.hiddenColumns(component.id);\n const drill = this.drill(component.id);\n\n if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {\n tile.sort = { ...sort };\n }\n if (search) {\n tile.search = search;\n }\n if (hidden.length) {\n tile.hidden = [...hidden];\n }\n if (drill.length) {\n tile.drill = drill.map((step) => ({ ...step }));\n }\n\n if (Object.keys(tile).length) {\n tiles[component.id] = tile;\n }\n }\n\n return tiles;\n }\n\n // A group back at its authored default.\n private _seedAuthored(group: ReportFilterGroup): void {\n const value = this._defaultValue(group);\n\n this._cleared.delete(group.id);\n\n if (value) {\n this._values.set(group.id, value);\n } else {\n this._values.delete(group.id);\n }\n }\n\n // Every tile back at its authored state.\n private _clearTiles(): void {\n this._listSorts.clear();\n this._listSearches.clear();\n this.listHidden.set(new Map());\n this._drills.set(new Map());\n this._gridLayouts.set(new Map());\n this._gridClearedFilters.set(new Map());\n }\n\n // setGridLayout() without the change event; true when the layout changed.\n private _putGridLayout(component: ReportComponent, layout: GridLayout): boolean {\n const base = gridLayoutKey(authoredGridLayout(component));\n const key = gridLayoutKey(layout);\n const current = this._gridLayouts().get(component.id);\n const unchanged = key === base\n ? !current\n : current?.base === base && gridLayoutKey(current.layout) === key;\n\n if (component.type !== 'grid' || unchanged) {\n return false;\n }\n\n const next = new Map(this._gridLayouts());\n\n if (key === base) {\n next.delete(component.id);\n } else {\n next.set(component.id, { layout, base });\n }\n\n this._gridLayouts.set(next);\n\n return true;\n }\n\n // Every table that follows the group-by (followsGroupBy), its column filter\n // on the group-by's field moved to the grain it now reads at: the viewer's\n // pick, else the table's own (grainedGridLayout()). Tables on other pages\n // move too, so their files, the chat and their next paint read the moved\n // filter. A filter taken out is noted on its tile (gridClearedFilter()); a\n // note already there names the new grain, unless the field is filtered\n // again, which ends it.\n private _grainGridLayouts(): void {\n const cleared = new Map(this._gridClearedFilters());\n\n this._tiles().forEach((component) => {\n const groupBy = component.type === 'grid' ? component.followsGroupBy : null;\n const granularity = this._frequency ?? groupBy?.granularity;\n if (!groupBy || !granularity) {\n return;\n }\n\n const grained = grainedGridLayout(this.gridLayout(component), groupBy.field, granularity);\n const filtered = (grained.layout.filters ?? []).some((filter) => filter.field === groupBy.field);\n const note = grained.cleared ?? (filtered ? null : cleared.get(component.id));\n if (note) {\n cleared.set(component.id, { ...note, granularity: GRID_GRANULARITIES[granularity] });\n } else {\n cleared.delete(component.id);\n }\n\n this._putGridLayout(component, grained.layout);\n });\n\n this._gridClearedFilters.set(cleared);\n }\n\n // One chart's drill path; an empty path is the chart's top.\n private _setDrillPath(componentId: number, path: readonly ReportDrillStep[]): void {\n const next = new Map(this._drills());\n\n if (path.length) {\n next.set(componentId, path);\n } else {\n next.delete(componentId);\n }\n\n this._drills.set(next);\n }\n\n // After resetToDefaults(): every bar and tile repaints, and the tiles that\n // follow the group-by refetch when the grain moved.\n private _notifyReset(frequency: ChartGranularity | null): void {\n this._stateVersion.update((version) => version + 1);\n this._changed$.next(null);\n\n if (frequency !== this._frequency) {\n this._frequencyChanged$.next();\n }\n\n this._stateChanged$.next();\n }\n\n // The tiles of the report init() last read.\n private _tiles(): ReportComponent[] {\n const report = this._report();\n\n return report\n ? reportComponents(report).filter(isTile)\n : [];\n }\n\n private _isChart(componentId: number): boolean {\n return this._tiles()\n .some((component) => component.id === componentId && component.type === 'chart');\n }\n\n // Drops each table layout and expansion whose tile is gone or is no table\n // any more. A layout whose tile is now authored otherwise (an edit, the\n // agent's) moves onto the new authored layout, keeping the viewer's filters\n // and sort terms on fields it still places (rebasedGridLayout), so the tile\n // shows both changes; one that then draws the authored layout is dropped.\n private _pruneGridLayouts(): void {\n const grids = new Map(this._tiles()\n .filter((component) => component.type === 'grid')\n .map((component) => [component.id, component]));\n const kept = new Map<number, ReportGridSessionLayout>();\n\n this._gridLayouts().forEach((session, componentId) => {\n const component = grids.get(componentId);\n if (!component) {\n return;\n }\n\n const authored = authoredGridLayout(component);\n const base = gridLayoutKey(authored);\n const layout = session.base === base ? session.layout : rebasedGridLayout(session.layout, session.base, authored);\n\n if (gridLayoutKey(layout) !== base) {\n kept.set(componentId, { layout, base });\n }\n });\n\n this._gridLayouts.set(kept);\n this._gridExpansions.set(new Map([...this._gridExpansions()]\n .filter(([componentId]) => grids.has(componentId))));\n this._gridClearedFilters.set(new Map([...this._gridClearedFilters()]\n .filter(([componentId]) => grids.has(componentId))));\n }\n\n // Keeps the page, drill and table state to what the report (re)loaded by\n // init() still has: drill paths on charts it still has, the page while it\n // has it, and each table's layout and open groups while it is still a table\n // (_pruneGridLayouts). On another report it starts again: match 'all', no\n // drill, every table as authored and closed, and nothing temporary.\n private _prunePageState(report: Report): void {\n if (this._report()?.id !== report.id) {\n this._match.set('all');\n this._pageId.set(null);\n this._drills.set(new Map());\n this._gridLayouts.set(new Map());\n this._gridExpansions.set(new Map());\n this._gridClearedFilters.set(new Map());\n this._temporary.set(emptyTemporaryState());\n }\n\n this._report.set(report);\n this._drills.set(new Map([...this._drills()]\n .filter(([componentId]) => this._isChart(componentId))));\n this._pruneGridLayouts();\n // A table the report now authors otherwise reads at the grain on screen.\n this._grainGridLayouts();\n\n if (this._pageId() && !(report.pages ?? []).some((page) => page.id === this._pageId())) {\n this._pageId.set(null);\n }\n }\n\n // A select's values to leave out (only when it keeps none) and a number\n // range's ends, an open end left out and 0 kept, written onto `fields`.\n private _resolveExcludeAndRange(value: FilterGroupValue, fields: Omit<ResolvedFilterValue, 'filterId'>): void {\n if (value.excludeValues?.length && !fields.values) {\n fields.excludeValues = value.excludeValues;\n }\n\n const min = finiteNumber(value.min);\n const max = finiteNumber(value.max);\n\n if (min !== undefined) {\n fields.min = min;\n }\n if (max !== undefined) {\n fields.max = max;\n }\n }\n\n // An authored default that leaves select values out, or a number range's\n // ends (0 kept), as a session value; null when it holds neither.\n private _excludeOrRangeDefault(groupDefault: FilterGroupDefault): FilterGroupValue | null {\n if (groupDefault.excludeValues?.length) {\n return { excludeValues: groupDefault.excludeValues };\n }\n\n const min = finiteNumber(groupDefault.min);\n const max = finiteNumber(groupDefault.max);\n\n if (min === undefined && max === undefined) {\n return null;\n }\n\n return {\n ...(min !== undefined ? { min } : {}),\n ...(max !== undefined ? { max } : {}),\n };\n }\n\n // Counts a reset for each list whose sort is not the one it had (`before`,\n // the sorts by list before the reset). A sort a list lost and one it\n // gained both count; the authored sort is no entry either side.\n private _countSortResets(before: ReadonlyMap<number, ReportSort>): void {\n const moved = [...new Set([...before.keys(), ...this._listSorts.keys()])]\n .filter((componentId) => {\n const was = before.get(componentId);\n const now = this._listSorts.get(componentId) ?? null;\n\n return was ? !sameSort(was, now) : now !== null;\n });\n\n if (!moved.length) {\n return;\n }\n\n const counts = new Map(this._listSortResets());\n moved.forEach((componentId) => counts.set(componentId, (counts.get(componentId) ?? 0) + 1));\n this._listSortResets.set(counts);\n }\n}\n","import { DestroyRef, Injectable, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { Observable, Subject, defer, of } from 'rxjs';\nimport { catchError, filter, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../data/report.data';\nimport { ReportFilterOptionPair } from '../interfaces/report-filter-option-pair.interface';\nimport { ReportFilterOptionsAsk } from '../interfaces/report-filter-options-ask.interface';\nimport { ReportFilterOptionsList } from '../interfaces/report-filter-options-list.interface';\nimport { ReportFilterOptionsRequest } from '../interfaces/report-filter-options-request.interface';\nimport { ReportFilterOptionsStream } from '../interfaces/report-filter-options-stream.interface';\nimport { ReportFilterOptions } from '../interfaces/report-filter-options.interface';\nimport {\n FilterGroupValue, Report, ReportFilter, ReportFilterGroup, ReportFilterOption, ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { isMatchAnyGroup } from '../report-filter-items';\nimport { tileDataState, tilePageId, valuesMatchAnyGroupIds } from '../tile-data-state';\nimport { reportComponents } from '../values';\n\nimport { ReportFilterStateService } from './report-filter-state.service';\n\n\n// The most picks one request asks names for: the server's option cap.\nconst SELECTED_CAP = 500;\n\n// The options a select group's control offers. When the server serves\n// cascadingOptions, a group's list is narrowed by the other entries of its\n// host tile (the narrowed options POST); otherwise it is the full list (the\n// options GET), fetched once per group while its host stays the same. The\n// host is the member whose list the group shows (optionsHost).\n//\n// A list is replayed while its request's signature holds: the host's entries\n// without the group's own, without a cross-filter entry and, while the\n// groups match 'any', without the other groups this one combines with. A new\n// signature fetches again, and a request still in flight for an older one is\n// dropped (switchMap). fs-filter asks on focus and on each keystroke, so a\n// list is fetched on the first of them after a change and replayed for the\n// rest; typing filters the replayed list in the viewer (matchOptions).\n//\n// Every list and every 'selected' answer teaches label() the names of the\n// values it holds, so a pick the narrowed list leaves out keeps its name.\n//\n// Each load of the report (the first, and every reload after a chat or\n// dialog edit) starts again: no list is replayed and no name is kept from an\n// earlier load, so an edit to a tile's source or to an option's name shows on\n// the next ask, as when every bar build fetched its list.\n@Injectable()\nexport class ReportFilterOptionsService {\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _destroyRef = inject(DestroyRef);\n private _streams = new Map<number, ReportFilterOptionsStream>();\n private _labels = new Map<number, Map<string, string>>();\n // The picks each group has asked names for, so a value the server cannot\n // name (its entity was deleted) is asked for once, not on every keystroke.\n private _asked = new Map<number, Set<string>>();\n // The report load the lists and names above belong to (the object init()\n // last read).\n private _loaded: Report | null = null;\n\n // The options the group's control offers now. Nothing is read or sent\n // until the list is subscribed to, so the signature is the one of the\n // moment the control asks.\n public options(group: ReportFilterGroup, report: Report | null): Observable<ReportFilterOptionPair[]> {\n return defer(() => {\n const narrowed = !!report?.viewerFeatures?.includes('cascadingOptions');\n const host = optionsHost(group, narrowed);\n\n if (!host || !report) {\n return of([]);\n }\n\n this._syncLoad();\n const stream = this._stream(group.id);\n const seq = this._ask(stream, group, report, host, narrowed);\n\n return stream.lists$\n .pipe(\n filter((list) => list.seq >= seq),\n take(1),\n map((list) => list.options),\n );\n });\n }\n\n // The name a value of the group was last listed or labeled with in this\n // load of the report, or null when no list or answer has named it yet.\n public label(groupId: number, value: unknown): string | null {\n this._syncLoad();\n\n return this._labels.get(groupId)?.get(String(value)) ?? null;\n }\n\n // Whether the group's latest list was cut at 500.\n public truncated(groupId: number): boolean {\n this._syncLoad();\n\n return this._streams.get(groupId)?.truncated ?? false;\n }\n\n // Whether the group's latest request failed. Its list is then empty, and\n // the next ask fetches again.\n public failed(groupId: number): boolean {\n this._syncLoad();\n\n return this._streams.get(groupId)?.failed ?? false;\n }\n\n // Sends a request when the signature moved, or when a pick has no name\n // yet and was never asked for. Returns the number of the request whose\n // answer the caller takes: the one sent, else the latest.\n private _ask(\n stream: ReportFilterOptionsStream,\n group: ReportFilterGroup,\n report: Report,\n host: ReportFilter,\n narrowed: boolean,\n ): number {\n const body = narrowed ? this._request(group, report, host) : null;\n // The host member is part of it: a report edit that moves the group's\n // list to another member or column lists again.\n const signature = JSON.stringify([host.id, host.filterColumn, body?.filters ?? null, body?.matchAnyGroupIds ?? []]);\n const unnamed = (body?.selected ?? [])\n .filter((value) => this.label(group.id, value) === null && !this._askedFor(group.id).has(String(value)));\n\n if (signature === stream.signature && !unnamed.length) {\n return stream.seq;\n }\n\n unnamed.forEach((value) => this._askedFor(group.id).add(String(value)));\n stream.signature = signature;\n stream.seq += 1;\n stream.requests$.next({ seq: stream.seq, fetch: this._fetch(stream, group.id, report.id, host.id, body) });\n\n return stream.seq;\n }\n\n // The narrowed request for the group: what its host tile's data request\n // carries now, minus the entries that must not narrow the group's list.\n private _request(group: ReportFilterGroup, report: Report, host: ReportFilter): ReportFilterOptionsRequest {\n const tile = reportComponents(report).find((component) => component.id === host.componentId) ?? null;\n const selected = groupPicks(this._filterState.value(group.id));\n\n if (!tile) {\n return { filters: [], ...(selected.length ? { selected } : {}) };\n }\n\n const snapshot = this._filterState.snapshot();\n // A group whose only members are inline values lists through a value,\n // which combines its groups by the tile rule over its own page.\n const matchAnyGroupIds = tile.type === 'value'\n ? valuesMatchAnyGroupIds(report, tilePageId(report, tile, snapshot), snapshot)\n : tileDataState(report, tile, snapshot).matchAnyGroupIds ?? [];\n // Under 'any' another group this one combines with does not limit which\n // of its values can show rows, so the list leaves it out.\n const combined = matchAnyGroupIds.length && isMatchAnyGroup(group, tilePageId(report, tile, snapshot))\n ? matchAnyGroupIds\n : [];\n const groupOf = new Map((tile.filters ?? []).map((member) => [member.id, member.filterGroupId]));\n const filters = this._filterState.resolveForComponent(tile)\n .filter((entry) => {\n const groupId = groupOf.get(entry.filterId) ?? null;\n\n return !isCrossEntry(entry) && groupId !== group.id && !combined.includes(groupId);\n });\n\n return {\n filters,\n ...(matchAnyGroupIds.length ? { matchAnyGroupIds } : {}),\n ...(selected.length ? { selected } : {}),\n };\n }\n\n // One request's answer as a list. A failed request answers an empty list\n // marked failed, and clears the signature, so the next ask fetches again.\n private _fetch(\n stream: ReportFilterOptionsStream,\n groupId: number,\n reportId: number,\n filterId: number,\n body: ReportFilterOptionsRequest | null,\n ): Observable<ReportFilterOptionsList> {\n const seq = stream.seq;\n // An answer that lands after the report loaded again teaches no name.\n const loaded = this._filterState.report();\n const answer$: Observable<ReportFilterOptions> = body\n ? this._reportData.filterOptionsNarrowed(reportId, filterId, body)\n : this._reportData.filterOptions(reportId, filterId)\n .pipe(map((options: ReportFilterOption[]) => ({ options, truncated: false, narrowedBy: [], selected: [] })));\n\n return answer$\n .pipe(\n tap((answer) => {\n if (this._filterState.report() === loaded) {\n this._remember(groupId, [...(answer?.options ?? []), ...(answer?.selected ?? [])]);\n }\n }),\n map((answer) => ({\n seq,\n truncated: !!answer?.truncated,\n failed: false,\n options: (answer?.options ?? []).map((option) => ({ name: option.label, value: option.value })),\n })),\n catchError(() => {\n stream.signature = null;\n\n return of({ seq, truncated: false, failed: true, options: [] });\n }),\n );\n }\n\n // The group's stream, opened on its first ask. It is subscribed to here,\n // for the life of the report view, so an answer is kept for the next ask\n // even when the control that asked has moved on. When the view goes, the\n // stream ends: a request still in flight is dropped, whoever still listens.\n private _stream(groupId: number): ReportFilterOptionsStream {\n const existing = this._streams.get(groupId);\n if (existing) {\n return existing;\n }\n\n const requests$ = new Subject<ReportFilterOptionsAsk>();\n const stream: ReportFilterOptionsStream = {\n signature: null,\n seq: 0,\n truncated: false,\n failed: false,\n requests$,\n lists$: requests$\n .pipe(\n switchMap((request) => request.fetch),\n tap((list) => {\n stream.truncated = list.truncated;\n stream.failed = list.failed;\n }),\n takeUntilDestroyed(this._destroyRef),\n shareReplay({ bufferSize: 1, refCount: false }),\n ),\n };\n\n // Ends with the stream, when the view goes.\n stream.lists$.subscribe();\n this._streams.set(groupId, stream);\n\n return stream;\n }\n\n // A new load of the report (init() read another report object) drops what\n // the last load learned: every signature, so each list is fetched again on\n // its next ask, and every name and asked pick.\n private _syncLoad(): void {\n const loaded = this._filterState.report();\n if (loaded === this._loaded) {\n return;\n }\n\n this._loaded = loaded;\n this._streams.forEach((stream) => {\n stream.signature = null;\n });\n this._labels.clear();\n this._asked.clear();\n }\n\n private _remember(groupId: number, options: ReportFilterOption[]): void {\n const labels = this._labels.get(groupId) ?? new Map<string, string>();\n\n for (const option of options) {\n if (option && typeof option.label === 'string') {\n labels.set(String(option.value), option.label);\n }\n }\n\n this._labels.set(groupId, labels);\n }\n\n private _askedFor(groupId: number): Set<string> {\n const asked = this._asked.get(groupId) ?? new Set<string>();\n this._asked.set(groupId, asked);\n\n return asked;\n }\n}\n\n\n// The member whose list a group shows. The narrowed POST names the server's\n// host: the first enabled member with options, else the first with options.\n// The options GET keeps its older rule, the first member with options, as\n// loadGroupOptions does, so an older server is asked what it always was.\nfunction optionsHost(group: ReportFilterGroup, narrowed: boolean): ReportFilter | null {\n const members = (group.filters ?? []).filter((member) => member.hasOptions);\n\n return (narrowed ? members.find((member) => member.enabled) : null) ?? members[0] ?? null;\n}\n\n// A cross-filter entry rides in the same filters array as the group entries\n// and carries its crossFilterId. It never narrows a list: a click is a\n// temporary look, and the chip of the cross-filter already shows it.\nfunction isCrossEntry(entry: ResolvedFilterValue): boolean {\n return 'crossFilterId' in entry;\n}\n\n// A select group's picks, kept or left out, that a request can name: text\n// and numbers, at most SELECTED_CAP.\nfunction groupPicks(value: FilterGroupValue | undefined): (string | number)[] {\n return [...(value?.values ?? []), ...(value?.excludeValues ?? [])]\n .filter((pick): pick is string | number => typeof pick === 'string' || typeof pick === 'number')\n .slice(0, SELECTED_CAP);\n}\n","// A menu or popover that opens at a point, not at a control. fs-menu opens\n// at its trigger element, never at an event, so the caller keeps one\n// invisible trigger: a zero-size span inside a positioned container (a tile,\n// a text block), moved to the point just before the menu opens. On a phone\n// fs-menu opens as a bottom sheet and the point does not matter.\n//\n// The page may be zoomed (the canvas scales it, --canvas-zoom): a point in\n// page pixels is converted to the container's own unscaled pixels.\n\n// Where the anchor goes inside its container, in the container's unscaled\n// pixels: the point's distance from the container's top left corner (both in\n// page pixels), divided by the zoom.\nexport function anchorOffset(\n point: { x: number; y: number },\n corner: { x: number; y: number },\n zoom: number,\n): { left: number; top: number } {\n const scale = usableZoom(zoom);\n\n return {\n left: (point.x - corner.x) / scale,\n top: (point.y - corner.y) / scale,\n };\n}\n\n// Moves the anchor to the point (in page pixels) inside the element it is\n// positioned against, then opens what it triggers on the next turn: once the\n// move is laid out, and once the click that asked for it is over, so that\n// click does not close it again.\nexport function openAtPoint(\n anchor: HTMLElement,\n point: { x: number; y: number },\n zoom: number,\n open: () => void,\n): void {\n const container = (anchor.offsetParent as HTMLElement | null) ?? anchor.parentElement;\n const rect = container?.getBoundingClientRect();\n // An absolute child is placed from inside its container's border, which\n // the zoom scales too.\n const corner = rect\n ? {\n x: rect.left + window.scrollX + container.clientLeft * usableZoom(zoom),\n y: rect.top + window.scrollY + container.clientTop * usableZoom(zoom),\n }\n : point;\n const offset = anchorOffset(point, corner, zoom);\n\n Object.assign(anchor.style, {\n position: 'absolute',\n width: '0',\n height: '0',\n pointerEvents: 'none',\n left: `${offset.left}px`,\n top: `${offset.top}px`,\n });\n\n setTimeout(open);\n}\n\n// The zoom, or 1 when it is not a positive number.\nfunction usableZoom(zoom: number): number {\n return Number.isFinite(zoom) && zoom > 0 ? zoom : 1;\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\n\nimport { MatButton } from '@angular/material/button';\nimport { MatCheckbox } from '@angular/material/checkbox';\nimport {\n MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef,\n} from '@angular/material/dialog';\n\nimport { FsDialogModule } from '@firestitch/dialog';\n\n\nexport interface ListColumnsDialogData {\n // The list's configured columns, in order, each with the heading it shows.\n columns: { column: string; label: string }[];\n // The names of the columns the viewer has hidden.\n hidden: string[];\n}\n\n\n// Which of a plain list's columns the viewer sees. One checkbox per column,\n// and the last one still checked is disabled, so the list always keeps a\n// column. Done closes with the hidden names, in the list's order; Cancel\n// closes with nothing. Nothing here is validated, so there is no fsForm.\n@Component({\n templateUrl: './list-columns.component.html',\n styleUrls: ['./list-columns.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatButton,\n MatCheckbox,\n MatDialogActions,\n MatDialogClose,\n MatDialogContent,\n FsDialogModule,\n ],\n})\nexport class ListColumnsComponent {\n\n public readonly data = inject<ListColumnsDialogData>(MAT_DIALOG_DATA);\n\n public readonly columns = this.data.columns;\n\n public readonly hidden = signal<ReadonlySet<string>>(new Set(this.data.hidden));\n\n // How many columns are still checked.\n public readonly shownCount = computed(() => this.columns\n .filter((column) => !this.hidden().has(column.column))\n .length);\n\n private readonly _dialogRef = inject<MatDialogRef<ListColumnsComponent, string[]>>(MatDialogRef);\n\n // Whether a column's box is the last one checked, which cannot be cleared.\n public isLastShown(name: string): boolean {\n return this.shownCount() === 1 && !this.hidden().has(name);\n }\n\n public toggle(name: string, shown: boolean): void {\n this.hidden.update((hidden) => {\n const next = new Set(hidden);\n\n if (shown) {\n next.delete(name);\n } else {\n next.add(name);\n }\n\n return next;\n });\n }\n\n public done(): void {\n this._dialogRef.close(this.columns\n .map((column) => column.column)\n .filter((name) => this.hidden().has(name)));\n }\n}\n","<fs-dialog>\n <fs-dialog-title>\n Columns\n </fs-dialog-title>\n <mat-dialog-content>\n <div class=\"fs-column.gap-xs\">\n @for (column of columns; track column.column) {\n <mat-checkbox\n class=\"column-option\"\n [checked]=\"!hidden().has(column.column)\"\n [disabled]=\"isLastShown(column.column)\"\n (change)=\"toggle(column.column, $event.checked)\">\n {{ column.label }}\n </mat-checkbox>\n }\n </div>\n </mat-dialog-content>\n <mat-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"primary\"\n (click)=\"done()\">\n Done\n </button>\n <button\n type=\"button\"\n mat-button\n [mat-dialog-close]=\"undefined\">\n Cancel\n </button>\n </mat-dialog-actions>\n</fs-dialog>\n","// Which way a KPI's change points, as shown: up, down, or flat when the\n// change rounds to zero at the digits the card prints. A flat change draws no\n// arrow.\nexport enum ReportKpiTrend {\n Up = 'up',\n Down = 'down',\n Flat = 'flat',\n}\n","import { ReportChangePolarity } from './enums/report-change-polarity.enum';\nimport { ReportKpiTrend } from './enums/report-kpi-trend.enum';\nimport { ReportValueFormat } from './enums/report-value-format.enum';\nimport {\n formatDayRange, formatDayWindow, formatNumber, formatOutputValue, formatReadingDay, isReadOnOneDay,\n} from './format';\nimport {\n ChartGranularity,\n ComparisonWindow,\n ComponentComparison,\n ComponentData,\n ComponentKpi,\n KpiCardSettings,\n KpiConfig,\n OutputMeta,\n ReportFormatContext,\n ReportLocaleTag,\n} from './interfaces/report.interface';\n\n\n// A sparkline's period and length when its config names neither: monthly,\n// over 12 periods (the server's defaults).\nexport const KPI_SPARKLINE_DEFAULT_GRANULARITY: ChartGranularity = 'month';\nexport const KPI_SPARKLINE_DEFAULT_PERIODS = 12;\n\n\n// What a KPI card shows, decided from its config and its data. The server\n// sends every number (the value, the prior, the change, the target's progress,\n// the sparkline's points) and the note codes; this only formats them and\n// picks the arrow and the color. Pure, so the exports can draw the same card.\n//\n// Without a `kpi` key (a KPI with no comparison, target or sparkline, or an\n// older server) the card is the value and its label, as it always was, plus\n// the timeframe's days when the data has a timeframe.\n\n// The report the card is drawn for: its number format, and the zone a\n// timeframe's cut time reads in (a comparison names its own).\nexport interface KpiCardContext {\n format: ReportFormatContext;\n timezone: string;\n}\n\n// The delta row: the change as shown, the arrow it points (none when the\n// shown change rounds to zero), the color it means under the config's\n// increaseIs, and what it is compared with ('vs $1,139 (Aug 1 – 31, 2026)').\nexport interface KpiCardDelta {\n text: string;\n trend: ReportKpiTrend;\n tone: ReportChangePolarity;\n compared: string;\n}\n\n// The target line: its caption and value ('Goal: 150'), the progress the\n// server computed ('37% of target', '' without one), how much of the bar to\n// fill (0-1, null for no bar) and the bar's color.\nexport interface KpiCardTarget {\n text: string;\n progress: string;\n fill: number | null;\n tone: ReportChangePolarity;\n}\n\n// The sparkline's values, oldest first, and whether the last period is not\n// finished yet.\nexport interface KpiCardSparkline {\n values: (number | null)[];\n partial: boolean;\n}\n\nexport interface KpiCardView {\n value: string;\n label: string;\n delta: KpiCardDelta | null;\n window: string;\n target: KpiCardTarget | null;\n sparkline: KpiCardSparkline | null;\n}\n\n// The sparkline drawn in a 0-100 box on both axes (y down): one polyline per\n// run of values without a gap, a dot for a value with an empty period on both\n// sides, and the last point's marker, hollow when its period is partial.\nexport interface KpiSparklinePoint {\n x: number;\n y: number;\n}\n\nexport interface KpiSparklineGeometry {\n lines: string[];\n dots: KpiSparklinePoint[];\n last: (KpiSparklinePoint & { hollow: boolean }) | null;\n}\n\nconst EMPTY_VALUE = '—';\nconst TARGET_CAPTION = 'Target';\nconst PROGRESS_SPEC = Object.freeze({ format: ReportValueFormat.Percent, precision: 0 });\nconst SPARKLINE_BOX = 100;\n\nexport function kpiCardView(\n config: KpiConfig | null | undefined,\n data: ComponentData | null | undefined,\n context: KpiCardContext,\n): KpiCardView {\n const measure = config?.measure;\n const kpi = data?.kpi ?? null;\n\n return {\n value: formatNumber(kpi ? kpi.value : rowValue(config, data), measure, context.format, { empty: EMPTY_VALUE }),\n label: measure?.label ?? '',\n delta: kpiDelta(config, data, context),\n window: windowLine(data, context),\n target: kpiTarget(config, kpi, context.format),\n sparkline: kpi?.sparkline\n ? { values: (kpi.sparkline.points ?? []).map((point) => point.value), partial: !!kpi.sparkline.partial }\n : null,\n };\n}\n\n// The polyline runs, lone dots and last marker for the values, scaled so the\n// lowest value sits on the bottom edge and the highest on the top one (a flat\n// series runs through the middle).\nexport function kpiSparklineGeometry(values: (number | null)[], partial: boolean): KpiSparklineGeometry {\n const numbers = values.filter((value): value is number => value !== null);\n\n if (!numbers.length) {\n return { lines: [], dots: [], last: null };\n }\n\n const low = Math.min(...numbers);\n const high = Math.max(...numbers);\n const points = values.map((value, index) => value === null ? null : {\n x: values.length === 1 ? SPARKLINE_BOX / 2 : index * SPARKLINE_BOX / (values.length - 1),\n y: high === low ? SPARKLINE_BOX / 2 : (high - value) * SPARKLINE_BOX / (high - low),\n });\n const runs = sparklineRuns(points);\n const lastPoint = points[points.length - 1];\n\n return {\n lines: runs.filter((run) => run.length > 1).map((run) => run.map((point) => `${point.x},${point.y}`).join(' ')),\n dots: runs.filter((run) => run.length === 1 && run[0] !== lastPoint).map((run) => run[0]),\n last: lastPoint ? { ...lastPoint, hollow: partial } : null,\n };\n}\n\nfunction sparklineRuns(points: (KpiSparklinePoint | null)[]): KpiSparklinePoint[][] {\n return points.reduce<KpiSparklinePoint[][]>((runs, point, index) => {\n if (point) {\n if (index === 0 || !points[index - 1]) {\n runs.push([]);\n }\n\n runs[runs.length - 1].push(point);\n }\n\n return runs;\n }, []);\n}\n\n// The one row's value, as the card has always read it: the measure's column,\n// or the row's first column when the config names none.\nfunction rowValue(config: KpiConfig | null | undefined, data: ComponentData | null | undefined): unknown {\n const row = data?.rows?.[0];\n const column = config?.measure?.column ?? Object.keys(row ?? {})[0];\n\n return row?.[column];\n}\n\n// A delta needs a value and a comparison that ran. A missing value shows only\n// the dash; a missing prior shows a dash for the delta, and the note says why.\nfunction kpiDelta(\n config: KpiConfig | null | undefined,\n data: ComponentData | null | undefined,\n context: KpiCardContext,\n): KpiCardDelta | null {\n const kpi = data?.kpi;\n\n if (!kpi || kpi.value === null || !data.comparison || (kpi.prior === null && kpi.note === null)) {\n return null;\n }\n\n const output = deltaOutput(kpi, config);\n const amount = output.role === 'percent_change' ? kpi.percentChange : kpi.change;\n const compared = comparedText(config, data, context);\n\n if (amount === null) {\n return { text: EMPTY_VALUE, trend: ReportKpiTrend.Flat, tone: ReportChangePolarity.Neutral, compared };\n }\n\n const options = { measureSpec: config?.measure ?? null };\n const text = formatOutputValue(amount, output, null, context.format, options).text;\n const zero = formatOutputValue(0, output, null, context.format, options).text;\n const trend = text === zero ? ReportKpiTrend.Flat : (amount > 0 ? ReportKpiTrend.Up : ReportKpiTrend.Down);\n\n return { text, trend, tone: deltaTone(trend, config?.increaseIs), compared };\n}\n\n// The delta the server named, as an output column: the percent change, or the\n// change (in points for a percent measure) when it named that or has no\n// percent change to give (a prior of 0, or a change across zero).\nfunction deltaOutput(kpi: ComponentKpi, config: KpiConfig | null | undefined): OutputMeta {\n const percent = kpi.show === 'percent_change' && kpi.percentChange !== null;\n\n return {\n measure: config?.measure?.column ?? '',\n kind: 'value',\n role: percent ? 'percent_change' : 'change',\n offset: 1,\n window: false,\n rank: null,\n share: null,\n };\n}\n\n// Good news is green and bad news red, whichever way the value moved; a flat\n// change, or a value whose direction means neither, is slate.\nfunction deltaTone(trend: ReportKpiTrend, increaseIs: ReportChangePolarity | null | undefined): ReportChangePolarity {\n const polarity = increaseIs ?? ReportChangePolarity.Good;\n\n if (trend === ReportKpiTrend.Flat || polarity === ReportChangePolarity.Neutral) {\n return ReportChangePolarity.Neutral;\n }\n\n const rise = trend === ReportKpiTrend.Up;\n\n return rise === (polarity === ReportChangePolarity.Good) ? ReportChangePolarity.Good : ReportChangePolarity.Bad;\n}\n\n// 'vs $1,139 (Aug 1 – 31, 2026)': the prior value and its window, either\n// alone when the other is missing. A value read on one day is compared with\n// the value on the prior window's last day: 'vs 20 (on Aug 31, 2026)', or\n// 'vs Aug 31, 2026' with no prior value.\nfunction comparedText(\n config: KpiConfig | null | undefined,\n data: ComponentData,\n context: KpiCardContext,\n): string {\n const comparison = data.comparison;\n const prior = comparison.priors?.[0];\n const value = data.kpi.prior === null ? '' : formatNumber(data.kpi.prior, config?.measure, context.format);\n const days = prior ? priorWindowText(comparison, prior, context.format.locale, !!value) : '';\n\n if (value && days) {\n return `vs ${value} (${days})`;\n }\n\n return value || days ? `vs ${value || days}` : '';\n}\n\n// The prior window in the compared text: its days, or the day its value is\n// read on ('on Aug 31, 2026' beside the value, the bare day without one).\nfunction priorWindowText(\n comparison: ComponentComparison,\n prior: ComparisonWindow,\n locale: ReportLocaleTag,\n withValue: boolean,\n): string {\n if (!isReadOnOneDay(comparison)) {\n return formatDayWindow(prior, comparison.timezone, locale);\n }\n\n return withValue ? formatReadingDay(prior, locale) : formatDayRange(prior.end, prior.end, locale);\n}\n\n// The days the value covers: the comparison's current window, else the\n// timeframe's. A value read on one day names that day ('On Sep 15, 2026').\n// '' when the data has neither.\nfunction windowLine(data: ComponentData | null | undefined, context: KpiCardContext): string {\n const comparison = data?.comparison;\n\n if (comparison?.current) {\n return isReadOnOneDay(comparison)\n ? formatReadingDay(comparison.current, context.format.locale, true)\n : formatDayWindow(comparison.current, comparison.timezone, context.format.locale);\n }\n\n return data?.timeframe ? formatDayWindow(data.timeframe, context.timezone, context.format.locale) : '';\n}\n\n// The target as the server sent it back: its value in the measure's format,\n// and the progress toward it, never computed here. A met target fills green.\nfunction kpiTarget(\n config: KpiConfig | null | undefined,\n kpi: ComponentKpi | null,\n format: ReportFormatContext,\n): KpiCardTarget | null {\n const target = kpi?.target;\n\n if (!target) {\n return null;\n }\n\n const progress = target.progress;\n\n return {\n text: `${target.label || TARGET_CAPTION}: ${formatNumber(target.value, config?.measure, format)}`,\n progress: progress === null ? '' : `${formatNumber(progress, PROGRESS_SPEC, { ...format, ratioPercent: true })} of target`,\n fill: progress === null ? null : Math.min(1, Math.max(0, progress)),\n tone: target.met ? ReportChangePolarity.Good : ReportChangePolarity.Neutral,\n };\n}\n\n\n// A KPI's card keys as its config holds them; an absent key reads null.\nexport function kpiCardSettings(config: KpiConfig | null | undefined): KpiCardSettings {\n return {\n increaseIs: config?.increaseIs ?? null,\n target: config?.target ?? null,\n sparkline: config?.sparkline ?? null,\n };\n}\n\n// Whether two sets of card keys draw the same card. Good and an absent\n// increaseIs are one, as are a null granularity and month, null periods and\n// 12, and an empty target label and none.\nexport function sameKpiCardSettings(a: KpiCardSettings, b: KpiCardSettings): boolean {\n return JSON.stringify(normalizedCardSettings(a)) === JSON.stringify(normalizedCardSettings(b));\n}\n\nfunction normalizedCardSettings(settings: KpiCardSettings): KpiCardSettings {\n const { increaseIs, target, sparkline } = settings;\n\n return {\n increaseIs: increaseIs === ReportChangePolarity.Good ? null : (increaseIs ?? null),\n target: target ? { value: target.value, label: target.label || null } : null,\n sparkline: sparkline\n ? {\n granularity: sparkline.granularity ?? KPI_SPARKLINE_DEFAULT_GRANULARITY,\n periods: sparkline.periods ?? KPI_SPARKLINE_DEFAULT_PERIODS,\n }\n : null,\n };\n}\n","import { ComponentDataDrill } from './interfaces/component-data-drill.interface';\nimport { ReportChartHit } from './interfaces/report-chart-hit.interface';\nimport { ReportDrillStep } from './interfaces/report-drill-step.interface';\nimport { ReportMarkAction } from './interfaces/report-mark-action.type';\nimport { ReportMarkClick } from './interfaces/report-mark-click.interface';\nimport { ReportMarkContext } from './interfaces/report-mark-context.interface';\nimport { ReportMarkDecision } from './interfaces/report-mark-decision.interface';\nimport { ReportMarkEvent } from './interfaces/report-mark-event.interface';\nimport { ReportMarkPoint } from './interfaces/report-mark-point.interface';\nimport {\n ChartConfig,\n ComponentData,\n KpiConfig,\n ReportComponent,\n ReportFormatContext,\n} from './interfaces/report.interface';\nimport {\n chartColumns,\n chartDateLabel,\n extractChartSeries,\n ExtractedChartSeries,\n formatPeriodLabel,\n partialSegmentOwner,\n} from './option-builder';\nimport { isCalendarDay, isChartGranularity } from './report-state';\n\n\n// The one click model (B10): what a click on a tile's mark stands for, and\n// what the tile does with it. Pure, so the node harness runs it.\n//\n// - chartMarkClick and kpiMarkClick turn a click into a ReportMarkClick: the\n// raw values from data.rows (never the drawn text), the clicked series and\n// its number, and the pointer.\n// - markActions lists what the click may do, each only while its feature is\n// offered; decideMarkClick applies the action rule: none does nothing, one\n// runs, two or more open the menu at the mark, and a touch first shows the\n// tooltip and acts on a second tap on the same mark.\n\n// A mark menu row's text, by action.\nexport const MARK_ACTION_LABELS: Record<ReportMarkAction, string> = {\n drill: 'Drill down',\n crossFilter: 'Filter other tiles',\n showRows: 'Show rows',\n};\n\n// Where a click was and what made it. A PointerEvent names its pointer; a\n// TouchEvent is a touch; anything else (a plain MouseEvent, a key press\n// that clicked) reads as the mouse.\nexport function markPointer(event: ReportMarkEvent | null | undefined): ReportMarkClick['pointer'] {\n const touch = event?.changedTouches?.[0];\n let type: ReportMarkClick['pointer']['type'] = touch ? 'touch' : 'mouse';\n\n if (event?.pointerType === 'touch' || event?.pointerType === 'pen' || event?.pointerType === 'mouse') {\n type = event.pointerType;\n }\n\n return {\n x: finite(event?.pageX) ?? finite(touch?.pageX) ?? 0,\n y: finite(event?.pageY) ?? finite(touch?.pageY) ?? 0,\n type,\n };\n}\n\n// A click on a chart: a bar (and its split value), a line or area point or\n// the line itself, a pie slice, a waterfall step, or a category's empty band\n// (with the mouse only: a tap there is how a phone shows the tooltip). A\n// partial segment reads as the series it continues, and a compared series\n// as its category, the current period. null for a reference line or band,\n// a waterfall's base and its Total, and a category the chart does not have.\nexport function chartMarkClick(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n hit: ReportChartHit,\n event: ReportMarkEvent | null | undefined,\n): ReportMarkClick | null {\n const pointer = markPointer(event);\n const extracted = extractChartSeries(component, data);\n const series = hitSeries(component.config as ChartConfig, extracted, hit);\n\n if (series === null || !Number.isInteger(hit.dataIndex)\n || hit.dataIndex < 0 || hit.dataIndex >= extracted.rawCategories.length\n || (series === 'band' && pointer.type !== 'mouse')) {\n return null;\n }\n\n const clicked = series === 'band' ? null : extracted.series[series];\n\n return {\n componentId: component.id,\n points: chartPoints(component, data, context, extracted, hit.dataIndex, series === 'band' ? null : series),\n measure: clicked?.measure.column ?? null,\n value: clicked?.values[hit.dataIndex] ?? null,\n additive: !!(event?.ctrlKey || event?.metaKey),\n pointer,\n };\n}\n\n// A click on a KPI's value: no points, the KPI's measure and its number.\nexport function kpiMarkClick(\n component: ReportComponent,\n data: ComponentData | null,\n event: ReportMarkEvent | null | undefined,\n): ReportMarkClick {\n const config = (component.config ?? {}) as KpiConfig;\n const row = data?.rows?.[0];\n const measure = config.measure?.column ?? Object.keys(row ?? {})[0] ?? null;\n const value = data?.kpi ? data.kpi.value : finite(numeric(measure === null ? undefined : row?.[measure]));\n\n return {\n componentId: component.id,\n points: [],\n measure,\n value: value ?? null,\n additive: !!(event?.ctrlKey || event?.metaKey),\n pointer: markPointer(event),\n };\n}\n\n// What a tile's marks may do on its last answer, before any one mark is\n// clicked: the chart's tooltip hint and its hand pointer read it. Drill\n// down while drill is offered and the answer names a level below.\nexport function tileMarkActions(context: ReportMarkContext): ReportMarkAction[] {\n return context.features.includes('drill') && context.data?.drill?.next ? ['drill'] : [];\n}\n\n// What this click may do: the tile's actions that apply to the clicked mark.\n// Drill down needs a period on the drilled axis, so a KPI's value and a mark\n// off that axis never drill.\nexport function markActions(click: ReportMarkClick, context: ReportMarkContext): ReportMarkAction[] {\n return tileMarkActions(context)\n .filter((action) => action !== 'drill' || drillPoint(click, context.data?.drill) !== null);\n}\n\n// The action rule (B10.2). No action: nothing happens. A touch (or a pen)\n// on a chart's mark first shows its tooltip only, and a second tap on the\n// same mark acts; a KPI's value has no tooltip, so its first tap acts. Then\n// one action runs at once, and two or more open the menu at the mark.\nexport function decideMarkClick(\n click: ReportMarkClick,\n actions: readonly ReportMarkAction[],\n touched: string | null,\n): ReportMarkDecision {\n if (!actions.length) {\n return { outcome: 'none', actions: [], touched: null };\n }\n\n const key = markKey(click);\n if (click.pointer.type !== 'mouse' && click.points.length && touched !== key) {\n return { outcome: 'tooltip', actions: [...actions], touched: key };\n }\n\n return { outcome: actions.length === 1 ? 'run' : 'menu', actions: [...actions], touched: null };\n}\n\n// Which mark a click is on: its tile, its raw values and its series. Two\n// taps are on the same mark when their keys match.\nexport function markKey(click: ReportMarkClick): string {\n return JSON.stringify([\n click.componentId,\n click.points.map((point) => [point.column, point.raw ?? null]),\n click.measure,\n ]);\n}\n\n// The point a drill steps into: the clicked period on the drilled axis, or\n// null when the click has none.\nexport function drillPoint(\n click: ReportMarkClick,\n drill: ComponentDataDrill | null | undefined,\n): ReportMarkPoint | null {\n return drill\n ? click.points.find((point) => point.column === drill.axis && !!point.period) ?? null\n : null;\n}\n\n// The drill path one level down from what the chart shows: the steps the\n// server applied (drill.path), then the clicked period at the level it was\n// clicked at (drill.level), which the chart then shows at drill.next. A step\n// names the period clicked, so the first step is at the chart's top level.\n// null when the chart is at its lowest level or the click has no period.\nexport function drillDownPath(\n drill: ComponentDataDrill | null | undefined,\n click: ReportMarkClick,\n): ReportDrillStep[] | null {\n const point = drillPoint(click, drill);\n\n if (!drill?.next || !point?.period) {\n return null;\n }\n\n return [\n ...drill.path.map((crumb) => ({ level: crumb.level, value: crumb.value })),\n { level: drill.level, value: point.period },\n ];\n}\n\n// The extracted series a hit is on: its index, 'band' for a category's\n// empty band, or null for what is not a mark. An axis chart's partial\n// segment maps to the series it continues; a reference carrier maps to\n// nothing. A waterfall's steps are its second series (the first is the\n// invisible base); a pie's slices its only one.\nfunction hitSeries(config: ChartConfig, extracted: ExtractedChartSeries, hit: ReportChartHit): number | 'band' | null {\n const chartType = config.chartType ?? 'bar';\n\n if (hit.seriesIndex === null) {\n return chartType === 'pie' || chartType === 'donut' ? null : 'band';\n }\n\n if (chartType === 'waterfall') {\n return hit.seriesIndex === 1 && extracted.series.length ? 0 : null;\n }\n\n if (hit.seriesIndex >= 0 && hit.seriesIndex < extracted.series.length) {\n return chartType === 'pie' || chartType === 'donut' ? 0 : hit.seriesIndex;\n }\n\n const owner = chartType === 'pie' || chartType === 'donut' ? null : partialSegmentOwner(hit.seriesId);\n\n return owner !== null && owner < extracted.series.length ? owner : null;\n}\n\n// The clicked category, then the split value when the chart splits by\n// another column than its axis (a colorBy chart's series are its categories).\nfunction chartPoints(\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n extracted: ExtractedChartSeries,\n dataIndex: number,\n series: number | null,\n): ReportMarkPoint[] {\n const config = component.config as ChartConfig;\n const { xColumn, groupColumn } = chartColumns(config, data);\n const points = [categoryPoint(config, data, context, extracted, xColumn, dataIndex)];\n\n if (series !== null && groupColumn && groupColumn !== xColumn) {\n points.push({ column: groupColumn, raw: extracted.rawGroups[series], label: extracted.series[series].name });\n }\n\n return points;\n}\n\n// The category as the rows hold it and as the axis wrote it. On a time axis\n// it also gives the period's first day and the grain, and reads as the\n// tooltip names it ('January 2026'); a pie writes its slices as they come.\nfunction categoryPoint(\n config: ChartConfig,\n data: ComponentData,\n context: ReportFormatContext,\n extracted: ExtractedChartSeries,\n column: string,\n dataIndex: number,\n): ReportMarkPoint {\n const raw = extracted.rawCategories[dataIndex];\n const label = extracted.categories[dataIndex];\n const grain = isChartGranularity(data.granularity) ? data.granularity : null;\n const period = grain && raw !== null && raw !== undefined ? String(raw).slice(0, 10) : '';\n\n if (!grain || !isCalendarDay(period)) {\n return { column, raw, label };\n }\n\n const pie = config.chartType === 'pie' || config.chartType === 'donut';\n\n return {\n column,\n raw,\n label: pie ? label : formatPeriodLabel(String(raw), grain, true, context.locale, chartDateLabel(config)),\n period,\n grain,\n };\n}\n\n// A number as a cell holds it (a number or numeric text), else null.\nfunction numeric(value: unknown): number | null {\n if (value === null || value === undefined || value === '') {\n return null;\n }\n\n return Number(value);\n}\n\n// A finite number, else null.\nfunction finite(value: number | null | undefined): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n","import { Observable, catchError, filter, map, merge, of, switchMap, timer } from 'rxjs';\n\nimport { TileLoadResult } from './interfaces/tile-load-result.interface';\n\n\n// A sweep of changes (a few filters set in a row, every value of a picked\n// saved filter) settles for this long before a tile refetches, so the sweep costs one\n// request, not one per change.\nexport const TILE_REFRESH_DEBOUNCE_MS = 300;\n\n// A tile's data as one stream: the first load at once, then one load per\n// settled burst of refresh triggers.\n//\n// - Each trigger starts over (switchMap): it cancels the wait for the one\n// before it and the request in flight, then waits for the sweep to settle.\n// So an answer to an older request never lands, not even while the next\n// load still waits, and the bar stays on until the settled load answers.\n// - Each load notes the state version it was sent under (stateVersion), and\n// its answer is dropped when the version has moved since. resetToDefaults()\n// moves the version and announces a full change together, so the load for the new state is already on its way.\n// - A failed load ends only itself: its message comes through as the answer,\n// and the next trigger loads again.\nexport function tileLoads<T>(\n refresh$: Observable<unknown>,\n load: () => Observable<T>,\n version: () => number,\n): Observable<TileLoadResult<T>> {\n return merge(of(0), refresh$.pipe(map(() => TILE_REFRESH_DEBOUNCE_MS)))\n .pipe(\n switchMap((wait) => (wait ? timer(wait) : of(0))\n .pipe(\n switchMap(() => oneLoad(load, version)),\n )),\n );\n}\n\n// One request: its answer, or its failure as a message, dropped when the\n// state version moved while it was out.\nfunction oneLoad<T>(load: () => Observable<T>, version: () => number): Observable<TileLoadResult<T>> {\n const sentAt = version();\n\n return load()\n .pipe(\n map((data): TileLoadResult<T> => ({ data, error: null })),\n catchError((error: unknown) => of<TileLoadResult<T>>({ data: null, error: loadErrorMessage(error) })),\n filter(() => version() === sentAt),\n );\n}\n\n// What a failed request says: the server's message, else the error's own,\n// else a plain fallback.\nfunction loadErrorMessage(error: unknown): string {\n const failure = error as { error?: { message?: unknown }; message?: unknown } | null;\n const message = failure?.error?.message ?? failure?.message;\n\n return typeof message === 'string' && message ? message : 'Failed to load data';\n}\n","import {\n comparisonNoteText,\n comparisonOffsetLabel,\n formatDayRange,\n formatDayWindow,\n formatReadingDay,\n isReadOnOneDay,\n kpiNoteText,\n windowNoteText,\n windowText,\n} from './format';\nimport {\n ComparisonOffset,\n ComparisonWindow,\n ComponentComparison,\n ComponentData,\n ComponentKpi,\n OutputMeta,\n OutputRole,\n ReportLocaleTag,\n WindowMeta,\n} from './interfaces/report.interface';\n\n\n// The notes a component shows about the numbers it draws: which days a\n// comparison compares, why it reads as it does, and how its windowed values\n// were computed. The server sends windows, fields and codes; every sentence is\n// worded here, through format.ts, in English with the days in the report's\n// locale. A component whose data carries none of those keys has no note.\n\n// The ComponentData keys a note reads.\nexport type ComponentNoteData = Pick<\n ComponentData,\n 'comparison' | 'timeframe' | 'outputs' | 'cellMeasures' | 'windows' | 'granularity' | 'kpi'\n>;\n\n// The report the note is written for: its locale, and the zone a timeframe's\n// cut time reads in (a comparison names its own).\nexport interface ComponentNoteContext {\n locale: ReportLocaleTag;\n timezone: string;\n}\n\n// Which parts of the note a component shows. Omitted, a part is shown, except\n// the window descriptions, which a chart's tooltips and a list's headers carry\n// instead.\nexport interface ComponentNoteParts {\n // The days the component reads: its comparison's current and prior windows,\n // else its timeframe's days.\n windows?: boolean;\n // What each windowed value is ('Rolling 3-month total, Sep 1 – 30, 2026').\n windowDescriptions?: boolean;\n // Why the windowed values read as they do.\n windowNotes?: boolean;\n}\n\n// Between the current window and each prior one on the windows line.\nconst WINDOWS_SEPARATOR = ' · ';\n\n// Ranks and shares are computed after the viewer's filters, never before.\nconst FILTERED_ROWS_SENTENCE = 'Computed over the rows the filters keep.';\n\nconst ROLE_LEADS: Record<OutputRole, string> = {\n current: 'Value',\n prior: 'Prior value',\n change: 'Change',\n percent_change: 'Percent change',\n};\n\n// The note's lines, in order: the windows, then the comparison's notes and a\n// KPI's delta note, then the windowed values' descriptions and notes. A line is never repeated (two\n// windowed values often share a note). Empty when the data has none of the\n// keys, or none of the parts asked for.\nexport function componentNoteLines(\n data: ComponentNoteData | null | undefined,\n context: ComponentNoteContext,\n parts: ComponentNoteParts = {},\n): string[] {\n if (!data) {\n return [];\n }\n\n const lines = [\n parts.windows === false ? '' : componentWindowsLine(data, context),\n ...comparisonNotes(data.comparison),\n kpiNote(data.kpi, data.comparison),\n ...(parts.windowDescriptions ? windowDescriptions(data, context.locale) : []),\n ...(parts.windowNotes === false ? [] : windowNotes(data, context.locale)),\n ];\n\n return [...new Set(lines.filter((line) => !!line))];\n}\n\n// What one output column holds, for its header's tooltip: the windows a\n// compared value covers, a rank's or a share's scope, and how a windowed value\n// was computed. A cross-tab cell column reads its measure's meaning through\n// cellMeasures. '' for a plain column.\nexport function outputColumnNote(\n column: string,\n data: ComponentNoteData | null | undefined,\n locale: ReportLocaleTag,\n): string {\n const alias = data?.cellMeasures?.[column] ?? column;\n const output = data?.outputs?.[alias];\n\n if (!output) {\n return '';\n }\n\n return [\n comparisonSentence(output, data.comparison, locale),\n rankSentence(output, data.outputs),\n shareSentence(output, data.outputs),\n windowSentences(data.windows?.[alias], locale, data),\n ]\n .filter((sentence) => !!sentence)\n .join(' ');\n}\n\n// 'Sep 1 – 15, 2026 · vs previous month: Aug 1 – 15, 2026'. A comparison\n// with no current window yet has no line (its no_window note says so); a\n// component without a comparison shows its timeframe's days. '' when the data\n// has neither. The note's first line, and the PDF and PowerPoint exports'\n// subtitle under a chart's or a list's title.\nexport function componentWindowsLine(data: ComponentNoteData, context: ComponentNoteContext): string {\n const comparison = data.comparison;\n\n if (comparison) {\n return comparison.current ? comparisonWindowsLine(comparison, comparison.current, context.locale) : '';\n }\n\n return data.timeframe ? formatDayWindow(data.timeframe, context.timezone, context.locale) : '';\n}\n\n// Read on one day, the line names the days the values are read on: 'On Sep\n// 15, 2026 · vs previous month: Aug 31, 2026'.\nfunction comparisonWindowsLine(\n comparison: ComponentComparison,\n currentWindow: ComparisonWindow,\n locale: ReportLocaleTag,\n): string {\n if (isReadOnOneDay(comparison)) {\n const priors = (comparison.offsets ?? []).map((offset, index) => {\n const prior = comparison.priors?.[index];\n const day = prior ? formatDayRange(prior.end, prior.end, locale) : '';\n\n return day ? `${comparisonOffsetLabel(offset)}: ${day}` : comparisonOffsetLabel(offset);\n });\n\n return [formatReadingDay(currentWindow, locale, true), ...priors]\n .filter((part) => !!part)\n .join(WINDOWS_SEPARATOR);\n }\n\n const current = formatDayWindow(currentWindow, comparison.timezone, locale);\n const priors = (comparison.offsets ?? []).map((offset, index) => {\n return priorWindowText(offset, comparison.priors?.[index], comparison.timezone, locale);\n });\n\n return [current, ...priors]\n .filter((part) => !!part)\n .join(WINDOWS_SEPARATOR);\n}\n\n// One prior lane: 'vs previous month: Aug 1 – 15, 2026', or its label alone\n// when the server sends no window for it.\nfunction priorWindowText(\n offset: ComparisonOffset,\n prior: ComparisonWindow | undefined,\n timezone: string,\n locale: ReportLocaleTag,\n): string {\n const label = comparisonOffsetLabel(offset);\n const days = prior ? formatDayWindow(prior, timezone, locale) : '';\n\n return days ? `${label}: ${days}` : label;\n}\n\nfunction comparisonNotes(comparison: ComponentComparison | null | undefined): string[] {\n return (comparison?.notes ?? []).map((code) => comparisonNoteText(code, comparison));\n}\n\n// Why a KPI card's delta reads as it does ('No baseline: the previous period\n// has no data.'), naming the baseline by what the first lane compares against.\nfunction kpiNote(\n kpi: ComponentKpi | null | undefined,\n comparison: ComponentComparison | null | undefined,\n): string {\n return kpi?.note ? kpiNoteText(kpi.note, comparison?.offsets?.[0]?.against) : '';\n}\n\n// One line per windowed value, named by its column when there are several.\nfunction windowDescriptions(data: ComponentNoteData, locale: ReportLocaleTag): string[] {\n const windows = Object.entries(data.windows ?? {});\n\n return windows.map(([alias, meta]) => {\n const text = windowText(meta, locale, data.granularity);\n\n return windows.length > 1 ? `${alias}: ${text}` : text;\n });\n}\n\nfunction windowNotes(data: ComponentNoteData, locale: ReportLocaleTag): string[] {\n return Object.values(data.windows ?? {})\n .flatMap((meta) => (meta.notes ?? []).map((code) => windowNoteText(code, meta, locale, data.granularity)));\n}\n\n// A compared column's windows. In range mode every row compares the same two\n// windows, so they are named, and read on one day the days the values are\n// read on are; over a series or a spine of periods each row compares its own\n// period, so only the lane is.\nfunction comparisonSentence(\n output: OutputMeta,\n comparison: ComponentComparison | null | undefined,\n locale: ReportLocaleTag,\n): string {\n if (!output.role || !comparison) {\n return '';\n }\n\n const offset = comparison.offsets?.[(output.offset ?? 1) - 1] ?? null;\n const current = comparison.current ? formatDayWindow(comparison.current, comparison.timezone, locale) : '';\n const priorWindow = comparison.priors?.[(output.offset ?? 1) - 1];\n const prior = priorWindow ? formatDayWindow(priorWindow, comparison.timezone, locale) : '';\n\n if (comparison.mode === 'range' && current && (output.role === 'current' || prior)) {\n return rangeSentence(output.role, current, prior, offset);\n }\n\n if (isReadOnOneDay(comparison) && comparison.current && priorWindow) {\n return readingDaySentence(output.role, comparison.current, priorWindow, offset, locale);\n }\n\n return output.role === 'current' || !offset ? '' : `${ROLE_LEADS[output.role]} ${comparisonOffsetLabel(offset)}.`;\n}\n\nfunction rangeSentence(role: OutputRole, current: string, prior: string, offset: ComparisonOffset | null): string {\n switch (role) {\n case 'current':\n return `Value for ${current}.`;\n case 'prior':\n return offset ? `Prior value for ${prior} (${comparisonOffsetLabel(offset)}).` : `Prior value for ${prior}.`;\n default:\n return `${ROLE_LEADS[role]} from ${prior} to ${current}.`;\n }\n}\n\n// A column of a comparison read on one day, named by the days its values are\n// read on: 'Prior value on Aug 31, 2026 (vs previous month).'\nfunction readingDaySentence(\n role: OutputRole,\n currentWindow: ComparisonWindow,\n priorWindow: ComparisonWindow,\n offset: ComparisonOffset | null,\n locale: ReportLocaleTag,\n): string {\n const current = formatReadingDay(currentWindow, locale);\n const prior = formatReadingDay(priorWindow, locale);\n\n switch (role) {\n case 'current':\n return `Value ${current}.`;\n case 'prior':\n return offset ? `Prior value ${prior} (${comparisonOffsetLabel(offset)}).` : `Prior value ${prior}.`;\n default:\n return `${ROLE_LEADS[role]} from the value ${prior} to the value ${current}.`;\n }\n}\n\n// 'Rank by Revenue, 1 being the largest, within each Region. Tied values share\n// a rank (1, 1, 3).' A measure written as its own rank ranks by the value it\n// would otherwise show, so it names no other measure ('Rank, 1 being the\n// largest, across all rows.').\nfunction rankSentence(output: OutputMeta, outputs: Record<string, OutputMeta> | null | undefined): string {\n const rank = output.kind === 'rank' ? output.rank : null;\n\n if (!rank) {\n return '';\n }\n\n const end = rank.direction === 'asc' ? 'smallest' : 'largest';\n const scope = rank.within?.length ? `within each ${joinNames(rank.within)}` : 'across all rows';\n const ties = rank.method === 'dense' ? '1, 1, 2' : '1, 1, 3';\n const by = isOwnOutput(output, outputs) ? '' : ` by ${output.measure}`;\n\n return `Rank${by}, 1 being the ${end}, ${scope}. Tied values share a rank (${ties}). `\n + FILTERED_ROWS_SENTENCE;\n}\n\n// 'Share of the total Revenue within each Region.' A measure written as its\n// own share names no other measure ('Share of the total within each\n// Region.', 'Share of the total across all rows.').\nfunction shareSentence(output: OutputMeta, outputs: Record<string, OutputMeta> | null | undefined): string {\n const share = output.kind === 'share' ? output.share : null;\n\n if (!share) {\n return '';\n }\n\n if (isOwnOutput(output, outputs)) {\n const scope = share.within?.length ? `within each ${joinNames(share.within)}` : 'across all rows';\n\n return `Share of the total ${scope}. ${FILTERED_ROWS_SENTENCE}`;\n }\n\n const scope = share.within?.length ? ` within each ${joinNames(share.within)}` : '';\n\n return `Share of the total ${output.measure}${scope}. ${FILTERED_ROWS_SENTENCE}`;\n}\n\n// Whether a rank or a share is its measure's own output: the server writes a\n// measure with a rank or a share as that rank or share, so its measure is a\n// column of the same kind (itself, or for a prior or a change the current\n// column), never a value of its own to name.\nfunction isOwnOutput(output: OutputMeta, outputs: Record<string, OutputMeta> | null | undefined): boolean {\n return outputs?.[output.measure]?.kind === output.kind;\n}\n\n// A windowed column: what it is, then why it reads as it does.\nfunction windowSentences(\n meta: WindowMeta | undefined,\n locale: ReportLocaleTag,\n data: ComponentNoteData,\n): string {\n if (!meta) {\n return '';\n }\n\n const notes = (meta.notes ?? []).map((code) => windowNoteText(code, meta, locale, data.granularity));\n\n return [`${windowText(meta, locale, data.granularity)}.`, ...notes].join(' ');\n}\n\n// 'Region', 'Region and Channel', 'Region, Channel and Plan'.\nfunction joinNames(names: string[]): string {\n return names.length > 1\n ? `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`\n : names.join('');\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\n\nimport { ComponentNoteData, componentNoteLines } from '../../output-notes';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\n\n\n// The small print under a chart or a KPI and above a list: which days a\n// comparison compares, why it reads as it does, and how its windowed values\n// were computed (output-notes.ts words it). Shared by the chart, KPI and list\n// components; it renders nothing when the data carries none of those keys, so\n// a component without them looks exactly as it did.\n@Component({\n selector: 'app-report-component-note',\n templateUrl: './component-note.component.html',\n styleUrls: ['./component-note.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class ComponentNoteComponent {\n\n public readonly data = input<ComponentNoteData | null>(null);\n\n // The comparison's (or the timeframe's) days. A component that prints its\n // own window line turns it off.\n public readonly windows = input(true);\n\n // What each windowed value is: for a component with no tooltip or header to\n // carry it, as a KPI.\n public readonly windowDescriptions = input(false);\n\n // Why the windowed values read as they do. A list puts them in its column\n // headers' tooltips instead.\n public readonly windowNotes = input(true);\n\n public readonly lines = computed(() => componentNoteLines(\n this.data(),\n { locale: this._filterState.formatContext().locale, timezone: this._filterState.timezone() },\n { windows: this.windows(), windowDescriptions: this.windowDescriptions(), windowNotes: this.windowNotes() },\n ));\n\n private readonly _filterState = inject(ReportFilterStateService);\n}\n","<!-- One line each, cut to the tile's width; the title holds the whole line. -->\n@for (line of lines(); track line) {\n <div\n class=\"note-line small\"\n [attr.title]=\"line\">\n {{ line }}\n </div>\n}\n","import {\n ChangeDetectionStrategy, Component, NgZone, computed, inject, input, model, output, untracked,\n} from '@angular/core';\n\nimport type { ECElementEvent, EChartsOption, ECharts, ElementEvent } from 'echarts';\nimport { NgxEchartsDirective } from 'ngx-echarts';\n\nimport { ChartConfig, ComponentData, ReportComponent } from '../../interfaces/report.interface';\nimport { ReportChartHit } from '../../interfaces/report-chart-hit.interface';\nimport { ReportMarkAction } from '../../interfaces/report-mark-action.type';\nimport { ReportMarkClick } from '../../interfaces/report-mark-click.interface';\nimport { ReportMarkEvent } from '../../interfaces/report-mark-event.interface';\nimport { chartMarkClick } from '../../mark-click';\nimport { buildChartOption } from '../../option-builder';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { ComponentNoteComponent } from '../component-note/component-note.component';\n\n\n// ECharts host for a chart component. Pure rendering: the parent owns the\n// data fetch; this maps (component config, rows, the open report's format\n// context) → option and exposes the chart instance for resize + the future\n// image exports (getDataURL needs the canvas renderer registered in\n// theme/echarts.ts). The shared note under the plot names the days a\n// comparison compares and why windowed series read as they do; the series'\n// tooltips describe the windows themselves.\n//\n// A click on a mark (a bar, a point or the line, a slice, a step, or a\n// category's empty band) is reported as a ReportMarkClick (markClick); the\n// tile decides what it does. The tile's actions only shape the option: the\n// hand pointer and the tooltip's hint.\n@Component({\n selector: 'app-report-component-chart',\n templateUrl: './component-chart.component.html',\n styleUrls: ['./component-chart.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n ComponentNoteComponent,\n NgxEchartsDirective,\n ],\n})\nexport class ComponentChartComponent {\n\n public readonly component = input.required<ReportComponent>();\n public readonly data = input<ComponentData | null>(null);\n // Which legend entries are on, by series name. The tile holds it (two-way),\n // so it outlives this chart and every option: each new option carries it\n // (legend.selected), because ngx-echarts sets an option with notMerge. A\n // click on the legend only records it: the chart has already toggled the\n // series, so the option is not built again for it (untracked).\n public readonly legendSelected = model<Readonly<Record<string, boolean>>>({});\n // What a click on the chart's marks does, from the tile (tileMarkActions).\n public readonly actions = input<readonly ReportMarkAction[]>([]);\n\n public readonly markClick = output<ReportMarkClick>();\n // A click or a tap on the chart that no mark answered (an empty band by\n // touch, outside the plot, a waterfall's Total): the tile forgets a tap\n // it was holding, so the next tap on a mark shows its tooltip first.\n public readonly markMiss = output<void>();\n\n public readonly options = computed<EChartsOption | null>(() => {\n const data = this.data();\n\n return data\n ? buildChartOption(\n this.component(),\n data,\n this._filterState.formatContext(),\n untracked(this.legendSelected),\n this.actions(),\n )\n : null;\n });\n\n private _chart: ECharts | null = null;\n // The browser event of the last click a mark answered, so the empty-band\n // handler skips that event.\n private _markEvent: unknown = null;\n private readonly _filterState = inject(ReportFilterStateService);\n private readonly _zone = inject(NgZone);\n\n public onChartInit(chart: ECharts): void {\n this._chart = chart;\n // A click in a category's empty band is no element's click: the chart's\n // drawing surface reports it. ECharts runs it outside Angular, and\n // before the chart's own click on a mark (ECharts calls its element\n // handler last), so it waits a microtask: by then a mark has answered\n // the same click.\n chart.getZr().on('click', (event: ElementEvent) => {\n queueMicrotask(() => this._zone.run(() => this._onBandClick(event)));\n });\n }\n\n // ECharts reports every entry of the legend after a click.\n public onLegendSelectChanged(event: { selected?: Record<string, boolean> } | null): void {\n this.legendSelected.set({ ...(event?.selected ?? {}) });\n }\n\n // A click on a series element. A click on a line or an area's line itself\n // carries no category, so it takes the category whose band it fell in, and\n // no series id, so it takes the id the option gave that series (a partial\n // segment's id names the series it continues).\n public onChartClick(params: ECElementEvent): void {\n this._markEvent = params.event?.event ?? null;\n\n if (params.componentType !== 'series') {\n this.markMiss.emit();\n\n return;\n }\n\n const seriesIndex = params.seriesIndex ?? null;\n const dataIndex = typeof params.dataIndex === 'number'\n ? params.dataIndex\n : this._bandIndex(params.event?.offsetX, params.event?.offsetY);\n\n this._emit(\n { seriesIndex, seriesId: params.seriesId ?? this._seriesId(seriesIndex), dataIndex: dataIndex ?? -1 },\n params.event?.event,\n );\n }\n\n // Called by the canvas when the box is resized in edit mode.\n public resize(): void {\n this._chart?.resize();\n }\n\n // High-res image for the (later-phase) PPT/PDF exports.\n public getDataURL(pixelRatio = 3): string | null {\n return this._chart?.getDataURL({\n type: 'png',\n pixelRatio,\n backgroundColor: '#ffffff',\n }) ?? null;\n }\n\n // A click on the chart that no element answered: the category whose band\n // it fell in. Outside the plot it is a miss.\n private _onBandClick(event: ElementEvent): void {\n if (event.event === this._markEvent) {\n return;\n }\n\n this._emit(\n { seriesIndex: null, seriesId: null, dataIndex: this._bandIndex(event.offsetX, event.offsetY) ?? -1 },\n event.event,\n );\n }\n\n // The category index under a point of the chart, read off the category\n // axis (the y axis of a horizontal chart); null outside the plot or on a\n // chart without one. An axis finder takes the one coordinate along its\n // axis, not the point.\n private _bandIndex(x: number | undefined, y: number | undefined): number | null {\n const chart = this._chart;\n\n if (!chart || typeof x !== 'number' || typeof y !== 'number' || !chart.containPixel('grid', [x, y])) {\n return null;\n }\n\n const horizontal = (this.component().config as ChartConfig)?.orientation === 'horizontal';\n const index = Number(horizontal\n ? chart.convertFromPixel({ yAxisIndex: 0 }, y)\n : chart.convertFromPixel({ xAxisIndex: 0 }, x));\n\n return Number.isFinite(index) ? Math.round(index) : null;\n }\n\n // The id the option gave a drawn series, by its index.\n private _seriesId(seriesIndex: number | null): string | null {\n const series = this.options()?.series;\n const id = Array.isArray(series) && seriesIndex !== null ? series[seriesIndex]?.id : null;\n\n return id === null || id === undefined ? null : String(id);\n }\n\n private _emit(hit: ReportChartHit, event: unknown): void {\n const data = this.data();\n const click = data\n ? chartMarkClick(this.component(), data, this._filterState.formatContext(), hit, event as ReportMarkEvent)\n : null;\n\n if (click) {\n this.markClick.emit(click);\n } else {\n this.markMiss.emit();\n }\n }\n}\n","<div\n class=\"chart-host\"\n echarts\n [options]=\"options() ?? {}\"\n [theme]=\"'report'\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n (chartLegendSelectChanged)=\"onLegendSelectChanged($event)\">\n</div>\n<app-report-component-note [data]=\"data()\"></app-report-component-note>\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { signal } from '@angular/core';\n\nimport { StreamEvent, StreamEventType } from '@firestitch/api';\nimport { GridField, GridParams, GridRequest, GridResult, GridSource } from '@firestitch/grid';\n\nimport { EMPTY, Observable, catchError, concatWith, defer, mergeMap, of, throwError } from 'rxjs';\n\nimport { REPORT_FALLBACK_LOCALE } from '../format';\nimport { ReportGridLine } from '../interfaces/report-grid-line.interface';\nimport { ReportGridParams } from '../interfaces/report-grid-params.interface';\nimport { ReportGridReport } from '../interfaces/report-grid-report.interface';\nimport { ComponentDataState, ReportLocaleTag } from '../interfaces/report.interface';\nimport { outputColumnNote } from '../output-notes';\n\nimport { ReportData } from './report.data';\n\n\n// What a failed read says when the server gave no message of its own.\nconst READ_FAILED = 'Failed to load data';\n\n// A stream that ended before its summary was cut off on the way: the parts\n// it brought may be short, so the read counts as failed.\nconst STREAM_CUT = 'The table\\'s answer was cut off. Try again.';\n\n// How a grid source is built: `isExport` marks every read as part of a PDF or\n// PowerPoint render, which the server gives its export ceiling; `locale` is\n// the report's, which an output field's description is written in.\nexport interface ReportGridSourceOptions {\n isExport?: boolean;\n locale?: () => ReportLocaleTag;\n}\n\n// One grid tile's rows, read through the report: fs-grid asks, and each ask\n// is one componentGrid request. The params (ReportGridParams) are mapped onto\n// the request body's own names: the report filters go to `filters`, the 'any'\n// groups and the grain to `state`.\n//\n// The answer streams. Its report line is held in `report`, so output cells\n// format and the note strip fills from the first paint; each grid line is\n// passed on as one part, its output fields described as today's header\n// tooltip describes them (outputColumnNote); the envelope's summary is the\n// last part. A stream that ends without its summary is a failure.\n//\n// Every failure reaches the grid as an Error carrying the server's message:\n// a streamed request shows no error dialog of its own, so the grid's error\n// state is where it is read.\nexport class ReportGridSource implements GridSource {\n\n // The report line of the latest read, null until one arrives.\n public readonly report = signal<ReportGridReport | null>(null);\n // The summary of the latest read (its version and notes), null until one\n // arrives.\n public readonly summary = signal<GridResult | null>(null);\n\n private readonly _isExport: boolean;\n private readonly _locale: () => ReportLocaleTag;\n\n constructor(\n private readonly _reportData: ReportData,\n private readonly _reportId: number,\n private readonly _componentId: number,\n options: ReportGridSourceOptions = {},\n ) {\n this._isExport = options.isExport ?? false;\n this._locale = options.locale ?? (() => REPORT_FALLBACK_LOCALE);\n }\n\n public read(request: GridRequest, params: GridParams): Observable<GridResult> {\n return defer(() => {\n let summary: GridResult | null = null;\n\n return this._stream$(request, params as ReportGridParams)\n .pipe(\n mergeMap((event) => {\n if (event.type === StreamEventType.Complete) {\n summary = envelopeSummary(event) ?? summary;\n\n return EMPTY;\n }\n\n return this._part$(event.data);\n }),\n concatWith(defer(() => {\n if (!summary) {\n return throwError(() => new Error(STREAM_CUT));\n }\n this.summary.set(summary);\n\n return of(summary);\n })),\n catchError((error: unknown) => throwError(() => readError(error))),\n );\n });\n }\n\n private _stream$(request: GridRequest, params: ReportGridParams): Observable<StreamEvent> {\n return this._reportData.componentGrid(\n this._reportId,\n this._componentId,\n params.filters ?? [],\n requestState(params),\n request,\n this._isExport,\n );\n }\n\n // One data line: the report line is held, a grid line is passed on as a\n // part, and every other line is skipped.\n private _part$(data: unknown): Observable<GridResult> {\n const line = data as ReportGridLine | null;\n\n if (line?.report) {\n this.report.set(line.report);\n\n return EMPTY;\n }\n\n return line?.grid ? of(this._described(line.grid)) : EMPTY;\n }\n\n // A part whose fields say what each output holds, as today's header\n // tooltip says it. A field the report says nothing of keeps its own.\n private _described(part: GridResult): GridResult {\n if (!part.fields?.length) {\n return part;\n }\n\n const report = this.report();\n const locale = this._locale();\n\n return {\n ...part,\n fields: part.fields.map((field: GridField) => {\n const note = outputColumnNote(field.name, report, locale);\n\n return note ? { ...field, description: note } : field;\n }),\n };\n }\n\n}\n\n// The tile state the data request carries for a grid: the 'any' groups and\n// the grain, each only when set.\nfunction requestState(params: ReportGridParams): ComponentDataState {\n return {\n ...(params.matchAnyGroupIds?.length ? { matchAnyGroupIds: [...params.matchAnyGroupIds] } : {}),\n ...(params.frequency ? { frequency: params.frequency } : {}),\n };\n}\n\n// The read's summary from the envelope that closes the stream\n// ({data: {data: {grid}}, code}), or null for the bare end-of-response event.\nfunction envelopeSummary(event: StreamEvent): GridResult | null {\n return event.data?.data?.data?.grid ?? null;\n}\n\n// Any failure as an Error: the server's message when it sent one.\nfunction readError(error: unknown): Error {\n if (error instanceof HttpErrorResponse) {\n const message = error.error?.message;\n\n return new Error(typeof message === 'string' && message ? message : READ_FAILED);\n }\n\n return error instanceof Error ? error : new Error(READ_FAILED);\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { GridField } from '@firestitch/grid';\n\nimport { FormattedOutputValue, formatOutputValue, laneOutputAlias } from '../../format';\nimport { ReportGridReport } from '../../interfaces/report-grid-report.interface';\nimport { ReportFormatContext } from '../../interfaces/report.interface';\n\n\n// A detail cell of an output field (a prior, a change, a % change, a rank)\n// as a list writes it: a change reads its prior beside it on the line, so a\n// missing baseline reads '—' and a zero one 'n/a', and the cell's title says\n// why, as the list's hover does. A value it holds keeps the grid's own text\n// (its placement's format); a rank change is written whole, since a new rank\n// reads apart from an unranked line. Every other cell is the grid's text,\n// with no title.\n@Pipe({\n name: 'fsReportGridCell',\n standalone: true,\n})\nexport class ReportGridCellPipe implements PipeTransform {\n\n // The cell's raw value, its field, its line's record (absent on a group or\n // total row) and the grid's own text, from the fsGridCell context.\n public transform(\n value: unknown,\n field: GridField | null,\n record: Record<string, unknown> | undefined,\n text: string,\n report: ReportGridReport | null,\n format: ReportFormatContext,\n ): FormattedOutputValue {\n const name = field?.name ?? '';\n const output = record ? report?.outputs?.[name] : null;\n if (!output || !record) {\n return { text, title: null };\n }\n\n const priorAlias = output.role === 'change' || output.role === 'percent_change'\n ? laneOutputAlias(report?.outputs, name, 'prior')\n : null;\n const formatted = formatOutputValue(value, output, null, format, {\n ...(priorAlias ? { prior: record[priorAlias] } : {}),\n floor: report?.comparison?.floor ?? null,\n empty: '',\n });\n const isMissing = value === null || value === undefined || value === '';\n\n return { text: isMissing || output.kind === 'rank' ? formatted.text : text, title: formatted.title };\n }\n\n}\n","import {\n GridDetail, GridField, GridFieldType, GridFormat, GridFormatter, GridLevel, GridUnits, GridValue,\n} from '@firestitch/grid';\n\nimport { ReportChartDateLabel } from '../../enums/report-chart-date-label.enum';\nimport { ReportNumberUnits } from '../../enums/report-number-units.enum';\nimport { ReportValueFormat } from '../../enums/report-value-format.enum';\nimport { formatNumber, formatOutputValue, formatReportDate, numberFormat } from '../../format';\nimport { ReportGridReport } from '../../interfaces/report-grid-report.interface';\nimport { ChartGranularity, NumberFormatSpec, ReportFormatContext } from '../../interfaces/report.interface';\nimport { formatPeriodLabel } from '../../option-builder';\nimport { GRID_GRANULARITIES } from '../../report-grid-layout';\n\n\ntype GridPlacement = GridValue | GridDetail | GridLevel;\n\n// What a grid tile is written with: the report's locale, currency and\n// percent form, the zone its instants read in, and the report line of its\n// latest read (what each output field holds).\nexport interface ReportGridFormatContext {\n format: ReportFormatContext;\n timezone: string;\n report: ReportGridReport | null;\n}\n\nconst VALUE_FORMATS: Readonly<Record<GridFormat, ReportValueFormat>> = {\n [GridFormat.Number]: ReportValueFormat.Number,\n [GridFormat.Percent]: ReportValueFormat.Percent,\n [GridFormat.Currency]: ReportValueFormat.Currency,\n};\n\nconst NUMBER_UNITS: Readonly<Record<GridUnits, ReportNumberUnits>> = {\n [GridUnits.None]: ReportNumberUnits.None,\n [GridUnits.Thousands]: ReportNumberUnits.Thousands,\n [GridUnits.Millions]: ReportNumberUnits.Millions,\n [GridUnits.Auto]: ReportNumberUnits.Auto,\n};\n\n// What an abbreviated number's suffix multiplies it by, when a viewer types one.\nconst UNIT_SUFFIXES: Readonly<Record<string, number>> = { k: 1e3, m: 1e6 };\n\nconst YES = 'Yes';\nconst NO = 'No';\n\n// A grid tile's formatter: every value written as the report writes it on\n// a list today. An output number reads through formatOutputValue with what\n// the report line says the output holds (a change is signed, a missing prior\n// reads as the list's dash); a plain number through formatNumber; a key's\n// digits as they are; a date at its grain in the report's locale, an instant\n// in its zone. The placement's format, precision and units win over the\n// field's.\nexport function reportGridFormatter(context: ReportGridFormatContext): GridFormatter {\n return {\n format: (value, field, placement) => formatGridValue(context, value, field, placement),\n toNumber: (text, field, placement) => readGridNumber(context, text, field, placement),\n };\n}\n\nfunction formatGridValue(\n context: ReportGridFormatContext,\n value: unknown,\n field: GridField,\n placement?: GridPlacement,\n): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n switch (field.type) {\n case GridFieldType.Number:\n return formatGridNumber(context, value, field, placement);\n case GridFieldType.Date:\n return formatGridDate(context, value, field, placement);\n case GridFieldType.Datetime:\n return formatReportDate(value, context.timezone, context.format.locale);\n case GridFieldType.Boolean:\n return value ? YES : NO;\n default:\n return optionLabel(value, field) ?? String(value);\n }\n}\n\nfunction formatGridNumber(\n context: ReportGridFormatContext,\n value: unknown,\n field: GridField,\n placement?: GridPlacement,\n): string {\n // A key, such as a client's id, is a name: its digits print as they are, never grouped\n if (field.identifier && !isAggregate(placement)) {\n return String(value);\n }\n\n const spec = numberSpec(field, placement);\n const output = isAggregate(placement) ? null : context.report?.outputs?.[field.name];\n\n return output\n ? formatOutputValue(value, output, spec, context.format).text\n : formatNumber(value, spec, context.format);\n}\n\n// A calendar date at the grain it prints at: the placement's, else the\n// field's own, which on a time axis is the report's group-by. A quarter reads\n// \"Q3 2023\", a month \"Jul 2023\" and a year \"2023\", as the report's charts\n// label them, rather than as their first day; a week, like a chart's, reads as\n// the day it starts. A day reads as the report writes a date.\nfunction formatGridDate(\n context: ReportGridFormatContext,\n value: unknown,\n field: GridField,\n placement?: GridPlacement,\n): string {\n const granularity = (placement as GridDetail | GridLevel | undefined)?.granularity ?? field.granularities?.[0];\n const chartGranularity = (Object.keys(GRID_GRANULARITIES) as ChartGranularity[])\n .find((name) => GRID_GRANULARITIES[name] === granularity);\n\n return chartGranularity && chartGranularity !== 'day' && typeof value === 'string'\n ? formatPeriodLabel(value.slice(0, 10), chartGranularity, false, context.format.locale, ReportChartDateLabel.Long)\n : formatReportDate(value, context.timezone, context.format.locale);\n}\n\n// The format, precision and units a number is written with: the placement's,\n// else the field's.\nfunction numberSpec(field: GridField, placement?: GridPlacement): NumberFormatSpec {\n const placed = placement as GridValue | GridDetail | undefined;\n const format = placed?.format ?? field.format;\n const precision = placed?.precision ?? field.precision;\n const units = placed?.units ?? field.units;\n\n return {\n ...(format ? { format: VALUE_FORMATS[format] } : {}),\n ...(typeof precision === 'number' ? { precision } : {}),\n ...(units ? { units: NUMBER_UNITS[units] } : {}),\n };\n}\n\n// A value placement is an aggregate of the field, not the output itself.\nfunction isAggregate(placement?: GridPlacement): boolean {\n return !!(placement as GridValue | undefined)?.aggregation;\n}\n\nfunction optionLabel(value: unknown, field: GridField): string | null {\n return field.options?.find((option) => option.key === value)?.label ?? null;\n}\n\n// A number a viewer typed, read in the report's locale: its grouping dropped,\n// its decimal mark read, a K or M suffix multiplied out, and a percent of a\n// ratio-percent report read back to its ratio. null when it is no number.\nfunction readGridNumber(\n context: ReportGridFormatContext,\n text: string,\n field: GridField,\n placement?: GridValue | GridDetail,\n): number | null {\n const decimal = decimalMark(context.format.locale);\n const trimmed = text.trim().toLowerCase();\n const multiplier = UNIT_SUFFIXES[trimmed.slice(-1)] ?? 1;\n const digits = trimmed\n .split(decimal).map((part) => part.replace(/[^0-9-]/g, '')).join('.');\n const number = digits && digits !== '-' && digits !== '.' ? Number(digits) * multiplier : NaN;\n\n if (!Number.isFinite(number)) {\n return null;\n }\n\n const isPercent = (placement?.format ?? field.format) === GridFormat.Percent;\n\n return isPercent && context.format.ratioPercent ? number / 100 : number;\n}\n\nfunction decimalMark(locale: string): string {\n return numberFormat(locale, {}).formatToParts(1.5).find((part) => part.type === 'decimal')?.value ?? '.';\n}\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, Injector, OnInit, computed, effect, inject, input, signal, untracked,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { FsGridCellDirective, FsGridComponent, GridExpansion, GridLayout, GridNote } from '@firestitch/grid';\nimport { FsPopoverDirective } from '@firestitch/popover';\n\nimport { Observable, filter, map, of, switchMap, tap, timer } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportGridSource } from '../../data/report-grid-source';\nimport { followsGroupBy } from '../../group-by';\nimport { ReportGridParams } from '../../interfaces/report-grid-params.interface';\nimport { ReportComponent } from '../../interfaces/report.interface';\nimport { authoredGridLayout, prunedGridLayout } from '../../report-grid-layout';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { TILE_REFRESH_DEBOUNCE_MS } from '../../tile-loads';\nimport { ComponentNoteComponent } from '../component-note/component-note.component';\n\nimport { ReportGridCellPipe } from './report-grid-cell.pipe';\nimport { reportGridFormatter } from './report-grid-formatter';\n\n\n// A grid tile: fs-grid over the tile's rows, read through ReportGridSource.\n//\n// - The params (the report filters the tile resolves to and the 'any'\n// groups) are seeded before the first render, so no read goes out without\n// them. After that a change to one of the tile's filter groups settles for\n// TILE_REFRESH_DEBOUNCE_MS, so a sweep of changes costs one read; one sent\n// under an older state version is dropped.\n// - The layout on screen is the state service's (gridLayout): the viewer's\n// own while they changed it from the layout authored now, else the\n// authored one. It outlives a page switch, and the chat reads it. So do\n// the groups the viewer left open (gridExpansion), which a Clear leaves.\n// - A state version move (Clear filters, a saved filter) skips the wait; the\n// reset has put the authored layout back in the same tick, so it costs one\n// read.\n// - A table that follows the report's group-by (followsGroupBy) sends its\n// grain, and reads again at once when it changes. The state service has\n// moved its filter on the group-by's field to the new grain by then, or\n// taken it out (clearedFilter, which the status line names), so one read\n// goes out and nothing paints unfiltered.\n// - fs-grid compares the layout and params by value: a cloned value never\n// reads again.\n// - An output's detail cell is drawn by fsReportGridCell, so a change tells\n// a missing prior from a zero one, as a list does; a click on it opens\n// why, as no cell carries a native tooltip.\n// - After the tile's first read, the viewer's layout loses the filters and\n// sort terms that read refused (prunedGridLayout), so stale tile state\n// (a field the AI took out of the query) does not linger.\n@Component({\n selector: 'app-report-component-grid',\n templateUrl: './component-grid.component.html',\n styleUrls: ['./component-grid.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FsGridComponent,\n FsGridCellDirective,\n FsPopoverDirective,\n ComponentNoteComponent,\n ReportGridCellPipe,\n ],\n})\nexport class ComponentGridComponent implements OnInit {\n\n public readonly reportId = input.required<number>();\n public readonly component = input.required<ReportComponent>();\n\n public readonly params = signal<ReportGridParams | null>(null);\n public readonly controls = computed(() => this.component().config?.controls ?? {});\n public readonly source = computed(() => new ReportGridSource(this._reportData, this.reportId(), this._componentId(), {\n locale: () => this._filterState.formatContext().locale,\n }));\n\n public readonly layout = computed(() => this._filterState.gridLayout(this.component()));\n public readonly clearedFilter = computed(() => this._filterState.gridClearedFilter(this.component()));\n // Read once: fs-grid owns the open groups from then on and writes them out.\n public readonly expansion = signal<GridExpansion | undefined>(undefined);\n\n public readonly noteData = computed(() => this.source().report());\n public readonly formatContext = computed(() => this._filterState.formatContext());\n public readonly formatter = computed(() => reportGridFormatter({\n format: this._filterState.formatContext(),\n timezone: this._filterState.timezone(),\n report: this.source().report(),\n }));\n\n private readonly _componentId = computed(() => this.component().id);\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _destroyRef = inject(DestroyRef);\n private _injector = inject(Injector);\n // Whether the first read's notes have pruned the viewer's layout.\n private _isPruned = false;\n // The state version the params on screen were read under.\n private _paramsVersion = 0;\n\n public ngOnInit(): void {\n this.expansion.set(this._filterState.gridExpansion(this.component()));\n this._init();\n this._pruneAfterFirstRead();\n }\n\n public setLayout(layout: GridLayout): void {\n this._filterState.setGridLayout(this.component(), layout);\n }\n\n public setExpansion(expansion: GridExpansion | undefined): void {\n this._filterState.setGridExpansion(this.component(), expansion);\n }\n\n private _init(): void {\n this._paramsVersion = this._filterState.stateVersion();\n this.params.set(this._readParams());\n\n this._filterState.changesFor(this.component())\n .pipe(\n switchMap(() => this._settled$()),\n tap(() => this._applyParams()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n\n if (followsGroupBy(this.component())) {\n this._filterState.frequencyChanges()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._applyParams());\n }\n }\n\n // Once the tile's first read is in, its notes prune the viewer's layout\n // (prunedGridLayout). A tile showing its authored layout has nothing to\n // prune.\n private _pruneAfterFirstRead(): void {\n effect(() => {\n const summary = this.source().summary();\n if (!summary || this._isPruned) {\n return;\n }\n\n this._isPruned = true;\n untracked(() => this._prune(summary.notes ?? []));\n }, { injector: this._injector, allowSignalWrites: true });\n }\n\n private _prune(notes: GridNote[]): void {\n const component = this.component();\n const session = this._filterState.gridSessionLayout(component);\n if (!session) {\n return;\n }\n\n const pruned = prunedGridLayout(session, notes, this.controls().filter, authoredGridLayout(component).filters);\n if (pruned !== session) {\n this._filterState.setGridLayout(component, pruned);\n }\n }\n\n // A change, once it has settled: at once when the state version moved,\n // else after the debounce; dropped when the version moves while it waits,\n // since that move brings its own change.\n private _settled$(): Observable<void> {\n const version = this._filterState.stateVersion();\n const moved = version !== this._paramsVersion;\n\n return (moved ? of(0) : timer(TILE_REFRESH_DEBOUNCE_MS))\n .pipe(\n filter(() => this._filterState.stateVersion() === version),\n map(() => undefined),\n );\n }\n\n private _applyParams(): void {\n this._paramsVersion = this._filterState.stateVersion();\n this.params.set(this._readParams());\n }\n\n // The tile's report filters, 'any' groups and group-by grain as they stand\n // (tileState()).\n private _readParams(): ReportGridParams {\n const component = this.component();\n const { matchAnyGroupIds, frequency } = this._filterState.tileState(component);\n\n return {\n filters: this._filterState.resolveForComponent(component),\n ...(matchAnyGroupIds?.length ? { matchAnyGroupIds } : {}),\n ...(frequency ? { frequency } : {}),\n };\n }\n\n}\n","<!-- The comparison and window note strip above the table, from the report\n line of the latest read; the windows' descriptions and notes go in each\n column's \"About this column\" instead. -->\n<div class=\"fs-column grid-pane\">\n <app-report-component-note\n [data]=\"noteData()\"\n [windowNotes]=\"false\">\n </app-report-component-note>\n <!-- The params are seeded before the first render, so the grid's first read\n carries the tile's report filters. -->\n @if (params(); as params) {\n <fs-grid\n class=\"fs-flex\"\n [source]=\"source()\"\n [layout]=\"layout()\"\n [expansion]=\"expansion()\"\n [clearedFilter]=\"clearedFilter()\"\n (expansionChange)=\"setExpansion($event)\"\n [params]=\"params\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n <ng-template fsGridCell let-value let-field=\"field\" let-record=\"record\" let-text=\"text\">\n @if (value | fsReportGridCell: field : record : text : noteData() : formatContext(); as shown) {\n <!-- A cell that says why (a missing or zero prior) opens it on a\n click; no cell carries a native tooltip. -->\n @if (shown.title) {\n <span\n class=\"explained\"\n fsPopover\n trigger=\"click\"\n [template]=\"explanation\"\n [indication]=\"false\"\n [maxWidth]=\"320\">\n {{ shown.text }}\n </span>\n <ng-template #explanation>{{ shown.title }}</ng-template>\n } @else {\n <span>{{ shown.text }}</span>\n }\n }\n </ng-template>\n </fs-grid>\n }\n</div>\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\n\nimport { kpiSparklineGeometry } from '../../../../kpi-card';\n\n\n// A KPI's trend over its last periods: a line that stretches to the card's\n// width, broken where a period has no value, with the last point marked\n// (hollow while its period is still running). The markers are drawn over the\n// line rather than in it, so they stay round however the line is stretched.\n@Component({\n selector: 'app-component-kpi-sparkline',\n templateUrl: './sparkline.component.html',\n styleUrls: ['./sparkline.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class SparklineComponent {\n\n public readonly values = input<(number | null)[]>([]);\n public readonly partial = input(false);\n\n public readonly geometry = computed(() => kpiSparklineGeometry(this.values(), this.partial()));\n}\n","<svg\n class=\"sparkline-lines\"\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"none\">\n @for (line of geometry().lines; track $index) {\n <polyline [attr.points]=\"line\"></polyline>\n }\n</svg>\n@for (dot of geometry().dots; track $index) {\n <span\n class=\"sparkline-marker\"\n [style.left.%]=\"dot.x\"\n [style.top.%]=\"dot.y\">\n </span>\n}\n@if (geometry().last; as last) {\n <span\n class=\"sparkline-marker\"\n [class.hollow]=\"last.hollow\"\n [style.left.%]=\"last.x\"\n [style.top.%]=\"last.y\">\n </span>\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, output } from '@angular/core';\n\nimport { ReportChangePolarity } from '../../enums/report-change-polarity.enum';\nimport { ReportKpiTrend } from '../../enums/report-kpi-trend.enum';\nimport { ComponentData, KpiConfig, ReportComponent } from '../../interfaces/report.interface';\nimport { ReportMarkClick } from '../../interfaces/report-mark-click.interface';\nimport { kpiCardView } from '../../kpi-card';\nimport { kpiMarkClick } from '../../mark-click';\nimport { componentNoteLines } from '../../output-notes';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { REPORT_KPI_CHANGE_COLORS, REPORT_KPI_SPARKLINE_COLOR } from '../../theme/palette';\nimport { REPORT_KPI_VALUE_FONT_SIZE } from '../../theme/typography';\nimport { DEFAULT_TEXT_COLOR } from '../../text';\nimport { ComponentNoteComponent } from '../component-note/component-note.component';\n\nimport { SparklineComponent } from './components/sparkline/sparkline.component';\n\n\n// A single big number: the component's measure aggregated over all (filtered)\n// rows server-side, in the open report's format context (its locale, its\n// currency, and whether a percent arrives as a 0-1 ratio or, from an older\n// server, already x100). With a comparison, a target or a sparkline the server\n// sends every other number the card shows too (ComponentData.kpi); kpi-card.ts\n// decides what each line says, and this only lays them out, in order: the\n// value and its label, the delta, the days, the target and the trend, then the\n// note.\n//\n// The palette's colors and the value's size arrive as custom properties from\n// the same constants the exports draw with. A host page overrides a color by\n// setting --report-kpi-good-color, --report-kpi-bad-color,\n// --report-kpi-neutral-color or --report-kpi-sparkline-color around the report.\n@Component({\n selector: 'app-report-component-kpi',\n templateUrl: './component-kpi.component.html',\n styleUrls: ['./component-kpi.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n ComponentNoteComponent,\n SparklineComponent,\n ],\n host: {\n '[style.--report-kpi-value-size]': 'tokens.valueSize',\n '[style.--report-kpi-text-default]': 'tokens.text',\n '[style.--report-kpi-good-default]': 'tokens.good',\n '[style.--report-kpi-bad-default]': 'tokens.bad',\n '[style.--report-kpi-neutral-default]': 'tokens.neutral',\n '[style.--report-kpi-sparkline-default]': 'tokens.sparkline',\n },\n})\nexport class ComponentKpiComponent {\n\n public readonly component = input.required<ReportComponent>();\n public readonly data = input<ComponentData | null>(null);\n\n // A click on the value, as a mark with no points (kpiMarkClick); the tile\n // decides what it does.\n public readonly markClick = output<ReportMarkClick>();\n\n public readonly ReportKpiTrend = ReportKpiTrend;\n\n public readonly tokens = {\n valueSize: `${REPORT_KPI_VALUE_FONT_SIZE}px`,\n text: DEFAULT_TEXT_COLOR,\n good: `#${REPORT_KPI_CHANGE_COLORS[ReportChangePolarity.Good]}`,\n bad: `#${REPORT_KPI_CHANGE_COLORS[ReportChangePolarity.Bad]}`,\n neutral: `#${REPORT_KPI_CHANGE_COLORS[ReportChangePolarity.Neutral]}`,\n sparkline: `#${REPORT_KPI_SPARKLINE_COLOR}`,\n };\n\n // Read off the component on every data change rather than through a memo of\n // the config: a settings save repaints the same component object with new\n // KPI keys, then reloads its data.\n public readonly view = computed(() => kpiCardView(\n (this.component().config ?? {}) as KpiConfig,\n this.data(),\n { format: this._filterState.formatContext(), timezone: this._filterState.timezone() },\n ));\n\n // The note sits under the card only when it has something to say, so an\n // empty one takes no room.\n public readonly hasNote = computed(() => componentNoteLines(\n this.data(),\n { locale: this._filterState.formatContext().locale, timezone: this._filterState.timezone() },\n { windows: false, windowDescriptions: true },\n ).length > 0);\n\n private readonly _filterState = inject(ReportFilterStateService);\n\n public onValueClick(event: MouseEvent): void {\n this.markClick.emit(kpiMarkClick(this.component(), this.data(), event));\n }\n}\n","@let card = view();\n<div class=\"kpi fs-column.gap-xs.align-center.justify-center\">\n <div\n class=\"kpi-value\"\n (click)=\"onValueClick($event)\">{{ card.value }}</div>\n @if (card.label) {\n <div class=\"kpi-label small\">{{ card.label }}</div>\n }\n @if (card.delta; as delta) {\n <div class=\"kpi-delta fs-row.gap-xs.align-baseline.justify-center.wrap\">\n <span\n class=\"kpi-change\"\n [attr.data-tone]=\"delta.tone\">\n @if (delta.trend !== ReportKpiTrend.Flat) {\n <svg\n class=\"kpi-arrow\"\n [class.down]=\"delta.trend === ReportKpiTrend.Down\"\n viewBox=\"0 0 10 10\">\n <polygon points=\"5,1 9.5,9 0.5,9\"></polygon>\n </svg>\n }\n {{ delta.text }}\n </span>\n @if (delta.compared) {\n <span class=\"small\">{{ delta.compared }}</span>\n }\n </div>\n }\n @if (card.window) {\n <div class=\"kpi-line small\">{{ card.window }}</div>\n }\n @if (card.target; as target) {\n <div class=\"kpi-target fs-column.gap-xs.align-center\">\n <div class=\"kpi-line small\">\n {{ target.text }}\n @if (target.progress) {\n · {{ target.progress }}\n }\n </div>\n @if (target.fill !== null) {\n <div\n class=\"kpi-progress\"\n [attr.data-tone]=\"target.tone\">\n <div\n class=\"kpi-progress-fill\"\n [style.width.%]=\"target.fill * 100\">\n </div>\n </div>\n }\n </div>\n }\n @if (card.sparkline; as sparkline) {\n <app-component-kpi-sparkline\n class=\"kpi-sparkline\"\n [values]=\"sparkline.values\"\n [partial]=\"sparkline.partial\">\n </app-component-kpi-sparkline>\n }\n <!-- The card prints its own days, so the note leaves them out. A KPI has no\n tooltip, so its note also says what a windowed value is. -->\n @if (hasNote()) {\n <app-report-component-note\n [data]=\"data()\"\n [windows]=\"false\"\n [windowDescriptions]=\"true\">\n </app-report-component-note>\n }\n</div>\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { formatReportDate } from '../format';\nimport { ReportLocaleTag } from '../interfaces/report.interface';\n\n\n// A report row's date cell as the calendar day in the report's zone, written in\n// the report's locale. Use it in place of Angular's DatePipe, which reads a\n// 'YYYY-MM-DD HH:MM:SS' value as the browser's local wall time instead of the\n// UTC instant it is, and writes in the browser's language.\n@Pipe({\n name: 'fsReportDate',\n standalone: true,\n})\nexport class ReportDatePipe implements PipeTransform {\n\n public transform(value: unknown, timezone: string, locale: ReportLocaleTag): string {\n return formatReportDate(value, timezone, locale);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { formatNumber, hasNumberFormat } from '../format';\nimport { NumberFormatSpec, ReportFormatContext } from '../interfaces/report.interface';\n\n\n// A list cell in its column's number format, in the report's locale and\n// currency; an empty value reads ''. A column without number-format keys\n// prints its value as it came, as a cell always has, so an id or a year is\n// never grouped ('2,026').\n@Pipe({\n name: 'fsReportNumber',\n standalone: true,\n})\nexport class ReportNumberPipe implements PipeTransform {\n\n public transform(value: unknown, column: NumberFormatSpec, context: ReportFormatContext): string {\n if (hasNumberFormat(column)) {\n return formatNumber(value, column, context, { empty: '' });\n }\n\n return value === null || value === undefined ? '' : String(value);\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\nimport { FormattedOutputValue, formatOutputValue } from '../format';\nimport { ListColumn, ReportFormatContext } from '../interfaces/report.interface';\nimport { ListOutputColumn } from '../list-config';\n\n\n// A list cell (or a totals cell) of an output column, written by what it holds:\n// a prior or a change in its measure's format, a signed percent change, a\n// change of a rate in points, a rank as a whole number, a share as a percent.\n// It reads the whole row, since a change looks up its prior beside it to tell\n// a missing baseline ('—') from a zero one ('n/a'). An empty value reads ''.\n@Pipe({\n name: 'fsReportOutput',\n standalone: true,\n})\nexport class ReportOutputPipe implements PipeTransform {\n\n public transform(\n row: Record<string, unknown> | null | undefined,\n column: ListColumn,\n output: ListOutputColumn,\n context: ReportFormatContext,\n ): FormattedOutputValue {\n return formatOutputValue(row?.[column.column], output.output, column, context, {\n measureSpec: output.measureSpec,\n prior: output.priorAlias && row ? row[output.priorAlias] : undefined,\n floor: output.floor,\n empty: '',\n });\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n AfterRenderRef,\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n Injector,\n OnInit,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsListComponent, FsListConfig, FsListModule, PaginationStrategy } from '@firestitch/list';\n\nimport { Observable, map, merge, tap } from 'rxjs';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportListColumnFormat } from '../../enums/report-list-column-format.enum';\nimport { formatPlainNumber, hasNumberFormat } from '../../format';\nimport {\n ComponentData,\n ComponentDataState,\n ListColumn,\n ListConfig,\n ReportComponent,\n ReportSort,\n} from '../../interfaces/report.interface';\nimport {\n LIST_TOTAL_LABEL,\n ListOutputColumn,\n columnClasses,\n listOutputColumns,\n listPinnedColumns,\n listSortTerms,\n listTotalsLabelColumn,\n} from '../../list-config';\nimport { pivotColumnSpecs } from '../../option-builder';\nimport { ComponentNoteData, outputColumnNote } from '../../output-notes';\nimport { ReportDatePipe } from '../../pipes/report-date.pipe';\nimport { ReportNumberPipe } from '../../pipes/report-number.pipe';\nimport { ReportOutputPipe } from '../../pipes/report-output.pipe';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { ComponentNoteComponent } from '../component-note/component-note.component';\n\n\n// A list component: an FsList rendered from the component's config. It has no\n// filter bar of its own: its filters are group-keyed like every other\n// component's, so component-level groups render in the component header strip\n// (ReportComponentComponent) and report-level groups in the report bar, and\n// every request takes its values from the shared filter-state service.\n// Paging and sorting are pushed into the SQL wrap server-side.\n//\n// A list whose query compares, windows, ranks or shares says so: the shared\n// note above it names the windows a comparison compares, each such column's\n// header tooltip says what it holds, and its cells (totals included, which the\n// server computes) are written by what they hold.\n@Component({\n selector: 'app-report-component-list',\n templateUrl: './component-list.component.html',\n styleUrls: ['./component-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n ComponentNoteComponent,\n FsListModule,\n MatTooltip,\n NgTemplateOutlet,\n ReportDatePipe,\n ReportNumberPipe,\n ReportOutputPipe,\n ],\n})\nexport class ComponentListComponent implements OnInit {\n\n public readonly reportId = input.required<number>();\n public readonly component = input.required<ReportComponent>();\n\n public readonly listComponent = viewChild(FsListComponent);\n\n public listConfig: FsListConfig;\n\n // A plain list's columns are authored and fixed at init. A cross-tab's are\n // the pivot dimension's VALUES, so they arrive with the rows and change\n // whenever the filters do — which is why this is a signal rather than the\n // one-shot read it used to be. `numeric` marks a column whose cells are\n // formatted numbers, decided once here rather than per cell, so the column\n // and its header are right-aligned.\n public columns = signal<(ListColumn & { numeric: boolean })[]>([]);\n\n // A cross-tab sorts only by its row-key column: every other header is a\n // pivot value, and the server orders the long rows before pivoting, so a\n // click on \"Mar 2026\" has nothing to order by.\n public pivoted = signal(false);\n\n // A cut result is worse for a grid than for a list: the cut lands on the LONG\n // rows before the reshape, so a pivot value living only in the tail vanishes\n // as a whole COLUMN and straddled cells come back blank, indistinguishable\n // from a real zero. The parent's truncation banner never fires for a list\n // (it only renders what _load() fetched, which lists skip), so the warning\n // belongs here.\n public truncated = signal(false);\n\n // Why the search box did not narrow the rows (the list has no text column to\n // search), from the latest page 1; null when the search applied or none was\n // made.\n public readonly searchNote = signal<string | null>(null);\n\n // config.totals, read once at init: a list with totals renders its columns\n // with a footer template, which fs-list reads only when it builds them.\n public readonly showTotals = signal(false);\n\n // The totals row from the latest page 1, raw values keyed like the columns;\n // null when the list has none, or the server says why in totalsNote.\n public readonly totals = signal<Record<string, unknown> | null>(null);\n\n public readonly totalsNote = signal<string | null>(null);\n\n // The latest page 1's comparison windows, timeframe and output metadata, for\n // the note above the list, the header tooltips and the output cells; null\n // until it arrives, and empty of every key for a list that has none.\n public readonly noteData = signal<ComponentNoteData | null>(null);\n\n // How many rows the list shows (load more appends) out of how many its\n // filters keep. A cross-tab counts grid rows.\n public readonly rowCount = signal<{ shown: number; total: number } | null>(null);\n\n // The report's effective zone, which date cells render in. Injected right\n // here rather than read off _filterState, which is declared further down and\n // is still undefined while this initializer runs.\n public readonly timezone = inject(ReportFilterStateService).timezone;\n\n // The open report's format context: date cells, number cells and a\n // cross-tab's period headings are written in its locale (and money in its\n // currency). Injected here for the same reason.\n public readonly formatContext = inject(ReportFilterStateService).formatContext;\n\n public readonly ReportListColumnFormat = ReportListColumnFormat;\n\n // How many leading columns stay in view while the list scrolls sideways.\n public readonly pinned = computed(() => listPinnedColumns(this.component().config));\n\n public readonly columnClasses = columnClasses;\n\n // The config columns the viewer hid on this list (the Columns dialog). fs-list\n // hides and shows them in place through [show], so the rows\n // already fetched stand.\n public readonly hidden = computed(() => new Set(this._filterState.hiddenColumns(this.component().id)));\n\n public readonly totalLabel = LIST_TOTAL_LABEL;\n\n // The columns that hold a compared, windowed, ranked or shared output, by\n // name; the rest are written as before.\n public readonly outputColumns = computed<Record<string, ListOutputColumn>>(() => listOutputColumns(\n this.columns(),\n this.noteData(),\n ((this.component().config ?? {}) as ListConfig).columns ?? [],\n ));\n\n // Each column's header tooltip: what an output column holds ('' for any\n // other).\n public readonly columnNotes = computed<Record<string, string>>(() => {\n const locale = this.formatContext().locale;\n\n return Object.fromEntries(this.columns()\n .map((column) => [column.column, outputColumnNote(column.column, this.noteData(), locale)]));\n });\n\n // The column whose footer cell reads 'Total': the first one shown, unless\n // it holds a total itself.\n public readonly totalsLabelColumn = computed(() => listTotalsLabelColumn(\n this.columns().filter((column) => !this.hidden().has(column.column)),\n this.totals(),\n ));\n\n // The line under the list: its row count, then why it has no totals and why\n // its search narrowed nothing. The digits are written in the report's\n // locale, never the app's.\n public readonly caption = computed(() => {\n const count = this.rowCount();\n const locale = this.formatContext().locale;\n const parts: string[] = [];\n\n if (count) {\n const total = formatPlainNumber(count.total, locale);\n parts.push(count.shown < count.total\n ? `Showing ${formatPlainNumber(count.shown, locale)} of ${total}`\n : `${total} row(s)`);\n }\n\n return [...parts, this.totalsNote(), this.searchNote()]\n .filter((part): part is string => !!part)\n .join(' · ');\n });\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _destroyRef = inject(DestroyRef);\n private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private _injector = inject(Injector);\n private _pinOffsetsRef: AfterRenderRef | null = null;\n\n constructor() {\n // Hiding or showing a column moves the pinned columns after it.\n effect(() => {\n this.hidden();\n untracked(() => this._schedulePinOffsets());\n });\n }\n\n public ngOnInit(): void {\n const component = this.component();\n const config = (component.config ?? {}) as ListConfig;\n this.pivoted.set(!!config.pivotBy?.column);\n this.showTotals.set(config.totals === true);\n this.columns.set((config.columns ?? []).map((column) => ({ ...column, numeric: hasNumberFormat(column) })));\n\n this._initListConfig(config);\n this._observePinOffsets();\n\n // A change to any group this list's filters belong to (from the report bar\n // or the component header strip) re-runs the list.\n // So does a change of the text in its search box (in the component header).\n merge(this._filterState.changesFor(component), this._filterState.listSearchChanges(component.id))\n .pipe(\n tap(() => this.listComponent()?.reload()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n private _initListConfig(config: ListConfig): void {\n // The viewer's last sort wins over the authored one, so a list recreated\n // in the same session (page switch, reload after an edit) keeps it.\n // fs-list holds one sorting column, so it shows the authored sort's first\n // term; the request sends only that term and the server appends the rest.\n const sort: ReportSort | undefined = this._filterState.listSort(this.component().id)\n ?? listSortTerms(config)[0];\n\n this.listConfig = {\n // Inside a report component the list is a clean data pane — no status\n // bar, no reload button (filter changes already refetch).\n status: false,\n reload: false,\n // FsList never touches the URL or persists sort/paging state. The sort\n // is kept in ReportFilterStateService (setListSort), and paging stays\n // out of it.\n queryParam: false,\n persist: false,\n sort: sort\n ? { value: sort.column, direction: sort.direction ?? 'asc' }\n : undefined,\n // Load-more: the list keeps a fixed, scrollable height and appends the\n // next page in place instead of swapping pages. The button is pinned to\n // the bottom of the scroll pane (see component SCSS).\n //\n // Uses the Offset strategy (offset + limit) rather than Many: in\n // @firestitch/list the pagination template resolves `hasManyStrategy`\n // BEFORE `loadMoreEnabled`, and Many renders a forward-only page pager —\n // so Many would suppress the load-more button entirely. Offset + loadMore\n // is the combination that actually renders and appends. `_fetch` already\n // derives `page` from `offset`, so the server-side wrap is unaffected.\n paging: {\n limit: config.pageSize ?? 25,\n strategy: PaginationStrategy.Offset,\n },\n loadMore: {\n enabled: true,\n label: 'Load more',\n buttonType: 'stroked',\n },\n fetch: (query: any) => this._fetch(query),\n };\n }\n\n private _fetch(query: any): Observable<{ data: Record<string, unknown>[]; paging: any }> {\n // Many/load-more sends `offset` + `limit` (not `page`); derive the page so\n // the server-side wrap keeps working unchanged. Page strategy still sends\n // `page` directly.\n const pageSize = query.limit ?? 25;\n const page = query.page\n ?? (query.offset != null ? Math.floor(query.offset / pageSize) + 1 : 1);\n\n const state: ComponentDataState = {\n page,\n pageSize,\n };\n\n const order = String(query.order ?? '');\n if (order) {\n const [column, direction] = order.split(',');\n state.sort = { column, direction: direction === 'desc' ? 'desc' : 'asc' };\n }\n\n const component = this.component();\n this._filterState.setListSort(component, state.sort ?? null);\n\n const search = this._filterState.listSearch(component.id);\n if (search) {\n state.search = search;\n }\n\n // The groups that match 'any', as every other read of this tile sends\n // them (tileDataState). The sort and paging above are FsList's own.\n const { matchAnyGroupIds } = this._filterState.tileState(component);\n if (matchAnyGroupIds) {\n state.matchAnyGroupIds = matchAnyGroupIds;\n }\n\n // One source for filter values, the same one charts, KPIs and the exports\n // read, so the list is filtered exactly as its header strip shows.\n const filters = this._filterState.resolveForComponent(component);\n\n return this._reportData\n .componentData(this.reportId(), component.id, filters, state)\n .pipe(\n map((data: ComponentData) => {\n // A cross-tab's headers come back with the rows: the row-key column\n // first, then one per pivot value. Re-read them on every fetch, since\n // a filter change can add or remove a column.\n if (this.pivoted()) {\n this.columns.set(this._pivotColumns(data));\n this.truncated.set(!!data.truncated);\n }\n\n // Only page 1 carries the notes and the totals; a load-more page\n // leaves them as they are.\n if (state.page === 1) {\n this.searchNote.set(data.searchNote ?? null);\n this.totals.set(data.totals ?? null);\n this.totalsNote.set(data.totalsNote ?? null);\n this.noteData.set(this._noteData(data));\n this._alignOutputColumns(data);\n }\n\n // The server's page size when it sends one (it clamps the request),\n // the size the paging below hands fs-list too.\n const size = data.paging?.pageSize ?? state.pageSize;\n const shown = (state.page - 1) * size + (data.rows?.length ?? 0);\n this.rowCount.set({ shown, total: data.paging?.total ?? shown });\n\n // New rows can widen a pinned column, which moves the ones after it.\n this._schedulePinOffsets();\n\n return {\n data: data.rows ?? [],\n paging: {\n limit: data.paging?.pageSize ?? state.pageSize,\n records: data.paging?.total ?? (data.rows?.length ?? 0),\n page: data.paging?.page ?? state.page,\n },\n };\n }),\n );\n }\n\n // A cross-tab's columns, built from the wire by pivotColumnSpecs(): the same\n // headings and cell format the PDF and PowerPoint exports use. A cell column\n // whose measure is a rank or a share (cellMeasures names it) holds numbers\n // whether or not the grid names a cell format.\n private _pivotColumns(data: ComponentData): (ListColumn & { numeric: boolean })[] {\n const config = (this.component().config ?? {}) as ListConfig;\n const outputCells = Object.keys(listOutputColumns(\n (data.columns ?? []).slice(1).map((column) => ({ column })),\n data,\n [],\n ));\n\n return pivotColumnSpecs(config, data, this.formatContext().locale)\n .map((column) => ({ ...column, numeric: column.numeric || outputCells.includes(column.column) }));\n }\n\n private _noteData(data: ComponentData): ComponentNoteData {\n return {\n comparison: data.comparison,\n timeframe: data.timeframe,\n outputs: data.outputs,\n cellMeasures: data.cellMeasures,\n windows: data.windows,\n granularity: data.granularity,\n };\n }\n\n // A plain list's columns are built before any data arrives, so an output\n // column that names no format of its own (a rank, a share, a prior that takes\n // its measure's format) learns it holds numbers from page 1. fs-list reads a\n // column's alignment only when it builds the column, so a column whose\n // alignment changes is rebuilt (the template tracks columns by both).\n private _alignOutputColumns(data: ComponentData): void {\n if (this.pivoted() || !data.outputs) {\n return;\n }\n\n const columns = this.columns();\n const aligned = columns.map((column) => ({\n ...column,\n numeric: hasNumberFormat(column) || !!data.outputs[column.column],\n }));\n\n if (aligned.some((column, index) => column.numeric !== columns[index].numeric)) {\n this.columns.set(aligned);\n }\n }\n\n // A tile resize reflows the table's auto layout, so the pinned columns'\n // widths, and with them their offsets, change.\n private _observePinOffsets(): void {\n if (this.pinned() < 2 || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const observer = new ResizeObserver(() => this._schedulePinOffsets());\n observer.observe(this._elementRef.nativeElement);\n this._destroyRef.onDestroy(() => observer.disconnect());\n }\n\n // Measures the pinned offsets once the next render has laid the table out.\n // One pending measurement covers every request made before it runs. Only\n // afterNextRender exists in every Angular version this library runs on.\n private _schedulePinOffsets(): void {\n if (this.pinned() < 2 || this._pinOffsetsRef) {\n return;\n }\n\n this._pinOffsetsRef = afterNextRender(() => {\n this._pinOffsetsRef = null;\n this._updatePinOffsets();\n }, { injector: this._injector });\n }\n\n // Each pinned column sticks at the summed width of the visible pinned\n // columns before it. A hidden column renders no header, so the next pinned\n // one takes its place. A variable is written only when its value changed,\n // which keeps a resize from restyling the table for nothing.\n private _updatePinOffsets(): void {\n const host = this._elementRef.nativeElement;\n let left = 0;\n\n for (let index = 0; index < this.pinned(); index++) {\n const header = host.querySelector<HTMLElement>(`thead th.report-pin-${index}`);\n\n if (!header) {\n continue;\n }\n\n const name = `--report-pin-left-${index}`;\n const value = `${Math.round(left * 100) / 100}px`;\n\n if (host.style.getPropertyValue(name) !== value) {\n host.style.setProperty(name, value);\n }\n\n left += header.getBoundingClientRect().width;\n }\n }\n}\n","@if (truncated()) {\n <div class=\"pivot-truncated\">\n This grid was built from a partial result, so some columns or values may be missing. Narrow it with a filter.\n </div>\n}\n\n<!-- The windows a comparison compares, and why it reads as it does. A\n windowed column's own notes are in its header's tooltip. -->\n<app-report-component-note\n [data]=\"noteData()\"\n [windowNotes]=\"false\">\n</app-report-component-note>\n\n<!-- fs-list reads a column's footer template once, as a direct child of\n fs-list-column, so a list with totals renders its columns in a branch of\n their own rather than wrapping the footer in an @if. Its header template too,\n which every column carries: an output column's tooltip says what it holds.\n Columns are tracked by alignment as well as name, since fs-list reads a\n column's alignment only when it builds the column. -->\n<fs-list\n [config]=\"listConfig\"\n [class.report-totals-empty]=\"!totals()\">\n @if (showTotals()) {\n @for (column of columns(); track column.column + ':' + column.numeric) {\n <fs-list-column\n [name]=\"column.column\"\n [title]=\"column.label || column.column\"\n [show]=\"!hidden().has(column.column)\"\n [sortable]=\"!pivoted() || $first\"\n [align]=\"column.numeric ? 'right' : 'left'\"\n [class]=\"columnClasses(column, $index, pinned())\">\n <ng-template fs-list-header>\n <ng-container\n [ngTemplateOutlet]=\"headerTpl\"\n [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n </ng-template>\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row[column.column], row: row, column: column }\">\n </ng-container>\n </ng-template>\n <ng-template fs-list-footer>\n @if (totals()?.[column.column] !== undefined) {\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: totals()?.[column.column], row: totals(), column: column }\">\n </ng-container>\n } @else if (column.column === totalsLabelColumn()) {\n {{ totalLabel }}\n }\n </ng-template>\n </fs-list-column>\n }\n } @else {\n @for (column of columns(); track column.column + ':' + column.numeric) {\n <fs-list-column\n [name]=\"column.column\"\n [title]=\"column.label || column.column\"\n [show]=\"!hidden().has(column.column)\"\n [sortable]=\"!pivoted() || $first\"\n [align]=\"column.numeric ? 'right' : 'left'\"\n [class]=\"columnClasses(column, $index, pinned())\">\n <ng-template fs-list-header>\n <ng-container\n [ngTemplateOutlet]=\"headerTpl\"\n [ngTemplateOutletContext]=\"{ column: column }\">\n </ng-container>\n </ng-template>\n <ng-template\n fs-list-cell\n let-row=\"row\">\n <ng-container\n [ngTemplateOutlet]=\"cellTpl\"\n [ngTemplateOutletContext]=\"{ $implicit: row[column.column], row: row, column: column }\">\n </ng-container>\n </ng-template>\n </fs-list-column>\n }\n }\n</fs-list>\n\n@if (caption()) {\n <div class=\"list-caption small\">\n {{ caption() }}\n </div>\n}\n\n<!-- A column's heading, with what an output column holds as its tooltip (an\n empty one never shows). -->\n<ng-template\n #headerTpl\n let-column=\"column\">\n <span [matTooltip]=\"columnNotes()[column.column] ?? ''\">{{ column.label || column.column }}</span>\n</ng-template>\n\n<!-- One cell, in the body and the totals row alike: an output column by what\n it holds (its row gives a change its prior), a date column as a day in the\n report's zone and locale, any other through its number format. -->\n<ng-template\n #cellTpl\n let-value\n let-row=\"row\"\n let-column=\"column\">\n @if (outputColumns()[column.column]; as output) {\n @if (row | fsReportOutput: column : output : formatContext(); as cell) {\n <span [attr.title]=\"cell.title\">{{ cell.text }}</span>\n }\n } @else if (column.format === ReportListColumnFormat.Date) {\n {{ value | fsReportDate: timezone() : formatContext().locale }}\n } @else {\n {{ value | fsReportNumber: column : formatContext() }}\n }\n</ng-template>\n","import { Plugin, PluginConfig } from '@firestitch/html-editor';\n\nimport {\n FIELD_TOKEN_PATTERN, TextTokenContext, TextValue, VALUE_TOKEN_PATTERN, fieldText, fieldToken, textFields, valueText,\n valueToken,\n} from '../../text';\n\n\n// How a value chip is marked in the editor. The names follow the embeds of\n// @firestitch/markdown-editor. Attributes rather than a class: the report keeps\n// Froala on inline styles (useClasses: false), and a chip never reaches storage\n// anyway — it turns back into its {{value.key}} token on the way out.\nconst TYPE_ATTRIBUTE = 'data-embed-type';\nconst KEY_ATTRIBUTE = 'data-embed-key';\nconst MISSING_ATTRIBUTE = 'data-embed-missing';\nconst CHIP_SELECTOR = `[${KEY_ATTRIBUTE}]`;\nconst VALUE_TYPE = 'value';\n\n// A field chip ({{page.number}}, {{filter.12}}, …) is marked by its field\n// instead of a key. It has nothing behind it, so none of the guards on value\n// chips (CHIP_SELECTOR) apply to it.\nconst FIELD_ATTRIBUTE = 'data-embed-field';\nconst FIELD_SELECTOR = `[${FIELD_ATTRIBUTE}]`;\nconst FIELD_TYPE = 'field';\n\n// Either kind of chip.\nconst EMBED_SELECTOR = `${CHIP_SELECTOR}, ${FIELD_SELECTOR}`;\n\n// The page a copy came from, on the clipboard beside its text: values belong\n// to their page, so a value pasted onto another one doesn't come with it.\nconst SCOPE_TYPE = 'application/x-fs-report-value-scope';\n\n// What Froala must keep on a chip when it cleans html it is handed.\nexport const VALUE_EMBED_ATTRIBUTES = [\n TYPE_ATTRIBUTE, KEY_ATTRIBUTE, FIELD_ATTRIBUTE, MISSING_ATTRIBUTE, 'contenteditable',\n];\n\n// The list inside a Froala dropdown (Froala's own markup).\nconst DROPDOWN_LIST_SELECTOR = '.fr-dropdown-list';\n\n// A brief ring around the chips an edit was stopped at.\nconst FLASH: Keyframe[] = [{ boxShadow: '0 0 0 2px #e15759' }, { boxShadow: '0 0 0 2px transparent' }];\nconst FLASH_MS = 700;\n\n// Commands that would build what the server rewrites (ReportTextHtml): a table\n// is kept only between paragraphs, and a cell holds words and values only.\nconst TABLE_INSERT_COMMANDS = ['insertTable', 'tableInsert'];\nconst NO_TABLE_INSIDE = 'li, td, th';\nconst CELL_COMMANDS = ['formatUL', 'formatOL', 'paragraphFormat'];\nconst CELL = 'td, th';\n\n// Undo and redo restore a step; they remove nothing of their own.\nconst HISTORY_COMMANDS = ['undo', 'redo'];\n\n// Keys that, pressed alone, edit nothing.\nconst MODIFIER_KEYS = ['Shift', 'Control', 'Alt', 'AltGraph', 'Meta'];\n\n// The cells of a table selected as cells (Froala's own marking).\nconst SELECTED_CELL = '.fr-selected-cell';\n\n// An edit that would have removed values, and was stopped.\nexport interface ValueEmbedBlock {\n count: number;\n // Present when the edit was on a selection: removes the selection, values\n // and all — the deliberate way through.\n removeSelection?: () => void;\n}\n\n// An edit that took the last chip of some values out of the block: deleting\n// a row, a column or a table, or emptying cells. Allowed, values and all.\nexport interface ValueEmbedRemoval {\n // The keys the block's chips named before the edit, and after it.\n before: string[];\n after: string[];\n // The editor's own undo, which brings the chips back.\n undo: () => void;\n}\n\n// One entry of the toolbar dropdown that inserts tokens: the token, and what\n// it is called.\nexport interface EmbedMenuEntry {\n token: string;\n name: string;\n}\n\n// A token found in the editor's text: a value's key, or a field\n// ('page.number', 'filter.12'), both lowercase.\ninterface EmbedToken {\n index: number;\n length: number;\n key?: string;\n field?: string;\n}\n\nexport interface ValueEmbedPluginConfig extends PluginConfig {\n // The element the editor sits in. html-editor registers a plugin with Froala\n // globally, so Froala hands it every editor built afterwards; it works only\n // for the one inside this element.\n host: () => HTMLElement;\n // The page's values, by key. One whose number is still on its way is listed\n // with loading: true; a key not listed is no value of the page.\n values: () => Record<string, TextValue>;\n // The page the block's values belong to.\n scope: () => string;\n // What fills the block's page, report and filter fields: a field chip reads\n // as its filled text, like the viewed block.\n fields: () => TextTokenContext;\n // The toolbar dropdown that inserts tokens (insert()): its command, and\n // what it lists, in order.\n menu: {\n command: string;\n entries: () => EmbedMenuEntry[];\n };\n // Label chips with the value's name instead of its number, and field chips\n // with the field's name instead of its text.\n showNames: () => boolean;\n click: (key: string, chip: HTMLElement) => void;\n blocked: (block: ValueEmbedBlock) => void;\n removed: (removal: ValueEmbedRemoval) => void;\n // A key was pressed or a command is about to run: what was said about the\n // last edit no longer applies.\n changed: () => void;\n // A command was refused, and why.\n refused: (text: string) => void;\n}\n\n// The token a chip of either kind stands for.\nfunction chipToken(chip: Element): string {\n return chip.hasAttribute(FIELD_ATTRIBUTE)\n ? fieldToken(chip.getAttribute(FIELD_ATTRIBUTE))\n : valueToken(chip.getAttribute(KEY_ATTRIBUTE));\n}\n\n// Live values and fields inside a text block's editor.\n//\n// Stored html carries a value as a {{value.key}} token. While editing, each\n// token is a chip: one character to the cursor, labeled with the value, and\n// reporting a click. Froala's html.get hands back tokens again, so the draft\n// and the saved html never hold a chip.\n//\n// A chip can't be deleted by editing: Backspace or Delete beside it, and any\n// deleting, typing over, cutting, pasting over or dragging of a selection that\n// holds one, is stopped and reported. It is taken out on purpose by selecting\n// it and pressing Delete, then taking the stopped selection's\n// removeSelection(); a value that was deleted leaves through removeKey().\n//\n// A table is the exception: deleting a row, a column or the table, or\n// emptying several selected cells, goes through with the chips in it, and is\n// reported as removed() when it took a value's last chip, with the undo that\n// brings them back.\n//\n// A page, report or filter field ({{page.number}}, {{filter.12}}, …) edits as\n// a field chip the same way — one character, labeled, back to its token on the\n// way out — but nothing guards it: a field has nothing behind it to lose.\n// Backspace or Delete takes it out like a character, a selection holding one\n// deletes as any other, and a copy or a cut carries its token to any block of\n// the report. A field chip reports no click.\nexport class ValueEmbedPlugin extends Plugin {\n\n // The base class's config, typed for this plugin.\n public declare config: ValueEmbedPluginConfig;\n\n // The editor this plugin serves; null until it is built, and after it is gone.\n private _editor: any = null;\n // Set while a deliberate removal runs, so the guards let it through.\n private _removing = false;\n // Listeners on the editable element, captured so each runs before Froala's\n // own handler for the same event.\n private _domListeners: [string, EventListener][] = [];\n // The page the paste under way was copied on ('' when not from a block).\n private _pasteScope = '';\n // How many chips each key had as the command under way started; null for\n // one that removes nothing of its own (undo, redo).\n private _before: Map<string, number> | null = null;\n\n constructor(config: ValueEmbedPluginConfig) {\n super();\n this.config = config;\n }\n\n public initialize(): void {\n if (!this.config.host().contains(this.editor.el)) {\n return;\n }\n\n const editor = this.editor;\n const el: HTMLElement = editor.el;\n this._editor = editor;\n\n editor.events.on('html.set', () => this._toChips());\n editor.events.on('paste.after', () => this._toChips(true));\n this._watchCommands(editor);\n editor.events.on('html.get', (html: string) => this._toTokens(html));\n // First in Froala's chain, so its own Backspace handling never runs on a\n // stopped key.\n editor.events.on('keydown', (event: KeyboardEvent) => this._onKeydown(event), true);\n editor.events.on('paste.before', (event: ClipboardEvent) => {\n this._pasteScope = event?.clipboardData?.getData(SCOPE_TYPE) ?? '';\n\n return this._guardSelection(event);\n });\n // A press on a chip opens its popover; Froala's floating toolbar, which\n // pops up on any press in the text and sits above every overlay, stays\n // away for it.\n editor.events.on('toolbar.show', (event?: Event) => (this._onChip(event) ? false : undefined), true);\n // Only while it is still this editor: reopening a block builds the next\n // one before the last is torn down.\n editor.events.on('destroy', () => {\n if (this._editor === editor) {\n this.destroy();\n }\n });\n\n this._domListeners = [\n ['beforeinput', (event) => this._onBeforeInput(event as InputEvent)],\n ['cut', (event) => this._onCut(event as ClipboardEvent)],\n ['dragstart', (event) => this._guardSelection(event)],\n ['copy', (event) => this._onCopy(event as ClipboardEvent)],\n ['click', (event) => this._onClick(event as MouseEvent)],\n ];\n this._domListeners.forEach(([name, listener]) => el.addEventListener(name, listener, true));\n\n this._toChips();\n this._fillMenu();\n }\n\n public destroy(): void {\n const el: HTMLElement | undefined = this._editor?.el;\n this._domListeners.forEach(([name, listener]) => el?.removeEventListener(name, listener, true));\n this._domListeners = [];\n this._editor = null;\n }\n\n // Relabel every chip: the values or the fields arrived or changed, or names\n // were toggled. The insert menu follows the values and filters too.\n public refresh(): void {\n this._chips().forEach((chip) => this._label(chip));\n this._fieldChips().forEach((chip) => this._labelField(chip));\n this._fillMenu();\n }\n\n // Put a token in at the cursor as its chip, in place of any selection: the\n // insert menu. A value comes in as a chip like any other, guarded and read\n // by the block from then on; a field as a field chip. It runs as the menu's\n // toolbar command, so a selection holding values is replaced, and reported,\n // as by any command.\n public insert(token: string): void {\n const [embed] = this._embedTokens(token);\n const chip = embed ? this._tokenChip(embed, false) : null;\n const range = chip ? this._range() : null;\n if (!range) {\n return;\n }\n\n // The chip goes in where the selection ends, and the selection up to it\n // then comes out through Froala's own delete, the one typing over a\n // selection runs, so paragraphs it spans join as for a typed character.\n // The browser's delete would raise an input event, which Froala saves as\n // an undo step of its own; this one raises none, so one undo takes the\n // whole insert back. And with the chip already between them, the spaces\n // either side of the selection never meet, so neither turns into a\n // non-breaking space.\n const selected = this._inBlocks(range);\n const end = selected.cloneRange();\n end.collapse(false);\n end.insertNode(chip);\n\n const selection = this._selection();\n if (!selected.collapsed) {\n selected.setEndBefore(chip);\n selection.removeAllRanges();\n selection.addRange(selected);\n this._editor.selection.remove();\n }\n\n // The cursor goes after the chip, so typing carries on behind it.\n const caret = document.createRange();\n caret.setStartAfter(chip);\n caret.collapse(true);\n selection.removeAllRanges();\n selection.addRange(caret);\n }\n\n // Put Froala's floating toolbar and a table's popup away, when either is\n // already up as a chip's popover opens: they sit above every overlay.\n public hideToolbar(): void {\n this._editor?.toolbar.hide();\n this._editor?.popups.hide('table.edit');\n }\n\n // The editor's own undo of the last step: what puts back the chips an edit\n // took out.\n public undo(): void {\n this._editor?.commands.undo();\n }\n\n // Take a value out of the text, wherever it appears — it was deleted.\n public removeKey(key: string): void {\n this._chips()\n .filter((chip) => chip.getAttribute(KEY_ATTRIBUTE) === key)\n .forEach((chip) => this.remove(chip));\n }\n\n // Take one chip out of the text.\n public remove(chip: HTMLElement): void {\n if (!this._editor?.el.contains(chip)) {\n return;\n }\n\n // The cursor goes back where the chip was — whatever asked for the\n // removal (a dialog, a popover) took the focus, and without it an Undo\n // straight after would never reach the editor.\n const caret = document.createRange();\n caret.setStartBefore(chip);\n caret.collapse(true);\n\n this._editor.undo.saveStep();\n chip.remove();\n this._editor.el.focus();\n const selection = this._selection();\n selection.removeAllRanges();\n selection.addRange(caret);\n this._changed();\n }\n\n private _chips(): HTMLElement[] {\n return this._editor\n ? Array.from(this._editor.el.querySelectorAll(CHIP_SELECTOR))\n : [];\n }\n\n private _fieldChips(): HTMLElement[] {\n return this._editor\n ? Array.from(this._editor.el.querySelectorAll(FIELD_SELECTOR))\n : [];\n }\n\n // Froala writes a dropdown's list once, as its toolbar is built, from the\n // options registered for the command (globally, for every editor), and puts\n // a title on each entry. So the insert menu is filled here instead, for this\n // editor, from what its block has now, and again as that changes. No title:\n // hovering an entry shows nothing.\n private _fillMenu(): void {\n const toolbar: HTMLElement | undefined = this._editor?.$tb?.get(0);\n const button = toolbar?.querySelector(`.fr-dropdown[data-cmd=\"${this.config.menu.command}\"]`);\n const list = button\n ? toolbar.querySelector(`[id=\"${button.getAttribute('aria-controls')}\"] ${DROPDOWN_LIST_SELECTOR}`)\n : null;\n if (!list) {\n return;\n }\n\n list.replaceChildren(...this.config.menu.entries().map((entry) => this._menuItem(entry)));\n }\n\n // An entry as Froala writes one: choosing it runs the command with the\n // token.\n private _menuItem(entry: EmbedMenuEntry): HTMLElement {\n const option = document.createElement('a');\n option.className = 'fr-command';\n option.tabIndex = -1;\n option.setAttribute('role', 'option');\n option.setAttribute('data-cmd', this.config.menu.command);\n option.setAttribute('data-param1', entry.token);\n option.textContent = entry.name;\n\n const item = document.createElement('li');\n item.setAttribute('role', 'presentation');\n item.append(option);\n\n return item;\n }\n\n // How many chips each key has in the block.\n private _chipCounts(): Map<string, number> {\n const counts = new Map<string, number>();\n this._chips().forEach((chip) => {\n const key = chip.getAttribute(KEY_ATTRIBUTE);\n counts.set(key, (counts.get(key) ?? 0) + 1);\n });\n\n return counts;\n }\n\n // Tell the host when an edit took the last chip of some key out of the\n // block, given the counts from before it.\n private _reportRemoved(before: Map<string, number> | null): void {\n if (!before || !this._editor) {\n return;\n }\n\n const after = this._chipCounts();\n if ([...before.keys()].some((key) => !after.has(key))) {\n this.config.removed({\n before: [...before.keys()],\n after: [...after.keys()],\n undo: () => this.undo(),\n });\n }\n }\n\n // A toolbar command sees tokens, not chips: Clear formatting unwraps every\n // span, a chip included, which would leave a typed number behind. Around a\n // token it formats plain text, and the chip comes back inside whatever\n // formatting the token was given.\n private _watchCommands(editor: any): void {\n editor.events.on('commands.before', (command: string) => this._onCommandBefore(command));\n editor.events.on('commands.after', () => {\n this._toChips();\n this._reportRemoved(this._before);\n this._before = null;\n });\n // Undo and redo restore a step as Froala saved it: the one before a\n // command holds tokens, as the command saw them. Neither fires\n // commands.after: Froala's commands.undo() — Ctrl+Z, and undo() here —\n // runs the undo directly.\n editor.events.on('commands.undo', () => this._toChips());\n editor.events.on('commands.redo', () => this._toChips());\n }\n\n // Every command starts a new edit. One that would build what the server\n // rewrites is refused (returning false cancels it); any other runs on\n // tokens, its chip counts kept to see what it removed.\n private _onCommandBefore(command: string): false | void {\n this.config.changed();\n\n if (TABLE_INSERT_COMMANDS.includes(command) && this._caretIn(NO_TABLE_INSIDE)) {\n this.config.refused('A table goes between paragraphs, never inside a list or another table.');\n\n return false;\n }\n\n if (CELL_COMMANDS.includes(command) && this._caretIn(CELL)) {\n this.config.refused('A table cell holds words and values; a list or a heading goes outside the table.');\n\n return false;\n }\n\n this._before = HISTORY_COMMANDS.includes(command) ? null : this._chipCounts();\n // The insert menu puts a chip in itself, among chips that stay chips: as\n // tokens they would take a cursor just after one to before it.\n if (command !== this.config.menu.command) {\n this._toTokenText();\n }\n }\n\n // Whether the caret sits inside an element of this editor that `selector`\n // matches.\n private _caretIn(selector: string): boolean {\n const container: Element | null = this._editor.selection.element()?.closest?.(selector) ?? null;\n\n return !!container && this._editor.el.contains(container);\n }\n\n // Turn every {{value.key}} and field token in the editor's text into a chip.\n // For a paste, a value's token only stays when it was copied on this page and\n // the page has the value; otherwise it goes, and just the text around it is\n // pasted. A field's always stays: fields belong to the whole report.\n private _toChips(pasted = false): void {\n const el: HTMLElement | undefined = this._editor?.el;\n if (!el) {\n return;\n }\n\n const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);\n const texts: Text[] = [];\n while (walker.nextNode()) {\n const text = walker.currentNode as Text;\n if (text.data.includes('{{') && !text.parentElement?.closest(EMBED_SELECTOR)) {\n texts.push(text);\n }\n }\n\n texts.forEach((text) => this._splitText(text, pasted));\n }\n\n private _keepsPasted(key: string): boolean {\n return this._pasteScope === this.config.scope() && !!this.config.values()[key];\n }\n\n private _splitText(text: Text, pasted: boolean): void {\n const tokens = this._embedTokens(text.data);\n if (!tokens.length) {\n return;\n }\n\n // Only non-empty text around the chips, so a selection counted in child\n // nodes keeps its place.\n const fragment = document.createDocumentFragment();\n const appendText = (value: string) => {\n if (value) {\n fragment.append(value);\n }\n };\n let consumed = 0;\n tokens.forEach((token) => {\n appendText(text.data.slice(consumed, token.index));\n const chip = this._tokenChip(token, pasted);\n if (chip) {\n fragment.append(chip);\n }\n consumed = token.index + token.length;\n });\n appendText(text.data.slice(consumed));\n\n text.replaceWith(fragment);\n }\n\n // The value and field tokens in a text, in order.\n private _embedTokens(text: string): EmbedToken[] {\n const values = Array.from(text.matchAll(VALUE_TOKEN_PATTERN), (match): EmbedToken => ({\n index: match.index,\n length: match[0].length,\n key: match[1].toLowerCase(),\n }));\n const fields = Array.from(text.matchAll(FIELD_TOKEN_PATTERN), (match): EmbedToken => ({\n index: match.index,\n length: match[0].length,\n field: match[1].toLowerCase(),\n }));\n\n return [...values, ...fields].sort((a, b) => a.index - b.index);\n }\n\n // The chip a token edits as; null for a pasted value that does not stay.\n private _tokenChip(token: EmbedToken, pasted: boolean): HTMLElement | null {\n if (token.field) {\n return this._createFieldChip(token.field);\n }\n\n return !pasted || this._keepsPasted(token.key) ? this._createChip(token.key) : null;\n }\n\n // Every chip in the editor back to its token, as text.\n private _toTokenText(): void {\n [...this._chips(), ...this._fieldChips()].forEach((chip) => chip.replaceWith(chipToken(chip)));\n }\n\n private _createChip(key: string): HTMLElement {\n const chip = document.createElement('span');\n chip.setAttribute(TYPE_ATTRIBUTE, VALUE_TYPE);\n chip.setAttribute(KEY_ATTRIBUTE, key);\n chip.setAttribute('contenteditable', 'false');\n this._label(chip);\n\n return chip;\n }\n\n // A chip reads as the value does in the viewed block — its number, the\n // ellipsis while that loads, else the em dash — so opening the editor moves\n // no word; or as its name, when names are toggled on. A key with no value on\n // the page reads as the key itself, marked missing.\n private _label(chip: HTMLElement): void {\n const key = chip.getAttribute(KEY_ATTRIBUTE);\n const value = this.config.values()[key];\n\n chip.textContent = !value\n ? key\n : this.config.showNames() ? value.name : valueText(value);\n // Named for screen readers only: a title would pop the browser's own\n // tooltip on hover, and a chip's name is shown by its popover on click.\n chip.setAttribute('aria-label', value?.name ?? key);\n chip.toggleAttribute(MISSING_ATTRIBUTE, !value);\n }\n\n private _createFieldChip(field: string): HTMLElement {\n const chip = document.createElement('span');\n chip.setAttribute(TYPE_ATTRIBUTE, FIELD_TYPE);\n chip.setAttribute(FIELD_ATTRIBUTE, field);\n chip.setAttribute('contenteditable', 'false');\n this._labelField(chip);\n\n return chip;\n }\n\n // A field chip reads as the field does in the viewed block, or as its name\n // ('Page number', the filter's label) when names are toggled on. One whose\n // text is empty, a blank keyword filter, reads as its name, so it can still\n // be seen. A filter the block cannot read (the report has no group of it,\n // or it is another page's page filter) reads as the field itself, marked\n // missing. Named for screen readers only, as a value chip is.\n private _labelField(chip: HTMLElement): void {\n const field = chip.getAttribute(FIELD_ATTRIBUTE);\n const context = this.config.fields();\n const name = textFields(context).find((entry) => entry.field === field)?.name;\n\n chip.textContent = !name\n ? field\n : this.config.showNames() ? name : fieldText(field, context) || name;\n chip.setAttribute('aria-label', name ?? field);\n chip.toggleAttribute(MISSING_ATTRIBUTE, !name);\n }\n\n // The html Froala hands out, with every chip back to its token.\n private _toTokens(html: string): string {\n if (!html.includes(KEY_ATTRIBUTE) && !html.includes(FIELD_ATTRIBUTE)) {\n return html;\n }\n\n const template = document.createElement('template');\n template.innerHTML = html;\n template.content.querySelectorAll(EMBED_SELECTOR).forEach((chip) => chip.replaceWith(chipToken(chip)));\n\n return template.innerHTML;\n }\n\n private _onKeydown(event: KeyboardEvent): boolean | void {\n // Any key but a lone modifier starts a new edit.\n if (!MODIFIER_KEYS.includes(event.key)) {\n this.config.changed();\n }\n\n const deleting = event.key === 'Backspace' || event.key === 'Delete';\n\n // Deleting across several selected cells goes through, values and all:\n // Froala saves an undo step and empties the cells, and what that took is\n // reported once they are empty.\n if (deleting && this._editor.el.querySelectorAll(SELECTED_CELL).length > 1) {\n const before = this._chipCounts();\n setTimeout(() => this._reportRemoved(before));\n\n return undefined;\n }\n\n const range = this._range();\n if (!range) {\n return;\n }\n\n if (range.collapsed) {\n if (!deleting) {\n return;\n }\n\n const backward = event.key === 'Backspace';\n const granularity = this._granularity(event);\n const chip = this._adjacentChip(backward, granularity);\n\n return chip\n ? this._block(event, [chip], null)\n : this._removeAdjacentField(event, backward, granularity);\n }\n\n // A selection is replaced by a deleting key, Enter, a typed character or\n // a cut.\n const typing = event.key.length === 1 && !event.ctrlKey && !event.metaKey;\n const cutting = (event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'x';\n if (!deleting && !typing && !cutting && event.key !== 'Enter') {\n return;\n }\n\n const chips = this._chipsIn(range);\n\n return chips.length ? this._block(event, chips, range) : undefined;\n }\n\n // The same rule for edits that arrive without a key Froala sees: a phone\n // keyboard, an input method, a spell-check replacement.\n private _onBeforeInput(event: InputEvent): void {\n const range = this._range();\n if (this._removing || !range) {\n return;\n }\n\n if (range.collapsed) {\n const backward = event.inputType.endsWith('Backward');\n if (event.inputType.startsWith('delete')) {\n const chip = this._adjacentChip(backward, event.inputType.includes('Word') ? 'word' : 'character');\n if (chip) {\n this._block(event, [chip], null);\n }\n }\n\n return;\n }\n\n const chips = this._chipsIn(range);\n if (chips.length) {\n this._block(event, chips, range);\n }\n }\n\n // Cut, drag and paste-over: stopped when the selection holds a value.\n private _guardSelection(event: Event): boolean | void {\n const range = this._range();\n if (this._removing || !range || range.collapsed) {\n return;\n }\n\n const chips = this._chipsIn(range);\n\n return chips.length ? this._block(event, chips, range) : undefined;\n }\n\n // Backspace or Delete beside a field chip takes it out like one character,\n // with no prompt: a field has nothing behind it to lose. Done here, as a\n // value's guard would be, rather than left to Froala's own handling of a\n // non-editable element.\n private _removeAdjacentField(event: Event, backward: boolean, granularity: string): false | void {\n const reach = this._reach(backward, granularity);\n if (!reach || !this._fieldChipsIn(reach).length) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n this._removeRange(reach);\n\n return false;\n }\n\n // Cut: stopped when the selection holds a value. One holding a field puts\n // its tokens on the clipboard as a copy does, and so is deleted here: a cut\n // that writes its own clipboard deletes nothing.\n private _onCut(event: ClipboardEvent): void {\n const range = this._range();\n if (this._guardSelection(event) === false || !range || range.collapsed || !this._fieldChipsIn(range).length) {\n return;\n }\n\n this._copyTokens(event, range);\n this._removeRange(range);\n }\n\n // Copying a chip copies its token, so pasting it makes it a chip again: a\n // field's in any block of the report, a value's on the page it was copied\n // on — in this block or another — which goes on the clipboard beside it.\n private _onCopy(event: ClipboardEvent): void {\n const range = this._range();\n if (!range || range.collapsed || !(this._chipsIn(range).length || this._fieldChipsIn(range).length)) {\n return;\n }\n\n this._copyTokens(event, range);\n }\n\n private _copyTokens(event: ClipboardEvent, range: Range): void {\n const holder = document.createElement('div');\n holder.append(range.cloneContents());\n holder.querySelectorAll(EMBED_SELECTOR).forEach((chip) => chip.replaceWith(chipToken(chip)));\n\n event.clipboardData.setData('text/plain', this._plainText(holder));\n event.clipboardData.setData('text/html', holder.innerHTML);\n event.clipboardData.setData(SCOPE_TYPE, this.config.scope());\n event.preventDefault();\n }\n\n // What copied html reads as in plain text: a paragraph on its own lines, a\n // table's cells tab-separated and its rows on lines of their own. That is\n // the browser's innerText, which only text laid out on the page has — so\n // the holder is put offscreen (not hidden: hidden text has none) while it is\n // read.\n private _plainText(holder: HTMLElement): string {\n holder.style.cssText = 'position: fixed; left: -10000px; top: 0';\n document.body.append(holder);\n const text = holder.innerText;\n holder.remove();\n\n return text;\n }\n\n private _onClick(event: MouseEvent): void {\n const chip = (event.target as Element)?.closest?.(CHIP_SELECTOR) as HTMLElement | null;\n if (!chip || !this._editor?.el.contains(chip)) {\n return;\n }\n\n event.preventDefault();\n // A press in a table cell can open the table's popup on mouseup, just\n // before this click; a chip in a cell shows only its own popover.\n this._editor.popups.hide('table.edit');\n this.config.click(chip.getAttribute(KEY_ATTRIBUTE), chip);\n }\n\n private _onChip(event?: Event): boolean {\n return !!(event?.target as Element | undefined)?.closest?.(CHIP_SELECTOR);\n }\n\n private _block(event: Event, chips: HTMLElement[], range: Range | null): false {\n event.preventDefault();\n event.stopPropagation();\n chips.forEach((chip) => chip.animate(FLASH, FLASH_MS));\n\n this.config.blocked({\n count: chips.length,\n ...(range ? { removeSelection: () => this._removeRange(range) } : {}),\n });\n\n return false;\n }\n\n private _removeRange(range: Range): void {\n if (!this._editor) {\n return;\n }\n\n const selection = this._selection();\n this._editor.el.focus();\n selection.removeAllRanges();\n selection.addRange(range);\n\n this._editor.undo.saveStep();\n this._removing = true;\n // The browser's own delete, so two paragraphs a selection spans join the\n // way they would for a plain Delete.\n document.execCommand('delete');\n this._removing = false;\n this._changed();\n }\n\n // An edit made here rather than typed: record it for undo, and tell\n // html-editor so the draft follows.\n private _changed(): void {\n this._editor.undo.saveStep();\n this._editor.events.trigger('contentChanged');\n }\n\n private _selection(): Selection {\n return this._editor.el.ownerDocument.getSelection();\n }\n\n // The selection, when it is inside this editor.\n private _range(): Range | null {\n const selection = this._editor ? this._selection() : null;\n if (!selection?.rangeCount) {\n return null;\n }\n\n const range = selection.getRangeAt(0);\n\n return this._editor.el.contains(range.commonAncestorContainer) ? range : null;\n }\n\n // A copy of the range with an end that sits in the editor itself, between\n // blocks (as some browsers leave select-all), moved inside the block beside\n // it, so a chip put at that end lands in a block.\n private _inBlocks(range: Range): Range {\n const root: HTMLElement = this._editor.el;\n const inner = range.cloneRange();\n\n const first = range.startContainer === root ? root.childNodes[range.startOffset] : null;\n if (first && this._editor.node.isBlock(first)) {\n inner.setStart(this._edgeBlock(first as Element, false), 0);\n }\n\n const last = range.endContainer === root ? root.childNodes[range.endOffset - 1] : null;\n if (last && this._editor.node.isBlock(last)) {\n const block = this._edgeBlock(last as Element, true);\n inner.setEnd(block, block.childNodes.length);\n }\n\n return inner;\n }\n\n // The innermost first or last block of a block: a list's item, a table's\n // cell.\n private _edgeBlock(block: Element, last: boolean): Element {\n const child = last ? block.lastElementChild : block.firstElementChild;\n\n return child && this._editor.node.isBlock(child) ? this._edgeBlock(child, last) : block;\n }\n\n private _chipsIn(range: Range): HTMLElement[] {\n return this._chips().filter((chip) => range.intersectsNode(chip));\n }\n\n private _fieldChipsIn(range: Range): HTMLElement[] {\n return this._fieldChips().filter((chip) => range.intersectsNode(chip));\n }\n\n // The chip a collapsed cursor would delete into.\n private _adjacentChip(backward: boolean, granularity: string): HTMLElement | null {\n const reach = this._reach(backward, granularity);\n\n return reach ? this._chipsIn(reach)[0] ?? null : null;\n }\n\n // What a deleting key would take from a collapsed cursor: stretch the\n // selection by what the key deletes, keep what it covers, and put it back.\n // Letting the browser stretch it handles every shape the html takes — a\n // chip inside a bold span, at a line's end, beside an empty text node.\n private _reach(backward: boolean, granularity: string): Range | null {\n const selection = this._selection();\n const range = selection.getRangeAt(0).cloneRange();\n\n selection.modify('extend', backward ? 'backward' : 'forward', granularity);\n const reach = selection.rangeCount ? selection.getRangeAt(0).cloneRange() : null;\n\n selection.removeAllRanges();\n selection.addRange(range);\n\n return reach;\n }\n\n // How far a deleting key reaches: a word with Ctrl/Alt, to the line's start\n // with Cmd on a Mac, one character otherwise.\n private _granularity(event: KeyboardEvent): string {\n if (event.metaKey) {\n return 'lineboundary';\n }\n\n return event.ctrlKey || event.altKey ? 'word' : 'character';\n }\n}\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef, computed, effect, inject, input, output, signal,\n untracked, viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\nimport { FsHtmlEditorComponent, FsHtmlEditorConfig } from '@firestitch/html-editor';\nimport { FsPopoverDirective, FsPopoverRef } from '@firestitch/popover';\n\nimport {\n DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, HEADING_TEXT_SIZES, TEXT_TABLE_BORDER_COLOR, TEXT_TABLE_BORDER_WIDTH,\n TEXT_TABLE_CELL_PADDING, TEXT_TABLE_MARGIN, TextTokenContext, TextValue, fieldToken, fillTextTokens, textFields,\n valueToken,\n} from '../../text';\nimport { NO_VALUE_KEYS, readKeys } from '../../values';\n\nimport {\n EmbedMenuEntry, VALUE_EMBED_ATTRIBUTES, ValueEmbedBlock, ValueEmbedPlugin, ValueEmbedRemoval,\n} from './value-embed.plugin';\n\n\n// Point sizes — the report's type unit (1:1 with PowerPoint and PDF).\nconst FONT_SIZES = ['8', '9', '10', '11', '12', '14', '16', '18', '20', '24', '28', '32', '36', '40', '48', '60', '72'];\n\n// The toolbar dropdown that inserts a field or a value into the text.\nconst INSERT_FIELD_BUTTON = 'insertField';\n\n// What the editor may produce — exactly what the server keeps\n// (ReportTextHtml) and the exports draw. Anything else would edit fine and\n// then vanish on save. A table keeps its rows, cells and spans, and a cell its\n// alignment, fill and width; its borders and padding are never stored, so\n// every renderer draws the one grid in text.ts (TEXT_TABLE_*).\nconst ALLOWED_TAGS = [\n 'p', 'h1', 'h2', 'h3', 'br', 'strong', 'em', 'u', 's', 'span', 'a', 'ul', 'ol', 'li',\n 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td',\n];\nconst ALLOWED_STYLES = [\n 'color', 'background-color', 'font-size', 'font-weight', 'font-style', 'text-decoration', 'font-family', 'text-align',\n 'vertical-align', 'width',\n];\n\n// With useClasses: false, Froala's html.get copies every stylesheet declaration\n// that matches an element into its inline style, then lays the element's own\n// inline style back over it. So an ignored property never loses what the user\n// set; it only keeps the canvas's, Froala's and the host app's css out of the\n// saved html. Listed: every property the server keeps and the shorthands that\n// set one (otherwise Froala's grey header fill would be saved as the user's),\n// then everything else those stylesheets set on a block's elements, so a block\n// opened and closed untouched saves nothing new. Names match exactly, so a\n// rule's longhands are listed too: the browser spells Froala's table\n// `border: none` as border-width/-style/-color/-image, and the host app's\n// headings set margin-top and margin-bottom. Froala also outlines a table the\n// pointer is over, with a class that is still on it when the html is read.\nconst IGNORED_SHEET_STYLES = [\n 'color', 'background', 'background-color', 'font', 'font-family', 'font-size', 'font-style', 'font-weight',\n 'text-decoration', 'text-align', 'vertical-align', 'width',\n 'height', 'min-width', 'max-width', 'margin', 'margin-top', 'margin-bottom', 'padding', 'padding-left',\n 'border', 'border-width', 'border-style', 'border-color', 'border-image', 'border-collapse', 'empty-cells',\n 'outline', 'position', 'display', 'list-style', 'line-height', 'user-select',\n];\n\n// Froala's own toolbars and popups live on the body, not in the block, and so\n// does a value chip's popover (an overlay); a press on any of them is still part\n// of editing the block.\nconst EDITOR_CHROME = '.fr-toolbar, .fr-popup, .fr-dropdown-menu, .fr-modal, .fr-tooltip, .cdk-overlay-container';\n\n// The toolbar toggle between a chip's number and its name.\nconst VALUE_NAMES_BUTTON = 'valueNames';\n\n// How long a notice under the open block stays up.\nconst VALUE_BLOCK_NOTICE_MS = 6000;\n\n// What the notice under the open block says, one at a time: an edit was\n// stopped because it would have removed values; an edit left values that no\n// text reads any more, with the undo that puts them back; or a command was\n// refused.\ntype TextNotice =\n | { kind: 'blocked'; block: ValueEmbedBlock }\n | { kind: 'unused'; count: number; undo: () => void }\n | { kind: 'message'; text: string };\n\n// A clicked value chip's popover is an fs-popover, which attaches to an element\n// of this component's own template — the chip belongs to the editor. So it\n// opens from an invisible anchor laid over the chip, in the block's own\n// (unscaled) pixels.\ninterface ValuePopoverAnchor {\n key: string;\n chip: HTMLElement;\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n// A text block: authored rich text on the page.\n//\n// Read mode renders the stored html with its tokens ({{page.number}}, …) filled\n// for the page it is drawn on. The html has already been rebuilt server-side\n// from an allowlist (ReportTextHtml), which is what makes binding it as trusted\n// markup safe — Angular's own sanitizer would strip the inline styles that ARE\n// the formatting.\n//\n// Edit mode mounts <fs-html-editor> in its floating mode in place — the words\n// stay where they sit on the slide — with Froala's inline toolbar popping up\n// over them. The editor exists only while editing; the raw html is edited, but\n// every token edits as a chip that reads as the token does (ValueEmbedPlugin),\n// and Insert field puts any of them in. A page, report or filter field\n// ({{page.number}}, {{filter.12}}) deletes like a character. A live value\n// ({{value.key}}) is guarded: no stray keystroke removes it, and selecting it\n// and pressing Delete offers to take it out. Deleting a table's rows, columns\n// or cells does take the chips in them, and a notice under the block counts the\n// values that leaves unused, with an Undo.\n//\n// The block never saves on its own: it emits the new html when editing ends\n// and the host persists it.\n@Component({\n selector: 'app-report-component-text',\n templateUrl: './component-text.component.html',\n styleUrls: ['./component-text.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n MatButton,\n MatIconButton,\n MatIcon,\n MatTooltip,\n FsHtmlEditorComponent,\n FsPopoverDirective,\n ],\n host: {\n '(keydown)': 'onKeydown($event)',\n // The document type scale comes from the same constants the PowerPoint and\n // PDF exports draw with, so a paragraph is one size in all three.\n '[style.--text-size]': 'typeScale.body',\n '[style.--text-h1-size]': 'typeScale.h1',\n '[style.--text-h2-size]': 'typeScale.h2',\n '[style.--text-h3-size]': 'typeScale.h3',\n '[style.--text-color]': 'typeScale.color',\n // A table's grid comes from them the same way.\n '[style.--text-table-border]': 'tableLook.border',\n '[style.--text-table-padding]': 'tableLook.padding',\n '[style.--text-table-margin]': 'tableLook.margin',\n },\n})\nexport class ComponentTextComponent {\n\n // The block's stored html (config.html). Its own input rather than read off\n // the component, so a saved edit — a new string on the same component — is\n // seen as a change and repaints.\n public readonly html = input('');\n public readonly tokens = input.required<TextTokenContext>();\n public readonly editing = input(false);\n\n // The canvas is being laid out, so an empty block shows how to fill it.\n public readonly editMode = input(false);\n\n // The value keys the other text blocks of this block's layer show. Asked\n // for when an edit takes the last chip of a value out of this block, as a\n // value another block still shows is not left unused; a function, as a\n // saved block's html changes without any input changing.\n public readonly shownElsewhere = input<() => ReadonlySet<string>>(() => NO_VALUE_KEYS);\n\n // The html after an edit, only when it changed.\n public readonly saved = output<string>();\n\n // A press landed outside the block (or Escape): the host ends edit mode,\n // which saves.\n public readonly editEnded = output<void>();\n\n // A value's settings were asked for from its popover, by the value's key.\n // The host opens the value's settings dialog, where it can also be deleted\n // (then removeValue()).\n public readonly valueSettings = output<string>();\n\n public readonly typeScale = {\n body: `${DEFAULT_TEXT_SIZE}pt`,\n h1: `${HEADING_TEXT_SIZES[1]}pt`,\n h2: `${HEADING_TEXT_SIZES[2]}pt`,\n h3: `${HEADING_TEXT_SIZES[3]}pt`,\n color: DEFAULT_TEXT_COLOR,\n };\n\n public readonly tableLook = {\n border: `${TEXT_TABLE_BORDER_WIDTH}pt solid ${TEXT_TABLE_BORDER_COLOR}`,\n padding: `${TEXT_TABLE_CELL_PADDING.vertical}pt ${TEXT_TABLE_CELL_PADDING.horizontal}pt`,\n margin: `${TEXT_TABLE_MARGIN}pt`,\n };\n\n // Chips label values with their names instead of their numbers.\n public readonly showValueNames = signal(false);\n\n // The notice under the open block. A new one replaces it.\n public readonly notice = signal<TextNotice | null>(null);\n\n // The chip whose popover was opened last, and what the popover says about it.\n public readonly valuePopover = signal<ValuePopoverAnchor | null>(null);\n public readonly valuePopoverValue = computed<TextValue | null>(() => {\n const key = this.valuePopover()?.key;\n\n return key ? this.tokens().values?.[key] ?? null : null;\n });\n\n public readonly valueEmbeds = new ValueEmbedPlugin({\n name: 'reportValueEmbeds',\n host: () => this._host.nativeElement,\n values: () => this.tokens().values ?? {},\n scope: () => String(this.tokens().valuePageId ?? ''),\n fields: () => this.tokens(),\n menu: { command: INSERT_FIELD_BUTTON, entries: () => this._insertFieldEntries() },\n showNames: () => this.showValueNames(),\n click: (key, chip) => this._openValuePopover(key, chip),\n blocked: (block) => this._showNotice({ kind: 'blocked', block }),\n removed: (removal) => this._onValuesRemoved(removal),\n changed: () => this.dismissNotice(),\n refused: (text) => this._showNotice({ kind: 'message', text }),\n });\n\n public readonly editorConfig: FsHtmlEditorConfig = {\n floating: true,\n autofocus: true,\n placeholder: 'Type here',\n plugins: [this.valueEmbeds],\n buttons: [\n {\n name: INSERT_FIELD_BUTTON,\n title: 'Insert field',\n svgKey: 'tags',\n // Options make it a dropdown. Its entries are the block's own, filled\n // in by ValueEmbedPlugin each time an editor is built.\n options: {},\n click: (editor, token) => this.valueEmbeds.insert(token),\n },\n {\n name: VALUE_NAMES_BUTTON,\n title: 'Show value names',\n svgKey: 'textMore',\n click: () => this.showValueNames.update((names) => !names),\n },\n ],\n froalaConfig: {\n toolbarButtons: [\n 'paragraphFormat', 'fontSize', '|',\n 'bold', 'italic', 'underline', 'strikeThrough', 'textColor', '|',\n 'align', 'formatUL', 'formatOL', 'insertTable', '|',\n 'insertLink', INSERT_FIELD_BUTTON, VALUE_NAMES_BUTTON, 'clearFormatting',\n ],\n // A table's popup offers only what the server keeps: no table or cell\n // styles (classes) and no footer row.\n tableEditButtons: [\n 'tableHeader', 'tableRemove', 'tableRows', 'tableColumns', '-',\n 'tableCells', 'tableCellBackground', 'tableCellVerticalAlign', 'tableCellHorizontalAlign',\n ],\n tableDefaultWidth: '100%',\n // Both are positioned in screen space inside the canvas's CSS scale, so\n // they land off the table; rows and columns are added from the table's\n // popup instead.\n tableResizer: false,\n tableInsertHelper: false,\n paragraphFormat: { N: 'Normal', H1: 'Heading 1', H2: 'Heading 2', H3: 'Heading 3' },\n paragraphFormatSelection: true,\n fontSize: FONT_SIZES,\n fontSizeUnit: 'pt',\n fontSizeSelection: true,\n htmlAllowedTags: ALLOWED_TAGS,\n htmlAllowedAttrs: ['style', 'href', 'target', 'rel', 'colspan', 'rowspan', ...VALUE_EMBED_ATTRIBUTES],\n htmlAllowedStyleProps: ALLOWED_STYLES,\n htmlIgnoreCSSProperties: IGNORED_SHEET_STYLES,\n htmlRemoveTags: ['script', 'style'],\n // Inline styles rather than Froala's fr-* classes, which neither the\n // server nor the exports know.\n useClasses: false,\n // A paste is its words only: a pasted table flattens to text.\n pastePlain: true,\n // Every keystroke reaches the model straight away, so ending the edit an\n // instant after typing never loses the last word.\n typingTimer: 0,\n },\n };\n\n public readonly displayHtml = computed<SafeHtml>(() => this._sanitizer.bypassSecurityTrustHtml(\n fillTextTokens(this.html(), this.tokens()),\n ));\n\n // The block shows nothing: no words and no table. A new block is stored\n // empty, and an emptied editor can still leave a bare <p><br></p>.\n public readonly isBlank = computed(() => {\n const body = new DOMParser().parseFromString(this.html(), 'text/html').body;\n\n return !body.textContent?.trim() && !body.querySelector('table');\n });\n\n // What the editor holds right now.\n public draft = '';\n\n private readonly _editor = viewChild(FsHtmlEditorComponent);\n private readonly _valuePopoverAnchor = viewChild('valuePopoverAnchor', { read: ElementRef });\n private readonly _sanitizer = inject(DomSanitizer);\n private readonly _host: ElementRef<HTMLElement> = inject(ElementRef);\n private readonly _destroyRef = inject(DestroyRef);\n private _isOpen = false;\n private _noticeTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n // Opening seeds the draft; closing — whoever closed it: a press outside,\n // Escape, the block being deselected or edit mode ending — saves it.\n effect(() => {\n const editing = this.editing();\n\n untracked(() => {\n if (editing && !this._isOpen) {\n this._isOpen = true;\n this.draft = this.html();\n } else if (!editing && this._isOpen) {\n this._finish();\n }\n });\n });\n\n // Chips, and the Insert field menu, follow the block's values and fields\n // and the names toggle.\n effect(() => {\n this.tokens();\n this.showValueNames();\n untracked(() => this.valueEmbeds.refresh());\n });\n\n // A press anywhere that is not the block or the editor's own chrome ends\n // the edit. Captured, so it is seen before the canvas or a sibling\n // component acts on the same press.\n const onPress = (event: PointerEvent) => this._onDocumentPress(event);\n document.addEventListener('pointerdown', onPress, true);\n this._destroyRef.onDestroy(() => {\n document.removeEventListener('pointerdown', onPress, true);\n this._clearNoticeTimer();\n });\n }\n\n public onKeydown(event: KeyboardEvent): void {\n if (this.editing() && event.key === 'Escape') {\n event.preventDefault();\n this._close();\n }\n }\n\n // Take a value out of the text: its settings dialog deleted it.\n public removeValue(key: string): void {\n this.valueEmbeds.removeKey(key);\n }\n\n // Only for a value the page has: a chip naming no value there has no\n // settings to open.\n public openValueSettings(popover: FsPopoverRef): void {\n popover.close();\n const key = this.valuePopover()?.key;\n if (key && this.tokens().values?.[key]) {\n this.valueSettings.emit(key);\n }\n }\n\n public removeBlockedSelection(): void {\n const notice = this.notice();\n if (notice?.kind === 'blocked') {\n notice.block.removeSelection?.();\n }\n this.dismissNotice();\n }\n\n // Put back the values an edit left unused: the editor's own undo of it.\n public undoValuesUnused(): void {\n const notice = this.notice();\n if (notice?.kind === 'unused') {\n notice.undo();\n }\n this.dismissNotice();\n }\n\n public dismissNotice(): void {\n this._clearNoticeTimer();\n this.notice.set(null);\n }\n\n // What Insert field lists, in order: the page and report fields, each filter\n // of the report by its label in the filter bar's order, then every value of\n // the block's layer by its name, whether any text shows it or not.\n private _insertFieldEntries(): EmbedMenuEntry[] {\n const context = this.tokens();\n\n return [\n ...textFields(context).map(({ field, name }) => ({ token: fieldToken(field), name })),\n ...Object.entries(context.values ?? {}).map(([key, value]) => ({ token: valueToken(key), name: value.name })),\n ];\n }\n\n private _openValuePopover(key: string, chip: HTMLElement): void {\n const host = this._host.nativeElement;\n const hostRect = host.getBoundingClientRect();\n const chipRect = chip.getBoundingClientRect();\n // The canvas is CSS-scaled; the anchor sits in the block's own pixels.\n const scale = host.offsetWidth ? hostRect.width / host.offsetWidth : 1;\n\n this.valueEmbeds.hideToolbar();\n this.valuePopover.set({\n key,\n chip,\n left: (chipRect.left - hostRect.left) / scale,\n top: (chipRect.top - hostRect.top) / scale,\n width: chipRect.width / scale,\n height: chipRect.height / scale,\n });\n\n // fs-popover opens on a click on its element: once the anchor has moved\n // over the chip, click it.\n setTimeout(() => this._valuePopoverAnchor()?.nativeElement.click());\n }\n\n private _showNotice(notice: TextNotice): void {\n this._clearNoticeTimer();\n this.notice.set(notice);\n this._noticeTimer = setTimeout(() => this.notice.set(null), VALUE_BLOCK_NOTICE_MS);\n }\n\n private _clearNoticeTimer(): void {\n if (this._noticeTimer) {\n clearTimeout(this._noticeTimer);\n this._noticeTimer = null;\n }\n }\n\n // An edit took the last chip of some values out of this block. Counted are\n // the values the layer no longer reads: shown by no block, this one or\n // another, nor read by a formula one of them shows. They are not deleted:\n // saving html never deletes a value.\n private _onValuesRemoved(removal: ValueEmbedRemoval): void {\n const elsewhere = [...this.shownElsewhere()()];\n const values = this.tokens().values ?? {};\n const before = readKeys([...removal.before, ...elsewhere], values);\n const after = readKeys([...removal.after, ...elsewhere], values);\n const count = [...before].filter((key) => !after.has(key) && !!values[key]).length;\n\n if (count > 0) {\n this._showNotice({ kind: 'unused', count, undo: removal.undo });\n }\n }\n\n private _onDocumentPress(event: PointerEvent): void {\n if (!this.editing()) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n if (target && (this._host.nativeElement.contains(target) || target.closest(EDITOR_CHROME))) {\n return;\n }\n\n this._close();\n }\n\n // Save NOW, then ask the host to close. Saving here rather than waiting for\n // the editing input to flip matters: the same press may be on a page tab,\n // and by the time the input changed this block could already be destroyed,\n // with its edit gone.\n private _close(): void {\n this._syncDraft();\n this._finish();\n this.editEnded.emit();\n }\n\n // Read the editor directly rather than trusting the last model update.\n private _syncDraft(): void {\n const html = this._editor()?.editor?.html?.get();\n if (typeof html === 'string') {\n this.draft = html;\n }\n }\n\n private _finish(): void {\n if (!this._isOpen) {\n return;\n }\n\n this._isOpen = false;\n this.dismissNotice();\n if (this.draft !== this.html()) {\n this.saved.emit(this.draft);\n }\n }\n}\n","@if (editing()) {\n <!-- Floating fs-html-editor: no frame, Froala's inline toolbar pops up over\n the text. pointerdown stays here so a press in the text never starts a\n drag of the block or a pan of the canvas. -->\n <fs-html-editor\n class=\"text-content editing\"\n [config]=\"editorConfig\"\n [(ngModel)]=\"draft\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n </fs-html-editor>\n\n <!-- One notice at a time: an edit stopped because it would have removed\n values, an edit that left values no text reads, or a refused command.\n mousedown keeps the editor's focus and selection, so Undo reaches it. -->\n @if (notice(); as current) {\n <div\n class=\"value-notice fs-row.gap-sm\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault()\">\n @switch (current.kind) {\n @case ('blocked') {\n @if (current.block.removeSelection) {\n <span>\n This selection includes {{ current.block.count }} {{ current.block.count === 1 ? 'value' : 'values' }}.\n </span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"removeBlockedSelection()\">\n Remove text and {{ current.block.count === 1 ? 'value' : current.block.count + ' values' }}\n </button>\n } @else {\n <span>To take a value out, select it, then press Delete.</span>\n }\n }\n @case ('unused') {\n <span>{{ current.count }} {{ current.count === 1 ? 'value' : 'values' }} moved to Not used</span>\n <button\n mat-button\n color=\"primary\"\n type=\"button\"\n (click)=\"undoValuesUnused()\">\n Undo\n </button>\n }\n @case ('message') {\n <span>{{ current.text }}</span>\n }\n }\n <button\n mat-button\n type=\"button\"\n (click)=\"dismissNotice()\">\n Dismiss\n </button>\n </div>\n }\n} @else if (editMode() && isBlank()) {\n <!-- An empty block while the canvas is laid out: a hint in the block's own\n type, never its html, so nothing is typed onto it or exported. -->\n <div class=\"text-content text-hint\">Double-click to edit</div>\n} @else {\n <div\n class=\"text-content\"\n [innerHTML]=\"displayHtml()\">\n </div>\n}\n\n<!-- A clicked value chip's popover: an fs-popover on an invisible anchor laid\n over the chip (the chip itself belongs to the editor). Outside the editing\n block, so a popover still open when editing ends closes the usual way. -->\n<span\n #valuePopoverAnchor\n class=\"value-popover-anchor\"\n aria-hidden=\"true\"\n fsPopover\n trigger=\"click\"\n wrapperClass=\"value-popover-wrapper\"\n [template]=\"valuePopoverTemplate\"\n [indication]=\"false\"\n [maxWidth]=\"320\"\n [style.left.px]=\"valuePopover()?.left\"\n [style.top.px]=\"valuePopover()?.top\"\n [style.width.px]=\"valuePopover()?.width\"\n [style.height.px]=\"valuePopover()?.height\">\n</span>\n<ng-template\n #valuePopoverTemplate\n let-popover=\"popover\">\n <!-- What the value is, and its settings (where it can also be deleted); a\n chip naming no value on the page has no settings. -->\n <div class=\"value-popover fs-row\">\n <div class=\"fs-flex\">\n <div class=\"value-popover-name\">{{ valuePopoverValue()?.name ?? valuePopover()?.key }}</div>\n @if (!valuePopoverValue()) {\n <div class=\"small\">Not a value on this page</div>\n }\n </div>\n @if (valuePopoverValue()) {\n <button\n mat-icon-button\n type=\"button\"\n class=\"value-popover-settings\"\n matTooltip=\"Settings\"\n (click)=\"openValueSettings(popover)\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n</ng-template>\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef,\n EventEmitter, HostBinding, Input, NgZone, OnChanges, OnInit, Output, SimpleChanges, ViewChild, computed, inject,\n input, output, signal, viewChild,\n} from '@angular/core';\n\n\nimport { MatIconButton } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FilterConfig, FsFilterModule } from '@firestitch/filter';\nimport { FsMenuComponent, FsMenuModule } from '@firestitch/menu';\nimport { FsMessage } from '@firestitch/message';\nimport { FsProcess } from '@firestitch/process';\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { Observable, Subject, filter as rxFilter, map, switchMap, tap } from 'rxjs';\n\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\n\nimport { openAtPoint } from '../../anchor-at-point';\nimport { ReportData } from '../../data/report.data';\nimport { ListColumnsComponent, ListColumnsDialogData } from '../../dialogs/list-columns/list-columns.component';\nimport {\n DRILL_CRUMB_SEPARATOR, DRILL_RESET_MESSAGE, adoptedDrillPath, drillCrumbLabels, drillOutsideMessage,\n drillResetNoted,\n} from '../../drill-crumbs';\nimport {\n ComponentData,\n ComponentSettings,\n FilterGroupValue,\n KpiConfig,\n ReportComponent as ReportComponentModel,\n ReportComponentType,\n ReportFilterGroup,\n} from '../../interfaces/report.interface';\nimport { ReportExportFormat } from '../../interfaces/report-export-format.type';\nimport { ReportMarkAction } from '../../interfaces/report-mark-action.type';\nimport { ReportMarkClick } from '../../interfaces/report-mark-click.interface';\nimport { TileLoadResult } from '../../interfaces/tile-load-result.interface';\nimport { kpiCardSettings, sameKpiCardSettings } from '../../kpi-card';\nimport { componentPaddingCss } from '../../layout';\nimport { listHideableColumns } from '../../list-config';\nimport {\n MARK_ACTION_LABELS, decideMarkClick, drillDownPath, markActions, tileMarkActions,\n} from '../../mark-click';\nimport {\n LIST_SEARCH_ITEM, filterItemForGroup, groupValuesFromQuery, listSearchItem,\n} from '../../report-filter-items';\nimport { groupValueSignature } from '../../report-filter-items';\nimport { offeredViewerFeatures } from '../../report-viewer-features';\nimport { ReportFilterOptionsService } from '../../services/report-filter-options.service';\nimport { movedGroupValues, ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { followsGroupBy } from '../../group-by';\nimport { tileLoads } from '../../tile-loads';\nimport { ComponentChartComponent } from '../component-chart/component-chart.component';\nimport { ComponentGridComponent } from '../component-grid/component-grid.component';\nimport { ComponentKpiComponent } from '../component-kpi/component-kpi.component';\nimport { ComponentListComponent } from '../component-list/component-list.component';\nimport { ComponentTextComponent } from '../component-text/component-text.component';\nimport { TextTokenContext, fillTitleTokens } from '../../text';\nimport { NO_VALUE_KEYS, isDrawn, valueKeys } from '../../values';\nimport { CanvasSnapper, PX_PER_INCH } from '../report-canvas/report-canvas.component';\n\n\n// Resize handles, named by compass direction.\nconst HANDLES = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'] as const;\ntype Handle = typeof HANDLES[number];\n\nconst MIN_W = 0.6; // inches\nconst MIN_H = 0.4; // inches\n\n// The tiles that read their own rows: a list through FsList paging, a grid\n// through fs-grid's source. This component loads every other tile's data.\nconst SELF_READING_TYPES: readonly ReportComponentType[] = ['list', 'grid'];\n\n// Two presses on a text block this close together open its editor. Detected\n// here rather than with a dblclick listener because the drag loop claims the\n// pointer on every press, and a browser is not obliged to deliver dblclick\n// through a captured, default-prevented pointer.\nconst DOUBLE_PRESS_MS = 400;\n\n// One component on the page: title bar, the type-specific body (chart | list\n// | kpi), a menu (settings, filter toggles, export) — and the editing\n// interactions: click selects; the selection frame shows 8 resize handles;\n// dragging the body moves with smart alignment guides (via the canvas\n// snapper); everything works at any zoom (pixel deltas ÷ zoom·96 → inches).\n//\n// Charts and KPIs fetch their own data here; lists fetch inside\n// ComponentListComponent through FsList paging, and grids inside\n// ComponentGridComponent through fs-grid's source.\n@Component({\n selector: 'app-report-component',\n templateUrl: './report-component.component.html',\n styleUrls: ['./report-component.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatIcon,\n MatIconButton,\n MatProgressSpinner,\n MatTooltip,\n FsFilterModule,\n FsMenuModule,\n ComponentChartComponent,\n ComponentGridComponent,\n ComponentKpiComponent,\n ComponentListComponent,\n ComponentTextComponent,\n ],\n})\nexport class ReportComponentComponent implements OnInit, OnChanges {\n\n @Input() public reportId: number;\n @Input() public component: ReportComponentModel;\n @Input() public groups: Map<number, ReportFilterGroup>;\n @Input() public editMode = false;\n // The canvas zoom — converts on-screen pixel deltas back to inches.\n @Input() public zoom = 1;\n @Input() public snapper: CanvasSnapper | null = null;\n @Input() public selected = false;\n\n @Output() public selectComponent = new EventEmitter<number>();\n @Output() public positionChanged = new EventEmitter<{ componentId: number } & Record<string, number>>();\n @Output() public openSettings = new EventEmitter<ReportComponentModel>();\n\n // What the {{tokens}} of a text block, and of any component's title, fill\n // with where it is drawn: its page's, or the master's for a header or\n // footer component.\n public readonly tokens = input<TextTokenContext>({ pageNumber: 1, pageName: '', reportName: '' });\n\n // The value keys the other text blocks of a text's layer show, read by the\n // canvas when the text's editor asks.\n public readonly valueKeysElsewhere = input<((text: ReportComponentModel) => ReadonlySet<string>) | null>(null);\n\n // A text block was deleted from its menu — the canvas drops it.\n public readonly removed = output<number>();\n\n // A value's settings were asked for from its chip in the text, by the\n // value's key. The canvas opens them.\n public readonly valueSettings = output<string>();\n\n // The text's html was saved. Emitted on the response, so the server already\n // holds the html when the canvas reads the values it shows.\n public readonly textSaved = output<string>();\n\n // Deleting the text also deleted the values no other text on its page reads,\n // by id. The canvas has the report reloaded.\n public readonly valuesRemoved = output<number[]>();\n\n // The text block's editor is open (double-press in edit mode). Closed by focus\n // leaving the block, by deselecting it, or by leaving edit mode — each of\n // which saves.\n public readonly textEditing = signal(false);\n // A text block's html as last saved here; null until then, so the block\n // shows its stored html.\n public readonly textHtml = signal<string | null>(null);\n\n // What the other text blocks of this text's layer show, for its editor's\n // notice. Stable, so the text block's input never changes; it asks when an\n // edit takes a value's last chip out.\n public readonly shownElsewhere = (): ReadonlySet<string> =>\n this.valueKeysElsewhere()?.(this.component) ?? NO_VALUE_KEYS;\n\n @ViewChild(ComponentChartComponent)\n public chartComponent: ComponentChartComponent;\n\n // Resize handles by type: a fixed-height component (chart/list)\n // gets all eight (resize width AND height); an auto-height one (kpi) gets\n // only the side handles since its height fits its content and can't be set.\n public get resizeHandles(): readonly Handle[] {\n return this._heightAuto ? ['e', 'w'] : HANDLES;\n }\n\n // The component's header IS an fs-filter: heading template = its title (and\n // the drag handle), actions = the Settings / filter-toggles / Export menu,\n // items = its component-level filter groups, for every component type, lists\n // included, plus a list's search box. Rebuilt when a filter toggle changes which groups show,\n // and when the settings dialog changes the title or padding: setting it\n // repaints the header and body.\n public readonly filterConfig = signal<FilterConfig | null>(null);\n\n public readonly data = signal<ComponentData | null>(null);\n // A load shows a spinner centred on the tile. `loading` is the first load,\n // with nothing to show yet; a refetch keeps the data on screen, dimmed\n // under the spinner (`refreshing`). The title is never dimmed.\n public readonly loading = signal(false);\n public readonly refreshing = signal(false);\n public readonly error = signal<string | null>(null);\n\n // Which of a chart's legend entries are on, by series name. Held here and\n // handed to each option the chart builds: ngx-echarts sets an option with\n // notMerge, which would otherwise turn every entry back on at each refetch.\n public readonly legendSelected = signal<Readonly<Record<string, boolean>>>({});\n\n // A list is drawn again when a reset moves its sort: FsList reads its sort\n // only when it is created. Every other reset reloads it in place.\n public readonly listResetKey = computed(() => this._filterState.listSortResets().get(this.component?.id) ?? 0);\n\n // What a click on this tile's marks may do on its last answer: the chart\n // shows a hand and a tooltip hint for them. (While the layout is edited a\n // veil covers the body, so no mark is hovered or clicked.)\n public readonly tileActions = computed<ReportMarkAction[]>(() => tileMarkActions({\n data: this.data(),\n features: this._offeredFeatures(),\n }));\n\n // The actions the mark menu lists for the click it was opened on.\n public readonly markMenuActions = signal<ReportMarkAction[]>([]);\n public readonly markActionLabels = MARK_ACTION_LABELS;\n\n // The breadcrumb after the title while the chart is drilled ('2026', 'Q3'),\n // one label per step of its path, in the report's locale. Empty at the top\n // and while the viewer is not offered drill: a path an older server never\n // applies is kept in the state, but not shown.\n public readonly drillCrumbs = computed<string[]>(() => (this._offeredFeatures().includes('drill')\n ? drillCrumbLabels(this._filterState.drill(this.component?.id), this._filterState.formatContext())\n : []));\n public readonly drillSeparator = DRILL_CRUMB_SEPARATOR;\n\n // What an empty tile says: the drilled period it reads no day of, else\n // 'No data'.\n public readonly emptyMessage = computed(() => drillOutsideMessage(\n this.data()?.drill,\n this._filterState.formatContext(),\n ) ?? 'No data');\n\n @ViewChild('markMenu')\n public markMenu: FsMenuComponent;\n\n @ViewChild('markAnchor')\n public markAnchor: ElementRef<HTMLElement>;\n\n private readonly _text = viewChild(ComponentTextComponent);\n private _refresh$ = new Subject<void>();\n // The state version the header was last built for (filterKey).\n private readonly _headerVersion = signal(0);\n // The header groups' values as the header last showed them: as it was\n // built, then as its own bar reported each change. filterKey carries their\n // signature as built.\n private _shown = new Map<number, FilterGroupValue | null>();\n private readonly _headerValues = signal('');\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _filterOptions = inject(ReportFilterOptionsService);\n private _process = inject(FsProcess);\n private _message = inject(FsMessage);\n private _prompt = inject(FsPrompt);\n private _dialog = inject(MatDialog);\n private _lastPress = 0;\n private _destroyRef = inject(DestroyRef);\n private _zone = inject(NgZone);\n private _host: ElementRef<HTMLElement> = inject(ElementRef);\n // The features a mark action needs: served by the report's server and\n // implemented by this viewer.\n private readonly _offeredFeatures = computed(() => offeredViewerFeatures(this._filterState.viewerFeatures()));\n // The mark a first tap previewed (decideMarkClick), and the click the mark\n // menu is open for.\n private _touchedMark: string | null = null;\n private _menuClick: ReportMarkClick | null = null;\n // The group-by moved since the last answer: a path the server then drops\n // because it no longer starts at the chart's top is not news to the viewer.\n private _grainMoved = false;\n\n public ngOnInit(): void {\n this._buildFilterConfig();\n\n if (!this.isText) {\n this._rebuildHeaderOnNewState();\n }\n\n // Lists fetch through FsList and grids through fs-grid's source (each\n // reads its own rows); text has nothing to fetch, and a value is never\n // drawn (it reads inside text).\n if (!SELF_READING_TYPES.includes(this.component.type) && !this.isText && isDrawn(this.component)) {\n // One load stream (tileLoads): the first load at once, then one per\n // settled sweep of changes, each cancelling the one in flight, and an\n // answer sent before a reset is dropped.\n tileLoads(this._refresh$, () => this._load(), () => this._filterState.stateVersion())\n .pipe(\n tap((result) => this._loaded(result)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n\n this._filterState.changesFor(this.component)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._refresh$.next());\n\n // A group-by change re-buckets every tile that follows it; it isn't\n // scoped to a filter group, so it rides its own stream.\n if (followsGroupBy(this.component)) {\n this._filterState.frequencyChanges()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n this._grainMoved = true;\n this._refresh$.next();\n });\n }\n\n // A drill moves this chart alone.\n this._filterState.drillChanges(this.component.id)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._refresh$.next());\n }\n }\n\n // The report reloads (e.g. after the settings dialog adds/moves a filter)\n // hand this instance fresh `component`/`groups` inputs without re-running\n // ngOnInit. Rebuild the header config so the inline component-filter strip\n // reflects the new filters; the template recreates the fs-filter via\n // `filterKey` so it actually re-reads this config.\n public ngOnChanges(changes: SimpleChanges): void {\n // Clicking away (deselect) or leaving edit mode closes an open text editor,\n // which is what saves it.\n if ((changes.selected && !this.selected) || (changes.editMode && !this.editMode)) {\n this.textEditing.set(false);\n }\n\n // A new component object carries its own stored html.\n if (changes.component && !changes.component.firstChange) {\n this.textHtml.set(null);\n }\n\n const filtersChanged = (changes.component && !changes.component.firstChange)\n || (changes.groups && !changes.groups.firstChange);\n\n if (filtersChanged) {\n this._buildFilterConfig();\n }\n }\n\n // fs-filter reads its config only once at init, so the header is keyed on what\n // it renders that no signal carries: the set of component-level filter groups\n // AND the stored title, which lives in fs-filter's heading template. fs-filter\n // is OnPush and the heading is rendered inside ITS view, so marking this\n // component does not repaint a new title — recreating the block does, once a\n // settings save has rebuilt the config. What fills the title's tokens is\n // another matter: see shownTitle. The key also carries the state version\n // the header was built for, so an applied view, which replaces every value\n // at once, recreates it with the new values. And it carries the values the\n // header was built with: a group shown here and in the report bar (level\n // 'both') that the report bar changes is built again here, so the header\n // never shows 'West' while the data leaves West out.\n public get filterKey(): string {\n return [\n this._headerVersion(),\n this.component.title,\n ...this.componentFilterGroups.map((group) => `${group.id}:${group.level}`),\n this._headerValues(),\n ].join('|');\n }\n\n // The title as the viewer reads it: its page, report and filter fields filled\n // with the tokens of the layer it is drawn on ('Sign-ups — September 2026').\n // The header reads it, and the CSV export names its file after it. The\n // tokens are a signal, read inside fs-filter's heading, so a filter change\n // repaints the title in place rather than through filterKey: a recreated\n // header would lose what the viewer is doing in its own filters (a pick\n // landing, a half-typed keyword, an open picker), and each filter in it\n // would show the value it was built with.\n public get shownTitle(): string {\n return fillTitleTokens(this.component.title, this.tokens());\n }\n\n public get isText(): boolean {\n return this.component.type === 'text';\n }\n\n // Open the text editor in place.\n public editText(): void {\n if (!this.editMode || !this.isText) {\n return;\n }\n\n this.selectComponent.emit(this.component.id);\n this.textEditing.set(true);\n }\n\n // Take a deleted value's chips out of the text's open editor.\n public removeValue(key: string): void {\n this._text()?.removeValue(key);\n }\n\n // The editor closed with changed html. Kept locally at once so the block\n // re-renders what was typed, then replaced by what the server stored: it\n // rebuilds the html from its allowlist and drops any value token its page has\n // no value for, so the block never holds a token the server doesn't.\n public onTextSaved(html: string): void {\n this._setTextHtml(html);\n this._reportData.updateComponent(this.reportId, this.component.id, { html })\n .pipe(\n map((response) => (typeof response?.config?.html === 'string' ? response.config.html as string : html)),\n tap((stored) => {\n this._setTextHtml(stored);\n this.textSaved.emit(stored);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // The server deletes the text and then every value on its page that no other\n // text shows, and answers with their ids.\n public deleteText(): void {\n const valuesNote = valueKeys(this.component.config?.html).length\n ? ' Values no other text on this page uses are deleted with it.'\n : '';\n\n this._prompt.confirm({\n title: 'Confirm',\n template: `Are you sure you would like to delete this text?${valuesNote}`,\n })\n .pipe(\n switchMap(() => this._reportData.deleteComponent(this.reportId, this.component.id)),\n tap((response: { removedValues?: number[] }) => {\n if (response?.removedValues?.length) {\n this.valuesRemoved.emit(response.removedValues);\n }\n this.removed.emit(this.component.id);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n public get truncated(): boolean {\n return !!this.data()?.truncated;\n }\n\n // Content padding (the canvas zoom scales the page as a whole). Each edge\n // defaults to 1/8\".\n public get bodyPadding(): string {\n return componentPaddingCss(this.component);\n }\n\n // The component-level filter groups that should render as an inline control\n // strip on THIS component: a group is included when it's level=component and\n // has an enabled, session-on filter here. Report-level groups live in the\n // top bar instead. Lists use this strip like charts do: a value set here is\n // the group's value, so it reaches every component in the group.\n public get componentFilterGroups(): ReportFilterGroup[] {\n if (!this.groups) {\n return [];\n }\n\n const groupIds = new Set<number>();\n for (const filter of this.component.filters ?? []) {\n if (!filter.enabled || this._filterState.isFilterDisabled(filter.id)) {\n continue;\n }\n const group = this.groups.get(filter.filterGroupId);\n if (group && (group.level === 'component' || group.level === 'both')) {\n groupIds.add(group.id);\n }\n }\n\n return [...groupIds].map((id) => this.groups.get(id)).filter(Boolean);\n }\n\n public settings(): void {\n this.openSettings.emit(this.component);\n }\n\n // Whether the menu offers Columns: a plain list with more than one\n // configured column. A cross-tab's columns come and go with the data.\n public get hidesColumns(): boolean {\n return this.component.type === 'list' && listHideableColumns(this.component.config).length > 1;\n }\n\n // Which of a plain list's columns show. The choice is the viewer's (kept in\n // the report's state, never saved to the report), and the\n // list hides the columns in place, with no refetch.\n public chooseColumns(): void {\n const columns = (this.component.config?.columns ?? [])\n .map((column) => ({ column: column.column, label: column.label || column.column }));\n\n this._dialog.open<ListColumnsComponent, ListColumnsDialogData, string[]>(ListColumnsComponent, {\n data: { columns, hidden: [...this._filterState.hiddenColumns(this.component.id)] },\n width: '400px',\n maxWidth: '95vw',\n autoFocus: false,\n })\n .afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((hidden) => {\n // Cancel closes with nothing, which changes nothing.\n if (hidden) {\n this._filterState.setHiddenColumns(this.component.id, hidden);\n }\n });\n }\n\n // Presentation settings saved from the settings dialog. Title and padding are\n // not part of the query, so the data already fetched still stands — this only\n // repaints. The header config is rebuilt because `filterKey` changes with the\n // title and recreates the fs-filter block around it; setting the config signal\n // is also what repaints the new padding. The chart follows its box on its own\n // (ngx-echarts observes the host), so nothing is told to resize. A KPI's card\n // keys are different: settings.kpi carries the keys the server saved (never\n // the ones the dialog sent), and the server sends the target's progress and\n // the sparkline's points with the data, so a change to them reloads it.\n public applySettings(settings: ComponentSettings): void {\n const cardChanged = !!settings.kpi\n && !sameKpiCardSettings(settings.kpi, kpiCardSettings(this.component.config as KpiConfig));\n\n this.component.title = settings.title;\n this.component.config = { ...this.component.config, padding: settings.padding, ...(settings.kpi ?? {}) };\n\n this._buildFilterConfig();\n\n if (cardChanged) {\n this._refresh$.next();\n }\n }\n\n // The CSV is what the screen shows, so it carries the tile's interaction\n // state (tileDataState): the group-by grain for a tile that follows it, a\n // chart's drill path, the viewer's header sort, search and hidden columns\n // for a list (a searched list exports only the rows the search leaves, and\n // the hidden columns stay out of the file), and the groups that match\n // 'any'; a table's layout as the viewer changed it; and its title as the\n // header reads it (shownTitle), which the server names the file after. A\n // note the server returns (the file was cut) is shown before the download\n // starts, so a short file never passes for the whole result.\n public exportCsv(): void {\n this._export('csv');\n }\n\n // The same file as an Excel workbook: numbers stay numbers with their\n // formats, and a table is drawn as the screen draws it (group rows, totals).\n public exportExcel(): void {\n this._export('xlsx');\n }\n\n private _export(format: ReportExportFormat): void {\n const filters = this._filterState.resolveForComponent(this.component);\n const layout = this.component.type === 'grid' ? this._filterState.gridSessionLayout(this.component) : null;\n const state = { ...this._filterState.tileState(this.component), ...(layout ? { layout } : {}) };\n const title = this.shownTitle;\n\n this._process.download(\n `Exporting ${title || 'component'}`,\n this._reportData.exportComponent(this.reportId, this.component.id, filters, state, title, {}, format)\n .pipe(\n tap(({ notes }) => notes?.length && this._message.warning(notes.join(' '))),\n map(({ url }) => url),\n ),\n );\n }\n\n // The one click handler (B10.2): every click on a mark of this tile, a\n // chart's or a KPI's value, comes here, so its actions never compete. The\n // rule (decideMarkClick) does nothing without an action, lets a first tap\n // show the tooltip, runs a lone action at once, and opens the mark menu at\n // the click for two or more. Not while the layout is edited.\n public onMarkClick(click: ReportMarkClick): void {\n if (this.editMode) {\n return;\n }\n\n const actions = markActions(click, { data: this.data(), features: this._offeredFeatures() });\n const decision = decideMarkClick(click, actions, this._touchedMark);\n this._touchedMark = decision.touched;\n\n if (decision.outcome === 'run') {\n this._runMarkAction(decision.actions[0], click);\n } else if (decision.outcome === 'menu') {\n this._openMarkMenu(decision.actions, click);\n }\n }\n\n // A click or a tap on the chart that hit no mark: a tap held for its\n // second tap is let go, so tapping that mark again shows its tooltip first.\n public onMarkMiss(): void {\n this._touchedMark = null;\n }\n\n // A row of the mark menu: runs its action for the click the menu opened on.\n public runMarkAction(action: ReportMarkAction): void {\n const click = this._menuClick;\n this._menuClick = null;\n\n if (click) {\n this._runMarkAction(action, click);\n }\n }\n\n // Back up the drill path to its first `depth` steps: 0 is the chart's top\n // (the title's crumb and Back to top), and a crumb goes back to the period\n // it names. The chart reads again (drillChanges).\n public drillTo(depth: number): void {\n if (this.editMode) {\n return;\n }\n\n this._filterState.setDrill(this.component.id, this._filterState.drill(this.component.id).slice(0, depth));\n }\n\n // One level up: the period the chart is drilled into is left.\n public drillUp(): void {\n this.drillTo(Math.max(0, this._filterState.drill(this.component.id).length - 1));\n }\n\n // Any interaction inside a component must never start a canvas pan (the\n // zoom-pan host listens for mousedown/touchstart at the container level).\n public stopCanvasPan(event: Event): void {\n event.stopPropagation();\n }\n\n public onComponentPointerDown(event: PointerEvent): void {\n event.stopPropagation();\n if (this.editMode && !this.selected) {\n this.selectComponent.emit(this.component.id);\n }\n }\n\n // ----- edit-mode gestures ---------------------------------------------------\n\n public onDragStart(event: PointerEvent): void {\n if (!this.editMode || this.textEditing()) {\n return;\n }\n\n // A second press on a text block opens its editor instead of dragging.\n if (this.isText) {\n const now = Date.now();\n const isDoublePress = now - this._lastPress < DOUBLE_PRESS_MS;\n this._lastPress = now;\n\n if (isDoublePress) {\n event.preventDefault();\n event.stopPropagation();\n this.editText();\n\n return;\n }\n }\n\n this.selectComponent.emit(this.component.id);\n\n this._track(event, (deltaX, deltaY) => {\n let x = Math.max(0, this._origin.x + this._inches(deltaX));\n let y = Math.max(0, this._origin.y + this._inches(deltaY));\n\n if (this.snapper) {\n ({ x, y } = this.snapper.snapMove(this.component, x, y));\n }\n\n this.component.x = x;\n this.component.y = y;\n this._applyGeometry();\n }, () => this._emitGeometry());\n }\n\n public onResizeStart(event: PointerEvent, handle: Handle): void {\n if (!this.editMode) {\n return;\n }\n\n this.selectComponent.emit(this.component.id);\n\n this._track(event, (deltaX, deltaY) => {\n const dx = this._inches(deltaX);\n const dy = this._inches(deltaY);\n let { x, y, w, h } = this._origin;\n\n if (handle.includes('e')) {\n w = Math.max(MIN_W, this._origin.w + dx);\n }\n if (handle.includes('s')) {\n h = Math.max(MIN_H, this._origin.h + dy);\n }\n if (handle.includes('w')) {\n const clamped = Math.min(dx, this._origin.w - MIN_W);\n x = this._origin.x + clamped;\n w = this._origin.w - clamped;\n }\n if (handle.includes('n')) {\n const clamped = Math.min(dy, this._origin.h - MIN_H);\n y = this._origin.y + clamped;\n h = this._origin.h - clamped;\n }\n\n let geometry = { x, y, w, h };\n if (this.snapper) {\n geometry = this.snapper.snapResize(this.component, geometry, handle);\n }\n\n Object.assign(this.component, geometry);\n this._applyGeometry();\n this.chartComponent?.resize();\n }, () => this._emitGeometry());\n }\n\n // (Re)build the header fs-filter config: heading template renders the title\n // and items are this component's component-level filter groups. The actions\n // menu (Settings / Export CSV) is NOT here — it's a standalone kebab floated\n // top-right in the template, so its button height no longer drives the header\n // row's height (which would otherwise inflate the heading by ~40px).\n //\n // A list also gets a search box over its text columns, unless its header\n // shows a keyword group (ReportFilterStateService.listSearchable, which also\n // drops a search kept from before such a group appeared).\n //\n // `reported` is what this header last reported for each of its groups,\n // starting from the values it is built with. A change sets only the groups\n // whose header value moved (movedGroupValues): fs-filter reports every item\n // on any change, and a group shown in the report bar too may have changed\n // there since, without this header being repainted.\n private _setTextHtml(html: string): void {\n this.component.config = { ...this.component.config, html };\n this.textHtml.set(html);\n }\n\n private _buildFilterConfig(): void {\n const groups = this.componentFilterGroups;\n const listSearch = this._filterState.listSearchable(this.component);\n const reported = new Map(groups.map((group) => [group.id, this._filterState.value(group.id) ?? null]));\n const features = this._filterState.viewerFeatures();\n const report = this._filterState.report();\n\n this._shown = reported;\n this._headerValues.set([...reported.values()].map(groupValueSignature).join('|'));\n this._headerVersion.set(this._filterState.stateVersion());\n this.filterConfig.set({\n // fs-filter never touches the URL or persists filter state: a report\n // keeps no state in the URL. The values are owned by\n // ReportFilterStateService.\n queryParam: false,\n persist: false,\n items: [\n ...groups.map((group) =>\n filterItemForGroup(group, this._filterOptions, report, this._filterState.value(group.id), features)),\n ...(listSearch ? [listSearchItem(this._filterState.listSearch(this.component.id))] : []),\n ],\n // Typing in the search box must not refetch through the groups, nor set\n // a stale group value back, and a group change must not refetch through\n // the search.\n change: (query) => {\n const values = groupValuesFromQuery(query ?? {}, this.componentFilterGroups);\n\n for (const { groupId, value } of movedGroupValues(reported, values)) {\n this._filterState.setValue(groupId, value);\n }\n\n if (listSearch) {\n this._filterState.setListSearch(this.component.id, String(query?.[LIST_SEARCH_ITEM] ?? ''));\n }\n },\n // 'Clear filters' puts this header's own groups back on their authored\n // defaults. fs-filter reports its own cleared items (change) just\n // before this, so the reset wins.\n clear: () => this._filterState.resetGroupsToDefaults(groups.map((group) => group.id)),\n // The chip shows exactly while one of those groups differs from what\n // that clear puts back (groupsDifferFromDefaults). fs-filter's own rule\n // compares the items with the values this header was built with, which\n // may be the viewer's own picks, and would offer a clear that changes\n // nothing.\n clearVisible: () => this._filterState.groupsDifferFromDefaults(groups.map((group) => group.id)),\n });\n }\n\n // resetToDefaults() moves the state version and announces a full change\n // (null). The header is built again for the new version, and\n // filterKey, which carries it, recreates the block: fs-filter reads its\n // config once. Any other full change (a reload, the match) leaves it be.\n // A change to one group the header shows with another value (another bar\n // set it) builds it again too.\n private _rebuildHeaderOnNewState(): void {\n this._filterState.changesFor(this.component)\n .pipe(\n rxFilter((groupId) => (groupId === null\n ? this._filterState.stateVersion() !== this._headerVersion()\n : this._showsOtherValue(groupId))),\n tap(() => this._buildFilterConfig()),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // Whether the header shows a group with a value other than the one stored\n // for it. A change the header's own bar made is what it shows already.\n private _showsOtherValue(groupId: number): boolean {\n return this._shown.has(groupId)\n && groupValueSignature(this._shown.get(groupId)) !== groupValueSignature(this._filterState.value(groupId));\n }\n\n private _origin = { x: 0, y: 0, w: 0, h: 0 };\n\n // Pointer-capture gesture loop: runs outside Angular, repaints imperatively,\n // and finishes back inside Angular (selection/persistence).\n private _track(\n event: PointerEvent,\n onMove: (deltaX: number, deltaY: number) => void,\n onEnd: () => void,\n ): void {\n event.preventDefault();\n event.stopPropagation();\n\n const handle = event.target as HTMLElement;\n handle.setPointerCapture(event.pointerId);\n\n this._origin = {\n x: this.component.x,\n y: this.component.y,\n w: this.component.w,\n h: this.component.h,\n };\n const startX = event.clientX;\n const startY = event.clientY;\n\n this._zone.runOutsideAngular(() => {\n const move = (e: PointerEvent) => onMove(e.clientX - startX, e.clientY - startY);\n const end = () => {\n handle.releasePointerCapture(event.pointerId);\n handle.removeEventListener('pointermove', move);\n handle.removeEventListener('pointerup', end);\n handle.removeEventListener('pointercancel', end);\n\n this._zone.run(() => {\n this.snapper?.clear();\n onEnd();\n });\n };\n\n handle.addEventListener('pointermove', move);\n handle.addEventListener('pointerup', end);\n handle.addEventListener('pointercancel', end);\n });\n }\n\n private _emitGeometry(): void {\n this.component.x = this._round(this.component.x);\n this.component.y = this._round(this.component.y);\n this.component.w = this._round(Math.max(MIN_W, this.component.w));\n this.component.h = this._round(Math.max(MIN_H, this.component.h));\n this._applyGeometry();\n this.chartComponent?.resize();\n\n this.positionChanged.emit({\n componentId: this.component.id,\n x: this.component.x,\n y: this.component.y,\n w: this.component.w,\n h: this.component.h,\n });\n }\n\n // Auto height (box fits its content) vs fixed (use `h` exactly). Derived from\n // type, server-side: KPI tiles are auto; charts and lists are fixed — charts\n // fit the box and never overflow, lists scroll inside it.\n private get _heightAuto(): boolean {\n return this.component.autoHeight !== false;\n }\n\n // Drives the auto-only CSS default (empty-state baseline) so it never applies\n // to a fixed-height component.\n @HostBinding('class.height-auto')\n public get heightAuto(): boolean {\n return this._heightAuto;\n }\n\n // Screen pixels → inches at the current zoom.\n private _inches(pixels: number): number {\n return pixels / (this.zoom * PX_PER_INCH);\n }\n\n // Clean persisted values: hundredths of an inch.\n private _round(value: number): number {\n return Math.round(value * 100) / 100;\n }\n\n // The canvas positions the host via [style]; mid-gesture we set it directly\n // so OnPush never re-renders in the move loop.\n private _applyGeometry(): void {\n const style = this._host.nativeElement.style;\n style.left = `${this.component.x * PX_PER_INCH}px`;\n style.top = `${this.component.y * PX_PER_INCH}px`;\n style.width = `${this.component.w * PX_PER_INCH}px`;\n\n // Auto (kpi): no fixed height — the box sizes to its content. Fixed\n // (chart/list): `h` is the exact height. Mirrors the canvas [style] binding\n // so the mid-gesture paint matches the post-gesture re-render.\n if (this._heightAuto) {\n style.height = '';\n } else {\n style.height = `${this.component.h * PX_PER_INCH}px`;\n }\n }\n\n // ----- data ----------------------------------------------------------------\n\n // One request of the load stream (tileLoads), built from the state now. The\n // spinner shows either way; a tile with data on screen keeps it, dimmed.\n private _load(): Observable<ComponentData> {\n const first = !this.data();\n\n this.loading.set(first);\n this.refreshing.set(!first);\n this.error.set(null);\n\n const filters = this._filterState.resolveForComponent(this.component);\n // The tile's interaction state, the one its CSV and every export carry\n // (tileDataState): the grain of a tile that follows the group-by (when\n // the viewer picked one) so the backend re-buckets, a chart's drill\n // path, and the groups that match 'any'.\n const state = this._filterState.tileState(this.component);\n\n return this._reportData.componentData(this.reportId, this.component.id, filters, state);\n }\n\n // A failed load clears the data with its message, so the next load starts\n // from an empty tile and never shows the data the failure replaced. A\n // chart's answer gives its drill path.\n private _loaded(result: TileLoadResult<ComponentData>): void {\n this.data.set(result.data);\n this.error.set(result.error);\n this.loading.set(false);\n this.refreshing.set(false);\n\n if (result.error === null && result.data) {\n this._adoptDrill(result.data);\n }\n }\n\n // A chart takes the drill path its answer applied (adoptedDrillPath) while\n // the viewer is offered drill; an older server applies none, and the path\n // stays in the state. When the path it sent was cut, the viewer is told\n // once (drillResetNoted): the shorter path is what the chart reads from\n // now on, so the server cuts nothing again.\n private _adoptDrill(data: ComponentData): void {\n const grainMoved = this._grainMoved;\n this._grainMoved = false;\n\n if (this.component.type !== 'chart' || !this._offeredFeatures().includes('drill')) {\n return;\n }\n\n if (this._filterState.adoptDrill(this.component.id, adoptedDrillPath(data.drill))\n && drillResetNoted(data.drill, grainMoved)) {\n this._message.warning(DRILL_RESET_MESSAGE);\n }\n }\n\n // ----- mark clicks ---------------------------------------------------------\n\n private _runMarkAction(action: ReportMarkAction, click: ReportMarkClick): void {\n if (action === 'drill') {\n this._drillDown(click);\n }\n }\n\n // Drill down: the chart's path goes one level below the period clicked,\n // and the chart reads again (drillChanges).\n private _drillDown(click: ReportMarkClick): void {\n const path = drillDownPath(this.data()?.drill, click);\n\n if (path) {\n this._filterState.setDrill(this.component.id, path);\n }\n }\n\n // Lists the click's actions in the mark menu and opens it at the click,\n // through the zero-size anchor (openAtPoint).\n private _openMarkMenu(actions: ReportMarkAction[], click: ReportMarkClick): void {\n const anchor = this.markAnchor?.nativeElement;\n\n if (!anchor) {\n return;\n }\n\n this._menuClick = click;\n this.markMenuActions.set(actions);\n openAtPoint(anchor, click.pointer, this.zoom, () => this.markMenu?.openMenu(null));\n }\n}\n","<div\n class=\"component-box\"\n [class.editing]=\"editMode\"\n [class.text]=\"isText\"\n [class.selected]=\"selected\"\n [class.refreshing]=\"refreshing()\"\n [style.padding]=\"bodyPadding\"\n (pointerdown)=\"onComponentPointerDown($event)\"\n (mousedown)=\"stopCanvasPan($event)\"\n (touchstart)=\"stopCanvasPan($event)\">\n <!-- The header is an fs-filter: heading template = title (and the edit-mode\n drag handle), actions = the menu, items = component-level filter groups,\n the same strip for every type (lists included). fs-filter reads its\n config once, so the block is keyed on the component-filter set to be\n recreated when it changes. The title shows its tokens filled, and a\n filter change repaints it in place (shownTitle). -->\n <!-- A text block has no title bar — it IS its words, like a text box on a\n slide — so it gets neither the header nor the data actions. -->\n @for (key of isText ? [] : [filterKey]; track key) {\n <fs-filter\n class=\"component-filter\"\n [config]=\"filterConfig()\">\n <ng-template fsFilterHeading>\n <div\n class=\"component-title\"\n (pointerdown)=\"onDragStart($event)\">\n <!-- While the chart is drilled the title leads its breadcrumb:\n 'Title › 2026 › Q3', the title as the viewer reads it\n (shownTitle). The title goes back to the top and each\n crumb to the period it names; the last is where the chart is.\n A long path is cut at its left end, so the crumbs nearest the\n chart stay in view. While the layout is edited the crumbs are\n plain text (the stylesheet; drillTo does nothing then). -->\n @if (drillCrumbs().length) {\n <span class=\"drill-path\">\n <span dir=\"ltr\">\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo(0)\"\n (keydown.enter)=\"drillTo(0)\">\n {{ shownTitle }}\n </a>\n @for (label of drillCrumbs(); track $index; let last = $last) {\n <span class=\"drill-separator\">{{ drillSeparator }}</span>\n @if (last) {\n <span>{{ label }}</span>\n } @else {\n <a\n class=\"drill-crumb\"\n tabindex=\"0\"\n (click)=\"drillTo($index + 1)\"\n (keydown.enter)=\"drillTo($index + 1)\">\n {{ label }}\n </a>\n }\n }\n </span>\n </span>\n } @else {\n {{ shownTitle }}\n }\n @if (truncated) {\n <mat-icon\n class=\"truncated-icon\"\n matTooltip=\"Showing a truncated result — refine the filters to see everything.\">\n warning_amber\n </mat-icon>\n }\n </div>\n </ng-template>\n </fs-filter>\n }\n <!-- The actions menu is floated top-right (absolute) rather than living in\n fs-filter's actions slot, so its ~40px button height no longer drives the\n header row's height. It overlays the box corner; the heading reserves\n right padding so a long title ellipsises before it. -->\n @if (!isText || (editMode && !textEditing())) {\n <button\n mat-icon-button\n class=\"component-menu\"\n [fsMenuTriggerFor]=\"menu\"\n (pointerdown)=\"$event.stopPropagation()\"\n (mousedown)=\"stopCanvasPan($event)\">\n <mat-icon>more_vert</mat-icon>\n </button>\n <!-- Beside its trigger, inside the same block: an fs-menu that finds no\n trigger of its own draws one. -->\n <fs-menu #menu>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"editText()\">\n <mat-icon>edit</mat-icon>\n <span>Edit text</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!isText\"\n (click)=\"deleteText()\">\n <mat-icon>delete</mat-icon>\n <span>Delete</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillUp()\">\n <mat-icon>arrow_upward</mat-icon>\n <span>Drill up</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!drillCrumbs().length || editMode\"\n (click)=\"drillTo(0)\">\n <mat-icon>vertical_align_top</mat-icon>\n <span>Back to top</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"settings()\">\n <mat-icon>tune</mat-icon>\n <span>Settings</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportCsv()\">\n <mat-icon>download</mat-icon>\n <span>Export CSV</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"isText\"\n (click)=\"exportExcel()\">\n <mat-icon>table_view</mat-icon>\n <span>Export Excel</span>\n </ng-template>\n <ng-template\n fs-menu-item\n [hidden]=\"!hidesColumns\"\n (click)=\"chooseColumns()\">\n <mat-icon>view_column</mat-icon>\n <span>Columns</span>\n </ng-template>\n </fs-menu>\n }\n <div class=\"component-body\">\n @if (isText) {\n <app-report-component-text\n [html]=\"textHtml() ?? component.config?.html ?? ''\"\n [tokens]=\"tokens()\"\n [editing]=\"textEditing()\"\n [editMode]=\"editMode\"\n [shownElsewhere]=\"shownElsewhere\"\n (saved)=\"onTextSaved($event)\"\n (editEnded)=\"textEditing.set(false)\"\n (valueSettings)=\"valueSettings.emit($event)\">\n </app-report-component-text>\n } @else if (component.type === 'list') {\n @for (key of [listResetKey()]; track key) {\n <app-report-component-list\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-list>\n }\n } @else if (component.type === 'grid') {\n <app-report-component-grid\n [reportId]=\"reportId\"\n [component]=\"component\">\n </app-report-component-grid>\n } @else if (loading()) {\n <!-- Holds the tile's height for the spinner on the first load. -->\n <div class=\"component-state\"></div>\n } @else if (error()) {\n <div class=\"component-state error\">\n {{ error() }}\n </div>\n } @else if (!data()?.rows?.length) {\n <div class=\"component-state\">\n {{ emptyMessage() }}\n </div>\n } @else if (component.type === 'kpi') {\n <app-report-component-kpi\n [component]=\"component\"\n [data]=\"data()\"\n (markClick)=\"onMarkClick($event)\">\n </app-report-component-kpi>\n } @else {\n <app-report-component-chart\n [component]=\"component\"\n [data]=\"data()\"\n [actions]=\"tileActions()\"\n [(legendSelected)]=\"legendSelected\"\n (markClick)=\"onMarkClick($event)\"\n (markMiss)=\"onMarkMiss()\">\n </app-report-component-chart>\n }\n <!-- In edit mode a transparent veil over the body makes the WHOLE\n component draggable (industry standard: you grab the object, not just\n its title bar) and keeps inner widgets from swallowing the gesture. -->\n @if (editMode && !textEditing()) {\n <div\n class=\"drag-veil\"\n (pointerdown)=\"onDragStart($event)\">\n </div>\n }\n </div>\n <!-- A load: a spinner centred on the whole tile. On a refetch the body and\n the menu are dimmed under it (.refreshing); the title is not. -->\n @if (loading() || refreshing()) {\n <mat-progress-spinner\n class=\"load-spinner\"\n aria-label=\"Loading data\"\n mode=\"indeterminate\"\n [diameter]=\"15\">\n </mat-progress-spinner>\n }\n</div>\n<!-- The mark menu, for a click whose mark offers two or more actions. It\n opens at the click: its trigger is a zero-size anchor that\n anchor-at-point.ts moves there first. -->\n@if (!isText && !editMode) {\n <span\n #markAnchor\n [style.position]=\"'absolute'\"\n [fsMenuTriggerFor]=\"markMenu\">\n </span>\n <fs-menu #markMenu>\n @for (action of markMenuActions(); track action) {\n <ng-template\n fs-menu-item\n (click)=\"runMarkAction(action)\">\n {{ markActionLabels[action] }}\n </ng-template>\n }\n </fs-menu>\n}\n<!-- Handles live OUTSIDE the clipped box so they straddle its edges. -->\n@if (editMode && selected) {\n @for (handle of resizeHandles; track handle) {\n <div\n class=\"handle handle-{{ handle }}\"\n (mousedown)=\"stopCanvasPan($event)\"\n (pointerdown)=\"onResizeStart($event, handle)\">\n </div>\n }\n}","import {\n AfterViewInit, ChangeDetectionStrategy, Component, DestroyRef,\n ElementRef, EventEmitter, Input, OnChanges, Output, QueryList, SimpleChanges, ViewChild, ViewChildren,\n WritableSignal, computed, inject, signal,\n} from '@angular/core';\nimport { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';\n\nimport { CdkDragDrop, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsMessage } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsZoomPanComponent, FsZoomPanModule } from '@firestitch/zoom-pan';\n\nimport {\n Observable, Subject, catchError, debounceTime, distinctUntilChanged, filter as rxFilter, from, map, merge, mergeMap,\n of, switchMap, tap,\n} from 'rxjs';\n\nimport { canvasLandingPage } from '../../canvas-landing-page';\nimport { ReportData } from '../../data/report.data';\nimport { valuePicks } from '../../export/report-filter-lines';\nimport { layerFilterGroups, sameFilterFields, textFilterFields } from '../../filter-text';\nimport {\n ComponentSettings, Report, ReportComponent, ReportFilterGroup, ReportHeaderFooter, ReportMaster, ReportPage,\n ReportPageValue, ResolvedFilterValue,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_HEADING_SIZE } from '../../layout';\nimport { groupOptionsReader, pickedOptionNames } from '../../report-filter-items';\nimport { ReportFilterOptionsService } from '../../services/report-filter-options.service';\nimport { ReportFilterStateService } from '../../services/report-filter-state.service';\nimport { TextFilterField, TextTokenContext } from '../../text';\nimport { valuesMatchAnyGroupIds } from '../../tile-data-state';\nimport {\n isDrawn, layerValueKeys, sameTextValues, shownValues, textValues, valueKey, valueKeys,\n} from '../../values';\nimport { ReportComponentComponent } from '../report-component/report-component.component';\n\n\n// Screen density of the canvas: 96 CSS px per inch (the CSS reference pixel),\n// before zoom. All geometry stays in inches; only rendering multiplies by it.\nexport const PX_PER_INCH = 96;\n\n// One smart guide line, in page inches.\nexport interface GuideLine {\n orientation: 'v' | 'h';\n position: number;\n}\n\n// The snapping contract handed to each component's drag loop. Implemented by\n// the canvas because only it sees every component (alignment candidates) and\n// owns the guides overlay.\nexport interface CanvasSnapper {\n snapMove(component: ReportComponent, x: number, y: number): { x: number; y: number };\n snapResize(component: ReportComponent, geometry: { x: number; y: number; w: number; h: number }, handle: string): { x: number; y: number; w: number; h: number };\n clear(): void;\n}\n\n// One layer's values request (a page, or the master), read when it is sent:\n// the layer, the values its text shows at that moment (what reads as loading\n// until it lands) and the filter values of every value on the layer.\ninterface LayerValuesRequest {\n pageId: number | null;\n shown: ReportComponent[];\n filters: ResolvedFilterValue[];\n // While the groups match 'any', the groups that combine\n // (valuesMatchAnyGroupIds); empty otherwise.\n matchAnyGroupIds: number[];\n // Everything the layer's numbers depend on: the request, and how each value\n // it reads is defined. A reload of the report that leaves it as it was asks\n // for nothing.\n signature: string;\n}\n\n// One layer's numbers as they last arrived, by value id, and the request they\n// answer — results for another page are not this page's.\ninterface LayerValues {\n pageId: number | null;\n signature: string;\n rows: ReadonlyMap<number, ReportPageValue>;\n}\n\n// A layer whose values the canvas reads: the active page, or the master.\ninterface ValueLayer {\n // The layer as it stands, or null when none of its numbers are needed.\n source: () => ReportPage | ReportMaster | null;\n // Asks for its numbers again.\n reload$: Subject<void>;\n // Its numbers as they last arrived.\n results: WritableSignal<LayerValues | null>;\n // The request on its way, null once it has landed. A value it asks for\n // reads as loading until then, so a number on screen is never one read for\n // an earlier request (another filter, the value as it was).\n pending: WritableSignal<LayerValuesRequest | null>;\n}\n\n// A select group with options picked whose names a filter token reads,\n// keyed by the group and the picked ids (optionNamesKey).\ninterface OptionPick {\n group: ReportFilterGroup;\n reportId: number;\n values: unknown[];\n key: string;\n}\n\n// Whether two token contexts fill every token the same, so recomputing one\n// that changed nothing a token shows hands back the object the blocks have.\nfunction sameTokens(a: TextTokenContext, b: TextTokenContext): boolean {\n return a.pageNumber === b.pageNumber\n && a.pageName === b.pageName\n && a.reportName === b.reportName\n && a.valuePageId === b.valuePageId\n && sameTextValues(a.values, b.values)\n && sameFilterFields(a.filters, b.filters);\n}\n\n// One of the two bands the header and footer are drawn in.\ntype Band = 'header' | 'footer';\n\n// What the names of a select group's picked options are kept under.\nfunction optionNamesKey(groupId: number, values: unknown[]): string {\n return JSON.stringify([groupId, values.map(String)]);\n}\n\n// The fixed-size page canvas — the PowerPoint model. Pages are tabs (only the\n// ACTIVE page's components exist → only they fetch); the page is a\n// pageWidth×pageHeight INCHES sheet rendered at 96px/in inside fs-zoom-pan\n// (Ctrl/Cmd + wheel or pinch to zoom, background drag pan, toolbar buttons; a\n// plain wheel scrolls the list under the pointer).\n//\n// Components are absolutely positioned; dragging gets smart alignment guides\n// (edges + centers of siblings and the page) with snapping.\n//\n// Header and footer: the report's master components (report.master) are drawn\n// on a layer UNDER every page's own components, like a PowerPoint slide master,\n// unless the page hides them. In edit mode the host toolbar's \"Header & footer\"\n// (toggleMasterMode) switches which layer is live: the page's components dim\n// and the master's become the ones that drag, resize and snap. The header/footer bands (config.headerFooter)\n// are drawn as guides while editing and are snap lines for both layers. While\n// the header and footer are edited, an empty band says how to fill it, and\n// double-clicking a band adds a text block there with its editor open.\n//\n// Live values: a text block shows numbers inline ({{value.key}}). A value is\n// never drawn; it belongs to the page whose text shows it (the master for a\n// header or footer) and is listed in that layer's `values`. The canvas reads\n// the numbers one request per layer — the active page's and the master's —\n// and hands them to every block of the layer with the page tokens. Which\n// values a request reads is the server's call alone: the ones the text shows,\n// and the operands of the formulas among them.\n@Component({\n selector: 'app-report-canvas',\n templateUrl: './report-canvas.component.html',\n styleUrls: ['./report-canvas.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n DragDropModule,\n MatIcon,\n MatTooltip,\n FsMenuModule,\n FsZoomPanModule,\n ReportComponentComponent,\n ],\n})\nexport class ReportCanvasComponent implements OnChanges, AfterViewInit {\n\n @Input() public report: Report;\n @Input() public editMode = false;\n\n // The page the host wants on screen, by page id (a ?page= the report opened\n // with, or an opened view's page). Keyed on id rather than index so it\n // survives pages being reordered or deleted; an id that no longer resolves\n // falls back to the first page.\n @Input() public pageId: number | null = null;\n\n // A component asked for its settings dialog — the page-level host opens it\n // (it owns MatDialog + the post-save reload).\n @Output() public componentSettings = new EventEmitter<ReportComponent>();\n\n // The report's structure changed here (a page was added) — the host re-fetches\n // it (it owns the assembled report + filter state).\n @Output() public reportChanged = new EventEmitter<void>();\n\n // The page on screen changed — the host keeps it in the report's state.\n // Carries the page id, never the index.\n @Output() public pageChanged = new EventEmitter<number | null>();\n\n @ViewChild(FsZoomPanComponent)\n public zoomPan: FsZoomPanComponent;\n\n // The rendered components of the active page — only the canvas can reach the\n // one instance a settings save applies to.\n @ViewChildren(ReportComponentComponent)\n private _renderedComponents: QueryList<ReportComponentComponent>;\n\n @ViewChild('viewport', { static: true })\n private _viewport: ElementRef<HTMLDivElement>;\n\n @ViewChild('guides', { static: false })\n private _guides: ElementRef<HTMLDivElement>;\n\n public readonly PX = PX_PER_INCH;\n\n // The report's pages as the canvas draws them. This is the host's own\n // `report.pages` array, patched in place (a rename, a delete, a reorder) so\n // the host's exports see the change too. Because the array\n // and its pages keep their identity across a patch, the signal notifies on\n // every set rather than only when the reference changes.\n public readonly pages = signal<ReportPage[]>([], { equal: () => false });\n public readonly activePageIndex = signal(0);\n public readonly activePageId = computed(() => this.pages()[this.activePageIndex()]?.id ?? null);\n public readonly zoom = signal(1);\n\n // Editing the header and footer (the master layer) rather than the page.\n public readonly masterMode = signal(false);\n public groups = new Map<number, ReportFilterGroup>();\n public readonly selectedComponentId = signal<number | null>(null);\n // The components each layer draws. A value only reads inside text, so one\n // that leaked into a layer's components is still never drawn.\n public readonly activePageComponents = computed(\n () => (this.pages()[this.activePageIndex()]?.components ?? []).filter(isDrawn),\n );\n\n public readonly masterComponents = computed(\n () => (this._report()?.master?.components ?? []).filter(isDrawn),\n );\n\n // What a text block's tokens fill with on the page on screen: {{page.number}},\n // {{page.name}} and {{report.name}} (the master's footer numbers each page by\n // its position), the report's {{filter.<id>}} fields, and the values of the\n // block's layer — the active page's for a page block, the master's for a\n // header or footer block, whose id is also the editor's clipboard scope.\n // Every other component of the layer fills its title's tokens with it too.\n // The same object is handed back until something a token shows changes:\n // every component takes it as an input, and a fresh object would make each\n // text block repaint its html.\n public readonly pageTokens = computed(\n () => this._tokenContext(\n this._pageValueComponents(),\n this._pageValues,\n this.activePageId(),\n this.activePageId(),\n ),\n { equal: sameTokens },\n );\n\n public readonly masterTokens = computed(\n () => this._tokenContext(\n this._masterValueComponents(),\n this._masterValues,\n this._report()?.master?.id ?? null,\n null,\n ),\n { equal: sameTokens },\n );\n\n // The snapper handed to every component (stable identity for OnPush).\n public readonly snapper: CanvasSnapper = {\n snapMove: (component, x, y) => this._snapMove(component, x, y),\n snapResize: (component, geometry, handle) => this._snapResize(component, geometry, handle),\n clear: () => this._clearGuides(),\n };\n\n // The value keys the other text blocks of a text's layer show (the master's\n // for a header or footer block), for its editor's notice: a value another\n // block still shows is not left unused. Read when asked: saving a block\n // writes its html into its component in place, which no signal sees.\n // Stable, as the snapper is.\n public readonly valueKeysElsewhere = (text: ReportComponent): ReadonlySet<string> => {\n const layer = this._isMasterComponent(text) ? this.report?.master : this.activePage;\n\n return new Set((layer?.components ?? [])\n .filter((component) => component.type === 'text' && component.id !== text.id)\n .flatMap((component) => valueKeys(component.config?.html)));\n };\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _filterOptions = inject(ReportFilterOptionsService);\n private _prompt = inject(FsPrompt);\n private _message = inject(FsMessage);\n private _destroyRef = inject(DestroyRef);\n private _fitted = false;\n private _previousPageCount = 0;\n private _previousReportId: number | null = null;\n\n // The page id last announced through pageChanged, so a re-render that lands on\n // the same page stays quiet — hosts reload on this and an unchanged page is\n // not news.\n private _emittedPageId: number | null = null;\n\n // A text block added by double-clicking a band, whose editor opens once the\n // reloaded report draws it.\n private _editOnArrival: number | null = null;\n\n // The report input as a signal, for the token contexts and the master's\n // drawn components. Notifies on every set: a reload hands over a new report\n // even when nothing a token shows moved, and a deleted header or footer\n // block is spliced out of the same report.\n private _report = signal<Report | null>(null, { equal: () => false });\n\n // The values each layer's text can show (shown or not).\n private _pageValueComponents = computed(() => this.pages()[this.activePageIndex()]?.values ?? []);\n private _masterValueComponents = computed(() => this._report()?.master?.values ?? []);\n\n // The master's numbers are needed while some page shows the header and\n // footer, or while they are being edited.\n private _masterNeeded = computed(() => this.masterMode() || this.pages().some((page) => !page.masterHidden));\n\n // The two layers whose values are read, each on its own stream.\n private _pageValues = this._valueLayer(() => this.activePage);\n private _masterValues = this._valueLayer(() => (this._masterNeeded() ? this.report?.master ?? null : null));\n\n // Bumped when a value is renamed in place, which no signal sees.\n private _valuesRevision = signal(0);\n\n // Bumped when a filter's value changed (_watchFilters): the filter state\n // holds its values outside any signal.\n private _filterRevision = signal(0);\n\n // The names of the options picked in each select group, by optionNamesKey,\n // as they last arrived (null when they could not be read, until a filter\n // value changes and asks again), and the keys asked for since the report\n // last loaded. A pick is named once per load, so a filter set back to an\n // earlier pick reads its names at once. A reload names every pick again\n // from the fresh lists, as an option may have been renamed; a pick keeps\n // showing the names it had until the new ones land.\n private _optionNames = signal<ReadonlyMap<string, readonly string[] | null>>(new Map());\n private _optionNamesAsked = new Set<string>();\n\n // Each select group's option list, fetched once and read for every pick\n // of the group; read afresh after a reload, which may have changed a group.\n private _groupOptions = groupOptionsReader(this._reportData);\n\n // The select groups with options picked (kept or left out). Each pick not\n // asked for since the report loaded is named (_watchOptionNames).\n private _selectPicks = computed((): OptionPick[] => {\n this._filterRevision();\n const report = this._report();\n\n return (report?.filterGroups ?? [])\n .filter((group) => group.type === 'select')\n .map((group): OptionPick => {\n const values = valuePicks(this._filterState.value(group.id));\n\n return { group, reportId: report.id, values, key: optionNamesKey(group.id, values) };\n })\n .filter((pick) => pick.values.length);\n });\n\n // The value keys each layer held at the last report load, by page id and\n // master id, so a reload can tell which values were deleted.\n private _valueKeysByLayer = new Map<number, Set<string>>();\n\n constructor() {\n this._init();\n }\n\n public ngOnChanges(changes: SimpleChanges): void {\n // Leaving edit mode always returns to the page layer, so the next edit\n // session starts where people expect.\n if (changes.editMode && !this.editMode) {\n this.masterMode.set(false);\n }\n\n this.groups = new Map((this.report?.filterGroups ?? []).map((group) => [group.id, group]));\n this.pages.set(this.report?.pages ?? []);\n\n // A page just added in this tab, else the asked-for page, else the page\n // shown (the first page on another report). See canvasLandingPage.\n const reportId = this.report?.id ?? null;\n this.activePageIndex.set(canvasLandingPage({\n reportId,\n previousReportId: this._previousReportId,\n previousPageCount: this._previousPageCount,\n pageIds: this.pages().map((page) => page.id),\n pageId: this.pageId,\n activePageIndex: this.activePageIndex(),\n }));\n this._previousPageCount = this.pages().length;\n this._previousReportId = reportId;\n\n // Tell the host which page is open whenever that changes — including the\n // FIRST time the report renders, not only when someone clicks a page.\n // Hosts bind things to the open page (the report chat scopes its\n // conversations to it), and without this they would sit on no page at all\n // until the first manual page click.\n const activePageId = this.activePage?.id ?? null;\n if (activePageId !== this._emittedPageId) {\n this._emittedPageId = activePageId;\n this.pageChanged.emit(activePageId);\n }\n\n // A (re)loaded report may have gained, lost or changed values, and any\n // text may now show different ones: read again each layer whose numbers\n // that moves. Its option lists may have renamed a pick: each is named\n // again from the fresh lists.\n if (changes.report) {\n this._groupOptions = groupOptionsReader(this._reportData);\n this._optionNamesAsked.clear();\n this._report.set(this.report);\n this._dropRemovedValueChips();\n this._reloadIfChanged(this._pageValues);\n this._reloadIfChanged(this._masterValues);\n }\n }\n\n // Report heading size in px (config is points; the canvas renders at\n // 96px/in, so points × 96/72). Inherited by component titles via a CSS var.\n public get headingSizePx(): number {\n const points = this.report?.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;\n\n return points * (PX_PER_INCH / 72);\n }\n\n public ngAfterViewInit(): void {\n // Fit the page to the viewport once on first render; after that the\n // viewer's zoom choice is respected across re-renders.\n setTimeout(() => this.zoomFit());\n\n this._renderedComponents.changes\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this._editArrivedText());\n }\n\n public get activePage(): ReportPage | null {\n return this.pages()[this.activePageIndex()] ?? null;\n }\n\n // The header/footer bands, in inches (0 = no band).\n public get bands(): ReportHeaderFooter {\n return this.report?.config?.headerFooter ?? { headerHeight: 0, footerHeight: 0 };\n }\n\n // The master draws unless the page hides it — and always while it is the\n // layer being edited, so a page that hides it can still be used to edit it.\n public get isMasterShown(): boolean {\n return this.masterMode() || !this.activePage?.masterHidden;\n }\n\n // Which layer the edit gestures reach.\n public get isPageEditing(): boolean {\n return this.editMode && !this.masterMode();\n }\n\n public get isMasterEditing(): boolean {\n return this.editMode && this.masterMode();\n }\n\n public toggleMasterMode(): void {\n this.masterMode.update((value) => !value);\n this.selectedComponentId.set(null);\n }\n\n // Drop a text block where it will be found: into the footer (or header) band\n // while editing the header and footer, below the header band on a page. The\n // host re-fetches the report and it appears; double-press opens its editor.\n public addText(): void {\n if (!this.report) {\n return;\n }\n\n const { headerHeight, footerHeight } = this.bands;\n const pageWidth = this.report.pageWidth;\n const pageHeight = this.report.pageHeight;\n const isMaster = this.masterMode();\n\n let geometry = { x: 0.5, y: headerHeight + 0.5, w: Math.min(5, pageWidth - 1), h: 0.8 };\n if (isMaster) {\n const bandHeight = footerHeight || headerHeight || 0.5;\n const y = footerHeight\n ? pageHeight - footerHeight\n : (headerHeight ? 0 : pageHeight - bandHeight);\n geometry = { x: 0.5, y: y + 0.05, w: Math.min(4, pageWidth - 1), h: Math.max(0.3, bandHeight - 0.1) };\n }\n\n this._reportData.addText(this.report.id, {\n ...geometry,\n pageId: isMaster ? undefined : this.activePage?.id,\n })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this.reportChanged.emit());\n }\n\n // Whether no header or footer block reaches into the band, so it shows how\n // to fill it. Read on every check: a drag moves a block in place.\n public isBandEmpty(band: Band): boolean {\n const { top, bottom } = this._bandSpan(band);\n\n return !this.masterComponents()\n .some((component) => component.y < bottom && component.y + component.h > top);\n }\n\n // Double-clicking a band while editing the header and footer adds a text\n // block where it was clicked, the band's height, and opens its editor once\n // the host's reload draws it — the way into a header in Word.\n public addTextInBand(band: Band, event: MouseEvent): void {\n if (!this.isMasterEditing) {\n return;\n }\n\n const { top, bottom } = this._bandSpan(band);\n const pageWidth = this.report.pageWidth;\n const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();\n const clickX = ((event.clientX - rect.left) / rect.width) * pageWidth;\n const w = Math.min(4, pageWidth - 1);\n\n this._reportData.addText(this.report.id, {\n x: Math.min(Math.max(0, clickX), pageWidth - w),\n y: top + 0.05,\n w,\n h: Math.max(0.3, bottom - top - 0.1),\n })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((text: ReportComponent) => {\n this._editOnArrival = text.id;\n this.reportChanged.emit();\n });\n }\n\n // A text block deleted itself from its menu: drop it from whichever layer it\n // was on without re-fetching the report. That covers the block alone: the\n // delete also takes the values only it showed, which come back as\n // valuesRemoved, and that asks the host to reload the report.\n public onComponentRemoved(componentId: number): void {\n const layers = [this.activePage?.components, this.report?.master?.components];\n for (const components of layers) {\n const index = components?.findIndex((component) => component.id === componentId) ?? -1;\n if (index > -1) {\n components.splice(index, 1);\n }\n }\n\n this.selectedComponentId.set(null);\n this.pages.set(this.pages());\n this._report.set(this.report);\n this._message.success('Deleted text');\n }\n\n // A text block's html was saved. Saving never deletes a value, but it can\n // show one the layer has no number for: a chip pasted back from a value no\n // text showed, which the server did not read. Its layer is read again so the\n // number comes in; an edit that shows only values already read asks nothing.\n public onTextSaved(text: ReportComponent, html: string): void {\n const isMaster = this._isMasterComponent(text);\n const layer = isMaster ? this._masterValues : this._pageValues;\n const layerId = isMaster ? (this.report?.master?.id ?? null) : this.activePageId();\n const results = layer.results();\n const rows = results?.pageId === layerId ? results.rows : null;\n const values = isMaster ? this._masterValueComponents() : this._pageValueComponents();\n const unread = shownValues(values, [{ ...text, config: { ...text.config, html } }])\n .some((value) => !rows?.has(value.id));\n\n if (unread) {\n layer.reload$.next();\n }\n }\n\n // A chip's gear: open the settings of the value it names, from the block's\n // own layer, through the same output as any component's settings.\n public openValueSettings(text: ReportComponent, key: string): void {\n const values = this._isMasterComponent(text) ? this._masterValueComponents() : this._pageValueComponents();\n // The newest value holds a key, as it does in the text's tokens.\n const value = values.filter((candidate) => valueKey(candidate) === key).pop();\n\n if (value) {\n this.componentSettings.emit(value);\n }\n }\n\n // What a component's tokens fill with where it is drawn: the master's for a\n // header or footer component, the page's for any other — what its header\n // reads its title with, and so what its settings dialog shows it as.\n public componentTokens(component: ReportComponent): TextTokenContext {\n return this._isMasterComponent(component) ? this.masterTokens() : this.pageTokens();\n }\n\n // Show or hide the header and footer on one page, from its tab's kebab.\n public toggleMasterHidden(page: ReportPage): void {\n const masterHidden = !page.masterHidden;\n\n this._reportData.updatePage(this.report.id, page.id, { masterHidden })\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => {\n page.masterHidden = masterHidden;\n this.pages.set(this.pages());\n this._message.success(masterHidden ? 'Header & footer hidden on this page' : 'Header & footer shown on this page');\n });\n }\n\n public selectPage(index: number): void {\n this.activePageIndex.set(index);\n this.selectedComponentId.set(null);\n\n // Kept in step with the ngOnChanges announcement so the two can't disagree\n // about what the host was last told.\n this._emittedPageId = this.activePage?.id ?? null;\n this.pageChanged.emit(this._emittedPageId);\n }\n\n // Append a blank page; the host re-fetches the report and ngOnChanges lands\n // the view on the new (last) page.\n public addPage(): void {\n if (!this.report) {\n return;\n }\n\n this._reportData.addPage(this.report.id)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe(() => this.reportChanged.emit());\n }\n\n public pageLabel(page: ReportPage, index: number): string {\n return page.name || `Page ${index + 1}`;\n }\n\n // Rename from the tab's kebab. The page list is patched in place rather than\n // re-fetching the report: nothing else on the canvas depends on a page's\n // name, and a re-fetch would re-run every component's query to repaint a\n // chip's label.\n public renamePage(page: ReportPage): void {\n this._prompt.input({\n title: 'Edit Page Name',\n label: 'Name',\n default: page.name ?? '',\n commitLabel: 'Save',\n required: true,\n })\n .pipe(\n switchMap((name: string) => this._reportData\n .updatePage(this.report.id, page.id, { name })\n .pipe(map(() => name))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((name: string) => {\n page.name = name;\n this.pages.set(this.pages());\n this._message.success('Saved page name');\n });\n }\n\n // Delete from the tab's kebab. The confirm names the page and says the\n // components go with it — the server refuses the last page, and that refusal\n // surfaces as the API error message rather than being second-guessed here.\n public deletePage(page: ReportPage): void {\n this._prompt.confirm({\n title: 'Confirm',\n template: `Are you sure you would like to delete \"${this.pageLabel(page, this.pages().indexOf(page))}\" and everything on it?`,\n })\n .pipe(\n switchMap(() => this._reportData.deletePage(this.report.id, page.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n const pages = this.pages();\n const index = pages.indexOf(page);\n pages.splice(index, 1);\n this.pages.set(pages);\n\n // Land on the neighbour rather than snapping back to the first page —\n // deleting page 4 of 6 should leave you looking at what is now page 4.\n this.activePageIndex.set(Math.min(index, pages.length - 1));\n this._previousPageCount = pages.length;\n this.selectedComponentId.set(null);\n\n // The page on screen just stopped existing — report the neighbour we\n // landed on, so the host's state names a page the report has.\n this.pageChanged.emit(this.activePage?.id ?? null);\n\n this._message.success('Deleted page');\n });\n }\n\n // A tab was dragged to a new slot: reorder locally so the chips settle\n // immediately, keep the viewer on the page they were looking at, and persist\n // the whole sequence in one PUT.\n public onPageDropped(event: CdkDragDrop<unknown>): void {\n if (event.previousIndex === event.currentIndex) {\n return;\n }\n\n const activePage = this.activePage;\n const pages = this.pages();\n\n moveItemInArray(pages, event.previousIndex, event.currentIndex);\n this.pages.set(pages);\n\n const positions = pages.map((page, order) => {\n page.order = order;\n\n return { pageId: page.id, order };\n });\n\n if (activePage) {\n this.activePageIndex.set(pages.indexOf(activePage));\n }\n\n this._reportData.savePagePositions(this.report.id, positions)\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n // Hand presentation settings (title, padding) saved in the settings dialog to\n // the one component they belong to. Nothing here feeds the query, so that\n // component repaints and every other one on the page is left alone. A value\n // is never drawn: its title is its Name, which its chips and tokens read.\n public applyComponentSettings(componentId: number, settings: ComponentSettings): void {\n const rendered = this._renderedComponents\n .find((candidate) => candidate.component.id === componentId);\n\n if (rendered) {\n rendered.applySettings(settings);\n\n return;\n }\n\n const value = [...this._pageValueComponents(), ...this._masterValueComponents()]\n .find((candidate) => candidate.id === componentId);\n\n // The server keeps the old Name for a blank one.\n if (value && settings.title?.trim()) {\n value.title = settings.title.trim();\n this._valuesRevision.update((revision) => revision + 1);\n }\n }\n\n public selectComponent(componentId: number | null): void {\n this.selectedComponentId.set(componentId);\n }\n\n public onCanvasPointerDown(): void {\n // Background click (pan start) deselects.\n if (this.selectedComponentId() !== null) {\n this.selectComponent(null);\n }\n }\n\n // ----- zoom toolbar ---------------------------------------------------------\n\n public onZoomed(scale: number): void {\n this.zoom.set(scale);\n }\n\n public zoomIn(): void {\n this.zoomPan?.zoomIn();\n }\n\n public zoomOut(): void {\n this.zoomPan?.zoomOut();\n }\n\n public zoomFit(): void {\n const viewport = this._viewport?.nativeElement;\n if (!viewport || !this.report?.pageWidth || !this.zoomPan) {\n return;\n }\n\n const fit = Math.min(\n (viewport.clientWidth - 32) / (this.report.pageWidth * PX_PER_INCH),\n (viewport.clientHeight - 32) / (this.report.pageHeight * PX_PER_INCH),\n );\n\n this.zoomPan.zoom(Math.min(1.5, Math.max(0.1, fit)));\n this.zoomPan.move(16, 16);\n this._fitted = true;\n }\n\n public zoomActual(): void {\n this.zoomPan?.zoom(1);\n }\n\n // ----- persistence ----------------------------------------------------------\n\n // A drag/resize landed — one PUT per gesture.\n public onPositionChanged(position: { componentId: number } & Record<string, number>): void {\n this._clearGuides();\n this._reportData.savePositions(this.report.id, [position as any])\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe();\n }\n\n // ----- values ---------------------------------------------------------------\n\n // Each layer reads its values' numbers on its own stream: again when a\n // report reload changes what they depend on (ngOnChanges), when a saved text\n // shows a value it has no number for, when a filter any of its values\n // follows changes (an operand no text shows moves the formula that reads\n // it), and when it comes on screen — the active page when another page does,\n // the master when a page shows it or it is edited.\n private _init(): void {\n this._watchValues(this._pageValues, toObservable(this.activePageId));\n this._watchValues(this._masterValues, toObservable(this._masterNeeded));\n this._watchFilters();\n this._watchOptionNames();\n }\n\n // The filter tokens follow every change of a filter's value, however it\n // comes: the bar, a saved filter picked, Clear, a reload. changes()\n // also announces what no token reads (a list's sort or search, its hidden\n // columns, a drill, the page), which moves nothing here.\n private _watchFilters(): void {\n this._filterState.changes()\n .pipe(\n map(() => this._filterValuesKey()),\n distinctUntilChanged(),\n tap(() => {\n this._forgetUnreadNames();\n this._filterRevision.update((revision) => revision + 1);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // Every filter group's value as one string: all a filter token reads of\n // the filter state.\n private _filterValuesKey(): string {\n return JSON.stringify((this._report()?.filterGroups ?? [])\n .map((group) => [group.id, this._filterState.value(group.id) ?? null]));\n }\n\n // Drops the picks whose names could not be read, so the change under way\n // asks for them again rather than their tokens reading the em dash until\n // the report reloads.\n private _forgetUnreadNames(): void {\n const loaded = new Map(this._optionNames());\n const unread = [...loaded.keys()].filter((key) => loaded.get(key) === null);\n if (!unread.length) {\n return;\n }\n\n unread.forEach((key) => {\n loaded.delete(key);\n this._optionNamesAsked.delete(key);\n });\n this._optionNames.set(loaded);\n }\n\n // Names each select pick the filter tokens show, once per group and picked\n // ids for each load of the report, as the bar's chips name them: a name its\n // lists taught, else the group's option list, which is fetched once for all\n // of its picks; nothing is asked while nothing is picked.\n private _watchOptionNames(): void {\n toObservable(this._selectPicks)\n .pipe(\n mergeMap((picks) => from(picks.filter((pick) => !this._optionNamesAsked.has(pick.key)))),\n tap((pick) => this._optionNamesAsked.add(pick.key)),\n mergeMap((pick) => pickedOptionNames(\n this._groupOptions(pick.group, pick.reportId),\n pick.values,\n (value) => this._filterOptions.label(pick.group.id, value),\n )\n .pipe(map((names) => ({ key: pick.key, names })))),\n tap(({ key, names }) => this._optionNames.update((loaded) => new Map(loaded).set(key, names))),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n private _valueLayer(source: () => ReportPage | ReportMaster | null): ValueLayer {\n return {\n source,\n reload$: new Subject<void>(),\n results: signal<LayerValues | null>(null),\n pending: signal<LayerValuesRequest | null>(null),\n };\n }\n\n // Triggers landing together (a reload that also changes the page) make one\n // request, and a newer request drops the one still in flight. Any other\n // change of the screen's state (changes) asks again only when it moved\n // the request: the bar reset (stateVersion moves on\n // it), the match changed, or, while the groups match 'any', a group the\n // values have no member of took or lost a value.\n private _watchValues(layer: ValueLayer, onScreen$: Observable<unknown>): void {\n merge(\n layer.reload$,\n onScreen$,\n this._filterState.changesForAny(() => layer.source()?.values ?? []).pipe(debounceTime(300)),\n this._filterState.changes().pipe(\n debounceTime(300),\n rxFilter(() => this._requestMoved(layer)),\n ),\n )\n .pipe(\n debounceTime(0),\n map(() => this._layerRequest(layer.source())),\n tap((request) => layer.pending.set(request)),\n switchMap((request) => this._loadValues(request)),\n tap((loaded) => {\n layer.results.set(loaded);\n layer.pending.set(null);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // A reload of the report reads a layer's numbers again only when something\n // they depend on moved: a rename, or an edit to a tile, hands over a new\n // report and leaves every number as it was. Compared with the request on its\n // way, else the one whose numbers are on screen.\n private _reloadIfChanged(layer: ValueLayer): void {\n if (this._requestMoved(layer)) {\n layer.reload$.next();\n }\n }\n\n // Whether the layer's request now differs from the one on its way, else\n // the one whose numbers are on screen.\n private _requestMoved(layer: ValueLayer): boolean {\n const last = layer.pending() ?? layer.results();\n\n return this._layerRequest(layer.source()).signature !== last?.signature;\n }\n\n // Read when the request is sent, not when it was asked for: an edit may have\n // just changed which values the layer's text shows. The filter values of\n // every value on the layer go out, shown or not: the server decides which\n // values it reads, and applies to each only the entries naming its own\n // filters, so an operand only a formula reads is filtered as if it were\n // shown. A value's Name is left out of the signature: a rename moves no\n // number. While the groups match 'any', the request lists the groups that\n // combine, by the tile rule (valuesMatchAnyGroupIds): a header or footer\n // value's are the page on screen's.\n private _layerRequest(layer: ReportPage | ReportMaster | null): LayerValuesRequest {\n const pageId = layer?.id ?? null;\n const values = layer?.values ?? [];\n const shown = this._shownValues(layer);\n const filters = values.flatMap((component) => this._filterState.resolveForComponent(component));\n const matchAnyGroupIds = values.length\n ? valuesMatchAnyGroupIds(this.report, pageId, this._filterState.snapshot())\n : [];\n\n return {\n pageId,\n shown,\n filters,\n matchAnyGroupIds,\n signature: JSON.stringify([\n pageId,\n shown.map((value) => value.id),\n values.map((value) => ({ ...value, title: null })),\n filters,\n matchAnyGroupIds,\n ]),\n };\n }\n\n // The values a layer's text shows. Its request also reads the operands of\n // the formulas among them, but only the shown ones read as loading while it\n // is on its way, and a layer that shows none asks for nothing.\n private _shownValues(layer: ReportPage | ReportMaster | null): ReportComponent[] {\n const texts = (layer?.components ?? []).filter((component) => component.type === 'text');\n\n return shownValues(layer?.values ?? [], texts);\n }\n\n // One layer's numbers, by value id. A layer whose text shows no value asks\n // for nothing. A failed request reads as no numbers (each value an em dash)\n // rather than an error dialog: the words around them still read.\n private _loadValues({\n pageId, shown, filters, matchAnyGroupIds, signature,\n }: LayerValuesRequest): Observable<LayerValues> {\n const loaded = (rows: ReportPageValue[]): LayerValues => ({\n pageId,\n signature,\n rows: new Map(rows.map((row) => [row.id, row])),\n });\n\n if (pageId === null || !shown.length) {\n return of(loaded([]));\n }\n\n return this._reportData.pageValues(this.report.id, pageId, filters, false, { handlers: false }, matchAnyGroupIds)\n .pipe(\n map((rows) => loaded(rows ?? [])),\n catchError(() => of(loaded([]))),\n );\n }\n\n // The tokens of one layer's blocks. Numbers read for another page are not\n // this one's, so until its own arrive its values read as loading; so does a\n // value the request on its way asks for, until it lands. filterPageId is\n // the page whose page filters the layer reads: the page's own, none (null)\n // for the header and footer.\n private _tokenContext(\n values: ReportComponent[],\n layer: ValueLayer,\n valuePageId: number | null,\n filterPageId: number | null,\n ): TextTokenContext {\n // Read so a rename, patched into the value in place, recomputes the names.\n this._valuesRevision();\n\n const index = this.activePageIndex();\n const page = this.pages()[index];\n const results = layer.results();\n const pending = layer.pending();\n\n return {\n pageNumber: index + 1,\n pageName: page ? this.pageLabel(page, index) : '',\n reportName: this._report()?.name ?? '',\n values: textValues(\n values,\n results?.pageId === valuePageId ? results : null,\n this._filterState.formatContext(),\n new Set(pending?.pageId === valuePageId ? pending.shown.map((value) => value.id) : []),\n ),\n valuePageId,\n filters: this._filterFields(filterPageId),\n };\n }\n\n // What the {{filter.<id>}} tokens of a layer print: each filter group the\n // layer reads (layerFilterGroups) at the viewer's current value. A select\n // reads as loading until the names of its picks arrive.\n private _filterFields(pageId: number | null): Record<number, TextFilterField> {\n this._filterRevision();\n const loaded = this._optionNames();\n\n return textFilterFields(\n layerFilterGroups(this._report()?.filterGroups ?? [], pageId),\n (groupId) => this._filterState.value(groupId),\n this._filterState.formatContext().locale,\n (group, values) => loaded.get(optionNamesKey(group.id, values)),\n );\n }\n\n // Take a deleted value's chips out of an open editor. Saving html never\n // deletes a value, so a key leaves its layer only when the value is deleted\n // (its dialog, the assistant), when a text delete or an assistant write\n // sweeps the page's unused values, or with its page. Hosts reload the report\n // after each, and this is what follows that reload into the editor. Only the\n // layers on screen have rendered blocks; other pages are left alone.\n private _dropRemovedValueChips(): void {\n const next = layerValueKeys(this.report);\n const masterId = this.report?.master?.id ?? null;\n const texts = (this._renderedComponents?.toArray() ?? []).filter((rendered) => rendered.isText);\n\n this._valueKeysByLayer.forEach((keys, layerId) => {\n const isMaster = layerId === masterId;\n if (!isMaster && layerId !== this.activePageId()) {\n return;\n }\n\n const removed = [...keys].filter((key) => !next.get(layerId)?.has(key));\n texts\n .filter((rendered) => this._isMasterComponent(rendered.component) === isMaster)\n .forEach((rendered) => removed.forEach((key) => rendered.removeValue(key)));\n });\n\n this._valueKeysByLayer = next;\n }\n\n // Header and footer blocks are the master's; every other block is the page's.\n private _isMasterComponent(component: ReportComponent): boolean {\n return (this.report?.master?.components ?? []).some((candidate) => candidate.id === component.id);\n }\n\n // A band's top and bottom edges, in page inches.\n private _bandSpan(band: Band): { top: number; bottom: number } {\n const { headerHeight, footerHeight } = this.bands;\n\n return band === 'header'\n ? { top: 0, bottom: headerHeight }\n : { top: this.report.pageHeight - footerHeight, bottom: this.report.pageHeight };\n }\n\n // Opens the editor of a block added by double-clicking a band, once it is\n // drawn.\n private _editArrivedText(): void {\n const text = this._renderedComponents\n .find((rendered) => rendered.component.id === this._editOnArrival);\n\n if (text) {\n this._editOnArrival = null;\n text.editText();\n }\n }\n\n // ----- smart guides ---------------------------------------------------------\n\n // Pixel feel of the snap, converted to inches at the current zoom.\n private get _snapThreshold(): number {\n return 8 / (PX_PER_INCH * Math.max(0.1, this.zoom()));\n }\n\n private _snapMove(component: ReportComponent, x: number, y: number): { x: number; y: number } {\n const { vertical, horizontal } = this._candidates(component);\n const guides: GuideLine[] = [];\n\n const snappedX = this._snapAxis(\n [\n { offset: 0, value: x },\n { offset: component.w / 2, value: x + component.w / 2 },\n { offset: component.w, value: x + component.w },\n ],\n vertical,\n );\n if (snappedX !== null) {\n x = snappedX.base;\n guides.push({ orientation: 'v', position: snappedX.guide });\n }\n\n const snappedY = this._snapAxis(\n [\n { offset: 0, value: y },\n { offset: component.h / 2, value: y + component.h / 2 },\n { offset: component.h, value: y + component.h },\n ],\n horizontal,\n );\n if (snappedY !== null) {\n y = snappedY.base;\n guides.push({ orientation: 'h', position: snappedY.guide });\n }\n\n this._renderGuides(guides);\n\n return { x, y };\n }\n\n private _snapResize(\n component: ReportComponent,\n geometry: { x: number; y: number; w: number; h: number },\n handle: string,\n ): { x: number; y: number; w: number; h: number } {\n const { vertical, horizontal } = this._candidates(component);\n const guides: GuideLine[] = [];\n const result = { ...geometry };\n\n // Only the edges the handle moves participate in snapping.\n if (handle.includes('e')) {\n const snapped = this._nearest(geometry.x + geometry.w, vertical);\n if (snapped !== null) {\n result.w = snapped - geometry.x;\n guides.push({ orientation: 'v', position: snapped });\n }\n }\n if (handle.includes('w')) {\n const snapped = this._nearest(geometry.x, vertical);\n if (snapped !== null) {\n result.w = geometry.x + geometry.w - snapped;\n result.x = snapped;\n guides.push({ orientation: 'v', position: snapped });\n }\n }\n if (handle.includes('s')) {\n const snapped = this._nearest(geometry.y + geometry.h, horizontal);\n if (snapped !== null) {\n result.h = snapped - geometry.y;\n guides.push({ orientation: 'h', position: snapped });\n }\n }\n if (handle.includes('n')) {\n const snapped = this._nearest(geometry.y, horizontal);\n if (snapped !== null) {\n result.h = geometry.y + geometry.h - snapped;\n result.y = snapped;\n guides.push({ orientation: 'h', position: snapped });\n }\n }\n\n this._renderGuides(guides);\n\n return result;\n }\n\n // Alignment candidates: the page's edges + center, the header/footer band\n // lines, and every sibling's edges + centers — siblings on the SAME layer,\n // since a page component aligns with the page and a header block with the\n // header.\n private _candidates(moving: ReportComponent): { vertical: number[]; horizontal: number[] } {\n const vertical = [0, this.report.pageWidth / 2, this.report.pageWidth];\n const horizontal = [0, this.report.pageHeight / 2, this.report.pageHeight];\n\n const { headerHeight, footerHeight } = this.bands;\n if (headerHeight) {\n horizontal.push(headerHeight);\n }\n if (footerHeight) {\n horizontal.push(this.report.pageHeight - footerHeight);\n }\n\n const isMaster = this._isMasterComponent(moving);\n const siblings = isMaster ? this.masterComponents() : this.activePageComponents();\n\n for (const component of siblings) {\n if (component.id === moving.id) {\n continue;\n }\n\n vertical.push(component.x, component.x + component.w / 2, component.x + component.w);\n horizontal.push(component.y, component.y + component.h / 2, component.y + component.h);\n }\n\n return { vertical, horizontal };\n }\n\n // Snap one axis: of the moving box's three lines (edge/center/edge), find\n // the closest candidate within threshold and return the adjusted base\n // coordinate plus the guide to draw.\n private _snapAxis(\n lines: { offset: number; value: number }[],\n candidates: number[],\n ): { base: number; guide: number } | null {\n let best: { base: number; guide: number; distance: number } | null = null;\n\n for (const line of lines) {\n for (const candidate of candidates) {\n const distance = Math.abs(candidate - line.value);\n if (distance <= this._snapThreshold && (!best || distance < best.distance)) {\n best = { base: candidate - line.offset, guide: candidate, distance };\n }\n }\n }\n\n return best ? { base: best.base, guide: best.guide } : null;\n }\n\n private _nearest(value: number, candidates: number[]): number | null {\n let best: number | null = null;\n let bestDistance = this._snapThreshold;\n\n for (const candidate of candidates) {\n const distance = Math.abs(candidate - value);\n if (distance <= bestDistance) {\n best = candidate;\n bestDistance = distance;\n }\n }\n\n return best;\n }\n\n // The guides overlay is drawn imperatively — the drag loop runs outside\n // Angular and repaints on every pointermove.\n private _renderGuides(guides: GuideLine[]): void {\n const host = this._guides?.nativeElement;\n if (!host) {\n return;\n }\n\n host.replaceChildren(...guides.map((guide) => {\n const line = document.createElement('div');\n line.className = `guide guide-${guide.orientation}`;\n if (guide.orientation === 'v') {\n line.style.left = `${guide.position * PX_PER_INCH}px`;\n } else {\n line.style.top = `${guide.position * PX_PER_INCH}px`;\n }\n\n return line;\n }));\n }\n\n private _clearGuides(): void {\n this._guides?.nativeElement?.replaceChildren();\n }\n}\n","<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n wheel=\"modifier\"\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage) {\n <div\n class=\"page\"\n [class.editing]=\"editMode\"\n [class.master-editing]=\"isMasterEditing\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.--canvas-zoom]=\"zoom()\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n <!-- The header and footer: the master's components, drawn under the\n page's own. -->\n @if (isMasterShown && masterComponents().length) {\n <div\n class=\"master-layer\"\n [class.editable]=\"isMasterEditing\">\n @for (component of masterComponents(); track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isMasterEditing\"\n [zoom]=\"zoom()\"\n [snapper]=\"snapper\"\n [tokens]=\"masterTokens()\"\n [valueKeysElsewhere]=\"valueKeysElsewhere\"\n [selected]=\"component.id === selectedComponentId()\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\"\n (valueSettings)=\"openValueSettings(component, $event)\"\n (textSaved)=\"onTextSaved(component, $event)\"\n (valuesRemoved)=\"reportChanged.emit()\">\n </app-report-component>\n }\n </div>\n }\n\n <!-- The header and footer bands, as guides while editing. While the\n header and footer are edited, an empty band says how to fill it\n and a double-click adds a text block there. -->\n @if (editMode) {\n @if (bands.headerHeight) {\n <div\n class=\"band band-header\"\n [class.addable]=\"isMasterEditing\"\n [style.height.px]=\"bands.headerHeight * PX\"\n (dblclick)=\"addTextInBand('header', $event)\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Header</span>\n @if (isBandEmpty('header')) {\n <span class=\"band-hint small\">Double-click to add text</span>\n }\n }\n </div>\n }\n @if (bands.footerHeight) {\n <div\n class=\"band band-footer\"\n [class.addable]=\"isMasterEditing\"\n [style.height.px]=\"bands.footerHeight * PX\"\n (dblclick)=\"addTextInBand('footer', $event)\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Footer</span>\n @if (isBandEmpty('footer')) {\n <span class=\"band-hint small\">Double-click to add text</span>\n }\n }\n </div>\n }\n }\n\n @for (component of activePageComponents(); track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isPageEditing\"\n [zoom]=\"zoom()\"\n [snapper]=\"snapper\"\n [tokens]=\"pageTokens()\"\n [valueKeysElsewhere]=\"valueKeysElsewhere\"\n [selected]=\"component.id === selectedComponentId()\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\"\n (valueSettings)=\"openValueSettings(component, $event)\"\n (textSaved)=\"onTextSaved(component, $event)\"\n (valuesRemoved)=\"reportChanged.emit()\">\n </app-report-component>\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!activePageComponents().length && !masterMode()) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes — pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land.\n Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of pages(); track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex()\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleMasterHidden(page)\">\n {{ page.masterHidden ? 'Show header & footer' : 'Hide header & footer' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out (Ctrl/Cmd + scroll)\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom() * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in (Ctrl/Cmd + scroll)\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n","import { Injectable } from '@angular/core';\n\nimport { FsAiChatData } from '@firestitch/ai';\n\n\n// The parent's own parameter types, so the override always matches the\n// @firestitch/ai build it extends (a linked build carries its own\n// @firestitch/api, whose RequestConfig is a different type).\ntype ChatStreamBody = Parameters<FsAiChatData['chatStream']>[1];\ntype ChatStreamConfig = Parameters<FsAiChatData['chatStream']>[2];\ntype ChatStream = ReturnType<FsAiChatData['chatStream']>;\n\n\n// The report view's chat gateway: the stock one, plus fields read at the\n// moment each turn is sent and merged into that turn's body only. The chat's\n// requestData can't carry them, because it is also the key of the conversation\n// list, and a change there reloads the list and drops the open conversation.\n//\n// It relies on FsAiChatData.chatStream(basePath, body, config) being the one\n// path a turn takes. Nothing else is overridden, so the conversation list and\n// the create never see these fields. It stands in for a per-turn input on\n// fs-ai-chat itself, and can be removed when @firestitch/ai ships one.\n@Injectable()\nexport class ReportAiChatData extends FsAiChatData {\n\n // Set by the host view. A function, so it is read at send time.\n public turnData: () => Record<string, unknown> = () => ({});\n\n public override chatStream(basePath: string, body: ChatStreamBody, config: ChatStreamConfig = {}): ChatStream {\n return super.chatStream(basePath, { ...body, ...this.turnData() }, config);\n }\n}\n","// The rules behind the two filter settings dialogs, kept pure so the node\n// harness checks them without a dialog. The component settings' Filters tab\n// reads the Type select, the Report bar select and the This component toggle\n// from here; the report settings' Filters tab reads its default rows (the\n// period, the exclude toggle, the number range ends and their check) from\n// here. The dialogs only call these.\nimport { FilterBarPlacement } from './interfaces/filter-bar-placement.type';\nimport { FilterComponentToggleState } from './interfaces/filter-component-toggle-state.interface';\nimport { FilterSettingsOption } from './interfaces/filter-settings-option.interface';\nimport { FilterTypeSelectState } from './interfaces/filter-type-select-state.interface';\nimport { ReportViewerFeature } from './interfaces/report-viewer-feature.type';\nimport {\n FilterGroupDefault,\n ReportFilterGroup,\n ReportFilterLevel,\n ReportFilterType,\n ReportPage,\n ReportRelativeRange,\n} from './interfaces/report.interface';\nimport { RELATIVE_RANGE_NAMES, isRelativeRange } from './report-state';\nimport { offersExclude } from './report-viewer-features';\n\n\n// The Type select's choices. A column that can be either holds both.\nexport const FILTER_TYPE_OPTIONS: FilterSettingsOption<ReportFilterType>[] = [\n { value: 'select', name: 'Values' },\n { value: 'numberRange', name: 'Number range' },\n];\n\nexport const TYPE_LOCKED_TOOLTIP = 'Remove the filter to change its type.';\nexport const PAGE_FILTER_TOOLTIP = 'A page filter shows in the page bar only.';\nexport const COMPONENT_TOGGLE_TOOLTIP = 'Show on this component';\n\n// The Default period select's value for a range of fixed days. No relative\n// range is named this.\nexport const FIXED_DATES_PERIOD = 'fixed';\n\n// How many decimals a Default minimum or Default maximum takes.\nexport const DEFAULT_BOUND_SCALE = 6;\n\n// A filter's Name and Label, checked as the server checks them, so a bad one\n// is caught before Save. The name is an identifier: a letter, then letters\n// and digits. That it is unique in the report is the server's to check.\nexport const FILTER_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9]*$/;\nexport const FILTER_NAME_PATTERN_MESSAGE = 'A name starts with a letter and holds only letters and digits.';\nexport const FILTER_NAME_MAX_LENGTH = 50;\nexport const FILTER_LABEL_MAX_LENGTH = 200;\n\n// Every Report bar choice, in the order the select lists them.\nconst BAR_PLACEMENT_OPTIONS: FilterSettingsOption<FilterBarPlacement>[] = [\n { value: 'off', name: 'Off' },\n { value: 'every', name: 'Every page' },\n { value: 'page', name: 'This page only' },\n];\n\n\n// A number with its group commas in place ('1,250.5', '-12,000').\nconst GROUPED_DECIMAL = /^-?\\d{1,3}(,\\d{3})+(\\.\\d*)?$/;\n// A plain decimal number ('1250.5', '-3', '0', '.5'). Hex, binary, octal,\n// exponents and inner spaces do not match, though Number() reads some.\nconst PLAIN_DECIMAL = /^-?(\\d+(\\.\\d*)?|\\.\\d+)$/;\n\n// A default range end as typed. An empty field is no end. A number input\n// with a mask hands back text with its group commas ('1,250.5'), so those go\n// before Number() reads it; 0 is an end like any other. Anything that is not\n// a decimal number is no end.\nexport function parseDefaultBound(raw: unknown): number | null {\n if (typeof raw === 'number') {\n return Number.isFinite(raw) ? raw : null;\n }\n\n if (typeof raw !== 'string') {\n return null;\n }\n\n const trimmed = raw.trim();\n const text = GROUPED_DECIMAL.test(trimmed) ? trimmed.replace(/,/g, '') : trimmed;\n if (!PLAIN_DECIMAL.test(text)) {\n return null;\n }\n\n const value = Number(text);\n\n return Number.isFinite(value) ? value : null;\n}\n\n// Why two range ends cannot be saved, in the server's words, or null. An open\n// end is always fine.\nexport function boundsError(min: number | null, max: number | null): string | null {\n if (min === null || max === null || min <= max) {\n return null;\n }\n\n return `min (${min}) is above max (${max}).`;\n}\n\n// The Type select of a column on the component settings' Filters tab. It\n// shows when the column can take either type and the server serves number\n// ranges (an older server lists no features). A filter's type cannot change,\n// so it is locked while the column has a filter on this component.\nexport function typeSelectState(\n types: ReportFilterType[] | null | undefined,\n hasFilterOnThisComponent: boolean,\n features: ReportViewerFeature[] | null | undefined,\n): FilterTypeSelectState {\n const show = (features ?? []).includes('numberRange')\n && FILTER_TYPE_OPTIONS.every((option) => (types ?? []).includes(option.value));\n\n if (!show) {\n return { show: false, disabled: false, tooltip: null };\n }\n\n return {\n show: true,\n disabled: hasFilterOnThisComponent,\n tooltip: hasFilterOnThisComponent ? TYPE_LOCKED_TOOLTIP : null,\n };\n}\n\n// The levels a new or moved filter can take on a component. This page only\n// needs a server that serves page filters and a component on a page (a\n// header or footer component is on no page).\nexport function filterLevelChoices(\n features: ReportViewerFeature[] | null | undefined,\n onPage: boolean,\n): ReportFilterLevel[] {\n const levels: ReportFilterLevel[] = ['component', 'report', 'both'];\n\n return onPage && (features ?? []).includes('pageScope')\n ? [...levels, 'page']\n : levels;\n}\n\n// The Report bar select's choices for the levels on offer. The choice a row\n// already holds is always listed, so the select never shows blank.\nexport function barPlacementOptions(\n levelChoices: ReportFilterLevel[],\n current: FilterBarPlacement = 'off',\n): FilterSettingsOption<FilterBarPlacement>[] {\n return BAR_PLACEMENT_OPTIONS.filter((option) => {\n switch (option.value) {\n case 'every':\n return levelChoices.includes('report') || levelChoices.includes('both') || current === 'every';\n case 'page':\n return levelChoices.includes('page') || current === 'page';\n default:\n return true;\n }\n });\n}\n\n// A value's Report bar choices. A value has no strip of its own and its\n// group may be shared, so a pick never lowers the group (the inline values\n// rule): This page only is offered for a new filter, or for a group that is\n// already a page group, never to move a shared group to one page.\nexport function valuePlacementOptions(\n levelChoices: ReportFilterLevel[],\n current: ReportFilterLevel | null | undefined,\n): FilterSettingsOption<FilterBarPlacement>[] {\n const choices = !current || current === 'page'\n ? levelChoices\n : levelChoices.filter((level) => level !== 'page');\n\n return barPlacementOptions(choices, barPlacement(current));\n}\n\n// The level a value's filter group ends at after a Report bar pick, or null\n// when the value leaves it. Off unlinks this value alone and the group keeps\n// its other members. A new filter takes the pick's level. Every page raises a\n// strip-only group to both, keeping its strips, and a page group to the\n// report bar. Nothing else moves the group, so a value never lowers it.\nexport function valueFilterLevel(\n placement: FilterBarPlacement,\n current: ReportFilterLevel | null | undefined,\n): ReportFilterLevel | null {\n if (placement === 'off') {\n return null;\n }\n\n if (!current) {\n return placement === 'page' ? 'page' : 'report';\n }\n\n if (placement !== 'every') {\n return current;\n }\n\n switch (current) {\n case 'component':\n return 'both';\n case 'page':\n return 'report';\n default:\n return current;\n }\n}\n\n// Where a group of a level shows in the report bar. No group (no filter) is\n// off.\nexport function barPlacement(level: ReportFilterLevel | null | undefined): FilterBarPlacement {\n switch (level) {\n case 'report':\n case 'both':\n return 'every';\n case 'page':\n return 'page';\n default:\n return 'off';\n }\n}\n\n// Whether a group of a level shows on its components.\nexport function shownOnComponent(level: ReportFilterLevel | null | undefined): boolean {\n return level === 'component' || level === 'both';\n}\n\n// The level the two controls of a row ask for, or null when they ask for no\n// filter at all. A page filter shows in its page's bar only, so This page\n// only ignores the This component toggle.\nexport function filterLevel(placement: FilterBarPlacement, component: boolean): ReportFilterLevel | null {\n switch (placement) {\n case 'page':\n return 'page';\n case 'every':\n return component ? 'both' : 'report';\n default:\n return component ? 'component' : null;\n }\n}\n\n// The This component toggle of a row: locked while This page only is picked.\nexport function componentToggleState(placement: FilterBarPlacement): FilterComponentToggleState {\n return placement === 'page'\n ? { disabled: true, tooltip: PAGE_FILTER_TOOLTIP }\n : { disabled: false, tooltip: COMPONENT_TOGGLE_TOOLTIP };\n}\n\n// The groups the report settings' Filters tab lists defaults for: those of\n// the report bar, every page or one, in bar order.\nexport function defaultRowGroups(groups: ReportFilterGroup[] | null | undefined): ReportFilterGroup[] {\n return (groups ?? [])\n .filter((group) => group.level === 'report' || group.level === 'both' || group.level === 'page')\n .sort((a, b) => a.order - b.order);\n}\n\n// A default row's label: a page group names its page, 'Region (page\n// \"Overview\")'. A page with no name reads as the canvas names it ('Page 2').\n// A page this report no longer holds adds nothing.\nexport function defaultRowLabel(group: ReportFilterGroup, pages: ReportPage[] | null | undefined): string {\n const label = group.label || group.filters?.[0]?.filterColumn || 'Filter';\n\n if (group.level !== 'page') {\n return label;\n }\n\n const index = (pages ?? []).findIndex((page) => page.id === group.pageId);\n if (index < 0) {\n return label;\n }\n\n return `${label} (page \"${pages[index].name || `Page ${index + 1}`}\")`;\n}\n\n// The Default period select's choices: Fixed dates, then every relative\n// range in the server enum's order, named by `labels`. A stored range this\n// viewer does not know is listed last, so the select still shows it.\nexport function defaultPeriodOptions(\n labels: (relative: ReportRelativeRange) => string,\n stored: string | null = null,\n): FilterSettingsOption[] {\n const options: FilterSettingsOption[] = [\n { value: FIXED_DATES_PERIOD, name: 'Fixed dates' },\n ...RELATIVE_RANGE_NAMES.map((relative) => ({ value: relative, name: labels(relative) })),\n ];\n\n return stored && stored !== FIXED_DATES_PERIOD && !isRelativeRange(stored)\n ? [...options, { value: stored, name: labels(stored as ReportRelativeRange) }]\n : options;\n}\n\n// The Default period a stored date range default opens on: its relative\n// range, else Fixed dates (the days, or none).\nexport function defaultPeriod(stored: FilterGroupDefault | null | undefined): string {\n return stored?.relative && !stored.start && !stored.end\n ? stored.relative\n : FIXED_DATES_PERIOD;\n}\n\n// A date range default in its stored shape: the relative range picked, else\n// the fixed days, or null when there are none. Never both: the server\n// refuses a relative range with days.\nexport function dateRangeDefault(\n period: string,\n start: string | null,\n end: string | null,\n): FilterGroupDefault | null {\n if (period !== FIXED_DATES_PERIOD) {\n return { relative: period };\n }\n\n if (!start && !end) {\n return null;\n }\n\n return { ...(start ? { start } : {}), ...(end ? { end } : {}) };\n}\n\n// A select default in its stored shape: the picks kept, or left out while\n// Exclude these values is on, or null when nothing is picked.\nexport function selectDefault(values: unknown[], exclude: boolean): FilterGroupDefault | null {\n if (!values.length) {\n return null;\n }\n\n return exclude ? { excludeValues: values } : { values };\n}\n\n// A number range default in its stored shape from the ends as typed: an\n// open end is left out, 0 is kept, and two open ends are no default.\nexport function numberRangeDefault(rawMin: unknown, rawMax: unknown): FilterGroupDefault | null {\n const min = parseDefaultBound(rawMin);\n const max = parseDefaultBound(rawMax);\n\n if (min === null && max === null) {\n return null;\n }\n\n return { ...(min !== null ? { min } : {}), ...(max !== null ? { max } : {}) };\n}\n\n// Whether a select group's default row offers Exclude these values: the\n// report bar's rule (offersExclude), so not on a server that does not serve\n// exclude (an older server lists no features) nor on a group with a member\n// that binds several columns (multiColumn). A default that already leaves\n// values out keeps the toggle, so it can be turned off.\nexport function showExcludeToggle(\n group: ReportFilterGroup,\n features: ReportViewerFeature[] | null | undefined,\n): boolean {\n if (group.type === 'select' && group.config?.default?.excludeValues?.length) {\n return true;\n }\n\n return offersExclude(group, features);\n}\n\n// A stored or draft default in a stable form for comparing: empty and\n// absent keys are dropped, so a no-op edit does not read as a change. 0 is an\n// end like any other. Nothing left is null.\nexport function normalizeDefault(value: FilterGroupDefault | null | undefined): FilterGroupDefault | null {\n if (!value) {\n return null;\n }\n\n const normalized: FilterGroupDefault = {};\n if (value.start) {\n normalized.start = value.start;\n }\n if (value.end) {\n normalized.end = value.end;\n }\n if (value.values?.length) {\n normalized.values = value.values;\n }\n if (value.excludeValues?.length) {\n normalized.excludeValues = value.excludeValues;\n }\n if (typeof value.min === 'number') {\n normalized.min = value.min;\n }\n if (typeof value.max === 'number') {\n normalized.max = value.max;\n }\n if (value.value) {\n normalized.value = value.value;\n }\n if (value.relative) {\n normalized.relative = value.relative;\n }\n\n return Object.keys(normalized).length ? normalized : null;\n}\n\n// Whether a row's draft default differs from the group's stored one. Only a\n// changed row is saved.\nexport function defaultChanged(\n stored: FilterGroupDefault | null | undefined,\n draft: FilterGroupDefault | null | undefined,\n): boolean {\n return JSON.stringify(normalizeDefault(stored)) !== JSON.stringify(normalizeDefault(draft));\n}\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef, EventEmitter, OnInit, computed, inject, signal, viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, FormsModule } from '@angular/forms';\n\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';\nimport { MatFormField, MatHint, MatLabel, MatSuffix } from '@angular/material/form-field';\nimport { MatButton, MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { MatInput } from '@angular/material/input';\nimport { MatOption, MatSelect } from '@angular/material/select';\nimport { MatSlideToggle } from '@angular/material/slide-toggle';\nimport { MatTabsModule } from '@angular/material/tabs';\nimport { MatTooltip } from '@angular/material/tooltip';\n\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsLabelModule } from '@firestitch/label';\nimport { FsMaskModule } from '@firestitch/mask';\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsMessage } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { Observable } from 'rxjs';\nimport { switchMap, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportChangePolarity } from '../../enums/report-change-polarity.enum';\nimport { ReportValueFormat } from '../../enums/report-value-format.enum';\nimport { ReportValueFormula } from '../../enums/report-value-formula.enum';\nimport { resolveFormatContext } from '../../format';\nimport {\n KPI_SPARKLINE_DEFAULT_GRANULARITY,\n KPI_SPARKLINE_DEFAULT_PERIODS,\n kpiCardSettings,\n sameKpiCardSettings,\n} from '../../kpi-card';\nimport {\n ChartGranularity,\n ComponentSettings,\n GRANULARITY_OPTIONS,\n KpiCardSettings,\n KpiConfig,\n Report,\n ReportComponent,\n ReportComponentSql,\n ReportFilter,\n ReportFilterGroup,\n ReportFilterLevel,\n ReportFilterType,\n ReportFilterableColumn,\n} from '../../interfaces/report.interface';\nimport { DEFAULT_COMPONENT_PADDING } from '../../layout';\nimport {\n FILTER_TYPE_OPTIONS,\n barPlacement,\n barPlacementOptions,\n componentToggleState,\n filterLevel,\n filterLevelChoices,\n shownOnComponent,\n typeSelectState,\n valueFilterLevel,\n valuePlacementOptions,\n} from '../../filter-settings-rules';\nimport { FilterBarPlacement } from '../../interfaces/filter-bar-placement.type';\nimport { FilterComponentToggleState } from '../../interfaces/filter-component-toggle-state.interface';\nimport { FilterSettingsOption } from '../../interfaces/filter-settings-option.interface';\nimport { FilterTypeSelectState } from '../../interfaces/filter-type-select-state.interface';\nimport { TextTokenContext, escapeHtml, fieldToken, fillTitleTokens, textFields } from '../../text';\nimport { operandKeys, reportComponents, valueKey } from '../../values';\n\n\n// What the dialog hands back. The Settings tab's Save carries the new\n// `settings`; Delete carries `deleted` and no settings, because the component\n// it was opened for no longer exists. Every other exit (Cancel, Done, Escape,\n// backdrop) closes with no result — filter work is announced as it happens\n// instead, through `filtersChanged`.\nexport interface ComponentSettingsResult {\n settings?: ComponentSettings;\n deleted?: boolean;\n}\n\n// What the dialog opens with: the report, the component, and what the tokens\n// of the component's title fill with where it is drawn (its page's, or the\n// master's for a header or footer component), for the title's Insert field\n// menu and the line saying how the title reads.\nexport interface ComponentSettingsDialogData {\n report: Report;\n component: ReportComponent;\n tokens: TextTokenContext;\n}\n\n// What the settings endpoint returns for the component: its id and, from a\n// server that saves a KPI's card keys, the whole config as saved.\ninterface ComponentSettingsResponse {\n id: number;\n config?: Record<string, unknown> | null;\n}\n\n\n// What a rise in a KPI's value means, for the Increase is select.\nconst KPI_CHANGE_POLARITY_OPTIONS: { value: ReportChangePolarity; name: string }[] = [\n { value: ReportChangePolarity.Good, name: 'Good news — a rise shows green' },\n { value: ReportChangePolarity.Bad, name: 'Bad news — a rise shows red' },\n { value: ReportChangePolarity.Neutral, name: 'Neither — no color' },\n];\n\n// A KPI sparkline's periods stay within 2 to 60.\nconst KPI_SPARKLINE_MIN_PERIODS = 2;\nconst KPI_SPARKLINE_MAX_PERIODS = 60;\n\n// A percent KPI's target is entered as the percent shown (15 for 15%) and\n// stored as the 0-1 ratio its value arrives in; the server refuses a stored\n// target above 100, which is 10,000% here.\nconst KPI_PERCENT_TARGET_MAX = 10000;\n\n// How a formula value's Settings tab writes out what it works out, in its\n// operands' names.\nconst FORMULA_LINES: Record<ReportValueFormula, (names: string[]) => string> = {\n [ReportValueFormula.Change]: (names) => names.join(' − '),\n [ReportValueFormula.PercentChange]: ([a, b]) => `% change of ${a} over ${b}`,\n [ReportValueFormula.Ratio]: (names) => names.join(' ÷ '),\n [ReportValueFormula.Sum]: (names) => names.join(' + '),\n};\n\n\n// One row of the Filters tab listing: a filterable column, its filter's type\n// (the inferred one, the one picked, or the filter's own), and where its\n// filter shows (the Report bar select and the This component toggle).\ninterface FilterRow {\n column: string;\n type: ReportFilterType;\n label: string;\n placement: FilterBarPlacement;\n component: boolean;\n typeSelect: FilterTypeSelectState;\n placementOptions: FilterSettingsOption<FilterBarPlacement>[];\n componentToggle: FilterComponentToggleState;\n}\n\n\n// Component settings, in tabs:\n// Settings — title and content padding (a value: just its name, since it\n// sits inside a text block's words and has no box). A title may carry the\n// page, report and filter fields a text block's words do: its Insert field\n// menu puts one in at the caret, and the line under it says how the title\n// reads. On a derived KPI its card: what a rise means, a target and a\n// sparkline (number formats stay with the AI). Position/size are tuned by\n// dragging on the canvas; height behaviour follows from the component type.\n// Filters — ONE listing of every filterable column on this component. Each\n// row carries two toggles: show in the report bar and/or show on this\n// component (both, either, or neither). The interface (date range vs value\n// picker) is inferred from the data, never chosen. Each toggle persists\n// immediately and refreshes the in-dialog list. A value has no component\n// to show a filter on, so it gets the report bar toggle only.\n// SQL / Config — read-only diagnostics.\n// A formula value has no Filters or SQL tab: the server works it out of other\n// values on its page, so it runs no statement and follows the filters of the\n// values it reads. Its Settings tab says what it works out, under its name.\n@Component({\n templateUrl: './component-settings.component.html',\n styleUrls: ['./component-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsMaskModule,\n FsDialogModule,\n FsLabelModule,\n FsTabsModule,\n MatTabsModule,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatDialogClose,\n MatFormField,\n MatHint,\n MatLabel,\n MatSuffix,\n MatButton,\n MatIcon,\n MatIconButton,\n MatInput,\n MatOption,\n MatSelect,\n MatSlideToggle,\n MatTooltip,\n FsMenuModule,\n ],\n})\nexport class ComponentSettingsComponent implements OnInit {\n\n // A filter was added, removed or re-levelled, so the report's filter groups\n // changed. Those mutations persist the moment they are clicked and the dialog\n // can then be dismissed by a route that carries no result (Escape, backdrop),\n // so the page is told here rather than through the close result.\n public readonly filtersChanged = new EventEmitter<void>();\n\n public component: ReportComponent;\n public report: Report;\n\n public selectedTab = 'settings';\n\n public readonly title = signal('');\n\n // What the title's Insert field menu lists, in order: the page and report\n // fields, then each filter of the report in the filter bar's order. A value\n // token is never offered: values belong to a page's text.\n public readonly titleFields = computed(() => textFields(this._data.tokens));\n\n // How the title reads where the component is drawn, while it holds a token\n // ('Sign-ups — September 2026'); empty for a title with none, and for a\n // value, whose Name is just its name.\n public readonly titleShownAs = computed(() => {\n const title = this.title();\n const shown = fillTitleTokens(title, this._data.tokens);\n\n return !this.isValue() && shown !== title ? shown : '';\n });\n\n // The dialog's heading: the title as it reads (a value's Name as it is),\n // else what the component is.\n public readonly heading = computed(() => this._shownTitle() || (this.isValue() ? 'Value' : 'Component'));\n\n // Component padding in inches. `number | string` for the same reason as the\n // page dimensions in report-settings: fsMaskNumber seeds from the number but\n // hands back the unmasked string, and save casts it once on the way out.\n public paddingTop: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingRight: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingBottom: number | string = DEFAULT_COMPONENT_PADDING;\n public paddingLeft: number | string = DEFAULT_COMPONENT_PADDING;\n\n public configJson = '';\n\n // ---- KPI card state (a derived KPI only) ----\n public readonly kpiPolarityOptions = KPI_CHANGE_POLARITY_OPTIONS;\n public readonly granularityOptions = GRANULARITY_OPTIONS;\n public readonly sparklineMinPeriods = KPI_SPARKLINE_MIN_PERIODS;\n public readonly sparklineMaxPeriods = KPI_SPARKLINE_MAX_PERIODS;\n public readonly kpiCard = signal(false);\n // A value inside a text block: no box, so no padding.\n public readonly isValue = signal(false);\n // A formula value: no statement, columns or filters of its own.\n public readonly isFormula = signal(false);\n // What a formula works out, in its operands' names; empty for any other\n // component.\n public readonly formulaLine = computed(() => (this.isFormula() ? this._formulaLine() : ''));\n public readonly increaseIs = signal<ReportChangePolarity>(ReportChangePolarity.Good);\n // The target as typed: fsMaskNumber hands back the unmasked string. Empty\n // means no target. A percent KPI's is in percent (targetPercent).\n public readonly targetValue = signal<number | string | null>(null);\n public readonly targetLabel = signal('');\n public readonly targetPercent = signal(false);\n public readonly hasTarget = computed(() => this._number(this.targetValue()) !== null);\n public readonly sparkline = signal(false);\n public readonly sparklineGranularity = signal<ChartGranularity>(KPI_SPARKLINE_DEFAULT_GRANULARITY);\n public readonly sparklinePeriods = signal<number | string>(KPI_SPARKLINE_DEFAULT_PERIODS);\n\n // ---- SQL tab state ----\n // The statement, once fetched. Null while it is in flight, and null when the\n // component's document could not be compiled (sqlError then says why).\n public readonly sql = signal<string | null>(null);\n // True when the statement is a DERIVED baseline: no filters, the authored\n // grain, times in the report's effective zone. The tab says so, because the\n // numbers on screen come from this statement plus the viewer's own choices\n // and the two can differ.\n public readonly sqlBaseline = signal(false);\n // The zone the statement was compiled in: the report's effective zone, sent\n // with the SQL. A server too old to send it compiled in UTC.\n public readonly sqlTimezone = signal('UTC');\n public readonly sqlError = signal<string | null>(null);\n\n // ---- filter management state ----\n // One row per filterable column. The placement and the toggle change\n // optimistically on click (so the UI never blinks while the request is in\n // flight) and reconcile from the server on reload.\n public readonly rows = signal<FilterRow[]>([]);\n public readonly columnsError = signal<string | null>(null);\n // The Type select's choices. A row's Type select, Report bar select and\n // This component toggle follow the rules in filter-settings-rules.ts.\n public readonly typeOptions = FILTER_TYPE_OPTIONS;\n\n // The raw inputs the rows are built from.\n private _filterableColumns: ReportFilterableColumn[] = [];\n private _filters: ReportFilter[] = [];\n private _groupsById = new Map<number, ReportFilterGroup>();\n // The type picked for a column with no filter yet, so a reload keeps it.\n private _pickedTypes = new Map<string, ReportFilterType>();\n\n private readonly _typeLabels: Record<ReportFilterType, string> = {\n select: 'Pick values',\n dateRange: 'Date range',\n keyword: 'Search text',\n numberRange: 'Number range',\n };\n\n private readonly _data: ComponentSettingsDialogData = inject(MAT_DIALOG_DATA);\n private readonly _titleInput = viewChild<ElementRef<HTMLInputElement>>('titleInput');\n private readonly _dialogRef = inject<MatDialogRef<ComponentSettingsComponent, ComponentSettingsResult>>(MatDialogRef);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _prompt = inject(FsPrompt);\n private readonly _destroyRef = inject(DestroyRef);\n\n public ngOnInit(): void {\n this.report = this._data.report;\n this.component = this._data.component;\n\n this.title.set(this.component.title ?? '');\n this.isValue.set(this.component.type === 'value');\n this.isFormula.set(!!this.component.config?.formula);\n\n const padding = this.component.config?.padding;\n this.paddingTop = padding?.top ?? DEFAULT_COMPONENT_PADDING;\n this.paddingRight = padding?.right ?? DEFAULT_COMPONENT_PADDING;\n this.paddingBottom = padding?.bottom ?? DEFAULT_COMPONENT_PADDING;\n this.paddingLeft = padding?.left ?? DEFAULT_COMPONENT_PADDING;\n\n this.configJson = JSON.stringify(this.component.config ?? {}, null, 2);\n\n this._seedKpiCard();\n\n this._seedFilters(this.report, this.component.id);\n\n // A formula has no statement to compile and no columns to filter on, and\n // the server would refuse both requests.\n if (!this.isFormula()) {\n this._loadColumns();\n this._loadSql();\n }\n }\n\n // Human-friendly name for the inferred interface shown beside each column.\n public typeLabel(type: ReportFilterType): string {\n return this._typeLabels[type] ?? type;\n }\n\n // Confirm and delete here, while the dialog is still open, then close with a\n // `deleted` result for the page to act on — the same shape the report\n // settings dialog uses for deleting a report.\n //\n // The confirm says it cannot be undone because, from the UI, it cannot: the\n // row is soft-deleted server-side but nothing here restores a component.\n // A value's confirm also says what goes with it: the server takes its\n // tokens out of every text on its page, not just the one it was opened from,\n // and deletes the formulas that read it (_dependentsNote).\n //\n // The prompt renders its template as html, so every name in it is escaped.\n public delete(): void {\n this._prompt.confirm(this.isValue()\n ? {\n title: 'Delete Value',\n template: `Delete the value \"${escapeHtml(this.component.title || valueKey(this.component))}\"? It is also taken out of every text on this page. This cannot be undone.${this._dependentsNote()}`,\n }\n : {\n title: 'Delete Component',\n template: `Are you sure you would like to delete \"${escapeHtml(this._shownTitle() || 'this component')}\"? This cannot be undone.`,\n })\n .pipe(\n switchMap(() => this._reportData.deleteComponent(this.report.id, this.component.id)),\n tap(() => {\n this._message.success(this.isValue() ? 'Value deleted' : 'Component deleted');\n this._dialogRef.close({ deleted: true });\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // Puts a field's token into the title at the caret, over any text selected\n // there, as if it were typed: the model follows and the field is dirty. The\n // input keeps its caret while the menu is open; focus comes back to it once\n // the menu has handed focus back to its button.\n public insertField(field: string): void {\n const input = this._titleInput()?.nativeElement;\n if (!input) {\n return;\n }\n\n const end = input.value.length;\n input.setRangeText(fieldToken(field), input.selectionStart ?? end, input.selectionEnd ?? end, 'end');\n input.dispatchEvent(new Event('input'));\n setTimeout(() => input.focus());\n }\n\n // A percent target's bound, in the percent it is typed in. It reads the\n // control, which fsForm validates before ngModelChange updates the signal.\n public validateTarget = (control: AbstractControl): void => {\n const value = this._number(control.value);\n\n if (this.targetPercent() && value !== null && value > KPI_PERCENT_TARGET_MAX) {\n throw new Error('A percent target can be at most 10,000%');\n }\n };\n\n public save = () => {\n const settings: ComponentSettings = {\n // The server trims a title; a value's Name is what its chips show, so it\n // goes as the server keeps it.\n title: this.isValue() ? this.title().trim() : this.title(),\n padding: {\n top: this._padding(this.paddingTop),\n right: this._padding(this.paddingRight),\n bottom: this._padding(this.paddingBottom),\n left: this._padding(this.paddingLeft),\n },\n };\n\n // The card keys go as config keys beside the padding (increaseIs, target\n // and sparkline, null to remove one), and only when they changed, so a\n // title edit never touches them.\n const kpi = this.kpiCard() ? this._kpiCardSettings() : null;\n const kpiChanged = !!kpi\n && !sameKpiCardSettings(kpi, kpiCardSettings(this.component.config as KpiConfig));\n\n return this._reportData.updateComponent(this.report.id, this.component.id, {\n title: settings.title,\n ...(this.isValue() ? {} : { padding: settings.padding }),\n ...(kpiChanged ? kpi : {}),\n })\n .pipe(\n tap((response: ComponentSettingsResponse) => {\n // The card is drawn from the keys the server saved, read back from\n // the config it returns. A server that returns no config did not\n // save them, so the card keeps what it had and the dialog says so.\n const saved = kpiChanged ? this._savedKpiCard(response) : null;\n\n if (kpiChanged && !saved) {\n this._message.warning('Component saved, but the server did not save the card settings');\n } else {\n this._message.success(this.isValue() ? 'Value saved' : 'Component saved');\n }\n\n this._dialogRef.close({ settings: saved ? { ...settings, kpi: saved } : settings });\n }),\n );\n };\n\n // The type a column's filter will be made with. Only a column with no\n // filter offers the pick (the Type select is locked otherwise), and nothing\n // is saved until the filter is made.\n public setType(row: FilterRow, type: ReportFilterType): void {\n this._pickedTypes.set(row.column, type);\n this._patchRow(row, { type });\n }\n\n // Where the row's filter shows in the report bar. This page only shows it\n // in its page's bar alone, so the This component toggle goes off and locks.\n // A value has this select only, with its own rules (_applyValueLevel).\n public setPlacement(row: FilterRow, placement: FilterBarPlacement): void {\n const patched = this._patchRow(row, {\n placement,\n component: placement === 'page' ? false : row.component,\n componentToggle: componentToggleState(placement),\n });\n\n if (this.isValue()) {\n this._applyValueLevel(patched);\n } else {\n this._applyLevel(patched);\n }\n }\n\n // A value has no This component toggle.\n public setComponent(row: FilterRow, component: boolean): void {\n if (this.isValue()) {\n return;\n }\n\n this._applyLevel(this._patchRow(row, { component }));\n }\n\n // Persist the level the row's controls ask for, then reconcile on reload.\n // No level → no filter (removed); otherwise the filter exists at that\n // level. A server refusal (a page filter whose members sit on two pages)\n // shows its own text and the row snaps back.\n private _applyLevel(row: FilterRow): void {\n const level = filterLevel(row.placement, row.component);\n const existing = this._filters.find((filter) => filter.filterColumn === row.column);\n\n if (!level) {\n if (existing) {\n this._run(this._reportData.deleteFilter(this.report.id, existing.id));\n }\n\n return;\n }\n\n if (existing) {\n this._run(this._reportData.updateFilterGroup(this.report.id, existing.filterGroupId, { level }));\n } else {\n this._addFilter(row, level);\n }\n }\n\n // A value's Report bar select, the only control it has. Its filter's group\n // may be shared (the report's Period, say), and a value has no strip of its\n // own, so a pick never lowers the group (valueFilterLevel). A pick that\n // moves nothing puts the row back as the group stands.\n private _applyValueLevel(row: FilterRow): void {\n const existing = this._filters.find((filter) => filter.filterColumn === row.column);\n const current = existing ? this._groupsById.get(existing.filterGroupId)?.level : undefined;\n const level = valueFilterLevel(row.placement, current);\n\n if (!level) {\n if (existing) {\n this._run(this._reportData.deleteFilter(this.report.id, existing.id));\n }\n } else if (!existing) {\n this._addFilter(row, level);\n } else if (level !== current) {\n this._run(this._reportData.updateFilterGroup(this.report.id, existing.filterGroupId, { level }));\n } else {\n this._rebuildRows();\n }\n }\n\n // The type goes only when the author could pick it; otherwise the server\n // infers it, as it always has.\n private _addFilter(row: FilterRow, level: ReportFilterLevel): void {\n this._run(this._reportData.addFilter(this.report.id, this.component.id, {\n filterColumn: row.column,\n label: row.label,\n level,\n ...(row.typeSelect.show ? { type: row.type } : {}),\n }));\n }\n\n // A new row object rather than a mutation, so the signal sees the change;\n // the @for tracks the column, so the row's controls survive the swap.\n private _patchRow(row: FilterRow, patch: Partial<FilterRow>): FilterRow {\n const patched = { ...row, ...patch };\n this.rows.update((rows) => rows.map((item) => (item.column === row.column ? patched : item)));\n\n return patched;\n }\n\n // The stored title as it reads where the component is drawn, its tokens\n // filled; a value's Name as it is.\n private _shownTitle(): string {\n return this.isValue() ? this.component.title ?? '' : fillTitleTokens(this.component.title, this._data.tokens);\n }\n\n // What a formula works out, naming each operand as its chips do. An op this\n // viewer does not know reads nothing.\n private _formulaLine(): string {\n const formula = this.component.config?.formula;\n const line = formula ? FORMULA_LINES[formula.op] : undefined;\n const values = this._layerValues();\n\n return line ? line(operandKeys(this.component).map((key) => this._valueName(values, key))) : '';\n }\n\n // The sentence a query value's delete confirm ends with when formulas on its\n // layer read it: the server deletes those with it. Empty when none does, and\n // for a formula, whose operands stay.\n private _dependentsNote(): string {\n if (this.isFormula()) {\n return '';\n }\n\n const key = valueKey(this.component);\n const names = this._layerValues()\n .filter((value) => operandKeys(value).includes(key))\n .map((value) => escapeHtml(value.title || valueKey(value)));\n\n return names.length ? ` The values worked out from it are deleted too: ${names.join(', ')}.` : '';\n }\n\n // The values of the layer this value belongs to: the page whose values hold\n // it, else the master's (a header or footer value).\n private _layerValues(): ReportComponent[] {\n const page = (this.report.pages ?? [])\n .find((candidate) => (candidate.values ?? []).some((value) => value.id === this.component.id));\n\n return (page ?? this.report.master)?.values ?? [];\n }\n\n // What a value is called where its chips show it: its name, else its key.\n // The newest value holds a key, as it does in the text's tokens.\n private _valueName(values: ReportComponent[], key: string): string {\n const value = values.filter((candidate) => valueKey(candidate) === key).pop();\n\n return value?.title || key;\n }\n\n // A derived KPI's card keys, from its config. A sql-mode KPI cannot carry\n // them, so it gets no card fields.\n private _seedKpiCard(): void {\n const config = (this.component.config ?? {}) as KpiConfig;\n\n this.kpiCard.set(this.component.type === 'kpi' && !this.component.sql);\n this.increaseIs.set(config.increaseIs ?? ReportChangePolarity.Good);\n this.targetPercent.set(config.measure?.format === ReportValueFormat.Percent\n && resolveFormatContext(this.report).ratioPercent);\n this.targetValue.set(this._targetShown(config.target?.value ?? null));\n this.targetLabel.set(config.target?.label ?? '');\n this.sparkline.set(!!config.sparkline);\n this.sparklineGranularity.set(config.sparkline?.granularity ?? KPI_SPARKLINE_DEFAULT_GRANULARITY);\n this.sparklinePeriods.set(config.sparkline?.periods ?? KPI_SPARKLINE_DEFAULT_PERIODS);\n }\n\n // The card keys the server saved, from the config its response carries;\n // null when it carries none (a server that does not save them).\n private _savedKpiCard(response: ComponentSettingsResponse | null | undefined): KpiCardSettings | null {\n const config = response?.config;\n\n return config && typeof config === 'object' ? kpiCardSettings(config as KpiConfig) : null;\n }\n\n // Good is what an absent increaseIs reads, so it is saved as absent.\n private _kpiCardSettings(): KpiCardSettings {\n const target = this._number(this.targetValue());\n const label = this.targetLabel().trim();\n\n return {\n increaseIs: this.increaseIs() === ReportChangePolarity.Good ? null : this.increaseIs(),\n target: target === null ? null : { value: this._targetStored(target), label: label || null },\n sparkline: this.sparkline()\n ? { granularity: this.sparklineGranularity(), periods: this._number(this.sparklinePeriods()) }\n : null,\n };\n }\n\n // A stored ratio as the percent typed, rounded so 0.15 reads 15 and not\n // 15.000000000000002.\n private _targetShown(value: number | null): number | null {\n if (value === null || !this.targetPercent()) {\n return value;\n }\n\n return Math.round(value * 100 * 1e6) / 1e6;\n }\n\n private _targetStored(value: number): number {\n return this.targetPercent() ? value / 100 : value;\n }\n\n // A typed number, or null when the field is empty.\n private _number(value: number | string | null): number | null {\n if (value === null || value === '') {\n return null;\n }\n\n const number = typeof value === 'number' ? value : parseFloat(value);\n\n return Number.isFinite(number) ? number : null;\n }\n\n // The padding as a real number for the wire. fsMaskNumber hands back the\n // unmasked string it built with a fixed '.' radix, so this is a straight\n // parse - the whole reason for the mask is that a native number input would\n // paint (and read back) the viewer's own locale separator instead.\n private _padding(value: number | string): number {\n return typeof value === 'number' ? value : parseFloat(value);\n }\n\n // Run a filter mutation, then reload to reconcile the optimistic state.\n private _run(request: Observable<unknown>): void {\n request.subscribe({\n next: () => this._afterMutation(),\n error: (error) => this._mutationError(error),\n });\n }\n\n // Build the row view-model from the loaded columns + filters/groups. Each\n // row's controls reflect where its filter group currently shows; a column\n // with a filter shows the filter's own type. A value's rows never read as\n // on a component: it has no strip, whatever level a group it shares is at,\n // and its Report bar select offers no pick that lowers that group.\n private _rebuildRows(): void {\n const levelChoices = filterLevelChoices(this.report.viewerFeatures, this._onPage());\n\n this.rows.set(this._filterableColumns.map((column) => {\n const filter = this._filters.find((candidate) => candidate.filterColumn === column.column);\n const group = filter ? this._groupsById.get(filter.filterGroupId) : undefined;\n const placement = barPlacement(group?.level);\n\n return {\n column: column.column,\n type: group?.type\n ?? this._pickedTypes.get(column.column)\n ?? column.types?.[0]\n ?? column.type,\n label: filter?.label\n || this._groupsById.get(filter?.filterGroupId ?? -1)?.label\n || this._humanize(column.column),\n placement,\n component: !this.isValue() && shownOnComponent(group?.level),\n typeSelect: typeSelectState(column.types, !!filter, this.report.viewerFeatures),\n placementOptions: this.isValue()\n ? valuePlacementOptions(levelChoices, group?.level)\n : barPlacementOptions(levelChoices, placement),\n componentToggle: componentToggleState(placement),\n };\n }));\n }\n\n // Whether the component sits on a page: among its components, or, for a\n // value, its values. A header or footer component or value sits on none,\n // so its filters cannot be page filters.\n private _onPage(): boolean {\n return (this.report.pages ?? [])\n .some((page) => [...(page.components ?? []), ...(page.values ?? [])]\n .some((candidate) => candidate.id === this.component.id));\n }\n\n // After any filter mutation: re-fetch the report so the dialog's filter list\n // (and the parent canvas, on close) reflect the new groups/levels.\n private _afterMutation(): void {\n this.filtersChanged.emit();\n\n this._reportData.get(this.report.id)\n .subscribe((report: Report) => {\n this.report = report;\n this._seedFilters(report, this.component.id);\n });\n }\n\n private _mutationError(error: any): void {\n this._message.error(error?.error?.message ?? error?.message ?? 'Filter operation failed');\n // Re-seed from the server so the optimistic toggle snaps back to truth.\n this._afterMutation();\n }\n\n // The component's filters and the groups they sit in, from the report as\n // last loaded. A value is listed in its page's values, not its components.\n private _seedFilters(report: Report, componentId: number): void {\n this._groupsById = new Map((report.filterGroups ?? []).map((group) => [group.id, group]));\n\n const component = reportComponents(report)\n .find((candidate) => candidate.id === componentId);\n\n this._filters = component?.filters ?? [];\n this._rebuildRows();\n }\n\n // The statement the SQL tab shows. Fetched rather than read off the\n // component: a derived component stores a document, not SQL, so its\n // statement only exists once the backend compiles it.\n //\n // Loaded in ngOnInit beside the columns, NOT on tab activation. The tabs are\n // not lazy (no matTabContent), and switching the tab-group's `[(selected)]`\n // banana-box to a one-way binding plus (selectedChange) to get a hook would\n // break it: FsTabsHeaderTabGroupDirective self-assigns `this.selected` before\n // it emits, so the event is filtered out and the load would never fire. One\n // small request when a dialog opens is not worth that risk.\n private _loadSql(): void {\n this._reportData.componentSql(this.report.id, this.component.id)\n .subscribe({\n next: (preview: ReportComponentSql) => {\n this.sql.set(preview?.sql ?? null);\n this.sqlBaseline.set(!!preview?.baseline);\n this.sqlTimezone.set(preview?.timezone || 'UTC');\n this.sqlError.set(preview?.error ?? null);\n },\n error: (error) => {\n this.sql.set(null);\n this.sqlError.set(error?.error?.message ?? 'Could not read the component SQL');\n },\n });\n }\n\n private _loadColumns(): void {\n this._reportData.componentColumns(this.report.id, this.component.id)\n .subscribe({\n next: (columns: ReportFilterableColumn[]) => {\n this._filterableColumns = columns ?? [];\n this._rebuildRows();\n },\n error: (error) => {\n this.columnsError.set(error?.error?.message ?? 'Could not read the component columns');\n },\n });\n }\n\n private _humanize(column: string): string {\n return column\n .replace(/[_\\-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n }\n}\n","<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet — give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query — no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>","import {\n ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal,\n} from '@angular/core';\nimport { ControlContainer, FormsModule, NgForm } from '@angular/forms';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatOption } from '@angular/material/core';\nimport { MatSelect } from '@angular/material/select';\n\nimport { guid } from '@firestitch/common';\nimport { FsFormModule } from '@firestitch/form';\n\n\n// Self-contained timezone picker for the report settings dialog. The IANA zone\n// list comes from the browser (Intl.supportedValuesOf), so the package carries no\n// dependency on any app timezone API. It shows the zone it is given and never\n// picks one itself: the dialog always seeds the zone the report uses, and that\n// zone is listed even when the browser's list lacks it (some browsers leave\n// 'UTC' out).\n@Component({\n selector: 'fs-ai-report-timezone-select',\n templateUrl: './timezone-select.component.html',\n styleUrls: ['./timezone-select.component.scss'],\n viewProviders: [{ provide: ControlContainer, useExisting: NgForm }],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n MatFormField,\n MatLabel,\n MatSelect,\n MatOption,\n FormsModule,\n FsFormModule,\n ],\n})\nexport class TimezoneSelectComponent {\n\n @Input() public placeholder = 'Timezone';\n @Input() public required = false;\n @Input() public disabled = false;\n @Output() public timezoneChange = new EventEmitter<string>();\n\n @Input() public set timezone(value: string) {\n if (value && value !== this._timezone()) {\n this._timezone.set(value);\n this.timezoneChange.emit(value);\n }\n }\n\n public get timezone(): string {\n return this._timezone();\n }\n\n public guid: string = guid();\n public readonly timezones = computed(() => this._supportedTimezones(this._timezone()));\n\n private readonly _timezone = signal<string>('');\n\n // The browser's IANA zone list where available, with the current value\n // prepended when the list lacks it, so the select always shows the zone the\n // report uses.\n private _supportedTimezones(current: string): string[] {\n const intl = Intl as unknown as { supportedValuesOf?: (key: string) => string[] };\n const zones = typeof intl.supportedValuesOf === 'function'\n ? intl.supportedValuesOf('timeZone')\n : [];\n\n return current && !zones.includes(current)\n ? [current, ...zones]\n : zones;\n }\n}\n","<mat-form-field class=\"full-width\">\n <mat-label>{{placeholder}}</mat-label>\n <mat-select\n [(ngModel)]=\"timezone\"\n [fsFormRequired]=\"required\"\n [disabled]=\"disabled\"\n name=\"timezone_select_{{ guid }}\">\n @for (item of timezones(); track item) {\n <mat-option [value]=\"item\">{{ item }}</mat-option>\n }\n </mat-select>\n</mat-form-field>\n","import { Report } from '../../interfaces/report.interface';\n\n\n// The locale and currency keys for the report settings PUT: each is sent only\n// when the dialog's value differs from the report's stored one ('' = follows\n// the default). An untouched dialog sends neither, so a report that follows the\n// default is never pinned to it, and a stored value the server no longer offers\n// is never sent back to be refused: renaming such a report still saves. A\n// changed value is sent as it is, and '' returns the report to the default.\nexport function reportLocalePatch(\n report: Pick<Report, 'locale' | 'currency'>,\n locale: string,\n currency: string,\n): { locale?: string; currency?: string } {\n return {\n ...(locale !== (report.locale ?? '') ? { locale } : {}),\n ...(currency !== (report.currency ?? '') ? { currency } : {}),\n };\n}\n","import { DOCUMENT } from '@angular/common';\nimport { HttpContext } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy, Component, DestroyRef, Injector, OnInit, afterNextRender, computed, inject, signal,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { AbstractControl, FormsModule } from '@angular/forms';\n\nimport { MatButton } from '@angular/material/button';\nimport { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';\nimport { MatFormField, MatLabel, MatHint, MatSuffix } from '@angular/material/form-field';\nimport { MatInput } from '@angular/material/input';\nimport { MatOption, MatSelect } from '@angular/material/select';\nimport { MatSlideToggle } from '@angular/material/slide-toggle';\nimport { MatTabsModule } from '@angular/material/tabs';\n\nimport { DisplayApiError } from '@firestitch/api';\nimport { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';\nimport { FsDatePickerModule } from '@firestitch/datepicker';\nimport { FsDialogModule } from '@firestitch/dialog';\nimport { FsFormModule } from '@firestitch/form';\nimport { FsLabelModule } from '@firestitch/label';\nimport { FsMaskModule } from '@firestitch/mask';\nimport { FsMessage, FsMessageModule } from '@firestitch/message';\nimport { FsPrompt } from '@firestitch/prompt';\nimport { FsSkeletonModule } from '@firestitch/skeleton';\nimport { FsTabsModule } from '@firestitch/tabs';\n\nimport { TimezoneSelectComponent } from '../../components/timezone-select/timezone-select.component';\n\nimport { Observable, forkJoin, from, of, throwError } from 'rxjs';\nimport { catchError, concatMap, finalize, switchMap, tap, toArray } from 'rxjs/operators';\n\nimport { ReportData } from '../../data/report.data';\nimport { ReportValueFormat } from '../../enums/report-value-format.enum';\nimport {\n DAY_SHORT,\n REPORT_FALLBACK_CURRENCY,\n currencyName,\n formatLocalDate,\n formatNumber,\n localeName,\n resolveReportCurrency,\n resolveReportLocale,\n} from '../../format';\nimport {\n FilterGroupDefault,\n Report,\n ReportFilterGroup,\n ReportLocales,\n} from '../../interfaces/report.interface';\nimport { ReportFilterGroupChanges } from '../../interfaces/report-filter-group-changes.interface';\nimport { DEFAULT_HEADING_SIZE, HEADER_FOOTER_MAX, PAGE_DIMENSION_MAX, PAGE_DIMENSION_MIN } from '../../layout';\nimport {\n dateFromBound, dateToBound, loadGroupOptions, matchOptions, relativeLabel, resolveOptionValues,\n} from '../../report-filter-items';\nimport {\n DEFAULT_BOUND_SCALE,\n FILTER_LABEL_MAX_LENGTH,\n FILTER_NAME_MAX_LENGTH,\n FILTER_NAME_PATTERN,\n FILTER_NAME_PATTERN_MESSAGE,\n FIXED_DATES_PERIOD,\n boundsError,\n dateRangeDefault,\n defaultChanged,\n defaultPeriod,\n defaultPeriodOptions,\n defaultRowGroups,\n defaultRowLabel,\n numberRangeDefault,\n parseDefaultBound,\n selectDefault,\n showExcludeToggle,\n} from '../../filter-settings-rules';\nimport { FilterSettingsOption } from '../../interfaces/filter-settings-option.interface';\n\nimport { reportLocalePatch } from './report-locale-patch';\n\n\n// What the dialog hands back when it closes, so the page knows what happened\n// without sniffing magic strings. A dismissed dialog closes with `undefined`.\nexport interface ReportSettingsResult {\n action: 'saved' | 'deleted';\n}\n\n\n// A Name or Label the server refused for a filter group, with the message it\n// gave.\ninterface FilterFieldRefusal {\n value: string;\n message: string;\n}\n\n// One report bar filter in the Filters tab: its group, its label and name,\n// and an editable draft default. The draft fields used depend on the type\n// (dateRange → a Default period, which is a relative range or Fixed dates\n// with start/end Dates; select → values, kept or left out; keyword → text;\n// numberRange → min and max). `fetch` loads the select options the same way\n// the report bar does.\ninterface FilterDefaultRow {\n group: ReportFilterGroup;\n // The section heading: the label, with the page for a page filter.\n heading: string;\n // The group's label and name as typed, independent of each other. Each is\n // saved only when it differs from the stored one; the name is never\n // derived from the label here.\n label: string;\n name: string;\n // The server sent a name, so it also takes a label and a name on the group\n // update (an older server sends none, and the two fields are hidden).\n showName: boolean;\n // The last label and name the server refused, each shown on its field\n // while the field still holds it.\n labelRefusal: FilterFieldRefusal | null;\n nameRefusal: FilterFieldRefusal | null;\n // A relative range name, or FIXED_DATES_PERIOD for start and end.\n period: string;\n periodOptions: FilterSettingsOption[];\n start: Date | null;\n end: Date | null;\n values: { name: string; value: unknown }[];\n // The values are left out rather than kept.\n exclude: boolean;\n showExclude: boolean;\n value: string;\n // The range ends as typed: fsMaskNumber hands back text. Read through\n // parseDefaultBound.\n min: number | string | null;\n max: number | string | null;\n fetch: (keyword?: string) => Observable<{ name: string; value: unknown }[]>;\n}\n\n// One filter's group update in a save: only the keys the operator changed.\ninterface FilterGroupSave {\n row: FilterDefaultRow;\n changes: ReportFilterGroupChanges;\n}\n\n// One entry of the Locale or Currency select. '' is the explicit Default.\ninterface LocaleSelectOption {\n value: string;\n label: string;\n}\n\n// The day the Locale hint writes, a fixed calendar day so the example never\n// changes under the operator.\nconst EXAMPLE_DAY = new Date(2026, 0, 5);\nconst EXAMPLE_AMOUNT = 1234.5;\n\n// 'Canadian French (fr-CA)', 'Canadian Dollar (CAD)': English names whatever\n// the report's locale, with the code that is stored.\nfunction localeLabel(tag: string): string {\n return `${localeName(tag)} (${tag})`;\n}\n\nfunction currencyLabel(code: string): string {\n return `${currencyName(code)} (${code})`;\n}\n\n\n// Report settings, in three tabs:\n// Settings — name + page setup (size in inches, header/footer band depths).\n// Styles — the report's typographic styles (sizes in POINTS, 1:1 with\n// PDF/PowerPoint); the Heading size to start.\n// Filters — the report bar filters (every page or one page) and their\n// DEFAULT values. A default seeds the report bar on every open (for every\n// viewer) but stays user-changeable — it pre-fills the control, it doesn't\n// lock it. This is the fix for heavy reports opening blank and timing out: a\n// default month + organization scopes the landing page from the first load.\n// The rules of the rows live in filter-settings-rules.ts.\n@Component({\n templateUrl: './report-settings.component.html',\n styleUrls: ['./report-settings.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n imports: [\n FormsModule,\n FsFormModule,\n FsLabelModule,\n FsMaskModule,\n FsDialogModule,\n FsMessageModule,\n FsTabsModule,\n FsSkeletonModule,\n FsDatePickerModule,\n FsAutocompleteChipsModule,\n MatTabsModule,\n MatButton,\n MatDialogTitle,\n MatDialogContent,\n MatDialogActions,\n MatFormField,\n MatLabel,\n MatHint,\n MatSuffix,\n MatInput,\n MatSelect,\n MatOption,\n MatSlideToggle,\n TimezoneSelectComponent,\n ],\n})\nexport class ReportSettingsComponent implements OnInit {\n\n // A signal, so a refused Label or Name can bring the Filters tab forward.\n public readonly selectedTab = signal('settings');\n // True once any save request has been stored, even when the save as a\n // whole then failed: the page reloads after a dismissed dialog too.\n public readonly wrote = signal(false);\n\n public name = '';\n // The page in inches. No initializer: every report carries a size, and\n // ngOnInit seeds both before the tab renders, so a placeholder here could only\n // ever be a wrong number briefly showing as the operator's own.\n //\n // Typed `number | string` because fsMaskNumber is the control: it is seeded\n // with the report's number but hands back the unmasked STRING the operator\n // typed. Save casts it once, on the way out — see `_pageDimension()`.\n public pageWidth: number | string;\n public pageHeight: number | string;\n public readonly pageDimensionMin = PAGE_DIMENSION_MIN;\n public readonly pageDimensionMax = PAGE_DIMENSION_MAX;\n // The header and footer band depths, inches — typed like the page size\n // because fsMaskNumber hands back a string.\n public headerHeight: number | string = 0;\n public footerHeight: number | string = 0;\n public readonly headerFooterMax = HEADER_FOOTER_MAX;\n // Seeded with the zone the report actually uses: its own stored zone, else\n // the application default the server resolved (effectiveTimezone). Save sends\n // it only when it differs from that effective zone, so opening and saving a\n // report that follows the default never pins it to a zone.\n public timezone = '';\n public headingSize = DEFAULT_HEADING_SIZE;\n\n // The locales and currencies the server offers. null until loaded, and\n // never loaded from a server too old to send effectiveLocale: there the\n // selects stay hidden and the report reads en-US/USD.\n public readonly locales = signal<ReportLocales | null>(null);\n // The report's own locale and currency, '' when it follows the default. Save\n // sends each only when it differs from the stored value.\n public readonly locale = signal('');\n public readonly currency = signal('');\n // The whole form waits behind one skeleton until the filter rows are built\n // and the locale request has settled, so the Settings tab never shows\n // without its Locale and Currency selects. A failed locale request settles\n // too: the two selects stay hidden (locales() is still null) and every other\n // setting stays editable.\n public readonly ready = computed(() => this._filtersReady() && (!this._serverHasLocale || this._localesSettled()));\n\n // An explicit Default ('') naming the locale it stands for, then each offered\n // locale. A stored locale the server no longer offers is listed first, so\n // the select still shows what the report holds.\n public readonly localeOptions = computed<LocaleSelectOption[]>(() => {\n const locales = this.locales();\n if (!locales) {\n return [];\n }\n\n const offered = locales.options.map((option) => option.locale);\n\n return [\n ...this._storedOption(this._data.report.locale, offered, localeLabel),\n { value: '', label: `Default — ${localeName(locales.defaultLocale)}` },\n ...offered.map((tag) => ({ value: tag, label: localeLabel(tag) })),\n ];\n });\n\n // An explicit Default ('') naming the currency the selected locale uses when\n // the report names none, then every currency. A stored code the server no\n // longer offers is listed first.\n public readonly currencyOptions = computed<LocaleSelectOption[]>(() => {\n const locales = this.locales();\n if (!locales) {\n return [];\n }\n\n return [\n ...this._storedOption(this._data.report.currency, locales.currencies, currencyLabel),\n { value: '', label: `Default — ${currencyLabel(this._defaultCurrency())}` },\n ...locales.currencies.map((code) => ({ value: code, label: currencyLabel(code) })),\n ];\n });\n\n // How the report will write an amount and a day once saved: the selected\n // locale and currency, or the defaults they fall back to, e.g.\n // '1 234,50 $ · 5 janv. 2026' in fr-CA.\n public readonly formatExample = computed(() => {\n const locale = resolveReportLocale(this._appliedLocale());\n const currency = resolveReportCurrency(this._appliedCurrency());\n\n return [\n formatNumber(\n EXAMPLE_AMOUNT,\n { format: ReportValueFormat.Currency, precision: 2 },\n { locale, currency, ratioPercent: true },\n ),\n formatLocalDate(EXAMPLE_DAY, locale, DAY_SHORT),\n ].join(' · ');\n });\n\n // The report bar filters and their editable default values (Filters tab).\n public readonly filterRows = signal<FilterDefaultRow[]>([]);\n public readonly fixedDatesPeriod = FIXED_DATES_PERIOD;\n public readonly boundScale = DEFAULT_BOUND_SCALE;\n public readonly namePattern = FILTER_NAME_PATTERN;\n public readonly namePatternMessage = FILTER_NAME_PATTERN_MESSAGE;\n public readonly nameMaxLength = FILTER_NAME_MAX_LENGTH;\n public readonly labelMaxLength = FILTER_LABEL_MAX_LENGTH;\n public readonly labelInputId = labelInputId;\n public readonly nameInputId = nameInputId;\n\n // The Default minimum and Default maximum checks, through fsForm. Each field\n // gets the other end as its validateData, so typing in one checks the pair\n // again; boundsError words the refusal as the server does.\n public readonly minBoundValidator = (control: AbstractControl, max: unknown): void => {\n this._throwBoundsError(control.value, max);\n };\n\n public readonly maxBoundValidator = (control: AbstractControl, min: unknown): void => {\n this._throwBoundsError(min, control.value);\n };\n\n // The server's refusal of a Label or Name, through fsForm. The shape and\n // length are checked on the field (fsFormPattern, fsFormMaxLength), but only\n // the server knows the report's other names, so the field shows the\n // server's own words while it still holds the refused value. A new refusal\n // arrives as the field's validateData, which checks the field again.\n public readonly refusalValidator = (control: AbstractControl, refusal: FilterFieldRefusal | null): void => {\n if (refusal && String(control.value ?? '').trim() === refusal.value) {\n throw new Error(refusal.message);\n }\n };\n\n private readonly _data: { report: Report } = inject(MAT_DIALOG_DATA);\n private readonly _dialogRef = inject<MatDialogRef<ReportSettingsComponent, ReportSettingsResult>>(MatDialogRef);\n private readonly _reportData = inject(ReportData);\n private readonly _message = inject(FsMessage);\n private readonly _prompt = inject(FsPrompt);\n private readonly _destroyRef = inject(DestroyRef);\n private readonly _injector = inject(Injector);\n private readonly _document = inject(DOCUMENT);\n // The id of the Label or Name input the server last refused, focused once\n // it is on screen (see focusRefusal).\n private _refusedInputId: string | null = null;\n // Only a server that resolves a report's locale offers the locale list.\n private readonly _serverHasLocale = this._data.report.effectiveLocale !== undefined;\n // True once the locale request has answered, with the list or an error.\n private readonly _localesSettled = signal(false);\n // True once the filter rows are published (see _buildFilterRows).\n private readonly _filtersReady = signal(false);\n\n // The locale the report would be written in: the selected one when the\n // server offers it, else the default (a stored locale it no longer offers\n // falls back to the default, as it does on the server).\n private readonly _appliedLocale = computed(() => {\n const locales = this.locales();\n const locale = this.locale();\n\n return locales?.options.some((option) => option.locale === locale)\n ? locale\n : locales?.defaultLocale ?? '';\n });\n\n // The currency a report in the applied locale uses when it names none.\n private readonly _defaultCurrency = computed(() => {\n const locale = this._appliedLocale();\n\n return this.locales()?.options.find((option) => option.locale === locale)?.defaultCurrency\n ?? REPORT_FALLBACK_CURRENCY;\n });\n\n // The currency the report would label money in: the selected one when the\n // server offers it, else the default.\n private readonly _appliedCurrency = computed(() => {\n const currency = this.currency();\n\n return this.locales()?.currencies.includes(currency)\n ? currency\n : this._defaultCurrency();\n });\n\n public ngOnInit(): void {\n const report = this._data.report;\n this.name = report.name;\n this.pageWidth = report.pageWidth;\n this.pageHeight = report.pageHeight;\n this.headerHeight = report.config?.headerFooter?.headerHeight ?? 0;\n this.footerHeight = report.config?.headerFooter?.footerHeight ?? 0;\n this.timezone = report.timezone ?? report.effectiveTimezone ?? '';\n this.headingSize = report.config?.styles?.heading?.size ?? DEFAULT_HEADING_SIZE;\n this.locale.set(report.locale ?? '');\n this.currency.set(report.currency ?? '');\n\n this._buildFilterRows(report);\n\n if (this._serverHasLocale) {\n this._reportData.locales()\n .pipe(\n tap((locales) => this.locales.set(locales)),\n catchError(() => of(null)),\n finalize(() => this._localesSettled.set(true)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n }\n\n // A change to a row's Label, Name, Default period, exclude toggle or range ends. A new\n // row object rather than a mutation, so the signal sees the change; the\n // @for tracks group.id, so the row's controls survive the swap.\n public patchRow(row: FilterDefaultRow, patch: Partial<FilterDefaultRow>): void {\n this.filterRows.update((rows) => rows\n .map((item) => (item.group.id === row.group.id ? { ...item, ...patch } : item)));\n }\n\n // Focuses the Label or Name input the server refused, once it is on\n // screen: straight after the refusal when the Filters tab is showing, else\n // when the tab group has brought it forward.\n public focusRefusal(): void {\n const input = this._refusedInputId ? this._document.getElementById(this._refusedInputId) : null;\n\n if (input) {\n input.focus();\n this._refusedInputId = null;\n }\n }\n\n // Confirm and delete here, while the dialog is still open, then close with\n // a `deleted` result. The page reacts to the result; it no longer owns the\n // prompt or the API call.\n public delete(): void {\n this._prompt.confirm({\n title: 'Delete Report',\n template: `Delete \"${this._data.report.name}\"? This cannot be undone.`,\n })\n .pipe(\n switchMap(() => this._reportData.delete(this._data.report.id)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe(() => {\n this._message.success('Report deleted');\n this._dialogRef.close({ action: 'deleted' });\n });\n }\n\n public save = () => {\n const reportId = this._data.report.id;\n\n // One Save covers all three tabs. The report reloads on the `saved`\n // result, re-seeding the bar from the new defaults.\n const settings = {\n name: this.name,\n pageWidth: this._pageDimension(this.pageWidth),\n pageHeight: this._pageDimension(this.pageHeight),\n ...this._timezoneSetting(),\n ...reportLocalePatch(this._data.report, this.locale(), this.currency()),\n styles: { heading: { size: this.headingSize } },\n headerFooter: {\n headerHeight: this._pageDimension(this.headerHeight) || 0,\n footerHeight: this._pageDimension(this.footerHeight) || 0,\n },\n };\n\n // One group update per changed filter, carrying only what changed: its\n // label, name and default all live in the group's config, so two requests\n // for one group would each write the config over the other.\n const saves = this.filterRows()\n .map((row) => ({ row, changes: this._groupChanges(row) }))\n .filter((save) => Object.keys(save.changes).length > 0);\n\n // A label or name can be refused, so those updates go first, one after\n // another, and a refusal stops the save before anything else is written:\n // the report settings and the other defaults wait until every name is\n // taken. In sequence, two renames in one save are checked against each\n // other, and a rename onto a name another filter is giving up goes after\n // it. The server applies name before default, so a refused name leaves\n // that filter's default unwritten too.\n const named = this._renameOrder(saves.filter((save) => this._namesOrLabels(save.changes)));\n const defaults = saves.filter((save) => !this._namesOrLabels(save.changes));\n\n return from(named)\n .pipe(\n concatMap((save) => this._saveNamed(reportId, save)),\n toArray(),\n switchMap(() => forkJoin([\n this._reportData.update(reportId, settings),\n ...defaults.map((save) => this._reportData.updateFilterGroup(reportId, save.row.group.id, save.changes)),\n ].map((request$) => request$.pipe(tap(() => this.wrote.set(true)))))),\n tap(() => {\n this._message.success('Report settings saved');\n this._dialogRef.close({ action: 'saved' });\n }),\n );\n };\n\n // The page dimension as a real number for the wire. fsMaskNumber hands back\n // the unmasked string it built with a fixed '.' radix (which is the whole\n // point of the mask - a native number input paints the viewer's locale\n // separator instead), so the cast here is a straight parse and never sees a\n // comma. The backend rejects anything non-numeric rather than coercing, so a\n // NaN fails loudly instead of silently storing a wrong page size.\n private _pageDimension(value: number | string): number {\n return typeof value === 'number' ? value : parseFloat(value);\n }\n\n // The zone for the settings PUT, sent only when it moves the report off the\n // zone it already uses, so an untouched dialog never pins a report that\n // follows the application default. A server too old to send\n // effectiveTimezone gets the zone every time, as it always did.\n private _timezoneSetting(): { timezone?: string } {\n const effectiveTimezone = this._data.report.effectiveTimezone;\n\n return effectiveTimezone === undefined || this.timezone !== effectiveTimezone\n ? { timezone: this.timezone }\n : {};\n }\n\n // The stored value as its own option when the server no longer offers it, so\n // the select names it instead of showing blank. Left as it is, it is never\n // sent (see reportLocalePatch), and the report reads the default meanwhile.\n private _storedOption(\n stored: string | null | undefined,\n offered: string[],\n label: (value: string) => string,\n ): LocaleSelectOption[] {\n return stored && !offered.includes(stored) ? [{ value: stored, label: label(stored) }] : [];\n }\n\n // What a save changes on a row's group: the label, name and default, each\n // only when the operator changed it. Label and name are sent only to a\n // server that sent a name, and never one from the other.\n private _groupChanges(row: FilterDefaultRow): ReportFilterGroupChanges {\n const changes: ReportFilterGroupChanges = {};\n\n if (row.showName) {\n const label = row.label.trim();\n if (label !== (row.group.label ?? '')) {\n changes.label = label;\n }\n\n const name = row.name.trim();\n if (name !== row.group.name) {\n changes.name = name;\n }\n }\n\n const rowDefault = this._rowDefault(row);\n if (defaultChanged(row.group.config?.default, rowDefault)) {\n changes.default = rowDefault;\n }\n\n return changes;\n }\n\n private _namesOrLabels(changes: ReportFilterGroupChanges): boolean {\n return changes.name !== undefined || changes.label !== undefined;\n }\n\n // The updates in the order they are sent: a rename onto a name another\n // filter holds goes after the others, so a filter giving that name up in\n // the same save has done so first.\n private _renameOrder(saves: FilterGroupSave[]): FilterGroupSave[] {\n const held = (save: FilterGroupSave): boolean => {\n const name = save.changes.name?.toLowerCase();\n\n return name !== undefined && this.filterRows()\n .some((row) => row.group.id !== save.row.group.id && row.group.name?.toLowerCase() === name);\n };\n\n return [...saves].sort((a, b) => Number(held(a)) - Number(held(b)));\n }\n\n // Saves a filter's update that carries a label or name. A refusal is the\n // server's to word ('Name \"region\" is already used by the filter\n // \"Area\".'), so it shows on the field rather than in a dialog, and the save\n // fails. What was saved becomes the row's stored group, so a later save\n // does not send it again.\n private _saveNamed(reportId: number, save: FilterGroupSave): Observable<unknown> {\n const { row, changes } = save;\n\n return this._reportData.updateFilterGroup(\n reportId,\n row.group.id,\n changes,\n { context: new HttpContext().set(DisplayApiError, false) },\n )\n .pipe(\n tap(() => {\n this.wrote.set(true);\n this.patchRow(row, { group: storedGroup(row.group, changes) });\n }),\n catchError((error: unknown) => {\n this._showRefusal(row, changes, refusalMessage(error));\n\n return throwError(() => error);\n }),\n );\n }\n\n // Shows a refusal on the field it is about (the name, which the server\n // checks first, else the label), brings the Filters tab forward and\n // focuses the field, so a save made from another tab says why it failed.\n private _showRefusal(row: FilterDefaultRow, changes: ReportFilterGroupChanges, message: string): void {\n if (changes.name !== undefined) {\n this.patchRow(row, { nameRefusal: { value: changes.name, message } });\n this._refusedInputId = nameInputId(row.group.id);\n } else {\n this.patchRow(row, { labelRefusal: { value: changes.label ?? '', message } });\n this._refusedInputId = labelInputId(row.group.id);\n }\n\n this.selectedTab.set('filters');\n afterNextRender(() => this.focusRefusal(), { injector: this._injector });\n }\n\n private _throwBoundsError(min: unknown, max: unknown): void {\n const error = boundsError(parseDefaultBound(min), parseDefaultBound(max));\n\n if (error) {\n throw new Error(error);\n }\n }\n\n // Build one editable row per report bar filter group (every page or one\n // page), in bar order, seeding each draft from the group's stored default.\n private _buildFilterRows(report: Report): void {\n const built = defaultRowGroups(report.filterGroups)\n .map((group) => {\n const groupDefault = group.config?.default;\n // One shared, replayed option stream per group: the chips fetch and the\n // stored default's labels read the same list, so it is fetched once.\n const options$ = loadGroupOptions(group, this._reportData, report.id);\n const row = this._filterRow(report, group, options$);\n\n return { row, options$, values: groupDefault?.values ?? groupDefault?.excludeValues ?? [] };\n });\n\n const rows = built.map((entry) => entry.row);\n const seeded = built.filter((entry) => entry.values.length);\n\n // Nothing to name — publish immediately rather than waiting on a request\n // no row needs.\n if (!seeded.length) {\n this._publishFilterRows(rows);\n\n return;\n }\n\n // A stored select default holds ids, so its chips can only be named once the\n // option list is in. Resolve every seeded row first and publish the rows in\n // one go, so the tab never renders a chip showing a raw id. When an option\n // list fails to load, the rows publish unresolved: each chip names its id,\n // and an untouched row still saves the stored default unchanged.\n forkJoin(seeded.map((entry) => resolveOptionValues(entry.options$, entry.values)))\n .pipe(\n catchError(() => of(seeded.map((entry) => entry.values.map((value) => ({ name: String(value), value }))))),\n tap((resolved) => {\n resolved.forEach((values, index) => seeded[index].row.values = values);\n this._publishFilterRows(rows);\n }),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe();\n }\n\n // One row's draft, seeded from its group's stored default. A stored select\n // default's values are named later, once the option list carrying their\n // labels is in (see _buildFilterRows).\n private _filterRow(\n report: Report,\n group: ReportFilterGroup,\n options$: Observable<{ name: string; value: unknown }[]>,\n ): FilterDefaultRow {\n const groupDefault = group.config?.default;\n\n return {\n group,\n heading: defaultRowLabel(group, report.pages),\n label: group.label ?? '',\n name: group.name ?? '',\n showName: typeof group.name === 'string',\n labelRefusal: null,\n nameRefusal: null,\n period: defaultPeriod(groupDefault),\n periodOptions: defaultPeriodOptions(relativeLabel, groupDefault?.relative ?? null),\n start: dateFromBound(groupDefault?.start),\n end: dateFromBound(groupDefault?.end),\n values: [],\n exclude: !!groupDefault?.excludeValues?.length,\n // An older server lists no features, and leaves no values out.\n showExclude: showExcludeToggle(group, report.viewerFeatures),\n value: groupDefault?.value ?? '',\n min: groupDefault?.min ?? null,\n max: groupDefault?.max ?? null,\n // fs-autocomplete-chips fetch: the group's distinct options, name-filtered.\n // Same loader the report bar uses, so the two never drift.\n fetch: (keyword?: string) => matchOptions(options$, keyword),\n };\n }\n\n private _publishFilterRows(rows: FilterDefaultRow[]): void {\n this.filterRows.set(rows);\n this._filtersReady.set(true);\n }\n\n // The draft default normalized to the wire shape for this row's type, or null\n // when empty (which clears the stored default).\n private _rowDefault(row: FilterDefaultRow): FilterGroupDefault | null {\n switch (row.group.type) {\n case 'dateRange':\n return dateRangeDefault(row.period, dateToBound(row.start), dateToBound(row.end));\n\n case 'select':\n // A hidden toggle leaves nothing out.\n return selectDefault(row.values.map((option) => option.value), row.showExclude && row.exclude);\n\n case 'numberRange':\n return numberRangeDefault(row.min, row.max);\n\n case 'keyword':\n default: {\n const value = row.value.trim();\n\n return value ? { value } : null;\n }\n }\n }\n\n}\n\n\n// What a refused request says: the server's message, else the error's own,\n// else a plain fallback.\nfunction refusalMessage(error: unknown): string {\n const failure = error as { error?: { message?: unknown }; message?: unknown } | null;\n const message = failure?.error?.message ?? failure?.message;\n\n return typeof message === 'string' && message ? message : 'The filter could not be saved.';\n}\n\n// The group as the server now stores it, once an update carrying `changes`\n// is taken.\nfunction storedGroup(group: ReportFilterGroup, changes: ReportFilterGroupChanges): ReportFilterGroup {\n return {\n ...group,\n ...(changes.name !== undefined ? { name: changes.name } : {}),\n ...(changes.label !== undefined ? { label: changes.label } : {}),\n config: changes.default !== undefined\n ? { ...group.config, default: changes.default ?? undefined }\n : group.config,\n };\n}\n\n// The ids of a filter's Label and Name inputs, so a refused one can be\n// focused.\nfunction labelInputId(groupId: number): string {\n return `filterLabel${groupId}`;\n}\n\nfunction nameInputId(groupId: number): string {\n return `filterName${groupId}`;\n}\n","<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\n <!-- animationDone: a refused Label or Name is focused once the\n Filters tab is on screen. -->\n <mat-tab-group\n [(selected)]=\"selectedTab\"\n (animationDone)=\"focusRefusal()\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout → Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n <!-- One section per report bar filter: its heading, its label\n and name, then its default, one field per row. -->\n @for (row of filterRows(); track row.group.id) {\n <h3>\n {{ row.heading }}\n </h3>\n <!-- The label and the name are independent: a new label\n never changes the name, and the name is edited on its\n own. The server checks both, and its refusal shows on\n the field (refusalValidator). -->\n @if (row.showName) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Label\n </mat-label>\n <input\n matInput\n [id]=\"labelInputId(row.group.id)\"\n [ngModel]=\"row.label\"\n (ngModelChange)=\"patchRow(row, { label: $event })\"\n [name]=\"'label' + row.group.id\"\n [fsFormRequired]=\"true\"\n [fsFormMaxLength]=\"labelMaxLength\"\n [validate]=\"refusalValidator\"\n [validateData]=\"row.labelRefusal\">\n <mat-hint>\n What the filter shows. Changing it never changes the name.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [id]=\"nameInputId(row.group.id)\"\n [ngModel]=\"row.name\"\n (ngModelChange)=\"patchRow(row, { name: $event })\"\n [name]=\"'name' + row.group.id\"\n [fsFormRequired]=\"true\"\n [fsFormPattern]=\"namePattern\"\n [fsFormPatternMessage]=\"namePatternMessage\"\n [fsFormMaxLength]=\"nameMaxLength\"\n [validate]=\"refusalValidator\"\n [validateData]=\"row.nameRefusal\">\n <mat-hint>\n How the AI refers to this filter: a letter, then letters and digits.\n </mat-hint>\n </mat-form-field>\n }\n @switch (row.group.type) {\n @case ('dateRange') {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default period\n </mat-label>\n <mat-select\n [ngModel]=\"row.period\"\n (ngModelChange)=\"patchRow(row, { period: $event })\"\n [name]=\"'period' + row.group.id\">\n @for (option of row.periodOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (row.period === fixedDatesPeriod) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default from\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default to\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n }\n }\n @case ('select') {\n <fs-label-field class=\"full-width\">\n <fs-autocomplete-chips\n class=\"full-width\"\n label=\"Default values\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n </fs-label-field>\n @if (row.showExclude) {\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"row.exclude\"\n (ngModelChange)=\"patchRow(row, { exclude: $event })\"\n [name]=\"'exclude' + row.group.id\">\n Exclude these values\n </mat-slide-toggle>\n </fs-label-field>\n }\n }\n @case ('numberRange') {\n <!-- fsMaskNumber hands back text; the check and the save\n read it through parseDefaultBound, so 0 is kept. -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default minimum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.min\"\n (ngModelChange)=\"patchRow(row, { min: $event })\"\n [name]=\"'min' + row.group.id\"\n [validate]=\"minBoundValidator\"\n [validateData]=\"row.max\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default maximum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.max\"\n (ngModelChange)=\"patchRow(row, { max: $event })\"\n [name]=\"'max' + row.group.id\"\n [validate]=\"maxBoundValidator\"\n [validateData]=\"row.min\">\n </mat-form-field>\n }\n @default {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default text\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report bar filters yet. Add a filter to a\n component (its settings → Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>","// A table tile as the PDF and the deck draw it: the printed table\n// readGridTable() reads (GridTable) as heading rows, body rows and a total\n// row of plain cells, and the lines its notes add. Pure, so both renderers\n// draw one table one way.\nimport { GridLayout, GridRowKind, GridTable, GridTableHeading, headingLabel } from '@firestitch/grid';\n\nimport { ReportFormatContext } from '../interfaces/report.interface';\n\nimport { gridFilterLineText } from './report-filter-lines';\n\n\n// The most pivot columns a file draws, from the first.\nexport const GRID_EXPORT_COLUMNS = 60;\n\n// One cell of an exported table. A heading cell spans what the screen's\n// header spans; a group, total or emphasized (subtotal, total) cell is bold;\n// a group's label steps in by its depth.\nexport interface GridExportCell {\n text: string;\n colSpan: number;\n rowSpan: number;\n bold: boolean;\n indent: number;\n numeric: boolean;\n}\n\nexport interface GridExportTable {\n // Heading rows top first, each holding only the cells that start on it\n head: GridExportCell[][];\n body: GridExportCell[][];\n foot: GridExportCell[] | null;\n // One per table column: it holds formatted numbers, right-aligned\n numeric: boolean[];\n // Lines past the row cap, which the moreRowsNotice row counts\n moreRows: number;\n}\n\n// The table's heading, body and total row as cells. A group's label carries\n// its row count after it, as the screen writes it.\nexport function gridExportTable(table: GridTable): GridExportTable {\n const numeric = table.columns.map((column) => column.numeric);\n const head = Array.from({ length: Math.max(1, table.headingRows) }, (_, row) => table.headings\n .filter((heading) => heading.row === row)\n .sort((a, b) => a.column - b.column)\n .map((heading) => exportCell(headingText(heading), true, 0, heading.numeric, heading.columnSpan, heading.rowSpan)));\n const line = (row: GridTable['rows'][number]) => row.cells.map((cell, index) => {\n const isLabel = index === 0 && table.groupColumn;\n\n return exportCell(\n isLabel && row.count ? `${cell.text} (${row.count})` : cell.text,\n row.kind !== GridRowKind.Detail || !!table.columns[index]?.emphasis,\n isLabel ? row.depth : 0,\n numeric[index] ?? false,\n );\n });\n\n return {\n head,\n body: table.rows.map(line),\n foot: table.totalRow ? line(table.totalRow) : null,\n numeric,\n moreRows: table.moreRows,\n };\n}\n\n// The lines a table adds under its box: the screen's notes, the pivot\n// columns it leaves out, and each column filter of the layout it was read in,\n// its field named as its column is headed.\nexport function gridExportNotes(table: GridTable, layout: GridLayout, locale: ReportFormatContext['locale']): string[] {\n const fields = new Map(table.fields.map((field) => [field.name, field]));\n const filters = (layout.filters ?? [])\n .map((filter) => gridFilterLineText(headingLabel(table.fields, layout, filter.field), filter, fields.get(filter.field), locale))\n .filter((text): text is string => !!text);\n\n return [\n ...table.notes,\n ...(table.shownColumns < table.columnCount ? [`Showing the first ${table.shownColumns} of ${table.columnCount} columns`] : []),\n ...filters,\n ];\n}\n\nfunction headingText(heading: GridTableHeading): string {\n return heading.hint ? `${heading.label} (${heading.hint})` : heading.label;\n}\n\nfunction exportCell(text: string, bold: boolean, indent: number, numeric: boolean, colSpan = 1, rowSpan = 1): GridExportCell {\n return { text, colSpan, rowSpan, bold, indent, numeric };\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { GridFormatter, GridTable, readGridTable } from '@firestitch/grid';\n\nimport { Observable, forkJoin, from, map, of } from 'rxjs';\nimport { catchError, mergeMap, switchMap, toArray } from 'rxjs/operators';\n\nimport { reportGridFormatter } from '../components/component-grid/report-grid-formatter';\nimport { ReportGridSource } from '../data/report-grid-source';\nimport { ReportData } from '../data/report.data';\nimport { crumbedTitle, drillCrumbLabels } from '../drill-crumbs';\nimport { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport { layerFilterFields, textFilterFields } from '../filter-text';\nimport {\n DAY_LONG,\n formatLocalDate,\n formatNumber,\n formatOutputValue,\n formatReportDate,\n hasNumberFormat,\n resolveReportTimezone,\n} from '../format';\nimport { ReportExportLine } from '../interfaces/report-export-line.interface';\nimport { ReportExportLinesInput } from '../interfaces/report-export-lines-input.interface';\nimport { ReportExportSnapshot } from '../interfaces/report-export-snapshot.interface';\nimport { ReportStateSnapshot } from '../interfaces/report-state-snapshot.interface';\nimport {\n ComponentData,\n ComponentDataState,\n FilterGroupValue,\n ListColumn,\n ListConfig,\n Report,\n ReportComponent,\n ReportFormatContext,\n ReportLocaleTag,\n ReportMaster,\n ReportPage,\n ReportPageValue,\n ReportRelativeRange,\n ResolvedFilterValue,\n} from '../interfaces/report.interface';\nimport { KpiCardView } from '../kpi-card';\nimport {\n LIST_TOTAL_LABEL,\n ListOutputColumn,\n listHiddenColumns,\n listOutputColumns,\n listTotalsLabelColumn,\n} from '../list-config';\nimport { pivotColumnSpecs } from '../option-builder';\nimport { componentNoteLines, componentWindowsLine } from '../output-notes';\nimport { groupOptionsReader, resolveOptionValues } from '../report-filter-items';\nimport { authoredGridLayout } from '../report-grid-layout';\nimport { isTile } from '../report-tile';\nimport { offeredViewerFeatures } from '../report-viewer-features';\nimport { ReportFilterOptionsService } from '../services/report-filter-options.service';\nimport { ReportFilterStateService } from '../services/report-filter-state.service';\nimport { TextFilterField, TextTokenContext, TextValue, fillTitleTokens, textPlain } from '../text';\nimport { tileDataState, valuesMatchAnyGroupIds } from '../tile-data-state';\nimport {\n failedValueKeys, reportComponents, shownValues, textValues, valueKeys,\n} from '../values';\n\nimport { exportLines, matchLineText, valuePicks } from './report-filter-lines';\nimport { GRID_EXPORT_COLUMNS, gridExportNotes } from './report-grid-export';\n\n\nexport interface CollectedComponent {\n component: ReportComponent;\n // null = its query failed; exports show a note. Always null for a text\n // block, which has no query — see isFailed().\n data: ComponentData | null;\n // The text a list was searched by when it was fetched; absent when its\n // search box was empty, and for every other component.\n search?: string;\n // The config columns a viewer hid on a plain list, which its table leaves\n // out (listColumns); empty for every other component.\n hiddenColumns: string[];\n // The breadcrumb of the drill path a chart was read at (the path its\n // answer applied), in the report's locale; absent at the chart's top.\n crumbs?: string[];\n // A table tile as the screen draws it (readGridTable()), up to the\n // renderer's row cap and GRID_EXPORT_COLUMNS columns; its data is then\n // the read's report line, with no rows. Absent for every other component.\n table?: GridTable;\n // The lines a table adds under its box (gridExportNotes()).\n tableNotes?: string[];\n // A table whose column filters narrowed its rows, which its title says.\n filtered?: boolean;\n}\n\nexport interface CollectedPage {\n page: ReportPage;\n components: CollectedComponent[];\n // What the page's text blocks fill their {{value.<key>}} tokens with, by key\n // (textValues), and the keys of the values its text shows whose numbers did\n // not come back: the request failed, or the value's own query did.\n values: Record<string, TextValue>;\n failedValues: string[];\n}\n\nexport interface CollectedReport {\n report: Report;\n pages: CollectedPage[];\n // The header and footer's values, as a page's: read once for the whole\n // file, since every page that shows the master shows the same numbers.\n masterValues: Record<string, TextValue>;\n masterFailedValues: string[];\n // The filter lines of the title slide/page, in order: the\n // export's filter lines (coverFilterLines), then the match while it is\n // 'any'.\n filterSummary: string[];\n // What each {{filter.<id>}} token prints, by filter group id: the filter\n // bar's values as the screen words them, read once so every page of the\n // file agrees. Every group's: a page reads its own (layerFilterFields).\n filterFields: Record<number, TextFilterField>;\n // What the numbers are measured in, for the title slide/page: the zone and\n // the currency the server resolved for the report. Each is left out when the\n // server does not send it, rather than a guess that would be wrong whenever\n // the default applies.\n contextLines: string[];\n // How the open report writes its numbers and dates (its locale, currency\n // and percent form), read once so every page of the file agrees.\n formatContext: ReportFormatContext;\n}\n\n// How an export words the screen (exportWording): the filter lines (the\n// cover's, and the zip's notes), what each {{filter.<id>}} token prints, by\n// filter group id, and each tile's title as the canvas header reads it, by\n// component id, which the zip names the tile's file after.\nexport interface ReportExportWording {\n lines: ReportExportLine[];\n filterFields: Record<number, TextFilterField>;\n titles: Record<number, string>;\n}\n\n// A text block whose words do not fit its box in a built file: the block, the\n// page the overflow gate names it under (HEADER_FOOTER_NAME for a header or\n// footer block) and the start of its text, so the reader can find it.\nexport interface TextOverflow {\n componentId: number;\n page: string;\n snippet: string;\n}\n\n// A component a build could not draw: the page the export's gate names it\n// under and how it reads there, its title or the start of a text block's\n// words.\nexport interface UndrawnComponent {\n componentId: number;\n page: string;\n name: string;\n}\n\n// A file built and not yet saved. Whether text fits its box, and whether every\n// component could be drawn, is known only once the file is built, so the\n// export asks about both between the build and the save: `overflowNote` says\n// what this format does with such text, `undrawn` lists the components the\n// file marks as not drawn in their place, and `save` writes the file.\nexport interface BuiltExport {\n overflows: TextOverflow[];\n overflowNote: string;\n undrawn: UndrawnComponent[];\n save: () => void | Promise<void>;\n}\n\n// One exported list column: the cell key, its heading and its format, and\n// whether its cells are formatted numbers, which every export right-aligns\n// (header included) as the screen does. A column that holds a compared,\n// windowed, ranked or shared output carries how it is written (output), and\n// holds numbers whether or not it names a format.\nexport type ExportListColumn = ListColumn & { numeric: boolean; output?: ListOutputColumn };\n\n// How tall each part of an exported KPI card is, in the renderer's unit\n// (points in the PDF, inches in the deck). A note is one line.\nexport interface KpiExportHeights {\n value: number;\n label: number;\n delta: number;\n window: number;\n target: number;\n sparkline: number;\n note: number;\n}\n\n// The parts of a KPI card an export draws: the value and its label always,\n// the rest when the card has them and the tile has room (kpiExportParts).\n// scale shrinks the rows and their text when the parts that always stay still\n// stand taller than the tile (scaledKpiHeights): 1 when they fit.\nexport interface KpiExportParts {\n delta: boolean;\n window: boolean;\n target: boolean;\n sparkline: boolean;\n notes: string[];\n scale: number;\n}\n\n// How far a KPI card's rows shrink to fit a short tile. A tile shorter still\n// lets the card run past its foot rather than print it unreadably small.\nconst KPI_EXPORT_MIN_SCALE = 0.5;\n\n// How many tile queries an export runs at once.\n//\n// Not a politeness setting — it is the difference between a deck and a broken\n// one. These queries are heavy and read the same tables, so firing all of them\n// together puts every one in contention for the same database at the same\n// moment and they cross the statement ceiling as a group: measured on report\n// 28, ten tiles that each answer in 9-24s run one after another all failed at\n// ~30s when released together. Concurrency buys wall-clock only up to the point\n// where the queries start taking it back off each other, and past that it buys\n// failures.\nconst EXPORT_CONCURRENCY = 3;\n\n// What the export gates call the header and footer: when a value they show\n// came back without its number, and when one of their text blocks does not\n// fit its box.\nexport const HEADER_FOOTER_NAME = 'Header & footer';\n\n// How much of a text block's words the export gates quote to name a block that\n// does not fit its box.\nconst OVERFLOW_SNIPPET_LENGTH = 40;\n\n// One request in an export's queue: a tile's data, or the numbers of the\n// values one layer's text reads, read together. A values job's pageIndex is\n// null for the header and footer (the master); `values` is every value of the\n// layer, which names its tokens and whose filter values the request carries,\n// and `components` the ones its text shows, whose numbers the failure gate\n// requires.\ntype CollectJob =\n | { kind: 'component'; pageIndex: number; component: ReportComponent }\n | {\n kind: 'values';\n pageIndex: number | null;\n pageId: number;\n values: ReportComponent[];\n components: ReportComponent[];\n };\n\n// One layer's values as the file prints them.\ntype CollectedValues = Pick<CollectedPage, 'values' | 'failedValues'>;\n\n// What a job came back with, and the page it is filed under.\ntype CollectResult =\n | { kind: 'component'; pageIndex: number; item: CollectedComponent }\n | { kind: 'values'; pageIndex: number | null; collected: CollectedValues };\n\n// What a component with nothing to draw prints in the exported file.\n//\n// The two cases must not read alike. A tile that returned no rows is a finding\n// about the period — the report worked and the answer is \"none\". A tile whose\n// query failed is a hole in the file, and calling that \"Data unavailable\" tells\n// the reader the data does not exist when what happened is that nobody managed\n// to ask for it. Shared by both renderers so the PDF and the deck cannot end up\n// describing the same hole two different ways.\nexport function emptyLabel(item: CollectedComponent): string {\n return item.data ? 'No data' : 'Could not be generated';\n}\n\n// A component's title as an exported file prints it: its tokens filled with\n// the page it is drawn on (the physical page where the PDF numbers a\n// continuation page), as the canvas header reads it. A drilled chart's title\n// is followed by its breadcrumb, `crumbs` (drillCrumbLabels): 'Orders by\n// Period › 2026 › Q3'. A searched list says so, since its table holds only\n// the matching rows: 'Orders (matching \"north\")'. An untitled one reads\n// 'Matching \"north\"'. '' when there is nothing to print. Shared by the PDF\n// and the deck, continuation pages included.\nexport function exportTitle(\n component: ReportComponent,\n tokens: TextTokenContext,\n search?: string | null,\n crumbs?: readonly string[] | null,\n filtered = false,\n): string {\n const title = crumbedTitle(fillTitleTokens(component.title, tokens), crumbs ?? []);\n\n if (filtered) {\n return title ? `${title} (filtered)` : 'Filtered';\n }\n\n if (!search) {\n return title;\n }\n\n return title ? `${title} (matching \"${search}\")` : `Matching \"${search}\"`;\n}\n\n// Whether a tile's query failed. A text block has no query, so it never did.\nexport function isFailed(item: CollectedComponent): boolean {\n return !item.data && item.component.type !== 'text';\n}\n\n// A text block that does not fit its box in a built file, as the overflow gate\n// names it: under its page (HEADER_FOOTER_NAME for a header or footer block)\n// and by the start of its words, on one line. Shared by the PDF and the deck.\nexport function textOverflow(component: ReportComponent, page: string, tokens: TextTokenContext): TextOverflow {\n const text = textPlain(component.config?.html ?? '', tokens).replace(/\\s+/g, ' ').trim();\n\n return {\n componentId: component.id,\n page,\n snippet: text.length > OVERFLOW_SNIPPET_LENGTH ? `${text.slice(0, OVERFLOW_SNIPPET_LENGTH).trimEnd()}…` : text,\n };\n}\n\n// The lines under the report's name on the PDF title page and the title slide:\n// the export date, the active filters, then what the numbers are measured in.\n// The date always leads (the PowerPoint marks that line as written in the\n// report's locale). It is today in the report's zone, the same day its filters\n// resolve \"today\" to, written in the report's locale.\nexport function coverLines(collected: CollectedReport): string[] {\n return [\n formatLocalDate(\n new Date(),\n collected.formatContext.locale,\n DAY_LONG,\n resolveReportTimezone(collected.report),\n ),\n ...collected.filterSummary,\n ...collected.contextLines,\n ];\n}\n\n// An exported list cell, reading like the on-screen cell, through the same\n// functions as the screen: a date column renders in the report's zone and\n// locale, and a column with number-format keys (a cross-tab's cells through\n// its cellFormat) in the report's locale and currency. Any other value goes\n// out verbatim, and an empty one as ''. CSV never comes through here: its\n// values stay raw.\n//\n// An output column is written by what it holds, as the screen's cell is\n// (formatOutputValue): a signed change, a percent change, a change of a rate\n// in points, a rank, a share. Its row gives a change the prior beside it, so\n// a missing baseline ('—') reads apart from a zero one ('n/a').\nexport function exportCell(\n value: unknown,\n column: ListColumn & { output?: ListOutputColumn },\n timezone: string,\n context: ReportFormatContext,\n row?: Record<string, unknown> | null,\n): string {\n const output = column.output;\n\n if (output) {\n return formatOutputValue(value, output.output, column, context, {\n measureSpec: output.measureSpec,\n prior: output.priorAlias && row ? row[output.priorAlias] : undefined,\n floor: output.floor,\n empty: '',\n }).text;\n }\n\n if (value === null || value === undefined) {\n return '';\n }\n\n if (column.format === ReportListColumnFormat.Date) {\n return formatReportDate(value, timezone, context.locale);\n }\n\n return hasNumberFormat(column) ? formatNumber(value, column, context, { empty: '' }) : String(value);\n}\n\n// The columns an exported list table draws. A cross-tab's arrive with its\n// rows (the row key first, then one per pivot value), since only the result\n// knows the pivot values, and are built by pivotColumnSpecs() as on screen:\n// headed by its periods in the report's locale, each pivot value formatted by\n// cellFormat. A plain list draws its configured columns but the ones the\n// viewer hid (`hidden`, kept to listHiddenColumns, so never all of them),\n// else every column the query returned, as it came. Output columns (the\n// data's outputs, a cross-tab cell through cellMeasures) carry how they are\n// written; without those keys the columns are exactly as before.\nexport function listColumns(\n component: ReportComponent,\n data: ComponentData,\n locale: ReportLocaleTag,\n hidden: readonly string[] = [],\n): ExportListColumn[] {\n const config = (component.config ?? {}) as ListConfig;\n\n if (config.pivotBy?.column) {\n return withOutputColumns(pivotColumnSpecs(config, data, locale), data, []);\n }\n\n if (config.columns?.length) {\n const hiddenNames = listHiddenColumns(config, hidden);\n\n return withOutputColumns(\n config.columns\n .filter((column) => !hiddenNames.includes(column.column))\n .map((column) => ({ ...column, numeric: hasNumberFormat(column) })),\n data,\n config.columns,\n );\n }\n\n return withOutputColumns(data.columns.map((column) => ({ column, numeric: false })), data, []);\n}\n\n// The columns with their output metadata attached (listOutputColumns, as the\n// screen's list resolves it): an output column holds numbers and is written\n// by what it holds. Unchanged when the data has no outputs.\nfunction withOutputColumns(\n columns: ExportListColumn[],\n data: ComponentData,\n authored: readonly ListColumn[],\n): ExportListColumn[] {\n if (!data.outputs) {\n return columns;\n }\n\n const outputs = listOutputColumns(columns, data, authored);\n\n return columns.map((column) => (outputs[column.column]\n ? { ...column, numeric: true, output: outputs[column.column] }\n : column));\n}\n\n// The heading over each column of listColumns(): a plain list's configured\n// label, else its column; a cross-tab's heading from pivotColumnSpecs().\nexport function listHeadings(\n component: ReportComponent,\n data: ComponentData,\n locale: ReportLocaleTag,\n hidden: readonly string[] = [],\n): string[] {\n return listColumns(component, data, locale, hidden).map((column) => column.label || column.column);\n}\n\n// An exported list's totals row, one cell per column of listColumns(): each\n// total written like its column's cells, and LIST_TOTAL_LABEL in the first\n// column when that column holds no total (a cross-tab's row key). null when\n// the list has no totals. The CSV never carries one: its rows stay raw.\nexport function listTotalsRow(\n data: ComponentData,\n columns: readonly ExportListColumn[],\n timezone: string,\n context: ReportFormatContext,\n): string[] | null {\n const totals = data.totals;\n\n if (!totals) {\n return null;\n }\n\n const label = listTotalsLabelColumn(columns, totals);\n\n return columns.map((column) => (column.column === label\n ? LIST_TOTAL_LABEL\n : exportCell(totals[column.column], column, timezone, context, totals)));\n}\n\n// The subtitle under a chart's or a list's title: the days it reads, and the\n// days each comparison lane reads ('Sep 1 – 15, 2026 · vs previous month:\n// Aug 1 – 15, 2026'), as the screen's note opens with. '' without a\n// comparison or a timeframe, and for a KPI, whose card prints its own window\n// line.\nexport function exportWindowsLine(item: CollectedComponent, timezone: string, locale: ReportLocaleTag): string {\n if (!item.data || item.component.type === 'kpi') {\n return '';\n }\n\n return componentWindowsLine(item.data, { locale, timezone });\n}\n\n// The note lines under a component's box: why a comparison reads as it does,\n// a KPI's delta note, and what each windowed value is and why. The days are\n// left out (the subtitle or the KPI card prints them), and the window\n// descriptions are in, since a file has no tooltip or header to carry them.\n// Empty when the data has none of the keys.\nexport function exportNoteLines(item: CollectedComponent, timezone: string, locale: ReportLocaleTag): string[] {\n return [\n ...componentNoteLines(item.data, { locale, timezone }, { windows: false, windowDescriptions: true }),\n ...(item.tableNotes ?? []),\n ];\n}\n\n// Whether a tile has nothing to draw: no rows, or a table with no line.\nexport function isEmptyTile(item: CollectedComponent): boolean {\n return item.table\n ? !item.table.rows.length && !item.table.totalRow\n : !item.data?.rows?.length;\n}\n\n// Whether a KPI card has more to draw than its value and label. Without, both\n// exports draw the tile exactly as they always have.\nexport function kpiCardHasExtras(view: KpiCardView, notes: readonly string[]): boolean {\n return !!(view.delta || view.window || view.target || view.sparkline || notes.length);\n}\n\n// Which parts of a KPI card fit a tile `available` tall. A short tile sheds the\n// sparkline first, then the target line, then the notes; the value, its label\n// and the delta row always stay, and the window line stays whenever the card\n// shows a comparison (its days are what the delta is measured over). The\n// sparkline needs values to draw. When what stays is still too tall, every\n// row shrinks by the same scale, down to KPI_EXPORT_MIN_SCALE; by then the\n// sparkline, the target and the notes are gone.\nexport function kpiExportParts(\n view: KpiCardView,\n notes: readonly string[],\n available: number,\n heights: KpiExportHeights,\n): KpiExportParts {\n const parts: KpiExportParts = {\n delta: !!view.delta,\n window: !!view.window,\n target: !!view.target,\n sparkline: !!view.sparkline?.values.some((value) => value !== null),\n notes: [...notes],\n scale: 1,\n };\n const height = () => kpiExportHeight(view, parts, heights);\n\n if (height() > available) {\n parts.sparkline = false;\n }\n\n if (height() > available) {\n parts.target = false;\n }\n\n while (height() > available && parts.notes.length) {\n parts.notes.pop();\n }\n\n if (height() > available && !parts.delta) {\n parts.window = false;\n }\n\n if (height() > available) {\n parts.scale = Math.max(KPI_EXPORT_MIN_SCALE, Math.max(0, available) / height());\n }\n\n return parts;\n}\n\n// The heights scaled by the parts' scale: what the renderer lays the card\n// out with, its text sized by the same scale.\nexport function scaledKpiHeights(heights: KpiExportHeights, scale: number): KpiExportHeights {\n return {\n value: heights.value * scale,\n label: heights.label * scale,\n delta: heights.delta * scale,\n window: heights.window * scale,\n target: heights.target * scale,\n sparkline: heights.sparkline * scale,\n note: heights.note * scale,\n };\n}\n\n// How tall the card's drawn parts stand together, in the heights' unit.\nexport function kpiExportHeight(view: KpiCardView, parts: KpiExportParts, heights: KpiExportHeights): number {\n return heights.value\n + (view.label ? heights.label : 0)\n + (parts.delta ? heights.delta : 0)\n + (parts.window ? heights.window : 0)\n + (parts.target ? heights.target : 0)\n + (parts.sparkline ? heights.sparkline : 0)\n + parts.notes.length * heights.note;\n}\n\n// The last row of an exported list table that stops short of its result: how\n// many rows the file leaves out and where the whole set can be had. Each\n// format fetches its own number of rows (PDF_LIST_ROWS, PPTX_LIST_ROWS), and\n// both name what is left with this one sentence.\nexport function moreRowsNotice(remaining: number): string {\n return `… ${remaining} more row(s) — use the component's CSV export for the full dataset`;\n}\n\n// The pages of a collected report that have at least one tile whose query\n// failed, or whose text shows a value that came back without its number, then\n// HEADER_FOOTER_NAME when the header or footer shows one on a page that shows\n// the master — what the failure gate names to the user, and what makes \"some\n// of this file is missing\" a fact the caller can act on rather than a thing\n// they notice in the PDF afterwards.\nexport function failedPageNames(collected: CollectedReport): string[] {\n // Numbered before the filter — an unnamed page 4 that failed has to read\n // \"Page 4\", not \"Page 1\" because it happened to be the first failure.\n const names = collected.pages\n .map((page, index) => ({ page, number: index + 1 }))\n .filter(({ page }) => page.components.some(isFailed)\n || showsFailedValue(page.components.map((item) => item.component), page.failedValues))\n .map(({ page, number }) => page.page.name || `Page ${number}`);\n const master = collected.report.master;\n const showsMaster = collected.pages.some(({ page }) => !page.masterHidden);\n\n if (master && showsMaster && showsFailedValue(master.components, collected.masterFailedValues)) {\n names.push(HEADER_FOOTER_NAME);\n }\n\n return names;\n}\n\n// Whether any of the text blocks shows one of the failed value keys.\nfunction showsFailedValue(components: ReportComponent[], failed: readonly string[]): boolean {\n const shown = new Set(components\n .filter((component) => component.type === 'text')\n .flatMap((component) => valueKeys(component.config?.html)));\n\n return failed.some((key) => shown.has(key));\n}\n\n// The cover's filter lines: the export's filter lines, then the match while the report bar's filters match any. A drilled chart's line\n// is its title as the canvas header reads it (`titles`, by component id) and\n// the crumbs of the path its answer applied (the ones its title prints), not\n// the path the screen asked for: the server may have cut that path short or\n// refused it.\nexport function coverFilterLines(\n snapshot: ReportExportSnapshot,\n lines: readonly ReportExportLine[],\n pages: readonly Pick<CollectedPage, 'components'>[],\n titles: Readonly<Record<number, string>> = {},\n): string[] {\n const match = snapshot.features.includes('matchAny') ? matchLineText(snapshot.state.match, 'line') : null;\n const drilled = pages\n .flatMap((page) => page.components)\n .filter((item) => !!item.crumbs?.length)\n .map((item) => crumbedTitle(titles[item.component.id] ?? item.component.title, item.crumbs));\n\n return [\n ...lines.filter((line) => line.kind !== 'drill').map((line) => line.text),\n ...drilled,\n match,\n ]\n .filter((line): line is string => !!line);\n}\n\n// Whether a PDF or PowerPoint export lays a component out: every tile, and\n// every text block, which has nothing to fetch and rides through with no\n// data. Any other type (an inline value, or a type this viewer does not\n// know) never is: a value is read only through its layer's values job.\nexport function isExportSlot(component: ReportComponent): boolean {\n return isTile(component) || component.type === 'text';\n}\n\n// Gathers everything an export needs: every component's data across ALL pages\n// (the canvas only renders the active page, so exports can't scrape the\n// screen), and the numbers of the values their text reads, fetched fresh with\n// the viewer's current filter state.\n//\n// A failed component resolves to a null `data`, and a failed value to a key in\n// its page's failedValues, rather than failing the whole collection — but that\n// is so the caller can REPORT what failed, not so it can be ignored: see\n// failedPageNames() and the failure gate that uses it.\n@Injectable()\nexport class ReportExportCollectorService {\n\n private _reportData = inject(ReportData);\n private _filterState = inject(ReportFilterStateService);\n private _filterOptions = inject(ReportFilterOptionsService);\n\n // listRows is how many rows each list fetches: the renderer's own cap, since\n // a PDF table continues onto extra pages and a slide table cannot.\n //\n // The screen is read once, when the export starts (snapshot): every tile,\n // every values job, the filter lines and the cover read that copy, so a\n // filter changed while the tiles are fetched reaches none of them. A retry\n // collects again, and so reads the screen as it is then.\n public collect(report: Report, listRows: number): Observable<CollectedReport> {\n const jobs = this._jobs(report);\n const snapshot = this.snapshot(report);\n const formatContext = snapshot.formatContext;\n\n // Released a few at a time rather than all at once, a page's values in the\n // same queue as the tiles, so they never add to the queries already\n // running. mergeMap completes out of order, so each result carries the job\n // it came from and the rows are filed by index — the deck's page order\n // can't depend on which query happened to finish first.\n const all$ = jobs.length\n ? from(jobs.map((job, index) => ({ job, index })))\n .pipe(\n mergeMap(\n ({ job, index }) => this._runJob(report, job, listRows, snapshot)\n .pipe(map((result) => ({ result, index }))),\n EXPORT_CONCURRENCY,\n ),\n toArray(),\n )\n : of([] as { result: CollectResult; index: number }[]);\n\n // The lines and the filter tokens ride alongside the component data\n // rather than being built at the end, because naming a select filter's\n // values is itself a request.\n return forkJoin({ collected: all$, wording: this.exportWording(report, snapshot) })\n .pipe(\n map(({ collected, wording }) => {\n const file = this._file(report, collected, formatContext);\n\n return {\n report,\n ...file,\n filterSummary: coverFilterLines(snapshot, wording.lines, file.pages, wording.titles),\n filterFields: wording.filterFields,\n contextLines: this._contextLines(report),\n formatContext,\n };\n }),\n );\n }\n\n // The screen as one export reads it: the state snapshot, each group's value\n // and live preset, each tile's filter entries and state (tileDataState),\n // each value's filter entries, the grain, the features served and the\n // format. A value's entries are read here too, so the\n // numbers in a file's text are filtered as its tiles are, whatever the bar\n // does while the export runs.\n public snapshot(report: Report): ReportExportSnapshot {\n const state = this._filterState.snapshot();\n const tiles = (report.pages ?? [])\n .flatMap((page) => page.components ?? [])\n .filter((component) => isTile(component));\n const values = reportComponents(report)\n .filter((component) => component.type === 'value');\n\n return {\n state,\n ...this._groupValues(report),\n filters: Object.fromEntries(tiles.map((tile) => [tile.id, this._filterState.resolveForComponent(tile)])),\n valueFilters: Object.fromEntries(values\n .map((value) => [value.id, this._filterState.resolveForComponent(value)])),\n states: Object.fromEntries(tiles.map((tile) => [tile.id, this._tileState(report, tile, state)])),\n gridExpansions: Object.fromEntries(tiles\n .map((tile) => [tile.id, this._filterState.gridExpansion(tile)] as const)\n .filter(([, expansion]) => !!expansion)),\n frequency: this._filterState.frequency(),\n features: offeredViewerFeatures(report.viewerFeatures),\n formatContext: this._filterState.formatContext(),\n };\n }\n\n // How an export words the screen, over a snapshot (`pageId` for a This\n // Page zip): its filter lines (exportLines: the cover's, and the zip's\n // filterLines), what each {{filter.<id>}} token prints, and each tile's\n // title as the canvas header reads it (the zip names its files after\n // them). A select's picks are named once for all three, as the report bar\n // names them, so no token in a file reads as loading.\n public exportWording(\n report: Report,\n snapshot: ReportExportSnapshot,\n pageId: number | null = null,\n ): Observable<ReportExportWording> {\n const names = this._pickNamer(report);\n\n return this._filterFields(report, snapshot, names)\n .pipe(\n switchMap((filterFields) => {\n const titles = this._exportTitles(report, pageId, filterFields);\n\n return exportLines({ report, snapshot, pageId, names, titles })\n .pipe(map((lines) => ({ lines, filterFields, titles })));\n }),\n );\n }\n\n // The title of each tile, by component id, as the canvas header reads it:\n // its tokens filled with its page's fields and the filters the page reads\n // (layerFilterFields). The whole report's or one page's (pageId). An\n // untitled tile is left out: the server names its file by its type.\n private _exportTitles(\n report: Report,\n pageId: number | null,\n fields: Record<number, TextFilterField>,\n ): Record<number, string> {\n return Object.fromEntries((report.pages ?? [])\n .map((page, index) => ({ page, index }))\n .filter(({ page }) => !pageId || page.id === pageId)\n .flatMap(({ page, index }) => {\n const tokens: TextTokenContext = {\n pageNumber: index + 1,\n pageName: page.name || `Page ${index + 1}`,\n reportName: report.name,\n filters: layerFilterFields(fields, report.filterGroups ?? [], page.id),\n };\n\n return (page.components ?? [])\n .filter((component) => isTile(component) && !!component.title)\n .map((component): [number, string] => [component.id, fillTitleTokens(component.title, tokens)]);\n }));\n }\n\n // Every request the export makes, in page order: each page's tiles, then the\n // values its text shows; the header and footer's values last, when some page\n // shows the master. Text blocks have nothing to fetch of their own — they\n // ride through with no data, and their tokens are filled from their layer's\n // values. A value is read only through its layer's request, never as a tile\n // (isExportSlot). The header/footer blocks (report.master) are read by the\n // renderers straight off the report.\n private _jobs(report: Report): CollectJob[] {\n const jobs: CollectJob[] = [];\n\n report.pages.forEach((page, pageIndex) => {\n page.components\n .filter(isExportSlot)\n .forEach((component) => jobs.push({ kind: 'component', pageIndex, component }));\n jobs.push(...this._valuesJobs(page, pageIndex));\n });\n\n if (report.master && report.pages.some((page) => !page.masterHidden)) {\n jobs.push(...this._valuesJobs(report.master, null));\n }\n\n return jobs;\n }\n\n // A layer's one values job, or none when its text shows no value.\n private _valuesJobs(layer: ReportPage | ReportMaster, pageIndex: number | null): CollectJob[] {\n const texts = layer.components.filter((component) => component.type === 'text');\n const values = layer.values ?? [];\n const shown = shownValues(values, texts);\n\n return shown.length\n ? [{ kind: 'values', pageIndex, pageId: layer.id, values, components: shown }]\n : [];\n }\n\n // One queued job, its result tagged with the page it is filed under.\n private _runJob(\n report: Report,\n job: CollectJob,\n listRows: number,\n snapshot: ReportExportSnapshot,\n ): Observable<CollectResult> {\n if (job.kind === 'component') {\n return this._componentData(report, job.component, listRows, snapshot)\n .pipe(map((item): CollectResult => ({ kind: 'component', pageIndex: job.pageIndex, item })));\n }\n\n return this._pageValues(report, job.pageId, job.values, job.components, snapshot)\n .pipe(map((collected): CollectResult => ({ kind: 'values', pageIndex: job.pageIndex, collected })));\n }\n\n private _componentData(\n report: Report,\n component: ReportComponent,\n listRows: number,\n snapshot: ReportExportSnapshot,\n ): Observable<CollectedComponent> {\n if (component.type === 'text') {\n return of({ component, data: null, hiddenColumns: [] });\n }\n\n const filters = snapshot.filters[component.id] ?? [];\n\n if (component.type === 'grid') {\n return this._gridTable(report, component, filters, snapshot.states[component.id] ?? {}, listRows, snapshot);\n }\n\n // The tile's own state, the one its screen and its CSV carry\n // (tileDataState): a tile that follows the group-by re-buckets at the\n // viewer's grain, a time-series chart keeps its drill path, a list reads\n // in the screen's order and holds the screen's rows. A list adds its\n // export paging.\n const tileState = snapshot.states[component.id] ?? {};\n const state: ComponentDataState = component.type === 'list'\n ? { ...tileState, page: 1, pageSize: listRows }\n : { ...tileState };\n // The table leaves out the columns the viewer hid. The rows are fetched\n // whole, as the screen fetches them (the server reads hiddenColumns for a\n // CSV only), and the renderers drop the cells.\n const hiddenColumns = [...(state.hiddenColumns ?? [])];\n\n // handlers: false keeps the app's global error dialog out of this. A failed\n // tile is reported once, by the failure gate, naming the pages it cost —\n // never as ten stacked modals carrying the database's own wording.\n return this._reportData.componentData(report.id, component.id, filters, state, true, { handlers: false })\n .pipe(\n map((data: ComponentData) => this._collected(component, data, state.search, hiddenColumns, snapshot)),\n catchError(() => of({ component, data: null, hiddenColumns })),\n );\n }\n\n // A tile's state as an export reads it: tileDataState, and for a table the\n // layout the viewer put it in, absent while it shows its stored one.\n private _tileState(report: Report, tile: ReportComponent, state: ReportStateSnapshot): ComponentDataState {\n const layout = tile.type === 'grid' ? this._filterState.gridSessionLayout(tile) : null;\n\n return { ...tileDataState(report, tile, state), ...(layout ? { layout } : {}) };\n }\n\n // A table tile as the screen draws it, read apart from the screen through\n // an export source (readGridTable()): in the viewer's layout with the\n // groups they left open, at most `rows` lines and GRID_EXPORT_COLUMNS\n // pivot columns, each value written by the screen's formatter once the\n // read's report line is in. That line stands in as its data, so the title,\n // the subtitle and the notes read it as a list's. A failed read is a\n // failed tile.\n private _gridTable(\n report: Report,\n component: ReportComponent,\n filters: ResolvedFilterValue[],\n state: ComponentDataState,\n rows: number,\n snapshot: ReportExportSnapshot,\n ): Observable<CollectedComponent> {\n const locale = snapshot.formatContext.locale;\n const source = new ReportGridSource(this._reportData, report.id, component.id, { isExport: true, locale: () => locale });\n const screen = () => reportGridFormatter({\n format: snapshot.formatContext,\n timezone: this._filterState.timezone(),\n report: source.report(),\n });\n const formatter: GridFormatter = {\n format: (value, field, placement) => screen().format(value, field, placement),\n toNumber: (text, field, placement) => screen().toNumber(text, field, placement),\n };\n const layout = state.layout ?? authoredGridLayout(component);\n const params = {\n filters,\n ...(state.matchAnyGroupIds?.length ? { matchAnyGroupIds: state.matchAnyGroupIds } : {}),\n ...(state.frequency ? { frequency: state.frequency } : {}),\n };\n\n return readGridTable(source, layout, params, snapshot.gridExpansions?.[component.id], { rows, columns: GRID_EXPORT_COLUMNS }, formatter)\n .pipe(\n map((table): CollectedComponent => ({\n component,\n data: { ...(source.report() ?? {}), columns: [], rows: [] } as ComponentData,\n hiddenColumns: [],\n table,\n tableNotes: gridExportNotes(table, layout, locale),\n ...((layout.filters ?? []).length ? { filtered: true } : {}),\n })),\n catchError(() => of({ component, data: null, hiddenColumns: [] })),\n );\n }\n\n // One tile's answer as the renderers take it. A search the server could\n // not apply (searchNote: the list has no text column) narrowed nothing, so\n // the item does not carry it. A drilled chart carries the breadcrumb of the\n // path its answer applied, which is what its numbers were read at.\n private _collected(\n component: ReportComponent,\n data: ComponentData,\n search: string | undefined,\n hiddenColumns: string[],\n snapshot: ReportExportSnapshot,\n ): CollectedComponent {\n const path = data?.drill?.path ?? [];\n\n return {\n component,\n data,\n ...(search && !data?.searchNote ? { search } : {}),\n hiddenColumns,\n ...(path.length ? { crumbs: drillCrumbLabels(path, snapshot.formatContext) } : {}),\n };\n }\n\n // Each group's value as the bar holds it now, with the relative range a\n // date value still is. The picks are copied, so the snapshot keeps them\n // whatever the bar does next.\n private _groupValues(report: Report): Pick<ReportExportSnapshot, 'values' | 'presets'> {\n const values: Record<number, FilterGroupValue> = {};\n const presets: Record<number, ReportRelativeRange> = {};\n\n (report.filterGroups ?? []).forEach((group) => {\n const value = this._filterState.value(group.id);\n const preset = this._filterState.livePreset(group.id);\n\n if (value) {\n values[group.id] = {\n ...value,\n ...(value.values ? { values: [...value.values] } : {}),\n ...(value.excludeValues ? { excludeValues: [...value.excludeValues] } : {}),\n };\n }\n if (preset) {\n presets[group.id] = preset;\n }\n });\n\n return { values, presets };\n }\n\n // One layer's values, read in one request, as its text's tokens print them.\n // The request carries the filter values of every value on the layer, as the\n // canvas's does, read from the export's snapshot like every tile's, and\n // while the groups match 'any' the groups that combine\n // (valuesMatchAnyGroupIds): the server decides which values it reads (the\n // shown ones and the operands of the formulas among them) and applies to\n // each only the entries naming its own filters. handlers: false keeps the\n // error dialog out of it, as for a tile. A failed request reads as no rows,\n // so every value the text shows failed and the failure gate names its page;\n // one value's own error fails only that value, and a failed operand fails\n // the formula that reads it.\n private _pageValues(\n report: Report,\n pageId: number,\n values: ReportComponent[],\n shown: ReportComponent[],\n snapshot: ReportExportSnapshot,\n ): Observable<CollectedValues> {\n const formatContext = snapshot.formatContext;\n const filters = values.flatMap((component) => snapshot.valueFilters[component.id] ?? []);\n const matchAnyGroupIds = valuesMatchAnyGroupIds(report, pageId, snapshot.state);\n\n return this._reportData.pageValues(report.id, pageId, filters, true, { handlers: false }, matchAnyGroupIds)\n .pipe(\n map((rows) => new Map((rows ?? []).map((row) => [row.id, row]))),\n catchError(() => of(new Map<number, ReportPageValue>())),\n map((rows) => ({\n values: textValues(values, { rows }, formatContext),\n failedValues: failedValueKeys(shown, rows),\n })),\n );\n }\n\n // The results filed by page in job order. A layer with no values job (its\n // text shows no value) has no numbers to wait for: its values read as the\n // em dash, and none of them failed.\n private _file(\n report: Report,\n results: { result: CollectResult; index: number }[],\n formatContext: ReportFormatContext,\n ): Pick<CollectedReport, 'pages' | 'masterValues' | 'masterFailedValues'> {\n const unread = (values: ReportComponent[] | undefined): CollectedValues => ({\n values: textValues(values ?? [], { rows: new Map() }, formatContext),\n failedValues: [],\n });\n const pages: CollectedPage[] = report.pages.map((page) => ({ page, components: [], ...unread(page.values) }));\n let master = unread(report.master?.values);\n\n [...results]\n .sort((a, b) => a.index - b.index)\n .forEach(({ result }) => {\n if (result.kind === 'component') {\n pages[result.pageIndex].components.push(result.item);\n } else if (result.pageIndex === null) {\n master = result.collected;\n } else {\n Object.assign(pages[result.pageIndex], result.collected);\n }\n });\n\n return { pages, masterValues: master.values, masterFailedValues: master.failedValues };\n }\n\n // The zone the server resolved, as its IANA id, and the currency it says\n // the report's money is in (a label: nothing is converted). Only the\n // server's values are printed: the browser's zone (resolveReportTimezone's\n // fallback for an older server) is not what the numbers were measured in,\n // and an older server names no currency at all.\n private _contextLines(report: Report): string[] {\n return [\n ...(report.effectiveTimezone ? [`Timezone: ${report.effectiveTimezone}`] : []),\n ...(report.effectiveCurrency ? [`Currency: ${report.effectiveCurrency}`] : []),\n ];\n }\n\n // Every filter group of the report as its {{filter.<id>}} token prints it\n // in the file, at the snapshot's values and in its format, as the canvas\n // words it. A select's picks are named first, so no token in the file\n // reads as loading. Each page and the header and footer read their own\n // groups of these (layerFilterFields).\n private _filterFields(\n report: Report,\n snapshot: ReportExportSnapshot,\n names: ReportExportLinesInput['names'],\n ): Observable<Record<number, TextFilterField>> {\n const groups = report.filterGroups ?? [];\n const picked = groups\n .map((group) => ({ group, values: valuePicks(snapshot.values[group.id]) }))\n .filter(({ group, values }) => group.type === 'select' && values.length);\n const names$ = picked.length\n ? forkJoin(picked.map(({ group, values }) => names(group, values)))\n : of([] as string[][]);\n\n return names$.pipe(\n map((named) => {\n const byGroup = new Map(picked.map(({ group }, index) => [group.id, named[index]]));\n\n return textFilterFields(\n groups,\n (groupId) => snapshot.values[groupId],\n snapshot.formatContext.locale,\n (group) => byGroup.get(group.id),\n );\n }),\n );\n }\n\n // Names a select group's picks (kept or left out) for one export, their\n // stored ids resolved to the same names the on-screen chips show — a cover\n // reading \"Organization: 8774, 8777\" tells the reader nothing about what\n // the report covers. Each group's full list is read once for the export,\n // whatever names its picks: its filter line, its token, a title.\n //\n // Uses the report bar's own names and resolver so the two can't drift: a\n // name the bar's lists taught (ReportFilterOptionsService.label) comes first,\n // so a pick a cut or narrowed list leaves out reads as its chip does, and\n // the full list names the rest. A value whose entity was deleted keeps\n // showing its raw id rather than dropping off the cover and silently\n // understating the filter. A failed option fetch degrades the whole line to\n // ids for the same reason: an export must never fail on a cosmetic lookup.\n private _pickNamer(report: Report): ReportExportLinesInput['names'] {\n const options = groupOptionsReader(this._reportData);\n\n return (group, values) => resolveOptionValues(\n options(group, report.id),\n values,\n (value) => this._filterOptions.label(group.id, value),\n )\n .pipe(\n map((resolved) => resolved.map((item) => item.name)),\n catchError(() => of(values.map((item) => String(item)))),\n );\n }\n}\n","import { ComponentData, ReportComponent, ReportFormatContext } from '../interfaces/report.interface';\nimport { buildChartOption } from '../option-builder';\n\n\n// Renders a chart to a PNG data URL WITHOUT it being on screen — the PDF\n// export needs every page's charts, but the canvas only renders the active\n// page. ECharts happily initializes against a detached element when given\n// explicit pixel dimensions; animations are disabled so getDataURL is\n// complete synchronously after setOption. Its numbers and periods are written\n// in the report's format context, as on screen.\nexport async function renderChartImage(\n component: ReportComponent,\n data: ComponentData,\n width: number,\n height: number,\n context: ReportFormatContext,\n pixelRatio = 3,\n): Promise<string> {\n // The same tree-shaken echarts build + 'report' theme the live canvas uses.\n const echarts = (await import('../theme/echarts')).default;\n\n const host = document.createElement('div');\n host.style.width = `${width}px`;\n host.style.height = `${height}px`;\n\n const chart = echarts.init(host, 'report', {\n renderer: 'canvas',\n width,\n height,\n });\n\n try {\n chart.setOption({\n ...buildChartOption(component, data, context),\n animation: false,\n });\n\n return chart.getDataURL({\n type: 'png',\n pixelRatio,\n backgroundColor: '#ffffff',\n });\n } finally {\n chart.dispose();\n }\n}\n","import {\n ApplicationRef, ComponentRef, EnvironmentInjector, Injectable, Injector, afterNextRender, createComponent, inject,\n} from '@angular/core';\n\nimport { ComponentTextComponent } from '../components/component-text/component-text.component';\nimport { PX_PER_INCH } from '../components/report-canvas/report-canvas.component';\nimport { ReportComponent } from '../interfaces/report.interface';\nimport { componentPaddingCss } from '../layout';\nimport { TextTokenContext, fillTextTokens, parseTable, splitAtTables } from '../text';\n\n\n// Where a stretch of a block's words sits: the top of its first line and the\n// bottom of its last.\nexport interface TextSegmentLayout {\n top: number;\n bottom: number;\n}\n\n// Where a table sits in its block, and how tall its rows and how wide its\n// columns are.\nexport interface TextTableLayout {\n top: number;\n left: number;\n width: number;\n height: number;\n // A row's height, in the order textBlocks lists the rows: the head first and\n // the foot last.\n rowHeights: number[];\n // A grid column's width (tableGrid), left to right. Together they are the\n // table's width.\n columnWidths: number[];\n}\n\n// A text block as the canvas lays it out. Everything is in inches, measured\n// from the top left of the block's content box (inside its padding).\nexport interface TextBlockLayout {\n contentWidth: number;\n contentHeight: number;\n // How far down the block's words and tables reach.\n usedHeight: number;\n // They reach past the bottom of the box, where the canvas cuts them off.\n overflow: boolean;\n // One per text part of textBlocks, in order: null for a part that draws\n // nothing.\n segments: (TextSegmentLayout | null)[];\n // One per table part of textBlocks, in order.\n tables: TextTableLayout[];\n}\n\n// How far past the bottom of its box a block may reach and still fit: two\n// pixels, so the rounding of the last line's edge never counts as overflow.\n// The deck keeps a table's row on the same terms.\nexport const OVERFLOW_SLACK = 2 / PX_PER_INCH;\n\n// Where the canvas puts each part of a text block, for the exports. A\n// browser wraps the words and sizes a table's columns by its own layout, which\n// neither jsPDF nor PowerPoint reproduces. So the block is rendered offscreen\n// with the canvas's own component, at the canvas's 96px per inch and unscaled,\n// and the exports place what they draw where it sat: a table at its top, in\n// its column widths and row heights, and the words between tables at theirs.\n// It also tells whether the block runs past the bottom of its box.\n//\n// Provided beside the export services, so the block renders under the same\n// injector the canvas's blocks do.\n@Injectable()\nexport class ReportTextLayoutService {\n\n private readonly _appRef = inject(ApplicationRef);\n private readonly _environmentInjector = inject(EnvironmentInjector);\n private readonly _injector = inject(Injector);\n private readonly _layouts = new Map<string, Promise<TextBlockLayout>>();\n\n // A block is measured once per size, padding and filled html: an export that\n // draws it twice, or a second export with the same numbers, reads the same\n // layout, which nothing changes.\n public async measure(component: ReportComponent, tokens: TextTokenContext): Promise<TextBlockLayout> {\n const html = component.config?.html ?? '';\n const key = [\n component.id,\n component.w,\n component.h,\n JSON.stringify(component.config?.padding ?? null),\n fillTextTokens(html, tokens),\n ].join('|');\n\n let layout = this._layouts.get(key);\n if (!layout) {\n layout = this._render(component, html, tokens);\n this._layouts.set(key, layout);\n // A measure that failed is tried again next time.\n layout.catch(() => this._layouts.delete(key));\n }\n\n return layout;\n }\n\n private async _render(component: ReportComponent, html: string, tokens: TextTokenContext): Promise<TextBlockLayout> {\n const text = createComponent(ComponentTextComponent, {\n environmentInjector: this._environmentInjector,\n elementInjector: this._injector,\n });\n const box = blockBox(component, text.location.nativeElement);\n\n try {\n text.setInput('html', html);\n text.setInput('tokens', tokens);\n text.setInput('editing', false);\n document.body.append(box);\n await this._rendered(text);\n // Laid out first, so a font the words ask for is loading by the time\n // fonts.ready is read.\n box.getBoundingClientRect();\n await document.fonts.ready;\n\n return measureBlock(text.location.nativeElement.querySelector('.text-content'));\n } finally {\n // Destroying the block also takes it off the application.\n text.destroy();\n box.remove();\n }\n }\n\n // The block is rendered by the application's own change detection, as any\n // view attached to it: its inputs mark it for the next render, which draws\n // it before the callback runs. Not whenStable(): that also waits out\n // whatever else the host app has under way (its requests and, under\n // zone.js, its timers), and never resolves while a timer repeats.\n private _rendered(text: ComponentRef<ComponentTextComponent>): Promise<void> {\n return new Promise((resolve) => {\n afterNextRender(() => resolve(), { injector: this._environmentInjector });\n this._appRef.attachView(text.hostView);\n });\n }\n}\n\n// The block's box as the canvas draws it (the component box): its size, a\n// 1px border and the block's padding (componentPaddingCss) around a body the\n// text fills. Fixed far off to the left, and hidden, so it is never seen.\nfunction blockBox(component: ReportComponent, text: HTMLElement): HTMLElement {\n const box = document.createElement('div');\n const body = document.createElement('div');\n\n Object.assign(box.style, {\n position: 'fixed',\n left: '-10000px',\n top: '0',\n visibility: 'hidden',\n width: `${component.w * PX_PER_INCH}px`,\n height: `${component.h * PX_PER_INCH}px`,\n boxSizing: 'border-box',\n border: '1px solid transparent',\n padding: componentPaddingCss(component),\n });\n body.style.height = '100%';\n body.append(text);\n box.append(body);\n\n return box;\n}\n\n// Split the rendered block at its tables, as textBlocks splits the same html,\n// so the nth segment is the nth text part and the nth table the nth table\n// part. How far the block reaches is the bottom of its last part that draws\n// anything.\nfunction measureBlock(content: HTMLElement): TextBlockLayout {\n const box = content.getBoundingClientRect();\n const parts = splitAtTables(content);\n const segments: (TextSegmentLayout | null)[] = [];\n const tables: TextTableLayout[] = [];\n let usedHeight = 0;\n\n parts.forEach((part, index) => {\n if (Array.isArray(part)) {\n const segment = measureSegment(drawnNodes(part, index === parts.length - 1), box);\n segments.push(segment);\n usedHeight = segment?.bottom ?? usedHeight;\n } else {\n const table = measureTable(part, box);\n tables.push(table);\n usedHeight = table.top + table.height;\n }\n });\n\n const contentHeight = inches(box.height);\n\n return {\n contentWidth: inches(box.width),\n contentHeight,\n usedHeight,\n overflow: usedHeight > contentHeight + OVERFLOW_SLACK,\n segments,\n tables,\n };\n}\n\n// The nodes of a run between tables that the exports draw. Whitespace between\n// blocks draws nothing anywhere. A blank line at the start of a block is\n// drawn, on the canvas and by textBlocks alike, but textBlocks drops the blank\n// lines at the very end of a block, so they are not measured either: a\n// trailing empty paragraph never makes a block overflow.\nfunction drawnNodes(nodes: Node[], blockEnd: boolean): Node[] {\n const skipsLast = blockEnd ? isBlank : isVoid;\n let start = 0;\n let end = nodes.length;\n\n while (start < end && isVoid(nodes[start])) {\n start++;\n }\n while (end > start && skipsLast(nodes[end - 1])) {\n end--;\n }\n\n const drawn = nodes.slice(start, end);\n if (blockEnd && drawn.length) {\n trimBlankLines(drawn[drawn.length - 1]);\n }\n\n return drawn;\n}\n\n// Take the blank lines off the end of the block's last node, as textBlocks\n// drops them: the elements that hold no text after its last words, down its\n// last children — the <br>s of <p>b<br><br></p>, a list's empty last item.\n// Whitespace is passed over and left, so a paragraph never turns into an\n// empty one, which the canvas draws as a line. The block is the measure's own\n// copy, thrown away once measured, and nothing above what is taken off moves.\nfunction trimBlankLines(node: Node): void {\n let child = node.lastChild;\n while (child && isBlank(child)) {\n const previous = child.previousSibling;\n if (!isVoid(child)) {\n child.remove();\n }\n child = previous;\n }\n\n if (child) {\n trimBlankLines(child);\n }\n}\n\n// Whitespace between blocks, or a comment.\nfunction isVoid(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE\n ? !/[^ \\t\\n\\r\\f]/.test(node.textContent ?? '')\n : node.nodeType !== Node.ELEMENT_NODE;\n}\n\n// A node that draws no words: whitespace, or an element with no text in it,\n// such as the empty line <p><br></p>.\nfunction isBlank(node: Node): boolean {\n return isVoid(node) || !node.textContent;\n}\n\n// From before its first node to after its last. null for a run that draws\n// nothing.\nfunction measureSegment(nodes: Node[], box: DOMRect): TextSegmentLayout | null {\n if (!nodes.length) {\n return null;\n }\n\n const range = document.createRange();\n range.setStartBefore(nodes[0]);\n range.setEndAfter(nodes[nodes.length - 1]);\n const rect = range.getBoundingClientRect();\n\n return { top: inches(rect.top - box.top), bottom: inches(rect.bottom - box.top) };\n}\n\nfunction measureTable(table: HTMLTableElement, box: DOMRect): TextTableLayout {\n const rect = table.getBoundingClientRect();\n\n return {\n top: inches(rect.top - box.top),\n left: inches(rect.left - box.left),\n width: inches(rect.width),\n height: inches(rect.height),\n rowHeights: Array.from(table.rows, (row) => inches(row.getBoundingClientRect().height)),\n columnWidths: columnWidths(table, rect.width).map(inches),\n };\n}\n\n// A grid column is as wide as a cell that spans only it. A column that only\n// spanning cells cross shares what the others leave of the table's width, and\n// all of them are scaled to add up to it exactly. The cells come in the same\n// order as the grid's (parseTable reads the same rows), so the nth cell of a\n// row is the nth cell of that grid row.\nfunction columnWidths(table: HTMLTableElement, width: number): number[] {\n const grid = parseTable(table);\n const widths: (number | null)[] = Array.from({ length: grid.columns }, () => null);\n\n grid.rows.forEach((row, rowIndex) => row.cells.forEach((cell, cellIndex) => {\n if (cell.colSpan === 1 && widths[cell.column] === null) {\n widths[cell.column] = table.rows[rowIndex].cells[cellIndex].getBoundingClientRect().width;\n }\n }));\n\n const known = widths.filter((value): value is number => value !== null);\n const share = Math.max(0, width - sum(known)) / Math.max(1, widths.length - known.length);\n const filled = widths.map((value) => value ?? share);\n const total = sum(filled);\n\n return filled.map((value) => total ? value * width / total : width / filled.length);\n}\n\nfunction sum(values: number[]): number {\n return values.reduce((total, value) => total + value, 0);\n}\n\nfunction inches(pixels: number): number {\n return pixels / PX_PER_INCH;\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { ReportKpiTrend } from '../enums/report-kpi-trend.enum';\nimport { layerFilterFields } from '../filter-text';\nimport { resolveReportTimezone } from '../format';\nimport {\n ComponentData,\n KpiConfig,\n Report,\n ReportComponent,\n ReportFormatContext,\n ReportHeaderFooter,\n ReportPage,\n} from '../interfaces/report.interface';\nimport {\n KpiCardDelta, KpiCardTarget, KpiSparklinePoint, kpiCardView, kpiSparklineGeometry,\n} from '../kpi-card';\nimport { DEFAULT_COMPONENT_PADDING } from '../layout';\nimport {\n DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, TEXT_TABLE_BORDER_COLOR, TEXT_TABLE_BORDER_WIDTH, TEXT_TABLE_CELL_PADDING,\n TEXT_TABLE_MARGIN, TextFilterField, TextParagraph, TextRun, TextTable, TextTableCell, TextTokenContext, TextValue,\n textBlocks,\n} from '../text';\nimport {\n REPORT_KPI_CHANGE_COLORS, REPORT_KPI_SPARKLINE_COLOR, REPORT_KPI_TRACK_COLOR, REPORT_MUTED_TEXT_COLOR,\n} from '../theme/palette';\nimport { isDrawn } from '../values';\nimport { renderChartImage } from './offscreen-chart';\nimport {\n BuiltExport, CollectedComponent, CollectedPage, CollectedReport, HEADER_FOOTER_NAME, KpiExportHeights, TextOverflow,\n UndrawnComponent, coverLines, emptyLabel, exportCell, exportNoteLines, exportTitle, exportWindowsLine, isEmptyTile,\n kpiCardHasExtras, kpiExportHeight, kpiExportParts, listColumns, listHeadings, listTotalsRow, moreRowsNotice,\n scaledKpiHeights, textOverflow,\n} from './report-export-collector.service';\nimport { GridExportCell, gridExportTable } from './report-grid-export';\nimport { ReportTextLayoutService, TextTableLayout } from './report-text-layout.service';\n\n\n// Inches → points (the PDF unit).\nconst PT = 72;\n\n// Component title strip height, points.\nconst TITLE_H = 18;\n\n// The small print a component may carry, points: the days it reads under its\n// title (a subtitle line), its notes at the foot of its box (a line each), and\n// the lines of a KPI card under its value. A chart's or a list's notes give\n// way before its body would shrink under MIN_BODY_H.\nconst SMALL_SIZE = 7.5;\nconst SUBTITLE_H = 11;\nconst NOTE_LINE_H = 10;\nconst MIN_BODY_H = 40;\nconst MUTED_COLOR = `#${REPORT_MUTED_TEXT_COLOR}`;\n\n// A KPI card's parts, top to bottom, points (kpiExportParts sheds the\n// sparkline, then the target, then the notes on a short tile). The value's\n// baseline sits KPI_VALUE_BASELINE under its top.\nconst KPI_HEIGHTS: KpiExportHeights = {\n value: 30,\n label: 13,\n delta: 13,\n window: NOTE_LINE_H,\n target: NOTE_LINE_H + 6,\n sparkline: 28,\n note: NOTE_LINE_H,\n};\nconst KPI_VALUE_BASELINE = 23;\nconst KPI_DELTA_SIZE = 9;\n// The delta's triangle: its side, and the gap before the change.\nconst KPI_ARROW = 6;\nconst KPI_ARROW_GAP = 3;\n// The target's progress bar, and the track it fills.\nconst KPI_BAR_W = 120;\nconst KPI_BAR_H = 3;\nconst KPI_TRACK_COLOR = `#${REPORT_KPI_TRACK_COLOR}`;\n// The sparkline's widest box, its top and bottom inset, and its dots' radius.\nconst KPI_SPARKLINE_W = 140;\nconst KPI_SPARKLINE_INSET = 3;\nconst KPI_DOT_R = 1.5;\n\n// Rows fetched for a list's PDF table. A table that outgrows its box\n// continues onto pages of its own, so this is how far it may run: about 12-15\n// continuation pages on a letter page, and a tenth of the server's 5000-row\n// ceiling. A longer result ends in a moreRowsNotice() row.\nexport const PDF_LIST_ROWS = 500;\n\n// How far a continuation table sits inside the header and footer bands,\n// points. A page with no band (or with the master hidden) keeps\n// NO_BAND_MARGIN from that edge instead.\nconst CONTINUATION_GAP = 0.25 * PT;\nconst NO_BAND_MARGIN = 0.5 * PT;\nconst NO_BANDS: ReportHeaderFooter = { headerHeight: 0, footerHeight: 0 };\n\n// The last row of a list box whose rows carry on past it.\nconst CONTINUED_NOTICE = 'Continued on the following pages';\n\n// The last row of a list box whose rows have nowhere to go: its heading and\n// totals row, wrapped tall in narrow columns, leave a continuation page no\n// room for a row.\nconst NO_ROOM_NOTICE = 'Not enough room for this table — enlarge the tile';\n\n// A list's or a table tile's table: its font size and cell padding, points.\nconst TABLE_FONT_SIZE = 8;\nconst TABLE_CELL_PADDING = 3;\n\n// What a component's box says when it could not be drawn.\nconst UNDRAWN_NOTE = 'Could not be drawn';\n\n// Thrown from autoTable's page hook to stop an on-page table at the first page\n// it would add (_drawTable).\nconst STRAY_PAGE = new Error('The table ran past its page');\n\n// A text line's height as a multiple of its largest font size — the canvas\n// stylesheet's line-height, so a block wraps and stacks the same way.\nconst TEXT_LINE_HEIGHT = 1.25;\n\n// How far a list item's text sits from the block's edge, points; the marker\n// hangs in that space.\nconst LIST_INDENT = 16;\n\n// What the export's overflow gate says the PDF does with a text block that does\n// not fit its box.\nconst PDF_OVERFLOW_NOTE = 'The PDF cuts it off at the bottom of its box.';\n\n// What every drawing step of one export shares, built once in build().\n// Sizes are points.\ninterface PdfExportContext {\n doc: any;\n autoTable: any;\n // Lays a table out without drawing it, for measuring what fits.\n createTable: any;\n jsPDF: any;\n report: Report;\n timezone: string;\n formatContext: ReportFormatContext;\n pageW: number;\n pageH: number;\n orientation: 'landscape' | 'portrait';\n // What the header and footer's value tokens fill with, the same on every\n // page, continuation pages included (_pdfValues).\n masterValues: Record<string, TextValue>;\n // What the {{filter.<id>}} tokens fill with, every group's, the same on\n // every page; a page reads its own (layerFilterFields).\n filterFields: Record<number, TextFilterField>;\n // The ones the header and footer read: no page filter's.\n masterFilters: Record<number, TextFilterField>;\n // The text blocks cut off at the bottom of their box, by component id, so a\n // header or footer block cut on every page is listed once.\n textOverflows: Map<number, TextOverflow>;\n // The components that could not be drawn (_guarded), by component id.\n undrawn: Map<number, UndrawnComponent>;\n}\n\n// A word of a wrapped line (_wrap): its run, its text with any trailing space,\n// its font size and its width, points.\ninterface PdfWord {\n run: TextRun;\n text: string;\n size: number;\n width: number;\n}\n\n// Where a text block's words are drawn, points: the left edge and width they\n// wrap to, the top of the first line, and the bottom no line may run past. A\n// text table's cell draws its words the same way, inside its padding.\ninterface PdfTextBox {\n left: number;\n top: number;\n width: number;\n bottom: number;\n}\n\n// Where the next part of a text block starts, and whether the part just drawn\n// was cut off at the bottom of its box.\ninterface PdfTextCursor {\n cursorY: number;\n cut: boolean;\n}\n\n// A text table's cell as autoTable takes it. It prints no text of its own: the\n// cell's words (textCell) are drawn into it once its grid lines and fill are\n// (_drawTextCell).\ninterface PdfTextCellInput {\n content: string;\n colSpan: number;\n rowSpan: number;\n textCell: TextTableCell;\n styles: Record<string, unknown>;\n}\n\n// Fixed column widths, by column index, in points, and the right alignment of\n// a column of formatted numbers.\ntype PdfColumnStyles = Record<number, { cellWidth: number; halign?: 'right' }>;\n\n// What _measure reads off a list's laid-out table: how many body rows its box\n// holds, the column widths every page of it is drawn with, and how tall a\n// page's table space must be for autoTable to draw a row at all: the heading,\n// the totals row and one line of a row, points.\ninterface PdfTableMeasure {\n fit: number;\n columnStyles: PdfColumnStyles;\n minHeight: number;\n}\n\n// A table body cell: plain text, or a notice row's one cell spanning every\n// column.\ntype PdfTableCell = string | { content: string; colSpan?: number; rowSpan?: number; styles?: Record<string, unknown> };\n\n// How far a table's group label steps in per level, points.\nconst GRID_INDENT = 8;\n\n// What a list's or a table tile's table draws: its heading rows, its body\n// rows, which columns hold formatted numbers, its totals row and how many\n// rows its fetch left out.\ninterface PdfTableParts {\n head: PdfTableCell[][];\n cells: PdfTableCell[][];\n numeric: boolean[];\n foot: string[] | null;\n omitted: number;\n}\n\n// The rows of a list that did not fit its box, carried onto continuation\n// pages after its report page. x and w are the box's, in points, and the\n// column widths and alignments are the ones the on-page table was drawn with,\n// so the table reads as one across pages.\ninterface PdfTableOverflow {\n component: ReportComponent;\n // The text the list was searched by, for the continuation title.\n search?: string;\n // The crumbs of its drill path, for the continuation title.\n crumbs?: string[];\n // A table whose column filters narrowed it, for the continuation title.\n filtered?: boolean;\n // Heading rows, top first; a list has one.\n head: PdfTableCell[][];\n numeric: boolean[];\n rows: PdfTableCell[][];\n omitted: number;\n // The list's totals row, which closes the last continuation page.\n foot: string[] | null;\n x: number;\n w: number;\n columnStyles: PdfColumnStyles;\n}\n\n// Builds the PDF client-side with jspdf. The report's unit is inches and PDFs\n// are points at exactly 72/inch, so each report page becomes one PDF page of\n// the exact physical size and components land at their precise positions.\n// Charts are rendered through an offscreen ECharts instance at 3× pixel\n// ratio — pixel-identical to the screen, crisp at print size — and tables are\n// drawn with jspdf-autotable. Both libraries load lazily into their own chunks.\n//\n// A list table is fitted to its box by laying it out first, never by a\n// row-height estimate, so it cannot spill past the box. The rows that do not\n// fit continue on pages of their own after the report page, under the same\n// header/footer and with the same column widths, up to PDF_LIST_ROWS; a\n// longer result ends in a row pointing to the component's CSV export. A\n// table whose heading and totals row leave a continuation page no room for a\n// row stops at its box with a notice instead: autoTable would add pages\n// without end trying to place it.\n//\n// A component that fails to draw is marked in its box and the file goes on\n// (_guarded); build() hands back the ones that did, as it does the text it\n// cut.\n//\n// A text block's tables are drawn by autoTable too, from the line its words\n// reach, in the column widths the canvas gives them (ReportTextLayoutService).\n// A text block is cut at the bottom of its box, as the canvas clips it, and\n// build() hands the file back unsaved with the blocks it cut, so the export\n// can ask about them before it saves.\n@Injectable()\nexport class ReportPdfService {\n\n private readonly _textLayout = inject(ReportTextLayoutService);\n\n public async build(collected: CollectedReport): Promise<BuiltExport> {\n const context = await this._context(collected);\n\n this._titlePage(context.doc, collected, context.pageW, context.pageH);\n\n // The physical page number {{page.number}} prints: report pages and\n // their continuation pages alike, the title page not counted.\n let pageNumber = 0;\n\n for (const [index, collectedPage] of collected.pages.entries()) {\n const overflows: PdfTableOverflow[] = [];\n pageNumber += 1;\n\n await this._renderPage(context, collectedPage, index, pageNumber, overflows);\n\n // Each continuation appends its pages at the end of the document, so\n // two lists that overflowed on one page follow it back to back.\n for (const overflow of overflows) {\n const tokens = this._tokens(context, collectedPage.page, index, pageNumber + 1);\n\n await this._guarded(context, overflow.component, tokens.pageName, tokens, false, async () => {\n pageNumber = await this._renderContinuation(context, collectedPage.page, index, pageNumber, overflow);\n });\n }\n }\n\n return {\n overflows: [...context.textOverflows.values()],\n overflowNote: PDF_OVERFLOW_NOTE,\n undrawn: [...context.undrawn.values()],\n save: () => {\n context.doc.save(`${this._slug(collected.report.name)}.pdf`);\n },\n };\n }\n\n private async _context(collected: CollectedReport): Promise<PdfExportContext> {\n const report = collected.report;\n const { jsPDF } = await import('jspdf');\n const { default: autoTable, __createTable: createTable } = await import('jspdf-autotable');\n\n const pageW = report.pageWidth * PT;\n const pageH = report.pageHeight * PT;\n const orientation = pageW >= pageH ? 'landscape' : 'portrait';\n\n return {\n doc: new jsPDF({ orientation, unit: 'pt', format: [pageW, pageH] }),\n autoTable,\n createTable,\n jsPDF,\n report,\n timezone: resolveReportTimezone(report),\n formatContext: collected.formatContext,\n pageW,\n pageH,\n orientation,\n masterValues: this._pdfValues(collected.masterValues),\n filterFields: collected.filterFields,\n masterFilters: layerFilterFields(collected.filterFields, report.filterGroups ?? [], null),\n textOverflows: new Map(),\n undrawn: new Map(),\n };\n }\n\n // One report page: the header and footer first, under the page's own\n // components. A list that outgrows its box leaves its remaining rows in\n // overflows. The page's text fills its value tokens with the page's values.\n private async _renderPage(\n context: PdfExportContext,\n collectedPage: CollectedPage,\n index: number,\n pageNumber: number,\n overflows: PdfTableOverflow[],\n ): Promise<void> {\n const { doc } = context;\n const tokens = this._tokens(context, collectedPage.page, index, pageNumber);\n const pageTokens = { ...tokens, values: this._pdfValues(collectedPage.values) };\n\n doc.addPage([context.pageW, context.pageH], context.orientation);\n await this._renderMaster(context, collectedPage.page, tokens);\n\n for (const item of collectedPage.components) {\n await this._guarded(context, item.component, tokens.pageName, pageTokens, true, async () => {\n if (item.component.type !== 'text') {\n await this._renderComponent(context, collectedPage.page, item, tokens, overflows);\n } else if (await this._renderText(context, item.component, pageTokens)) {\n this._recordOverflow(context, item.component, tokens.pageName, pageTokens);\n }\n });\n }\n }\n\n // Draws one component, or one list's continuation pages, so that whatever\n // goes wrong stays with it: a draw that throws loses the pages it added, its\n // box on the page (boxed) is blanked under UNDRAWN_NOTE, and the export's\n // gate names it under page. One component can then never stop the file.\n private async _guarded(\n context: PdfExportContext,\n component: ReportComponent,\n page: string,\n tokens: TextTokenContext,\n boxed: boolean,\n draw: () => Promise<void>,\n ): Promise<void> {\n const { doc } = context;\n const current = doc.getCurrentPageInfo().pageNumber;\n const pages = doc.getNumberOfPages();\n\n try {\n await draw();\n } catch (error) {\n // The file only says the box could not be drawn; the console keeps why.\n console.error(error);\n\n while (doc.getNumberOfPages() > pages) {\n doc.deletePage(doc.getNumberOfPages());\n }\n\n doc.setPage(current);\n\n if (boxed) {\n this._undrawnBox(doc, component);\n }\n\n if (!context.undrawn.has(component.id)) {\n context.undrawn.set(component.id, {\n componentId: component.id,\n page,\n name: component.type === 'text'\n ? textOverflow(component, page, tokens).snippet\n : exportTitle(component, tokens),\n });\n }\n }\n }\n\n // A component's box blanked under UNDRAWN_NOTE, over whatever of it was\n // drawn before it failed.\n private _undrawnBox(doc: any, component: ReportComponent): void {\n const x = component.x * PT;\n const y = component.y * PT;\n const w = component.w * PT;\n const h = component.h * PT;\n\n doc.setFillColor('#ffffff');\n doc.rect(x, y, w, h, 'F');\n this._boxNote(doc, UNDRAWN_NOTE, x, y, w, h);\n }\n\n // The header and footer, their value tokens filled with the master's values\n // whichever page they sit on: a report page or a continuation page. They\n // read no page filter: its token prints the em dash there.\n private async _renderMaster(context: PdfExportContext, page: ReportPage, tokens: TextTokenContext): Promise<void> {\n if (page.masterHidden) {\n return;\n }\n\n const masterTokens = { ...tokens, values: context.masterValues, filters: context.masterFilters };\n\n for (const component of (context.report.master?.components ?? []).filter(isDrawn)) {\n await this._guarded(context, component, HEADER_FOOTER_NAME, masterTokens, true, async () => {\n if (await this._renderText(context, component, masterTokens)) {\n this._recordOverflow(context, component, HEADER_FOOTER_NAME, masterTokens);\n }\n });\n }\n }\n\n // Lists a text block that was cut, under the page the export's overflow gate\n // names it by. A block cut again on a later page (a header or footer) keeps\n // the first entry.\n private _recordOverflow(\n context: PdfExportContext,\n component: ReportComponent,\n page: string,\n tokens: TextTokenContext,\n ): void {\n if (!context.textOverflows.has(component.id)) {\n context.textOverflows.set(component.id, textOverflow(component, page, tokens));\n }\n }\n\n private _titlePage(doc: any, collected: CollectedReport, pageW: number, pageH: number): void {\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(28);\n doc.setTextColor('#1f2933');\n doc.text(collected.report.name, 40, pageH * 0.35);\n\n doc.setFont('helvetica', 'normal');\n doc.setFontSize(11);\n doc.setTextColor('#52606d');\n\n doc.text(coverLines(collected).map((line) => this._pdfText(line)), 40, pageH * 0.35 + 26);\n }\n\n // A text block, laid out by hand: jsPDF draws strings, not rich text, so the\n // words between its tables are drawn line by line (_drawParagraphs) and each\n // table by autoTable from the line the words above it reach\n // (_drawTextTable). Only a block with a table is measured, for the edges\n // and column widths the canvas gives its tables. Whatever runs past\n // the block's height is left off — the canvas clips the block there too.\n // Returns whether anything was.\n private async _renderText(\n context: PdfExportContext,\n component: ReportComponent,\n tokens: TextTokenContext,\n ): Promise<boolean> {\n const box = this._textBox(component);\n const blocks = textBlocks(component.config?.html ?? '', tokens);\n const layout = blocks.some((block) => block.kind === 'table')\n ? await this._textLayout.measure(component, tokens)\n : null;\n let cursorY = box.top;\n let tableIndex = 0;\n // The cursor sits on a table's bottom margin, nothing drawn since: the\n // next table's top margin is the same space, as two block margins that\n // meet collapse into one on the canvas.\n let onMargin = false;\n\n for (const block of blocks) {\n const drawn = block.kind === 'text'\n ? this._drawParagraphs(context.doc, block.paragraphs, box, cursorY)\n : this._drawTextTable(\n context, block.table, layout?.tables[tableIndex++] ?? null, box,\n onMargin ? cursorY : cursorY + TEXT_TABLE_MARGIN,\n );\n\n if (drawn.cut) {\n return true;\n }\n\n cursorY = drawn.cursorY;\n onMargin = block.kind === 'table' || (onMargin && !block.paragraphs.length);\n }\n\n return false;\n }\n\n // Where a text block's words go: inside its padding, each edge 1/8\" unless\n // set.\n private _textBox(component: ReportComponent): PdfTextBox {\n const padding = component.config?.padding;\n const inset = (value: number | undefined) => (value ?? DEFAULT_COMPONENT_PADDING) * PT;\n\n return {\n left: component.x * PT + inset(padding?.left),\n top: component.y * PT + inset(padding?.top),\n width: component.w * PT - inset(padding?.left) - inset(padding?.right),\n bottom: (component.y + component.h) * PT - inset(padding?.bottom),\n };\n }\n\n // Paragraphs drawn line by line from cursorY down: each one's runs are broken\n // into words, wrapped to the box's width and drawn word by word in their own\n // font, size and color, a list item's marker hung in its indent. The first\n // line that would run past the box's bottom ends the drawing, cut.\n private _drawParagraphs(doc: any, paragraphs: TextParagraph[], box: PdfTextBox, cursorY: number): PdfTextCursor {\n let y = cursorY;\n let listNumber = 0;\n\n for (const paragraph of paragraphs) {\n listNumber = paragraph.bullet === 'number' ? listNumber + 1 : 0;\n const indent = paragraph.bullet ? LIST_INDENT : 0;\n const lines = this._wrap(doc, paragraph, box.width - indent);\n\n for (const [lineIndex, line] of lines.entries()) {\n const size = this._lineSize(paragraph, line);\n if (y + size * TEXT_LINE_HEIGHT > box.bottom + 0.5) {\n return { cursorY: y, cut: true };\n }\n\n if (lineIndex === 0 && paragraph.bullet) {\n this._font(doc, line[0]?.run ?? { text: '' }, size);\n doc.text(paragraph.bullet === 'number' ? `${listNumber}.` : '•', box.left, y + size);\n }\n\n this._drawLine(doc, line, paragraph.align, box.left + indent, box.width - indent, y + size);\n y += size * TEXT_LINE_HEIGHT;\n }\n\n // An empty paragraph is still a line.\n if (!lines.length) {\n y += DEFAULT_TEXT_SIZE * TEXT_LINE_HEIGHT;\n }\n }\n\n return { cursorY: y, cut: false };\n }\n\n // How far _drawParagraphs takes its cursor down drawing the paragraphs whole\n // at a width.\n private _paragraphsHeight(doc: any, paragraphs: TextParagraph[], width: number): number {\n return paragraphs.reduce((height, paragraph) => {\n const lines = this._wrap(doc, paragraph, width - (paragraph.bullet ? LIST_INDENT : 0));\n\n return height + (lines.length\n ? lines.reduce((sum, line) => sum + this._lineSize(paragraph, line) * TEXT_LINE_HEIGHT, 0)\n : DEFAULT_TEXT_SIZE * TEXT_LINE_HEIGHT);\n }, 0);\n }\n\n // A line's font size: its largest word's, and never under its paragraph's\n // first run's.\n private _lineSize(paragraph: TextParagraph, line: PdfWord[]): number {\n return Math.max(...line.map((word) => word.size), paragraph.runs[0]?.fontSize ?? DEFAULT_TEXT_SIZE);\n }\n\n // One wrapped line on its baseline, aligned within the width from left.\n private _drawLine(\n doc: any,\n line: PdfWord[],\n align: TextParagraph['align'],\n left: number, width: number, baseline: number,\n ): void {\n const lineWidth = line.reduce((sum, word) => sum + word.width, 0);\n let x = left + this._alignOffset(align, width, lineWidth);\n\n for (const word of line) {\n this._drawWord(doc, word, x, baseline);\n x += word.width;\n }\n }\n\n // A table in a text block, drawn by autoTable from top (_renderText puts it\n // TEXT_TABLE_MARGIN under the line the words above it reach), in the one\n // look every renderer draws (TEXT_TABLE_* in text.ts). Its left edge, width\n // and column widths are the canvas's (layout), else the box's width split\n // evenly. A row is as tall as its cells' words wrapped as _drawParagraphs\n // wraps them, and the words are drawn into each cell once autoTable has\n // drawn its grid lines and fill (_drawTextCell), so they keep their runs'\n // fonts and colors. Only the rows the box holds are drawn, and a table that\n // loses any, or runs past its page anyway, is cut. The cursor it leaves is\n // TEXT_TABLE_MARGIN under it.\n private _drawTextTable(\n context: PdfExportContext,\n table: TextTable,\n layout: TextTableLayout | null,\n box: PdfTextBox,\n top: number,\n ): PdfTextCursor {\n if (top >= box.bottom) {\n return { cursorY: top, cut: true };\n }\n\n const left = box.left + (layout?.left ?? 0) * PT;\n const width = layout ? layout.width * PT : box.width;\n const columnWidths = layout?.columnWidths.length === table.columns\n ? layout.columnWidths.map((columnWidth) => columnWidth * PT)\n : Array.from({ length: table.columns }, () => width / table.columns);\n const body = table.rows.map((row) => row.cells.map((cell) => this._textCellInput(context.doc, cell, columnWidths)));\n const options = this._textTableOptions(context, columnWidths, left, top, width, box.bottom);\n const fit = this._textTableFit(context, { ...options, body }, top, box.bottom);\n const whole = !fit || this._drawTable(context, { ...options, body: this._keptRows(body, fit) });\n\n return {\n cursorY: fit && whole ? context.doc.lastAutoTable.finalY + TEXT_TABLE_MARGIN : top,\n cut: !whole || fit < table.rows.length,\n };\n }\n\n // A text table's cell as autoTable takes it: its spans and fill and, when it\n // is one row tall, the height its words need at the width it spans. A cell\n // that spans rows shares theirs.\n private _textCellInput(doc: any, cell: TextTableCell, columnWidths: number[]): PdfTextCellInput {\n const padding = TEXT_TABLE_CELL_PADDING;\n const width = columnWidths\n .slice(cell.column, cell.column + cell.colSpan)\n .reduce((sum, columnWidth) => sum + columnWidth, 0) - 2 * padding.horizontal;\n\n return {\n content: '',\n colSpan: cell.colSpan,\n rowSpan: cell.rowSpan,\n textCell: cell,\n styles: {\n ...(cell.fill ? { fillColor: cell.fill } : {}),\n ...(cell.rowSpan === 1\n ? { minCellHeight: this._paragraphsHeight(doc, cell.paragraphs, width) + 2 * padding.vertical }\n : {}),\n },\n };\n }\n\n // The autoTable options a text table's dry run and its draw share. Every\n // column is listed and fixed at its width: autoTable would otherwise count\n // the columns of the first row, which may be narrower than the grid. A row\n // is never split at the box's bottom: it fits whole or moves past it. bottom\n // is the box's.\n private _textTableOptions(\n context: PdfExportContext,\n columnWidths: number[],\n left: number, top: number, width: number, bottom: number,\n ): Record<string, unknown> {\n const padding = TEXT_TABLE_CELL_PADDING;\n\n return {\n theme: 'plain',\n columns: columnWidths.map((_, index) => ({ dataKey: index })),\n startY: top,\n margin: { left, right: context.pageW - left - width, bottom: context.pageH - bottom },\n tableWidth: width,\n columnStyles: Object.fromEntries(columnWidths.map((cellWidth, index) => [index, { cellWidth }])),\n rowPageBreak: 'avoid',\n styles: {\n font: 'helvetica',\n fontStyle: 'normal',\n fontSize: DEFAULT_TEXT_SIZE,\n cellPadding: {\n top: padding.vertical, right: padding.horizontal, bottom: padding.vertical, left: padding.horizontal,\n },\n lineColor: TEXT_TABLE_BORDER_COLOR,\n lineWidth: TEXT_TABLE_BORDER_WIDTH,\n valign: 'middle',\n textColor: DEFAULT_TEXT_COLOR,\n },\n didDrawCell: (hook: any) => this._drawTextCell(hook),\n };\n }\n\n // How many of a text table's rows its box, from top to bottom, holds whole:\n // the table laid out as _measure lays out a list's.\n private _textTableFit(context: PdfExportContext, options: Record<string, unknown>, top: number, bottom: number): number {\n return this._fittingRows(context.createTable(this._scratchDocument(context), options), top, bottom, 0);\n }\n\n // The first `fit` rows, a cell that spans down past the last of them cut\n // there.\n private _keptRows(body: PdfTextCellInput[][], fit: number): PdfTextCellInput[][] {\n return body.slice(0, fit).map((row) => row.map((input) => {\n const rowSpan = Math.min(input.rowSpan, fit - input.textCell.row);\n\n return rowSpan === input.rowSpan ? input : { ...input, rowSpan };\n }));\n }\n\n // A text table cell's words, drawn once autoTable has drawn the cell: inside\n // its padding, wrapped to its width and placed by its vertical alignment, the\n // middle unless set. Lines past the cell are left off.\n private _drawTextCell(hook: any): void {\n const cell: TextTableCell | undefined = hook.cell.raw?.textCell;\n if (!cell) {\n return;\n }\n\n const { x, y, width, height } = hook.cell;\n const box: PdfTextBox = {\n left: x + hook.cell.padding('left'),\n top: y + hook.cell.padding('top'),\n width: width - hook.cell.padding('horizontal'),\n bottom: y + height - hook.cell.padding('bottom'),\n };\n const spare = Math.max(0, box.bottom - box.top - this._paragraphsHeight(hook.doc, cell.paragraphs, box.width));\n const offset = cell.valign === 'top' ? 0 : (cell.valign === 'bottom' ? spare : spare / 2);\n\n this._drawParagraphs(hook.doc, cell.paragraphs, box, box.top + offset);\n }\n\n // Break a paragraph's runs into lines of measured words that fit the width.\n // A word keeps its trailing space so spacing survives run boundaries. A\n // no-break space is part of its word, never a break between two: a number\n // grouped with one (fr-CA's thousands, or a narrow space _pdfText turned\n // into one) stays on one line.\n private _wrap(doc: any, paragraph: TextParagraph, width: number): PdfWord[][] {\n const lines: PdfWord[][] = [];\n let line: PdfWord[] = [];\n let lineWidth = 0;\n\n for (const run of paragraph.runs) {\n const size = run.fontSize ?? DEFAULT_TEXT_SIZE;\n this._font(doc, run, size);\n\n for (const text of run.text.match(/(?:[^\\s]|\\u00a0)+[^\\S\\u00a0]*|[^\\S\\u00a0]+/g) ?? []) {\n const wordWidth = doc.getTextWidth(text);\n\n if (line.length && lineWidth + wordWidth - this._trailingSpace(doc, text) > width) {\n lines.push(line);\n line = [];\n lineWidth = 0;\n }\n\n line.push({ run, text, size, width: wordWidth });\n lineWidth += wordWidth;\n }\n }\n\n if (line.length) {\n lines.push(line);\n }\n\n return lines;\n }\n\n private _drawWord(doc: any, word: PdfWord, x: number, baseline: number): void {\n const run = word.run;\n\n if (run.highlight) {\n doc.setFillColor(run.highlight);\n doc.rect(x, baseline - word.size * 0.9, word.width, word.size * 1.15, 'F');\n }\n\n this._font(doc, run, word.size);\n doc.text(word.text, x, baseline);\n\n const color = run.color ?? DEFAULT_TEXT_COLOR;\n const inkWidth = word.width - this._trailingSpace(doc, word.text);\n if (run.underline) {\n doc.setDrawColor(color);\n doc.setLineWidth(word.size / 16);\n doc.line(x, baseline + word.size * 0.12, x + inkWidth, baseline + word.size * 0.12);\n }\n if (run.strike) {\n doc.setDrawColor(color);\n doc.setLineWidth(word.size / 16);\n doc.line(x, baseline - word.size * 0.3, x + inkWidth, baseline - word.size * 0.3);\n }\n\n if (run.link) {\n doc.link(x, baseline - word.size, inkWidth, word.size * 1.2, { url: run.link });\n }\n }\n\n // jsPDF's standard fonts are Helvetica, Times and Courier; a block's face is\n // mapped onto whichever of the three it resembles.\n private _font(doc: any, run: TextRun, size: number): void {\n const face = (run.fontFace ?? '').toLowerCase();\n const family = /courier|mono/.test(face)\n ? 'courier'\n : (/times|georgia|serif/.test(face) && !face.includes('sans') ? 'times' : 'helvetica');\n const style = run.bold && run.italic\n ? 'bolditalic'\n : (run.bold ? 'bold' : (run.italic ? 'italic' : 'normal'));\n\n doc.setFont(family, style);\n doc.setFontSize(size);\n doc.setTextColor(run.color ?? DEFAULT_TEXT_COLOR);\n }\n\n private _trailingSpace(doc: any, text: string): number {\n const trailing = text.length - text.trimEnd().length;\n\n return trailing ? doc.getTextWidth(' ') * trailing : 0;\n }\n\n private _alignOffset(align: TextParagraph['align'], width: number, lineWidth: number): number {\n switch (align) {\n case 'center':\n return Math.max(0, (width - lineWidth) / 2);\n case 'right':\n return Math.max(0, width - lineWidth);\n default:\n return 0;\n }\n }\n\n // What the tokens of a text block and of a tile's title fill with on this\n // page. The number is the physical page among the report's pages,\n // continuation pages included — the title page is not a report page. The\n // name stays the report page's, so a continuation page is named for the\n // page its table started on. The filters are the report's and the page's\n // own page filters (layerFilterFields).\n private _tokens(context: PdfExportContext, page: ReportPage, index: number, pageNumber: number): TextTokenContext {\n return {\n pageNumber,\n pageName: page.name || `Page ${index + 1}`,\n reportName: context.report.name,\n filters: layerFilterFields(context.filterFields, context.report.filterGroups ?? [], page.id),\n };\n }\n\n // A tile on its report page, its title's tokens filled with that page's.\n private async _renderComponent(\n context: PdfExportContext,\n page: ReportPage,\n item: CollectedComponent,\n tokens: TextTokenContext,\n overflows: PdfTableOverflow[],\n ): Promise<void> {\n const { doc } = context;\n const component = item.component;\n // Geometry is stored in inches; the PDF draws in points.\n const x = component.x * PT;\n const y = component.y * PT;\n const w = component.w * PT;\n const h = component.h * PT;\n\n const title = exportTitle(component, tokens, item.search, item.crumbs, item.filtered);\n if (title) {\n this._componentTitle(doc, title, x, y, w);\n }\n\n // A chart or list that compares or has a timeframe names its days under\n // the title, and its notes sit at the foot of its box; a KPI card draws\n // both itself. Neither takes room from a component without those keys.\n const locale = context.formatContext.locale;\n const subtitle = this._pdfText(exportWindowsLine(item, context.timezone, locale));\n const notes = component.type === 'kpi' ? [] : exportNoteLines(item, context.timezone, locale);\n const top = y + TITLE_H + (subtitle ? SUBTITLE_H : 0);\n const room = Math.max(20, y + h - top);\n const kept = notes.slice(0, Math.max(0, Math.floor((room - MIN_BODY_H) / NOTE_LINE_H)));\n\n if (subtitle) {\n this._smallLine(doc, subtitle, x, y + TITLE_H, w, 'left', 'normal');\n }\n\n const bodyY = top;\n const bodyH = Math.max(20, room - kept.length * NOTE_LINE_H);\n\n kept.forEach((line, index) => {\n this._smallLine(doc, this._pdfText(line), x, bodyY + bodyH + index * NOTE_LINE_H, w, 'left', 'italic');\n });\n\n if (!item.data || isEmptyTile(item)) {\n this._boxNote(doc, emptyLabel(item), x, bodyY, w, bodyH);\n\n return;\n }\n\n switch (component.type) {\n case 'chart': {\n const image = await renderChartImage(component, item.data, w, bodyH, context.formatContext);\n doc.addImage(image, 'PNG', x, bodyY, w, bodyH);\n break;\n }\n case 'list':\n case 'grid':\n this._renderTable(context, page, item, x, bodyY, w, bodyH, overflows);\n break;\n case 'kpi':\n this._renderKpi(context, item, x, bodyY, w, bodyH);\n break;\n }\n }\n\n // One line of small grey print, cut to the width with an ellipsis: a\n // subtitle, a note or a line of a KPI card. y is the line's top; the line is\n // NOTE_LINE_H tall, times the scale a short KPI tile shrinks its lines by.\n private _smallLine(\n doc: any,\n text: string,\n x: number, y: number, w: number,\n align: 'left' | 'center',\n style: 'normal' | 'italic',\n scale = 1,\n ): void {\n doc.setFont('helvetica', style);\n doc.setFontSize(SMALL_SIZE * scale);\n doc.setTextColor(MUTED_COLOR);\n doc.text(this._fit(doc, text, w), align === 'center' ? x + w / 2 : x, y + SMALL_SIZE * scale, { align });\n }\n\n // The text, ellipsized to the width in the doc's current font.\n private _fit(doc: any, text: string, width: number): string {\n if (doc.getTextWidth(text) <= width) {\n return text;\n }\n\n let cut = text;\n while (cut.length > 1 && doc.getTextWidth(`${cut}…`) > width) {\n cut = cut.slice(0, -1);\n }\n\n return `${cut.trimEnd()}…`;\n }\n\n // The bold strip over a component, and over each of its continuation pages.\n // A drilled title's crumbs are written in the report's locale, so the title\n // goes through _pdfText like any formatted text (the › between crumbs is\n // WinAnsi and stays).\n private _componentTitle(doc: any, title: string, x: number, y: number, w: number): void {\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(9);\n doc.setTextColor('#1f2933');\n doc.text(this._pdfText(title), x, y + 10, { maxWidth: w });\n }\n\n // An italic grey line centered in a component's body, for a body that holds\n // something other than its content. A line wider than the body wraps.\n private _boxNote(doc: any, text: string, x: number, y: number, w: number, h: number): void {\n doc.setFont('helvetica', 'italic');\n doc.setFontSize(9);\n doc.setTextColor(MUTED_COLOR);\n doc.text(text, x + w / 2, y + h / 2, { align: 'center', maxWidth: w });\n }\n\n // A list's on-page table. All of its fetched rows are laid out once to learn\n // how many the box holds; when they do not all fit, the box's last row says\n // the table continues and the rest go to overflows for continuation pages.\n // A box too short for even the head carries the notice as a line instead.\n // A table whose heading and totals row leave a continuation page no room for\n // a row stops at its box, its notice saying so. A totals row closes the\n // table once: in the box when every row fits it, else after the last\n // continuation row. Points throughout.\n private _renderTable(\n context: PdfExportContext,\n page: ReportPage,\n item: CollectedComponent,\n x: number, y: number, w: number, h: number,\n overflows: PdfTableOverflow[],\n ): void {\n const { component, search, filtered } = item;\n const { head, cells, numeric, foot, omitted } = item.table ? this._gridCells(item) : this._listCells(context, item);\n const bottom = context.pageH - (y + h);\n const { fit, columnStyles, minHeight } = this._measure(context, head, cells, numeric, foot, x, y, w, bottom);\n\n if (fit === cells.length && omitted === 0) {\n this._drawTable(\n context,\n this._tableOptions(context, head, numeric, cells, x, y, w, bottom, columnStyles, foot),\n );\n\n return;\n }\n\n // autoTable needs room for a row under the heading on every page it adds,\n // or it adds pages until the browser's stack runs out.\n const continues = minHeight < this._continuationRoom(context, page);\n const notice = continues ? CONTINUED_NOTICE : NO_ROOM_NOTICE;\n\n // The notice takes the place of the last row that fit, so that row moves\n // to the continuation. omitted > 0 means a full PDF_LIST_ROWS fetch, which\n // never fits one box, so the CSV notice always lands on a continuation\n // page.\n const kept = Math.max(0, fit - 1);\n\n if (fit >= 1) {\n const body = [...cells.slice(0, kept), this._noticeRow(notice, numeric.length, true)];\n this._drawTable(context, this._tableOptions(context, head, numeric, body, x, y, w, bottom, columnStyles));\n } else {\n this._boxNote(context.doc, notice, x, y, w, h);\n }\n\n if (continues) {\n overflows.push({\n component, search, crumbs: item.crumbs, filtered, head, numeric, rows: cells.slice(kept), omitted, foot, x, w,\n columnStyles,\n });\n }\n }\n\n // A list's heading, rows, totals row and the rows past its fetch.\n private _listCells(context: PdfExportContext, item: CollectedComponent): PdfTableParts {\n const { component, hiddenColumns } = item;\n const data = item.data as ComponentData;\n const head = [listHeadings(component, data, context.formatContext.locale, hiddenColumns).map((heading) => this._pdfText(heading))];\n const { cells, numeric, foot } = this._tableCells(context, component, data, hiddenColumns);\n\n return { head, cells, numeric, foot, omitted: Math.max(0, (data.paging?.total ?? cells.length) - cells.length) };\n }\n\n // A table tile's heading rows (spanned as the screen's header), its lines\n // (groups and totals bold, a group's label stepped in by its depth) and its\n // total row, as gridExportTable() lays them out, and the lines past its cap.\n private _gridCells(item: CollectedComponent): PdfTableParts {\n const table = gridExportTable(item.table!);\n const cell = (exported: GridExportCell): PdfTableCell => ({\n content: this._pdfText(exported.text),\n colSpan: exported.colSpan,\n rowSpan: exported.rowSpan,\n styles: {\n ...(exported.bold ? { fontStyle: 'bold' } : {}),\n ...(exported.indent\n ? {\n cellPadding: {\n top: TABLE_CELL_PADDING,\n right: TABLE_CELL_PADDING,\n bottom: TABLE_CELL_PADDING,\n left: TABLE_CELL_PADDING + exported.indent * GRID_INDENT,\n },\n }\n : {}),\n },\n });\n\n return {\n head: table.head.map((row) => row.map(cell)),\n cells: table.body.map((row) => row.map(cell)),\n numeric: table.numeric,\n foot: table.foot ? table.foot.map((exported) => this._pdfText(exported.text)) : null,\n omitted: table.moreRows,\n };\n }\n\n // Each fetched row as the strings its table cells print, in the report's\n // zone, locale and currency, which columns hold formatted numbers, and the\n // totals row (null without one). The columns the viewer hid are left out.\n private _tableCells(\n context: PdfExportContext,\n component: ReportComponent,\n data: ComponentData,\n hiddenColumns: readonly string[],\n ): { cells: string[][]; numeric: boolean[]; foot: string[] | null } {\n const columns = listColumns(component, data, context.formatContext.locale, hiddenColumns);\n const cells = data.rows.map((row) => columns.map((column) => this._pdfText(\n exportCell(row[column.column], column, context.timezone, context.formatContext, row),\n )));\n const foot = listTotalsRow(data, columns, context.timezone, context.formatContext);\n\n return {\n cells,\n numeric: columns.map((column) => column.numeric),\n foot: foot ? foot.map((cell) => this._pdfText(cell)) : null,\n };\n }\n\n // The autoTable options every list table shares: the dry run, the on-page\n // draw and the continuation pages, so the three lay a table out alike. The\n // font is named rather than inherited, since the doc carries whatever the\n // last text drawn left set. bottom is the margin under the table, points.\n //\n // A column of formatted numbers is right-aligned, its heading and total\n // too: the body through columnStyles, which autoTable applies to body cells\n // only, and the heading and total through the didParseCell hook, on every\n // page the heading repeats. A totals row (foot) prints once, under the\n // table's last row, bold on the border gray.\n private _tableOptions(\n context: PdfExportContext,\n head: PdfTableCell[][],\n numeric: boolean[],\n body: PdfTableCell[][],\n x: number, startY: number, w: number, bottom: number,\n columnStyles?: PdfColumnStyles,\n foot?: string[] | null,\n ): Record<string, unknown> {\n return {\n theme: 'grid',\n head,\n body,\n startY,\n margin: { left: x, right: context.pageW - x - w, bottom },\n tableWidth: w,\n rowPageBreak: 'avoid',\n styles: {\n font: 'helvetica',\n fontStyle: 'normal',\n fontSize: TABLE_FONT_SIZE,\n cellPadding: TABLE_CELL_PADDING,\n textColor: '#1f2933',\n },\n headStyles: { fillColor: '#4e79a7', textColor: '#ffffff', fontStyle: 'bold' },\n alternateRowStyles: { fillColor: '#f5f7fa' },\n ...(columnStyles ? { columnStyles } : {}),\n ...(foot\n ? {\n foot: [foot],\n showFoot: 'lastPage',\n footStyles: { fillColor: '#e4e7eb', textColor: '#1f2933', fontStyle: 'bold' },\n }\n : {}),\n didParseCell: (hook: any) => {\n if ((hook.section === 'head' || hook.section === 'foot') && numeric[hook.column.index]) {\n hook.cell.styles.halign = 'right';\n }\n },\n };\n }\n\n // A notice as a table row: one italic grey cell spanning every column. A\n // single-line notice is ellipsized at the box's width and keeps the data\n // cells' font size and padding, so it is never taller than the data row\n // whose place it takes.\n private _noticeRow(text: string, span: number, singleLine: boolean): PdfTableCell[] {\n return [{\n content: text,\n colSpan: span,\n // Left-aligned whatever the first column is: a spanned cell otherwise\n // takes columnStyles[0], right-aligned when that column is numeric.\n styles: {\n fontStyle: 'italic',\n textColor: MUTED_COLOR,\n halign: 'left',\n ...(singleLine ? { overflow: 'ellipsize' } : {}),\n },\n }];\n }\n\n // Lays every fetched row out once on a scratch document of the same page\n // size, with the options the real draw uses, and reads back how many body\n // rows the box holds (fit), the column widths autoTable chose, with each\n // numeric column's right alignment merged in, so the on-page table and its\n // continuation pages carry both, and the least room a page must give the\n // table (minHeight). The totals row is laid out too, so the widths hold it,\n // and a table whose rows fit the box but whose totals row does not moves\n // its last row on. fit 0 means not even one body row fits under the head.\n // The table is laid out, never drawn: drawn, autoTable pages it, and a table\n // with no room for a row on a page pages without end.\n private _measure(\n context: PdfExportContext,\n head: PdfTableCell[][],\n cells: PdfTableCell[][],\n numeric: boolean[],\n foot: string[] | null,\n x: number, y: number, w: number, bottom: number,\n ): PdfTableMeasure {\n const scratch = this._scratchDocument(context);\n const table = context.createTable(\n scratch,\n this._tableOptions(context, head, numeric, cells, x, y, w, bottom, undefined, foot),\n );\n const columns: { width: number }[] = table.columns;\n const columnStyles: PdfColumnStyles = {};\n columns.forEach((column, index) => {\n columnStyles[index] = numeric[index]\n ? { cellWidth: column.width, halign: 'right' }\n : { cellWidth: column.width };\n });\n\n const headHeight = table.getHeadHeight(table.columns);\n const footHeight = table.getFootHeight(table.columns);\n\n return {\n fit: this._fittingRows(table, y + headHeight, context.pageH - bottom, footHeight),\n columnStyles,\n // One line of a row: the line autoTable must place on a page before it\n // moves on, at the table's font size and padding.\n minHeight: headHeight + footHeight + TABLE_FONT_SIZE * scratch.getLineHeightFactor() + 2 * TABLE_CELL_PADDING,\n };\n }\n\n // How many of a laid-out table's body rows fit whole between top and\n // bottom, as autoTable decides it: a row fits when its tallest cell (one that\n // spans rows counts all of them) ends by bottom, the last row's by the top\n // of the totals row (footHeight) under it, and the next row starts where it\n // ends.\n private _fittingRows(table: any, top: number, bottom: number, footHeight: number): number {\n let cursor = top;\n let fit = 0;\n\n for (const [index, row] of table.body.entries()) {\n const limit = index === table.body.length - 1 ? bottom - footHeight : bottom;\n if (cursor + row.getMaxCellHeight(table.columns) > limit) {\n break;\n }\n\n cursor += row.height;\n fit += 1;\n }\n\n return fit;\n }\n\n // A blank document of the export's page size, for laying a table out to see\n // what fits before the real one is drawn on.\n private _scratchDocument(context: PdfExportContext): any {\n return new context.jsPDF({\n unit: 'pt',\n format: [context.pageW, context.pageH],\n orientation: context.orientation,\n });\n }\n\n // Draws an on-page table (a list's, or a text block's) on its page alone.\n // That is all it should need: the measured fit, the identical column widths\n // and a single-line notice keep the table inside its box. Should autoTable\n // start another page anyway, the table stops there and the page goes, so a\n // stray page can never catch the report page's remaining components, nor a\n // table with no room for a row add pages without end. Returns whether the\n // table was drawn whole.\n private _drawTable(context: PdfExportContext, options: Record<string, unknown>): boolean {\n const { doc } = context;\n const page = doc.getCurrentPageInfo().pageNumber;\n const pages = doc.getNumberOfPages();\n let whole = true;\n\n try {\n context.autoTable(doc, {\n ...options,\n // Fires as the table starts its own page, and again on each page it\n // moves to (an existing page, such as a continuation page under a\n // header, as well as a new one).\n willDrawPage: () => {\n if (doc.getCurrentPageInfo().pageNumber !== page) {\n throw STRAY_PAGE;\n }\n },\n });\n } catch (error) {\n if (error !== STRAY_PAGE) {\n throw error;\n }\n\n whole = false;\n }\n\n while (doc.getNumberOfPages() > pages) {\n doc.deletePage(doc.getNumberOfPages());\n }\n\n doc.setPage(page);\n\n return whole;\n }\n\n // The rows of one list that did not fit its box, on pages appended after\n // the report page, each with the page's header and footer, the table's\n // title and its head again, the title's tokens filled with the physical\n // page it is drawn on. The table sits CONTINUATION_GAP inside the bands.\n // Returns the physical page counter after these pages.\n private async _renderContinuation(\n context: PdfExportContext,\n page: ReportPage,\n index: number,\n pageNumber: number,\n overflow: PdfTableOverflow,\n ): Promise<number> {\n const { doc } = context;\n const { top, bottom } = this._continuationMargins(context, page);\n const { x, w } = overflow;\n const body: PdfTableCell[][] = overflow.omitted > 0\n ? [...overflow.rows, this._noticeRow(moreRowsNotice(overflow.omitted), overflow.numeric.length, false)]\n : overflow.rows;\n // The document's pages the table draws on, in order.\n const pages: number[] = [];\n\n doc.addPage([context.pageW, context.pageH], context.orientation);\n context.autoTable(doc, {\n ...this._tableOptions(\n context, overflow.head, overflow.numeric, body, x, top + TITLE_H, w, bottom, overflow.columnStyles,\n overflow.foot,\n ),\n margin: { top: top + TITLE_H, bottom, left: x, right: context.pageW - x - w },\n showHead: 'everyPage',\n // Fires on every page the table draws on, the first included.\n willDrawPage: () => {\n pages.push(doc.getCurrentPageInfo().pageNumber);\n const tokens = this._tokens(context, page, index, pageNumber + pages.length);\n this._componentTitle(\n doc,\n this._continuedTitle(overflow.component, tokens, overflow.search, overflow.crumbs, overflow.filtered),\n x,\n top,\n w,\n );\n },\n });\n\n await this._renderContinuationMasters(context, page, index, pageNumber, pages);\n\n return pageNumber + pages.length;\n }\n\n // The header and footer of each continuation page, numbered on from\n // pageNumber. They go on once the table is drawn, since a text block with a\n // table is measured before it is drawn, which autoTable's page hook cannot\n // wait for; they sit in the bands, clear of the table.\n private async _renderContinuationMasters(\n context: PdfExportContext,\n page: ReportPage,\n index: number,\n pageNumber: number,\n pages: number[],\n ): Promise<void> {\n const { doc } = context;\n\n for (const [offset, documentPage] of pages.entries()) {\n doc.setPage(documentPage);\n await this._renderMaster(context, page, this._tokens(context, page, index, pageNumber + offset + 1));\n }\n\n doc.setPage(doc.getNumberOfPages());\n }\n\n // The margins a continuation table keeps from the top and bottom of its\n // pages, under its title's strip at the top.\n private _continuationMargins(context: PdfExportContext, page: ReportPage): { top: number; bottom: number } {\n const bands = page.masterHidden ? NO_BANDS : context.report.config?.headerFooter ?? NO_BANDS;\n\n return {\n top: this._continuationMargin(bands.headerHeight),\n bottom: this._continuationMargin(bands.footerHeight),\n };\n }\n\n // The height a continuation page gives its table: between its margins, under\n // the title.\n private _continuationRoom(context: PdfExportContext, page: ReportPage): number {\n const { top, bottom } = this._continuationMargins(context, page);\n\n return context.pageH - top - TITLE_H - bottom;\n }\n\n // The margin a continuation table keeps from one edge: inside the band when\n // the page has one.\n private _continuationMargin(band: number): number {\n return band ? band * PT + CONTINUATION_GAP : NO_BAND_MARGIN;\n }\n\n private _continuedTitle(\n component: ReportComponent,\n tokens: TextTokenContext,\n search?: string,\n crumbs?: string[],\n filtered?: boolean,\n ): string {\n const title = exportTitle(component, tokens, search, crumbs, filtered);\n\n return title ? `${title} (continued)` : 'Continued';\n }\n\n // A KPI tile: the card the screen draws (kpi-card.ts decides every line),\n // stacked and centered in the body. A card with only its value and label\n // keeps the tile's long-standing layout.\n private _renderKpi(\n context: PdfExportContext,\n item: CollectedComponent,\n x: number, y: number, w: number, h: number,\n ): void {\n const { doc } = context;\n const config = item.component.config as KpiConfig;\n const view = kpiCardView(config, item.data, { format: context.formatContext, timezone: context.timezone });\n const value = this._pdfText(view.value);\n const notes = exportNoteLines(item, context.timezone, context.formatContext.locale);\n\n if (!kpiCardHasExtras(view, notes)) {\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(26);\n doc.setTextColor('#1f2933');\n doc.text(value, x + w / 2, y + h / 2, { align: 'center' });\n\n if (view.label) {\n doc.setFont('helvetica', 'normal');\n doc.setFontSize(9);\n doc.setTextColor(MUTED_COLOR);\n doc.text(view.label, x + w / 2, y + h / 2 + 16, { align: 'center' });\n }\n\n return;\n }\n\n // A tile too short for the card's lines shrinks them all alike.\n const parts = kpiExportParts(view, notes, h, KPI_HEIGHTS);\n const heights = scaledKpiHeights(KPI_HEIGHTS, parts.scale);\n let top = y + Math.max(0, (h - kpiExportHeight(view, parts, heights)) / 2);\n\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(26 * parts.scale);\n doc.setTextColor('#1f2933');\n doc.text(value, x + w / 2, top + KPI_VALUE_BASELINE * parts.scale, { align: 'center' });\n top += heights.value;\n\n if (view.label) {\n doc.setFont('helvetica', 'normal');\n doc.setFontSize(9 * parts.scale);\n doc.setTextColor(MUTED_COLOR);\n doc.text(this._fit(doc, this._pdfText(view.label), w), x + w / 2, top + 9 * parts.scale, { align: 'center' });\n top += heights.label;\n }\n\n if (parts.delta && view.delta) {\n this._kpiDelta(doc, view.delta, x, top, w, parts.scale);\n top += heights.delta;\n }\n\n if (parts.window) {\n this._smallLine(doc, this._pdfText(view.window), x, top, w, 'center', 'normal', parts.scale);\n top += heights.window;\n }\n\n if (parts.target && view.target) {\n this._kpiTarget(doc, view.target, x, top, w);\n top += heights.target;\n }\n\n if (parts.sparkline && view.sparkline) {\n this._kpiSparkline(doc, view.sparkline.values, view.sparkline.partial, x, top, w);\n top += heights.sparkline;\n }\n\n for (const line of parts.notes) {\n this._smallLine(doc, this._pdfText(line), x, top, w, 'center', 'italic');\n top += heights.note;\n }\n }\n\n // The delta row, centered as one group: a triangle pointing the way the\n // value moved (none when the shown change rounds to zero) and the change in\n // the color of what it means, then what it is compared with in grey.\n private _kpiDelta(doc: any, delta: KpiCardDelta, x: number, top: number, w: number, scale = 1): void {\n const color = `#${REPORT_KPI_CHANGE_COLORS[delta.tone]}`;\n const change = this._pdfText(delta.text);\n const size = KPI_DELTA_SIZE * scale;\n const side = KPI_ARROW * scale;\n const arrow = delta.trend === ReportKpiTrend.Flat ? 0 : side + KPI_ARROW_GAP * scale;\n\n doc.setFont('helvetica', 'bold');\n doc.setFontSize(size);\n const changeWidth = doc.getTextWidth(change);\n\n doc.setFont('helvetica', 'normal');\n const compared = delta.compared\n ? this._fit(doc, ` ${this._pdfText(delta.compared)}`, Math.max(0, w - arrow - changeWidth))\n : '';\n const width = arrow + changeWidth + (compared ? doc.getTextWidth(compared) : 0);\n const baseline = top + size;\n let left = x + Math.max(0, (w - width) / 2);\n\n if (arrow) {\n const up = delta.trend === ReportKpiTrend.Up;\n const tip = up ? baseline - side : baseline;\n const base = up ? baseline : baseline - side;\n\n doc.setFillColor(color);\n doc.triangle(left, base, left + side, base, left + side / 2, tip, 'F');\n left += arrow;\n }\n\n doc.setFont('helvetica', 'bold');\n doc.setTextColor(color);\n doc.text(change, left, baseline);\n\n if (compared) {\n doc.setFont('helvetica', 'normal');\n doc.setTextColor(MUTED_COLOR);\n doc.text(compared, left + changeWidth, baseline);\n }\n }\n\n // The target line ('Goal: $1,000 · 56% of target') and, when the server sent\n // the progress, a bar filled that far: green once the target is met.\n private _kpiTarget(doc: any, target: KpiCardTarget, x: number, top: number, w: number): void {\n const text = target.progress ? `${target.text} · ${target.progress}` : target.text;\n\n this._smallLine(doc, this._pdfText(text), x, top, w, 'center', 'normal');\n\n if (target.fill === null) {\n return;\n }\n\n const barW = Math.min(w * 0.6, KPI_BAR_W);\n const barX = x + (w - barW) / 2;\n const barY = top + NOTE_LINE_H + 1;\n\n doc.setFillColor(KPI_TRACK_COLOR);\n doc.rect(barX, barY, barW, KPI_BAR_H, 'F');\n\n if (target.fill > 0) {\n doc.setFillColor(`#${REPORT_KPI_CHANGE_COLORS[target.tone]}`);\n doc.rect(barX, barY, barW * target.fill, KPI_BAR_H, 'F');\n }\n }\n\n // The sparkline in a box under the card's lines, as the screen draws it\n // (kpiSparklineGeometry, a 0-100 box): a vector line per run of values, a\n // dot for a lone value, and the last point's marker, hollow while its period\n // is partial.\n private _kpiSparkline(\n doc: any,\n values: (number | null)[],\n partial: boolean,\n x: number, top: number, w: number,\n ): void {\n const geometry = kpiSparklineGeometry(values, partial);\n const boxW = Math.min(w * 0.7, KPI_SPARKLINE_W);\n const boxH = KPI_HEIGHTS.sparkline - 2 * KPI_SPARKLINE_INSET;\n const left = x + (w - boxW) / 2;\n const at = (point: KpiSparklinePoint) => ({\n x: left + point.x * boxW / 100,\n y: top + KPI_SPARKLINE_INSET + point.y * boxH / 100,\n });\n const color = `#${REPORT_KPI_SPARKLINE_COLOR}`;\n\n doc.setDrawColor(color);\n doc.setFillColor(color);\n doc.setLineWidth(1);\n\n for (const line of geometry.lines) {\n const points = line.split(' ').map((pair) => {\n const [px, py] = pair.split(',').map(Number);\n\n return at({ x: px, y: py });\n });\n const steps = points.slice(1).map((point, index) => [point.x - points[index].x, point.y - points[index].y]);\n\n doc.lines(steps, points[0].x, points[0].y, [1, 1], 'S', false);\n }\n\n for (const dot of geometry.dots) {\n const point = at(dot);\n doc.circle(point.x, point.y, KPI_DOT_R, 'F');\n }\n\n if (geometry.last) {\n const point = at(geometry.last);\n\n if (geometry.last.hollow) {\n doc.setFillColor('#ffffff');\n doc.circle(point.x, point.y, KPI_DOT_R, 'FD');\n } else {\n doc.circle(point.x, point.y, KPI_DOT_R, 'F');\n }\n }\n }\n\n // A formatted value as jsPDF can draw it. Its standard fonts write text in\n // WinAnsi, which has the no-break space (U+00A0, fr-CA's digit grouping) but\n // not the narrow one (U+202F, which other locales group and space with), the\n // thin and hair spaces (U+2009, U+200A, which Intl puts around a date\n // range's dash: 'Sep 1 – 30, 2026'), the minus sign (U+2212, some locales'\n // negative sign) or a rank change's triangles: each would print as stray\n // glyphs. The narrow space becomes a no-break space, so a number still never\n // wraps across a line; the thin and hair spaces a plain space; the minus\n // sign a hyphen; and a rank's rise a plus sign and its fall a hyphen\n // ('▲ 2' reads '+2').\n private _pdfText(text: string): string {\n return text\n .replace(/\\u202F/g, '\\u00A0')\n .replace(/[\\u2009\\u200A]/g, ' ')\n .replace(/\\u2212/g, '-')\n .replace(/\\u25B2\\s?/g, '+')\n .replace(/\\u25BC\\s?/g, '-');\n }\n\n // A layer's values with each number as jsPDF can draw it (_pdfText), so a\n // value grouped with narrow spaces reads, and wraps, like any other number.\n private _pdfValues(values: Record<string, TextValue>): Record<string, TextValue> {\n return Object.fromEntries(Object.entries(values).map(([key, value]) => [\n key,\n value.text === undefined ? value : { ...value, text: this._pdfText(value.text) },\n ]));\n }\n\n private _slug(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\n }\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { ReportChartDataLabels } from '../enums/report-chart-data-labels.enum';\nimport { ReportChartDateLabel } from '../enums/report-chart-date-label.enum';\nimport { ReportChartLineStyle } from '../enums/report-chart-line-style.enum';\nimport { ReportChartMarkStat } from '../enums/report-chart-mark-stat.enum';\nimport { ReportKpiTrend } from '../enums/report-kpi-trend.enum';\nimport { ReportListColumnFormat } from '../enums/report-list-column-format.enum';\nimport { layerFilterFields } from '../filter-text';\nimport {\n axisNumberFormat,\n chartAxisFormatCode,\n chartValuePeak,\n hasNumberFormat,\n numberFormatCode,\n resolveChartNumberFormat,\n resolveReportTimezone,\n} from '../format';\nimport {\n ChartConfig,\n ChartGranularity,\n ChartMeasure,\n ChartValueAxis,\n ComponentData,\n LegendPosition,\n KpiConfig,\n NumberFormatSpec,\n ReportComponent,\n ReportFormatContext,\n ReportLocaleTag,\n ReportPage,\n WaterfallStepKind,\n} from '../interfaces/report.interface';\nimport { KpiCardDelta, KpiCardTarget, kpiCardView, kpiSparklineGeometry } from '../kpi-card';\nimport { DEFAULT_COMPONENT_PADDING } from '../layout';\nimport { listTotalsLabelColumn } from '../list-config';\nimport {\n DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, TEXT_TABLE_BORDER_COLOR, TEXT_TABLE_BORDER_WIDTH, TEXT_TABLE_CELL_PADDING,\n TextBlock, TextParagraph, TextRun, TextTable, TextTableCell, TextTokenContext, blockParagraphs, textBlocks,\n} from '../text';\nimport { isDrawn } from '../values';\nimport {\n categoryAxisTitle,\n chartDateLabel,\n chartReferences,\n colorByValues,\n DrawnReference,\n drawsStatLines,\n ExtractedChartSeries,\n extractChartSeries,\n extractWaterfall,\n formatPeriodLabel,\n isColorBy,\n measureLineStyle,\n measureMarkStat,\n PERCENT_AXIS_INTERVAL,\n PERCENT_AXIS_MAX,\n percentAxisMin,\n PercentShares,\n percentStackedShares,\n priorSeriesStyles,\n RANK_AXIS_MIN,\n rankValueAxes,\n referencePeak,\n resolveLegendPosition,\n seriesAxisIndexes,\n seriesHex,\n seriesStat,\n seriesTypes,\n spansMultipleYears,\n STAT_LABEL,\n ValueAxisIndex,\n valueAxisRange,\n WaterfallStep,\n} from '../option-builder';\nimport {\n REPORT_CHART_COLORS,\n REPORT_KPI_CHANGE_COLORS,\n REPORT_KPI_SPARKLINE_COLOR,\n REPORT_KPI_TRACK_COLOR,\n REPORT_MUTED_TEXT_COLOR,\n REPORT_REFERENCE_COLOR,\n REPORT_WATERFALL_COLORS,\n} from '../theme/palette';\nimport {\n BuiltExport, CollectedComponent, CollectedReport, HEADER_FOOTER_NAME, KpiExportHeights, TextOverflow, coverLines,\n emptyLabel, exportCell, exportNoteLines, exportTitle, exportWindowsLine, isEmptyTile, kpiCardHasExtras,\n kpiExportHeight, kpiExportParts, listColumns, listHeadings, listTotalsRow, moreRowsNotice, scaledKpiHeights,\n textOverflow,\n} from './report-export-collector.service';\nimport { GridExportCell, gridExportTable } from './report-grid-export';\nimport {\n OVERFLOW_SLACK, ReportTextLayoutService, TextBlockLayout, TextSegmentLayout, TextTableLayout,\n} from './report-text-layout.service';\n\n\n// Component title strip height on the slide, inches.\nconst TITLE_H = 0.28;\n\n// The small print a component may carry, inches: the days it reads under its\n// title (a subtitle line), its notes at the foot of its box (a line each), and\n// the lines of a KPI card under its value. A chart's or a list's notes give\n// way before its body would shrink under MIN_BODY_H.\nconst SMALL_FONT_SIZE = 8;\nconst SUBTITLE_H = 0.18;\nconst NOTE_LINE_H = 0.16;\nconst MIN_BODY_H = 0.6;\nconst MUTED_COLOR = REPORT_MUTED_TEXT_COLOR;\n\n// A KPI card's parts, top to bottom, inches (kpiExportParts sheds the\n// sparkline, then the target, then the notes on a short tile).\nconst KPI_TARGET_TEXT_H = 0.18;\nconst KPI_BAR_GAP = 0.02;\nconst KPI_BAR_H = 0.05;\nconst KPI_HEIGHTS: KpiExportHeights = {\n value: 0.48,\n label: 0.22,\n delta: 0.22,\n window: 0.18,\n target: KPI_TARGET_TEXT_H + KPI_BAR_GAP + KPI_BAR_H + 0.03,\n sparkline: 0.42,\n note: NOTE_LINE_H,\n};\n// The size of the delta, window and target lines.\nconst KPI_LINE_FONT_SIZE = 9;\n// The delta's triangle: its side, and the gap before the change.\nconst KPI_ARROW = 0.09;\nconst KPI_ARROW_GAP = 0.04;\n// A character's average width as a share of its font size, for placing the\n// triangle beside text PowerPoint lays out.\nconst PPTX_CHAR_WIDTH = 0.42;\n// The target's progress bar, and the track it fills.\nconst KPI_BAR_W = 1.7;\nconst KPI_TRACK_COLOR = REPORT_KPI_TRACK_COLOR;\n// The sparkline's widest box, and its series name in the data sheet when the\n// measure has no label.\nconst KPI_SPARKLINE_W = 2;\nconst KPI_SPARKLINE_NAME = 'Trend';\n\n// A rank axis drawn top-down keeps its category labels under the plot: at the\n// axis's high end, which a reversed axis puts at the bottom. Ranks up to this\n// many are stepped one at a time.\nconst PPTX_RANK_CATEGORY_LABEL_POS = 'high';\nconst PPTX_RANK_WHOLE_STEP_PEAK = 10;\nconst PPTX_RANK_FORMAT_CODE = '0';\n// Approximate table row height, inches — drives the rows-that-fit cap.\nconst SLIDE_ROW_H = 0.26;\n\n// The spaces a table's group label steps in by per level: a cell's text is\n// the one place a slide table indents.\nconst GRID_INDENT = '\\u00A0\\u00A0\\u00A0';\n\n// Rows fetched for a list's slide table. A slide table never continues onto\n// another slide, so this only has to cover the rows a box can show; the\n// moreRowsNotice() row names the rest.\nexport const PPTX_LIST_ROWS = 100;\n\n// Our legend positions mapped to pptxgenjs's single-letter legendPos codes.\n// 'hidden' has no slot — showLegend is turned off instead — so it falls back\n// to top.\nconst PPTX_LEGEND_POS: Record<LegendPosition, 't' | 'b' | 'l' | 'r'> = {\n top: 't',\n bottom: 'b',\n left: 'l',\n right: 'r',\n hidden: 't',\n};\n\n// What a waterfall's series are called in PowerPoint's data sheet and on hover.\n// The legend stays off, as it does on screen, unless the chart draws\n// references, which only the legend can name in PowerPoint.\nconst WATERFALL_SERIES_NAMES: Record<WaterfallStepKind, string> = {\n rise: 'Increase',\n fall: 'Decrease',\n total: 'Total',\n};\n\n// A null is a period with no value. The screen breaks the line there, and\n// pptxgenjs's default ('span') would draw straight across it. The setting is\n// chart-level, so a combo's every type inherits it through the chart options.\nconst BLANKS_AS_GAPS = { displayBlanksAs: 'gap' } as const;\n\n// The axis label and title sizes every chart with axes shares, whichever axis\n// they land on.\nconst AXIS_FONT_SIZES = { catAxisLabelFontSize: 9, valAxisLabelFontSize: 9, valAxisTitleFontSize: 10 } as const;\n\n// A line style as PowerPoint's preset dash (a:prstDash). pptxgenjs writes it\n// on line series only, so an area is never dashed.\nconst PPTX_LINE_DASH: Record<ReportChartLineStyle, string> = {\n [ReportChartLineStyle.Solid]: 'solid',\n [ReportChartLineStyle.Dashed]: 'dash',\n [ReportChartLineStyle.Dotted]: 'sysDot',\n};\n\n// A line's markers, as on screen: a dot the screen's size on each point.\nconst PPTX_LINE_SYMBOL_SIZE = 6;\n\n// A 100% stacked chart's share axis: whole percentages. The shares are\n// ratios, so '0%' is right whatever the report's percentFormat.\nconst PPTX_PERCENT_FORMAT_CODE = '0%';\n\n// The size of a chart's data labels, a step under the axis labels, as on\n// screen.\nconst PPTX_DATA_LABEL_FONT_SIZE = 8;\n\n// The most categories an 'auto' data-labeled chart labels in PowerPoint,\n// which cannot hide the labels that overlap: past this many, it labels none.\nexport const PPTX_AUTO_LABEL_MAX_POINTS = 24;\n\n// A reference or statistic line's width in points: a hairline beside the\n// series, as on screen.\nconst PPTX_CONSTANT_LINE_SIZE = 1;\n\n// What the upper edge of a reference band is called in the data sheet and the\n// legend, after the band's own label on its lower edge.\nconst PPTX_BAND_UPPER_SUFFIX = ' (upper)';\n\n// What the export's overflow gate says the deck does with a text block that\n// does not fit its box.\nconst PPTX_OVERFLOW_NOTE = 'In the PowerPoint it runs past the bottom of its box, and table rows past it are '\n + 'left out.';\n\n// The shortest text box a text block's words get between its tables, inches,\n// however close the canvas sets their top and bottom.\nconst TEXT_SEGMENT_MIN_H = 0.05;\n\n// A text table's cell margins, top, right, bottom and left, in points: the\n// padding every renderer draws (TEXT_TABLE_CELL_PADDING). pptxgenjs 3.12 reads\n// a margin list as points when its first value is at least 1, and as inches\n// otherwise.\nconst TEXT_TABLE_CELL_MARGIN = [\n TEXT_TABLE_CELL_PADDING.vertical,\n TEXT_TABLE_CELL_PADDING.horizontal,\n TEXT_TABLE_CELL_PADDING.vertical,\n TEXT_TABLE_CELL_PADDING.horizontal,\n];\n\n// Where the legend of a chart with reference or statistic lines sits when\n// the config does not pin it: the one place PowerPoint names those lines.\nconst PPTX_CONSTANT_LEGEND: LegendPosition = 'top';\n\n// One native chart series: its name, its fill and its value per category. A\n// null is a blank point: a gap in every axis chart, not only the waterfall,\n// and a zero where bars stack.\ninterface PptxChartSeries {\n name: string;\n color: string;\n values: (number | null)[];\n}\n\n// One native chart of a PowerPoint chart: the type it draws, which of the\n// chart data's series it holds (by index), whether they plot against the\n// secondary value axis, and the options laid over the chart's for it alone.\ninterface PptxEntry {\n type: string;\n indexes: number[];\n secondary: boolean;\n options: Record<string, unknown>;\n}\n\n// A line PowerPoint draws at one value the whole width of the plot, as a\n// series of its own: a reference line, one edge of a reference band, or a\n// measure's statistic line. pptxgenjs has no markLine or markArea.\ninterface PptxConstantLine {\n name: string;\n value: number;\n color: string;\n secondary: boolean;\n}\n\n// The options of one run of PowerPoint text. PowerPoint proofs every run in its\n// language, and pptxgenjs writes en-US for a run that names none. A run whose\n// whole text is a value written in the report's locale (a KPI value, a date\n// cell, the cover's date) passes that locale, so a French date is not marked\n// as misspelled English. Authored and interface text (titles, labels,\n// headings, filter lines, notices) passes none and keeps the default, so an\n// English title in a French report is never proofed as French.\nexport function pptxRunOptions(\n options: Record<string, unknown>,\n valueLocale?: ReportLocaleTag,\n): Record<string, unknown> {\n return valueLocale ? { ...options, lang: valueLocale } : options;\n}\n\n// Builds the PowerPoint deck client-side with pptxgenjs. Charts are NATIVE\n// editable PowerPoint charts (slide.addChart writes real chart XML with an\n// embedded data workbook — \"Edit Data\" works), never images. The page IS the\n// slide: the report's unit is inches — exactly PowerPoint's unit — so the\n// layout and every component position transfer with no conversion at all.\n// pptxgenjs is loaded lazily so it lives in its own webpack chunk.\n//\n// A text block's words and tables are placed where the canvas lays them out\n// (ReportTextLayoutService). Words that do not fit a block's box run on past\n// its bottom, and table rows past it are left out, so build() hands the deck\n// back unsaved with the blocks that do not fit, and the export can ask about\n// them before it saves.\n@Injectable()\nexport class ReportPptxService {\n\n private readonly _textLayout = inject(ReportTextLayoutService);\n\n public async build(collected: CollectedReport): Promise<BuiltExport> {\n const PptxGenJS = (await import('pptxgenjs')).default;\n\n const report = collected.report;\n const pageW = report.pageWidth;\n const pageH = report.pageHeight;\n\n const pptx = new PptxGenJS();\n pptx.defineLayout({ name: 'REPORT', width: pageW, height: pageH });\n pptx.layout = 'REPORT';\n pptx.title = report.name;\n\n this._titleSlide(pptx, collected, pageW, pageH);\n\n // The text blocks that do not fit their box, by component id, so a header\n // or footer block is listed once, not once per slide.\n const overflows = new Map<number, TextOverflow>();\n\n for (const index of collected.pages.keys()) {\n await this._renderPage(pptx, collected, index, overflows);\n }\n\n return {\n overflows: [...overflows.values()],\n overflowNote: PPTX_OVERFLOW_NOTE,\n // A slide's shapes are laid out by PowerPoint, so a component cannot\n // fail to draw here as a PDF table can.\n undrawn: [],\n save: async () => {\n await pptx.writeFile({ fileName: `${this._slug(report.name)}.pptx` });\n },\n };\n }\n\n // One report page's slide. The header and footer first, so the page's own\n // components sit on top of them exactly as on the canvas. Each layer's text\n // fills its value tokens with that layer's values: the master's or the\n // page's.\n private async _renderPage(\n pptx: any,\n collected: CollectedReport,\n index: number,\n overflows: Map<number, TextOverflow>,\n ): Promise<void> {\n const report = collected.report;\n const collectedPage = collected.pages[index];\n const slide = pptx.addSlide();\n const tokens = this._tokens(collected, collectedPage.page, index);\n const pageTokens = { ...tokens, values: collectedPage.values };\n const timezone = resolveReportTimezone(report);\n\n if (!collectedPage.page.masterHidden) {\n await this._renderMaster(slide, collected, tokens, overflows);\n }\n\n for (const item of collectedPage.components) {\n if (item.component.type !== 'text') {\n this._renderComponent(pptx, slide, item, tokens, timezone, collected.formatContext);\n } else if (await this._renderText(slide, item.component, pageTokens)) {\n this._recordOverflow(overflows, item.component, tokens.pageName, pageTokens);\n }\n }\n }\n\n // The header and footer, their value tokens filled with the master's\n // values. They read no page filter: its token prints the em dash there.\n private async _renderMaster(\n slide: any,\n collected: CollectedReport,\n tokens: TextTokenContext,\n overflows: Map<number, TextOverflow>,\n ): Promise<void> {\n const masterTokens = {\n ...tokens,\n values: collected.masterValues,\n filters: layerFilterFields(collected.filterFields, collected.report.filterGroups ?? [], null),\n };\n\n for (const component of (collected.report.master?.components ?? []).filter(isDrawn)) {\n if (await this._renderText(slide, component, masterTokens)) {\n this._recordOverflow(overflows, component, HEADER_FOOTER_NAME, masterTokens);\n }\n }\n }\n\n // Lists a text block that does not fit its box, under the page the export's\n // overflow gate names it by. A block listed on an earlier slide (a header or\n // footer) keeps that entry.\n private _recordOverflow(\n overflows: Map<number, TextOverflow>,\n component: ReportComponent,\n page: string,\n tokens: TextTokenContext,\n ): void {\n if (!overflows.has(component.id)) {\n overflows.set(component.id, textOverflow(component, page, tokens));\n }\n }\n\n private _titleSlide(pptx: any, collected: CollectedReport, pageW: number, pageH: number): void {\n const slide = pptx.addSlide();\n\n slide.addText(collected.report.name, {\n x: 0.5, y: pageH * 0.3, w: pageW - 1, h: 0.8,\n fontSize: 30, bold: true, color: '1F2933',\n });\n\n // coverLines() leads with the export date, the one line written in the\n // report's locale; the filter and context lines are interface text.\n const lines = coverLines(collected);\n const runs = lines.map((line, index) => ({\n text: line,\n options: pptxRunOptions(\n { breakLine: index < lines.length - 1 },\n index === 0 ? collected.formatContext.locale : undefined,\n ),\n }));\n\n slide.addText(runs, {\n x: 0.5, y: pageH * 0.3 + 0.9, w: pageW - 1, h: Math.max(0.4, lines.length * 0.25),\n fontSize: 12, color: '52606D',\n });\n }\n\n // A text block as native PowerPoint text, editable in the deck, each run\n // carrying its own bold/italic/color/size. The block is measured as the\n // canvas lays it out (ReportTextLayoutService). A block without a table is\n // ONE text box (_addTextBox). A block with tables is a stack inside its\n // padding (_renderTextStack). Returns whether anything runs past the bottom\n // of the box or was left out.\n private async _renderText(slide: any, component: ReportComponent, tokens: TextTokenContext): Promise<boolean> {\n const html = component.config?.html ?? '';\n const blocks = textBlocks(html, tokens);\n const layout = await this._textLayout.measure(component, tokens);\n const textCount = blocks.filter((block) => block.kind === 'text').length;\n const tableCount = blocks.length - textCount;\n\n // The measure finds a block's parts one for one with textBlocks, unless the\n // canvas rendered the html differently. A block whose parts it did not\n // find falls back to the one text box, its tables read as lines of text.\n if (!tableCount || layout.tables.length !== tableCount || layout.segments.length !== textCount) {\n this._addTextBox(slide, component, blockParagraphs(blocks));\n\n return layout.overflow;\n }\n\n return this._renderTextStack(slide, component, blocks, layout) || layout.overflow;\n }\n\n // The words as ONE text box over the whole block. Its inset is the block's\n // padding, so the words land where they sat on screen.\n private _addTextBox(slide: any, component: ReportComponent, paragraphs: TextParagraph[]): void {\n const runs = this._paragraphRuns(paragraphs);\n if (!runs.length) {\n return;\n }\n\n const padding = component.config?.padding;\n const inset = (value: number | undefined) => (value ?? DEFAULT_COMPONENT_PADDING) * 72;\n\n slide.addText(runs, {\n x: component.x, y: component.y, w: component.w, h: component.h,\n valign: 'top',\n fontFace: 'Arial',\n margin: [inset(padding?.left), inset(padding?.right), inset(padding?.bottom), inset(padding?.top)],\n fit: 'none',\n });\n }\n\n // A block with tables as a stack inside its padding: a text box for the\n // words before, between and after its tables, and a native table for each\n // table, each at the top the canvas gives it. PowerPoint spaces lines a\n // little differently from the canvas, so placing every part afresh keeps\n // that drift from adding up down the block. Returns whether any part was\n // left out.\n private _renderTextStack(\n slide: any,\n component: ReportComponent,\n blocks: TextBlock[],\n layout: TextBlockLayout,\n ): boolean {\n const padding = component.config?.padding;\n const x = component.x + (padding?.left ?? DEFAULT_COMPONENT_PADDING);\n const y = component.y + (padding?.top ?? DEFAULT_COMPONENT_PADDING);\n let segmentIndex = 0;\n let tableIndex = 0;\n let flagged = false;\n\n for (const block of blocks) {\n const leftOut = block.kind === 'text'\n ? this._addTextSegment(slide, block.paragraphs, layout.segments[segmentIndex++], layout, x, y)\n : this._addTextTable(slide, block.table, layout.tables[tableIndex++], layout, x, y);\n\n flagged = flagged || leftOut;\n }\n\n return flagged;\n }\n\n // The words between two tables (or before the first, or after the last) as\n // a text box from the top of their first line to the bottom of their last,\n // as wide as the block's content. A stretch that draws nothing is skipped,\n // and one that starts below the box is left out. Returns whether it was.\n private _addTextSegment(\n slide: any,\n paragraphs: TextParagraph[],\n segment: TextSegmentLayout | null,\n layout: TextBlockLayout,\n x: number, y: number,\n ): boolean {\n if (!segment || !paragraphs.some((paragraph) => paragraph.runs.length)) {\n return false;\n }\n\n if (segment.top >= layout.contentHeight) {\n return true;\n }\n\n slide.addText(this._paragraphRuns(paragraphs), {\n x, y: y + segment.top, w: layout.contentWidth, h: Math.max(TEXT_SEGMENT_MIN_H, segment.bottom - segment.top),\n margin: 0,\n valign: 'top',\n fontFace: 'Arial',\n fit: 'none',\n });\n\n return false;\n }\n\n // A table as a native, editable PowerPoint table where the canvas puts it,\n // in its column widths and row heights, in the one look every renderer\n // draws (TEXT_TABLE_* in text.ts). Only the rows that end inside the box are\n // kept. Returns whether any row was left out.\n private _addTextTable(\n slide: any,\n table: TextTable,\n tableLayout: TextTableLayout,\n layout: TextBlockLayout,\n x: number, y: number,\n ): boolean {\n const kept = this._keptRows(tableLayout, layout.contentHeight);\n\n if (kept) {\n slide.addTable(this._tableRows(table, kept), {\n x: x + tableLayout.left,\n y: y + tableLayout.top,\n w: tableLayout.width,\n colW: tableLayout.columnWidths,\n rowH: tableLayout.rowHeights.slice(0, kept),\n autoPage: false,\n fontFace: 'Arial',\n fontSize: DEFAULT_TEXT_SIZE,\n color: DEFAULT_TEXT_COLOR.replace('#', ''),\n border: { type: 'solid', pt: TEXT_TABLE_BORDER_WIDTH, color: TEXT_TABLE_BORDER_COLOR.replace('#', '') },\n margin: TEXT_TABLE_CELL_MARGIN,\n });\n }\n\n return kept < table.rows.length;\n }\n\n // How many of a table's rows, from the top, end inside the box.\n private _keptRows(tableLayout: TextTableLayout, contentHeight: number): number {\n let bottom = tableLayout.top;\n let kept = 0;\n\n for (const rowHeight of tableLayout.rowHeights) {\n bottom += rowHeight;\n if (bottom > contentHeight + OVERFLOW_SLACK) {\n break;\n }\n\n kept++;\n }\n\n return kept;\n }\n\n // The kept rows as pptxgenjs cells, each row in grid order. A PowerPoint\n // table is a full grid, and pptxgenjs counts its columns on the first row\n // and slips a merged cell's continuation into the row below at that cell's\n // place in its own row. So a cell is written in its top left slot only, a\n // slot no cell holds gets an empty cell, and a cell's spans end where they\n // would reach past the kept rows or into a slot another cell holds\n // (claimSlots).\n private _tableRows(table: TextTable, kept: number): any[][] {\n const slots: (TextTableCell | null)[][] = Array.from({ length: kept }, () => Array(table.columns).fill(null));\n table.rows.slice(0, kept).forEach((row) => row.cells.forEach((cell) => claimSlots(slots, cell)));\n\n return slots.map((row, rowIndex) => row.flatMap((cell, column) => {\n if (!cell) {\n return [{ text: '' }];\n }\n\n return cell.row === rowIndex && cell.column === column ? [this._tableCell(cell)] : [];\n }));\n }\n\n // A text table's cell: its words, its spans, its fill and its alignment. A\n // header cell's runs are already bold (parseTable), so a run its html sets\n // in a normal weight stays that way.\n private _tableCell(cell: TextTableCell): Record<string, unknown> {\n const runs = this._paragraphRuns(cell.paragraphs);\n\n return {\n // An empty cell still needs its one empty paragraph.\n text: runs.length ? runs : '',\n options: {\n colspan: cell.colSpan,\n rowspan: cell.rowSpan,\n fill: cell.fill ? { color: cell.fill.replace('#', '') } : undefined,\n align: cell.align,\n valign: cell.valign ?? 'middle',\n margin: TEXT_TABLE_CELL_MARGIN,\n },\n };\n }\n\n // Paragraphs as the runs of one native text body, each run in its own\n // style, a line break after each paragraph but the last. An empty paragraph\n // is a blank line. Text boxes and table cells take the same runs.\n private _paragraphRuns(paragraphs: TextParagraph[]): any[] {\n return paragraphs.flatMap((paragraph, index) => {\n const isLast = index === paragraphs.length - 1;\n const paragraphOptions = {\n align: paragraph.align,\n bullet: paragraph.bullet === 'number'\n ? { type: 'number' }\n : (paragraph.bullet === 'bullet' ? true : undefined),\n };\n const runs: TextRun[] = paragraph.runs.length ? paragraph.runs : [{ text: '' }];\n\n return runs.map((run, runIndex) => ({\n text: run.text,\n options: this._runOptions(run, paragraphOptions, runIndex === runs.length - 1 && !isLast),\n }));\n });\n }\n\n // One run's options: its own style over its paragraph's alignment and\n // bullet, and a line break when it ends a paragraph that is not the last.\n private _runOptions(\n run: TextRun,\n paragraphOptions: Record<string, unknown>,\n breakLine: boolean,\n ): Record<string, unknown> {\n return {\n ...paragraphOptions,\n bold: run.bold,\n italic: run.italic,\n underline: run.underline ? { style: 'sng' } : undefined,\n strike: run.strike ? 'sngStrike' : undefined,\n color: (run.color ?? DEFAULT_TEXT_COLOR).replace('#', ''),\n highlight: run.highlight?.replace('#', ''),\n fontSize: run.fontSize ?? DEFAULT_TEXT_SIZE,\n fontFace: run.fontFace,\n hyperlink: run.link ? { url: run.link } : undefined,\n breakLine,\n };\n }\n\n // What the tokens of a text block and of a tile's title fill with on this\n // slide: the page's position among the report's pages — the title slide is\n // not a report page — and the report's filters with the page's own page\n // filters (layerFilterFields).\n private _tokens(collected: CollectedReport, page: ReportPage, index: number): TextTokenContext {\n return {\n pageNumber: index + 1,\n pageName: page.name || `Page ${index + 1}`,\n reportName: collected.report.name,\n filters: layerFilterFields(collected.filterFields, collected.report.filterGroups ?? [], page.id),\n };\n }\n\n // A tile on its slide, its title's tokens filled with the slide's page.\n private _renderComponent(\n pptx: any,\n slide: any,\n item: CollectedComponent,\n tokens: TextTokenContext,\n timezone: string,\n context: ReportFormatContext,\n ): void {\n const component = item.component;\n // Geometry is in inches — PowerPoint's native unit.\n const { x, y, w, h } = component;\n\n const title = exportTitle(component, tokens, item.search, item.crumbs, item.filtered);\n if (title) {\n slide.addText(title, {\n x, y, w, h: TITLE_H,\n fontSize: 10, bold: true, color: '1F2933', valign: 'top',\n });\n }\n\n // A chart or list that compares or has a timeframe names its days under\n // the title, and its notes sit at the foot of its box; a KPI card draws\n // both itself. Neither takes room from a component without those keys.\n const subtitle = exportWindowsLine(item, timezone, context.locale);\n const notes = component.type === 'kpi' ? [] : exportNoteLines(item, timezone, context.locale);\n const top = y + TITLE_H + (subtitle ? SUBTITLE_H : 0);\n const room = Math.max(0.3, y + h - top);\n const kept = notes.slice(0, Math.max(0, Math.floor((room - MIN_BODY_H) / NOTE_LINE_H)));\n\n if (subtitle) {\n slide.addText(this._fitEstimate(subtitle, SMALL_FONT_SIZE, w), {\n x, y: y + TITLE_H, w, h: SUBTITLE_H,\n fontSize: SMALL_FONT_SIZE, color: MUTED_COLOR, valign: 'top', margin: 0, fit: 'none',\n });\n }\n\n const bodyY = top;\n const bodyH = Math.max(0.3, room - kept.length * NOTE_LINE_H);\n\n if (kept.length) {\n const noteLines = kept.map((note) => this._fitEstimate(note, SMALL_FONT_SIZE, w));\n\n slide.addText(this._lineRuns(noteLines, { italic: true }), {\n x, y: bodyY + bodyH, w, h: kept.length * NOTE_LINE_H,\n fontSize: SMALL_FONT_SIZE, color: MUTED_COLOR, valign: 'top', margin: 0, fit: 'none',\n });\n }\n\n if (!item.data || isEmptyTile(item)) {\n slide.addText(emptyLabel(item), {\n x, y: bodyY, w, h: bodyH,\n fontSize: 10, italic: true, color: MUTED_COLOR, align: 'center', valign: 'middle',\n });\n\n return;\n }\n\n switch (component.type) {\n case 'chart':\n this._renderChart(pptx, slide, component, item.data, context, x, bodyY, w, bodyH);\n break;\n case 'list':\n this._renderTable(slide, component, item.data, item.hiddenColumns, timezone, context, x, bodyY, w, bodyH);\n break;\n case 'grid':\n this._renderGridTable(slide, item, context, x, bodyY, w, bodyH);\n break;\n case 'kpi':\n this._renderKpi(pptx, slide, item, timezone, context, x, bodyY, w, bodyH);\n break;\n }\n }\n\n // Lines of one text box, each its own paragraph.\n private _lineRuns(lines: readonly string[], options: Record<string, unknown> = {}): any[] {\n return lines.map((line, index) => ({ text: line, options: { ...options, breakLine: index < lines.length - 1 } }));\n }\n\n private _renderChart(\n pptx: any,\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = component.config as ChartConfig;\n const chartType = config.chartType ?? 'bar';\n\n if (chartType === 'waterfall') {\n this._renderWaterfall(pptx, slide, component, data, context, x, y, w, h);\n\n return;\n }\n\n const extracted = extractChartSeries(component, data);\n\n const typeMap: Record<string, any> = {\n bar: pptx.ChartType.bar,\n line: pptx.ChartType.line,\n area: pptx.ChartType.area,\n pie: pptx.ChartType.pie,\n donut: pptx.ChartType.doughnut,\n };\n\n const pie = chartType === 'pie' || chartType === 'donut';\n const colorBy = isColorBy(config);\n const labels = this._categoryLabels(\n extracted.categories,\n data.granularity,\n context.locale,\n chartDateLabel(config),\n );\n // A 100% stacked chart's primary bars and areas plot the shares the screen\n // draws, stacked: PowerPoint's own percentStacked grouping is dropped on an\n // area chart, so one rule covers both. The data sheet holds the shares;\n // the CSV keeps the raw values.\n const shares = percentStackedShares(extracted, config);\n\n // Native chart data: one entry per series (pie charts take exactly one).\n // colorBy emits one series per category for the on-screen overlap; PowerPoint\n // has no equivalent overlap, so collapse them back into a single series (each\n // category's value sits at its own slot) — one full-width bar per category —\n // rather than letting PowerPoint cluster them into slivers.\n const measureData = colorBy\n ? [{\n name: config.measures?.[0]?.label ?? config.colorBy?.label ?? '',\n labels,\n values: colorByValues(extracted),\n }]\n : (pie ? extracted.series.slice(0, 1) : extracted.series)\n .map((series, index) => ({\n name: series.name,\n labels,\n // A pie keeps the 0 the screen's pie uses; an axis chart keeps its\n // null so the point is a gap.\n values: pie ? series.values.map((value) => value ?? 0) : (shares?.get(index) ?? series.values),\n }));\n\n // The type each chartData entry is drawn as. A pie is one entry of its own\n // type; colorBy collapsed its series into one, drawn as the lone measure's.\n const seriesDataTypes: string[] = pie\n ? [chartType]\n : seriesTypes(extracted, chartType).slice(0, colorBy ? 1 : undefined);\n const dataTypes = seriesDataTypes.length ? seriesDataTypes : [chartType];\n // The value axis of each chartData entry; a pie and a colorBy chart have\n // one series on the one axis.\n const axisIndexes = pie || colorBy ? [0 as ValueAxisIndex] : seriesAxisIndexes(extracted, config);\n const twoAxes = axisIndexes.includes(1);\n const references = chartReferences(config, twoAxes);\n const formatCodes = pie ? [] : this._measureFormatCodes(config, extracted, axisIndexes, context, shares, references);\n // A value axis that plots nothing but ranks reads top-down, rank 1 at the\n // top, as on screen (a 100% stacked chart's primary axis is its shares).\n const rankAxes = pie || colorBy || shares ? [false, false] : rankValueAxes(extracted, data, config);\n const rankPeaks = ([0, 1] as const).map((axisIndex) => chartValuePeak(\n extracted.series.filter((_, index) => axisIndexes[index] === axisIndex).map((series) => series.values),\n false,\n ));\n\n // References and statistic lines follow the measures in the chart data,\n // each a constant series of its own.\n const constants = pie\n ? []\n : [\n ...this._referenceLines(references),\n ...this._statLines(config, extracted, axisIndexes, shares, colorBy, measureData[0]?.name ?? ''),\n ];\n const legendPosition = this._legendPosition(config, colorBy, extracted.series.length, constants.length);\n const chartData = [\n ...measureData,\n ...constants.map((line) => ({ name: line.name, labels, values: labels.map(() => line.value) })),\n ];\n\n // Series colors are per entry (_entryPlan), never chart-level, where a\n // multi-type chart's every entry would inherit them.\n const options = {\n x, y, w, h,\n showLegend: legendPosition !== 'hidden',\n legendPos: PPTX_LEGEND_POS[legendPosition],\n legendFontSize: 9,\n barDir: config.orientation === 'horizontal' ? 'bar' : 'col',\n barGrouping: config.stacked || shares ? 'stacked' : 'clustered',\n holeSize: chartType === 'donut' ? 55 : undefined,\n ...(twoAxes\n ? this._twoAxesOptions(config, data, formatCodes, shares, rankAxes, rankPeaks)\n : this._axisTextOptions(config, data, pie)),\n ...BLANKS_AS_GAPS,\n // A pie has no axes. A combo's types inherit these from the chart level;\n // a two-axis chart's value axes carry their own format codes. A 100%\n // stacked chart's one value axis is the share axis.\n ...(pie || twoAxes ? {} : (shares ? this._percentAxisOptions(shares) : {\n valAxisLabelFormatCode: formatCodes[0],\n })),\n ...(pie ? {} : this._categoryOrderOptions(config, dataTypes)),\n ...(twoAxes || !rankAxes[0] ? {} : {\n ...this._rankAxisOptions(config.valueAxis, rankPeaks[0]),\n catAxisLabelPos: PPTX_RANK_CATEGORY_LABEL_POS,\n }),\n dataBorder: { pt: 0, color: 'FFFFFF' },\n };\n\n const priorStyles = pie ? null : priorSeriesStyles(config, data, extracted);\n const entries = [\n ...this._entryPlan(dataTypes, extracted, config, axisIndexes, shares, chartData.length, priorStyles)\n .map((entry) => this._withDataLabels(entry, config, formatCodes, shares, labels.length)),\n ...constants.map((line, index) => this._constantEntry(line, measureData.length + index, chartData.length)),\n ];\n\n this._addChart(slide, typeMap, entries, chartData, options);\n }\n\n // Where the legend sits, as on screen (resolveLegendPosition), with two\n // differences. A single-series colorBy chart can't carry a per-category\n // legend in a native PowerPoint bar chart, so the category axis labels\n // identify each bar instead. And a reference or statistic line is named in\n // the legend alone, where the screen labels it on the line, so a chart that\n // draws one shows the legend whenever the config does not pin it. A pinned\n // position, 'hidden' included, still wins.\n private _legendPosition(\n config: ChartConfig,\n colorBy: boolean,\n seriesCount: number,\n constantCount: number,\n ): LegendPosition {\n if (constantCount) {\n return config.legend ?? PPTX_CONSTANT_LEGEND;\n }\n\n return colorBy ? 'hidden' : resolveLegendPosition(config, seriesCount);\n }\n\n // Each reference (chartReferences) as constant lines: a line at its value,\n // or a band's lower edge under its label and its upper edge under the label\n // with PPTX_BAND_UPPER_SUFFIX. A chart draws the ones the screen draws: none\n // on a horizontal chart or a pie.\n private _referenceLines(references: DrawnReference[]): PptxConstantLine[] {\n return references.flatMap((reference) => {\n const line = { name: reference.label, value: reference.low, color: REPORT_REFERENCE_COLOR, secondary: reference.axisIndex === 1 };\n\n return reference.band\n ? [line, { ...line, name: `${reference.label}${PPTX_BAND_UPPER_SUFFIX}`, value: reference.high }]\n : [line];\n });\n }\n\n // Each measure's statistic line, taken over the values the series plots\n // (its shares on a 100% stacked chart), named after the series ('Visits\n // average') and drawn in its color on its axis. A colorBy chart's one line\n // is taken over its collapsed bars and drawn in the reference slate, as on\n // screen. A series with no value draws none, and a horizontal chart none.\n private _statLines(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n shares: PercentShares | null,\n colorBy: boolean,\n colorByName: string,\n ): PptxConstantLine[] {\n if (!drawsStatLines(config)) {\n return [];\n }\n\n const line = (\n name: string,\n values: (number | null)[],\n stat: ReportChartMarkStat,\n color: string,\n secondary: boolean,\n ): PptxConstantLine[] => {\n const value = seriesStat(values, stat);\n const statName = STAT_LABEL[stat];\n\n return value === null\n ? []\n : [{ name: name ? `${name} ${statName.toLowerCase()}` : statName, value, color, secondary }];\n };\n\n if (colorBy) {\n const stat = measureMarkStat(extracted.series[0]?.measure);\n\n return stat ? line(colorByName, colorByValues(extracted), stat, REPORT_REFERENCE_COLOR, false) : [];\n }\n\n return extracted.series.flatMap((series, index) => {\n const stat = measureMarkStat(series.measure);\n\n return stat\n ? line(series.name, shares?.get(index) ?? series.values, stat, seriesHex(series, index), axisIndexes[index] === 1)\n : [];\n });\n }\n\n // A constant line's own entry: dashed, without markers or data labels, on\n // its value axis. Its colors run the length of the chart's data, as a\n // measure line's do (_entryPlan), so no marker ever takes a random color.\n private _constantEntry(line: PptxConstantLine, index: number, totalData: number): PptxEntry {\n return {\n type: 'line',\n indexes: [index],\n secondary: line.secondary,\n options: {\n chartColors: Array<string>(totalData).fill(line.color),\n lineDash: PPTX_LINE_DASH[ReportChartLineStyle.Dashed],\n lineDataSymbol: 'none',\n lineSize: PPTX_CONSTANT_LINE_SIZE,\n showValue: false,\n ...(line.secondary ? { secondaryValAxis: true, secondaryCatAxis: true } : {}),\n },\n };\n }\n\n // The number format code of the measures plotted on each value axis, by\n // axis index, matching the screen's ticks (_valueAxisCode): a one-axis chart\n // takes the format its plotted series' measures agree on, as on screen. A 100% stacked\n // chart's share axis is drawn in PPTX_PERCENT_FORMAT_CODE instead; these\n // codes still write the raw values of the series beside its shares. The\n // references on an axis count toward its peak, as on screen\n // (referencePeak), except a 100% stacked chart's, which are shares.\n private _measureFormatCodes(\n config: ChartConfig,\n extracted: ExtractedChartSeries,\n axisIndexes: ValueAxisIndex[],\n context: ReportFormatContext,\n shares: PercentShares | null,\n references: DrawnReference[],\n ): string[] {\n const reach = (axisIndex: ValueAxisIndex) => (shares && axisIndex === 0 ? 0 : referencePeak(references, axisIndex));\n\n if (!axisIndexes.includes(1)) {\n const values = extracted.series.map((series) => series.values);\n const spec = axisNumberFormat(extracted.series.map((series) => series.measure));\n\n return [this._valueAxisCode(spec, values, !!config.stacked, context, reach(0))];\n }\n\n return ([0, 1] as const).map((axisIndex) => {\n const onAxis = extracted.series.filter((_, index) => axisIndexes[index] === axisIndex);\n\n return this._valueAxisCode(\n axisNumberFormat(onAxis.map((series) => series.measure)),\n onAxis.map((series) => series.values),\n !!config.stacked && !shares,\n context,\n reach(axisIndex),\n );\n });\n }\n\n // A measure entry with its data labels (config.dataLabels), set on the\n // entry alone: on a chart of several entries a chart-level key would reach\n // every one of them. Never called for a reference or statistic line.\n //\n // 'all' labels every point. PowerPoint cannot hide overlapping labels, so\n // 'auto' labels every point up to PPTX_AUTO_LABEL_MAX_POINTS categories\n // and none past that. pptxgenjs cannot label a single point, so 'last'\n // labels none (a documented gap), except on a colorBy chart: there every\n // bar is its own series' latest point on screen, so 'last' labels every\n // bar of the one collapsed series, as 'all' does.\n //\n // A label is written in its axis's format code ('0%' for a share). A\n // stacked bar's sits in the middle of its segment and a line's above its\n // point. A clustered bar keeps PowerPoint's default, outside its end, which\n // pptxgenjs would drop on a one-entry chart if named; an area takes no\n // position at all, and pptxgenjs does not strip one from a combo's area.\n private _withDataLabels(\n entry: PptxEntry,\n config: ChartConfig,\n formatCodes: string[],\n shares: PercentShares | null,\n categoryCount: number,\n ): PptxEntry {\n const mode = config.dataLabels;\n const show = mode === ReportChartDataLabels.All\n || (mode === ReportChartDataLabels.Auto && categoryCount <= PPTX_AUTO_LABEL_MAX_POINTS)\n || (mode === ReportChartDataLabels.Last && isColorBy(config));\n const chartType = config.chartType ?? 'bar';\n\n if (!show || chartType === 'pie' || chartType === 'donut') {\n return entry;\n }\n\n const share = !!shares?.has(entry.indexes[0]);\n const stacked = entry.type === 'bar' && (shares ? share : !!config.stacked);\n const position = this._dataLabelPosition(entry.type, stacked);\n\n return {\n ...entry,\n options: {\n ...entry.options,\n showValue: true,\n dataLabelFormatCode: share ? PPTX_PERCENT_FORMAT_CODE : formatCodes[entry.secondary ? 1 : 0],\n dataLabelFontSize: PPTX_DATA_LABEL_FONT_SIZE,\n ...(position ? { dataLabelPosition: position } : {}),\n },\n };\n }\n\n // A 100% stacked chart's share axis, as on screen: from 0 (-100% when a\n // share is negative) to 100%, a gridline every 25%, in whole percentages.\n private _percentAxisOptions(shares: PercentShares): Record<string, unknown> {\n return {\n valAxisMinVal: percentAxisMin(shares),\n valAxisMaxVal: PERCENT_AXIS_MAX,\n valAxisMajorUnit: PERCENT_AXIS_INTERVAL,\n valAxisLabelFormatCode: PPTX_PERCENT_FORMAT_CODE,\n };\n }\n\n // A two-axis chart's axes, each in its own object: pptxgenjs builds the\n // second value and category axes from the chart's options with these laid\n // over them, so a value-axis key left at the chart level would reach both.\n // The primary value axis is on the left with the category axis under it;\n // the second is on the right, without gridlines of its own, and its\n // category axis is hidden. Each value axis is titled only by its own label\n // and formatted by the measures plotted against it, as on screen. On a 100%\n // stacked chart the primary axis is the share axis, and the second axis's\n // series are not stacked.\n private _twoAxesOptions(\n config: ChartConfig,\n data: ComponentData,\n formatCodes: string[],\n shares: PercentShares | null,\n rankAxes: boolean[],\n rankPeaks: number[],\n ): Record<string, unknown> {\n const valueAxis = (axisIndex: ValueAxisIndex) => {\n const axis = axisIndex === 1 ? config.secondaryAxis : config.valueAxis;\n const range = this._valueAxisRangeOptions(axis, axis?.label);\n const rank = rankAxes[axisIndex] ? this._rankAxisOptions(axis, rankPeaks[axisIndex]) : {};\n\n if (shares && axisIndex === 0) {\n return { ...range, ...this._percentAxisOptions(shares) };\n }\n\n return { ...range, valAxisLabelFormatCode: formatCodes[axisIndex], ...rank };\n };\n // The category labels stay under the plot when the primary value axis is\n // a rank axis drawn top-down.\n const category = rankAxes[0]\n ? { ...this._categoryTitleOptions(config, data), catAxisLabelPos: PPTX_RANK_CATEGORY_LABEL_POS }\n : this._categoryTitleOptions(config, data);\n\n return {\n ...AXIS_FONT_SIZES,\n valAxes: [valueAxis(0), { ...valueAxis(1), valGridLine: { style: 'none' } }],\n catAxes: [category, { catAxisHidden: true }],\n };\n }\n\n // A rank axis, as on screen: reversed ('maxMin'), so rank 1 is at the top,\n // starting at rank 1 unless the config pins a bound, and labeled in whole\n // ranks. Few ranks are stepped one at a time when the config pins no\n // interval, so no tick falls between two ranks.\n private _rankAxisOptions(axis: ChartValueAxis | undefined, peak: number): Record<string, unknown> {\n const range = valueAxisRange(axis);\n const wholeSteps = range.interval === undefined && peak <= PPTX_RANK_WHOLE_STEP_PEAK;\n\n return {\n valAxisOrientation: 'maxMin',\n valAxisMinVal: range.min ?? RANK_AXIS_MIN,\n valAxisLabelFormatCode: PPTX_RANK_FORMAT_CODE,\n ...(wholeSteps ? { valAxisMajorUnit: 1 } : {}),\n };\n }\n\n // A horizontal bar chart reads top-down, first category at the top, as it\n // does on screen. PowerPoint draws category 0 next to the value axis, at the\n // bottom, so the category axis is reversed ('maxMin'); the value axis then\n // crosses at the last category ('max'), which now sits at the bottom, and\n // 'nextTo' keeps its labels on that line (pptxgenjs's default for a bar\n // direction, 'low', would follow the first category to the top). Only an\n // all-bar chart: a line or area is never drawn sideways.\n private _categoryOrderOptions(config: ChartConfig, types: string[]): Record<string, unknown> {\n if (config.orientation !== 'horizontal' || types.some((type) => type !== 'bar')) {\n return {};\n }\n\n return { catAxisOrientation: 'maxMin', catAxisCrossesAt: 'max', valAxisLabelPos: 'nextTo' };\n }\n\n // The value axis's number format code, matching the screen's ticks: with an\n // axis format (axisNumberFormat, or a waterfall's formatted measure) the\n // units and decimals the screen decides from the same peak; without one,\n // the code for the screen's plain ticks. The peak is the series' or the\n // furthest reference on the axis (reach), whichever is larger; the format\n // helpers read it off a one-point series.\n private _valueAxisCode(\n spec: NumberFormatSpec | null,\n values: (number | null)[][],\n stacked: boolean,\n context: ReportFormatContext,\n reach: number,\n ): string {\n const peak = Math.max(chartValuePeak(values, stacked), reach);\n const peakSeries = [[peak]];\n\n if (!spec) {\n return chartAxisFormatCode(peakSeries, false);\n }\n\n const chart = resolveChartNumberFormat(spec, peak, context);\n\n return numberFormatCode(spec, context, chart, peakSeries, false);\n }\n\n // One native chart when the plan is a single entry, its options laid over\n // the chart's. Otherwise pptxgenjs's multi-type chart, where every entry's\n // own options are laid over the chart's.\n private _addChart(\n slide: any,\n typeMap: Record<string, any>,\n entries: PptxEntry[],\n chartData: unknown[],\n options: Record<string, unknown>,\n ): void {\n if (entries.length === 1) {\n const entry = entries[0];\n slide.addChart(typeMap[entry.type], entry.indexes.map((index) => chartData[index]), { ...options, ...entry.options });\n\n return;\n }\n\n slide.addChart(entries.map((entry) => ({\n type: typeMap[entry.type],\n data: entry.indexes.map((index) => chartData[index]),\n options: entry.options,\n })), options);\n }\n\n // How a chart's series (dataTypes, one per chartData entry) are cut into\n // native charts, and the colors each draws in.\n //\n // A pie's slices and a colorBy chart's collapsed bars are one series colored\n // point by point, so their one entry keeps the whole palette. Every other\n // entry is handed exactly its own series' colors (seriesHex), so a lone bar\n // series is one color, as on screen, rather than a color per bar.\n //\n // Bars share one entry per value axis, since separate bar charts on one axis\n // overlap instead of clustering, and areas likewise, since they stack only\n // inside one area chart. Each line gets an entry of its own, so its line\n // options are its own. pptxgenjs colors a line by its place in its entry but\n // fills its markers by its place across every entry's data, and with a\n // random color past the end of the list, so a line's list is its one color\n // the whole length of the chart's data (totalData, which counts the\n // constant lines after the measures too).\n //\n // An entry on the second value axis (seriesAxisIndexes) plots against the\n // second value and category axes.\n //\n // A line entry draws its measure's line style (PPTX_LINE_DASH) and its\n // markers, or none. On a 100% stacked chart only the share entries stack;\n // a bar or area entry on the second axis is drawn side by side, as on\n // screen.\n //\n // A chart that plots a prior series colors it as the screen does\n // (priorStyles): in its current series' color, and dashed when it is a line\n // whose measure names no line style of its own.\n private _entryPlan(\n dataTypes: string[],\n extracted: ExtractedChartSeries,\n config: ChartConfig,\n axisIndexes: ValueAxisIndex[],\n shares: PercentShares | null,\n totalData: number,\n priorStyles: { colors: string[]; priors: boolean[] } | null,\n ): PptxEntry[] {\n const chartType = config.chartType ?? 'bar';\n if (chartType === 'pie' || chartType === 'donut' || isColorBy(config)) {\n return [{ type: dataTypes[0], indexes: [0], secondary: false, options: { chartColors: REPORT_CHART_COLORS } }];\n }\n\n const entries: PptxEntry[] = [];\n const perAxis = new Map<string, PptxEntry>();\n dataTypes.forEach((type, index) => {\n const secondary = axisIndexes[index] === 1;\n const key = `${type}-${secondary}`;\n let entry = type === 'line' ? undefined : perAxis.get(key);\n\n if (!entry) {\n entry = { type, indexes: [], secondary, options: {} };\n entries.push(entry);\n perAxis.set(key, entry);\n }\n\n entry.indexes.push(index);\n });\n\n const hex = (index: number) => {\n if (!extracted.series[index]) {\n return REPORT_CHART_COLORS[index % REPORT_CHART_COLORS.length];\n }\n\n return priorStyles?.colors[index] ?? seriesHex(extracted.series[index], index);\n };\n\n return entries.map((entry) => ({\n ...entry,\n options: {\n chartColors: entry.type === 'line'\n ? Array<string>(totalData).fill(hex(entry.indexes[0]))\n : entry.indexes.map(hex),\n ...(entry.type === 'line'\n ? this._lineOptions(extracted.series[entry.indexes[0]]?.measure, !!priorStyles?.priors[entry.indexes[0]])\n : {}),\n ...(shares && entry.type !== 'line' && !shares.has(entry.indexes[0])\n ? { barGrouping: entry.type === 'area' ? 'standard' : 'clustered' }\n : {}),\n ...(entry.secondary ? { secondaryValAxis: true, secondaryCatAxis: true } : {}),\n },\n }));\n }\n\n // Where a data label sits: PowerPoint's dLblPos code, or undefined to leave\n // it out (_withDataLabels says why).\n private _dataLabelPosition(type: string, stackedBar: boolean): string | undefined {\n if (type === 'line') {\n return 't';\n }\n\n return stackedBar ? 'ctr' : undefined;\n }\n\n // A line entry's dash and markers. A style PowerPoint has no dash for is\n // drawn solid, and a prior's line dashed unless its measure names a style.\n private _lineOptions(measure: ChartMeasure | undefined, prior = false): Record<string, unknown> {\n const style = measureLineStyle(measure) ?? (prior ? ReportChartLineStyle.Dashed : undefined);\n\n return {\n lineDash: style ? PPTX_LINE_DASH[style] : PPTX_LINE_DASH[ReportChartLineStyle.Solid],\n lineDataSymbol: measure?.markers === false ? 'none' : 'circle',\n lineDataSymbolSize: PPTX_LINE_SYMBOL_SIZE,\n };\n }\n\n // A waterfall is a stacked bar chart whose first series is invisible: it\n // lifts each bar to where its step starts. The series are cut differently\n // from the screen's; _waterfallSeries says why.\n private _renderWaterfall(\n pptx: any,\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = component.config as ChartConfig;\n const waterfall = extractWaterfall(component, data);\n const measure = config.measures?.[0];\n const labels = this._categoryLabels(\n waterfall.steps.map((step) => step.category),\n data.granularity,\n context.locale,\n chartDateLabel(config),\n );\n const series = this._waterfallSeries(waterfall.steps);\n // The references are constant lines beside the stacked bars, on the one\n // value axis. Without any the chart is the one stacked bar chart, without\n // a legend; with them the legend names them (_legendPosition), as it\n // alone can, beside the steps' kinds.\n const references = chartReferences(config, false);\n const constants = this._referenceLines(references);\n const legendPosition: LegendPosition = constants.length ? config.legend ?? PPTX_CONSTANT_LEGEND : 'hidden';\n const chartData = [\n ...series.map((entry) => ({ name: entry.name, labels, values: entry.values })),\n ...constants.map((line) => ({ name: line.name, labels, values: labels.map(() => line.value) })),\n ];\n const entries: PptxEntry[] = [\n {\n type: 'bar',\n indexes: series.map((_, index) => index),\n secondary: false,\n options: { chartColors: series.map((entry) => entry.color), barGrouping: 'stacked' },\n },\n ...constants.map((line, index) => this._constantEntry(line, series.length + index, chartData.length)),\n ];\n\n this._addChart(slide, { bar: pptx.ChartType.bar, line: pptx.ChartType.line }, entries, chartData, {\n x, y, w, h,\n showLegend: legendPosition !== 'hidden',\n legendPos: PPTX_LEGEND_POS[legendPosition],\n legendFontSize: 9,\n barDir: config.orientation === 'horizontal' ? 'bar' : 'col',\n ...this._axisTextOptions(config, data, false),\n ...BLANKS_AS_GAPS,\n // The axis spans the running total, so its peak is the furthest a step\n // ends from zero (or the furthest reference); the pieces it is cut into\n // never stack past that. The one measure's format writes it, as on\n // screen.\n valAxisLabelFormatCode: this._valueAxisCode(\n measure && hasNumberFormat(measure) ? measure : null,\n [waterfall.steps.map((step) => step.start + (step.change ?? 0))],\n false,\n context,\n referencePeak(references, 0),\n ),\n ...this._categoryOrderOptions(config, ['bar']),\n // A running total can go below zero, where the category axis crosses;\n // its labels stay at the plot's edge instead of across the bars.\n catAxisLabelPos: 'low',\n });\n }\n\n // PowerPoint stacks positive and negative values apart, each from zero, so a\n // bar cannot simply sit on the total before it the way it does on screen.\n // Each step is cut at zero instead: the invisible base carries it to its end\n // nearer zero, and its kind's series carries the rest — one series above zero\n // and one below, because a step that crosses zero needs both. Every other\n // point is left blank: a zero there would still draw a zero-height bar, which\n // renders as a hairline. A kind's series that stays blank is dropped.\n private _waterfallSeries(steps: WaterfallStep[]): PptxChartSeries[] {\n const base: PptxChartSeries = { name: '', color: 'transparent', values: [] };\n const kinds = Object.keys(WATERFALL_SERIES_NAMES) as WaterfallStepKind[];\n const piece = (kind: WaterfallStepKind) => ({\n kind, name: WATERFALL_SERIES_NAMES[kind], color: REPORT_WATERFALL_COLORS[kind], values: [] as (number | null)[],\n });\n const above = kinds.map(piece);\n const below = kinds.map(piece);\n const blankZero = (value: number) => (value === 0 ? null : value);\n\n for (const step of steps) {\n const end = step.start + (step.change ?? 0);\n const low = Math.min(step.start, end);\n const high = Math.max(step.start, end);\n\n base.values.push(blankZero(low > 0 ? low : (high < 0 ? high : 0)));\n above.forEach((entry) => entry.values.push(\n entry.kind === step.kind ? blankZero(Math.max(high, 0) - Math.max(low, 0)) : null,\n ));\n below.forEach((entry) => entry.values.push(\n entry.kind === step.kind ? blankZero(Math.min(low, 0) - Math.min(high, 0)) : null,\n ));\n }\n\n return [base, ...[...above, ...below].filter((entry) => entry.values.some((value) => value !== null))];\n }\n\n // Compact period labels match the on-screen axis, in the report's locale and\n // the axis's date label style (a short label takes its year only when the\n // data spans years); PowerPoint can't do a styled second line, so it's\n // inline.\n private _categoryLabels(\n categories: string[],\n granularity: ChartGranularity | null | undefined,\n locale: ReportLocaleTag,\n dateLabel: ReportChartDateLabel,\n ): string[] {\n if (!granularity) {\n return categories;\n }\n\n const multiYear = spansMultipleYears(categories);\n\n return categories.map((category) => formatPeriodLabel(category, granularity, multiYear, locale, dateLabel));\n }\n\n // The axis label and title settings of a chart with one value axis, and that\n // axis's range (valueAxis). A pie has no value axis to title. Without a\n // valueAxis.label the value axis is titled by the first measure's label, as\n // decks always have been; the screen shows only an explicit title. An\n // explicit empty label suppresses that fallback, as it does on screen, and\n // a 100% stacked chart's share axis is never titled with one series' name.\n private _axisTextOptions(config: ChartConfig, data: ComponentData, pie: boolean): Record<string, unknown> {\n return {\n ...AXIS_FONT_SIZES,\n ...this._categoryTitleOptions(config, data),\n ...(pie\n ? { showValAxisTitle: false }\n : this._valueAxisRangeOptions(\n config.valueAxis,\n config.valueAxis?.label ?? (config.percentStacked === true ? undefined : config.measures?.[0]?.label),\n )),\n };\n }\n\n // The category axis's title, as the screen and the PDF name it\n // (categoryAxisTitle): a drilled chart's axis names the level it was read\n // at, else the authored title.\n private _categoryTitleOptions(config: ChartConfig, data: ComponentData): Record<string, unknown> {\n const title = categoryAxisTitle(config, data);\n\n return {\n showCatAxisTitle: !!title,\n catAxisTitle: title,\n catAxisTitleFontSize: 10,\n };\n }\n\n // One value axis's title and the range the config pins (valueAxisRange, as\n // on screen). Every key is set, even when empty, so on a two-axis chart\n // nothing is inherited from the chart's options.\n private _valueAxisRangeOptions(axis: ChartValueAxis | undefined, title: string | undefined): Record<string, unknown> {\n const range = valueAxisRange(axis);\n\n return {\n showValAxisTitle: !!title,\n valAxisTitle: title || undefined,\n valAxisMinVal: range.min,\n valAxisMaxVal: range.max,\n valAxisMajorUnit: range.interval,\n };\n }\n\n // A list's table, without the columns the viewer hid. A totals row closes\n // it, bold on the border gray, in a row kept free for it.\n private _renderTable(\n slide: any,\n component: ReportComponent,\n data: ComponentData,\n hiddenColumns: readonly string[],\n timezone: string,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const columns = listColumns(component, data, context.locale, hiddenColumns);\n const totals = listTotalsRow(data, columns, timezone, context);\n\n const cap = Math.max(2, Math.floor(h / SLIDE_ROW_H) - 1 - (totals ? 1 : 0));\n const rows = data.rows.slice(0, cap);\n const remaining = (data.paging?.total ?? data.rows.length) - rows.length;\n\n // A column of formatted numbers is right-aligned, its heading too, as on\n // screen.\n const align = (index: number) => (columns[index]?.numeric ? { align: 'right' } : {});\n\n const header = listHeadings(component, data, context.locale, hiddenColumns).map((heading, index) => ({\n text: heading,\n options: { bold: true, color: 'FFFFFF', fill: { color: '4E79A7' }, ...align(index) },\n }));\n\n // A date or formatted-number cell is a value written in the report's\n // locale; every other cell prints the query's text as it came.\n const valueLocale = (index: number) => {\n const column = columns[index];\n\n return column.numeric || column.format === ReportListColumnFormat.Date ? context.locale : undefined;\n };\n\n const body = rows.map((row) => columns.map((column, index) => ({\n text: exportCell(row[column.column], column, timezone, context, row),\n options: pptxRunOptions(align(index), valueLocale(index)),\n })));\n\n if (remaining > 0) {\n body.push([{\n text: moreRowsNotice(remaining),\n options: { colspan: columns.length, italic: true, color: MUTED_COLOR } as any,\n }]);\n }\n\n // The label is interface text, so it keeps the default proofing language.\n if (totals) {\n const labelColumn = listTotalsLabelColumn(columns, data.totals);\n\n body.push(totals.map((text, index) => ({\n text,\n options: pptxRunOptions(\n { bold: true, fill: { color: 'E4E7EB' }, ...align(index) },\n columns[index].column === labelColumn ? undefined : valueLocale(index),\n ),\n })));\n }\n\n slide.addTable([header, ...body], {\n x, y, w,\n fontSize: 9,\n color: '1F2933',\n border: { type: 'solid', pt: 0.5, color: 'E4E7EB' },\n autoPage: false,\n rowH: SLIDE_ROW_H,\n valign: 'middle',\n });\n }\n\n // A table tile as a native table (gridExportTable()): its heading rows\n // spanned as the screen's header, as many lines as the box holds (groups\n // and totals bold, a group's label stepped in by its depth), the\n // moreRowsNotice row for the rest and the total row. A number is written\n // in the report's locale.\n private _renderGridTable(\n slide: any,\n item: CollectedComponent,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const table = gridExportTable(item.table!);\n const cell = (exported: GridExportCell, options: Record<string, unknown> = {}) => ({\n text: `${GRID_INDENT.repeat(exported.indent)}${exported.text}`,\n options: pptxRunOptions({\n ...(exported.colSpan > 1 ? { colspan: exported.colSpan } : {}),\n ...(exported.rowSpan > 1 ? { rowspan: exported.rowSpan } : {}),\n ...(exported.bold ? { bold: true } : {}),\n ...(exported.numeric ? { align: 'right' } : {}),\n ...options,\n }, exported.numeric ? context.locale : undefined),\n });\n const cap = Math.max(1, Math.floor(h / SLIDE_ROW_H) - table.head.length - (table.foot ? 1 : 0));\n const lines = table.body.slice(0, cap);\n const remaining = table.body.length - lines.length + table.moreRows;\n\n slide.addTable([\n ...table.head.map((row) => row.map((heading) => cell(heading, { color: 'FFFFFF', fill: { color: '4E79A7' } }))),\n ...lines.map((row) => row.map((line) => cell(line))),\n ...(remaining > 0\n ? [[{ text: moreRowsNotice(remaining), options: { colspan: table.numeric.length, italic: true, color: MUTED_COLOR } }]]\n : []),\n ...(table.foot ? [table.foot.map((total) => cell(total, { bold: true, fill: { color: 'E4E7EB' } }))] : []),\n ], {\n x, y, w,\n fontSize: 9,\n color: '1F2933',\n border: { type: 'solid', pt: 0.5, color: 'E4E7EB' },\n autoPage: false,\n rowH: SLIDE_ROW_H,\n valign: 'middle',\n });\n }\n\n // A KPI tile: the card the screen draws (kpi-card.ts decides every line),\n // as native text boxes and shapes stacked and centered in the body. A card\n // with only its value and label keeps the tile's long-standing single text\n // box.\n private _renderKpi(\n pptx: any,\n slide: any,\n item: CollectedComponent,\n timezone: string,\n context: ReportFormatContext,\n x: number, y: number, w: number, h: number,\n ): void {\n const config = item.component.config as KpiConfig;\n const view = kpiCardView(config, item.data, { format: context, timezone });\n const notes = exportNoteLines(item, timezone, context.locale);\n\n if (!kpiCardHasExtras(view, notes)) {\n slide.addText([\n {\n text: view.value,\n options: pptxRunOptions({ fontSize: 28, bold: true, color: '1F2933', breakLine: true }, context.locale),\n },\n { text: view.label, options: { fontSize: 10, color: MUTED_COLOR } },\n ], {\n x, y, w, h,\n align: 'center',\n valign: 'middle',\n });\n\n return;\n }\n\n // A tile too short for the card's lines shrinks them all alike.\n const parts = kpiExportParts(view, notes, h, KPI_HEIGHTS);\n const heights = scaledKpiHeights(KPI_HEIGHTS, parts.scale);\n const lineFontSize = KPI_LINE_FONT_SIZE * parts.scale;\n let top = y + Math.max(0, (h - kpiExportHeight(view, parts, heights)) / 2);\n const line = (runs: any[] | string, rowH: number, options: Record<string, unknown>) => {\n slide.addText(runs, {\n x, y: top, w, h: rowH,\n align: 'center', valign: 'middle', margin: 0, fit: 'none', ...options,\n });\n top += rowH;\n };\n\n line(\n [{ text: view.value, options: pptxRunOptions({ bold: true, color: '1F2933' }, context.locale) }],\n heights.value,\n { fontSize: 28 * parts.scale },\n );\n\n if (view.label) {\n line(view.label, heights.label, { fontSize: 10 * parts.scale, color: MUTED_COLOR });\n }\n\n if (parts.delta && view.delta) {\n this._kpiDelta(pptx, slide, view.delta, context, x, top, w, parts.scale);\n top += heights.delta;\n }\n\n if (parts.window) {\n const days = this._fitEstimate(view.window, lineFontSize, w);\n\n line([{ text: days, options: pptxRunOptions({}, context.locale) }], heights.window, {\n fontSize: lineFontSize, color: MUTED_COLOR,\n });\n }\n\n if (parts.target && view.target) {\n this._kpiTarget(pptx, slide, view.target, x, top, w);\n top += heights.target;\n }\n\n if (parts.sparkline && view.sparkline) {\n this._kpiSparkline(pptx, slide, item, view.sparkline.values, view.label, x, top, w);\n top += heights.sparkline;\n }\n\n if (parts.notes.length) {\n const fitted = parts.notes.map((note) => this._fitEstimate(note, SMALL_FONT_SIZE, w));\n\n line(this._lineRuns(fitted, { italic: true }), parts.notes.length * heights.note, {\n fontSize: SMALL_FONT_SIZE, color: MUTED_COLOR,\n });\n }\n }\n\n // The delta row: the change in the color of what it means and what it is\n // compared with in grey, as one centered text box, with a triangle beside\n // it pointing the way the value moved (none when the shown change rounds to\n // zero). PowerPoint lays the text out itself, so the triangle sits where\n // the text's estimated width puts its start.\n private _kpiDelta(\n pptx: any,\n slide: any,\n delta: KpiCardDelta,\n context: ReportFormatContext,\n x: number, top: number, w: number,\n scale = 1,\n ): void {\n const color = REPORT_KPI_CHANGE_COLORS[delta.tone];\n const fontSize = KPI_LINE_FONT_SIZE * scale;\n const rowH = KPI_HEIGHTS.delta * scale;\n const side = KPI_ARROW * scale;\n const arrow = delta.trend === ReportKpiTrend.Flat ? 0 : side + KPI_ARROW_GAP * scale;\n const changeW = this._estimatedWidth(delta.text, fontSize);\n const compared = delta.compared\n ? this._fitEstimate(` ${delta.compared}`, fontSize, w - arrow - changeW)\n : '';\n const textW = Math.min(w - arrow, changeW + this._estimatedWidth(compared, fontSize));\n const runs = [\n { text: delta.text, options: pptxRunOptions({ bold: true, color }, context.locale) },\n ...(compared ? [{ text: compared, options: { color: MUTED_COLOR } }] : []),\n ];\n\n slide.addText(runs, {\n x: x + arrow, y: top, w: Math.max(0.1, w - arrow), h: rowH,\n fontSize, align: 'center', valign: 'middle', margin: 0, fit: 'none',\n });\n\n if (arrow) {\n slide.addShape(pptx.ShapeType.triangle, {\n x: Math.max(x, x + (w - arrow - textW) / 2),\n y: top + (rowH - side) / 2,\n w: side,\n h: side,\n fill: { color },\n line: { color, width: 0 },\n flipV: delta.trend === ReportKpiTrend.Down,\n });\n }\n }\n\n // About how wide a line of text runs, inches: PowerPoint lays it out, so\n // only an estimate from its average character width is to hand.\n private _estimatedWidth(text: string, fontSize: number): number {\n return text.length * fontSize * PPTX_CHAR_WIDTH / 72;\n }\n\n // The text cut with an ellipsis to about the width, so a line that would\n // wrap past its row stays one line.\n private _fitEstimate(text: string, fontSize: number, width: number): string {\n if (this._estimatedWidth(text, fontSize) <= width) {\n return text;\n }\n\n const chars = Math.max(0, Math.floor(width * 72 / (fontSize * PPTX_CHAR_WIDTH)) - 1);\n\n return chars ? `${text.slice(0, chars).trimEnd()}…` : '';\n }\n\n // The target line ('Goal: $1,000 · 56% of target') and, when the server sent\n // the progress, a bar filled that far: green once the target is met.\n private _kpiTarget(pptx: any, slide: any, target: KpiCardTarget, x: number, top: number, w: number): void {\n const text = target.progress ? `${target.text} · ${target.progress}` : target.text;\n\n slide.addText(this._fitEstimate(text, KPI_LINE_FONT_SIZE, w), {\n x, y: top, w, h: KPI_TARGET_TEXT_H,\n fontSize: KPI_LINE_FONT_SIZE, color: MUTED_COLOR, align: 'center', valign: 'middle', margin: 0, fit: 'none',\n });\n\n if (target.fill === null) {\n return;\n }\n\n const barW = Math.min(w * 0.6, KPI_BAR_W);\n const barX = x + (w - barW) / 2;\n const barY = top + KPI_TARGET_TEXT_H + KPI_BAR_GAP;\n const bar = (width: number, color: string) => slide.addShape(pptx.ShapeType.rect, {\n x: barX, y: barY, w: width, h: KPI_BAR_H, fill: { color }, line: { color, width: 0 },\n });\n\n bar(barW, KPI_TRACK_COLOR);\n\n if (target.fill > 0) {\n bar(barW * target.fill, REPORT_KPI_CHANGE_COLORS[target.tone]);\n }\n }\n\n // The sparkline as a native line chart with its axes, gridlines and legend\n // hidden, scaled from its lowest value to its highest as on screen, its\n // periods and values in the chart's data sheet. A gap stays a gap. Markers\n // show only when a value stands alone between gaps (the last one too),\n // which a line cannot draw.\n private _kpiSparkline(\n pptx: any,\n slide: any,\n item: CollectedComponent,\n values: (number | null)[],\n label: string,\n x: number, top: number, w: number,\n ): void {\n const numbers = values.filter((value): value is number => value !== null);\n const low = Math.min(...numbers);\n const high = Math.max(...numbers);\n const pad = high === low ? Math.max(1, Math.abs(high)) : 0;\n const boxW = Math.min(w * 0.7, KPI_SPARKLINE_W);\n const geometry = kpiSparklineGeometry(values, false);\n // kpiSparklineGeometry keeps the last point out of the dots, as the\n // screen marks it apart; a last value after a gap is a lone point too.\n const lastStandsAlone = values[values.length - 1] !== null\n && (values.length === 1 || values[values.length - 2] === null);\n const periods = item.data?.kpi?.sparkline?.points?.map((point) => point.period) ?? [];\n const color = REPORT_KPI_SPARKLINE_COLOR;\n\n this._addChart(slide, { line: pptx.ChartType.line }, [{\n type: 'line',\n indexes: [0],\n secondary: false,\n options: {\n chartColors: [color],\n lineSize: 1.5,\n lineDataSymbol: geometry.dots.length || lastStandsAlone ? 'circle' : 'none',\n lineDataSymbolSize: 4,\n },\n }], [{\n name: label || KPI_SPARKLINE_NAME,\n labels: values.map((_, index) => periods[index] ?? String(index + 1)),\n values,\n }], {\n x: x + (w - boxW) / 2, y: top, w: boxW, h: KPI_HEIGHTS.sparkline,\n showLegend: false,\n showTitle: false,\n catAxisHidden: true,\n valAxisHidden: true,\n catAxisLineShow: false,\n valAxisLineShow: false,\n showCatAxisTitle: false,\n showValAxisTitle: false,\n valGridLine: { style: 'none' },\n catGridLine: { style: 'none' },\n valAxisMinVal: low - pad,\n valAxisMaxVal: high + pad,\n ...BLANKS_AS_GAPS,\n });\n }\n\n private _slug(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '') || 'report';\n }\n}\n\n// Gives a text table's cell the grid slots it covers from its top left: as\n// many columns as are free in its top row, and as many rows down as are free\n// across those columns, at most its own spans. A slot is free until a cell\n// placed before it holds it, and the grid holds only the kept rows. So a span\n// the box cuts ends at the last kept row, and one the html makes overlap\n// another cell (which a browser draws on top of it) ends where they meet.\nfunction claimSlots(slots: (TextTableCell | null)[][], cell: TextTableCell): void {\n const free = (row: number, column: number) => row < slots.length && column < slots[row].length && !slots[row][column];\n const columns = (count: number) => Array.from({ length: count }, (_, offset) => cell.column + offset);\n let colSpan = 0;\n let rowSpan = 0;\n\n while (colSpan < cell.colSpan && free(cell.row, cell.column + colSpan)) {\n colSpan++;\n }\n while (colSpan && rowSpan < cell.rowSpan && columns(colSpan).every((column) => free(cell.row + rowSpan, column))) {\n rowSpan++;\n }\n\n const claimed = { ...cell, colSpan, rowSpan };\n for (let row = cell.row; row < cell.row + rowSpan; row++) {\n slots[row].fill(claimed, cell.column, cell.column + colSpan);\n }\n}\n","import { Injectable, inject } from '@angular/core';\n\nimport { FsPrompt } from '@firestitch/prompt';\n\nimport { EMPTY, Observable, from, of } from 'rxjs';\nimport { catchError, switchMap } from 'rxjs/operators';\n\nimport { Report } from '../interfaces/report.interface';\nimport { escapeHtml } from '../text';\nimport {\n BuiltExport, CollectedReport, ReportExportCollectorService, failedPageNames,\n} from './report-export-collector.service';\nimport { PDF_LIST_ROWS, ReportPdfService } from './report-pdf.service';\nimport { PPTX_LIST_ROWS, ReportPptxService } from './report-pptx.service';\n\n\n// What the user chose at an export gate. Retry, offered only when the export\n// is incomplete, re-runs the whole collection — the queries that failed were\n// killed on a clock, not on anything about the data, so a second attempt\n// against a warmed database genuinely often succeeds. Download keeps going.\nconst RETRY = 'retry';\nconst DOWNLOAD = 'download';\n\n// Runs a report export end to end: collect every tile and value, refuse to\n// write a file that is missing any of them without saying so, build it, refuse\n// to save one that could not draw a component, or whose text does not fit its\n// boxes, without saying so, then save.\n//\n// The gates are the reason this sits between the collector and the renderers\n// rather than in either of them. A deck with five blank pages is worse than no\n// deck: it looks finished, so it gets emailed to a client, and the pages that\n// are missing are exactly the ones nobody thinks to check. The renderers can\n// only describe a hole they are handed; the collector only knows one tile at a\n// time. Whether the FILE should exist is a decision about the whole report, and\n// this is the only place that sees it.\n//\n// Failures are decided before the build, which is the expensive part (every\n// chart drawn offscreen, every text block measured), so neither a Retry nor a\n// Cancel pays for one. Text that does not fit its box is known only after it:\n// the build is what measures it.\n@Injectable()\nexport class ReportExportService {\n\n private _collector = inject(ReportExportCollectorService);\n private _pdfService = inject(ReportPdfService);\n private _pptxService = inject(ReportPptxService);\n private _prompt = inject(FsPrompt);\n\n public pdf(report: Report): Observable<unknown> {\n return this._run(report, PDF_LIST_ROWS, (collected) => this._pdfService.build(collected));\n }\n\n public powerpoint(report: Report): Observable<unknown> {\n return this._run(report, PPTX_LIST_ROWS, (collected) => this._pptxService.build(collected));\n }\n\n // Retry re-collects the WHOLE report, not just the tiles that failed. Every\n // number in one file has to have been true at one moment: refetching four\n // tiles and keeping nine from three minutes ago produces a deck whose pages\n // disagree with each other, and nothing on it would say so.\n //\n // listRows is the format's own list cap, carried into the retry so a second\n // attempt fetches what the first did.\n private _run(\n report: Report,\n listRows: number,\n build: (collected: CollectedReport) => Promise<BuiltExport>,\n ): Observable<unknown> {\n return this._collector.collect(report, listRows)\n .pipe(\n switchMap((collected) => this._failureGate(collected)\n .pipe(\n switchMap((choice) => choice === RETRY\n ? this._run(report, listRows, build)\n : this._buildAndSave(collected, build)),\n )),\n );\n }\n\n // Builds the file, then saves it once the undrawn and overflow gates let it\n // through.\n private _buildAndSave(\n collected: CollectedReport,\n build: (collected: CollectedReport) => Promise<BuiltExport>,\n ): Observable<unknown> {\n return from(build(collected))\n .pipe(\n switchMap((built) => this._undrawnGate(built)\n .pipe(\n switchMap(() => this._overflowGate(built)),\n switchMap(() => from(Promise.resolve(built.save()))),\n )),\n );\n }\n\n // Resolves to DOWNLOAD when the export is whole (or the user accepted an\n // incomplete one) and to RETRY when they want another attempt. Cancelling\n // ends the export quietly: EMPTY completes without emitting, so nothing\n // builds and no error surfaces — they know what they just declined.\n private _failureGate(collected: CollectedReport): Observable<string> {\n const failed = failedPageNames(collected).map(escapeHtml);\n if (!failed.length) {\n return of(DOWNLOAD);\n }\n\n const pages = failed.length === 1\n ? `<strong>${failed[0]}</strong> could not be generated`\n : `${failed.length} pages could not be generated: <strong>${failed.join('</strong>, <strong>')}</strong>`;\n\n return this._prompt.confirm({\n title: 'Export is incomplete',\n template: `${pages}. This usually means those tiles or values took too long to load. `\n + 'Retry, or download the file with those pages marked as missing.',\n buttons: [\n { label: 'Retry', value: RETRY, color: 'primary' },\n { label: 'Download Anyway', value: DOWNLOAD, color: '' },\n { label: 'Cancel', cancel: true, color: '' },\n ],\n })\n .pipe(catchError(() => EMPTY));\n }\n\n // Resolves to DOWNLOAD when the build drew every component, or the user\n // accepted a file that marks the ones it could not in their place. There is\n // no Retry: a second build draws the same data the same way. Each component\n // is named by its page and its title (a text block by the start of its\n // words). Cancelling ends the export quietly, as at the failure gate, and\n // the built file is dropped unsaved.\n private _undrawnGate(built: BuiltExport): Observable<string> {\n if (!built.undrawn.length) {\n return of(DOWNLOAD);\n }\n\n const components = built.undrawn\n .map((undrawn) => `<strong>${escapeHtml(undrawn.page)}</strong>`\n + (undrawn.name ? ` (“${escapeHtml(undrawn.name)}”)` : ''));\n\n return this._prompt.confirm({\n title: 'Some tiles could not be drawn',\n template: `Some tiles could not be drawn: ${components.join(', ')}. `\n + 'The file says \"Could not be drawn\" in their place.',\n buttons: [\n { label: 'Download Anyway', value: DOWNLOAD, color: 'primary' },\n { label: 'Cancel', cancel: true, color: '' },\n ],\n })\n .pipe(catchError(() => EMPTY));\n }\n\n // Resolves to DOWNLOAD when every text block fits its box in the built file,\n // or the user accepted one that does not. There is no Retry: the words are\n // the report's own, so a second attempt would build the same file. Each block\n // is named by its page and the start of its words, and the note says what\n // this format does with the rest. Cancelling ends the export quietly, as at\n // the failure gate, and the built file is dropped unsaved.\n private _overflowGate(built: BuiltExport): Observable<string> {\n if (!built.overflows.length) {\n return of(DOWNLOAD);\n }\n\n // A block with no words to quote (an empty table, say) is named by its\n // page alone, not by an empty pair of quotes.\n const blocks = built.overflows\n .map((overflow) => `<strong>${escapeHtml(overflow.page)}</strong>`\n + (overflow.snippet ? ` (“${escapeHtml(overflow.snippet)}”)` : ''));\n\n return this._prompt.confirm({\n title: 'Text does not fit',\n template: `Some text does not fit its box: ${blocks.join(', ')}. ${built.overflowNote}`,\n buttons: [\n { label: 'Download Anyway', value: DOWNLOAD, color: 'primary' },\n { label: 'Cancel', cancel: true, color: '' },\n ],\n })\n .pipe(catchError(() => EMPTY));\n }\n}\n","// The parts of the chat's viewer state (ReportChatViewerState) read off a\n// snapshot of the screen (the state service's snapshot()) and the report on\n// it. Pure, so the node harness checks them. The caps are the server's: it\n// reads at most CHAT_DRILLS_MAX drilled charts, DRILL_MAX_DEPTH steps a path\n// and CHAT_LABEL_MAX characters a label, and drops the rest. A table's\n// layout is never cut: the server reads it whole, up to the grid's limits.\nimport { GridLayout } from '@firestitch/grid';\n\nimport { drillStepLabel } from './drill-crumbs';\nimport { ReportChatViewerDrill } from './interfaces/report-chat-viewer-drill.interface';\nimport { ReportChatViewerState } from './interfaces/report-chat-viewer-state.interface';\nimport { ReportChatViewerTile } from './interfaces/report-chat-viewer-tile.interface';\nimport { ReportStateSnapshot } from './interfaces/report-state-snapshot.interface';\nimport { Report, ReportComponent, ReportLocaleTag } from './interfaces/report.interface';\nimport { DRILL_MAX_DEPTH } from './report-state';\n\n\nexport const CHAT_DRILLS_MAX = 10;\nexport const CHAT_LABEL_MAX = 100;\n\n\n// The match the chat is told of: 'any' while the groups match any filter.\n// 'all' is the default and is left out.\nexport function chatViewerMatch(snapshot: ReportStateSnapshot): Pick<ReportChatViewerState, 'match'> {\n return snapshot.match === 'any' ? { match: 'any' } : {};\n}\n\n\n// Each drilled chart of the snapshot, in component id order (ids as object\n// keys always come in ascending order), with its path top first and each\n// step labeled as the breadcrumb labels it (drillStepLabel), in the report's\n// locale and with its year ('Q3 2026'), so a step reads the same on its own.\n// Empty when nothing is drilled.\nexport function chatViewerDrills(snapshot: ReportStateSnapshot, locale: ReportLocaleTag): ReportChatViewerDrill[] {\n return Object.entries(snapshot.tiles ?? {})\n .filter(([, tile]) => !!tile?.drill?.length)\n .slice(0, CHAT_DRILLS_MAX)\n .map(([componentId, tile]) => ({\n componentId: Number(componentId),\n path: (tile.drill ?? [])\n .slice(0, DRILL_MAX_DEPTH)\n .map((step) => ({\n level: step.level,\n label: [...drillStepLabel(step, locale)].slice(0, CHAT_LABEL_MAX).join(''),\n })),\n }));\n}\n\n\n// Every table tile on screen while `pageId` is the page on screen: the\n// page's own, then the header and footer's unless the page hides them, each\n// with the layout the viewer has it in (layoutOf; null while it shows the\n// stored layout, and then left out). Empty when the page is unknown or holds\n// no table.\nexport function chatViewerTiles(\n report: Report | null,\n pageId: number | null,\n layoutOf: (component: ReportComponent) => GridLayout | null,\n): ReportChatViewerTile[] {\n const page = (report?.pages ?? []).find((item) => item.id === pageId);\n if (!report || !page) {\n return [];\n }\n\n return [\n ...(page.components ?? []),\n ...(page.masterHidden ? [] : report.master?.components ?? []),\n ]\n .filter((component) => component.type === 'grid')\n .map((component) => {\n const layout = layoutOf(component);\n\n return layout ? { componentId: component.id, layout } : { componentId: component.id };\n });\n}\n","import { Provider } from '@angular/core';\n\nimport { FS_DATEPICKER_CONFIG, FS_DATEPICKER_CONFIG_DEFAULT, IFsDatePickerConfig } from '@firestitch/datepicker';\n\nimport { REPORT_WEEK_STARTS_ON } from './consts/report-week.const';\n\n\n// The date picker config of a report view: its weeks start on Monday, as the\n// server's weeks do, and its range pickers list the date picker's built-in\n// presets (Today, Last 7 days, This month, ...). The report adds none of its\n// own: the built-in list covers every period a report filter names. A preset\n// is a shortcut only: picking one sets the range's two days, which is all the\n// bar and a saved filter hold. Provided on the view; the host app's\n// own pickers keep their config.\nexport function provideReportDatePicker(): Provider {\n const config: IFsDatePickerConfig = {\n ...FS_DATEPICKER_CONFIG_DEFAULT,\n weekStartsOn: REPORT_WEEK_STARTS_ON,\n preset: true,\n };\n\n return { provide: FS_DATEPICKER_CONFIG, useValue: config };\n}\n","// The report bar's saved filters (@firestitch/filter's savedFilters): what a\n// saved filter holds, and how its values are read back. Pure, so the node\n// harness checks them.\n//\n// A saved filter holds the values of the report-wide filters only (level\n// report or both: the ones the bar shows on every page), keyed by their\n// item names (groupItemName). A page's own filters, the group-by grain, the\n// match, list sorts, searches, hidden columns, the page and drill paths are\n// never part of it. The same rule cleans what is saved and what is read\n// back, so a key the report no longer has a report-wide filter for, or a\n// value its filter can no longer take, is left out rather than applied.\nimport { FilterGroupValue, ReportFilterGroup } from './interfaces/report.interface';\nimport { dateBoundString, groupItemName } from './report-filter-items';\nimport { finiteNumber } from './report-state';\n\n\n// The groups a saved filter holds: the report-wide ones.\nexport function savedFilterGroups(groups: readonly ReportFilterGroup[] | null | undefined): ReportFilterGroup[] {\n return (groups ?? []).filter((group) => group.level === 'report' || group.level === 'both');\n}\n\n// A saved filter's values kept to `groups` (savedFilterGroups): each\n// report-wide group's item value, in a shape its item takes, a date range's\n// days as yyyy-MM-dd (a day is the same day in every zone, so everyone who\n// picks a shared filter gets the same days). Any other key is left out, and\n// so is a value that holds nothing or does not fit its group's type.\nexport function savedFilterValues(\n filters: Record<string, unknown> | null | undefined,\n groups: readonly ReportFilterGroup[],\n): Record<string, unknown> {\n const kept: Record<string, unknown> = {};\n\n groups.forEach((group) => {\n const name = groupItemName(group);\n const value = filters && Object.prototype.hasOwnProperty.call(filters, name)\n ? itemValue(group, filters[name])\n : null;\n\n if (value !== null) {\n kept[name] = value;\n }\n });\n\n return kept;\n}\n\n// One item value as a saved filter keeps it, or null.\nfunction itemValue(group: ReportFilterGroup, value: unknown): unknown {\n switch (group.type) {\n case 'dateRange':\n return dateRangeValue(value);\n\n case 'select':\n return selectValue(value);\n\n case 'numberRange':\n // A number range shows as a keyword box where the server does not\n // serve numberRange, and its item then holds text.\n return isPlainObject(value) ? rangeValue(value) : textValue(value);\n\n default:\n return textValue(value);\n }\n}\n\n// A date range item's { from, to }, each end a calendar day.\nfunction dateRangeValue(value: unknown): Record<string, string> | null {\n if (!isPlainObject(value)) {\n return null;\n }\n\n const from = dayText(value.from);\n const to = dayText(value.to);\n\n if (!from && !to) {\n return null;\n }\n\n return { ...(from ? { from } : {}), ...(to ? { to } : {}) };\n}\n\n// A select item's picks ({ name, value } pairs), or its left-out picks\n// ({ exclude: true, selected }).\nfunction selectValue(value: unknown): unknown {\n if (isPlainObject(value)) {\n const selected = picks(value.selected);\n\n return selected ? { exclude: value.exclude === true, selected } : null;\n }\n\n return picks(value);\n}\n\n// A range item's { min, max }; either end may be open, and 0 is an end.\nfunction rangeValue(value: Record<string, unknown>): Pick<FilterGroupValue, 'min' | 'max'> | null {\n const min = finiteNumber(value.min);\n const max = finiteNumber(value.max);\n\n if (min === undefined && max === undefined) {\n return null;\n }\n\n return { ...(min !== undefined ? { min } : {}), ...(max !== undefined ? { max } : {}) };\n}\n\nfunction textValue(value: unknown): string | null {\n const text = typeof value === 'string' || typeof value === 'number' ? String(value).trim() : '';\n\n return text || null;\n}\n\n// The picks of a select item that name a value, or null when none does.\nfunction picks(value: unknown): Record<string, unknown>[] | null {\n const kept = (Array.isArray(value) ? value : [])\n .filter((pick): pick is Record<string, unknown> => isPlainObject(pick)\n && pick.value !== null && pick.value !== undefined && pick.value !== '');\n\n return kept.length ? kept : null;\n}\n\n// A day as yyyy-MM-dd: a Date's local day, or the first ten characters of a\n// day already written as text. Null for anything else.\nfunction dayText(value: unknown): string | null {\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? null : dateBoundString(value) ?? null;\n }\n\n return typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(value) ? value.slice(0, 10) : null;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date);\n}\n","import {\n CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component,\n DestroyRef, ElementRef, NgZone, ViewChild, computed, effect, inject, input, output, signal, untracked,\n} from '@angular/core';\nimport { HttpContext } from '@angular/common/http';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialog } from '@angular/material/dialog';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\n\nimport { DisplayApiError } from '@firestitch/api';\nimport {\n BaseItem, FilterComponent, FilterConfig, FsFilterModule, IFilterConfigItem, IFilterSavedFilter, IFilterSavedFiltersConfig,\n} from '@firestitch/filter';\nimport { FsMenuModule } from '@firestitch/menu';\nimport { FsProcess } from '@firestitch/process';\n\nimport { of } from 'rxjs';\nimport { catchError, map, switchMap, takeUntil, tap } from 'rxjs/operators';\n\nimport { provideEchartsCore } from 'ngx-echarts';\n\nimport { FsAiChatComponent, FsAiChatData, FsAiChatResponse } from '@firestitch/ai';\n\nimport { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';\nimport { ReportAiChatData } from '../../data/report-ai-chat.data';\nimport { ReportData } from '../../data/report.data';\nimport {\n ComponentSettingsComponent, ComponentSettingsDialogData, ComponentSettingsResult,\n} from '../../dialogs/component-settings/component-settings.component';\nimport { ReportSettingsComponent, ReportSettingsResult } from '../../dialogs/report-settings/report-settings.component';\nimport { ReportExportCollectorService } from '../../export/report-export-collector.service';\nimport { ReportExportService } from '../../export/report-export.service';\nimport { ReportPdfService } from '../../export/report-pdf.service';\nimport { ReportPptxService } from '../../export/report-pptx.service';\nimport { ReportTextLayoutService } from '../../export/report-text-layout.service';\nimport { ReportChatViewerState } from '../../interfaces/report-chat-viewer-state.interface';\nimport { ReportSavedFilter } from '../../interfaces/report-saved-filter.interface';\nimport {\n ChartGranularity, Report, ReportChatResponse,\n ReportComponent as ReportComponentModel, ReportFilterGroup,\n} from '../../interfaces/report.interface';\nimport { ReportExportFormat } from '../../interfaces/report-export-format.type';\nimport { chatViewerDrills, chatViewerMatch, chatViewerTiles } from '../../report-chat-viewer-state';\nimport { provideReportDatePicker } from '../../report-date-presets';\nimport {\n GROUP_BY_ITEM, filterItemForGroup, groupByFilterItem, groupBySignature, groupItemName, groupValuesFromQuery,\n hasPageGroup, isGranularityOffered, matchFilterItem, matchFromQuery, reportBarGroups,\n} from '../../report-filter-items';\nimport { savedFilterGroups, savedFilterValues } from '../../report-saved-filters';\nimport { ReportFilterOptionsService } from '../../services/report-filter-options.service';\nimport { ReportFilterStateService, defaultSignature } from '../../services/report-filter-state.service';\nimport { zipExportStates } from '../../tile-data-state';\n\n\n// A single report: the AI chat on the left (unless the server turns it off),\n// the report canvas on the right, under an H2 title + settings gear. The host\n// supplies [reportId] (from its route) and switches reports through its own\n// routes — this component never picks one.\n@Component({\n selector: 'fs-ai-report',\n templateUrl: './fs-ai-report.component.html',\n styleUrls: ['./fs-ai-report.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n providers: [\n // Session filter state is per-open-report, not app-global; the export\n // services resolve filters through it, so they live at the same level.\n ReportFilterStateService,\n // The bars' select lists, narrowed by the other filters; per open report.\n ReportFilterOptionsService,\n ReportExportCollectorService,\n ReportPptxService,\n ReportPdfService,\n ReportTextLayoutService,\n ReportExportService,\n // fs-ai-chat sits in this template, so it resolves its gateway here: the\n // report one, which adds the viewer's state to each turn it sends.\n ReportAiChatData,\n { provide: FsAiChatData, useExisting: ReportAiChatData },\n // Tree-shaken ECharts core + the 'report' house theme, loaded lazily.\n provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),\n // The bar's date pickers start their weeks on Monday and list the built-in\n // presets; a preset only sets the days.\n provideReportDatePicker(),\n ],\n imports: [\n FsFilterModule,\n FsMenuModule,\n FsAiChatComponent,\n MatButtonModule,\n MatIconModule,\n MatTooltipModule,\n ReportCanvasComponent,\n ],\n})\nexport class FsAiReportComponent {\n\n // The report this view is focused on — supplied by the host from the route.\n public readonly reportId = input<number | null>(null);\n\n // API base for the reports + chat endpoints; override to mount elsewhere.\n public readonly basePath = input<string>('reports');\n\n // The query param that carries the page on screen (?page=7). A report opens\n // on the page it names, and each move to another page writes it, in place,\n // so a refresh or a shared link comes back to the same page. It is the only\n // state a report keeps in the URL: its filters and the rest live in the\n // report's state (ReportFilterStateService). A host that mounts several\n // reports on one route, or wants no URL writes, sets this to null.\n public readonly pageQueryParam = input<string | null>('page');\n\n // The report was deleted from its settings dialog — the host routes back to\n // the listing.\n public readonly deleted = output<number>();\n\n // The report was renamed (settings, or the agent) — the host can refresh a\n // breadcrumb / document title.\n public readonly renamed = output<Report>();\n\n // The viewer moved to another page — for hosts that track the open page for\n // their own reasons. Nothing is written to the URL.\n public readonly pageChanged = output<number | null>();\n\n public readonly report = signal<Report | null>(null);\n public readonly editMode = signal(false);\n\n // The page the canvas should open on: the ?page= the report opened with\n // (read once per report). Cleared as soon as the canvas reports back, so a\n // later in-app page change is never fought by a stale value.\n public readonly pageId = signal<number | null>(null);\n\n // The page the chat is bound to: the one on screen. A report conversation\n // belongs to exactly one page, so this both scopes the conversation list and\n // becomes the new conversation's page. A signal because it feeds\n // chatBasePath — changing it is what reloads the panel onto the new page's\n // conversations. Null until the canvas reports which page it opened on, which\n // keeps the chat from listing against a page guess.\n public readonly chatPageId = signal<number | null>(null);\n\n // Where the chat's calls go: beneath the page it is bound to\n // ({basePath}/{reportId}/pages/{pageId}/chat, …/conversations, …). Every\n // conversation is reached through its page, so the path carries the report\n // and the page and nothing rides in the chat's requestData.\n //\n // The chat is held closed ([ready] in the template) until the page is known,\n // so the path is never called while chatPageId is null: on a fresh load the\n // report has to arrive and the canvas has to render before any page exists.\n public readonly chatBasePath = computed(() => {\n return `${this.basePath()}/${this.reportId()}/pages/${this.chatPageId()}`;\n });\n\n // The chat and its resizer show once the report says the server keeps the\n // chat on, so a report whose chat is off never flashes one. A server too\n // old to send chatEnabled keeps it.\n public readonly chatEnabled = computed(() => {\n const report = this.report();\n\n return !!report && report.chatEnabled !== false;\n });\n\n // The report-level filter toolbar (fs-filter). Rebuilt whenever the loaded\n // report (and thus its groups) changes.\n public readonly reportFilterConfig = signal<FilterConfig | null>(null);\n\n // Gates the toolbar fs-filter so it isn't rendered when there is nothing to\n // put in it — no report-level filters and no group-by control.\n public readonly reportHasFilters = computed(() => {\n return this._reportGroups().length > 0 || !!this._groupByItem();\n });\n\n // fs-filter reads its config only once (at init). The template keys the\n // toolbar fs-filter on this signature so it's recreated (and re-reads the\n // rebuilt config) whenever the report-level filter set changes.\n public readonly reportFilterKey = computed(() => {\n return [\n // The state version the bar was built for: a reset to the defaults\n // replaces every value at once.\n this._barVersion(),\n // The effective zone is part of it too: a zone change re-resolves relative\n // presets, and the bar must be recreated to show the new days.\n this._filterState.timezone(),\n // The stored default is part of the signature: saving a new default in report\n // settings rebuilds the config, but without a key change fs-filter keeps\n // rendering the values it was created with until a full page reload.\n groupBySignature(this.report()),\n ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}:${defaultSignature(group)}`),\n // A page group shows on its own page only, so such a bar is recreated\n // when the page on screen changes.\n ...(hasPageGroup(this.report()) ? [`page:${this.chatPageId()}`] : []),\n ].join('|');\n });\n\n @ViewChild('split', { static: true })\n private _split!: ElementRef<HTMLDivElement>;\n\n // Only while the chat is on (chatEnabled).\n @ViewChild('chatPanel', { read: ElementRef })\n private _chatPanel?: ElementRef<HTMLElement>;\n\n // Only the canvas knows which page is on screen, and a page-scoped export\n // has to ask it.\n @ViewChild(ReportCanvasComponent)\n private _canvas?: ReportCanvasComponent;\n\n // The report-level filter bar, while it is drawn. A saved filter being\n // picked reads the bar's values off it (_keepBarOnPick).\n @ViewChild(FilterComponent)\n private _reportBar?: FilterComponent;\n\n private _reportData = inject(ReportData);\n private _reportAiChatData = inject(ReportAiChatData);\n private _route = inject(ActivatedRoute);\n private _router = inject(Router);\n private _filterState = inject(ReportFilterStateService);\n private _filterOptions = inject(ReportFilterOptionsService);\n private _exportService = inject(ReportExportService);\n private _collector = inject(ReportExportCollectorService);\n private _process = inject(FsProcess);\n private _dialog = inject(MatDialog);\n private _destroyRef = inject(DestroyRef);\n private _zone = inject(NgZone);\n\n // The state version the bar was last built for (reportFilterKey).\n private readonly _barVersion = signal(0);\n\n // The report bar's values as they were the moment fs-filter read a saved\n // filter's values, or null outside that moment. A pick sets every item of\n // the bar from the saved filter's values; each item a saved filter never\n // holds (the group-by grain, the match, a page's own filters) is put back\n // to its noted value as it is set (_keepItemOnPick).\n private _barValuesAtPick: Record<string, unknown> | null = null;\n\n // The report the screen was opened on its first saved filter for\n // (_openOnFirstSavedFilter), or null before that.\n private _openedOnSavedFilterReportId: number | null = null;\n\n constructor() {\n // Each chat turn carries what the viewer has on screen. Only the function\n // is set here; it is called when a turn is sent.\n this._reportAiChatData.turnData = () => ({ viewerState: this._chatViewerState() });\n\n // Point the shared data gateway at the configured base first (before any\n // load below reads it).\n effect(() => {\n this._reportData.basePath = this.basePath();\n });\n\n // (Re)load whenever the host switches the report id.\n effect(() => {\n const reportId = this.reportId();\n\n // The page this report opens on, from the ?page= the URL already holds.\n // Read per report rather than once at construction: the host may swap\n // reports on the same route, and each arrival carries its own ?page=.\n const pageId = this._pageIdFromUrl();\n\n // Only the report id and the page param re-run this. The view state below\n // is written here and read by the config build, so it stays untracked.\n untracked(() => {\n this.editMode.set(false);\n\n // A new report's pages are not this report's pages — drop the binding\n // until its canvas says which page it landed on.\n this.chatPageId.set(null);\n this.pageId.set(pageId);\n\n if (reportId != null) {\n this._loadReport(reportId);\n } else {\n this.report.set(null);\n this._buildReportConfig();\n }\n });\n });\n\n // resetToDefaults() moves the state version. The bar is built again for\n // it, and reportFilterKey, which carries it, recreates fs-filter: it reads\n // its config once.\n effect(() => {\n const version = this._filterState.stateVersion();\n\n untracked(() => {\n if (version !== this._barVersion()) {\n this._buildReportConfig();\n }\n });\n });\n\n this._buildReportConfig();\n }\n\n public toggleEditMode(): void {\n this.editMode.update((editMode) => !editMode);\n }\n\n // The edit tools live in this toolbar, but the canvas owns what they act on\n // (the active page, the header/footer bands, which layer is live).\n public get isMasterMode(): boolean {\n return this._canvas?.masterMode() ?? false;\n }\n\n public addText(): void {\n this._canvas?.addText();\n }\n\n public toggleMasterMode(): void {\n this._canvas?.toggleMasterMode();\n }\n\n // Report settings — name, page size, delete. The\n // dialog performs the delete itself; we react to what it reports back.\n public reportSettings(): void {\n const report = this.report();\n if (!report) {\n return;\n }\n\n const reportId = report.id;\n\n const dialogRef = this._dialog.open<ReportSettingsComponent, unknown, ReportSettingsResult>(ReportSettingsComponent, {\n data: { report },\n width: '460px',\n });\n const settings = dialogRef.componentInstance;\n\n dialogRef.afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((result) => {\n if (result?.action === 'deleted') {\n this.deleted.emit(reportId);\n\n return;\n }\n\n // A save that failed part way (a refused name) may still have stored\n // the filters before it, so a dismissed dialog that wrote reloads too.\n if (result?.action === 'saved' || settings.wrote()) {\n this._loadReport(reportId, true);\n }\n });\n }\n\n // Component settings — title, exact geometry, and the diagnostic views\n // (SQL, config, filter wiring).\n public componentSettings(component: ReportComponentModel): void {\n const report = this.report();\n if (!report || !this._canvas) {\n return;\n }\n\n const reportId = report.id;\n\n // The dialog gets what the component's title tokens fill with where it is\n // drawn, for the title's Insert field menu and the line saying how it reads.\n const dialogRef = this._dialog.open<ComponentSettingsComponent, ComponentSettingsDialogData, ComponentSettingsResult>(\n ComponentSettingsComponent,\n {\n data: { report, component, tokens: this._canvas.componentTokens(component) },\n width: '640px',\n },\n );\n\n // Filter add/remove/level changes persist immediately inside the dialog (no\n // \"save\") and can leave it by an exit that carries no result, so they are\n // announced as they land. The reload waits for the close so the canvas isn't\n // re-rendering underneath an open dialog.\n let filtersChanged = false;\n dialogRef.componentInstance.filtersChanged\n .pipe(takeUntil(dialogRef.afterClosed()))\n .subscribe(() => filtersChanged = true);\n\n dialogRef.afterClosed()\n .pipe(takeUntilDestroyed(this._destroyRef))\n .subscribe((result) => {\n // The dialog confirms + performs the delete itself. The component is\n // gone from the report, so reload rather than patching it out locally —\n // its filters went with it, which the report bar has to be rebuilt for.\n if (result?.deleted) {\n this._loadReport(reportId);\n\n return;\n }\n\n // The report's filter groups changed, so the report bar and the\n // on-component strips have to be rebuilt from a fresh report.\n if (filtersChanged) {\n this._loadReport(reportId);\n\n return;\n }\n\n // Nothing else in the dialog touches the query — title and padding are\n // presentation. Repaint the one component it was opened for and leave\n // every other component's data, and its query, alone.\n if (result?.settings) {\n this._canvas?.applyComponentSettings(component.id, result.settings);\n }\n });\n }\n\n // The canvas moved to another page. The report-level filters stay as they\n // are (they live in the state service); the page goes into the URL.\n public onCanvasPageChanged(pageId: number | null): void {\n // The asked-for page has been consumed; from here the canvas owns the page.\n this.pageId.set(null);\n this.chatPageId.set(pageId);\n // The open page is part of the state the tiles and exports read.\n this._filterState.setPage(pageId);\n this.pageChanged.emit(pageId);\n this._writePageToUrl(pageId);\n\n // The bar shows the page groups of the page on screen.\n if (hasPageGroup(this.report())) {\n this._buildReportConfig();\n }\n }\n\n // The canvas changed the report's structure (added a page) — re-fetch so the\n // new page renders; the canvas lands the view on it.\n public onCanvasReportChanged(): void {\n const report = this.report();\n if (report) {\n this._loadReport(report.id);\n }\n }\n\n // Export the report to PowerPoint, entirely client-side (native editable\n // charts; page = slide). The dock shows progress until the file saves.\n public exportPowerpoint(): void {\n const report = this.report();\n if (!report) {\n return;\n }\n\n this._process.run(\n 'Exporting PowerPoint',\n this._exportService.powerpoint(report),\n );\n }\n\n // Export to PDF, entirely client-side (offscreen ECharts at 3×; page = PDF page).\n public exportPdf(): void {\n const report = this.report();\n if (!report) {\n return;\n }\n\n this._process.run(\n 'Exporting PDF',\n this._exportService.pdf(report),\n );\n }\n\n // The whole report as files in one action: the server writes one CSV per\n // component, each what the screen shows (a chart or KPI as drawn, at the\n // viewer's group-by grain; a list in full), and zips them foldered by page\n // with an Export Notes.txt that records the filters as the bar reads them.\n // Each file carries its tile's own state (zipExportStates): a list's sort,\n // search and hidden columns, a chart's drill path and the groups that match\n // 'any'; a server that does not read it uses each list's saved sort. The\n // notes get the filter lines as the cover words them (exportLines; a This\n // Page zip names only the groups that reach the page), and each file is\n // named after its tile's title as the canvas header reads it (titles). All\n // of it is read once, when the export starts (exportWording). `thisPage`\n // narrows it to the page the canvas is showing. Unlike the PDF/PowerPoint\n // exports the files are written server-side, so they are not capped by\n // what a slide can hold.\n public exportData(thisPage = false, format: ReportExportFormat = 'csv'): void {\n const report = this.report();\n if (!report) {\n return;\n }\n\n const pageId = thisPage ? this._canvas?.activePage?.id ?? null : null;\n const filters = this._filterState.resolveForReport(report, pageId);\n const frequency = this._filterState.frequency();\n const snapshot = this._collector.snapshot(report);\n const states = zipExportStates(report, snapshot.state, pageId, (component) => this._filterState.gridSessionLayout(component));\n\n this._process.download(\n format === 'xlsx' ? 'Exporting Excel' : 'Exporting data',\n this._collector.exportWording(report, snapshot, pageId)\n .pipe(\n switchMap(({ lines, titles }) => this._reportData.exportReport(\n report.id,\n filters,\n pageId,\n frequency,\n lines,\n states,\n titles,\n {},\n format,\n )),\n ),\n );\n }\n\n // React to each chat turn (fs-chat handles the request + persistence); we\n // only care about the report side effects this context's backend flags.\n public onChatResponse(response: FsAiChatResponse): void {\n const reportId = this.reportId();\n if (reportId == null) {\n return;\n }\n\n const reportResponse = response as FsAiChatResponse & ReportChatResponse;\n\n // A structural change or a rename both re-fetch the report (session filter\n // values survive); a rename additionally notifies the host so it can\n // refresh a breadcrumb / title.\n if (reportResponse.reportChanged || reportResponse.reportRenamed) {\n this._loadReport(reportId, !!reportResponse.reportRenamed);\n }\n }\n\n // Drag the divider between the chat and canvas panes (pointer-capture loop\n // outside Angular).\n public onResizeStart(event: PointerEvent): void {\n event.preventDefault();\n\n const handle = event.target as HTMLElement;\n handle.setPointerCapture(event.pointerId);\n this._split.nativeElement.classList.add('resizing');\n\n this._zone.runOutsideAngular(() => {\n const move = (e: PointerEvent) => this._resizeTo(e.clientX);\n const end = () => {\n handle.releasePointerCapture(event.pointerId);\n handle.removeEventListener('pointermove', move);\n handle.removeEventListener('pointerup', end);\n handle.removeEventListener('pointercancel', end);\n this._split.nativeElement.classList.remove('resizing');\n };\n\n handle.addEventListener('pointermove', move);\n handle.addEventListener('pointerup', end);\n handle.addEventListener('pointercancel', end);\n });\n }\n\n // What the viewer has on screen as a chat turn sends it. The canvas\n // selection counts only in edit mode: it is drawn only then, and it is kept\n // (not cleared) when edit mode is left. The match is sent only while it is\n // 'any', the drilled charts only when one is drilled, and the tables only\n // when the bound page shows one, each with the layout the viewer has it in\n // while that differs from the stored one.\n private _chatViewerState(): ReportChatViewerState {\n const snapshot = this._filterState.snapshot();\n const drills = chatViewerDrills(snapshot, this._filterState.formatContext().locale);\n const tiles = chatViewerTiles(\n this._filterState.report(),\n this.chatPageId(),\n (component) => this._filterState.gridSessionLayout(component),\n );\n\n return {\n granularity: this._filterState.frequency(),\n selectedComponentId: this.editMode() ? this._canvas?.selectedComponentId() ?? null : null,\n filters: this._filterState.viewerFilters(),\n ...chatViewerMatch(snapshot),\n ...(drills.length ? { drills } : {}),\n ...(tiles.length ? { tiles } : {}),\n };\n }\n\n private _resizeTo(clientX: number): void {\n const rect = this._split.nativeElement.getBoundingClientRect();\n if (rect.width === 0 || !this._chatPanel) {\n return;\n }\n\n const ratio = (clientX - rect.left) / rect.width;\n const clamped = Math.min(0.8, Math.max(0.2, ratio));\n this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;\n }\n\n // The page on screen into the URL (?page=), replacing the current history\n // entry rather than adding one, so Back leaves the report instead of\n // stepping through its pages. Only the page param is touched; the host's\n // own query params stay. Nothing is written when the param is off, or when\n // the URL already names the page.\n private _writePageToUrl(pageId: number | null): void {\n const param = this.pageQueryParam();\n if (!param || !pageId || this._pageIdFromUrl() === pageId) {\n return;\n }\n\n this._router.navigate([], {\n relativeTo: this._route,\n queryParams: { [param]: pageId },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n\n // The page id the URL holds right now (?page=), or null when the page param\n // is off or the value is not a usable id.\n private _pageIdFromUrl(): number | null {\n const param = this.pageQueryParam();\n if (!param) {\n return null;\n }\n\n const pageId = Number(this._route.snapshot.queryParamMap.get(param));\n\n return Number.isFinite(pageId) && pageId > 0 ? pageId : null;\n }\n\n // Every load sets the viewer state up for the report (init): its first\n // load opens it on its authored defaults, and a later one (a chat edit, a\n // settings save) keeps the state in memory.\n private _loadReport(reportId: number, emitRenamed = false): void {\n this._reportData.get(reportId)\n .pipe(\n tap((report: Report) => this._filterState.init(report)),\n takeUntilDestroyed(this._destroyRef),\n )\n .subscribe((report: Report) => {\n this.report.set(report);\n this._buildReportConfig();\n\n if (emitRenamed) {\n this.renamed.emit(report);\n }\n });\n }\n\n // Report-level filter groups in their saved order — the ones that render in\n // the toolbar (component-level groups render on their components), with\n // the page groups of the page on screen.\n private _reportGroups(): ReportFilterGroup[] {\n return reportBarGroups(this.report(), this.chatPageId());\n }\n\n // (Re)build the toolbar fs-filter config — the report-level filter items and\n // then the group-by control.\n private _buildReportConfig(): void {\n const report = this.report();\n const reportId = report?.id ?? null;\n\n // Drop a grain the control no longer offers — the agent can narrow the list\n // mid-session, and an override the viewer can't see is worse than none.\n if (report && !isGranularityOffered(report, this._filterState.frequency())) {\n this._filterState.setFrequency(null);\n }\n\n const features = report?.viewerFeatures ?? [];\n const items = reportId\n ? this._reportGroups().map((group) =>\n filterItemForGroup(group, this._filterOptions, report, this._filterState.value(group.id), features))\n : [];\n\n // The group-by control leads the bar, ahead of every filter: it sets the\n // grain the whole report is read at, so it is the first thing a viewer\n // decides. It is not a filter group — it re-buckets rows rather than\n // narrowing them — so it is placed here rather than ordered among them.\n const groupByItem = this._groupByItem();\n if (groupByItem) {\n items.unshift(groupByItem);\n }\n\n // How the groups combine closes the bar.\n const matchItem = this._matchItem();\n if (matchItem) {\n items.push(matchItem);\n }\n\n const savedFilters = this._savedFiltersConfig();\n\n this._barVersion.set(this._filterState.stateVersion());\n this.reportFilterConfig.set({\n // fs-filter never touches the URL or persists filter state: a report\n // keeps no state in the URL. ReportFilterStateService owns the values.\n queryParam: false,\n persist: false,\n items: savedFilters ? this._keepOnPick(items) : items,\n change: (query) => this._barChanged(query ?? {}, !!matchItem),\n // 'Clear filters' puts the screen back on the report's authored\n // defaults and drops the temporary layer. fs-filter reports its own\n // cleared items (change) just before this, so the reset wins.\n clear: () => this._filterState.resetToDefaults(),\n // The chip shows exactly while the screen differs from what a clear\n // returns to (C5).\n clearVisible: () => this._filterState.differsFromDefaults(),\n savedFilters,\n // fs-filter calls init once its saved filters are loaded.\n ...(savedFilters && reportId ? { init: () => this._openOnFirstSavedFilter(reportId) } : {}),\n });\n }\n\n // A report opens on its first saved filter: once its saved filters are\n // first loaded, the first one is picked as a viewer would pick it, so it\n // applies on every page through the same change (_barChanged). Once per\n // report opened: the bar is recreated as the screen changes, and a later\n // build must not pick it again over the viewer's own edits. Reordering the\n // saved filters changes which one a report opens on, for everyone.\n private _openOnFirstSavedFilter(reportId: number): void {\n const savedFilterController = this._reportBar?.savedFilterController;\n\n if (this._openedOnSavedFilterReportId === reportId || !savedFilterController) {\n return;\n }\n\n this._openedOnSavedFilterReportId = reportId;\n\n const [first] = savedFilterController.savedFilters;\n if (first) {\n savedFilterController.setActiveFilter(first);\n }\n }\n\n // The bar's saved filters, shared by everyone who may open the report, or\n // undefined when the bar has none to offer: a report not yet saved has no\n // id to keep them under, and a bar with no report-wide filter has nothing\n // a saved filter holds. fs-filter's own Saved filters menu lists them,\n // saves the bar's values as a new one or over the picked one, orders and\n // deletes them. What it saves is kept to the report-wide filters\n // (savedFilterValues): a page's own filters, the grain and the match are\n // left out. The list is read every time the bar is built; one that cannot\n // be read shows as empty rather than keeping the bar from drawing.\n private _savedFiltersConfig(): IFilterSavedFiltersConfig | undefined {\n const reportId = this.report()?.id ?? null;\n\n if (!reportId || !savedFilterGroups(this._reportGroups()).length) {\n return undefined;\n }\n\n return {\n load: () => this._reportData\n .savedFilters(reportId, { context: new HttpContext().set(DisplayApiError, false) })\n .pipe(\n catchError(() => of([] as ReportSavedFilter[])),\n map((savedFilters) => (savedFilters ?? []).map((savedFilter) => this._barSavedFilter(savedFilter))),\n ),\n save: (savedFilter) => {\n const filters = savedFilterValues(savedFilter.filters, this._savedFilterGroups());\n const save$ = savedFilter.id\n ? this._reportData.updateSavedFilter(reportId, Number(savedFilter.id), {\n ...(savedFilter.name ? { name: savedFilter.name } : {}),\n filters,\n })\n : this._reportData.createSavedFilter(reportId, { name: savedFilter.name ?? '', filters });\n\n return save$.pipe(map((saved) => this._barSavedFilter(saved)));\n },\n order: (savedFilters) => this._reportData\n .saveSavedFilterPositions(reportId, savedFilters.map((savedFilter) => Number(savedFilter.id)))\n .pipe(map((ordered) => (ordered ?? []).map((savedFilter) => this._barSavedFilter(savedFilter)))),\n delete: (savedFilter) => this._reportData\n .deleteSavedFilter(reportId, Number(savedFilter.id))\n .pipe(map(() => savedFilter)),\n };\n }\n\n // The report's report-wide filter groups: the ones a saved filter holds.\n private _savedFilterGroups(): ReportFilterGroup[] {\n return savedFilterGroups(this.report()?.filterGroups);\n }\n\n // A saved filter as the bar's menu holds it. Its values are kept to the\n // report-wide filters the report has now (a key it no longer has, or a\n // value its filter can no longer take, is dropped rather than applied), and\n // each read of them hands out a copy, so nothing the bar does to the values\n // it set changes the saved filter. A read also notes the bar's values\n // (_keepBarOnPick): picking a saved filter reads its values and sets the\n // bar from them in one go, and the items it does not hold are put back.\n private _barSavedFilter(savedFilter: ReportSavedFilter): IFilterSavedFilter {\n const filters = savedFilterValues(savedFilter.filters, this._savedFilterGroups());\n const keepBar = () => this._keepBarOnPick();\n\n return {\n id: savedFilter.id,\n name: savedFilter.name,\n get filters() {\n keepBar();\n\n return JSON.parse(JSON.stringify(filters));\n },\n };\n }\n\n // Notes the bar's values for a pick of a saved filter (_barValuesAtPick).\n // fs-filter sets the bar from the saved filter's values in the same task\n // as it reads them, so the note is dropped once this task is done: any\n // other read of a saved filter's values (its row in View all, a save) sets\n // nothing.\n private _keepBarOnPick(): void {\n if (!this._reportBar) {\n return;\n }\n\n this._barValuesAtPick = { ...this._reportBar.values };\n queueMicrotask(() => this._barValuesAtPick = null);\n }\n\n // The bar's items, each one a saved filter does not hold (the group-by\n // grain, the match, a page's own filters) set back to its value when a pick\n // of a saved filter sets it. fs-filter sets every item from a saved filter\n // and calls each one's change before it reports the bar's change, so the\n // change the bar reports carries these items as they were: the pick moves\n // the report-wide filters only, on every page, through the same change as\n // a viewer's own edit (_barChanged). On any other change an item's change\n // comes after the bar's, with no pick noted, and does nothing.\n private _keepOnPick(items: IFilterConfigItem[]): IFilterConfigItem[] {\n const held = new Set(this._savedFilterGroups().map((group) => groupItemName(group)));\n\n return items.map((item) => (held.has(item.name)\n ? item\n : { ...item, change: (barItem: BaseItem<IFilterConfigItem>) => this._keepItemOnPick(barItem) }));\n }\n\n private _keepItemOnPick(item: BaseItem<IFilterConfigItem>): void {\n if (this._barValuesAtPick) {\n item.setValue(this._barValuesAtPick[item.name], false);\n }\n }\n\n // The bar's values into the state: every group it shows, the grain and,\n // when the bar has the control, the match.\n private _barChanged(query: Record<string, unknown>, hasMatch: boolean): void {\n for (const { groupId, value } of groupValuesFromQuery(query, this._reportGroups())) {\n this._filterState.setValue(groupId, value);\n }\n // Not a filter group — the grain is read straight off the query.\n this._filterState.setFrequency((query[GROUP_BY_ITEM] as ChartGranularity) || null);\n // Nor is the match; a bar without the control leaves it as it is.\n if (hasMatch) {\n this._filterState.setMatch(matchFromQuery(query));\n }\n }\n\n // The report's group-by control as an fs-filter item, or null when the report\n // has none to show. Seeded from the session state so the grain the viewer\n // picked survives the report being re-fetched after a chat edit.\n private _groupByItem(): IFilterConfigItem | null {\n const report = this.report();\n\n return report\n ? groupByFilterItem(report, this._filterState.frequency())\n : null;\n }\n\n // The bar's Match control, seeded with the match on screen, or null when\n // the bar holds fewer than two groups that combine.\n private _matchItem(): IFilterConfigItem | null {\n return matchFilterItem(this.report(), this._reportGroups(), this.chatPageId(), this._filterState.match());\n }\n}\n","<div class=\"fs-ai-report fs-column\">\n\n <div class=\"fs-ai-report__header fs-row.align-center\">\n <h2 class=\"fs-ai-report__title fs-flex\">{{ report()?.name }}</h2>\n\n @if (report()) {\n <!-- Report-level filters, inline with the toolbar actions, with the\n report's saved filters in fs-filter's own Saved filters menu.\n fs-filter reads its config once at init, so it's keyed on the\n filter signature: when the report-level filter set changes the\n block is recreated and re-reads the rebuilt config. -->\n @if (reportHasFilters()) {\n @for (key of [reportFilterKey()]; track key) {\n <fs-filter\n class=\"fs-ai-report__filters\"\n [config]=\"reportFilterConfig()\">\n </fs-filter>\n }\n }\n\n <!-- What layout editing can add or switch to, and the way out of it.\n One style for all three — outlined, icon and text. \"Header & footer\"\n is a toggle: it keeps its label and turns gray while it is on. -->\n @if (editMode()) {\n <div class=\"fs-ai-report__edit-tools fs-row.align-center.gap-xs\">\n <button\n mat-stroked-button\n type=\"button\"\n matTooltip=\"Add a block of text\"\n (click)=\"addText()\">\n <mat-icon>title</mat-icon>\n Add text\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n class=\"fs-ai-report__master\"\n [class.active]=\"isMasterMode\"\n [matTooltip]=\"isMasterMode ? 'Back to editing this page' : 'Edit the header and footer shown on every page'\"\n (click)=\"toggleMasterMode()\">\n <mat-icon>web_asset</mat-icon>\n Header & footer\n </button>\n <button\n mat-stroked-button\n type=\"button\"\n (click)=\"toggleEditMode()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n </div>\n }\n\n <!-- One icon for both states: it reads as pressed while editing rather\n than swapping to something else. -->\n <button\n mat-icon-button\n type=\"button\"\n class=\"fs-ai-report__toggle\"\n [class.active]=\"editMode()\"\n [matTooltip]=\"editMode() ? 'Done editing' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>dashboard_customize</mat-icon>\n </button>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Export\"\n [fsMenuTriggerFor]=\"exportMenu\">\n <mat-icon>download</mat-icon>\n </button>\n <fs-menu #exportMenu>\n <ng-template\n fs-menu-item\n (click)=\"exportPowerpoint()\">\n Export PowerPoint\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportPdf()\">\n Export PDF\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"exportData()\">\n Export Raw Data\n </ng-template>\n @if ((report()?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true)\">\n Export Raw Data (This Page)\n </ng-template>\n }\n <ng-template\n fs-menu-item\n (click)=\"exportData(false, 'xlsx')\">\n Export Excel\n </ng-template>\n @if ((report()?.pages?.length ?? 0) > 1) {\n <ng-template\n fs-menu-item\n (click)=\"exportData(true, 'xlsx')\">\n Export Excel (This Page)\n </ng-template>\n }\n </fs-menu>\n\n <button\n mat-icon-button\n type=\"button\"\n matTooltip=\"Report settings\"\n (click)=\"reportSettings()\">\n <mat-icon>settings</mat-icon>\n </button>\n }\n </div>\n\n <div\n #split\n class=\"fs-ai-report__split fs-row.align-start\">\n @if (chatEnabled()) {\n <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"chatBasePath()\"\n [ready]=\"chatPageId() !== null\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n }\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report()) {\n <app-report-canvas\n [report]=\"report()\"\n [editMode]=\"editMode()\"\n [pageId]=\"pageId()\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (pageChanged)=\"onCanvasPageChanged($event)\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n","import { Injectable, inject } from '@angular/core';\n\nimport { BehaviorSubject, Observable, of } from 'rxjs';\nimport { map, tap } from 'rxjs/operators';\n\nimport { ReportData } from '../data/report.data';\nimport { ReportListItem } from '../interfaces/report.interface';\n\n\n// Holds the report list in memory so the picker doesn't hit the API on every\n// focus. Loaded once when the page opens; create/rename/delete keep the cache\n// in sync.\n@Injectable({\n providedIn: 'root',\n})\nexport class ReportService {\n\n private _reportData = inject(ReportData);\n\n private _reports$ = new BehaviorSubject<ReportListItem[]>([]);\n\n public get reports$(): Observable<ReportListItem[]> {\n return this._reports$.asObservable();\n }\n\n public load(): Observable<ReportListItem[]> {\n return this._reportData.reports()\n .pipe(\n tap((reports: ReportListItem[]) => this._reports$.next(reports ?? [])),\n );\n }\n\n // Filters the cached list locally — what the autocomplete's [fetch] calls.\n public filter(keyword: string): Observable<ReportListItem[]> {\n const term = (keyword ?? '').trim().toLowerCase();\n const reports = this._reports$.getValue();\n\n if (!term) {\n return of(reports);\n }\n\n return of(reports.filter((report) => report.name.toLowerCase().includes(term)));\n }\n\n public create(name: string): Observable<ReportListItem> {\n return this._reportData.create(name)\n .pipe(\n tap((report: ReportListItem) => {\n this._reports$.next([...this._reports$.getValue(), report]);\n }),\n );\n }\n\n public rename(reportId: number, name: string): Observable<ReportListItem> {\n return this._reportData.rename(reportId, name)\n .pipe(\n tap((report: ReportListItem) => {\n this._reports$.next(\n this._reports$.getValue()\n .map((existing) => (existing.id === report.id ? report : existing)),\n );\n }),\n );\n }\n\n public delete(reportId: number): Observable<void> {\n return this._reportData.delete(reportId)\n .pipe(\n tap(() => {\n this._reports$.next(\n this._reports$.getValue().filter((report) => report.id !== reportId),\n );\n }),\n map(() => undefined),\n );\n }\n}\n","/*\n * Public API Surface of @firestitch/reports\n *\n * The AI-built report viewer/editor, its data gateway, session filter state and\n * renderer components. The AI chat is provided by @firestitch/ai, reached\n * through the report's page on screen.\n */\n// Routing-free surface: a reports listing and a single-report view. The host\n// routes between them and passes [reportId] into FsAiReportComponent.\nexport { FsAiReportsComponent } from './app/reports/views/reports/fs-ai-reports.component';\nexport { FsAiReportComponent } from './app/reports/views/report/fs-ai-report.component';\nexport { ReportData } from './app/reports/data/report.data';\nexport { ReportService } from './app/reports/services/report.service';\nexport { ReportFilterStateService } from './app/reports/services/report-filter-state.service';\nexport * from './app/reports/interfaces/report.interface';\nexport * from './app/reports/interfaces/report-state-snapshot.interface';\nexport * from './app/reports/interfaces/report-tile-state.interface';\nexport * from './app/reports/interfaces/report-drill-step.interface';\nexport * from './app/reports/interfaces/report-drill-crumb.interface';\nexport * from './app/reports/interfaces/report-drill-refusal.type';\nexport * from './app/reports/interfaces/report-filter-match.type';\nexport * from './app/reports/interfaces/report-filter-skip.type';\nexport * from './app/reports/interfaces/report-viewer-feature.type';\nexport * from './app/reports/interfaces/report-export-format.type';\nexport * from './app/reports/interfaces/component-data-applied.interface';\nexport * from './app/reports/interfaces/component-data-drill.interface';\nexport * from './app/reports/interfaces/report-filter-options.interface';\nexport * from './app/reports/interfaces/report-filter-options-request.interface';\nexport * from './app/reports/interfaces/report-saved-filter.interface';\nexport * from './app/reports/interfaces/report-saved-filter-changes.interface';\nexport * from './app/reports/interfaces/report-mark-point.interface';\nexport * from './app/reports/interfaces/report-mark-click.interface';\nexport * from './app/reports/interfaces/report-export-line.interface';\nexport * from './app/reports/interfaces/report-export-line-kind.type';\nexport * from './app/reports/enums/report-value-format.enum';\nexport * from './app/reports/enums/report-value-formula.enum';\nexport * from './app/reports/enums/report-list-column-format.enum';\nexport * from './app/reports/enums/report-number-units.enum';\nexport * from './app/reports/enums/report-chart-data-labels.enum';\nexport * from './app/reports/enums/report-chart-color.enum';\nexport * from './app/reports/enums/report-chart-line-style.enum';\nexport * from './app/reports/enums/report-chart-mark-stat.enum';\nexport * from './app/reports/enums/report-chart-date-label.enum';\nexport * from './app/reports/enums/report-change-polarity.enum';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":["i1","i2","i4","i3","i6","switchMap","EMPTY_VALUE","isPointsChange","valueText","numeric","earliestOf","calendarDay","latestOf","isPlainObject","rangeText","rxFilter","priorWindowText","map","catchError","filter","tap","i5","i7","i8","MatOption","exportCell","mergeMap","TITLE_H","SUBTITLE_H","NOTE_LINE_H","MIN_BODY_H","MUTED_COLOR","KPI_HEIGHTS","KPI_ARROW","KPI_ARROW_GAP","KPI_BAR_W","KPI_BAR_H","KPI_TRACK_COLOR","KPI_SPARKLINE_W","GRID_INDENT"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,eAAe,GAAmC;IAC7D,cAAc;IACd,eAAe;IACf,aAAa;IACb,UAAU;IACV,WAAW;IACX,kBAAkB;IAClB,OAAO;IACP,MAAM;CACP,CAAC;AAEF;AACA;AACM,SAAU,qBAAqB,CAAC,MAAyD,EAAA;IAC7F,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,aAAa,CAC3B,KAAsD,EACtD,QAA2D,EAAA;AAE3D,IAAA,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;WACzB,CAAC,KAAK,CAAC,WAAW;WAClB,CAAC,QAAQ,IAAI,EAAE,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;AAClD;;ACtBA;AACA;AACA;MAIa,UAAU,CAAA;AACb,IAAA,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;IAItB,QAAQ,GAAG,SAAS,CAAC;;;IAIpB,KAAK,CAAC,MAAM,GAAG,EAAE,EAAA;AACvB,QAAA,OAAO,MAAM,GAAG,CAAA,EAAG,IAAI,CAAC,QAAQ,CAAI,CAAA,EAAA,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;KAC9D;AAEM,IAAA,OAAO,CAAC,KAAA,GAAa,EAAE,EAAE,SAAwB,EAAE,EAAA;AACxD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,EAAE,EACZ,KAAK,EACL;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,IAAI,CAAC,KAAA,GAAa,EAAE,EAAE,SAAwB,EAAE,EAAA;AACrD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,EAAE,EACZ,KAAK,EACL,MAAM,CACP,CAAC;KACH;AAEM,IAAA,MAAM,CAAC,IAAY,EAAE,iBAAyB,IAAI,EAAE,SAAwB,EAAE,EAAA;AACnF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,EAAE,EACZ,EAAE,IAAI,EAAE,cAAc,EAAE,EACxB;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,UAAU,CAAC,QAAgB,EAAE,cAA6B,EAAE,SAAwB,EAAE,EAAA;AAC3F,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAE,CAAA,CAAC,EACzB,EAAE,cAAc,EAAE,EAClB;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;AAEM,IAAA,YAAY,CACjB,IAAY,EACZ,uBAA+B,IAAI,EACnC,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EACrB,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAC9B;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,YAAY,CACjB,cAAsB,EACtB,MAA+B,EAC/B,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,WAAW,cAAc,CAAA,CAAE,CAAC,EACvC,MAAM,EACN;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,YAAY,CAAC,cAAsB,EAAE,MAAA,GAAwB,EAAE,EAAA;AACpE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,WAAW,cAAc,CAAA,CAAE,CAAC,EACvC,EAAE,EACF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,cAAc,CAAC,cAAsB,EAAE,MAAA,GAAwB,EAAE,EAAA;AACtE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,WAAW,cAAc,CAAA,SAAA,CAAW,CAAC,EAChD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;AAEM,IAAA,MAAM,CAAC,QAAgB,EAAE,IAAY,EAAE,SAAwB,EAAE,EAAA;AACtE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAE,CAAA,CAAC,EACzB,EAAE,IAAI,EAAE,EACR;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;AASM,IAAA,MAAM,CAAC,QAAgB,EAAE,QAAiC,EAAE,SAAwB,EAAE,EAAA;AAC3F,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,CAAE,CAAC,EACzB,QAAQ,EACR;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,OAAO,CAAC,QAAgB,EAAE,MAAA,GAAwB,EAAE,EAAA;AACzD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,MAAA,CAAQ,CAAC,EAC/B,EAAE,EACF;AACE,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;IAKM,UAAU,CACf,QAAgB,EAChB,MAAc,EACd,IAA+C,EAC/C,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAU,OAAA,EAAA,MAAM,EAAE,CAAC,EACzC,IAAI,EACJ;AACE,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,UAAU,CAAC,QAAgB,EAAE,MAAc,EAAE,SAAwB,EAAE,EAAA;AAC5E,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAU,OAAA,EAAA,MAAM,EAAE,CAAC,EACzC,EAAE,EACF;AACE,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,iBAAiB,CACtB,QAAgB,EAChB,SAA8C,EAC9C,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAkB,gBAAA,CAAA,CAAC,EACzC,EAAE,SAAS,EAAE,EACb;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;IAKM,eAAe,CACpB,QAAgB,EAChB,WAAmB,EACnB,QAAiC,EACjC,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,WAAW,CAAC,EAC5D,QAAQ,EACR;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,OAAO,CACZ,QAAgB,EAChB,IAAoF,EACpF,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,WAAA,CAAa,CAAC,EACpC,IAAI,EACJ;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,eAAe,CACpB,QAAgB,EAChB,WAAmB,EACnB,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,EAAE,CAAC,EACnD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,MAAM,CAAC,QAAgB,EAAE,MAAA,GAAwB,EAAE,EAAA;AACxD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,CAAE,CAAC,EACzB,EAAE,EACF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,QAAQ,CAAC,QAAgB,EAAE,MAAA,GAAwB,EAAE,EAAA;AAC1D,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,SAAA,CAAW,CAAC,EAClC,EAAE,EACF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;AAMM,IAAA,GAAG,CAAC,QAAgB,EAAE,MAAA,GAAwB,EAAE,EAAA;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAG,EAAA,QAAQ,EAAE,CAAC,EACzB,EAAE,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EACvC;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,aAAa,CAClB,QAAgB,EAChB,SAAgG,EAChG,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAuB,qBAAA,CAAA,CAAC,EAC9C,EAAE,SAAS,EAAE,EACb;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;AASM,IAAA,aAAa,CAClB,QAAgB,EAChB,WAAmB,EACnB,UAAiC,EAAE,EACnC,KAA4B,GAAA,EAAE,EAC9B,QAAQ,GAAG,KAAK,EAChB,SAAwB,EAAE,EAAA;QAE1B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAA,YAAA,EAAe,WAAW,CAAO,KAAA,CAAA,CAAC,EACxD,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,EACpC;AACE,YAAA,GAAG,EAAE,MAAM;AACX,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;;AAUM,IAAA,aAAa,CAClB,QAAgB,EAChB,WAAmB,EACnB,OAA8B,EAC9B,KAAyB,EACzB,IAAiB,EACjB,QAAQ,GAAG,KAAK,EAChB,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,aAAa,CAAC,IAAI,EAClB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,YAAA,EAAe,WAAW,CAAA,KAAA,CAAO,CAAC,EACxD,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAC1C,MAAM,CACP,CAAC;KACH;;;;;;;;;;;;;;;;;;AAmBM,IAAA,UAAU,CACf,QAAgB,EAChB,MAAc,EACd,UAAiC,EAAE,EACnC,QAAQ,GAAG,KAAK,EAChB,MAAA,GAAwB,EAAE,EAC1B,mBAA6B,EAAE,EAAA;AAE/B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAU,OAAA,EAAA,MAAM,SAAS,CAAC,EAChD,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,gBAAgB,CAAC,MAAM,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,EAAE,EACvF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;;;;;AAaM,IAAA,eAAe,CACpB,QAAgB,EAChB,WAAmB,EACnB,OAAA,GAAiC,EAAE,EACnC,KAAA,GAA4B,EAAE,EAC9B,KAAK,GAAG,EAAE,EACV,SAAwB,EAAE,EAC1B,SAA6B,KAAK,EAAA;AAElC,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,SAAS,CAAC,EAC1D,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,MAAM,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,EAClE;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;;;;;;;;;;IAkBM,YAAY,CACjB,QAAgB,EAChB,OAAiC,GAAA,EAAE,EACnC,MAAwB,GAAA,IAAI,EAC5B,SAAA,GAAqC,IAAI,EACzC,cAAkC,EAAE,EACpC,MAA6C,GAAA,EAAE,EAC/C,MAAA,GAAiC,EAAE,EACnC,MAAwB,GAAA,EAAE,EAC1B,MAAA,GAA6B,KAAK,EAAA;AAElC,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAA,OAAA,CAAS,CAAC,EAChC;YACE,OAAO;AACP,YAAA,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC7B,YAAA,IAAI,SAAS,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACnC,YAAA,aAAa,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;AACnD,YAAA,IAAI,WAAW,CAAC,MAAM,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;AAC9C,YAAA,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACjD,YAAA,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACjD,YAAA,IAAI,MAAM,KAAK,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;SACxC,EACD;AACE,YAAA,GAAG,EAAE,KAAK;AACV,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,aAAa,CAAC,QAAgB,EAAE,QAAgB,EAAE,SAAwB,EAAE,EAAA;AACjF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAY,SAAA,EAAA,QAAQ,UAAU,CAAC,EACrD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;;;;AAYM,IAAA,YAAY,CACjB,QAAgB,EAChB,WAAmB,EACnB,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,MAAM,CAAC,EACvD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,gBAAgB,CAAC,QAAgB,EAAE,WAAmB,EAAE,SAAwB,EAAE,EAAA;AACvF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,UAAU,CAAC,EAC3D,EAAE,EACF;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;IAKM,SAAS,CACd,QAAgB,EAChB,WAAmB,EACnB,MAAiG,EACjG,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAe,YAAA,EAAA,WAAW,UAAU,CAAC,EAC3D,MAAM,EACN;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;IAGM,YAAY,CACjB,QAAgB,EAChB,QAAgB,EAChB,OAA8C,EAC9C,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAY,SAAA,EAAA,QAAQ,EAAE,CAAC,EAC7C,OAAO,EACP;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,YAAY,CAAC,QAAgB,EAAE,QAAgB,EAAE,SAAwB,EAAE,EAAA;AAChF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAY,SAAA,EAAA,QAAQ,EAAE,CAAC,EAC7C,EAAE,EACF;AACE,YAAA,GAAG,EAAE,QAAQ;AACb,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;IAIM,YAAY,CAAC,SAAwB,EAAE,EAAA;AAC5C,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAC1B,EAAE,EACF;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,gBAAgB,CAAC,OAAe,EAAE,MAAA,GAAwB,EAAE,EAAA;AACjE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAC1B,EAAE,OAAO,EAAE,EACX;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,kBAAkB,CAAC,aAAqB,EAAE,MAAA,GAAwB,EAAE,EAAA;AACzE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,gBAAgB,aAAa,CAAA,QAAA,CAAU,CAAC,EACnD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;IAKM,aAAa,CAAC,SAAwB,EAAE,EAAA;QAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,MAAM,EACN,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAC5B,EAAE,MAAM,EAAE,IAAI,EAAE,EAChB,MAAM,CACP,CAAC;KACH;;IAGM,mBAAmB,CAAC,SAAwB,EAAE,EAAA;AACnD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAC5B,EAAE,EACF;AACE,YAAA,GAAG,EAAE,IAAI;AACT,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;IAGM,iBAAiB,CAAC,SAAwB,EAAE,EAAA;AACjD,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,EACjC,EAAE,EACF;AACE,YAAA,GAAG,EAAE,OAAO;AACZ,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;AAKM,IAAA,uBAAuB,CAAC,MAAc,EAAE,MAAA,GAAwB,EAAE,EAAA;AACvE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,qBAAqB,MAAM,CAAA,UAAA,CAAY,CAAC,EACnD,EAAE,EACF;AACE,YAAA,GAAG,EAAE,iBAAiB;AACtB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;IAGM,QAAQ,CAAC,SAAwB,EAAE,EAAA;AACxC,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EACtB,EAAE,EACF;AACE,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;IAMM,OAAO,CAAC,SAAwB,EAAE,EAAA;AACvC,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EACrB,EAAE,EACF;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,YAAY,CAAC,QAA8C,EAAE,MAAA,GAAwB,EAAE,EAAA;AAC5F,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EACtB,QAAQ,EACR;AACE,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;;;;IASM,iBAAiB,CACtB,QAAgB,EAChB,OAAe,EACf,OAAiC,EACjC,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAiB,cAAA,EAAA,OAAO,EAAE,CAAC,EACjD,OAAO,EACP;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;;;IAMM,qBAAqB,CAC1B,QAAgB,EAChB,QAAgB,EAChB,IAAgC,EAChC,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAY,SAAA,EAAA,QAAQ,UAAU,CAAC,EACrD,IAAI,EACJ;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,YAAY,CAAC,QAAgB,EAAE,MAAA,GAAwB,EAAE,EAAA;AAC9D,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,aAAA,CAAe,CAAC,EACtC,EAAE,EACF;AACE,YAAA,GAAG,EAAE,cAAc;AACnB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;AAGM,IAAA,iBAAiB,CACtB,QAAgB,EAChB,WAA+C,EAC/C,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CACnB,IAAI,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAA,aAAA,CAAe,CAAC,EACtC,WAAW,EACX;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;IAGM,iBAAiB,CACtB,QAAgB,EAChB,mBAA2B,EAC3B,OAAiC,EACjC,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAiB,cAAA,EAAA,mBAAmB,EAAE,CAAC,EAC7D,OAAO,EACP;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;AAEM,IAAA,iBAAiB,CACtB,QAAgB,EAChB,mBAA2B,EAC3B,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CACrB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAiB,cAAA,EAAA,mBAAmB,EAAE,CAAC,EAC7D,EAAE,EACF;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;;;AAIM,IAAA,wBAAwB,CAC7B,QAAgB,EAChB,oBAA8B,EAC9B,SAAwB,EAAE,EAAA;AAE1B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,KAAK,CAAC,CAAA,EAAG,QAAQ,CAAyB,uBAAA,CAAA,CAAC,EAChD,EAAE,oBAAoB,EAAE,EACxB;AACE,YAAA,GAAG,EAAE,cAAc;AACnB,YAAA,GAAG,MAAM;AACV,SAAA,CACF,CAAC;KACH;wGA7zBU,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAV,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cAFT,MAAM,EAAA,CAAA,CAAA;;4FAEP,UAAU,EAAA,UAAA,EAAA,CAAA;kBAHtB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA,CAAA;;;ACRD;AACA;AACA;AACA;AACA;MAkBa,2BAA2B,CAAA;AAErB,IAAA,KAAK,GAAG,MAAM,CAA+B,eAAe,CAAC,CAAC;IAE/D,QAAQ,GAAG,MAAM,CAAsB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAE3D,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;;AAG3C,IAAA,OAAO,CAAC,OAA0B,EAAA;AACvC,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,iBAAiB;AACxB,YAAA,QAAQ,EAAE,qFAAqF;AAC/F,YAAA,WAAW,EAAE,SAAS;SACvB,CAAC;aACC,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAChE,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,YAAgC,KAAI;YAC9C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;AACzC,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAC5C,SAAC,CAAC,CAAC;KACN;wGA1BU,2BAA2B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAA3B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,2BAA2B,wEC9CxC,svDAyDA,EAAA,MAAA,EAAA,CAAA,oYAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDtBI,SAAS,EACT,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,yGAChB,gBAAgB,EAAA,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,cAAc,EACd,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,qXACZ,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,cAAc,EACd,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,2BAA2B,gGAC3B,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGN,2BAA2B,EAAA,UAAA,EAAA,CAAA;kBAjBvC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,SAAS;wBACT,gBAAgB;wBAChB,gBAAgB;wBAChB,cAAc;wBACd,YAAY;wBACZ,YAAY;wBACZ,cAAc;wBACd,2BAA2B;wBAC3B,eAAe;AAChB,qBAAA,EAAA,QAAA,EAAA,svDAAA,EAAA,MAAA,EAAA,CAAA,oYAAA,CAAA,EAAA,CAAA;;;AErCH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAca,oBAAoB,CAAA;AAEf,IAAA,OAAO,GAAG,KAAK,CAAS,EAAE,CAAC,CAAC;AAC5B,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,EAA0B,CAAC;wGAHvD,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,gZC7BjC,4eAaA,EAAA,MAAA,EAAA,CAAA,kJAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDWI,WAAW,EACX,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,4gBACZ,yBAAyB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,UAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EANZ,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FASxD,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAbhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,2CAA2C,iBAGtC,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAClD,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,YAAY;wBACZ,yBAAyB;AAC1B,qBAAA,EAAA,QAAA,EAAA,4eAAA,EAAA,MAAA,EAAA,CAAA,kJAAA,CAAA,EAAA,CAAA;;;AElBH;AACA;AACA;AACA;AACA;AACA;AACA;MAiBa,gBAAgB,CAAA;AAEX,IAAA,WAAW,GAAG,KAAK,CAAS,CAAC,CAAC,CAAC;AAC/B,IAAA,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAU,CAAC;AAC/B,IAAA,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAU,CAAC;wGAJpC,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,mBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EChC7B,4qBAmBA,EAAA,MAAA,EAAA,CAAA,4EAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDKI,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACX,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,UAAA,EAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,YAAY,EACZ,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAQ,EACR,QAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,OAAO,8EACP,QAAQ,EAAA,QAAA,EAAA,yHAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,IAAA,EAAA,aAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,mBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EATK,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAYxD,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAhB5B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sCAAsC,iBAGjC,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAClD,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,YAAY;wBACZ,YAAY;wBACZ,QAAQ;wBACR,OAAO;wBACP,QAAQ;AACT,qBAAA,EAAA,QAAA,EAAA,4qBAAA,EAAA,MAAA,EAAA,CAAA,4EAAA,CAAA,EAAA,CAAA;;;AELH;AACA;AACA;AACA;MAiBa,wBAAwB,CAAA;;IAG3B,OAAgB,WAAW,GAA2B;AAC5D,QAAA,aAAa,EAAE,SAAS;AACxB,QAAA,eAAe,EAAE,SAAS;AAC1B,QAAA,OAAO,EAAE,SAAS;AAClB,QAAA,UAAU,EAAE,SAAS;AACrB,QAAA,UAAU,EAAE,SAAS;AACrB,QAAA,OAAO,EAAE,SAAS;KACnB,CAAC;;AAGM,IAAA,OAAgB,UAAU,GAAG,CAAC,aAAa,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;;;IAIxG,OAAgB,aAAa,GAA2C;AAC9E,QAAA,KAAK,EAAE,iBAAiB;AACxB,QAAA,OAAO,EAAE,mBAAmB;AAC5B,QAAA,KAAK,EAAE,gBAAgB;KACxB,CAAC;AAEe,IAAA,KAAK,GAAG,MAAM,CAA4B,eAAe,CAAC,CAAC;AAE5D,IAAA,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IACjC,WAAW,GAAG,wBAAwB,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;;AAGxE,IAAA,eAAe,GAAG,MAAM,CAAiC,IAAI,CAAC,CAAC;;;AAI/D,IAAA,eAAe,GAAG,QAAQ,CAAgB,MAAK;AAC7D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;AAEtC,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,GAAG,MAAM,EAAE,YAAY,GAAG,MAAM,EAAE,UAAU,CAAC;AACrF,KAAC,CAAC,CAAC;;AAGa,IAAA,SAAS,GAAG,QAAQ,CAA2B,MAC7D,IAAI,CAAC,cAAc,CACjB,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,SAAS,IAAI,EAAE;AACrC,SAAA,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CACnD,CACF,CAAC;AAEF,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,UAAU,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;aAC7D,IAAI,CAAC,kBAAkB,EAAE,CAAC;AAC1B,aAAA,SAAS,CAAC,CAAC,eAAwC,KAAI;AACtD,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC5C,SAAC,CAAC,CAAC;KACN;AAEM,IAAA,SAAS,CAAC,IAAY,EAAA;AAC3B,QAAA,OAAO,wBAAwB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,WAAW,CAAC,KAAK,CAAC;KACjG;AAEO,IAAA,cAAc,CAAC,SAAmC,EAAA;QACxD,OAAO,CAAC,GAAG,SAAS,CAAC;AAClB,aAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AACb,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAEjE,OAAO,QAAQ,KAAK,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACtE,SAAC,CAAC,CAAC;KACN;AAEO,IAAA,SAAS,CAAC,IAAY,EAAA;QAC5B,MAAM,IAAI,GAAG,wBAAwB,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAE/D,QAAA,OAAO,IAAI,KAAK,CAAC,CAAC,GAAG,wBAAwB,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;KACxE;wGAxEU,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,wBAAwB,wEC7CrC,oyDAsDA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDnBI,SAAS,EAAA,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,cAAc,oLACd,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,WAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,UAAA,EAAA,SAAA,EAAA,eAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAc,8TACd,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGP,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAhBpC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,SAAS;wBACT,gBAAgB;wBAChB,gBAAgB;wBAChB,cAAc;wBACd,YAAY;wBACZ,YAAY;wBACZ,cAAc;wBACd,gBAAgB;AACjB,qBAAA,EAAA,QAAA,EAAA,oyDAAA,EAAA,MAAA,EAAA,CAAA,8nBAAA,CAAA,EAAA,CAAA;;;AECH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAgBa,yBAAyB,CAAA;;IAG5B,OAAgB,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAEhD,OAAgB,YAAY,GAA2B;AAC7D,QAAA,CAAC,EAAE,QAAQ;AACX,QAAA,CAAC,EAAE,SAAS;AACZ,QAAA,CAAC,EAAE,UAAU;AACb,QAAA,CAAC,EAAE,WAAW;AACd,QAAA,CAAC,EAAE,SAAS;AACZ,QAAA,CAAC,EAAE,QAAQ;KACZ,CAAC;;;;IAKM,OAAgB,SAAS,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;;;;AAK7C,IAAA,OAAgB,aAAa,GAAG,SAAS,CAAC;;;;;AAM1C,IAAA,OAAgB,WAAW,GAAG,OAAO,CAAC;;AAG9B,IAAA,MAAM,GAAG,MAAM,CAA6B,IAAI,CAAC,CAAC;;;AAIlD,IAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;AAI5B,IAAA,MAAM,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;;AAG5B,IAAA,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAEzB,WAAW,GAAG,QAAQ,CAAU,MAC9C,IAAI,CAAC,QAAQ,EAAE;AACV,WAAA,yBAAyB,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CACnF,CAAC;;;AAIc,IAAA,OAAO,GAAG,QAAQ,CAAU,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IAExE,eAAe,GAAG,QAAQ,CAAS,MACjD,yBAAyB,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAC1E,CAAC;;;;;;;;;;;AAYc,IAAA,aAAa,GAAG,QAAQ,CAAU,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC;;;;AAKnF,IAAA,qBAAqB,GAAG,QAAQ,CAAS,MACvD,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE;AACnC,SAAA,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC;AACtD,SAAA,MAAM,CACV,CAAC;;;;AAKc,IAAA,UAAU,GAAG,QAAQ,CAAU,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;;;IAI9E,cAAc,GAAG,QAAQ,CAAuB,MAC9D,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,cAAc,KAAK,UAAU,CAAC,CACtE,CAAC;;;;AAKc,IAAA,iBAAiB,GAAG,QAAQ,CAAuB,MACjE,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,cAAc,KAAK,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CACxF,CAAC;;;;;AAMc,IAAA,KAAK,GAAG,QAAQ,CAAqB,MAAK;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,MAAM;YACxD,GAAG,EAAE,MAAM,CAAC,GAAG;AACf,YAAA,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;AACjD,YAAA,QAAQ,EAAE,IAAI;YACd,MAAM;YACN,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,aAAa,EAAE,MAAM,CAAC,aAAa;AACpC,SAAA,CAAC,CAAC,CAAC;AAEJ,QAAA,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAwB,MAAM;YACxE,GAAG,EAAE,IAAI,CAAC,GAAG;AACb,YAAA,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC;AAC7C,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,MAAM,EAAE,IAAI;YACZ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,aAAa,EAAE,IAAI,CAAC,aAAa;AAClC,SAAA,CAAC,CAAC,CAAC;AAEJ,QAAA,OAAO,CAAC,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;AAC7B,aAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAClD,KAAC,CAAC,CAAC;;;AAIa,IAAA,aAAa,GAAG,QAAQ,CAAqB,MAAK;AAChE,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC;SACrB;AAED,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,KAC9B,CAAA,EAAG,IAAI,CAAC,IAAI,CAAI,CAAA,EAAA,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA,CAAA,EAAI,IAAI,CAAC,GAAG,CAAE,CAAA,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AACnF,KAAC,CAAC,CAAC;;;AAIa,IAAA,QAAQ,GAAG,QAAQ,CAAS,MAAK;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC;QACrC,IAAI,CAAC,MAAM,EAAE;AACX,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,KAAK,GAAG,CAAC,CAAA,EAAG,MAAM,CAAC,WAAW,CAAW,SAAA,CAAA,EAAE,GAAG,MAAM,CAAC,UAAU,CAAA,aAAA,CAAe,CAAC,CAAC;AAEtF,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;AACrB,YAAA,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,qBAAqB;kBACnC,GAAG,MAAM,CAAC,aAAa,CAAe,YAAA,EAAA,MAAM,CAAC,qBAAqB,CAAc,YAAA,CAAA;AAClF,kBAAE,CAAG,EAAA,MAAM,CAAC,aAAa,CAAA,UAAA,CAAY,CAAC,CAAC;SAC1C;QAED,KAAK,CAAC,IAAI,CAAC,CAAA,EAAG,MAAM,CAAC,aAAa,CAAiB,eAAA,CAAA,CAAC,CAAC;AAErD,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE,EAAE;YACrB,KAAK,CAAC,IAAI,CAAC,CAAA,EAAG,MAAM,CAAC,aAAa,CAAkB,gBAAA,CAAA,CAAC,CAAC;SACvD;AAED,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,KAAC,CAAC,CAAC;;;AAIc,IAAA,OAAO,GAAG,QAAQ,CAAuB,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;;;IAI7F,eAAe,GAAG,KAAK,CAAC;AAEf,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAElD,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,KAAK,EAAE,CAAC;KACd;;;IAIM,KAAK,GAAA;AACV,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;AAE/B,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;YACnB,KAAK,EAAE,OAAO,GAAG,2BAA2B,GAAG,yBAAyB;AACxE,YAAA,QAAQ,EAAE,OAAO;AACf,kBAAE,yGAAyG;AAC3G,kBAAE,yDAAyD;YAC7D,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO;SAC3C,CAAC;AACC,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;KACtC;IAEM,SAAS,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,YAAY;AACnB,YAAA,QAAQ,EAAE,8FAA8F;AACxG,YAAA,WAAW,EAAE,MAAM;SACpB,CAAC;aACC,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE,CAAC,EACrD,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACzB,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;YAC7C,IAAI,CAAC,cAAc,EAAE,CAAC;AACxB,SAAC,CAAC,CAAC;KACN;;;;IAKO,SAAS,GAAA;AACf,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;AAE7B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;aAC7C,IAAI;;;AAGH,QAAA,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,EACrD,MAAM,CAAC,CAAC,KAAK,KACX,KAAK,EAAE,IAAI,KAAK,eAAe,CAAC,IAAI;eACjC,yBAAyB,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;eAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,EACzC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,IAAc,CAAC,CAC1C,CAAC;AAEJ,QAAA,IAAI,CAAC,QAAQ;AACV,aAAA,GAAG,CAAC,yBAAyB,EAAE,OAAO,CAAC;aACvC,UAAU;AACV,aAAA,IAAI,CACH,IAAI,CAAC,CAAC,CAAC,EACP,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;KAC/C;AAED;;;;;;;;AAQG;AACK,IAAA,cAAc,CAAC,WAAoB,EAAA;AACzC,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;YACxB,OAAO;SACR;AACD,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;AAE5B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEzB,IAAI,WAAW,EAAE;YACf,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;AAEpD,YAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM;kBACtB,CAAwC,qCAAA,EAAA,MAAM,CAAE,CAAA;kBAChD,oFAAoF,CAAC,CAAC;YAC1F,IAAI,CAAC,cAAc,EAAE,CAAC;YAEtB,OAAO;SACR;QAED,IAAI,CAAC,WAAW,EAAE;AACf,aAAA,SAAS,CAAC,CAAC,MAA2B,KAAK,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;KAC9E;AAED;;;;;;;AAOG;AACK,IAAA,kBAAkB,CAAC,WAAoB,EAAA;QAC7C,MAAM,KAAK,GAAG,WAAoE,CAAC;AAEnF,QAAA,IAAI,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;AACzB,YAAA,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;SAC5B;AAED,QAAA,MAAM,UAAU,GAAG,KAAK,EAAE,UAAU,CAAC;AACrC,QAAA,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,eAAe,EAAE;AACjD,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;aACjC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAC1B,aAAA,MAAM,CAAC,CAAC,IAAI,KAAI;YACf,IAAI,CAAC,IAAI,EAAE;AACT,gBAAA,OAAO,KAAK,CAAC;aACd;AAED,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAEjB,gBAAA,OAAO,KAAK,CAAC;aACd;AAAC,YAAA,MAAM;AACN,gBAAA,OAAO,IAAI,CAAC;aACb;AACH,SAAC,CAAC,CAAC;QAEL,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;KACxD;AAED;;;;AAIG;AACK,IAAA,gBAAgB,CAAC,MAA2B,EAAA;AAClD,QAAA,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,CAAC;AAC5B,QAAA,IAAI,KAAK,EAAE,KAAK,KAAK,GAAG,IAAI,KAAK,EAAE,KAAK,KAAK,GAAG,EAAE;YAChD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,IAAI,6CAA6C,CAAC,CAAC;SACrF;AAAM,aAAA,IAAI,KAAK,EAAE,KAAK,KAAK,GAAG,EAAE;AAC/B,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;SAC5D;KACF;IAEM,YAAY,GAAA;QACjB,OAAO,yBAAyB,CAAC,aAAa,CAAC;KAChD;AAED;;;AAGG;AACI,IAAA,aAAa,CAAC,IAAsB,EAAA;AACzC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAEnC,QAAA,OAAO,MAAM;cACT,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC;cAC/D,EAAE,CAAC;KACR;AAEM,IAAA,SAAS,CAAC,KAAa,EAAA;AAC5B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACxB;AAED;;;;AAIG;IACI,aAAa,CAAC,IAAsB,EAAE,MAA8B,EAAA;AACzE,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE;AAC1C,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,QAAQ,EAAE,MAAM;AAChB,YAAA,SAAS,EAAE,MAAM;AACjB,YAAA,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE;AACtC,SAAA,CAAC,CAAC;KACJ;IAEO,KAAK,GAAA;QACX,IAAI,CAAC,cAAc,EAAE,CAAC;KACvB;AAED;;;;;AAKG;IACK,YAAY,CAAC,KAAoB,EAAE,GAAW,EAAA;QACpD,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,GAAG,CAAC;SACZ;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAE1C,OAAO,SAAS,CAAC,MAAM,GAAG,yBAAyB,CAAC,WAAW,CAAC,MAAM;AACjE,eAAA,SAAS,CAAC,QAAQ,CAAC,yBAAyB,CAAC,WAAW,CAAC;AAC5D,cAAE,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,yBAAyB,CAAC,WAAW,CAAC,MAAM,CAAC;cACjE,SAAS,CAAC;KACf;IAEO,cAAc,GAAA;QACpB,IAAI,CAAC,WAAW,EAAE;AACf,aAAA,SAAS,EAAE,CAAC;KAChB;;;IAIO,WAAW,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE;AAC1C,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,MAA2B,KAAI;AAClC,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5B,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1B,SAAC,CAAC,EACF,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAE3B,YAAA,OAAO,KAAK,CAAC;SACd,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC,CAAC;KACL;wGA1ZU,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAzB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,yBAAyB,ECtEtC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gDAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,2sXAgRA,EDlNI,MAAA,EAAA,CAAA,q2BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,kBAAkB,EAClB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAF,IAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,aAAA,EAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,iBAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,uCAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,WAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,UAAA,EAAA,SAAA,EAAA,eAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,yHACf,gBAAgB,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGP,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAfrC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gDAAgD,mBAGzC,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,kBAAkB;wBAClB,gBAAgB;wBAChB,YAAY;wBACZ,YAAY;wBACZ,eAAe;wBACf,gBAAgB;AACjB,qBAAA,EAAA,QAAA,EAAA,2sXAAA,EAAA,MAAA,EAAA,CAAA,q2BAAA,CAAA,EAAA,CAAA;;;AE3CH;AACA;AACA,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB;AACA;AACA,MAAM,QAAQ,GAAG;IACf,YAAY;IACZ,EAAE;IACF,gIAAgI;IAChI,EAAE;IACF,kBAAkB;IAClB,EAAE;IACF,kEAAkE;IAClE,EAAE;IACF,iBAAiB;IACjB,EAAE;IACF,oEAAoE;IACpE,EAAE;AACH,CAAA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAGb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAsBa,uBAAuB,CAAA;IAE3B,WAAW,GAAG,WAAW,CAAC;;;AAIjB,IAAA,gBAAgB,GAAG,SAAS,CAAC,yBAAyB,CAAC,CAAC;;;AAIxD,IAAA,OAAO,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;AAE7B,IAAA,YAAY,GAA2B;AACrD,QAAA,SAAS,EAAE,UAAU;AACrB,QAAA,WAAW,EAAE,0EAA0E;KACxF,CAAC;;AAGc,IAAA,YAAY,GAAG,MAAM,CAA4B,IAAI,CAAC,CAAC;AACvD,IAAA,QAAQ,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;;AAG/C,IAAA,WAAW,GAAG,MAAM,CAAS,CAAC,CAAC,CAAC;;IAGhC,MAAM,GAAG,QAAQ,CAAU,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE5E,IAAA,UAAU,GAAG,MAAM,CAAwC,YAAY,CAAC,CAAC;AACzE,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAElD,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,KAAK,EAAE,CAAC;KACd;;;;IAKM,IAAI,GAAG,MAAK;AACjB,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,EAAE;AAClC,YAAA,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,wBAAwB,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;AACnF,iBAAA,IAAI,CACH,GAAG,CAAC,CAAC,QAAwB,KAAI;AAC/B,gBAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;AAC9B,gBAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;aACzC,CAAC,CACH,CAAC;SACL;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;AACrD,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,YAAgC,KAAI;AACvC,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAC5C,YAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;SACrC,CAAC,CACH,CAAC;AACN,KAAC,CAAC;;;;;IAMK,WAAW,GAAA;QAChB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC;AAExD,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,2BAA2B,EAAE;AAC7C,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,QAAQ,EAAE,MAAM;AAChB,YAAA,SAAS,EAAE,MAAM;AACjB,YAAA,SAAS,EAAE,KAAK;AAChB,YAAA,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,IAAI,EAAE,EAAE;SACxD,CAAC;AACC,aAAA,WAAW,EAAE;aACb,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,EAChD,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,YAAgC,KAAI;YAC9C,IAAI,YAAY,CAAC,YAAY,EAAE,EAAE,KAAK,SAAS,EAAE;AAC/C,gBAAA,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;aACvC;iBAAM;AACL,gBAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;aACrC;AACH,SAAC,CAAC,CAAC;KACN;IAEO,KAAK,GAAA;AACX,QAAA,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;AAC5B,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,YAAgC,KAAK,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;AAE1F,QAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;AACxB,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,QAAwB,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;KAC3E;AAEO,IAAA,kBAAkB,CAAC,YAAgC,EAAA;AACzD,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACpC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,IAAI,QAAQ,CAAC,CAAC;KAClE;AAEO,IAAA,cAAc,CAAC,QAAwB,EAAA;AAC7C,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;KACzD;wGA1GU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,EAMW,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,yBAAyB,ECtFxE,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,62GAkGA,EDjCI,MAAA,EAAA,CAAA,wBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,EACX,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAJ,IAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,MAAA,EAAA,QAAA,EAAA,wDAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAc,EACd,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,cAAA,EAAA,WAAA,EAAA,SAAA,EAAA,eAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,SAAA,EAAA,OAAA,EAAA,WAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,oBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,EACT,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,cAAc,EACd,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,aAAa,EACb,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,WAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,oBAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,qBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,oBAAoB,EACpB,QAAA,EAAA,2CAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,wJAChB,yBAAyB,EAAA,QAAA,EAAA,gDAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGhB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBArBnC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,cAAc;wBACd,YAAY;wBACZ,gBAAgB;wBAChB,YAAY;wBACZ,SAAS;wBACT,gBAAgB;wBAChB,cAAc;wBACd,gBAAgB;wBAChB,aAAa;wBACb,oBAAoB;wBACpB,gBAAgB;wBAChB,yBAAyB;AAC1B,qBAAA,EAAA,QAAA,EAAA,62GAAA,EAAA,MAAA,EAAA,CAAA,wBAAA,CAAA,EAAA,CAAA;;;AE9EH;AACA;AACA;AACA;AACA;AA8TA;AACA;AACA;AACa,MAAA,mBAAmB,GAAgD;AAC9E,IAAA,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AAC7B,IAAA,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;AAC/B,IAAA,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE;AACjC,IAAA,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;AACrC,IAAA,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE;EACnC;IAmtBU,eAGX;AAHD,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,cAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACnB,CAAC,EAHW,cAAc,KAAd,cAAc,GAGzB,EAAA,CAAA,CAAA,CAAA;AAuBD;AACA;AACA;AACA;IACY,YAGX;AAHD,CAAA,UAAY,WAAW,EAAA;AACrB,IAAA,WAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,WAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EAHW,WAAW,KAAX,WAAW,GAGtB,EAAA,CAAA,CAAA;;ACjhCD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAgBa,oBAAoB,CAAA;;AAGf,IAAA,QAAQ,GAAG,KAAK,CAAS,SAAS,CAAC,CAAC;;;AAIpC,IAAA,WAAW,GAAG,KAAK,CAAS,KAAK,CAAC,CAAC;;AAGnC,IAAA,aAAa,GAAG,KAAK,CAAS,KAAK,CAAC,CAAC;;AAGrC,IAAA,KAAK,GAAG,MAAM,CAAe,IAAI,CAAC,CAAC;AAE5C,IAAA,UAAU,CAA4B;AACtC,IAAA,YAAY,CAAe;;IAGlB,QAAQ,GAAG,cAAc,CAAC;AAEzB,IAAA,KAAK,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;AAE5C,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACzB,IAAA,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAChC,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;;IAGjC,MAAM,GAA4B,EAAE,CAAC;;;;IAKrC,qBAAqB,GAAoB,IAAI,CAAC;AAEtD,IAAA,WAAA,GAAA;QACE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9C,SAAC,CAAC,CAAC;KACJ;IAEM,QAAQ,GAAA;;;QAGb,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE5C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;KACd;;AAGM,IAAA,QAAQ,CAAC,MAAsB,EAAA;AACpC,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;KAC7D;;;IAIM,YAAY,CAAC,iBAAyB,IAAI,EAAA;AAC/C,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AACjB,YAAA,KAAK,EAAE,eAAe;AACtB,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,WAAW,EAAE,QAAQ;AACrB,YAAA,QAAQ,EAAE,IAAI;SACf,CAAC;aACC,IAAI,CACHG,WAAS,CAAC,CAAC,IAAY,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,EAC1E,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,MAAsB,KAAI;AACpC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;AACrC,YAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CACnB,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,EACzC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAC3D,CAAC;AACJ,SAAC,CAAC,CAAC;KACN;;;;IAKM,YAAY,GAAA;AACjB,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,uBAAuB,EAAE;AACzC,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,QAAQ,EAAE,MAAM;AAChB,YAAA,SAAS,EAAE,MAAM;AACjB,YAAA,SAAS,EAAE,KAAK;AACjB,SAAA,CAAC,CAAC;KACJ;IAEO,iBAAiB,GAAA;QACvB,IAAI,CAAC,YAAY,GAAG;AAClB,YAAA,KAAK,EAAE;AACL,gBAAA;AACE,oBAAA,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,QAAQ,CAAC,OAAO;AACtB,oBAAA,KAAK,EAAE,QAAQ;AAChB,iBAAA;;;;;;AAMD,gBAAA;AACE,oBAAA,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ,CAAC,QAAQ;AACvB,oBAAA,KAAK,EAAE,cAAc;AACrB,oBAAA,OAAO,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;AAC7D,iBAAA;AACF,aAAA;AACD,YAAA,OAAO,EAAE;AACP,gBAAA;AACE,oBAAA,IAAI,EAAE,aAAa;AACnB,oBAAA,OAAO,EAAE,YAAY;AACrB,oBAAA,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE;AACvC,iBAAA;AACD,gBAAA;AACE,oBAAA,IAAI,EAAE,aAAa;AACnB,oBAAA,OAAO,EAAE,cAAc;AACvB,oBAAA,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE;AACzC,iBAAA;AACD,gBAAA;AACE,oBAAA,IAAI,EAAE,UAAU;AAChB,oBAAA,OAAO,EAAE,iBAAiB;AAC1B,oBAAA,OAAO,EAAE,KAAK;AACd,oBAAA,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;AACjC,iBAAA;AACD,gBAAA;AACE,oBAAA,KAAK,EAAE,YAAY;AACnB,oBAAA,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;AACtC,iBAAA;AACD,gBAAA;AACE,oBAAA,KAAK,EAAE,QAAQ;AACf,oBAAA,OAAO,EAAE,IAAI;AACb,oBAAA,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;AACjC,iBAAA;AACF,aAAA;;;;;;;AAOD,YAAA,MAAM,EAAE,CAAC,KAAK,KAAI;gBAChB,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;gBAC1F,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACpF,gBAAA,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;gBAE3B,IAAI,cAAc,EAAE;AAClB,oBAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;iBAC9B;gBAED,IAAI,YAAY,EAAE;oBAChB,IAAI,CAAC,KAAK,EAAE,CAAC;iBACd;aACF;SACF,CAAC;KACH;IAEO,eAAe,GAAA;;QAErB,IAAI,CAAC,UAAU,GAAG;AAChB,YAAA,IAAI,EAAE,EAAE;AACR,YAAA,YAAY,EAAE,UAAU;AACxB,YAAA,SAAS,EAAE,IAAI;;;;YAIf,QAAQ,EAAE,YAAY,CAAC,IAAI;;;AAG3B,YAAA,OAAO,EAAE,CAAC,IAAkB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;;;;;;;YAO3D,OAAO,EAAE,CAAC,IAAkB,EAAE,UAAwB,EAAE,QAAsB,KAAI;AAChF,gBAAA,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;aACtF;YACD,aAAa,EAAE,CAAC,KAAyB,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAC/D,SAAS,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,IAAI,EAAE,IAAI;;;;AAIlD,YAAA,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,KAAI;gBAC1B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;AACjC,qBAAA,WAAW,EAAE;qBACb,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;aAChD;AACD,YAAA,OAAO,EAAE;AACP,gBAAA;oBACE,IAAI,EAAE,cAAc,CAAC,IAAI;AACzB,oBAAA,IAAI,EAAE,WAAW;AACjB,oBAAA,KAAK,EAAE;AACL,wBAAA;AACE,4BAAA,KAAK,EAAE,QAAQ;AACf,4BAAA,IAAI,EAAE,CAAC,IAAkB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;4BACxD,KAAK,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;AAClD,yBAAA;AACD,wBAAA;AACE,4BAAA,KAAK,EAAE,YAAY;AACnB,4BAAA,IAAI,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;AACpF,4BAAA,KAAK,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AAChE,yBAAA;AACD,wBAAA;AACE,4BAAA,KAAK,EAAE,YAAY;AACnB,4BAAA,IAAI,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;AACpF,4BAAA,KAAK,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AACjE,yBAAA;AACD,wBAAA;AACE,4BAAA,KAAK,EAAE,QAAQ;AACf,4BAAA,IAAI,EAAE,CAAC,IAAkB,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;4BACxD,KAAK,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;AAClD,yBAAA;;;AAGD,wBAAA;AACE,4BAAA,KAAK,EAAE,SAAS;4BAChB,IAAI,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;4BACvD,KAAK,EAAE,CAAC,IAAkB,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AACnD,yBAAA;AACF,qBAAA;AACF,iBAAA;AACF,aAAA;SACF,CAAC;KACH;AAEO,IAAA,aAAa,CAAC,IAAkB,EAAA;QACtC,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,cAAc,CAAC,MAAM,CAAC;KACnD;AAEO,IAAA,cAAc,CAAC,IAAkB,EAAA;AACvC,QAAA,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;KAC9B;;;;;AAMO,IAAA,OAAO,CAAC,OAAe,EAAA;AAC7B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,IAAI,OAAO,EAAE;AACX,YAAA,IAAI,CAAC,qBAAqB,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;AACpD,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO;SACR;QAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACnB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;AACnD,QAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;KACnC;IAEO,KAAK,GAAA;;;;QAIX,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;AAEpE,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,aAAA,IAAI,CACH,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,UAAsB,KAAI;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;AAC3C,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;;;AAKtB,YAAA,IAAI,CAAC,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAEtD,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,EAAE;gBACT,OAAO;aACR;;;;;AAMD,YAAA,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;AAC1C,YAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACpB,YAAA,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAE/B,YAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAClD,IAAI,OAAO,EAAE;AACX,gBAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;aACtB;AACH,SAAC,CAAC,CAAC;KACN;;IAGO,aAAa,GAAA;AACnB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,IAAI,GAAG,CAAC,MAAoB,KAAe,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;aACnE,MAAM,CAAC,CAAC,IAAkB,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;aACjD,OAAO,CAAC,CAAC,IAAkB,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEpE,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;KACnB;AAEO,IAAA,WAAW,CAAC,IAAc,EAAA;AAChC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACzB,OAAO;SACR;AAED,QAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3B,QAAA,MAAM,IAAI,GAAG,CAAC,MAAoB,KAAU;AAC1C,YAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;AAClB,iBAAA,MAAM,CAAC,CAAC,IAAkB,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACxD,iBAAA,OAAO,CAAC,CAAC,IAAkB,KAAI;gBAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,IAAI,CAAC,IAAI,CAAC,CAAC;AACb,aAAC,CAAC,CAAC;AACP,SAAC,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,CAAC;KACZ;;;;;;;;AASO,IAAA,WAAW,CAAC,UAAsB,EAAA;AACxC,QAAA,MAAM,OAAO,GAAG,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC;AAC1C,QAAA,MAAM,OAAO,GAAG,UAAU,EAAE,OAAO,IAAI,EAAE,CAAC;AAE1C,QAAA,MAAM,KAAK,GAAG,CAAC,QAAuB,EAAE,aAAsB,KAAkB;YAC9E,MAAM,WAAW,GAAiB,OAAO;AACtC,iBAAA,MAAM,CAAC,CAAC,MAAoB,KAAK,CAAC,MAAM,CAAC,oBAAoB,IAAI,IAAI,MAAM,QAAQ,CAAC;AACpF,iBAAA,GAAG,CAAC,CAAC,MAAoB,KAAI;gBAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC;AAC1D,gBAAA,MAAM,OAAO,GAAG,aAAa,IAAI,YAAY,CAAC;gBAE9C,OAAO;AACL,oBAAA,GAAG,EAAE,CAAA,EAAA,EAAK,MAAM,CAAC,EAAE,CAAE,CAAA;oBACrB,EAAE,EAAE,MAAM,CAAC,EAAE;oBACb,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE,cAAc,CAAC,MAAM;oBAC3B,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC;oBACnC,YAAY;oBACZ,OAAO;iBACR,CAAC;AACJ,aAAC,CAAC,CAAC;YAEL,MAAM,WAAW,GAAiB,OAAO;AACtC,iBAAA,MAAM,CAAC,CAAC,MAAsB,KAAK,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,MAAM,QAAQ,CAAC;AAChF,iBAAA,GAAG,CAAC,CAAC,MAAsB,KAAI;gBAC9B,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,CAAC;gBAE1D,OAAO;AACL,oBAAA,GAAG,EAAE,CAAA,EAAA,EAAK,MAAM,CAAC,EAAE,CAAE,CAAA;oBACrB,EAAE,EAAE,MAAM,CAAC,EAAE;oBACb,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,IAAI,EAAE,cAAc,CAAC,MAAM;AAC3B,oBAAA,QAAQ,EAAE,EAAE;oBACZ,MAAM;oBACN,YAAY;oBACZ,OAAO,EAAE,aAAa,IAAI,YAAY;iBACvC,CAAC;AACJ,aAAC,CAAC,CAAC;AAEL,YAAA,OAAO,CAAC,GAAG,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC;AAC1C,SAAC,CAAC;AAEF,QAAA,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;KAC3B;;;;AAKO,IAAA,KAAK,CAAC,KAAyB,EAAA;AACrC,QAAA,MAAM,IAAI,GAAe,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAC1C,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,oBAAoB,GAAW,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,IAAI,CAAC;AAEtE,QAAA,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE;AAClD,YAAA,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;SACzB;QAED,MAAM,KAAK,GAAwB,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM;AACpE,cAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,oBAAoB,EAAE,CAAC;AAClE,cAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC;QAE/D,KAAK;AACF,aAAA,IAAI,CACH,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC;YACT,IAAI,EAAE,MAAK;AACT,gBAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;gBACvC,IAAI,CAAC,KAAK,EAAE,CAAC;aACd;AACD,YAAA,KAAK,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE;AAC1B,SAAA,CAAC,CAAC;KACN;AAEO,IAAA,aAAa,CAAC,oBAA4B,EAAA;AAChD,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AACjB,YAAA,KAAK,EAAE,YAAY;AACnB,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,WAAW,EAAE,QAAQ;AACrB,YAAA,QAAQ,EAAE,IAAI;SACf,CAAC;aACC,IAAI,CACHA,WAAS,CAAC,CAAC,IAAY,KAAK,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC,EACtF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE,CAAC;AACf,SAAC,CAAC,CAAC;KACN;AAEO,IAAA,OAAO,CAAC,IAAkB,EAAA;AAChC,QAAA,MAAM,IAAI,GAAe,IAAI,EAAE,IAAI,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM,CAAC;AAEnD,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACjB,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe;AACjD,YAAA,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,IAAI,CAAC,IAAI;AAClB,YAAA,WAAW,EAAE,MAAM;AACnB,YAAA,QAAQ,EAAE,IAAI;SACf,CAAC;aACC,IAAI,CACHA,WAAS,CAAC,CAAC,IAAY,MAAM,MAAM;AACjC,cAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;cAChD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EAC5C,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,EAAE,CAAC;AACf,SAAC,CAAC,CAAC;KACN;;;;AAKO,IAAA,OAAO,CAAC,IAAkB,EAAA;AAChC,QAAA,MAAM,IAAI,GAAe,IAAI,EAAE,IAAI,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM,CAAC;AAEnD,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,QAAQ,EAAE,MAAM;AACd,kBAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;AACjC,kBAAE,oDAAoD;SACzD,CAAC;AACC,aAAA,IAAI,CACHA,WAAS,CAAC,OAAO,MAAM;cACnB,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;cACtC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EACtC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,gBAAgB,GAAG,gBAAgB,CAAC,CAAC;YACpE,IAAI,CAAC,KAAK,EAAE,CAAC;AACf,SAAC,CAAC,CAAC;KACN;;;;AAKO,IAAA,oBAAoB,CAAC,MAAkB,EAAA;QAC7C,MAAM,KAAK,GAAG,CAAC,IAAgB,KAA2C,IAAI,CAAC,QAAQ;aACpF,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;AACjC,aAAA,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,KAAI;AACvB,YAAA,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAE3B,OAAO;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;gBACvF,OAAO,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;aACxF,CAAC;SACH,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QAEjC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC3C,QAAA,MAAM,QAAQ,GAAG;YACf,OAAO,GAAG,CAAA,EAAG,OAAO,CAAI,CAAA,EAAA,OAAO,KAAK,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAE,CAAA,GAAG,EAAE;YACnE,OAAO,GAAG,CAAA,EAAG,OAAO,CAAI,CAAA,EAAA,OAAO,KAAK,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAE,CAAA,GAAG,EAAE;AACpE,SAAA,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAElB,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAY,SAAA,EAAA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA,UAAA,CAAY,GAAG,EAAE,CAAC;AAErF,QAAA,OAAO,qDAAqD,MAAM,CAAC,IAAI,CAAI,CAAA,EAAA,MAAM,yCAAyC,CAAC;KAC5H;;;AAIO,IAAA,QAAQ,CAAC,IAAkB,EAAA;AACjC,QAAA,MAAM,IAAI,GAAe,IAAI,EAAE,IAAI,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,MAAM,CAAC;AAEnD,QAAA,CAAC,MAAM;cACH,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;cACxC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;AACnC,aAAA,IAAI,CACH,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,iBAAiB,GAAG,iBAAiB,CAAC,CAAC;YACtE,IAAI,CAAC,KAAK,EAAE,CAAC;AACf,SAAC,CAAC,CAAC;KACN;;;IAIO,gBAAgB,CAAC,OAAe,EAAE,EAAU,EAAA;QAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACzC,QAAA,MAAM,QAAQ,GAAc,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;aAC3C,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;aACvC,GAAG,CAAC,CAAC,OAAO,MAAM,OAAO,KAAK,KAAK,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC;AAExD,QAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YACpB,OAAO,CAAC,EAAE,CAAC,CAAC;SACb;QAED,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAA,CAAA,EAAI,QAAQ,CAAC,CAAC,CAAC,CAAA,CAAE,CAAC;SACjC;AAED,QAAA,OAAO,QAAQ,CAAC;KACjB;wGA/iBU,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAqBI,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,aAAA,EAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,UAAA,EAAA,eAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,eAAe,ECzGpD,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,o+CA2CA,kbDiCI,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,WAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,UAAA,EAAA,SAAA,EAAA,eAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAJ,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,gBAAgB,EAChB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,aAAa,sLACb,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGD,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAfhC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,mBAGR,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,YAAY;wBACZ,cAAc;wBACd,gBAAgB;wBAChB,YAAY;wBACZ,aAAa;wBACb,UAAU;AACX,qBAAA,EAAA,QAAA,EAAA,o+CAAA,EAAA,MAAA,EAAA,CAAA,2XAAA,CAAA,EAAA,CAAA;;;AE/EH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,iBAAiB,CAAC,KAAyB,EAAA;AACzD,IAAA,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;IACvC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,gBAAgB,CAAC;AAE7D,IAAA,IAAI,UAAU,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,iBAAiB,EAAE;QACpF,OAAO,SAAS,GAAG,CAAC,CAAC;KACtB;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/E,IAAA,IAAI,MAAM,GAAG,CAAC,CAAC,EAAE;AACf,QAAA,OAAO,MAAM,CAAC;KACf;AAED,IAAA,MAAM,KAAK,GAAG,UAAU,GAAG,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC;IAErD,OAAO,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACvC;;AC/BA;AACA;AACA;AACA;AACA;AACA;IACY,qBAIX;AAJD,CAAA,UAAY,oBAAoB,EAAA;AAC9B,IAAA,oBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,oBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,GAI/B,EAAA,CAAA,CAAA;;ACVD;AACA;AACA;AACA;AACA;IACY,iBAWX;AAXD,CAAA,UAAY,gBAAgB,EAAA;AAC1B,IAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,gBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,gBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,gBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,gBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,gBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EAXW,gBAAgB,KAAhB,gBAAgB,GAW3B,EAAA,CAAA,CAAA;;AChBD;AACA;AACA;AACA;AACA;IACY,sBAKX;AALD,CAAA,UAAY,qBAAqB,EAAA;AAC/B,IAAA,qBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,qBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,qBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,qBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EALW,qBAAqB,KAArB,qBAAqB,GAKhC,EAAA,CAAA,CAAA;;ACVD;AACA;AACA;AACA;AACA;IACY,qBAIX;AAJD,CAAA,UAAY,oBAAoB,EAAA;AAC9B,IAAA,oBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,oBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,oBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACnB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,GAI/B,EAAA,CAAA,CAAA;;ACTD;AACA;AACA;AACA;IACY,oBAKX;AALD,CAAA,UAAY,mBAAmB,EAAA;AAC7B,IAAA,mBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,mBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,mBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,mBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACb,CAAC,EALW,mBAAmB,KAAnB,mBAAmB,GAK9B,EAAA,CAAA,CAAA;;ACTD;AACA;AACA;AACA;AACA;AACA;IACY,uBAKX;AALD,CAAA,UAAY,sBAAsB,EAAA;AAChC,IAAA,sBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,sBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,sBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,sBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACvB,CAAC,EALW,sBAAsB,KAAtB,sBAAsB,GAKjC,EAAA,CAAA,CAAA;;ACXD;AACA;AACA;AACA;AACA;AACA;IACY,kBAKX;AALD,CAAA,UAAY,iBAAiB,EAAA;AAC3B,IAAA,iBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,iBAAA,CAAA,WAAA,CAAA,GAAA,WAAuB,CAAA;AACvB,IAAA,iBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACrB,IAAA,iBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EALW,iBAAiB,KAAjB,iBAAiB,GAK5B,EAAA,CAAA,CAAA;;ACXD;AACA;AACA;AACA;AACA;AACA;IACY,kBAIX;AAJD,CAAA,UAAY,iBAAiB,EAAA;AAC3B,IAAA,iBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,iBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACnB,IAAA,iBAAA,CAAA,UAAA,CAAA,GAAA,UAAqB,CAAA;AACvB,CAAC,EAJW,iBAAiB,KAAjB,iBAAiB,GAI5B,EAAA,CAAA,CAAA;;ACiBD;AACA;AACA;AACO,MAAM,sBAAsB,GAAoB,OAAO,CAAC;AACxD,MAAM,wBAAwB,GAAuB,KAAK,CAAC;AAE3D,MAAM,sBAAsB,GAAkC,MAAM,CAAC,MAAM,CAAC;AACjF,IAAA,MAAM,EAAE,sBAAsB;AAC9B,IAAA,QAAQ,EAAE,wBAAwB;AAClC,IAAA,YAAY,EAAE,IAAI;AACnB,CAAA,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAGtC;AACA;AACA;AACM,SAAU,mBAAmB,CAAC,GAA8B,EAAA;IAChE,IAAI,CAAC,GAAG,EAAE;AACR,QAAA,OAAO,sBAAsB,CAAC;KAC/B;AAED,IAAA,IAAI;AACF,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,sBAAsB,CAAC;KACjF;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,sBAAsB,CAAC;KAC/B;AACH,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,qBAAqB,CAAC,IAA+B,EAAA;IACnE,IAAI,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AACzC,QAAA,OAAO,wBAAwB,CAAC;KACjC;AAED,IAAA,IAAI;AACF,QAAA,YAAY,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAE5E,QAAA,OAAO,IAAI,CAAC;KACb;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,wBAAwB,CAAC;KACjC;AACH,CAAC;AAED;AACA;AACA;AACM,SAAU,oBAAoB,CAClC,MAA+E,EAAA;IAE/E,OAAO;AACL,QAAA,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,eAAe,CAAC;AACnD,QAAA,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC,iBAAiB,CAAC;AACzD,QAAA,YAAY,EAAE,MAAM,CAAC,aAAa,KAAK,OAAO;KAC/C,CAAC;AACJ,CAAC;AAGD;AACA;AACA;AACA,MAAM,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;AAC5D,MAAM,YAAY,GAAG,IAAI,GAAG,EAA+B,CAAC;AAE5C,SAAA,YAAY,CAAC,MAAc,EAAE,OAAiC,EAAA;AAC5E,IAAA,MAAM,GAAG,GAAG,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA,CAAE,CAAC;IACnD,IAAI,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAExC,IAAI,CAAC,SAAS,EAAE;QACd,SAAS,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACnD,QAAA,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;KACpC;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;AACA;SACgB,UAAU,CACxB,MAAc,EACd,OAAmC,EACnC,QAAiB,EAAA;AAEjB,IAAA,MAAM,GAAG,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAI,CAAA,EAAA,QAAQ,IAAI,EAAE,EAAE,CAAC;IACrE,IAAI,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;AACtE,QAAA,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;KAClC;AAED,IAAA,OAAO,SAAS,CAAC;AACnB,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB;AACA,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B;AACA,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B;AACA,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC;AACA,MAAMI,aAAW,GAAG,GAAG,CAAC;AACxB;AACA,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;AACA,MAAM,MAAM,GAA6B,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;AAEvE,MAAM,eAAe,GAAG,+CAA+C,CAAC;AACxE;AACA,MAAM,YAAY,GAAG,IAAI,GAAG,CAA6B,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AACtG,MAAM,WAAW,GAAG,IAAI,GAAG,CAA6B,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AAYjF,MAAM,WAAW,GAAG,IAAI,GAAG,CAA2B;AACpD,IAAA,CAAC,iBAAiB,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACzE,IAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1E,CAAA,CAAC,CAAC;AAsBH;AACA;AACM,SAAU,cAAc,CAAC,KAAc,EAAA;AAC3C,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;KAC9C;AAED,IAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AAC7D,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE9B,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACM,SAAU,eAAe,CAAC,IAA8B,EAAA;IAC5D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,sBAAsB,CAAC,IAAI,EAAE;AACxD,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI;AAC5B,WAAA,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,MAAM,IAAI;AACjC,YAAC,CAAC,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC,IAAI,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;AACA;AACA;SACgB,YAAY,CAC1B,KAA2C,EAC3C,SAAiB,EACjB,QAAgB,EAAA;IAEhB,QAAQ,KAAK;QACX,KAAK,iBAAiB,CAAC,SAAS,CAAC;QACjC,KAAK,iBAAiB,CAAC,QAAQ;AAC7B,YAAA,OAAO,KAAK,CAAC;QACf,KAAK,iBAAiB,CAAC,IAAI;YACzB,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAClD,QAAA;YACE,OAAO,iBAAiB,CAAC,IAAI,CAAC;KACjC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB,EAAE,QAAgB,EAAA;AACpD,IAAA,IAAI,SAAS,IAAI,GAAG,EAAE;QACpB,OAAO,iBAAiB,CAAC,QAAQ,CAAC;KACnC;AAED,IAAA,IAAI,SAAS,GAAG,GAAG,EAAE;QACnB,OAAO,iBAAiB,CAAC,IAAI,CAAC;KAC/B;IAED,OAAO,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,QAAQ,CAAC,IAAI,IAAI;UAC7C,iBAAiB,CAAC,QAAQ;AAC5B,UAAE,iBAAiB,CAAC,SAAS,CAAC;AAClC,CAAC;AAED;AACA;AACA,SAAS,OAAO,CAAC,KAAa,EAAE,QAAgB,EAAA;IAC9C,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;;AAG5C,IAAA,OAAO,MAAM,CAAC,YAAY,CAAC,sBAAsB,EAAE;AACjD,QAAA,WAAW,EAAE,KAAK;AAClB,QAAA,qBAAqB,EAAE,CAAC;AACxB,QAAA,qBAAqB,EAAE,MAAM;AAC9B,KAAA,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACpB,CAAC;AAED;AACM,SAAU,YAAY,CAC1B,KAAc,EACd,IAAyC,EACzC,OAA4B,EAC5B,OAAA,GAA+B,EAAE,EAAA;AAEjC,IAAA,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;AACvB,QAAA,OAAO,OAAO,CAAC,KAAK,IAAIA,aAAW,CAAC;KACrC;AAED,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AACtC,IAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;KACtB;AAED,IAAA,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACjD,IAAA,MAAM,KAAK,GAAG,KAAK,KAAK,iBAAiB,CAAC,OAAO;UAC7C,iBAAiB,CAAC,IAAI;AACxB,UAAE,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,IAAI,eAAe,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC;AAC9D,IAAA,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE;QAC7C,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;AAClD,QAAA,IAAI,OAAO,CAAC,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;AAClC,KAAA,CAAC,CAAC;AACH,IAAA,MAAM,IAAI,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAE1G,OAAO,KAAK,KAAK,iBAAiB,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,GAAG,IAAI,CAAA,CAAA,CAAG,GAAG,IAAI,CAAC;AAC1F,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAA;IAClC,OAAO,KAAK,KAAK,IAAI;AAChB,WAAA,KAAK,KAAK,SAAS;AACnB,WAAA,KAAK,KAAK,EAAE;AACZ,WAAA,KAAK,KAAK,GAAG;AACb,YAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;AACA,SAAS,WAAW,CAAC,IAAyC,EAAA;IAC5D,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC;AAC5F,CAAC;AAED,SAAS,YAAY,CAAC,IAAyC,EAAA;IAC7D,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC;AACvD,CAAC;AAED;AACA;AACA,SAAS,aAAa,CAAC,QAAmC,EAAA;IACxD,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;UAC5D,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;UAC1D,IAAI,CAAC;AACX,CAAC;AAED,SAAS,YAAY,CACnB,KAAwB,EACxB,OAA4B,EAC5B,QAAuB,EACvB,MAAe,EAAA;AAEf,IAAA,MAAM,cAAc,GAAG,oBAAoB,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtF,QAAQ,KAAK;QACX,KAAK,iBAAiB,CAAC,QAAQ;AAC7B,YAAA,OAAO,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,cAAc,EAAE,CAAC;QACrE,KAAK,iBAAiB,CAAC,OAAO;AAC5B,YAAA,OAAO,OAAO,CAAC,YAAY,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC;AACzF,QAAA;AACE,YAAA,OAAO,cAAc,CAAC;KACzB;AACH,CAAC;AAED,SAAS,eAAe,CAAC,QAA4B,EAAA;IACnD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;AACpE,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,KAAwB,EAAE,MAAe,EAAA;IAChE,IAAI,MAAM,EAAE;AACV,QAAA,OAAO,eAAe,CAAC;KACxB;IAED,QAAQ,KAAK;QACX,KAAK,iBAAiB,CAAC,OAAO;AAC5B,YAAA,OAAO,gBAAgB,CAAC;QAC1B,KAAK,iBAAiB,CAAC,QAAQ;AAC7B,YAAA,OAAO,iBAAiB,CAAC;AAC3B,QAAA;AACE,YAAA,OAAO,IAAI,CAAC;KACf;AACH,CAAC;AAED;AACA;AACA,SAAS,oBAAoB,CAAC,MAAqB,EAAE,OAAsB,EAAA;AACzE,IAAA,IAAI,MAAM,KAAK,IAAI,EAAE;QACnB,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC;KACzE;AAED,IAAA,OAAO,OAAO,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,qBAAqB,EAAE,CAAC,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC;AAC9F,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,SAA4B,EAAE,KAAa,EAAE,MAAe,EAAA;AAC/E,IAAA,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AACzB,QAAA,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;KAChC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAE7C,IAAA,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE;QACnD,OAAO,WAAW,CAAC,SAAS,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;KAC1C;IAED,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KACjD;AAED,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnG,OAAO;QACL,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC;QACrD,MAAM;AACN,QAAA,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC;AACnD,KAAA,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACb,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,SAA4B,EAAE,KAA8B,EAAA;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,KAAK,IAAI,GAAG,CAAC;AAE9F,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;WACjD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACjC,MAAM,YAAY,GAAG,GAAG,CAAC;AACzB,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,mBAAmB,GAAG,6BAA6B,CAAC;AAC1D,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAC5D;AACA,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,MAAM,iBAAiB,GAA+B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AACxH,MAAM,kBAAkB,GAA+B,MAAM,CAAC,MAAM,CAAC;IACnE,MAAM,EAAE,iBAAiB,CAAC,OAAO;AACjC,IAAA,SAAS,EAAE,cAAc;AAC1B,CAAA,CAAC,CAAC;AACH,MAAM,2BAA2B,GAA+B,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC;AAkCrH;AACA;AACA;AACgB,SAAA,iBAAiB,CAC/B,KAAc,EACd,MAAqC,EACrC,IAAyC,EACzC,OAA4B,EAC5B,OAAA,GAA8B,EAAE,EAAA;IAEhC,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;KAClF;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;QACtD,OAAO,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KACxD;AAED,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AACzB,IAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;AAEtE,IAAA,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;QACvB,OAAO,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KAChD;AAED,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,gBAAgB,CAAC,CAAC;IAElF,IAAI,IAAI,KAAK,QAAQ,IAAIC,gBAAc,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;QAC1D,OAAO,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;KACzG;IAED,MAAM,YAAY,GAAG,IAAI,KAAK,gBAAgB,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;UACrE,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE;UAClC,OAAO,CAAC;AAEZ,IAAA,OAAO,WAAW,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,eAAe,CAC7B,OAAsD,EACtD,KAAa,EACb,IAAgB,EAAA;AAEhB,IAAA,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC,CAAC;IAEhC,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO;AACzF,WAAA,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;WACzB,IAAI,CAAC,IAAI,KAAK,IAAI;YACjB,IAAI,KAAK,SAAS,KAAK,OAAO,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAE/F,IAAA,OAAO,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAA;AAC/B,IAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;AACA;AACA,SAAS,gBAAgB,CACvB,MAAkB,EAClB,GAAwC,EACxC,WAAgD,EAAA;AAEhD,IAAA,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;AAC7B,QAAA,OAAO,GAAG,CAAC;KACZ;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;AAC1B,QAAA,OAAO,aAAa,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;KAC9C;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE;AAC3B,QAAA,OAAO,aAAa,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;KAC/C;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE;AACpC,QAAA,OAAO,aAAa,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;KACxD;AAED,IAAA,OAAO,WAAW,GAAG,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC;AACrE,CAAC;AAED;AACA,SAAS,aAAa,CAAC,IAAsB,EAAE,GAAwC,EAAA;IACrF,OAAO;AACL,QAAA,GAAG,IAAI;QACP,IAAI,CAAC,GAAG,EAAE,SAAS,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;QAC1E,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;KAC/D,CAAC;AACJ,CAAC;AAED;AACA,SAASA,gBAAc,CAAC,MAAkB,EAAE,IAA6B,EAAA;AACvE,IAAA,OAAO,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,iBAAiB,CAAC,OAAO,CAAC;AACrF,CAAC;AAED;AACA;AACA;AACA,SAAS,YAAY,CACnB,KAAc,EACd,MAAkB,EAClB,IAA6B,EAC7B,OAA4B,EAC5B,IAAa,EACb,MAAe,EAAA;AAEf,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AACtC,IAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;KACtB;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,YAAY,GAAG,OAAO,GAAG,GAAG,GAAG,OAAO,CAAC;IACzF,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,eAAe,CAAC;IACnE,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAEvG,IAAA,OAAO,IAAI,GAAG,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,aAAa,CAAE,CAAA,GAAG,IAAI,CAAC;AAClD,CAAC;AAED;AACA;AACA;AACA,SAAS,aAAa,CACpB,MAAkB,EAClB,OAA4B,EAC5B,OAA2B,EAAA;AAE3B,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AAEzB,IAAA,IAAI,IAAI,KAAK,OAAO,EAAE;QACpB,OAAO,EAAE,IAAI,EAAED,aAAW,EAAE,KAAK,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;KAC/F;IAED,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,gBAAgB,EAAE;AAClD,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5B,IAAI,IAAI,KAAK,gBAAgB,IAAI,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YAC5D,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;SAC7D;QAED,OAAO;AACL,YAAA,IAAI,EAAEA,aAAW;YACjB,KAAK,EAAE,KAAK,KAAK,SAAS,IAAI,YAAY,CAAC,KAAK,CAAC;AAC/C,kBAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;AAC1D,kBAAE,IAAI;SACT,CAAC;KACH;IAED,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,IAAIA,aAAW,CAAC,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACA,SAAS,iBAAiB,CACxB,MAAkB,EAClB,KAAgC,EAChC,MAAuB,EAAA;AAEvB,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;AAC1B,QAAA,OAAO,mBAAmB,CAAC;KAC5B;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE;AAC3B,QAAA,OAAO,oBAAoB,CAAC;KAC7B;AAED,IAAA,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,eAAe,CAAC,KAAgC,EAAE,MAAuB,EAAA;AAChF,IAAA,MAAM,GAAG,GAAG,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;IAElD,OAAO,GAAG,GAAG,CAAA,4BAAA,EAA+B,GAAG,CAAA,CAAE,GAAG,aAAa,CAAC;AACpE,CAAC;AAED;AACA,SAAS,gBAAgB,CACvB,KAAc,EACd,IAAyC,EACzC,OAA4B,EAC5B,OAA2B,EAAA;AAE3B,IAAA,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE;AACvB,QAAA,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;cAC9B,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,mBAAmB,EAAE;AACtD,cAAE,WAAW,CAACA,aAAW,CAAC,CAAC;KAC9B;AAED,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AACtC,IAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,QAAA,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;KACnC;IAED,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,GAAG,aAAa,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;AAC5F,IAAA,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAElE,IAAI,MAAM,KAAK,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;AACjD,QAAA,OAAO,WAAW,CAAC,oBAAoB,CAAC,CAAC;KAC1C;AAED,IAAA,OAAO,WAAW,CAAC,CAAA,EAAG,OAAO,GAAG,CAAC,GAAG,YAAY,GAAG,cAAc,IAAI,MAAM,CAAA,CAAE,CAAC,CAAC;AACjF,CAAC;AAGD;AACA;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAAC,QAAwB,EAAA;AACvD,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAEjE,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,YAAY,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,EAAE;AACjF,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;AAEvE,IAAA,OAAO,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AACxD,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAsB,EAAA;IAC9C,OAAO;QACL,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;QAC7D,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;QACtE,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;KAC3D,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;SACgB,wBAAwB,CACtC,IAAsB,EACtB,IAAY,EACZ,OAA4B,EAAA;AAE5B,IAAA,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAChD,IAAA,MAAM,KAAK,GAAG,KAAK,KAAK,iBAAiB,CAAC,OAAO;UAC7C,iBAAiB,CAAC,IAAI;AACxB,UAAE,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,IAAI,eAAe,CAAC,CAAC;AAEjE,IAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,IAAI,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC;AACrF,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,YAAY,CACnB,KAAwB,EACxB,KAAoB,EACpB,IAAY,EACZ,OAA4B,EAAA;IAE5B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAErC,IAAI,KAAK,KAAK,iBAAiB,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE;AAChD,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,SAAS,GAAG,KAAK,KAAK,iBAAiB,CAAC,OAAO,IAAI,OAAO,CAAC,YAAY;UACzE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG;AACtB,UAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;AAC9C,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAElF,OAAO,KAAK,KAAK,iBAAiB,CAAC,QAAQ,IAAI,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,sBAAsB,GAAG,QAAQ,CAAC;AAC5G,CAAC;AAED;AACA;AACA,SAAS,QAAQ,CAAC,KAAa,EAAA;AAC7B,IAAA,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC3C,QAAA,OAAO,CAAC,CAAC;KACV;AAED,IAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrC,IAAA,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;IAC/B,IAAI,IAAI,GAAG,EAAE,CAAC;AACd,IAAA,IAAI,QAAQ,GAAG,GAAG,EAAE;QAClB,IAAI,GAAG,CAAC,CAAC;KACV;AAAM,SAAA,IAAI,QAAQ,GAAG,GAAG,EAAE;QACzB,IAAI,GAAG,CAAC,CAAC;KACV;AAAM,SAAA,IAAI,QAAQ,GAAG,CAAC,EAAE;QACvB,IAAI,GAAG,CAAC,CAAC;KACV;AAAM,SAAA,IAAI,QAAQ,GAAG,CAAC,EAAE;QACvB,IAAI,GAAG,CAAC,CAAC;KACV;IAED,OAAO,IAAI,GAAG,KAAK,CAAC;AACtB,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAC9B,IAAsB,EACtB,OAA4B,EAC5B,KAAwB,EACxB,MAA2B,EAC3B,OAAgB,EAAA;AAEhB,IAAA,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,KAAK,KAAK,iBAAiB,CAAC,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAE7F,IAAA,IAAI,KAAK,KAAK,iBAAiB,CAAC,MAAM,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE;AAC3E,QAAA,OAAO,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC7C;AAED,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,CAAQ,KAAA,EAAA,QAAQ,GAAG,CAAC,GAAG,CAAI,CAAA,EAAA,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAE,CAAA,CAAE,CAAC;AAExE,IAAA,IAAI,KAAK,KAAK,iBAAiB,CAAC,OAAO,EAAE;AACvC,QAAA,OAAO,CAAG,EAAA,MAAM,CAAG,EAAA,OAAO,CAAC,YAAY,GAAG,GAAG,GAAG,KAAK,EAAE,CAAC;KACzD;IAED,MAAM,MAAM,GAAG,CAAA,EAAG,MAAM,CAAA,EAAG,KAAK,EAAE,MAAM,IAAI,EAAE,CAAA,CAAE,CAAC;AACjD,IAAA,MAAM,IAAI,GAAG,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;AAEjC,IAAA,IAAI,KAAK,KAAK,iBAAiB,CAAC,QAAQ,EAAE;AACxC,QAAA,OAAO,IAAI,GAAG,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,IAAI,CAAG,CAAA,CAAA,GAAG,MAAM,CAAC;KAC7C;AAED,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAEvC,OAAO,MAAM,CAAC,MAAM;AAClB,UAAE,CAAI,CAAA,EAAA,MAAM,CAAC,IAAI,CAAA,CAAA,EAAI,MAAM,CAAG,EAAA,IAAI,GAAG,IAAI,IAAI,CAAA,CAAA,CAAG,GAAG,EAAE,CAAE,CAAA;UACrD,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA,CAAA,CAAG,CAAC;AACzC,CAAC;AAUD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA0B,CAAC;AAE3D,SAAS,cAAc,CAAC,OAA4B,EAAA;IAClD,MAAM,GAAG,GAAG,CAAA,EAAG,OAAO,CAAC,MAAM,CAAA,CAAA,EAAI,OAAO,CAAC,QAAQ,CAAA,CAAE,CAAC;IACpD,IAAI,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/F,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AACnG,QAAA,MAAM,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAChC,QAAA,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;aACrF,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC;aACzB,IAAI,CAAC,EAAE,CAAC;AACR,aAAA,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAErB,QAAA,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,QAAA,gBAAgB,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;KACnC;AAED,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,YAAY,GAA6B,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC;AAE7D,SAAA,iBAAiB,CAAC,KAAc,EAAE,MAAuB,EAAA;AACvE,IAAA,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ;AACvC,UAAE,KAAK;UACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;AAE3E,IAAA,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;AACzB,QAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,GAAG,CAAC;KAChD;IAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AAC7B,QAAA,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;KACxB;IAED,OAAO,YAAY,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;AAChF,CAAC;AAGD;AACA;AACA;AACO,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,mBAAmB,CAAC,MAA2B,EAAE,OAAgB,EAAA;AAC/E,IAAA,OAAO,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,wBAAwB,GAAG,OAAO,GAAG,SAAS,CAAC;AAC3F,CAAC;AAED;AACA;AACA;AACgB,SAAA,cAAc,CAAC,MAA2B,EAAE,OAAgB,EAAA;AAC1E,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvF,IAAA,OAAO,OAAO;UACV,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,UAAU;aAChE,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3D,UAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;AACxC,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,qBAAqB,CAAC,MAAsD,EAAA;AAC1F,IAAA,OAAO,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC;AACzG,CAAC;AAGD;AACA;AACO,MAAM,SAAS,GAA+B,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AACzG;AACO,MAAM,QAAQ,GAA+B,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AACvG;AACO,MAAM,UAAU,GAA+B,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACxE;AACO,MAAM,UAAU,GAA+B,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACzF;AACO,MAAM,SAAS,GAA+B,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAExF;AACA;AACA;AACA;AACA;AACM,SAAU,eAAe,CAC7B,IAAU,EACV,MAAuB,EACvB,OAAmC,EACnC,QAAiB,EAAA;IAEjB,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AAChC,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,IAAI;AACF,QAAA,OAAO,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;KAC/D;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;KACjF;AACH,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAU,EACV,MAAuB,EACvB,OAAmC,EACnC,QAAiB,EAAA;AAEjB,IAAA,IAAI;AACF,QAAA,OAAO,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;KAC/D;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;KAC5D;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,SAAS,CAAC,SAA8B,EAAE,IAAU,EAAA;AAC3D,IAAA,IAAI,IAAI,CAAC,cAAc,EAAE,GAAG,IAAI,EAAE;AAChC,QAAA,OAAO,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;KAC/B;AAED,IAAA,OAAO,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;AACjC,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;SAC9E,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAGD,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAChD,MAAM,iBAAiB,GAAG,sDAAsD,CAAC;AAEjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,gBAAgB,CAC9B,KAAc,EACd,QAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE;AACzD,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE3B,IAAA,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAChC,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;AAE3B,QAAA,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC;KACtE;IAED,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ,EAAE;AACb,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAA,EAAG,QAAQ,CAAC,CAAC,CAAC,CAAA,CAAA,EAAI,QAAQ,CAAC,CAAC,CAAC,CAAA,CAAA,CAAG,CAAC,CAAC;IAE3D,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;AACzF,CAAC;AAGD;AACA;AACO,MAAM,UAAU,GAA+B,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAE7F;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAC5B,KAAgC,EAChC,GAA8B,EAC9B,MAAuB,EACvB,OAAA,GAAsC,SAAS,EAAA;AAE/C,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9B,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE3B,IAAA,IAAI,KAAK,IAAI,IAAI,EAAE;QACjB,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;KACpD;IAED,IAAI,KAAK,EAAE;QACT,OAAO,CAAA,MAAA,EAAS,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA,CAAE,CAAC;KAC3D;AAED,IAAA,OAAO,IAAI,GAAG,CAAW,QAAA,EAAA,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA,CAAE,GAAG,EAAE,CAAC;AACzE,CAAC;AAED;AACA;AACA;SACgB,iBAAiB,CAC/B,OAAkC,EAClC,QAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,MAAM,QAAQ,GAAG,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAClE,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAG,EAAA,QAAQ,CAAC,CAAC,CAAC,CAAI,CAAA,EAAA,QAAQ,CAAC,CAAC,CAAC,CAAA,CAAA,CAAG,CAAC,GAAG,IAAI,CAAC;IAE7E,OAAO,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAC;AACnG,CAAC;AAED;AACA;AACA;SACgB,eAAe,CAC7B,IAA2E,EAC3E,QAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AAC1D,IAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE/D,IAAA,OAAO,IAAI,IAAI,IAAI,GAAG,CAAA,EAAG,IAAI,CAAA,QAAA,EAAW,IAAI,CAAE,CAAA,GAAG,IAAI,CAAC;AACxD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,UAAkD,EAAA;AAC/E,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE,OAAO,CAAC;IACpC,MAAM,KAAK,GAAG,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;AAEtC,IAAA,IAAI,UAAU,EAAE,IAAI,KAAK,YAAY,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE;AAC3D,QAAA,OAAO,KAAK,CAAC;KACd;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE7C,OAAO,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,YAAY,CAAC,OAAO,EAAE,CAAC;AACnG,CAAC;AAED;AACA;AACA;AACM,SAAU,gBAAgB,CAC9B,MAAqC,EACrC,MAAuB,EACvB,IAAI,GAAG,KAAK,EAAA;IAEZ,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE1C,IAAI,CAAC,GAAG,EAAE;AACR,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,IAAI,GAAG,CAAM,GAAA,EAAA,GAAG,CAAE,CAAA,GAAG,CAAM,GAAA,EAAA,GAAG,EAAE,CAAC;AAC1C,CAAC;AAED;AACA,SAAS,SAAS,CAAC,GAAW,EAAE,MAAuB,EAAA;AACrD,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE3B,IAAA,OAAO,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC;AAC9D,CAAC;AAED;AACA,SAAS,QAAQ,CAAC,GAA8B,EAAA;IAC9C,IAAI,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;AACxC,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE3B,IAAA,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACrC,CAAC;AAED;AACA;AACA;AACM,SAAU,aAAa,CAC3B,KAAW,EACX,IAAU,EACV,MAAuB,EACvB,OAAmC,EAAA;IAEnC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAEjE,IAAA,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE;AACvD,QAAA,IAAI;AACF,YAAA,OAAO,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;SACvD;AAAC,QAAA,MAAM;;SAEP;KACF;AAED,IAAA,OAAO,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;AAC/F,CAAC;AAGD;AACA;AACA;AACA;AACM,SAAU,UAAU,CAAC,GAAoB,EAAA;AAC7C,IAAA,OAAO,WAAW,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAEK,SAAU,YAAY,CAAC,IAAwB,EAAA;AACnD,IAAA,OAAO,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,WAAW,CAAC,IAA6B,EAAE,IAAY,EAAA;AAC9D,IAAA,IAAI;QACF,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;KACjE;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAGD;AACA;AACA;AACA;AAEA,MAAM,iBAAiB,GAA4D;IACjF,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;IACjC,IAAI,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;IACpC,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;IACvC,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;IAC7C,IAAI,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE;CACrC,CAAC;AAEF;AACA;AACA,MAAM,eAAe,GAAsC;AACzD,IAAA,eAAe,EAAE,iBAAiB;AAClC,IAAA,aAAa,EAAE,eAAe;AAC9B,IAAA,cAAc,EAAE,gBAAgB;AAChC,IAAA,gBAAgB,EAAE,kBAAkB;AACpC,IAAA,aAAa,EAAE,eAAe;AAC9B,IAAA,KAAK,EAAE,cAAc;CACtB,CAAC;AAEF;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,qBAAqB,CAAC,MAAwB,EAAA;AAC5D,IAAA,OAAO,MAAM,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;AACtC,CAAC;AAED,SAAS,YAAY,CAAC,MAAwB,EAAA;AAC5C,IAAA,IAAI,MAAM,CAAC,OAAO,KAAK,iBAAiB,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;QACzE,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,eAAe,CAAC;KAC3E;AAED,IAAA,OAAO,MAAM,CAAC,KAAK,KAAK,CAAC;UACrB,CAAY,SAAA,EAAA,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAE,CAAA;AAClD,UAAE,CAAA,SAAA,EAAY,MAAM,CAAC,KAAK,CAAI,CAAA,EAAA,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AACxE,CAAC;AAED;AACA;AACgB,SAAA,kBAAkB,CAChC,IAAwB,EACxB,UAAuC,EAAA;IAEvC,MAAM,MAAM,GAAG,UAAU,EAAE,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;AAChD,IAAA,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAqB,kBAAA,EAAA,YAAY,CAAC,MAAM,CAAC,CAAE,CAAA,GAAG,IAAI,CAAC;IAE7E,QAAQ,IAAI;AACV,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,0CAA0C,CAAC;AACpD,QAAA,KAAK,eAAe;AAClB,YAAA,OAAO,QAAQ;kBACX,CAAG,EAAA,QAAQ,CAAiC,+BAAA,CAAA;kBAC5C,4DAA4D,CAAC;AACnE,QAAA,KAAK,kBAAkB;AACrB,YAAA,OAAO,wEAAwE,CAAC;AAClF,QAAA,KAAK,mBAAmB;AACtB,YAAA,OAAO,+DAA+D,CAAC;AACzE,QAAA,KAAK,gBAAgB;AACnB,YAAA,OAAO,QAAQ;kBACX,CAAG,EAAA,QAAQ,CAAkC,gCAAA,CAAA;kBAC7C,6CAA6C,CAAC;AACpD,QAAA;AACE,YAAA,OAAO,EAAE,CAAC;KACb;AACH,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,UAAU,CACxB,IAAgB,EAChB,MAAuB,EACvB,WAAqC,EAAA;AAErC,IAAA,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC;AAEvD,IAAA,OAAO,IAAI,GAAG,CAAG,EAAA,MAAM,CAAK,EAAA,EAAA,IAAI,CAAE,CAAA,GAAG,MAAM,CAAC;AAC9C,CAAC;AAED,SAAS,YAAY,CAAC,IAAgB,EAAE,WAAoC,EAAA;AAC1E,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAEjD,IAAA,QAAQ,IAAI,CAAC,IAAI;AACf,QAAA,KAAK,SAAS;AACZ,YAAA,OAAO,IAAI,CAAC,aAAa,GAAG,CAAA,QAAA,EAAW,KAAK,CAAA,4BAAA,CAA8B,GAAG,CAAW,QAAA,EAAA,KAAK,EAAE,CAAC;QAClG,KAAK,SAAS,EAAE;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;AAE9E,YAAA,OAAO,KAAK,GAAG,CAAG,EAAA,UAAU,CAAC,KAAK,CAAC,CAAY,SAAA,EAAA,KAAK,EAAE,GAAG,CAAW,QAAA,EAAA,KAAK,EAAE,CAAC;SAC7E;QACD,KAAK,SAAS,EAAE;AACd,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC;AACtC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,GAAG,CAAA,EAAG,IAAI,CAAC,OAAO,CAAA,CAAA,EAAI,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,QAAQ,CAAG,CAAA,CAAA,GAAG,EAAE,CAAC;AAErG,YAAA,OAAO,CAAW,QAAA,EAAA,IAAI,CAAG,EAAA,KAAK,EAAE,CAAC;SAClC;AACD,QAAA;AACE,YAAA,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;KAC5B;AACH,CAAC;AAED;AACM,SAAU,cAAc,CAC5B,IAAoB,EACpB,IAAgB,EAChB,MAAuB,EACvB,WAAqC,EAAA;IAErC,QAAQ,IAAI;QACV,KAAK,eAAe,EAAE;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAE9D,YAAA,OAAO,KAAK;kBACR,CAA0B,uBAAA,EAAA,KAAK,CAA0D,wDAAA,CAAA;kBACzF,+EAA+E,CAAC;SACrF;AACD,QAAA,KAAK,gBAAgB;YACnB,OAAO,iBAAiB,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC;AACtD,QAAA,KAAK,kBAAkB;AACrB,YAAA,OAAO,gFAAgF,CAAC;AAC1F,QAAA,KAAK,mBAAmB;AACtB,YAAA,OAAO,oFAAoF,CAAC;AAC9F,QAAA,KAAK,yBAAyB;AAC5B,YAAA,OAAO,qFAAqF,CAAC;AAC/F,QAAA,KAAK,gBAAgB;AACnB,YAAA,OAAO,6EAA6E,CAAC;AACvF,QAAA,KAAK,iBAAiB;AACpB,YAAA,OAAO,+FAA+F,CAAC;AACzG,QAAA;AACE,YAAA,OAAO,EAAE,CAAC;KACb;AACH,CAAC;AAED;AACA,SAAS,iBAAiB,CAAC,IAAgB,EAAE,WAAoC,EAAA;AAC/E,IAAA,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;AACrD,QAAA,OAAO,yDAAyD,CAAC;KAClE;AAED,IAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,WAAW;UACrB,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;UACzC,GAAG,IAAI,CAAC,YAAY,CAAI,CAAA,EAAA,IAAI,CAAC,YAAY,KAAK,CAAC,GAAG,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7E,IAAA,OAAO,GAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,IAAI,GAAG,KAAK,CAAa,UAAA,EAAA,KAAK,oBAAoB,CAAC;AAChG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,IAAsB,EAAA;IACtD,OAAO,CAAA,EAAG,KAAK,CAAA,CAAA,EAAI,KAAK,KAAK,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAA,CAAE,CAAC;AAChG,CAAC;AAED;AACA;AACA;AACgB,SAAA,WAAW,CAAC,IAAiB,EAAE,OAAkC,EAAA;AAC/E,IAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAE1C,QAAQ,IAAI;AACV,QAAA,KAAK,eAAe;YAClB,OAAO,CAAA,aAAA,EAAgB,QAAQ,CAAA,aAAA,CAAe,CAAC;AACjD,QAAA,KAAK,cAAc;YACjB,OAAO,CAAA,KAAA,EAAQ,QAAQ,CAAA,OAAA,CAAS,CAAC;AACnC,QAAA,KAAK,WAAW;YACd,OAAO,CAAA,eAAA,EAAkB,QAAQ,CAAA,CAAA,CAAG,CAAC;AACvC,QAAA,KAAK,gBAAgB;AACnB,YAAA,OAAO,2BAA2B,CAAC;AACrC,QAAA,KAAK,aAAa;AAChB,YAAA,OAAO,wDAAwD,CAAC;AAClE,QAAA;AACE,YAAA,OAAO,EAAE,CAAC;KACb;AACH,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,OAA6C,EAAA;IACpE,QAAQ,OAAO;AACb,QAAA,KAAK,iBAAiB;AACpB,YAAA,OAAO,qBAAqB,CAAC;AAC/B,QAAA,KAAK,eAAe;AAClB,YAAA,OAAO,mBAAmB,CAAC;AAC7B,QAAA,KAAK,gBAAgB;AACnB,YAAA,OAAO,oBAAoB,CAAC;AAC9B,QAAA,KAAK,kBAAkB;AACrB,YAAA,OAAO,sBAAsB,CAAC;AAChC,QAAA,KAAK,eAAe;AAClB,YAAA,OAAO,2BAA2B,CAAC;AACrC,QAAA;AACE,YAAA,OAAO,uBAAuB,CAAC;KAClC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAA;AAC9B,IAAA,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAGD;AACA;AACA;AACA;AACM,SAAU,WAAW,CAAC,QAAgB,EAAA;AAC1C,IAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAEvB,IAAA,IAAI;QACF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;AAEzC,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC;KACpD;AAAC,IAAA,MAAM;AACN,QAAA,OAAO,GAAG,CAAC;KACZ;AACH;;ACl6CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACO,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,kBAAkB,GAA2B,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC;AAC3E,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C;AACA;AACA;AACA;AACO,MAAM,uBAAuB,GAAG,SAAS,CAAC;AAC1C,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAC5C;AACO,MAAM,uBAAuB,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;AACtE;AACA;AACO,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAkDnC;AACA;AACO,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAE9E;AACA;AACA;AACA;AACO,MAAM,mBAAmB,GAAG,oEAAoE,CAAC;AAExG;AACA;AACA;AACO,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAEpC;AACA;AACO,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAEhC,SAAU,UAAU,CAAC,GAAW,EAAA;IACpC,OAAO,CAAA,QAAA,EAAW,GAAG,CAAA,EAAA,CAAI,CAAC;AAC5B,CAAC;AAED;AACA;AACM,SAAUE,WAAS,CAAC,KAA4B,EAAA;AACpD,IAAA,OAAO,KAAK,EAAE,IAAI,KAAK,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;AACjF,CAAC;AAgED;AACA,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAEnC;AACA;AACA;AACA;AACA;AACA,MAAM,WAAW,GAAkF;AACjG,IAAA,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;AACrF,IAAA,WAAW,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,EAAE;AACvE,IAAA,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,OAAO,CAAC,UAAU,EAAE;CAC9E,CAAC;AAEF,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAUtC;AACA;AACA;AACM,SAAU,UAAU,CAAC,OAAyB,EAAA;IAClD,OAAO;QACL,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;aACrC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM;AACtB,YAAA,KAAK,EAAE,CAAA,EAAG,mBAAmB,CAAA,EAAG,EAAE,CAAE,CAAA;YACpC,IAAI,EAAE,MAAM,CAAC,IAAI;AAClB,SAAA,CAAC,CAAC;KACN,CAAC;AACJ,CAAC;AAED;AACM,SAAU,UAAU,CAAC,KAAa,EAAA;IACtC,OAAO,CAAA,EAAA,EAAK,KAAK,CAAA,EAAA,CAAI,CAAC;AACxB,CAAC;AAED;AACA;AACA;AACgB,SAAA,cAAc,CAAC,IAAY,EAAE,OAAyB,EAAA;AACpE,IAAA,OAAO,IAAI;SACR,OAAO,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,GAAW,KAAK,UAAU,CAC9DA,WAAS,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAC/C,CAAC;SACD,OAAO,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,KAAa,KAAK,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAAC,KAAgC,EAAE,OAAyB,EAAA;AACzF,IAAA,OAAO,CAAC,KAAK,IAAI,EAAE;AAChB,SAAA,OAAO,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;AAC9C,SAAA,OAAO,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,KAAa,KAAK,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AACvF,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,SAAS,CAAC,KAAa,EAAE,OAAyB,EAAA;AAChE,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEjC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE;QACzC,OAAO,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAAC;KAC7D;AAED,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAEjF,IAAA,OAAO,MAAM,EAAE,IAAI,KAAK,MAAM,EAAE,OAAO,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;AACnF,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,UAAU,CAAC,IAAY,EAAE,OAAyB,EAAA;AAChE,IAAA,MAAM,QAAQ,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,CAAA,MAAA,EAAS,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAC/G,IAAA,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAe;QAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACxB,YAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;SACnD;AAED,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QACnD,MAAM,UAAU,GAAoB,EAAE,CAAC;AACvC,QAAA,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AACzB,QAAA,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAEvC,QAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACtC,KAAC,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,CAAC,CAAC;AAErB,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;AACA;AACgB,SAAA,cAAc,CAAC,IAAY,EAAE,OAAyB,EAAA;IACpE,OAAO,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACpD,CAAC;AAED;AACM,SAAU,eAAe,CAAC,MAAmB,EAAA;AACjD,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM;UAClD,KAAK,CAAC,UAAU;AAClB,UAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;AACgB,SAAA,SAAS,CAAC,IAAY,EAAE,OAAyB,EAAA;AAC/D,IAAA,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC;SACjC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SAClE,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,aAAa,CAAC,MAAY,EAAA;IACxC,MAAM,KAAK,GAAkC,EAAE,CAAC;IAChD,IAAI,GAAG,GAAkB,IAAI,CAAC;IAE9B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;AACjC,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE;AAC7B,YAAA,KAAK,CAAC,IAAI,CAAC,IAAwB,CAAC,CAAC;YACrC,GAAG,GAAG,IAAI,CAAC;SACZ;aAAM,IAAI,GAAG,EAAE;AACd,YAAA,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAChB;aAAM;AACL,YAAA,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;AACb,YAAA,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACjB;AACH,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAED;AACA;AACA;AACM,SAAU,UAAU,CAAC,OAAyB,EAAA;AAClD,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,MAAoB;AAC5D,QAAA,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC;QAC1B,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC;AACxC,KAAA,CAAC,CAAC,CAAC;IAEJ,OAAO,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;AACzC,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,SAAS,CAAC,KAAgB,EAAA;AACxC,IAAA,MAAM,KAAK,GAAgB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACpD,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,KAAkB;QACvD,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAmB;YAClD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE;AAC3B,gBAAA,MAAM,EAAE,CAAC;aACV;YAED,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC;AACpG,YAAA,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACtB,YAAA,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC;YACzB,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAEpC,YAAA,OAAO,MAAM,CAAC;AAChB,SAAC,CAAC,CAAC;AAEH,QAAA,OAAO,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC;AAC3B,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,YAAY,CAAC,GAAwB,EAAA;AAC5C,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC;IAE5C,OAAO,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,KAAK,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAC9E,CAAC;AAED;AACA;AACA;AACA,SAAS,SAAS,CAAC,IAA0B,EAAA;AAC3C,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;AAC9E,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IACxC,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IAEjE,OAAO;QACL,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;QAC9F,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC;QAClC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC;AAClC,QAAA,GAAG,EAAE,CAAC;AACN,QAAA,MAAM,EAAE,CAAC;QACT,KAAK;AACL,QAAA,MAAM,EAAE,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS;QAC3F,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,SAAS;KACpF,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAA;IAC9B,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AAChH,CAAC;AAED;AACA,SAAS,aAAa,CAAC,IAAoB,EAAE,KAAa,EAAA;AACxD,IAAA,IAAI,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;IACpB,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;AACrE,QAAA,GAAG,EAAE,CAAC;KACP;AAED,IAAA,OAAO,GAAG,CAAC;AACb,CAAC;AAED;AACA,SAAS,MAAM,CAAC,KAAkB,EAAE,IAAmB,EAAA;IACrD,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;QAC7D,KAAK,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5E,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;SAC3B;KACF;AACH,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,GAAiB,EAAA;IACrC,OAAO;AACL,QAAA,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK;AACvC,YAAA,IAAI,KAAK,GAAG,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,GAAG,EAAE,CAAC;AAClD,YAAA,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,IAAI,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;SACvG,CAAC;KACH,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,MAAmB,EAAA;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAEvC,IAAA,OAAO,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE;AAClH,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;KACvB;AACH,CAAC;AAED;AACA,SAAS,UAAU,CACjB,MAAY,EACZ,UAA2B,EAC3B,IAAgC,EAChC,IAAA,GAAyB,EAAE,EAAA;;;IAI3B,IAAI,KAAK,GAAyB,IAAI,CAAC;IACvC,MAAM,KAAK,GAAG,MAAK;AACjB,QAAA,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;AAC3B,YAAA,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACxB;QACD,KAAK,GAAG,IAAI,CAAC;AACf,KAAC,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAEzC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAC5F,YAAA,KAAK,EAAE,CAAC;YACR,SAAS,CAAC,IAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAEvD,OAAO;SACR;QAED,KAAK,GAAG,KAAK,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9B,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AAClD,KAAC,CAAC,CAAC;AAEH,IAAA,KAAK,EAAE,CAAC;AACV,CAAC;AAED;AACA;AACA;AACA,SAAS,OAAO,CAAC,KAAoB,EAAA;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,SAAS,CAChB,OAAoB,EACpB,UAA2B,EAC3B,IAAgC,EAChC,IAAsB,EAAA;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE;AAClC,QAAA,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC;KAC5E;AAAM,SAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACxB,QAAA,MAAM,IAAI,GAAkB,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,IAAI,QAAQ,EAAE,CAAC;QACnE,MAAM,MAAM,GAAoB,EAAE,CAAC;;;QAGnC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC;AACzD,QAAA,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,IAAI,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;KAClE;SAAM;AACL,QAAA,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;KAC1C;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,aAAa,CAAC,OAAoB,EAAE,UAA2B,EAAE,IAAsB,EAAA;IAC9F,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;AACnE,IAAA,MAAM,SAAS,GAAkB;AAC/B,QAAA,IAAI,EAAE,EAAE;AACR,QAAA,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC;AAC1B,QAAA,MAAM,EAAE,SAAS;QACjB,OAAO;KACR,CAAC;IACF,MAAM,KAAK,GAAqB,OAAO;AACrC,UAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,kBAAkB,CAAC,OAAO,CAAC,EAAE;UAC9D,IAAI,CAAC;AAET,IAAA,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACjE,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE;AACpC,QAAA,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KAC5B;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,UAAU,CACjB,IAAU,EACV,KAAuB,EACvB,SAAwB,EACxB,UAA2B,EAC3B,MAAM,GAAG,KAAK,EAAA;IAEd,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAE5D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1G,CAAC;AAED,SAAS,cAAc,CACrB,IAAU,EACV,KAAuB,EACvB,SAAwB,EACxB,UAA2B,EAAA;IAE3B,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,EAAE;AACpC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QACpC,IAAI,IAAI,EAAE;AACR,YAAA,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;SACzC;AAED,QAAA,OAAO,CAAC,CAAC;KACV;IAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE;AACvC,QAAA,OAAO,CAAC,CAAC;KACV;IAED,MAAM,OAAO,GAAG,IAAmB,CAAC;IAEpC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI,EAAE;AAC3C,QAAA,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7D,QAAA,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;AAE1B,QAAA,OAAO,CAAC,CAAC;KACV;AAED,IAAA,OAAO,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAC3F,CAAC;AAED,SAAS,WAAW,CAAC,OAAoB,EAAA;IACvC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAqB,EAAE,CAAC;AAEnC,IAAA,IAAI,IAAI,KAAK,QAAQ,EAAE;AACrB,QAAA,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;KACnB;AACD,IAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,QAAA,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;KACrB;AACD,IAAA,IAAI,IAAI,KAAK,GAAG,EAAE;AAChB,QAAA,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;KACxB;AACD,IAAA,IAAI,IAAI,KAAK,GAAG,EAAE;AAChB,QAAA,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;KACrB;AACD,IAAA,IAAI,IAAI,KAAK,GAAG,EAAE;QAChB,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;AACvD,QAAA,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;KACxB;;AAGD,IAAA,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;AAC1B,IAAA,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;AAC1D,IAAA,MAAM,SAAS,GAAG,GAAG,CAAC,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,SAAS,CAAC;IAClF,IAAI,KAAK,EAAE;AACT,QAAA,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;KACrB;IACD,IAAI,SAAS,EAAE;AACb,QAAA,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;KAC7B;AACD,IAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;QAChB,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KACvC;AACD,IAAA,IAAI,GAAG,CAAC,UAAU,EAAE;AAClB,QAAA,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,UAAU,KAAK,MAAM,IAAI,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC;KACzE;AACD,IAAA,IAAI,GAAG,CAAC,SAAS,EAAE;QACjB,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,SAAS,KAAK,QAAQ,CAAC;KAC3C;AACD,IAAA,IAAI,GAAG,CAAC,cAAc,EAAE;QACtB,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3D,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;KAC5D;AACD,IAAA,IAAI,GAAG,CAAC,UAAU,EAAE;QAClB,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;KAC3E;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,UAAU,CAAC,OAAoB,EAAA;AACtC,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;AAEtC,IAAA,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AAC5F,CAAC;AAED;AACA;AACA,SAAS,MAAM,CAAC,KAAa,EAAA;IAC3B,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9D,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,SAAS,CAAC;KAClB;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,IAAA,QAAQ,KAAK,CAAC,CAAC,CAAC;AACd,QAAA,KAAK,IAAI;AACP,YAAA,OAAO,IAAI,CAAC;AACd,QAAA,KAAK,IAAI;YACP,OAAO,IAAI,GAAG,IAAI,CAAC;AACrB,QAAA,KAAK,GAAG;AACN,YAAA,OAAO,CAAC,IAAI,GAAG,GAAG,IAAI,iBAAiB,CAAC;AAC1C,QAAA;YACE,OAAO,IAAI,GAAG,iBAAiB,CAAC;KACnC;AACH,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,IAAI,YAAY,GAAoC,IAAI,CAAC;AAEzD,SAAS,QAAQ,CAAC,KAAa,EAAA;AAC7B,IAAA,YAAY,GAAG,YAAY,IAAI,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACjF,IAAI,CAAC,YAAY,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;AACxD,QAAA,OAAO,SAAS,CAAC;KAClB;;;;IAKD,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9D,IAAI,QAAQ,KAAK,YAAY,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;AAC7D,QAAA,OAAO,SAAS,CAAC;KAClB;AAED,IAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC5B,QAAA,OAAO,QAAQ,CAAC;KACjB;;IAGD,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;AAE/E,IAAA,OAAO,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,CAAC;AACtC,UAAE,SAAS;AACX,UAAE,CAAI,CAAA,EAAA,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5G,CAAC;AAED;AACA,SAAS,YAAY,CAAC,OAAiC,EAAE,IAAY,EAAE,KAAa,EAAA;AAClF,IAAA,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;AACzB,IAAA,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC;AAE1B,IAAA,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;AAEK,SAAU,UAAU,CAAC,KAAa,EAAA;AACtC,IAAA,OAAO,KAAK;AACT,SAAA,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;AACtB,SAAA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AACrB,SAAA,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;AACrB,SAAA,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B;;AC3rBA;AACA;AACA;AACA;IACY,qBAIX;AAJD,CAAA,UAAY,oBAAoB,EAAA;AAC9B,IAAA,oBAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,oBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACX,IAAA,oBAAA,CAAA,SAAA,CAAA,GAAA,SAAmB,CAAA;AACrB,CAAC,EAJW,oBAAoB,KAApB,oBAAoB,GAI/B,EAAA,CAAA,CAAA;;ACHD;AACA;AACA;AACO,MAAM,mBAAmB,GAAG;AACjC,IAAA,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;AAChD,IAAA,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;CACjD,CAAC;AAEF;AACa,MAAA,uBAAuB,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,KAAK,CAAA,CAAE,EAAE;AAEvF;AACA;AACO,MAAM,0BAA0B,GAAqC;IAC1E,CAAC,gBAAgB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAC/C,CAAC,gBAAgB,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;IACjD,CAAC,gBAAgB,CAAC,GAAG,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAC9C,CAAC,gBAAgB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAC/C,CAAC,gBAAgB,CAAC,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAChD,CAAC,gBAAgB,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;IACjD,CAAC,gBAAgB,CAAC,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC;IACjD,CAAC,gBAAgB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAC/C,CAAC,gBAAgB,CAAC,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC;IAChD,CAAC,gBAAgB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC;CAChD,CAAC;AAEF;AACA;AACO,MAAM,sBAAsB,GAAG,QAAQ,CAAC;AAE/C;AACA;AACA;AACO,MAAM,uBAAuB,GAAsC;AACxE,IAAA,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAC5B,IAAA,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAC5B,IAAA,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF;AACA;AACO,MAAM,uBAAuB,GAAG,QAAQ,CAAC;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,wBAAwB,GAAyC;IAC5E,CAAC,oBAAoB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC;IACnD,CAAC,oBAAoB,CAAC,GAAG,GAAG,mBAAmB,CAAC,CAAC,CAAC;AAClD,IAAA,CAAC,oBAAoB,CAAC,OAAO,GAAG,uBAAuB;CACxD,CAAC;AAEF;AACO,MAAM,sBAAsB,GAAG,QAAQ,CAAC;AAE/C;AACA;AACO,MAAM,0BAA0B,GAAG,mBAAmB,CAAC,CAAC,CAAC;;AClEhE;AACA;AACA;AACO,MAAM,wBAAwB,GAAG,uCAAuC;AACxE,MAAM,2BAA2B,GAAG,GAAG;AAC9C;AACA;AACO,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAC9C;AACA;AACA;AACO,MAAM,0BAA0B,GAAG,EAAE;;AC+E5C;AACA;AACA;AACA;AACA,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B;AACA,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B;AACA;AACA,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B;AACA;AACA;AACA,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B;AACA;AACA;AACA,MAAM,eAAe,GAAG,CAAA,EAAG,2BAA2B,CAAM,GAAA,EAAA,wBAAwB,EAAE,CAAC;AACvF;AACA;AACA,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAiB,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAChE,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B;AACA;AACA,MAAM,mBAAmB,GAAqB,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAClG,MAAM,oBAAoB,GAAqB,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAC5F,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C;AACA;AACA,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AACtD;AACA;AACA,MAAM,cAAc,GAAG,EAAE,eAAe,EAAE,2BAA2B,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;AAC1G;AACA;AACA,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;AACA;AACA;AACA;AACA,MAAM,mBAAmB,GAAG,SAAS,CAAC;AACtC;AACA;AACA,MAAM,kBAAkB,GAAmD;AACzE,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,MAAM,EAAE,SAAS;AACjB,IAAA,cAAc,EAAE,WAAW;CAC5B,CAAC;AACF;AACA;AACA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,MAAM,CAAC;AACrD;AACA;AACA;AACA,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,MAAM,CAAC;AACvD,MAAM,iBAAiB,GAAG;AACxB,IAAA,MAAM,EAAE,MAAM;AACd,IAAA,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAClB,IAAA,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAClB,IAAA,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC;AACtB,IAAA,KAAK,EAAE,0BAA0B;CAClC,CAAC;AACF,MAAM,kBAAkB,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC;AACzG;AACA;AACA,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAC9C;AACA,MAAM,gBAAgB,GAAqB,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAC9F;AACO,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B;AACA;AACA,MAAM,oBAAoB,GAAqB,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,CAAC;AACrF;AACA,MAAM,wBAAwB,GAAG,KAAK,CAAC;AACvC;AACA;AACA,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC;AACA;AACA;AACA,MAAM,iBAAiB,GAAgC,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,CAAC;AAC5F,MAAM,iBAAiB,GAAqC;AAC1D,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,WAAW,EAAE,oBAAoB;AACjC,IAAA,QAAQ,EAAE,WAAW;CACtB,CAAC;AACF,MAAM,uBAAuB,GAAqC;AAChE,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,WAAW,EAAE,QAAQ;AACrB,IAAA,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF;AACA;AACO,MAAM,UAAU,GAAwC;AAC7D,IAAA,CAAC,mBAAmB,CAAC,OAAO,GAAG,SAAS;AACxC,IAAA,CAAC,mBAAmB,CAAC,MAAM,GAAG,QAAQ;AACtC,IAAA,CAAC,mBAAmB,CAAC,GAAG,GAAG,SAAS;AACpC,IAAA,CAAC,mBAAmB,CAAC,GAAG,GAAG,SAAS;CACrC,CAAC;AAwIF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,SAAS,CAAC,MAAmB,EAAA;IAC3C,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,KAAK,MAAM,KAAK,EAAE;AACjG,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,IAAI,MAAM,CAAC,OAAO,EAAE;AAClB,QAAA,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;KAChC;;IAGD,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE;AACzC,QAAA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,UAAU,MAAM,UAAU;AACnD,WAAA,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW;WAC1B,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AAGD;AACA;AACM,SAAU,aAAa,CAAC,MAAmB,EAAA;IAC/C,OAAO,SAAS,CAAC,MAAM,CAAC;AACtB,WAAG,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM;UAC/C,SAAS,CAAC;AAChB,CAAC;AAkCe,SAAA,kBAAkB,CAAC,SAA0B,EAAE,IAAmB,EAAA;AAChF,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;AAC/C,IAAA,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE7C,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvD,IAAA,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAmC,EAAE,CAAC;AAClD,IAAA,MAAM,SAAS,GAAG,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC;IAE1E,IAAI,WAAW,EAAE;;AAEf,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5B,QAAA,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE;YAClC,MAAM,CAAC,IAAI,CAAC;AACV,gBAAA,IAAI,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC;gBAC/B,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC;gBACnH,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO;AACP,gBAAA,YAAY,EAAE,CAAC;AAChB,aAAA,CAAC,CAAC;SACJ;KACF;SAAM;AACL,QAAA,KAAK,MAAM,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE;YACxD,MAAM,CAAC,IAAI,CAAC;AACV,gBAAA,IAAI,EAAE,kBAAkB,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM;AACpF,gBAAA,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC;gBACzE,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO;gBACP,YAAY;AACb,aAAA,CAAC,CAAC;SACJ;KACF;IAED,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAC1D,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,YAAY,CAAC,MAAmB,EAAE,IAAmB,EAAA;IACnE,OAAO;AACL,QAAA,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAChD,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,cAAc,CACrB,IAA+B,EAC/B,OAAe,EACf,aAAwB,EACxB,MAAc,EACd,KAAiD,EAAA;AAEjD,IAAA,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;AAC/C,IAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;QACtB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE;AACxB,YAAA,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;SAC3C;KACF;AAED,IAAA,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAKC,SAAO,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAC5E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,OAAqB,EAAE,QAAwB,EAAE,IAAmB,EAAA;IAC9F,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC;AAE1F,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AACnE,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,MAAM,KAAK,OAAO,CAAC,EAAE,KAAK,IAAI,OAAO,CAAC;AAE3F,IAAA,OAAO,CAAG,EAAA,KAAK,CAAG,EAAA,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC;AACzF,CAAC;AAED;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,OAAmC,EAAE,KAAa,EAAA;AAC5E,IAAA,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO;AACxC,UAAE,SAAS;UACT,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO;eACvE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;eACjC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAEnC,IAAA,OAAO,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,UAAU,IAAI,MAAM,CAAC,OAAO,CAAC;AACpF,CAAC;AAED;AACA;AACA;AACM,SAAU,WAAW,CAAC,MAAgC,EAAA;AAC1D,IAAA,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAElC,OAAO,GAAG,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,GAAG,SAAS,CAAC;AACrC,CAAC;AAED;AACA;AACgB,SAAA,SAAS,CAAC,MAAgC,EAAE,KAAa,EAAA;AACvE,IAAA,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC1F,CAAC;AAED,SAAS,aAAa,CAAC,MAAgC,EAAA;AACrD,IAAA,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;AACA;AACA;AACA,SAAS,eAAe,CAAC,OAAiC,EAAA;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,OAAO,EAAE,KAAK,CAAC,CAAC;AAEtF,IAAA,OAAO,KAAK,GAAG,0BAA0B,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;AAC/D,CAAC;AAED;AACA;AACM,SAAU,gBAAgB,CAAC,OAAiC,EAAA;IAChE,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,OAAO,EAAE,IAAI,CAAC,CAAC;AACtF,CAAC;AAED;AACA;AACM,SAAU,eAAe,CAAC,OAAiC,EAAA;IAC/D,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,OAAO,EAAE,QAAQ,CAAC,CAAC;AACvF,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,UAAU,CAAC,MAAyB,EAAE,IAAyB,EAAA;IAC7E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAsB,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAE/G,IAAA,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;AACnB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,QAAQ,IAAI;QACV,KAAK,mBAAmB,CAAC,OAAO;YAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;AACzE,QAAA,KAAK,mBAAmB,CAAC,MAAM,EAAE;YAC/B,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAE7C,YAAA,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACvF;QACD,KAAK,mBAAmB,CAAC,GAAG;AAC1B,YAAA,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAC9B,KAAK,mBAAmB,CAAC,GAAG;AAC1B,YAAA,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,IAAI,CAAC;KACf;AACH,CAAC;AAED;AACA;AACA;AACM,SAAU,cAAc,CAAC,MAAmB,EAAA;AAChD,IAAA,OAAO,MAAM,CAAC,WAAW,KAAK,YAAY,CAAC;AAC7C,CAAC;AAED;AACA;AACA;AACM,SAAU,aAAa,CAAC,SAA+B,EAAA;IAC3D,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;AAChG,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAAC,MAAmB,EAAE,OAAgB,EAAA;AACnE,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;IAC5C,MAAM,UAAU,GAA0C,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;AAEpH,IAAA,IAAI,MAAM,CAAC,WAAW,KAAK,YAAY,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,EAAE;AACvF,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAsB;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAE3C,QAAA,IAAI,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE;AACrC,YAAA,OAAO,EAAE,CAAC;SACX;QAED,MAAM,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACpC,QAAA,MAAM,KAAK,GAAG,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,GAAG,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;AACzE,QAAA,MAAM,SAAS,GAAmB,OAAO,IAAI,SAAS,CAAC,SAAS,KAAK,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;AAElF,QAAA,OAAO,CAAC,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,KAAK;AACtC,kBAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE;AACvF,kBAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AAClE,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,aAAa,CAAC,MAA2B,EAAA;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AACrE,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,MAAM;SACvD,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,MACpD,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAChE,CAAC,CAAC,CAAC;AACN,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,oBAAoB,CAAC,SAA+B,EAAE,MAAmB,EAAA;AACvF,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;AAE5C,IAAA,IAAI,MAAM,CAAC,cAAc,KAAK,IAAI;WAC7B,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,WAAW;AACzE,WAAA,SAAS,CAAC,MAAM,CAAC,EAAE;AACtB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzD,IAAA,MAAM,MAAM,GAAkB,IAAI,GAAG,EAAE,CAAC;IAExC,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,CAAU,EAAE;QAC3C,MAAM,OAAO,GAAG,KAAK;AAClB,aAAA,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,MAAM,UAAU,KAAK,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;aAC1F,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC;QACjC,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACzF,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,QAAQ,KAAK,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KAC3F;IAED,OAAO,MAAM,CAAC,IAAI,GAAG,MAAM,GAAG,IAAI,CAAC;AACrC,CAAC;AAED;AACA;AACM,SAAU,cAAc,CAAC,MAAqB,EAAA;AAClD,IAAA,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAClG,CAAC;AAED;AACA;AACA,SAAS,aAAa,CAAC,MAAmB,EAAE,IAAmB,EAAA;AAC7D,IAAA,OAAO,MAAM,CAAC,QAAQ,EAAE,MAAM;UAC1B,MAAM,CAAC,QAAQ;AACjB,UAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,WAAW,CAAC,SAA+B,EAAE,SAAwB,EAAA;AACnF,IAAA,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;AACpE,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAAC,SAA+B,EAAE,MAAmB,EAAA;IACpF,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,KAAK,YAAY,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE7G,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,WAAW,MAAM,OAAO,IAAI,WAAW,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1E,CAAC;AAiBM,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAE7C;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAAC,SAA0B,EAAE,IAAmB,EAAA;IAC9E,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACtD,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC;IACjD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,KAAI;QAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AACrC,QAAA,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAC1F,QAAA,KAAK,IAAI,MAAM,IAAI,CAAC,CAAC;AACvB,KAAC,CAAC,CAAC;IAEH,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAExF,IAAA,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC;AAC1D,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAC9B,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAC5B,cAAA,GAAoD,EAAE,EACtD,UAAuC,EAAE,EAAA;AAEzC,IAAA,OAAO,gBAAgB,CAAC,kBAAkB,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9G,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,OAAoC,EAAA;AACjE,IAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/E,IAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;QACxB,OAAO,CAAA,SAAA,EAAY,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA,CAAE,CAAC;KACpD;AAED,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvE,OAAO,KAAK,CAAC,MAAM;UACf,CAAY,SAAA,EAAA,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,IAAA,EAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAE,CAAA;UACzE,IAAI,CAAC;AACX,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,MAAqB,EAAE,OAAoC,EAAA;AACnF,IAAA,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;AACrC,IAAA,MAAM,MAAM,GAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,EAAqB,GAAG,CAAC,CAAC,IAAI,KAAI;AACpE,QAAA,IAAK,IAA6B,CAAC,MAAM,EAAE;AACzC,YAAA,OAAO,IAAI,CAAC;SACb;QAED,OAAO;AACL,YAAA,GAAG,IAAI;YACP,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS;YACpC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;SACpD,CAAC;AACpB,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,IAAI;AACT,UAAE,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,OAA6C,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;AACnH,UAAE,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,aAAa,CACpB,OAA2C,EAC3C,MAAsB,EACtB,IAAY,EAAA;IAEZ,MAAM,IAAI,GAAG,CAA8B,2BAAA,EAAA,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;AACrE,IAAA,MAAM,GAAG,GAAG,OAAO,OAAO,EAAE,SAAS,KAAK,UAAU,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAEhF,OAAO;AACL,QAAA,GAAG,OAAO;AACV,QAAA,SAAS,EAAE,CAAC,MAA+C,KAAI;AAC7D,YAAA,MAAM,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEjG,YAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;AACzB,gBAAA,OAAO,IAAI,CAAC;aACb;AAED,YAAA,OAAO,IAAI,GAAG,CAAG,EAAA,IAAI,CAAQ,KAAA,EAAA,IAAI,CAAE,CAAA,GAAG,IAAI,CAAC;SAC5C;KACF,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,MAA+C,EAAA;AACnE,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAK,MAAM,CAAC,IAAgD,EAAE,MAAM,KAAK,SAAS,CAAC;AACjH,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,MAA+C,EAAE,MAAsB,EAAA;IAC3F,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACnC,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AAC/B,QAAA,MAAM,KAAK,GAAI,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,EAAE,OAAqC,EAAE,cAAc,CAAC;AACrG,QAAA,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;QAChE,MAAM,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAEnE,QAAA,OAAO,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,UAAU,CAAC,IAAI,CAAC,CAAA,EAAA,EAAK,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/D,KAAC,CAAC,CAAC;AACH,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAA6D,CAAC;IACnF,MAAM,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,cAAc,IAAI,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC;IAE/E,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;AACA,SAAS,WAAW,CAClB,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;AAC/C,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;IAE5C,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,EAAE;AAChD,QAAA,OAAO,cAAc,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,KAAK,OAAO,EAAE,OAAO,CAAC,CAAC;KACxE;AAED,IAAA,IAAI,SAAS,KAAK,WAAW,EAAE;QAC7B,OAAO,oBAAoB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;KACvD;IAED,OAAO,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,eAAe,CACtB,SAA0B,EAC1B,IAAmB,EACnB,SAAwB,EACxB,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;IAC/C,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACtD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,KAAK,YAAY,CAAC;AACvD,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;IAqBtC,MAAM,WAAW,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACpD,IAAA,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,gBAAgB,CAClC,MAAM,EACN,WAAW,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,SAAS,EACrE,WAAW,EACX,WAAW,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,EACtG,CAAC,CAAC,MAAM,EACR,UAAU,CACX,CAAC;IACF,MAAM,QAAQ,GAAG,WAAW,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;;;;IAI3G,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;AACrD,IAAA,MAAM,MAAM,GAAmB,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,KAAK,KAAI;QAC7E,MAAM,YAAY,GAAG,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AACxC,QAAA,IAAI,KAAyB,CAAC;QAC9B,IAAI,YAAY,EAAE;AAChB,YAAA,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;SAC1C;AAAM,aAAA,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE;YACpC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;SACjF;;;AAID,QAAA,MAAM,KAAK,GAAG,WAAW,IAAI,CAAC,YAAY,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;AACtE,cAAE,YAAY,CAAC,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC;cAClE,IAAI,CAAC;AACT,QAAA,MAAM,IAAI,GAAG,SAAS,GAAG,eAAe,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;AAC9E,QAAA,MAAM,QAAQ,GAAG,IAAI,IAAI,YAAY,CACnC,YAAY,IAAI,eAAe,CAAC,MAAM,EACtC,IAAI,EACJ,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,aAAa,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAC/F,CAAC;QACF,MAAM,MAAM,GAAG,WAAW,CACxB,eAAe,EACf,YAAY,GAAG,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,eAAe,CAAC,MAAM,EACvF;AACE,YAAA,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC;YAClB,KAAK;AACL,YAAA,OAAO,EAAE,OAAO,IAAI,KAAK,KAAK,CAAC;YAC/B,KAAK;YACL,OAAO,EAAE,KAAK,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC;AAC5F,YAAA,SAAS,EAAE,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,SAAS;;;YAGnD,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC,IAAI,WAAW,CAAC,eAAe,CAAC;AACzF,YAAA,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK;AAC9C,kBAAE,oBAAoB,CAAC,KAAK,CAAC;kBAC3B,kBAAkB,CAClB,eAAe,CAAC,OAAO,EACvB,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,EACvC,CAAC,CAAC,YAAY,EACd,OAAO,CACR,CAAC;AACL,SAAA,CACF,CAAC;QACF,MAAM,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAEtG,QAAA,OAAO,QAAQ,GAAG,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAkB,GAAG,MAAM,CAAC;AACrE,KAAC,CAAC,CAAC;IAEH,IAAI,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE;QACtD,MAAM,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAChF,cAAE,YAAY,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC;cAClE,SAAS,CAAC,CAAC;KAChB;;AAGD,IAAA,MAAM,QAAQ,GAAG,WAAW,GAAG,eAAe,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC;AACzE,IAAA,MAAM,UAAU,GAAG,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;AAC/D,IAAA,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;;AAExG,IAAA,MAAM,UAAU,GAAI,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,IAAI,CAAC,MAAM;AAC7E,UAAE,eAAe,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC;AAC1E,UAAE,IAAI,KAAK,cAAc,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,OAAO;AACvB,UAAE,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC;UACjF,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,KAAK,SAAS;AACtE,cAAE,UAAU,CAAC,CAAC,CAAC;cACb,gBAAgB,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE1G,IAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7E,IAAA,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;AACnF,IAAA,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,QAAQ,CACZ,cAAc,EACd,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAC3C,cAAc,CAAC,WAAW,EAAE,UAAU,CAAC,CACxC;QACD,MAAM,EAAE,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC;;;;;AAKzE,QAAA,OAAO,EAAE,MAAM;AACb,cAAE;AACA,gBAAA,OAAO,EAAE,MAAM;gBACf,SAAS,EAAE,CAAC,MAA+C,KAAK,cAAc,CAC5E,MAAM,EACN,SAAS,EACT,MAAM,EACN,WAAW,EACX,cAAc,CAAC,MAAM,CAAC,EACtB,OAAO,CACR;AACF,aAAA;cACC,qBAAqB,CAAC,WAAW,IAAI,CAAC,OAAO,GAAG;gBAChD,SAAS;gBACT,WAAW;AACX,gBAAA,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC;gBAChD,WAAW;AACX,gBAAA,SAAS,EAAE,cAAc,CAAC,MAAM,CAAC;gBACjC,OAAO;AACR,aAAA,GAAG,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE;QACrD,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,YAAY;QAC5C,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS;AAC5C,QAAA,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;KAC1H,CAAC;AACJ,CAAC;AAgED,SAAS,gBAAgB,CACvB,MAAmB,EACnB,IAAmB,EACnB,SAA+B,EAC/B,OAAgB,EAAA;IAEhB,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,MAAM,IAAI,EAAE;AAC/F,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;AACxE,IAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACpH,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;AAE7C,IAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrH,IAAA,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;AAC3H,IAAA,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEhE,OAAO;QACL,OAAO;AACP,QAAA,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC;QAChE,YAAY,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;AAC/F,QAAA,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AAC3G,QAAA,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;AAC5F,QAAA,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC;AAC5D,QAAA,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,EAAE,IAAI,KAAK,OAAO,CAAC;AAC9D,QAAA,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;QACnC,YAAY,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,YAAY;KACrD,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA,SAAS,eAAe,CACtB,MAAmB,EACnB,IAAmB,EACnB,SAA+B,EAC/B,OAA8B,EAAA;AAE9B,IAAA,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACvD,IAAA,MAAM,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC;IAEvE,OAAO,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;QAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC;AACnD,cAAE,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;cAC7D,IAAI,CAAC;AACT,QAAA,MAAM,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,SAAS,CAAC;AAEzD,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE;AACrB,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,WAAW,GAAG,CAAC,GAA4B,KAAK,GAAG,CAAC,WAAW,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;QAE7G,OAAO;YACL,KAAK;AACL,YAAA,KAAK,EAAE;AACL,gBAAA,GAAG,EAAE,WAAW,GAAG,CAAA,EAAG,KAAK,CAAA,MAAA,EAAS,KAAK,CAAA,CAAE,GAAG,KAAK;gBACnD,MAAM;AACN,gBAAA,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC;AACxE,aAAA;SACF,CAAC;AACJ,KAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,IAAmC,EAAA;AACtD,IAAA,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,gBAAgB,CAAC;AACxD,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,SAA+B,EAAE,OAAiB,EAAA;IACzE,IAAI,IAAI,GAAG,CAAC,CAAC;AACb,IAAA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;AACjD,QAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QAElC,IAAI,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YAChC,OAAO,KAAK,IAAI,IAAI,CAAC;SACtB;QAED,OAAO,uBAAuB,CAAC,IAAI,EAAE,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAC1E,KAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAW,CAAC,CAAC;AAC3E,CAAC;AAED;AACA;AACA,SAAS,UAAU,CACjB,MAAoB,EACpB,WAA6B,EAC7B,KAAa,EACb,OAAqB,EAAA;AAErB,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC;IAEjH,OAAO,WAAW,CAAC,YAAY,KAAK,IAAI,GAAG,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;AACvG,CAAC;AAED;AACA;AACA,SAAS,UAAU,CAAC,MAAoB,EAAE,OAAqB,EAAE,KAAyB,EAAA;IACxF,MAAM,KAAK,GAAG,MAAqB,CAAC;AAEpC,IAAA,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;QACxB,OAAO;AACL,YAAA,GAAG,MAAM;AACT,YAAA,SAAS,EAAE;gBACT,GAAG,KAAK,CAAC,SAAS;AAClB,gBAAA,OAAO,EAAE,iBAAiB;AAC1B,gBAAA,WAAW,EAAE,CAAC;AACd,gBAAA,UAAU,EAAE,QAAQ;AACpB,gBAAA,IAAI,KAAK,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACzC,aAAA;SACc,CAAC;KACnB;IAED,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,IAAI,gBAAgB,EAAE,EAAkB,CAAC;AAC/H,CAAC;AAED;AACA,SAAS,gBAAgB,CAAC,MAAoB,EAAE,YAAoB,EAAA;IAClE,MAAM,KAAK,GAAG,MAAqB,CAAC;AACpC,IAAA,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;AACrC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAEhC,IAAI,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;AACnD,QAAA,OAAO,MAAM,CAAC;KACf;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAG,kBAAkB,CAAC;AACrG,IAAA,IAAI,CAAC,YAAY,CAAC,IAAI,OAAO,IAAI,KAAK,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAAsC,CAAC;AAEvI,IAAA,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAkB,CAAC;AAC7C,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,MAAsB,EAAE,WAA6B,EAAA;AAC5E,IAAA,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,CAAC;IACtC,MAAM,QAAQ,GAAqB,EAAE,CAAC;IAEtC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;QAC/B,MAAM,KAAK,GAAG,MAAqB,CAAC;AACpC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QAE1C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK;eACtG,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE;YAC3E,OAAO;SACR;QAED,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAkB,CAAC;AACpF,QAAA,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAkB,EAAE,CAAC,CAAC;AAC3H,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;AACA;AACA;AACA,SAAS,aAAa,CAAC,MAAoB,EAAE,KAAa,EAAE,IAAY,EAAA;IACtE,MAAM,KAAK,GAAG,MAAqB,CAAC;AACpC,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IAE9B,OAAO;AACL,QAAA,GAAG,MAAM;AACT,QAAA,QAAQ,EAAE,SAAS;AACnB,QAAA,SAAS,EAAE,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAClE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AAC7B,YAAA,IAAI,KAAK,KAAK,IAAI,EAAE;AAClB,gBAAA,OAAO,IAAI,CAAC;aACb;AAED,YAAA,OAAO,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC;AACzG,SAAC,CAAC;KACa,CAAC;AACpB,CAAC;AAED;AACM,SAAU,gBAAgB,CAAC,KAAa,EAAA;AAC5C,IAAA,OAAO,CAAG,EAAA,kBAAkB,CAAG,EAAA,KAAK,EAAE,CAAC;AACzC,CAAC;AAED;AACA;AACM,SAAU,mBAAmB,CAAC,QAAmC,EAAA;IACrE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,kBAAkB,CAAC,EAAE;AAC7C,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;AAEhE,IAAA,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;AAC9D,CAAC;AAED;AACA,SAAS,UAAU,CAAC,IAAmD,EAAA;IACrE,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE;AACvC,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,OAAO,IAAI,KAAK,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;AACtD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,WAAW,CAClB,WAA6B,EAC7B,KAAa,EACb,OAAqB,EACrB,OAA4B,EAAA;IAE5B,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzC,IAAA,OAAO,CAAC,KAAK,EAAE,SAAS,KAAK,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;AAChH,QAAA,WAAW,EAAE,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC;AAC5C,QAAA,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI;QAC5C,IAAI,MAAM,IAAI,SAAS,KAAK,SAAS,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;AACnF,KAAA,CAAC,CAAC;AACL,CAAC;AAED;AACA,SAAS,YAAY,CACnB,WAA6B,EAC7B,KAAa,EACb,OAAqB,EACrB,OAA4B,EAAA;AAE5B,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAEhE,IAAA,OAAO,CAAC,KAAK,EAAE,SAAS,KAAK,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqD,EAAA;AACjF,IAAA,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AACrE,CAAC;AAED;AACA;AACA,SAAS,mBAAmB,CAAC,SAA+B,EAAE,WAA6B,EAAA;IACzF,OAAO;AACL,QAAA,GAAG,SAAS;AACZ,QAAA,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM;AAC/C,YAAA,GAAG,MAAM;YACT,OAAO,EAAE,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACxG,SAAA,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA,SAAS,iBAAiB,CACxB,OAAqB,EACrB,MAAyB,EACzB,WAAqC,EAAA;IAErC,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAC,OAAO,CAAC,EAAE;AACxC,QAAA,OAAO,OAAO,CAAC;KAChB;AAED,IAAA,IAAI,IAAI,GAA4B,WAAW,IAAI,eAAe,CAAC,WAAW,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;AACjH,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;QAC1B,IAAI,GAAG,gBAAgB,CAAC;KACzB;AAAM,SAAA,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE;QACnC,IAAI,GAAG,oBAAoB,CAAC;KAC7B;AAED,IAAA,OAAO,IAAI;UACP,EAAE,GAAG,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAkB;UAC9G,OAAO,CAAC;AACd,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAsB,EAAA;IAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC;AAED;AACA,SAAS,UAAU,CAAC,IAAsB,EAAA;IACxC,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;KAChE,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,qBAAqB,CAC5B,WAA6B,EAC7B,WAA6B,EAC7B,OAA4B,EAAA;IAE5B,OAAQ,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,WAAW,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,CAAC;UACnH,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE;AACpC,UAAE,OAAO,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;AACA,SAAS,aAAa,CAAC,OAA8B,EAAE,WAA6B,EAAA;IAClF,OAAQ,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC;AAC5G,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAC/B,MAAmB,EACnB,IAAmB,EACnB,SAA+B,EAAA;AAE/B,IAAA,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjF,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE;AAC3E,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,EAAE,WAAW,CAAC,WAAW;KAChC,CAAC;AACJ,CAAC;AAED;AACA;SACgB,aAAa,CAAC,SAA+B,EAAE,IAAmB,EAAE,MAAmB,EAAA;AACrG,IAAA,OAAO,aAAa,CAClB,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,EAC/E,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CACrC,CAAC;AACJ,CAAC;AAED;AACA,SAAS,WAAW,CAClB,OAA8B,EAC9B,WAA6B,EAC7B,SAAyB,EACzB,IAAqC,EAAA;IAErC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;IAE9E,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AACjF,CAAC;AAED;AACA,SAAS,gBAAgB,CAAC,MAAkB,EAAA;IAC1C,OAAO,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC;AACrE,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,eAAe,CACtB,WAA6B,EAC7B,SAA+B,EAC/B,WAA6B,EAC7B,SAAyB,EACzB,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM;SAC5B,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;AACxB,SAAA,MAAM,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,cAAc,CACxE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAC1B,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAChH,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAEjG,IAAA,OAAO,EAAE,SAAS,EAAE,CAAC,KAAa,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;AACxD,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CAAC,MAAyB,EAAE,WAAyB,EAAA;AAC1E,IAAA,OAAO,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;AAChE,YAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,WAAW,CAAC,MAAM,KAAK,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACrF,CAAC;AAED;AACA,SAAS,cAAc,CAAC,MAAkB,EAAA;IACxC,OAAO,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC5D,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAqC,EAAA;AAClE,IAAA,OAAO,MAAM;AACX,UAAE;AACA,YAAA,OAAO,EAAE,MAAe;YACxB,SAAS,EAAE,CAAC,MAA+C,KAAK,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC;AACjG,SAAA;UACC,IAAI,CAAC;AACX,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,MAA+C,EAAE,MAA8B,EAAA;AACvG,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7C,IAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;AAE1C,IAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,WAAW,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;AAErF,QAAA,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC5D,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;SACxE;KACF;AAED,IAAA,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;AACjC,SAAA,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,GAAG,MAAM,CAAC;SAC3C,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;AAEjG,IAAA,OAAO,CAAC,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,uBAAuB,CAAC,MAA8B,EAAE,SAAiB,EAAA;AAChF,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AAC9D,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW;UAC7B,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC;UAC9F,QAAQ,CAAC;IAEb,OAAO,UAAU,CAAC,SAAS,KAAK,MAAM,CAAC,WAAW,CAAC,YAAY,GAAG,CAAG,EAAA,MAAM,KAAK,mBAAmB,CAAA,CAAA,CAAG,GAAG,MAAM,CAAC,CAAC;AACnH,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oBAAoB,CAC3B,MAA8B,EAC9B,KAAa,EACb,SAAiB,EACjB,MAAc,EACd,WAAwB,EAAA;IAExB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;IAC/C,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;UAC/C,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC;UACxF,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/F,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACvD,IAAA,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC;UACzD,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC;UACxD,EAAE,CAAC;IACP,IAAI,SAAS,EAAE;AACb,QAAA,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KAChC;IAED,MAAM,KAAK,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAExG,IAAA,OAAO,CAAG,EAAA,MAAM,CAAI,CAAA,EAAA,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAK,EAAA,EAAA,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,EAAE,CAAC;AAC9H,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,mBAAmB,CAC1B,MAA8B,EAC9B,KAAa,EACb,SAAoB,EACpB,SAAiB,EAAA;AAEjB,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACvC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;AACvD,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,CAAC,KAAK,CAAC;YAC7C,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,gBAAgB,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;IAC3G,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE;QAC1G,WAAW;AACX,QAAA,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI;KAC7C,CAAC,CAAC,IAAI,CAAC;AACR,IAAA,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEhE,IAAA,OAAO,MAAM,GAAG,CAAG,EAAA,qBAAqB,IAAI,IAAI,CAAA,EAAA,EAAK,MAAM,CAAG,CAAA,CAAA,GAAG,CAAA,EAAG,qBAAqB,CAAI,CAAA,EAAA,IAAI,EAAE,CAAC;AACtG,CAAC;AAED;AACA;AACA;AACA,SAAS,YAAY,CAAC,MAA8B,EAAE,KAAa,EAAE,SAAiB,EAAA;IACpF,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEjD,IAAA,IAAI,MAAM,EAAE,IAAI,KAAK,OAAO,EAAE;QAC5B,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;KAC/C;AAED,IAAA,OAAO,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;AACpH,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,WAAW,CAAC,MAA8B,EAAE,MAAkB,EAAE,SAAiB,EAAA;AACxF,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC;IACjD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;AAC3C,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;AAErC,IAAA,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE;AAC1B,QAAA,OAAO,EAAE,CAAC;KACX;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE;QACtD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAExC,QAAA,OAAO,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;KACzE;AAED,IAAA,MAAM,OAAO,GAAG,SAAS,KAAK,MAAM,CAAC,WAAW,CAAC,YAAY,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC;AAChG,IAAA,MAAM,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAElH,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,IAAI,UAAU,CAAC,IAAI,KAAK,YAAY,EAAE;AACpC,QAAA,OAAO,CAAM,GAAA,EAAA,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;KAC/D;AAED,IAAA,OAAO,eAAe,CACpB,EAAE,GAAG,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,GAAG,IAAI,EAAE,EACvH,UAAU,CAAC,QAAQ,EACnB,MAAM,CACP,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,cAAc,CACrB,MAAsC,EACtC,IAAkC,EAAA;IAElC,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,MAAM,CAAC;KACf;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IACpE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;AAE1D,IAAA,OAAO,KAAK,IAAI,GAAG,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;AAChD,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CACxB,QAAgB,EAChB,WAA6B,EAC7B,MAAwB,EACxB,KAAkB,EAAA;AAElB,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACjC,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AACzB,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAE3B,IAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE;AACtC,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,IAAI,GAAG,CAAC,IAAU,KAAK,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;AAC5D,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,KAAK,GAAGC,GAAU,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;AAE9F,IAAA,OAAO,EAAE,KAAK,EAAEC,aAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,EAAEA,aAAW,CAACC,GAAQ,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7F,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CACrB,KAAW,EACX,WAAiB,EACjB,IAA0B,EAC1B,IAAsB,EAAA;AAEtB,IAAA,MAAM,GAAG,GAAGA,GAAQ,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;AACvD,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;IAExB,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;AAChG,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAE,IAAsB,EAAE,KAAa,EAAA;IACnE,QAAQ,IAAI;AACV,QAAA,KAAK,KAAK;AACR,YAAA,OAAO,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9B,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/B,QAAA,KAAK,SAAS;AACZ,YAAA,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAClC,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/B,QAAA;AACE,YAAA,OAAO,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;KACjC;AACH,CAAC;AAED,SAASD,aAAW,CAAC,IAAU,EAAA;IAC7B,OAAO,SAAS,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC;AACrD,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,SAAS,CAAC,QAAgB,EAAA;AACjC,IAAA,IAAI;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,QAAQ,CAAC;AAC/F,aAAA,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,CAAC,IAAkC,KAAK,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/G,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAErE,QAAA,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;AAClB,YAAA,OAAO,KAAK,CAAC;SACd;KACF;AAAC,IAAA,MAAM;;KAEP;AAED,IAAA,OAAO,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AAChC,CAAC;AAED;AACA;AACA;AACA,SAAS,eAAe,CACtB,KAAmB,EACnB,SAA+B,EAC/B,OAA4B,EAC5B,KAAiC,EAAA;IAEjC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;AAC7C,IAAA,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,IAAI,YAAY,CACnC,aAAa,CAAC,SAAS,CAAC,EACxB,IAAI,EACJ,KAAK,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,EACxC,CAAI,CAAA,EAAA,sBAAsB,CAAE,CAAA,CAC7B,CAAC;AAEF,IAAA,OAAO,QAAQ,GAAG,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAkB,GAAG,KAAK,CAAC;AACnE,CAAC;AAED;AACA;AACA;AACA,SAAS,YAAY,CACnB,MAAyB,EACzB,IAAyB,EACzB,KAAgC,EAChC,KAAc,EAAA;IAEd,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEvC,IAAA,IAAI,KAAK,KAAK,IAAI,EAAE;AAClB,QAAA,OAAO,SAAS,CAAC;KAClB;AAED,IAAA,MAAM,IAAI,GAAG,CAAG,EAAA,UAAU,CAAC,IAAI,CAAC,CAAA,EAAA,EAAK,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IAEpD,OAAO;AACL,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,MAAM,EAAE,MAAM;QACd,SAAS,EAAE,EAAE,IAAI,EAAE,QAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE;AAC7E,QAAA,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,IAAI,EAAE,QAAQ,EAAE,cAAuB,EAAE,QAAQ,EAAE,2BAA2B,EAAE,GAAG,cAAc,EAAE;AAC7H,QAAA,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;KACzB,CAAC;AACJ,CAAC;AAED;AACA,SAAS,aAAa,CAAC,OAAiC,EAAE,OAA4B,EAAA;AACpF,IAAA,OAAO,CAAC,KAAK,KAAK,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,OAA4B,EAAA;IAC/C,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AAExD,IAAA,OAAO,CAAC,KAAK,KAAK,YAAY,CAAC,KAAK,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;AAC5E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CAAC,UAA4B,EAAE,UAAoB,EAAA;AAC3E,IAAA,MAAM,KAAK,GAAG,CAAI,CAAA,EAAA,sBAAsB,EAAE,CAAC;IAE3C,OAAQ,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,OAAO,CAAC,CAAC,SAAS,KAAoB;AAC7D,QAAA,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;AACnF,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC5D,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;AAE3D,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAClB,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,OAAO,CAAC;AACN,gBAAA,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC;AAChC,gBAAA,UAAU,EAAE,SAAS;AACrB,gBAAA,MAAM,EAAE,IAAI;AACZ,gBAAA,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;AACxB,gBAAA,QAAQ,EAAE;AACR,oBAAA,MAAM,EAAE,IAAI;AACZ,oBAAA,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;AAC9C,oBAAA,KAAK,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,QAAQ,EAAE,2BAA2B,EAAE,GAAG,cAAc,EAAE;AACpG,oBAAA,IAAI,EAAE;AACJ,wBAAA,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;wBACpG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM;4BAC3B,KAAK,EAAE,SAAS,CAAC,IAAI;;;AAGrB,4BAAA,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;AACvB,4BAAA,KAAK,EAAE,EAAE,QAAQ,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC,KAAK,EAAE;AAC3E,yBAAA,CAAC,CAAC;AACJ,qBAAA;AACF,iBAAA;AACD,gBAAA,IAAI,KAAK,CAAC,MAAM,GAAG;AACjB,oBAAA,QAAQ,EAAE;AACR,wBAAA,MAAM,EAAE,IAAI;AACZ,wBAAA,SAAS,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE;wBACzC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;AACtF,qBAAA;iBACF,GAAG,EAAE,CAAC;AACQ,aAAA,CAAC,CAAC;AACrB,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACgB,SAAA,aAAa,CAAC,UAA4B,EAAE,SAAyB,EAAA;IACnF,MAAM,KAAK,GAAG,cAAc,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAEpD,IAAA,OAAO,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACzE,CAAC;AAED;AACA;AACA;AACA,SAAS,eAAe,CACtB,MAA6B,EAC7B,MAAsB,EACtB,UAA4B,EAAA;IAE5B,OAAO,UAAU,CAAC,MAAM;UACpB,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE;UAClE,MAAM,CAAC;AACb,CAAC;AAED;AACA;AACA,SAAS,cAAc,CAAC,UAA4B,EAAE,SAAyB,EAAA;AAC7E,IAAA,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;IAEnF,OAAO,MAAM,CAAC,MAAM;UAChB,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE;UAC5H,SAAS,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,QAAQ,CAAC,KAAiC,EAAA;AACjD,IAAA,OAAO,KAAK;AACV,UAAE,CAAC,MAAkB,MAAM,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;UACxG,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,KAAiC,EAAA;AACjD,IAAA,OAAO,KAAK;AACV,UAAE,CAAC,MAAkB,MAAM,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;UACxG,SAAS,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5D,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B,SAAS,eAAe,CAAC,SAAiB,EAAA;AACxC,IAAA,MAAM,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;;;AAItG,IAAA,OAAO,MAAM,CAAC,CAAC,IAAI,GAAG,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CACzB,MAAmB,EACnB,IAAmB,EACnB,UAAoB,EACpB,UAAmB,EACnB,MAAuB,EAAA;AAEvB,IAAA,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;AAC5C,IAAA,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;AACzC,IAAA,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAChF,IAAA,MAAM,IAAI,GAAG;AACX,QAAA,IAAI,EAAE,UAAmB;AACzB,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,OAAO,EAAE,UAAU;AACnB,QAAA,IAAI,EAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC;AACrC,QAAA,YAAY,EAAE,QAAiB;AAC/B,QAAA,IAAI,WAAW,GAAG;AAChB,YAAA,WAAW,EAAE;AACX,gBAAA,KAAK,EAAE;oBACL,SAAS,EAAE,CAAC,MAA0B,KAAK,iBAAiB,CAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EACpB,WAAW,EACX,IAAI,EACJ,MAAM,EACN,SAAS,CACV;AACF,iBAAA;AACF,aAAA;SACF,GAAG,EAAE,CAAC;KACR,CAAC;IAEF,IAAI,CAAC,UAAU,EAAE;;AAEf,QAAA,MAAM,UAAU,GAAG,WAAW,IAAI,SAAS,KAAK,oBAAoB,CAAC,KAAK,IAAI,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAE7G,OAAO;AACL,YAAA,GAAG,IAAI;YACP,OAAO,EAAE,UAAU,GAAG,EAAE,GAAG,EAAE;AAC7B,YAAA,GAAG,WAAW;SACf,CAAC;KACH;;;;;IAMD,MAAM,KAAK,GAAG,WAAW;AACvB,UAAE,IAAI;UACJ,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,QAAQ,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,uBAAuB,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAEjH,OAAO;AACL,QAAA,GAAG,IAAI;QACP,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,iBAAiB,GAAG,mBAAmB;AAC1E,QAAA,IAAI,KAAK,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,CAAC,KAAa,KAAK,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,EAAE,EAAE,GAAG,WAAW,CAAC;KACtG,CAAC;AACJ,CAAC;AAED;AACA;AACgB,SAAA,iBAAiB,CAAC,MAAmB,EAAE,IAAmB,EAAA;IACxE,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC;AAChF,CAAC;AAED;AACA;AACA,SAAS,iBAAiB,CAAC,MAAmB,EAAE,IAAmB,EAAE,UAAmB,EAAA;IACtF,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;AACpC,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AACxC,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CAAC,IAAoC,EAAE,UAAmB,EAAA;AAC/E,IAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,KAAK,CAAC,EAAE;AACrC,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO,UAAU,GAAG,QAAQ,GAAG,KAAK,CAAC;AACvC,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,uBAAuB,CAC9B,UAAoB,EACpB,WAAoC,EACpC,MAAuB,EACvB,SAA+B,EAAA;AAE/B,IAAA,OAAO,WAAW;UACd,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,IAAI,QAAQ,CAAC;UAC7G,UAAU,CAAC;AACjB,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,MAAgB,EAAA;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAC9D,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAChE,MAAM,CACP,EAAE,CAAC,CAAC,CAAC;AACR,CAAC;AAED;AACA;AACA,SAAS,iBAAiB,CAAC,KAAa,EAAA;AACtC,IAAA,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AACpC,QAAA,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,wBAAwB,EAAE;AACpD,YAAA,OAAO,IAAI,CAAC;SACb;;QAGD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,CAAC,MAAc,KAAK,CAAG,EAAA,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA,EAAG,cAAc,CAAA,CAAE,CAAC;QACrG,IAAI,IAAI,GAAG,CAAC,CAAC;AACb,QAAA,IAAI,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC;AAChC,QAAA,OAAO,OAAO,GAAG,IAAI,GAAG,CAAC,EAAE;AACzB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC;YAChD,IAAI,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,wBAAwB,EAAE;gBAC3D,IAAI,GAAG,MAAM,CAAC;aACf;iBAAM;gBACL,OAAO,GAAG,MAAM,CAAC;aAClB;SACF;AAED,QAAA,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AACnB,KAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA,IAAI,gBAAgB,GAAoC,IAAI,CAAC;AAE7D,SAAS,cAAc,CAAC,IAAY,EAAA;IAClC,IAAI,CAAC,gBAAgB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;AACxD,QAAA,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;KACtE;IAED,IAAI,CAAC,gBAAgB,EAAE;AACrB,QAAA,OAAO,CAAC,CAAC;KACV;AAED,IAAA,gBAAgB,CAAC,IAAI,GAAG,eAAe,CAAC;IAExC,OAAO,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;AAClD,CAAC;AAED,SAAS,oBAAoB,CAC3B,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;IAC/C,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACpD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,KAAK,YAAY,CAAC;AACvD,IAAA,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC;AAChE,IAAA,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;;;;IAI9F,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAClD,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,CAAC,sBAAsB,CACnG,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,EAC3C,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EACzH,OAAO,CACR,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;;IAEvD,MAAM,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACxD,IAAA,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,QAAQ,CACZ,cAAc,EACd,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,EAC3C,cAAc,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,UAAU,CAAC,CAC/C;AACD,QAAA,MAAM,EAAE,EAAE,GAAG,YAAY,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;;AAEnE,QAAA,OAAO,EAAE;AACP,YAAA,OAAO,EAAE,MAAM;AACf,YAAA,SAAS,EAAE,CAAC,MAA+C,KAAK,gBAAgB,CAC9E,SAAS,EACT,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,EAAE,SAAS,EACtD,WAAW,EACX,cAAc,CAAC,MAAM,CAAC,EACtB,IAAI,EACJ,OAAO,CACR;AACF,SAAA;QACD,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,YAAY;QAC5C,KAAK,EAAE,UAAU,GAAG,YAAY,GAAG,SAAS;AAC5C,QAAA,MAAM,EAAE,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,EAAE,GAAG,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;KACtF,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,eAAe,CAAC,SAA6B,EAAA;IACpD,OAAO;AACL,QAAA;AACE,YAAA,IAAI,EAAE,KAAK;AACX,YAAA,KAAK,EAAE,WAAW;AAClB,YAAA,aAAa,EAAE,KAAK;AACpB,YAAA,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC;AAC/C,YAAA,WAAW,EAAE,EAAE;AACf,YAAA,SAAS,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE;AACnC,YAAA,MAAM,EAAE,IAAI;AACb,SAAA;AACD,QAAA;YACE,IAAI,EAAE,SAAS,CAAC,IAAI;AACpB,YAAA,IAAI,EAAE,KAAK;AACX,YAAA,KAAK,EAAE,WAAW;AAClB,YAAA,aAAa,EAAE,KAAK;AACpB,YAAA,WAAW,EAAE,EAAE;;;;;YAKf,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,uBAAuB,CAAC,IAAI,CAAA,CAAE,EAAE;AACxD,YAAA,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;gBACnC,KAAK,EAAE,IAAI,CAAC,MAAM;AAClB,gBAAA,SAAS,EAAE,EAAE,KAAK,EAAE,CAAI,CAAA,EAAA,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE,EAAE;AAC9D,gBAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACxD,aAAA,CAAC,CAAC;AACJ,SAAA;KACF,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CACvB,SAA6B,EAC7B,KAAa,EACb,WAAoC,EACpC,SAA+B,EAC/B,IAAkC,EAClC,OAA4B,EAAA;IAE5B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACpC,IAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW;AACrC,UAAE,iBAAiB,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAChF,UAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnB,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACxC,IAAA,MAAM,MAAM,GAAG,CAAC,KAAoB,KAAK,YAAY,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AAElF,IAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE;AACzB,QAAA,OAAO,CAAG,EAAA,QAAQ,CAAQ,KAAA,EAAA,IAAI,CAAK,EAAA,EAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA,CAAE,CAAC;KAC1D;AAED,IAAA,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC;AAE/C,IAAA,OAAO,CAAG,EAAA,QAAQ,CAAQ,KAAA,EAAA,IAAI,CAAK,EAAA,EAAA,IAAI,CAAG,EAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAE,CAAA;AAC3D,UAAA,CAAA,oBAAA,EAAuB,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACvE,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,qBAAqB,CAAC,MAAmB,EAAE,WAAmB,EAAE,OAAO,GAAG,KAAK,EAAA;AAC7F,IAAA,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,OAAO,MAAM,CAAC,MAAM,CAAC;KACtB;AAED,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,CAAC;;;IAIvE,OAAO,GAAG,IAAI,OAAO,IAAI,WAAW,GAAG,CAAC,IAAI,GAAG,GAAG,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC;AAChF,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CAAC,MAAqB,EAAE,QAA2C,EAAA;AAC5F,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE;AAC9F,QAAA,OAAO,MAAM,CAAC;KACf;AAED,IAAA,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE,CAAC;AACzE,CAAC;AAED,SAAS,YAAY,CAAC,QAAwB,EAAA;AAC5C,IAAA,IAAI,QAAQ,KAAK,QAAQ,EAAE;AACzB,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;KACxB;AAED,IAAA,MAAM,IAAI,GAA0B,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAEvD,QAAQ,QAAQ;AACd,QAAA,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAChC,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AACjE,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClE,QAAA;YACE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAC9B;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,QAAQ,CACf,QAAwB,EACxB,aAAmC,EACnC,UAAgC,EAAA;IAEhC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,MAAM,CACvC,CAAC,IAAI,EAAE,IAAI,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,cAAc,EAAE,GAAG,IAAI,CAAC,EAChF,UAAU,CAAC,QAAQ,CAAC,CACrB,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,UAAU,CAAC,QAAwB,EAAA;IAC1C,MAAM,IAAI,GAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAEzF,QAAQ,QAAQ;AACd,QAAA,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AACjC,QAAA,KAAK,MAAM;YACT,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC/B,QAAA,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAChC,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,IAAI,CAAC;AACd,QAAA;YACE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;KAC/B;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,QAAQ,CAAC,IAAmB,EAAE,KAAc,EAAE,SAAqC,EAAA;AAC1F,IAAA,IAAI,SAAS,KAAK,SAAS,EAAE;AAC3B,QAAA,OAAO,CAAS,MAAA,EAAA,IAAI,CAAI,CAAA,EAAA,SAAS,EAAE,CAAC;KACrC;IAED,OAAO,KAAK,GAAG,CAAA,MAAA,EAAS,IAAI,CAAA,CAAE,GAAG,OAAO,CAAC;AAC3C,CAAC;AAiBD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,WAAW,CAClB,MAAgC,EAChC,MAAyC,EACzC,MAAoB,EAAA;;IAGpB,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AACpF,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAC3B,IAAA,MAAM,SAAS,GAAG,KAAK,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC;AAExD,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE;;;AAGzB,QAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC;QAE7G,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;AACjB,YAAA,IAAI,EAAE,KAAK;YACX,IAAI;YACJ,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;AACvB,YAAA,GAAG,IAAI;AACP,YAAA,GAAG,SAAS;AACZ,YAAA,WAAW,EAAE,EAAE;;YAEf,IAAI,MAAM,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACrE,YAAA,GAAG,MAAM;SACV,CAAC;KACH;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAClD,IAAA,MAAM,SAAS,GAAG,KAAK,IAAI,QAAQ;AACjC,UAAE,EAAE,SAAS,EAAE,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,QAAQ,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;UACvF,EAAE,CAAC;AACP,IAAA,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAE/E,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;AACjB,QAAA,IAAI,EAAE,MAAM;QACZ,IAAI;QACJ,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;AACvB,QAAA,GAAG,IAAI;AACP,QAAA,GAAG,SAAS;AACZ,QAAA,GAAG,SAAS;QACZ,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAClE,QAAA,MAAM,EAAE,IAAI;AACZ,QAAA,UAAU,EAAE,CAAC;AACb,QAAA,SAAS,EAAE,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,SAAS;;;AAGjE,QAAA,IAAI,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AACjC,QAAA,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAAC,MAAyB,EAAE,MAAyB,EAAA;IACrE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAC7B,IAAuC,EACvC,SAA6B,EAAA;AAE7B,IAAA,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,IAAa,EAAE,QAAQ,EAAE,2BAA2B,EAAE,SAAS,EAAE,CAAC;IAEvF,QAAQ,IAAI;QACV,KAAK,qBAAqB,CAAC,GAAG;YAC5B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACvD,KAAK,qBAAqB,CAAC,IAAI;YAC7B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACtD,KAAK,qBAAqB,CAAC,IAAI;YAC7B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AACtD,QAAA;AACE,YAAA,OAAO,IAAI,CAAC;KACf;AACH,CAAC;AAED;AACA;AACA;AACA,SAAS,eAAe,CACtB,MAA+B,EAC/B,QAAW,EACX,MAAyC,EAAA;IAEzC,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;KACrC;IAED,MAAM,KAAK,GAAiB,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;AAEzD,IAAA,IAAI,MAAM,CAAC,QAAQ,EAAE;AACnB,QAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;KAC5D;IAED,OAAO;QACL,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,MAAM,CAAC,WAAW,GAAG,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;AACxF,QAAA,IAAI,EAAE,MAAM;KACb,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,cAAc,CACrB,MAAyC,EACzC,KAAmB,EAAA;AAEnB,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAS,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAE5G,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAuB;AACnD,QAAA,IAAI,KAAK,KAAK,IAAI,EAAE;AAClB,YAAA,OAAO,IAAI,CAAC;SACb;QAED,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7E,KAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,IAAmC,EAAA;IAC1D,OAAO,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CACzB,OAAqB,EACrB,UAAkC,EAClC,KAAc,EACd,OAA4B,EAAA;IAE5B,IAAI,KAAK,EAAE;AACT,QAAA,MAAM,OAAO,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAE/C,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;KAC1C;IAED,IAAI,UAAU,EAAE;AACd,QAAA,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;AAEvF,QAAA,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;KACpF;AAED,IAAA,OAAO,CAAC,MAAM,KAAK,iBAAiB,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC/E,CAAC;AAED;AACA;AACA,SAAS,cAAc,CAAC,MAAuB,EAAA;AAC7C,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,GAAI,IAA0B,CAAC,GAAG,GAAG,SAAS,CAAC;AAEpG,IAAA,OAAO,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC;AAC7B,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CACrB,MAA+C,EAC/C,SAA+B,EAC/B,MAAqB,EACrB,WAAoC,EACpC,SAA+B,EAC/B,OAA4B,EAAA;AAE5B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACvD,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW;AACpC,UAAE,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;UACzE,QAAQ,CAAC,CAAC;IACd,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAExD,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AAC/B,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;AACxD,QAAA,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;AAClE,QAAA,MAAM,KAAK,GAAG,CAAA,EAAG,MAAM,CAAI,CAAA,EAAA,UAAU,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,CAAC;QAC7G,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;QAE3E,OAAO,KAAK,KAAK,IAAI;AACnB,cAAE,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,KAAK,CAAE,CAAA;AACtB,cAAE,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,YAAY,CAAC,KAAK,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAK,EAAA,EAAA,KAAK,GAAG,CAAC;AACxF,KAAC,CAAC,CAAC;IAEH,OAAO,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CACtB,IAAgC,EAChC,UAAmB,EACnB,SAAyB,EACzB,MAAA,GAA0B,EAAE,EAAA;AAE5B,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS;AAC3C,UAAE,cAAc,CAAC,IAAI,CAAC;AACtB,UAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE,gBAAgB,EAAE,QAAQ,EAAE,qBAAqB,EAAE,CAAC;IAEvF,OAAO;AACL,QAAA,IAAI,EAAE,OAAgB;AACtB,QAAA,IAAI,EAAE,IAAI,EAAE,KAAK,IAAI,SAAS;QAC9B,YAAY,EAAE,UAAU,GAAG,QAAiB,GAAG,KAAc;QAC7D,OAAO,EAAE,UAAU,GAAG,EAAE,GAAG,EAAE;QAC7B,aAAa,EAAE,UAAU,GAAG,SAAS,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,CAAC,GAAG,OAAgB,GAAG,MAAe,EAAE;;;QAG1G,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI,GAAG,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;QACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS;QACT,IAAI,MAAM,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,IAAgC,EAAA;IAC7D,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE5C,OAAO;AACL,QAAA,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;AAC1B,QAAA,GAAG,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC;AAC1B,QAAA,QAAQ,EAAE,QAAQ,KAAK,SAAS,IAAI,QAAQ,GAAG,CAAC,GAAG,QAAQ,GAAG,SAAS;KACxE,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CACzB,MAAmB,EACnB,UAA4B,EAC5B,OAA4B,EAC5B,UAA8B,EAC9B,UAA4B,EAC5B,QAAmB,EAAA;AAEnB,IAAA,MAAM,OAAO,GAAG,UAAU,KAAK,SAAS,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,SAAyB,KAAK,UAAU,CAAC,SAAS,CAAC,CAAC;IAEnE,OAAO;QACL,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;AACvF,YAAA,KAAK,EAAE,CAAC;YACR,UAAU;AACV,YAAA,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;AACpC,YAAA,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;SAClB,CAAC;AACF,QAAA;AACE,YAAA,GAAG,eAAe,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE;AACxD,gBAAA,KAAK,EAAE,CAAC;AACR,gBAAA,KAAK,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;AACpC,gBAAA,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;aAClB,CAAC;AACF,YAAA,QAAQ,EAAE,OAAgB;AAC1B,YAAA,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;AAC1B,YAAA,UAAU,EAAE,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,mBAAA,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC;AAC5E,SAAA;KACF,CAAC;AACJ,CAAC;AAED;AACA,SAAS,YAAY,CAAC,IAAgC,EAAA;IACpD,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,SAAS,CAAC,CAAC;AAClF,CAAC;AAED;AACA,SAAS,UAAU,CAAC,KAAc,EAAA;AAChC,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC;AACjF,CAAC;AAOD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,MAA8B,EAAE,OAA4B,EAAA;IAClF,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,iBAAiB,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,EAAE;AAChG,QAAA,OAAO,EAAE,SAAS,EAAE,CAAC,KAAa,KAAK,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;KACnF;AAED,IAAA,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAE/E,OAAO;AACL,QAAA,SAAS,EAAE,CAAC,KAAa,KAAK,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;KACxF,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA,SAAS,sBAAsB,CAC7B,IAA6B,EAC7B,IAAkB,EAClB,OAA4B,EAAA;IAE5B,OAAO,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;AACjG,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CACvB,MAAmB,EACnB,SAA+B,EAC/B,WAA6B,EAC7B,QAA+B,EAC/B,OAAgB,EAChB,UAA4B,EAAA;IAE5B,MAAM,KAAK,GAAG,CAAC,SAAyB,MAAM,OAAO,IAAI,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;IAErH,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;AAC5B,QAAA,OAAO,CAAC,sBAAsB,CAC5B,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,EAClE,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAC3G,QAAQ,CAAC,CAAC,CAAC,CACZ,CAAC,CAAC;KACJ;IAED,OAAQ,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,KAAI;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;AAEvF,QAAA,OAAO,sBAAsB,CAC3B,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,EACxD,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,EACrH,QAAQ,CAAC,SAAS,CAAC,CACpB,CAAC;AACJ,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA,SAAS,gBAAgB,CAAC,OAA4B,EAAA;IACpD,OAAO,EAAE,SAAS,EAAE,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;AACvD,CAAC;AAED;AACA;AACA,SAAS,qBAAqB,CAAC,OAA4B,EAAA;IACzD,MAAM,YAAY,GAAG,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;AAExD,IAAA,OAAO,CAAC,KAAc,KAAK,YAAY,CAAC,KAAK,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAAC;AACpF,CAAC;AAOD;AACA;AACA;AACA;AACA,SAAS,aAAa,CAAC,OAAiC,EAAE,OAA4B,EAAA;AACpF,IAAA,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE;AAC7B,QAAA,OAAO,EAAE,cAAc,EAAE,CAAC,KAAc,KAAK,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;KACzF;IAED,OAAO;AACL,QAAA,cAAc,EAAE,CAAC,KAAc,KAAK,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;KAC5G,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,SAA0B,EAC1B,IAAmB,EACnB,KAAc,EACd,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;IAC/C,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACtD,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC;AACjD,IAAA,MAAM,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAE9E,OAAO;AACL,QAAA,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;AAC5B,QAAA,MAAM,EAAE,YAAY,CAAC,cAAc,CAAC;AACpC,QAAA,MAAM,EAAE;AACN,YAAA;AACE,gBAAA,IAAI,EAAE,KAAK;AACX,gBAAA,MAAM,EAAE,KAAK,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK;AACtC,gBAAA,MAAM,EAAE,SAAS,CAAC,cAAc,CAAC;AACjC,gBAAA,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC;AAC7D,gBAAA,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;AACtB,gBAAA,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,MAAM;AACnD,oBAAA,IAAI,EAAE,QAAQ;AACd,oBAAA,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;AAC1B,iBAAA,CAAC,CAAC;AACJ,aAAA;AACF,SAAA;KACF,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAAC,QAAwB,EAAA;IACzC,QAAQ,QAAQ;AACd,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxB,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxB,QAAA,KAAK,KAAK;AACR,YAAA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxB,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACxB,QAAA;AACE,YAAA,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KACzB;AACH,CAAC;AAED,SAAS,YAAY,CAAC,IAA+B,EAAE,MAAc,EAAA;AACnE,IAAA,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;IAChC,MAAM,MAAM,GAAc,EAAE,CAAC;AAC7B,IAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;AACtB,QAAA,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AACpB,YAAA,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChB,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACpB;KACF;AAED,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAASF,SAAO,CAAC,KAAc,EAAA;AAC7B,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE;AACzD,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAE7B,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;AACjD,CAAC;AAED;AACA;AACA,SAAS,iBAAiB,CAAC,IAAmB,EAAA;IAC5C,OAAO,IAAI,CAAC,WAAW,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC;UAC9F,IAAI,CAAC,WAAW;UAChB,IAAI,CAAC;AACX,CAAC;AAED;AACA;AACM,SAAU,kBAAkB,CAAC,UAAoB,EAAA;AACrD,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;AAChC,IAAA,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE;AACjC,QAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAChC,QAAA,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE;YACjB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;SAC/B;KACF;AAED,IAAA,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;AACxB,CAAC;AAED;AACA;AACM,SAAU,cAAc,CAAC,MAA+B,EAAA;IAC5D,OAAO,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC;WACzF,oBAAoB,CAAC,KAAK,CAAC;AAClC,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CACvB,KAAa,EACb,WAA6B,EAC7B,MAAuB,EACvB,SAAA,GAAkC,oBAAoB,CAAC,KAAK,EAAA;AAE5D,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7B,IAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACxC,IAAA,IAAI,WAAW,KAAK,MAAM,EAAE;AAC1B,QAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KAChC;AAED,IAAA,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC;AACrF,CAAC;AAED;AACA;AACA,SAAS,kBAAkB,CACzB,IAAU,EACV,WAA8C,EAC9C,MAAuB,EACvB,SAA+B,EAAA;IAE/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AACxC,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpD,IAAA,IAAI,SAAS,KAAK,oBAAoB,CAAC,OAAO,EAAE;AAC9C,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3D,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACpD,QAAQ,WAAW;AACjB,YAAA,KAAK,SAAS;AACZ,gBAAA,OAAO,CAAG,EAAA,IAAI,CAAK,EAAA,EAAA,OAAO,EAAE,CAAC;AAC/B,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,KAAK,EAAE,CAAC;AAC5B,YAAA;AACE,gBAAA,OAAO,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAI,CAAA,EAAA,GAAG,EAAE,CAAC;SACpC;KACF;AAED,IAAA,MAAM,IAAI,GAAG,SAAS,KAAK,oBAAoB,CAAC,IAAI,CAAC;IACrD,QAAQ,WAAW;AACjB,QAAA,KAAK,SAAS;AACZ,YAAA,OAAO,IAAI;kBACP,CAAG,EAAA,aAAa,CAAC,MAAM,CAAC,CAAG,EAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAAE,CAAA;kBAC5C,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA,EAAG,OAAO,CAAA,CAAE,CAAC;AAC3C,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC;AACvE,QAAA;AACE,YAAA,OAAO,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC,CAAC;KACtE;AACH,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,WAA6B,EAAE,SAA+B,EAAA;IACrF,OAAO,WAAW,KAAK,MAAM,IAAI,SAAS,KAAK,oBAAoB,CAAC,KAAK,CAAC;AAC5E,CAAC;AAED,SAAS,aAAa,CAAC,MAAuB,EAAA;AAC5C,IAAA,OAAO,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,cAAc,CAAC;AACpF,CAAC;AAED;AACA;AACA;AACgB,SAAA,iBAAiB,CAC/B,KAAa,EACb,WAA6B,EAC7B,SAAkB,EAClB,MAAuB,EACvB,SAAkC,GAAA,oBAAoB,CAAC,KAAK,EAAA;AAE5D,IAAA,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,KAAK,CAAC;KACd;IAED,OAAO,SAAS,IAAI,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,CAAG,EAAA,KAAK,CAAC,OAAO,CAAA,CAAA,EAAI,KAAK,CAAC,IAAI,CAAA,CAAE,GAAG,KAAK,CAAC,OAAO,CAAC;AACjH,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,aAAa,CAC3B,MAAkB,EAClB,IAAmB,EACnB,MAAuB,EAAA;AAEvB,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;AACnC,IAAA,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE9C,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;AACnC,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;AACf,YAAA,OAAO,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,MAAM,CAAC;SACtC;QAED,OAAO,IAAI,CAAC,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;AACpG,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA;SACgB,gBAAgB,CAC9B,MAAkB,EAClB,IAAmB,EACnB,MAAuB,EAAA;IAEvB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACrD,IAAA,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACrC,IAAA,MAAM,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;AAC5C,IAAA,MAAM,KAAK,GAAuD,OAAO,IAAI,UAAU;UACnF,EAAE,MAAM,EAAE,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE;UACzG,EAAE,CAAC;AAEP,IAAA,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,KAAK,KAAK,CAAC;AAC5D,UAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;AACpD,UAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;AACA;AACA,SAAS,gBAAgB,CAAC,MAAkC,EAAA;AAC1D,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC,CAAC;AACjF,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,eAAe,CACtB,WAAoC,EACpC,UAAoB,EACpB,MAAuB,EACvB,SAA+B,EAAA;IAE/B,IAAI,CAAC,WAAW,EAAE;AAChB,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,SAAS,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAEjD,OAAO;AACL,QAAA,SAAS,EAAE;AACT,YAAA,SAAS,EAAE,CAAC,KAAa,KAAI;AAC3B,gBAAA,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;gBACtE,IAAI,CAAC,KAAK,EAAE;AACV,oBAAA,OAAO,KAAK,CAAC;iBACd;AAED,gBAAA,OAAO,SAAS,IAAI,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC;sBACvD,GAAG,KAAK,CAAC,OAAO,CAAS,MAAA,EAAA,KAAK,CAAC,IAAI,CAAG,CAAA,CAAA;AACxC,sBAAE,KAAK,CAAC,OAAO,CAAC;aACnB;AACD,YAAA,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE;AACjE,SAAA;KACF,CAAC;AACJ;;ACt9FA;AACA;AACA;AACA;AACA;AACA;AAGA;AACO,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C;AACA;AACO,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAG9E;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAC9B,KAAsD,EACtD,aAAkD,EAAA;IAElD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC;AACzF,CAAC;AAED;AACA;AACA;SACgB,YAAY,CAAC,KAAgC,EAAE,SAA4B,EAAE,EAAA;AAC3F,IAAA,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC;SAC5B,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,qBAAqB,CAAC,CAAC;AACjC,CAAC;AAED;AACA;AACgB,SAAA,cAAc,CAAC,IAAwC,EAAE,MAAuB,EAAA;IAC9F,OAAO,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED;AACA;AACgB,SAAA,mBAAmB,CACjC,KAA4C,EAC5C,aAAkD,EAAA;IAElD,MAAM,IAAI,GAAG,KAAK,EAAE,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;AAE7E,IAAA,OAAO,IAAI,GAAG,CAAG,EAAA,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA,sCAAA,CAAwC,GAAG,IAAI,CAAC;AAC7G,CAAC;AAED;AACA;AACA;AACM,SAAU,gBAAgB,CAAC,KAA4C,EAAA;IAC3E,OAAO,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAAC,KAA4C,EAAE,UAAmB,EAAA;IAC/F,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,KAAK,CAAC,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,KAAK,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC;AAC9E,CAAC;AAED;AACA;AACA;AACA,SAAS,UAAU,CAAC,IAAwC,EAAE,MAAuB,EAAE,IAAa,EAAA;IAClG,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;QACjC,OAAO,IAAI,CAAC,KAAK,CAAC;KACnB;AAED,IAAA,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE,EAAE;QAC5C,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC;KAC9F;AAED,IAAA,OAAO,iBAAiB,CACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAClB,IAAI,CAAC,KAAK,EACV,KAAK,EACL,MAAM,EACN,IAAI,GAAG,oBAAoB,CAAC,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAC9D,CAAC;AACJ;;ACxGA;AACM,SAAU,iBAAiB,CAAC,SAA0B,EAAA;AAC1D,IAAA,OAAO,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,KAAK,MAAM,CAAC;AAChF,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,SAA0B,EAAA;IACvD,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACpE;;ACOA;AACA;AACA;AACM,SAAU,eAAe,CAAC,KAAuC,EAAA;AACrE,IAAA,IAAI,KAAK,YAAY,IAAI,EAAE;AACzB,QAAA,OAAO,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;KACpC;;;AAID,IAAA,OAAO,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,SAAS,CAAC;AACxD,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,cAAc,CAAC,KAAuC,EAAE,MAAuB,EAAA;AAC7F,IAAA,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAErC,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE7B,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AACjG,CAAC;AAGD;AACA;AACA;AACM,SAAU,aAAa,CAAC,KAAgC,EAAA;IAC5D,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAE1C,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACpD,CAAC;AAGD;AACA;AACA;AACM,SAAU,WAAW,CAAC,KAA8B,EAAA;AACxD,IAAA,OAAO,KAAK,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AAC5D,UAAE,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC;UAC3B,IAAI,CAAC;AACX,CAAC;AAGD;AACA;AACA;AACA;AACM,SAAU,aAAa,CAAC,QAAgB,EAAA;IAC5C,MAAM,KAAK,GAAG,QAAQ;AACnB,SAAA,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;AACtC,SAAA,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC;AAChC,SAAA,WAAW,EAAE,CAAC;AAEjB,IAAA,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACO,MAAM,aAAa,GAAG,SAAS,CAAC;AAEvC;AACA,MAAM,cAAc,GAAG,QAAQ,CAAC;AAMhC;AACA;AACA;AACgB,SAAA,aAAa,CAAC,IAAY,EAAE,GAAiB,EAAA;IAC3D,OAAO,CAAA,EAAG,IAAI,CAAG,EAAA,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA,EAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChE,CAAC;AAED;AACA;AACA;AACM,SAAU,aAAa,CAAC,KAAoC,EAAA;AAChE,IAAA,OAAO,GAAG,cAAc,CAAA,EAAG,KAAK,CAAC,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;AACA,SAAS,UAAU,CAAC,KAAmD,EAAA;AACrE,IAAA,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,YAAY,IAAI,EAAE,CAAC;AAC/D,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,gBAAgB,CAC9B,KAAwB,EACxB,UAAsB,EACtB,QAAgB,EAAA;IAEhB,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/E,IAAI,CAAC,YAAY,EAAE;AACjB,QAAA,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;KACf;IAED,OAAO,UAAU,CAAC,aAAa,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;AACvD,SAAA,IAAI,CACH,GAAG,CAAC,CAAC,OAA6B,KAAK,CAAC,OAAO,IAAI,EAAE;AAClD,SAAA,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAClE,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAChD,CAAC;AACN,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,mBAAmB,CACjC,QAA8C,EAC9C,MAAiB,EACjB,KAA2C,GAAA,MAAM,IAAI,EAAA;AAErD,IAAA,MAAM,KAAK,GAAG,CAAC,OAAiC,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;QACxE,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAEtF,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,EAAE,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;AACxE,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;AACnD,UAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;UACb,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAChC,CAAC;AAQD;AACA;AACA;AACA;AACA;AACM,SAAU,kBAAkB,CAAC,UAAsB,EAAA;AACvD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0D,CAAC;AAEjF,IAAA,OAAO,CAAC,KAAK,EAAE,QAAQ,KAAI;AACzB,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;AAE/B,QAAA,OAAO,QAAQ,CAAC;AAClB,KAAC,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,iBAAiB,CAC/B,QAAwD,EACxD,MAAiB,EACjB,KAA2C,GAAA,MAAM,IAAI,EAAA;AAErD,IAAA,OAAO,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC;AAChD,SAAA,IAAI,CACH,GAAG,CAAC,CAAC,OAAO,KAAsB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,EACvE,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAC3B,CAAC;AACN,CAAC;AAED;AACA;AACA;AACgB,SAAA,YAAY,CAC1B,QAA8C,EAC9C,OAAgB,EAAA;AAEhB,IAAA,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAElD,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI;UACtC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtE,UAAE,OAAO,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;AACO,MAAM,sBAAsB,GAAG,wCAAwC,CAAC;AAE/E;AACA;AACO,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAE9D;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,kBAAkB,CAChC,KAAwB,EACxB,OAAmC,EACnC,MAAqB,EACrB,OAA0B,EAC1B,QAAA,GAA2C,EAAE,EAAA;AAE7C,IAAA,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAClC,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAEhC,IAAA,QAAQ,KAAK,CAAC,IAAI;AAChB,QAAA,KAAK,WAAW;YACd,OAAO,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAEnD,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AAElG,QAAA,KAAK,aAAa;AAChB,YAAA,OAAO,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC;kBACnC,qBAAqB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;kBACpD,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAE9C,QAAA,KAAK,SAAS,CAAC;AACf,QAAA;YACE,OAAO,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;KAClD;AACH,CAAC;AAED;AACA;AACA,SAAS,mBAAmB,CAAC,IAAY,EAAE,KAAa,EAAE,OAA0B,EAAA;AAClF,IAAA,MAAM,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,GAAG,CAAC,CAAC;IAEnD,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ,CAAC,SAAS;AACxB,QAAA,KAAK,EAAE,EAAE,IAAI,EAAE,CAAG,EAAA,KAAK,CAAO,KAAA,CAAA,EAAE,EAAE,EAAE,CAAG,EAAA,KAAK,KAAK,EAAE;AACnD,QAAA,OAAO,EAAE,OAAO;AACd,cAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,IAAI,SAAS,EAAE;AACpE,cAAE,SAAS;KACd,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,gBAAgB,CACvB,KAAwB,EACxB,KAAa,EACb,OAAmC,EACnC,MAAqB,EACrB,OAAqC,EACrC,OAAgB,EAAA;AAEhB,IAAA,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC;AAC1F,IAAA,MAAM,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,EAAE,MAAM,CAAC;IAClE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEhD,OAAO;AACL,QAAA,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC;QAC1B,IAAI,EAAE,QAAQ,CAAC,iBAAiB;QAChC,KAAK;AACL,QAAA,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,OAAO,GAAG,EAAE,GAAG,SAAS;QACjC,MAAM,EAAE,CAAC,OAAgB,KAAK,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC7D,SAAS,EAAE,MAAM,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;;;QAG/C,OAAO,EAAE,KAAK,EAAE,MAAM;cAClB,MAAM,mBAAmB,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;iBACpF,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM,SAAS,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AAChF,cAAE,SAAS;KACd,CAAC;AACJ,CAAC;AAED;AACA,SAAS,WAAW,CAAC,OAAmC,EAAE,OAAe,EAAA;AACvE,IAAA,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;AAC3B,QAAA,OAAO,mBAAmB,CAAC;KAC5B;AAED,IAAA,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAAC;AACpE,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,qBAAqB,CAC5B,KAAwB,EACxB,KAAa,EACb,MAAqB,EACrB,OAA0B,EAAA;AAE1B,IAAA,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAClC,IAAA,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,SAAS,CAAC;AACtC,IAAA,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,SAAS,CAAC;IACtC,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IAEzD,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ,CAAC,KAAK;QACpB,KAAK;AACL,QAAA,OAAO,EAAE,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,SAAS;AAC1E,QAAA,QAAQ,EAAE,CAAC,IAAI,KAAK,cAAc,CAChC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAC7B,oBAAoB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EACtC,EAAE,MAAM,EAAE,EACV,MAAM,CACP;KACF,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY,EAAE,KAAa,EAAE,OAA0B,EAAA;IAChF,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ,CAAC,OAAO;QACtB,KAAK;QACL,OAAO,EAAE,OAAO,EAAE,KAAK;KACxB,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA,MAAM,gBAAgB,GAAiC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAClF,MAAM,eAAe,GAAgC,CAAC,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AAE1F;AACgB,SAAA,eAAe,CAAC,KAAwB,EAAE,MAAqB,EAAA;AAC7E,IAAA,OAAO,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;AACxC,WAAA,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;AACpC,YAAC,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC;AACzE,CAAC;AAED;AACA;AACgB,SAAA,eAAe,CAAC,MAAqB,EAAE,MAAqB,EAAA;AAC1E,IAAA,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE;AAC/B,SAAA,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM;AAChE,YAAC,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;AACpE,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;AACA;AACM,SAAU,YAAY,CAAC,MAAqB,EAAA;IAChD,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;AAC9E,CAAC;AAED;AACA;AACO,MAAM,UAAU,GAAG,OAAO,CAAC;AAElC,MAAM,aAAa,GAAiD;AAClE,IAAA,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE;AACrC,IAAA,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE;CACrC,CAAC;AAEF;AACA;AACA;AACM,SAAU,eAAe,CAC7B,MAAqB,EACrB,MAA2B,EAC3B,MAAqB,EACrB,KAAwB,EAAA;AAExB,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1E,IAAA,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;AACxE,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO;AACL,QAAA,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,QAAQ,CAAC,MAAM;AACrB,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,MAAM,EAAE,MAAM,aAAa;AAC3B,QAAA,OAAO,EAAE,KAAK;;AAEd,QAAA,QAAQ,EAAE,CAAC,IAAI,KAAK,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KACtE,CAAC;AACJ,CAAC;AAED;AACM,SAAU,cAAc,CAAC,KAA8B,EAAA;AAC3D,IAAA,OAAO,KAAK,GAAG,UAAU,CAAC,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACvD,CAAC;AAED;AACA;AACA;AACA;AACO,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAE7C;AACA;AACA;AACO,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,KAAoB,EAAA;IACjD,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,OAAO;AACtB,QAAA,IAAI,EAAE,gBAAgB;AACtB,QAAA,KAAK,EAAE,QAAQ;QACf,OAAO,EAAE,KAAK,IAAI,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,MAAqB,EAAA;AAClD,IAAA,OAAO,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;AAC5F,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CAAC,MAAc,EAAA;IACpC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC;IAElE,OAAO,aAAa,CAAC,MAAM;AACzB,UAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;UAC5E,mBAAmB,CAAC;AAC1B,CAAC;AAED;AACA;AACA;AACgB,SAAA,oBAAoB,CAAC,MAAc,EAAE,WAAoC,EAAA;IACvF,OAAO,CAAC,WAAW,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;AAC/F,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAC/B,MAAc,EACd,OAAiC,EAAA;AAEjC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;AAKvC,IAAA,IAAI,OAAO,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;AACzD,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO;AACL,QAAA,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,QAAQ,CAAC,MAAM;AACrB,QAAA,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,UAAU;AACnC,QAAA,QAAQ,EAAE,KAAK;AACf,QAAA,MAAM,EAAE,MAAM,MAAM;QACpB,OAAO,EAAE,oBAAoB,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS;KAC5F,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAAC,MAAqB,EAAA;IACpD,IAAI,CAAC,MAAM,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE;AACzC,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEvC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/F,CAAC;AAED;AACA;AACA;AACgB,SAAA,oBAAoB,CAClC,KAA0B,EAC1B,MAA2B,EAAA;AAE3B,IAAA,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;AAC1B,QAAA,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAElC,QAAA,QAAQ,KAAK,CAAC,IAAI;AAChB,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;AAEvE,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;AAEpE,YAAA,KAAK,aAAa;AAChB,gBAAA,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;YAEzE,SAAS;AACP,gBAAA,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBAEjD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;aAC1E;SACF;AACH,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA,SAAS,kBAAkB,CAAC,KAA0B,EAAE,IAAY,EAAA;IAClE,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE7C,IAAA,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,KAA0B,EAAE,IAAY,EAAA;AAC/D,IAAA,MAAM,aAAa,GAAG,iBAAiB,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACrE,IAAA,IAAI,aAAa,CAAC,MAAM,EAAE;QACxB,OAAO,EAAE,aAAa,EAAE,CAAC;KAC1B;IAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAE9C,IAAA,OAAO,MAAM,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;AAC3C,CAAC;AAED;AACA,SAAS,oBAAoB,CAAC,KAA0B,EAAE,IAAY,EAAA;AACpE,IAAA,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAC1D,IAAA,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAE1D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;AAChC,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO;AACL,QAAA,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChC,QAAA,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA,SAAS,UAAU,CAAC,GAAY,EAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9E,IAAA,MAAM,MAAM,GAAG,IAAI,KAAK,EAAE,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAEhD,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;AACjD,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,mBAAmB,CAAC,KAA0C,EAAA;IAC5E,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO,IAAI,CAAC,SAAS,CAAC;AACpB,QAAA,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;AAClC,QAAA,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE;QAChC,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC;QAChC,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC;QACvC,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE;QAC1B,KAAK,CAAC,GAAG,IAAI,EAAE;QACf,KAAK,CAAC,GAAG,IAAI,EAAE;AAChB,KAAA,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CAAC,GAAY,EAAA;AACrC,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;AACtB,QAAA,OAAO,GAAG,CAAC;KACZ;AAED,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,EAAE;AACnD,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAChC;;ACzpBA;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAmC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAEpF;AACA;AACA;AACM,SAAU,MAAM,CAAC,SAA2D,EAAA;AAChF,IAAA,OAAO,CAAC,CAAC,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC5D;;ACSA;AACO,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC;AACA;AACA;AACA,MAAM,eAAe,GAAsC;AACzD,IAAA,QAAQ,EAAE,IAAI;AACd,IAAA,QAAQ,EAAE,IAAI;AACd,IAAA,SAAS,EAAE,IAAI;AACf,IAAA,UAAU,EAAE,IAAI;AAChB,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,YAAY,EAAE,IAAI;AAClB,IAAA,SAAS,EAAE,IAAI;AACf,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,QAAQ,EAAE,IAAI;AACd,IAAA,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;AACA;AACO,MAAM,oBAAoB,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,CAA0B,CAAC;AAE1F,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEhD;AACA,MAAM,cAAc,GAAG,+CAA+C,CAAC;AAGvE;AACM,SAAU,eAAe,CAAC,IAAa,EAAA;AAC3C,IAAA,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;AACjG,CAAC;AAEK,SAAU,kBAAkB,CAAC,KAAc,EAAA;AAC/C,IAAA,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AACtE,CAAC;AAED;AACM,SAAU,aAAa,CAAC,IAAY,EAAA;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACtD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEtD,OAAO,IAAI,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC;AACzG,CAAC;AAED;AACA;AACM,SAAU,cAAc,CAAC,IAAY,EAAA;AACzC,IAAA,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAE9D,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;AACjD,CAAC;AAED;AACA;AACA;AACgB,SAAA,kBAAkB,CAChC,IAAsB,EACtB,KAA0C,EAAA;IAE1C,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;KACb;IAED,QAAQ,IAAI;AACV,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC;AAClC,kBAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE;kBAC1B,YAAY,CAAC,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7F,KAAK,QAAQ,EAAE;YACb,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAErD,OAAO,YAAY,CAAC,aAAa,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SAC9F;AAED,QAAA,KAAK,aAAa;YAChB,OAAO,YAAY,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAEtF,QAAA;AACE,YAAA,OAAO,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC,CAAC;KACpE;AACH,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,YAAY,CAAC,QAA6B,EAAE,OAA4B,EAAA;AACtF,IAAA,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,OAAO,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;AACxD,WAAA,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;WACxD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;AACpC,aAAA,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,cAAc,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,KAAK,CAAC,CAAC;AACxG,WAAA,WAAW,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;AACA;AACgB,SAAA,oBAAoB,CAClC,CAAwC,EACxC,CAAwC,EAAA;IAExC,OAAO,cAAc,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;AACA;AACA;AACM,SAAU,cAAc,CAAC,IAA2C,EAAA;IACxE,MAAM,IAAI,GAAsB,EAAE,CAAC;AAEnC,IAAA,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,EAAE,EAAE;QAC7B,IAAI,CAACI,eAAa,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;AACnF,eAAA,IAAI,CAAC,MAAM,KAAK,eAAe,EAAE;YACpC,MAAM;SACP;AAED,QAAA,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;KACrD;AAED,IAAA,OAAO,IAAI,CAAC;AACd,CAAC;AAED;AACA;AACgB,SAAA,aAAa,CAC3B,CAAgD,EAChD,CAAgD,EAAA;IAEhD,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED;AACA;AACM,SAAU,YAAY,CAAC,KAAc,EAAA;IACzC,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC;AAEhF,IAAA,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;AACpF,CAAC;AAED,SAAS,WAAW,CAAC,IAAqC,EAAE,OAAwC,EAAA;AAClG,IAAA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAEjF,IAAA,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAChH,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CAAC,KAA4C,EAAA;AAClE,IAAA,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,CAAC,IAA2B,KAAK,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/F,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,MAAM,CAAC,QAAQ,IAAI,IAAI;QACvB,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI;QAClC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI;AAChC,QAAA,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;AACpB,QAAA,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE;AAC3B,QAAA,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI;AAChC,QAAA,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI;AACjC,KAAA,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,IAAiC,EAAA;IACrD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI;QAC5E,IAAI,EAAE,MAAM,IAAI,EAAE;QAClB,CAAC,IAAI,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;AAChC,QAAA,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;AACtB,KAAA,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmD,EAAA;IACnE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,EAAE;AAC9B,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/G,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAAC,IAAkC,EAAA;IACnD,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;IAEvE,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AACxC,CAAC;AAED;AACA,SAAS,YAAY,CAAC,KAA8B,EAAA;AAClD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAuB,CAAC;AAEjH,IAAA,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AACpD,CAAC;AAED,SAAS,YAAY,CAAC,KAAc,EAAA;AAClC,IAAA,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC;AAClF,CAAC;AAED,SAAS,KAAK,CAAC,KAAc,EAAA;AAC3B,IAAA,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AAC/C,CAAC;AAED,SAASA,eAAa,CAAC,KAAc,EAAA;AACnC,IAAA,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E;;ACnNA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACO,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAC3C,MAAM,cAAc,GAAG,sCAAsC,CAAC;AAErE;AACA;AACO,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAEnD;AACA,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEjC;AACA,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAE7B;AACA,MAAM,cAAc,GAAG,SAAS,CAAC;AAEjC;AACA,MAAM,cAAc,GAAG,UAAU,CAAC;AAGlC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAC5B,KAAiD,EACjD,KAA0C,EAC1C,OAAgC,EAChC,IAA0B,EAAA;AAE1B,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,eAAe,CAAC;IAC7C,MAAM,IAAI,GAAG,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;AAEnE,IAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,QAAQ,GAAG,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC;AAC/E,IAAA,MAAM,IAAI,GAAG,QAAQ,GAAG,CAAG,EAAA,KAAK,CAAW,QAAA,EAAA,OAAO,CAAC,QAAQ,CAAA,OAAA,CAAS,GAAG,KAAK,CAAC;AAE7E,IAAA,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,UAAU,GAAG,EAAE,CAAA,EAAG,IAAI,CAAK,EAAA,EAAA,IAAI,EAAE,CAAC;AAChE,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,mBAAmB,CACjC,KAA0C,EAC1C,OAAgC,EAAA;AAEhC,IAAA,OAAO,KAAK,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;AAC9D,CAAC;AAED;AACA;AACM,SAAU,QAAQ,CAAC,KAA0C,EAAA;AACjE,IAAA,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC;AACzG,CAAC;AAED;AACA;AACM,SAAU,UAAU,CAAC,KAA0C,EAAA;IACnE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;AACtC,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;AACzE,CAAC;AAED;AACgB,SAAA,aAAa,CAAC,KAA2C,EAAE,IAA0B,EAAA;AACnG,IAAA,IAAI,KAAK,KAAK,KAAK,EAAE;AACnB,QAAA,OAAO,IAAI,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,GAAG,cAAc,GAAG,IAAI,CAAC;KACnE;IAED,OAAO,IAAI,KAAK,MAAM,GAAG,cAAc,GAAG,cAAc,CAAC;AAC3D,CAAC;AAED;AACA;SACgB,aAAa,CAC3B,SAAyC,EACzC,IAAgC,EAChC,aAAkD,EAAA;AAElD,IAAA,OAAO,YAAY,CAAC,SAAS,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,WAAW,CAAC,KAA6B,EAAA;IACvD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;AACrD,SAAA,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAC3C,IAAA,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;SACpD,MAAM,CAAC,CAAC,IAAI,KAA+B,IAAI,KAAK,IAAI,CAAC,CAAC;AAE7D,IAAA,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;AAChD,SAAA,IAAI,CACH,GAAG,CAAC,CAAC,KAAK,KAAK;AACb,QAAA,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAA+B,IAAI,KAAK,IAAI,CAAC;AAClE,QAAA,GAAG,IAAI;AACR,KAAA,CAAC,CACH,CAAC;AACN,CAAC;AAED;AACA;AACA;AACgB,SAAA,YAAY,CAAC,MAAc,EAAE,MAAqB,EAAA;AAChE,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;IAEzC,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,MAAM,CAAC;KACf;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IAC/E,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,EAAE;SACpC,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;AAC7E,WAAA,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED;AACA,SAAS,SAAS,CAChB,KAAa,EACb,KAAuB,EACvB,OAAgC,EAChC,IAA0B,EAAA;IAE1B,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;QAC5B,OAAO,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;KACvC;AAED,IAAA,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE;AACxB,QAAA,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACpD;AAED,IAAA,IAAI,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE;AAC/B,QAAA,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;KAC/D;IAED,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;IAE1E,OAAOC,WAAS,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,OAAO,GAAG,IAAI,OAAO,CAAA,CAAA,CAAG,GAAG,IAAI,CAAC,CAAC;AAC9E,CAAC;AAED;AACA;AACA,SAAS,QAAQ,CAAC,KAAuB,EAAE,OAAgC,EAAE,IAA0B,EAAA;AACrG,IAAA,IAAI,OAAO,CAAC,MAAM,EAAE;QAClB,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAC3C,QAAA,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM;cACxB,cAAc,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC;cACxF,EAAE,CAAC;AAEP,QAAA,OAAO,IAAI,GAAG,CAAG,EAAA,IAAI,CAAK,EAAA,EAAA,IAAI,CAAG,CAAA,CAAA,GAAG,IAAI,CAAC;KAC1C;IAED,OAAO,CAAA,EAAG,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,CAAM,GAAA,EAAA,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,CAAA,CAAE,CAAC;AACvH,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,WAAW,CAClB,KAAa,EACb,MAAiB,EACjB,OAAgC,EAChC,IAA0B,EAAA;AAE1B,IAAA,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnD,IAAA,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAEtC,IAAI,IAAI,KAAK,MAAM,IAAI,UAAU,KAAK,SAAS,EAAE;AAC/C,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,KAAK,GAAG,UAAU,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,KAAK,UAAU,CAAC,CAAC;AAE1F,IAAA,OAAO,CAAG,EAAA,IAAI,CAAkB,eAAA,EAAA,KAAK,IAAI,KAAK,GAAG,cAAc,GAAG,UAAU,GAAG,CAAC;AAClF,CAAC;AAED;AACA,SAASA,WAAS,CAAC,KAAuB,EAAE,OAAgC,EAAE,IAA0B,EAAA;IACtG,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACpC,IAAA,MAAM,KAAK,GAAG,CAAC,GAAW,KAAK,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE;QAC1C,OAAO,CAAA,EAAG,KAAK,CAAC,GAAG,CAAC,CAAO,IAAA,EAAA,KAAK,CAAC,GAAG,CAAC,CAAA,EAAG,IAAI,KAAK,MAAM,GAAG,kBAAkB,GAAG,EAAE,CAAA,CAAE,CAAC;KACrF;AAED,IAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,QAAA,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC;KAChC;AAED,IAAA,OAAO,GAAG,KAAK,SAAS,GAAG,CAAG,EAAA,KAAK,CAAC,GAAG,CAAC,CAAU,QAAA,CAAA,GAAG,IAAI,CAAC;AAC5D,CAAC;AAED;AACA,SAAS,SAAS,CAAC,MAAiB,EAAE,OAAgC,EAAA;AACpE,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAE5B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,GAAG,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,SAAS,CAAC,KAAwB,EAAE,KAA6B,EAAA;AACxE,IAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAExC,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;KACjB;AAED,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAChC,IAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;UACvB,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5D,UAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,MAAM,CAAC,IAAI,CAChB,GAAG,CAAC,CAAC,KAAK,KAA6B;AACrC,QAAA,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE;AACxC,YAAA,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM;YACrC,KAAK;YACL,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI;YAC1C,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;YAC9C,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,EAAE,MAAM,CAAC,CAAC;QAEX,OAAO,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;KACjE,CAAC,CACH,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,KAA6B,EAAA;AAChD,IAAA,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;IAE3C,IAAI,CAAC,SAAS,EAAE;AACd,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;AAC5E,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,cAAc,CAAC;AAEpE,IAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,MAAM,EAAE,IAAI,IAAI,SAAS,CAAA,CAAE,EAAE,CAAC;AAC7E,CAAC;AAED;AACA,SAAS,UAAU,CAAC,KAA6B,EAAA;IAC/C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE3C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AACxC,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;AACvB,SAAA,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;SAC/C,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;AACxC,SAAA,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC;AAC1G,SAAA,GAAG,CAAC,CAAC,SAAS,MAAwB;AACrC,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,IAAI,EAAE,aAAa,CACjB,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,EAC1D,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,EACxC,QAAQ,CAAC,aAAa,CACvB;QACD,WAAW,EAAE,SAAS,CAAC,EAAE;AAC1B,KAAA,CAAC,CAAC,CAAC;AACR,CAAC;AAED;AACA;AACA,SAAS,cAAc,CAAC,KAAwB,EAAA;IAC9C,OAAO,KAAK,CAAC,YAAY;AACpB,WAAA,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC;AACpG,CAAC;AAED;AACA;AACA,SAAS,QAAQ,CAAC,MAAc,EAAE,MAAiC,EAAA;AACjE,IAAA,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzF,IAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACb,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAQ,KAAA,EAAA,KAAK,GAAG,CAAC,EAAE,CAAC;AACzD,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,kBAAkB,CAChC,KAAa,EACb,MAAkB,EAClB,KAA4B,EAC5B,MAAqC,EAAA;AAErC,IAAA,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;AACjC,IAAA,MAAM,MAAM,GAAG,CAAC,QAAiB,MAAM,OAAO,GAAG,kBAAkB,KAAK,CAAA,CAAA,EAAI,QAAQ,GAAG,cAAc,GAAG,UAAU,CAAA,CAAA,CAAG,GAAG,EAAE,CAAC,CAAC;AAC5H,IAAA,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,QAAQ,GAAG,KAAK,KAAK,CAAA,EAAG,OAAO,GAAG,UAAU,GAAG,EAAE,GAAG,KAAK,CAAA,EAAA,EAAK,IAAI,CAAA,EAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;AAEpH,IAAA,IAAI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE;QACvB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;AAE/C,QAAA,OAAO,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAG,EAAA,IAAI,GAAG,CAAC,GAAG,CAAA,KAAA,EAAQ,IAAI,CAAO,KAAA,CAAA,GAAG,EAAE,CAAE,CAAA,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC;KACnH;AAED,IAAA,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,QAAQ,EAAE;QACZ,OAAO,CAAA,EAAG,KAAK,CAAK,EAAA,EAAA,OAAO,GAAG,kBAAkB,GAAG,UAAU,CAAA,EAAA,EAAK,QAAQ,CAAI,CAAA,EAAA,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;KAC/F;IAED,MAAM,MAAM,GAAG,KAAK,EAAE,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC;IAClD,MAAM,KAAK,GAAG,CAAC,GAAoB,MAAM,MAAM;UAC3C,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK,EAAE,aAAa,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC;UAClF,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAC5C,IAAA,MAAM,GAAG,GAAG,CAAC,GAAgC,KAA6B,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;AAE1H,IAAA,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AACtC,QAAA,OAAO,IAAI,CAAC,CAAG,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,IAAA,EAAO,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,EAAG,OAAO,IAAI,MAAM,GAAG,EAAE,GAAG,kBAAkB,CAAA,CAAE,CAAC,CAAC;KAC3G;AAED,IAAA,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,IAAI,CAAC,CAAG,EAAA,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,CAAA,EAAI,MAAM,GAAG,UAAU,GAAG,SAAS,CAAE,CAAA,CAAC,CAAC;KACzE;AAED,IAAA,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA,EAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,CAAA,EAAI,MAAM,GAAG,YAAY,GAAG,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC;AAClG,CAAC;AAED;AACA,SAAS,WAAW,CAAC,GAAY,EAAE,KAA4B,EAAA;AAC7D,IAAA,IAAI,GAAG,KAAK,IAAI,EAAE;AAChB,QAAA,OAAO,cAAc,CAAC;KACvB;AAED,IAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;AAC3H,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,KAAa,EAAE,WAAwC,EAAE,MAAqC,EAAA;IAClH,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,KAAK,CAAC;KACd;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/B,QAAQ,WAAW;QACjB,KAAK,eAAe,CAAC,IAAI;AACvB,YAAA,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,KAAK,eAAe,CAAC,OAAO;AAC1B,YAAA,OAAO,CAAI,CAAA,EAAA,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAC;QAC5C,KAAK,eAAe,CAAC,KAAK;YACxB,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACzF,iBAAA,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACpD,QAAA;YACE,OAAO,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC;KACjD;AACH;;ACvaA;AACA;AACA;AACA;AAEA;AACA,MAAM,cAAc,GAAG,QAAQ,CAAC;AAEhC;AACA,MAAM,cAAc,GAAG,WAAW,CAAC;AACnC,MAAM,QAAQ,GAAG,KAAK,CAAC;AAEvB;AACA,MAAM,eAAe,GAAG,YAAY,CAAC;AAErC;AACA,MAAM,IAAI,GAA+B,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAE7D;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAAC,MAA2B,EAAE,MAAqB,EAAA;IAClF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC;AACnG,CAAC;AAED;AACA;AACA;SACgB,iBAAiB,CAC/B,MAAuC,EACvC,MAA2B,EAC3B,MAAqB,EAAA;IAErB,OAAO,MAAM,CAAC,WAAW,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC;AACxD,SAAA,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SACrC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACM,SAAU,eAAe,CAAC,KAAgD,EAAA;IAC9E,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,IAAI,cAAc,CAAC;AACrD,CAAC;AAED;AACA;AACA;AACM,SAAU,gBAAgB,CAC9B,MAA2B,EAC3B,KAA+D,EAC/D,MAAuB,EACvB,KAA4F,EAAA;IAE5F,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;QAC7C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACnC,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,KAAK,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;AAErE,QAAA,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;KAC1G,CAAC,CAAC,CAAC;AACN,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,eAAe,CAC7B,KAAsC,EACtC,KAA0C,EAC1C,MAAuB,EACvB,KAAA,GAA2B,EAAE,EAAA;AAE7B,IAAA,QAAQ,KAAK,CAAC,IAAI;AAChB,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;AAChF,QAAA,KAAK,SAAS;YACZ,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACpC,QAAA;YACE,OAAO,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;KAC3C;AACH,CAAC;AAED;AACA;AACA;AACgB,SAAA,gBAAgB,CAC9B,CAA8C,EAC9C,CAA8C,EAAA;AAE9C,IAAA,IAAI,CAAC,KAAK,CAAC,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACZ,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvC,OAAO,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;AACtC,WAAA,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAI;AAClB,YAAA,MAAM,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YAEpB,OAAO,CAAC,CAAC,KAAK;mBACT,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;mBACzB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK;mBAC3B,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;AACzB,mBAAA,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;AAC3C,SAAC,CAAC,CAAC;AACP,CAAC;AAED;AACA;AACA,SAAS,eAAe,CACtB,KAAwB,EACxB,KAA0C,EAC1C,MAAuB,EACvB,KAA2C,EAAA;AAE3C,IAAA,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;AACpC,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;AAE1B,IAAA,IAAI,KAAK,KAAK,SAAS,EAAE;QACvB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KACvC;AAED,IAAA,OAAO,KAAK,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACvG,CAAC;AAED;AACA,SAAS,UAAU,CACjB,KAA0C,EAC1C,MAAuB,EACvB,KAAwB,EAAA;AAExB,IAAA,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAE3D,IAAA,IAAI,IAAI,KAAK,IAAI,EAAE;AACjB,QAAA,OAAO,QAAQ,CAAC;KACjB;AAED,IAAA,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAA,EAAG,eAAe,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,GAAG,IAAI,CAAC;AAC/D,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,KAAuC,EAAA;AAC1D,IAAA,OAAO,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,UAAU,CAAC,KAAkB,EAAE,GAAgB,EAAE,MAAuB,EAAA;AAC/E,IAAA,IAAI,KAAK,IAAI,GAAG,EAAE;QAChB,OAAO,KAAK,IAAI,GAAG,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;KACrF;IAED,IAAI,KAAK,EAAE;QACT,OAAO,CAAA,KAAA,EAAQ,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA,CAAE,CAAC;KAC5D;AAED,IAAA,OAAO,GAAG,GAAG,CAAS,MAAA,EAAA,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAA,CAAE,GAAG,cAAc,CAAC;AACnF,CAAC;AAED;AACA,SAAS,SAAS,CAAC,KAAW,EAAE,IAAU,EAAE,MAAuB,EAAA;IACjE,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAEhD,IAAA,IAAI,MAAM,KAAK,CAAC,EAAE;QAChB,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;KACnD;IAED,IAAI,MAAM,KAAK,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE;QAC3C,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;KAC7C;IAED,IAAI,MAAM,KAAK,CAAC,IAAI,YAAY,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE;AACrD,QAAA,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;KAC/E;AAED,IAAA,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC,CAAC;AAC7E,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,KAAW,EAAE,IAAU,EAAA;AAC1C,IAAA,IAAI,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE;AACpD,QAAA,OAAO,CAAC,CAAC;KACV;IAED,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AAClG,CAAC;AAED;AACA,SAAS,SAAS,CAAC,MAAuB,EAAA;AACxC,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC;AACrD;;ACrNA;AACO,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C;AACA;AACA;AACA;AACA;AACM,SAAU,mBAAmB,CAAC,SAA0B,EAAA;AAC5D,IAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AAC1C,IAAA,MAAM,IAAI,GAAG,CAAC,KAAyB,KAAK,CAAA,EAAG,KAAK,IAAI,yBAAyB,CAAA,EAAA,CAAI,CAAC;AAEtF,IAAA,OAAO,CAAG,EAAA,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAI,CAAA,EAAA,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;AACzG,CAAC;AAED;AACO,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;AACA;AACO,MAAM,iBAAiB,GAAG,CAAC;;ACjBlC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,aAAa,CAC3B,MAAqB,EACrB,SAA0B,EAC1B,QAA6B,EAAA;IAE7B,MAAM,KAAK,GAAuB,EAAE,CAAC;AAErC,IAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;AACtB,QAAA,OAAO,KAAK,CAAC;KACd;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;AAE5C,IAAA,IAAI,cAAc,CAAC,SAAS,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;AACrE,QAAA,KAAK,CAAC,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC;KACpC;AAED,IAAA,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE;AAC7B,QAAA,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE;YACtB,KAAK,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;SAC/B;AACD,QAAA,IAAI,IAAI,EAAE,MAAM,EAAE;AAChB,YAAA,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;SAC5B;AACD,QAAA,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE;YACxB,KAAK,CAAC,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACxC;KACF;AAED,IAAA,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;QACrD,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;KACvD;IAED,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAC3E,IAAA,IAAI,gBAAgB,CAAC,MAAM,EAAE;AAC3B,QAAA,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;KAC3C;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAGD;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAC7B,MAAc,EACd,QAA6B,EAC7B,MAAwB,GAAA,IAAI,EAC5B,UAAA,GAAgE,MAAM,IAAI,EAAA;IAE1E,MAAM,MAAM,GAAuC,EAAE,CAAC;AAEtD,IAAA,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;AAChB,SAAA,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;SAC/C,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;AACxC,SAAA,OAAO,CAAC,CAAC,SAAS,KAAI;AACrB,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,KAAK,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AACxE,QAAA,MAAM,KAAK,GAAG,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAE/F,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;AAC7B,YAAA,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;SAC9B;AACH,KAAC,CAAC,CAAC;AAEL,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,oBAAoB,CAAC,MAAqB,EAAE,SAA0B,EAAE,QAA6B,EAAA;IAC5G,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,sBAAsB,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC3F,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,sBAAsB,CACpC,MAAqB,EACrB,OAAsB,EACtB,QAA6B,EAAA;IAE7B,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;KACX;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;AAEhF,IAAA,OAAO,sBAAsB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,MAAM,IAAI,IAAI,EAAE,QAAQ,CAAC,CAAC;AACvF,CAAC;AAGD;AACA;AACA,SAAS,sBAAsB,CAAC,MAAc,EAAE,MAAqB,EAAE,QAA6B,EAAA;AAClG,IAAA,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,EAAE;AAC5B,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE;SAC9B,MAAM,CAAC,CAAC,KAAK,KAAK,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;SAC5F,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;AACxB,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3B,CAAC;AAGD;AACA;AACA;SACgB,UAAU,CAAC,MAAc,EAAE,SAA0B,EAAE,QAA6B,EAAA;IAClG,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;SAC7B,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,IAAI,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAChF,SAAA,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAE/C,OAAO,IAAI,EAAE,EAAE,IAAI,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;AAC7C,CAAC;AAGD;AACA;AACA,SAAS,UAAU,CAAC,KAA4C,EAAA;IAC9D,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM;AACxB,WAAA,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM;AAC7B,YAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACzD,WAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;AAC1B,WAAA,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAClC;;AC5KA;AACA;AACA;AACA;AACA;AACA;IACY,mBAKX;AALD,CAAA,UAAY,kBAAkB,EAAA;AAC5B,IAAA,kBAAA,CAAA,QAAA,CAAA,GAAA,QAAiB,CAAA;AACjB,IAAA,kBAAA,CAAA,eAAA,CAAA,GAAA,gBAAgC,CAAA;AAChC,IAAA,kBAAA,CAAA,OAAA,CAAA,GAAA,OAAe,CAAA;AACf,IAAA,kBAAA,CAAA,KAAA,CAAA,GAAA,KAAW,CAAA;AACb,CAAC,EALW,kBAAkB,KAAlB,kBAAkB,GAK7B,EAAA,CAAA,CAAA;;ACGD;AACA;AACA;AACA;AAEA;AACA;AACO,MAAM,aAAa,GAAwB,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAAU,CAAC,CAAC;AAEnF;AACA;AACM,SAAU,SAAS,CAAC,IAA+B,EAAA;AACvD,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAEvG,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED;AACM,SAAU,QAAQ,CAAC,SAA0B,EAAA;AACjD,IAAA,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3D,CAAC;AAED;AACA;AACM,SAAU,WAAW,CAAC,KAAsB,EAAA;IAChD,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;AAErC,IAAA,OAAO,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC;AAC7E,CAAC;AAED;AACA;AACA;AACgB,SAAA,WAAW,CAAC,MAAyB,EAAE,KAAwB,EAAA;IAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC7E,IAAA,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAEzE,IAAA,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC;AACxG,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,QAAQ,CAAC,KAAuB,EAAE,MAAiC,EAAA;AACjF,IAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;;IAG5B,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,KAAI;QACxB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,IAAI,CAAC;AACd,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,UAAU,CACxB,MAAyB,EACzB,OAA8D,EAC9D,MAA2B,EAC3B,OAAA,GAA+B,IAAI,GAAG,EAAE,EAAA;IAExC,MAAM,MAAM,GAA8B,EAAE,CAAC;IAE7C,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AAC7B,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC5B,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC;AAChC,QAAA,MAAM,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACxC,QAAA,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAElC,QAAA,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;AACrC,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;SACjD;AAAM,aAAA,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE;YAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;SACrF;aAAM;YACL,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;SAClC;AACH,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,eAAe,CAC7B,KAAsB,EACtB,GAAoB,EACpB,WAA8B,EAC9B,GAAwB,EAAA;AAExB,IAAA,IAAI,GAAG,CAAC,KAAK,EAAE;AACb,QAAA,OAAO,gBAAgB,CAAC;KACzB;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC;AAC9C,IAAA,MAAM,MAAM,GAAsB,GAAG,CAAC,IAAI,IAAI,OAAO;AACnD,UAAE;AACA,YAAA,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;AACxB,YAAA,IAAI,EAAE,OAAO;AACb,YAAA,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,IAAI;AACtB,YAAA,MAAM,EAAE,IAAI;AACZ,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,KAAK,EAAE,IAAI;AACZ,SAAA;UACC,IAAI,CAAC;IACT,MAAM,OAAO,GAAG,OAAO,EAAE,EAAE,KAAK,kBAAkB,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;AAEhG,IAAA,OAAO,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE;AAC1E,QAAA,KAAK,EAAE,gBAAgB;AACvB,QAAA,WAAW,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC;AAC9C,QAAA,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,SAAS;AACpC,QAAA,UAAU,EAAE,KAAK;KAClB,CAAC,CAAC,IAAI,CAAC;AACV,CAAC;AAED;AACA;AACgB,SAAA,eAAe,CAC7B,MAAyB,EACzB,IAA0C,EAAA;IAE1C,MAAM,MAAM,GAAG,MAAM;AAClB,SAAA,MAAM,CAAC,CAAC,KAAK,KAAI;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE/B,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;AAC7B,KAAC,CAAC;SACD,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEjB,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;AACA;AACgB,SAAA,cAAc,CAC5B,CAAwC,EACxC,CAAwC,EAAA;AAExC,IAAA,IAAI,CAAC,KAAK,CAAC,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACZ,QAAA,OAAO,KAAK,CAAC;KACd;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5B,OAAO,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;AACvC,WAAA,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAI;AACpB,YAAA,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAErB,OAAO,CAAC,CAAC,KAAK;mBACT,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;mBAC1B,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI;AAC1B,mBAAA,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO;mBACpC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;AACxE,SAAC,CAAC,CAAC;AACP,CAAC;AAED;AACA;AACM,SAAU,gBAAgB,CAAC,MAAqB,EAAA;IACpD,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO;AACL,QAAA,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/F,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,CAAC;QACpC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;AACA;AACM,SAAU,cAAc,CAAC,MAAqB,EAAA;AAClD,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;AAE9C,IAAA,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,KAAI;QACrC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAClE,KAAC,CAAC,CAAC;AAEH,IAAA,IAAI,MAAM,EAAE,MAAM,EAAE;AAClB,QAAA,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KACnF;AAED,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;AACA;AACM,SAAU,OAAO,CAAC,SAA0B,EAAA;AAChD,IAAA,OAAO,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC;AACpC,CAAC;AAED,SAAS,IAAI,CAAC,MAAyB,EAAA;IACrC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,KAAsB,EAAA;IAC1C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;AACvF,CAAC;AAED;AACA;AACA;AACA,SAAS,WAAW,CAClB,OAAkC,EAClC,WAA8B,EAAA;AAE9B,IAAA,IAAI,OAAO,EAAE,EAAE,KAAK,kBAAkB,CAAC,MAAM,IAAI,OAAO,EAAE,EAAE,KAAK,kBAAkB,CAAC,GAAG,EAAE;AACvF,QAAA,OAAO,SAAS,CAAC;KAClB;AAED,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAE1D,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC;AAC/F;;ACpPA;AACA;AACA;AACA;AACA;AACO,MAAM,qBAAqB,GAAQ,CAAC;;ACG3C;AACA;AACO,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,aAAa,CAAC,MAAqC,EAAA;AACjE,IAAA,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;IAE1B,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC;AACxC,SAAA,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AAED;AACA;AACA;AACM,SAAU,mBAAmB,CAAC,MAAqC,EAAA;AACvE,IAAA,OAAO,MAAM,EAAE,OAAO,EAAE,MAAM;AAC5B,UAAE,EAAE;UACF,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAAC,MAAqC,EAAE,KAAwB,EAAA;AAC/F,IAAA,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC7C,IAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/D,IAAA,OAAO,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;AACvD,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,iBAAiB,CAAC,MAAqC,EAAA;IACrE,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;AAC3C,IAAA,MAAM,MAAM,GAAG,MAAM,EAAE,aAAa,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAE3D,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC;AACnG,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;SACgB,aAAa,CAAC,MAAkB,EAAE,KAAa,EAAE,MAAc,EAAA;IAC7E,MAAM,OAAO,GAAa,EAAE,CAAC;AAE7B,IAAA,IAAI,KAAK,GAAG,MAAM,EAAE;QAClB,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,CAAc,WAAA,EAAA,KAAK,CAAE,CAAA,CAAC,CAAC;AAErD,QAAA,IAAI,KAAK,KAAK,MAAM,GAAG,CAAC,EAAE;AACxB,YAAA,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;SACjC;KACF;AAED,IAAA,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE;AACzB,QAAA,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;KAC/B;AAED,IAAA,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED;AACO,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC;AACA;AACA;AACA;AACgB,SAAA,qBAAqB,CACnC,OAA8B,EAC9B,MAAkD,EAAA;AAElD,IAAA,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEzB,OAAO,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;AAC7E,CAAC;AAcD;AACA;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAC/B,OAA8B,EAC9B,IAAuF,EACvF,QAA+B,EAAA;AAE/B,IAAA,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAqC,EAAE,CAAC;AAEtD,IAAA,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;QACzB,MAAM,WAAW,GAAG,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACxD,QAAA,MAAM,KAAK,GAAG,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;AAC3C,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAE9B,IAAI,MAAM,EAAE;AACV,YAAA,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG;gBACxB,MAAM;AACN,gBAAA,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;AAChF,gBAAA,UAAU,EAAE,WAAW,GAAG,IAAI,GAAG,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;AACvE,gBAAA,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,IAAI,IAAI;aACvC,CAAC;SACH;AACH,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;AACA;AACA,SAAS,cAAc,CAAC,OAAmC,EAAE,KAAa,EAAE,MAAkB,EAAA;IAC5F,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;UAC/D,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC;UACxC,IAAI,CAAC;AACX;;AC1JA;AACA;AASA,MAAM,SAAS,GAAe,EAAE,CAAC;AAEjC;AACO,MAAM,kBAAkB,GAA8C;IAC3E,GAAG,EAAE,eAAe,CAAC,GAAG;IACxB,IAAI,EAAE,eAAe,CAAC,IAAI;IAC1B,KAAK,EAAE,eAAe,CAAC,KAAK;IAC5B,OAAO,EAAE,eAAe,CAAC,OAAO;IAChC,IAAI,EAAE,eAAe,CAAC,IAAI;CAC3B,CAAC;AAEF;AACM,SAAU,kBAAkB,CAAC,SAA0B,EAAA;AAC3D,IAAA,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,IAAI,SAAS,CAAC;AAC/C,CAAC;AAED;AACA;AACM,SAAU,aAAa,CAAC,MAAkB,EAAA;IAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAAC,OAAmB,EAAE,IAAY,EAAE,QAAoB,EAAA;IACvF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;AAC/C,IAAA,MAAM,MAAM,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC5C,IAAA,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;AACrB,QAAA,IAAI,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;AACxB,QAAA,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;AAC3B,QAAA,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;AAC1B,QAAA,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;AAC5B,KAAA,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACvC,IAAA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE;AAClC,SAAA,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/F,IAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAE1E,IAAA,OAAO,mBAAmB,CAAC;AACzB,QAAA,GAAG,QAAQ;AACX,QAAA,OAAO,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC;AAClG,QAAA,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,IAAI;AACnD,KAAA,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAC/B,MAAkB,EAClB,KAAa,EACb,WAA6B,EAAA;AAE7B,IAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AAC3E,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,eAAe,CAAC,GAAG,MAAM,KAAK,EAAE;AACpE,QAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KAClC;IAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE;AAClC,SAAA,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,KAAK,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;SACnD,MAAM,CAAC,CAAC,IAAI,KAAyB,CAAC,CAAC,IAAI,CAAC,CAAC;AAEhD,IAAA,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC;AACvG,CAAC;AAED;AACA,MAAM,mBAAmB,GAA8B,IAAI,GAAG,CAAC;AAC7D,IAAA,YAAY,CAAC,YAAY;AACzB,IAAA,YAAY,CAAC,YAAY;AACzB,IAAA,YAAY,CAAC,aAAa;AAC1B,IAAA,YAAY,CAAC,kBAAkB;AAChC,CAAA,CAAC,CAAC;AAEH;AACA,MAAM,iBAAiB,GAA8B,IAAI,GAAG,CAAC;AAC3D,IAAA,YAAY,CAAC,YAAY;AACzB,IAAA,YAAY,CAAC,WAAW;AACzB,CAAA,CAAC,CAAC;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAC9B,MAAkB,EAClB,KAA0B,EAC1B,MAAyB,EACzB,QAAA,GAAkC,EAAE,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;AACrC,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/B,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC1E,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC;AACnE,IAAA,MAAM,SAAS,GAAG,CAAC,MAAM,IAAI,gBAAgB,CAAC,OAAO,MAAM,gBAAgB,CAAC,OAAO,CAAC;AACpF,IAAA,MAAM,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC5G,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,IAAA,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE9E,OAAO,aAAa,IAAI,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;AACrD,UAAE,MAAM;AACR,UAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC1D,CAAC;AAED;AACA,SAAS,YAAY,CAAC,KAA0B,EAAE,GAAW,EAAE,KAAgC,EAAA;IAC7F,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,CAAI,CAAA,EAAA,GAAG,CAAkB,gBAAA,CAAA,CAAC,CAAC;IAEtD,OAAO,IAAI,GAAG,CAAC,KAAK;AACjB,SAAA,MAAM,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;SAC5C,MAAM,CAAC,CAAC,KAAK,KAA+B,CAAC,CAAC,KAAK,CAAC;AACpD,SAAA,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC;;AClFA;AACA;AACgB,SAAA,WAAW,CACzB,CAA4B,EAC5B,CAA4B,EAAA;AAE5B,IAAA,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;AACZ,QAAA,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;KACjB;AAED,IAAA,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;AACrB,WAAA,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;AACf,WAAA,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;AACnB,WAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;WACzB,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;WAC5B,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,aAAa,CAAC;AAC1C,WAAA,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;AACf,WAAA,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC;AACvB,CAAC;AAGD;AACA,SAAS,QAAQ,CAAC,CAAwB,EAAE,CAAwB,EAAA;AAClE,IAAA,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,MAAM;WACvC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;AACrE,CAAC;AAGD;AACA;AACA,SAAS,QAAQ,CAAC,CAAa,EAAE,CAAoB,EAAA;IACnD,OAAO,CAAC,CAAC,CAAC;AACL,WAAA,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;AACrB,WAAA,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;AACzD,CAAC;AAGD;AACA;AACA;AACA;AACA;AACgB,SAAA,eAAe,CAC7B,CAAsC,EACtC,CAAsC,EAAA;IAEtC,OAAO,mBAAmB,CAAC,CAAC,CAAC,KAAK,mBAAmB,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAC9B,YAAkD,EAClD,QAA+D,EAAA;IAE/D,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAI;AAC5C,QAAA,IAAI,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE;AACrD,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAEjC,QAAA,OAAO,IAAI,CAAC;AACd,KAAC,CAAC,CAAC;AACL,CAAC;AAGD;AACA;AACM,SAAU,cAAc,CAAC,IAAY,EAAA;AACzC,IAAA,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAGD;AACA,SAAS,SAAS,CAAC,CAAoB,EAAE,CAAoB,EAAA;IAC3D,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9E,CAAC;AAGD;AACA,SAAS,UAAU,CACjB,CAAyC,EACzC,CAAyC,EAAA;AAEzC,IAAA,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;AACnB,WAAA,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1F,CAAC;AAGD;AACA,SAAS,QAAQ,CAAC,CAAmB,EAAE,CAAmB,EAAA;AACxD,IAAA,OAAO,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC;AACvD,WAAA,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACzD,CAAC;AAGD;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAAC,KAAwB,EAAA;AACvD,IAAA,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;IAE3C,IAAI,CAAC,YAAY,EAAE;AACjB,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO;QACL,YAAY,CAAC,KAAK,IAAI,EAAE;QACxB,YAAY,CAAC,GAAG,IAAI,EAAE;QACtB,YAAY,CAAC,KAAK,IAAI,EAAE;QACxB,YAAY,CAAC,QAAQ,IAAI,EAAE;QAC3B,CAAC,YAAY,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC;QACrC,CAAC,YAAY,CAAC,aAAa,IAAI,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC;QAC5C,YAAY,CAAC,GAAG,IAAI,EAAE;QACtB,YAAY,CAAC,GAAG,IAAI,EAAE;AACvB,KAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAGD;AACA,SAAS,mBAAmB,GAAA;IAC1B,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC9C,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,wBAAwB,CAAA;;;AAInB,IAAA,QAAQ,GAAG,MAAM,CAAS,KAAK,CAAC,CAAC;;;;;AAMjC,IAAA,aAAa,GAAG,MAAM,CAAsB,sBAAsB,EAAE;AAClF,QAAA,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;AACjC,eAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;AACzB,eAAA,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC,CAAC;;;;;;AAOa,IAAA,UAAU,GAAG,MAAM,CAAyC,IAAI,GAAG,EAAE,EAAE;AACrF,QAAA,KAAK,EAAE,UAAU;AAClB,KAAA,CAAC,CAAC;;;;IAKa,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;;;;;IAMpD,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;;IAGxD,IAAI,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;;;IAItC,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;;;;AAKtC,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,IAAI,EAAE,CAAC,CAAC;;;IAItE,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;;;;;;AAOxC,IAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAK;QAClD,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjB,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC9F,KAAC,CAAC,CAAC;AAEK,IAAA,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;AAC9C,IAAA,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAC;AAC/C,IAAA,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;;;;AAKrC,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;;;;;;;IAQ7B,UAAU,GAA4B,IAAI,CAAC;AAC3C,IAAA,kBAAkB,GAAG,IAAI,OAAO,EAAQ,CAAC;;;;AAKzC,IAAA,UAAU,GAAG,IAAI,GAAG,EAAsB,CAAC;;;;AAK3C,IAAA,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;;;AAI1C,IAAA,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;;;;IAK5C,eAAe,GAAG,KAAK,CAAC;;AAGxB,IAAA,mBAAmB,GAAG,IAAI,OAAO,EAAU,CAAC;;;AAI5C,IAAA,SAAS,GAAG,IAAI,OAAO,EAAiB,CAAC;;AAGzC,IAAA,cAAc,GAAG,IAAI,OAAO,EAAQ,CAAC;;;;;;;;;;IAWrC,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACpF,QAAA,YAAY,EAAE,CAAC;AACf,QAAA,aAAa,EAAE,IAAI;AACpB,KAAA,CAAC,CAAC;AAEK,IAAA,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;AAE1B,IAAA,eAAe,GAAG,MAAM,CAA8B,IAAI,GAAG,EAAE,CAAC,CAAC;;;AAIjE,IAAA,OAAO,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;AAGtC,IAAA,OAAO,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;AAGtC,IAAA,MAAM,GAAG,MAAM,CAAoB,KAAK,CAAC,CAAC;;;AAI1C,IAAA,OAAO,GAAG,MAAM,CAAkD,IAAI,GAAG,EAAE,CAAC,CAAC;;AAG7E,IAAA,cAAc,GAAG,IAAI,OAAO,EAAU,CAAC;;;;;AAMvC,IAAA,YAAY,GAAG,MAAM,CAA+C,IAAI,GAAG,EAAE,CAAC,CAAC;;;;;AAM/E,IAAA,eAAe,GAAG,MAAM,CAAqC,IAAI,GAAG,EAAE,CAAC,CAAC;;;;;AAMxE,IAAA,mBAAmB,GAAG,MAAM,CAAyC,IAAI,GAAG,EAAE,CAAC,CAAC;;;AAIhF,IAAA,UAAU,GAAG,MAAM,CAAuB,mBAAmB,EAAE,CAAC,CAAC;;;;;;;;;;;;;AAclE,IAAA,IAAI,CAAC,MAAc,EAAA;AACxB,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;;QAGzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;;QAErD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC;QAE5D,MAAM,eAAe,GAAG,gBAAgB,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC7D,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC;AACpC,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAA6B,CAAC;QAEpD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE;YAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAClC,YAAA,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,eAAe,CAAC,CAAC;SAC1E;AAED,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAElG,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACpB,QAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;AAE7B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;AAEM,IAAA,KAAK,CAAC,OAAe,EAAA;QAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KAClC;;;;;;IAOM,QAAQ,CAAC,OAAe,EAAE,KAA8B,EAAA;AAC7D,QAAA,IAAI,KAAK,KAAK,IAAI,EAAE;AAClB,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE7B,YAAA,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE;AAC9C,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aAC5B;SACF;aAAM;YACL,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9E,YAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;SAC/B;AAED,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;AAIM,IAAA,eAAe,CAAC,IAAY,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;KAClC;;IAGM,SAAS,GAAA;QACd,OAAO,IAAI,CAAC,UAAU,CAAC;KACxB;;;;AAKM,IAAA,YAAY,CAAC,SAAkC,EAAA;AACpD,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,iBAAiB,EAAE,CAAC;AACzB,QAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;AAC/B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;;IAKM,gBAAgB,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC;KAC/C;;;AAIM,IAAA,QAAQ,CAAC,WAAmB,EAAA;QACjC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;KACjD;;;;;;;;;IAUM,WAAW,CAAC,SAA0B,EAAE,IAAuB,EAAA;QACpE,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE;YACvE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;SACzC;aAAM;YACL,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;SACtC;AAED,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;AAGM,IAAA,UAAU,CAAC,WAAmB,EAAA;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;KACpD;;;;;;;;AASM,IAAA,cAAc,CAAC,SAA0B,EAAA;QAC9C,OAAO,IAAI,CAAC,eAAe;eACtB,SAAS,CAAC,IAAI,KAAK,MAAM;AACzB,eAAA,CAAC,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,KAAI;AAC5C,gBAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBAErD,OAAO,MAAM,CAAC,OAAO;uBAChB,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;uBACrC,KAAK,EAAE,IAAI,KAAK,SAAS;AACzB,wBAAC,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;AAC/D,aAAC,CAAC,CAAC;KACN;;;;IAKM,aAAa,CAAC,WAAmB,EAAE,IAAY,EAAA;AACpD,QAAA,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;AAEpC,QAAA,IAAI,MAAM,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE;YAC1D,OAAO;SACR;QAED,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;SAC7C;aAAM;AACL,YAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SACxC;AAED,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC3C,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;AAGM,IAAA,aAAa,CAAC,WAAmB,EAAA;QACtC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;KACjD;;;;IAKM,gBAAgB,CAAC,WAAmB,EAAE,KAAwB,EAAA;AACnE,QAAA,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE9E,QAAA,IAAI,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EAAE;YACtD,OAAO;SACR;QAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;AAExC,QAAA,IAAI,MAAM,CAAC,MAAM,EAAE;AACjB,YAAA,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;SAC/B;aAAM;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SAC1B;AAED,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;AAGM,IAAA,iBAAiB,CAAC,WAAmB,EAAA;AAC1C,QAAA,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,EAAE;aAC3C,IAAI,CACHC,MAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,WAAW,CAAC,EACpC,GAAG,CAAC,MAAM,SAAS,CAAC,CACrB,CAAC;KACL;;;;IAKM,OAAO,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;KAC3C;AAEM,IAAA,gBAAgB,CAAC,QAAgB,EAAA;QACtC,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KAC5C;IAEM,YAAY,CAAC,QAAgB,EAAE,OAAe,EAAA;QACnD,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AACvC,YAAA,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;SACxC;aAAM;AACL,YAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SACrC;;;QAID,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAEzB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;AAIM,IAAA,UAAU,CAAC,SAA0B,EAAA;QAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC;AAE1F,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE;aACjC,IAAI,CACHA,MAAQ,CAAC,CAAC,OAAO,KAAK,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CACjE,CAAC;KACL;;;;;;;;AASM,IAAA,aAAa,CAAC,UAAmC,EAAA;AACtD,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE;aACjC,IAAI,CACHA,MAAQ,CAAC,CAAC,OAAO,KAAwB,OAAO,KAAK,IAAI;AACpD,eAAA,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE;AACzD,iBAAA,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,CAC1D,CAAC;KACL;;;;AAKM,IAAA,mBAAmB,CAAC,SAA0B,EAAA;QACnD,MAAM,QAAQ,GAA0B,EAAE,CAAC;QAE3C,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE;AAC5C,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBAC3D,SAAS;aACV;AAED,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACrD,YAAA,MAAM,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YAE1D,IAAI,MAAM,EAAE;AACV,gBAAA,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;aACnD;SACF;AAED,QAAA,OAAO,QAAQ,CAAC;KACjB;;;;;;;IAQM,aAAa,GAAA;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAC/B,aAAA,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,KAAI;YACxB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AAE3C,YAAA,OAAO,MAAM,GAAG,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;AAChD,SAAC,CAAC;aACD,MAAM,CAAC,CAAC,KAAK,KAAsC,KAAK,KAAK,IAAI,CAAC,CAAC;KACvE;;;;;;AAOM,IAAA,gBAAgB,CAAC,MAAc,EAAE,MAAA,GAAwB,IAAI,EAAA;QAClE,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;AAC9B,aAAA,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;AAEnD,QAAA,OAAO,KAAK;AACT,aAAA,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE;aACtC,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC;AACxC,aAAA,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;KACnE;AAEM,IAAA,OAAO,CAAC,MAAqB,EAAA;AAClC,QAAA,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,EAAE;YAC7B,OAAO;SACR;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACzB,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;AAIM,IAAA,QAAQ,CAAC,KAAwB,EAAA;AACtC,QAAA,MAAM,IAAI,GAAsB,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAChE,QAAA,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE;YAC1B,OAAO;SACR;AAED,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;AAIM,IAAA,KAAK,CAAC,WAAmB,EAAA;QAC9B,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;KAC9C;;;;;IAMM,QAAQ,CAAC,WAAmB,EAAE,IAAgC,EAAA;AACnE,QAAA,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE;YAC/E,OAAO;SACR;AAED,QAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACtC,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACtC,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;AAGM,IAAA,YAAY,CAAC,WAAmB,EAAA;AACrC,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE;aACtC,IAAI,CACHA,MAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,WAAW,CAAC,EACpC,GAAG,CAAC,MAAM,SAAS,CAAC,CACrB,CAAC;KACL;;;;;IAMM,UAAU,CAAC,WAAmB,EAAE,IAAgC,EAAA;AACrE,QAAA,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE;AAC/E,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACtC,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;AAE3B,QAAA,OAAO,IAAI,CAAC;KACb;;;;AAKM,IAAA,UAAU,CAAC,SAA0B,EAAA;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC;KAC3E;;;;AAKM,IAAA,iBAAiB,CAAC,SAA0B,EAAA;AACjD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAEtD,OAAO,OAAO,EAAE,IAAI,KAAK,aAAa,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;cACjE,OAAO,CAAC,MAAM;cACd,IAAI,CAAC;KACV;;;;;IAMM,aAAa,CAAC,SAA0B,EAAE,MAAkB,EAAA;QACjE,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE;AAC1C,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;SAC5B;KACF;;;AAIM,IAAA,iBAAiB,CAAC,SAA0B,EAAA;AACjD,QAAA,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;KAC7D;;;AAIM,IAAA,aAAa,CAAC,SAA0B,EAAA;QAC7C,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;KACjD;;;IAIM,gBAAgB,CAAC,SAA0B,EAAE,SAAoC,EAAA;QACtF,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE;YACrG,OAAO;SACR;QAED,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC;KACxF;;;;;;;IAQM,QAAQ,GAAA;QACb,MAAM,QAAQ,GAAwB,EAAE,CAAC;AAEzC,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;AAClB,YAAA,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;SAClC;AAED,QAAA,IAAI,IAAI,CAAC,UAAU,EAAE;AACnB,YAAA,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;SACpC;AAED,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,KAAK,EAAE;AAC3B,YAAA,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;SACxB;AAED,QAAA,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;AAEzC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;AAC7B,YAAA,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;SACxB;AAED,QAAA,OAAO,QAAQ,CAAC;KACjB;;;IAIM,cAAc,GAAA;QACnB,MAAM,MAAM,GAA8C,EAAE,CAAC;QAE7D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AAC7B,YAAA,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/E,SAAC,CAAC,CAAC;QAEH,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB;;;;;;IAOM,eAAe,GAAA;AACpB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEvC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC3C,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3D,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC;AACnB,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;KAC9B;;;;;;AAOM,IAAA,qBAAqB,CAAC,QAA2B,EAAA;AACtD,QAAA,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,KAAI;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE;gBACV,OAAO;aACR;AAED,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC/B,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;;;;;AAOM,IAAA,wBAAwB,CAAC,QAA2B,EAAA;QACzD,IAAI,CAAC,SAAS,EAAE,CAAC;AAEjB,QAAA,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAI;YAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE;AACV,gBAAA,OAAO,KAAK,CAAC;aACd;AAED,YAAA,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AAC3E,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAE7G,YAAA,OAAO,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACjD,SAAC,CAAC,CAAC;KACJ;;;AAIM,IAAA,SAAS,CAAC,SAA0B,EAAA;AACzC,QAAA,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;KAClE;;;;AAKM,IAAA,UAAU,CAAC,OAAe,EAAA;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExC,QAAA,OAAO,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;KAC/C;;;;;;;;;AAUO,IAAA,eAAe,CAAC,KAAuB,EAAA;QAC7C,MAAM,MAAM,GAA0C,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AAEvC,QAAA,IAAI,KAAK,CAAC,KAAK,EAAE;YACf,MAAM,CAAC,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC7C;AACD,QAAA,IAAI,KAAK,CAAC,GAAG,EAAE;YACb,MAAM,CAAC,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SACzC;QACD,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;SACxB;AACD,QAAA,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE;AACxB,YAAA,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;SAC9B;AACD,QAAA,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SACnC;AAED,QAAA,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAE5C,QAAA,OAAO,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK;AAC7D,eAAA,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;AAC/E,cAAE,MAAM;cACN,IAAI,CAAC;KACV;;;;;AAMO,IAAA,WAAW,CAAC,KAAuB,EAAA;AACzC,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;AACnD,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAEhD,QAAA,OAAO,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;KAC9D;;;AAIO,IAAA,KAAK,CACX,KAAwB,EACxB,QAAkC,EAClC,eAAwB,EAAA;QAExB,MAAM,cAAc,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;QAEtG,IAAI,cAAc,EAAE;YAClB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAChC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE;YAC/B,OAAO;SACR;AAED,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,eAAe,GAAG,eAAe;eAClC,CAAC,CAAC,KAAK,EAAE,MAAM;eACf,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;QAEtD,IAAI,KAAK,IAAI,CAAC,cAAc,IAAI,CAAC,eAAe,EAAE;YAChD,OAAO;SACR;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE/C,IAAI,YAAY,EAAE;YAChB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;SAC1C;aAAM,IAAI,cAAc,EAAE;;YAEzB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAC/B;KACF;;;IAIO,iBAAiB,GAAA;QACvB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,KAAI;YACjD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAE/C,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE;AACjD,gBAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;aACxC;AACH,SAAC,CAAC,CAAC;KACJ;;;;;;;;;AAUO,IAAA,MAAM,CAAC,MAAc,EAAA;AAC3B,QAAA,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE;YAChE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;AAC9B,gBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC7B,gBAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;aAC/B;SACF;QAED,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,WAAW,KAAI;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAE/C,YAAA,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACzE,gBAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;aACrC;AACH,SAAC,CAAC,CAAC;;;QAIH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC;aAC/C,OAAO,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjF,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;YACzC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;AAC5B,gBAAA,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;aACxC;AACH,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAEzB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;QAEpD,IAAI,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,WAAW,KAAI;AAC/C,YAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAE5E,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,gBAAA,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;aAC/B;AACH,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;KAC7B;;;IAIO,WAAW,CAAC,MAAoC,EAAE,KAAuB,EAAA;AAC/E,QAAA,MAAM,KAAK,GAAqB,EAAE,GAAG,KAAK,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAC,MAAM,CAAC;QAEpB,OAAO,MAAM,EAAE,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;cAC5C,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;cACnC,KAAK,CAAC;KACX;AAEO,IAAA,eAAe,CAAC,MAAc,EAAA;QACpC,OAAO,gBAAgB,CAAC,MAAM,CAAC;AAC5B,aAAA,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;KACrD;;;AAIO,IAAA,gBAAgB,CAAC,SAA0B,EAAA;AACjD,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;AAEhC,QAAA,IAAI,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;AAC3B,YAAA,OAAO,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;SAC1D;AAED,QAAA,OAAO,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;KAC/D;;;;;AAMO,IAAA,aAAa,CAAC,KAAwB,EAAA;AAC5C,QAAA,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;QAC3C,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,IAAI,YAAY,CAAC,QAAQ,EAAE;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEzD,OAAO,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC;SAC7F;QAED,IAAI,YAAY,CAAC,KAAK,IAAI,YAAY,CAAC,GAAG,EAAE;YAC1C,OAAO;AACL,gBAAA,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,IAAI;AACjC,gBAAA,GAAG,EAAE,YAAY,CAAC,GAAG,IAAI,IAAI;aAC9B,CAAC;SACH;AAED,QAAA,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE;AAC/B,YAAA,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC;SACxC;AAED,QAAA,IAAI,YAAY,CAAC,KAAK,EAAE;AACtB,YAAA,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC;SACtC;AAED,QAAA,OAAO,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;KAClD;;;;;AAMO,IAAA,cAAc,CAAC,QAAgB,EAAA;QACrC,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEzC,QAAQ,QAAQ;;;;;;;;;AASd,YAAA,KAAK,UAAU;AACb,gBAAA,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;YACxF,KAAK,UAAU,EAAE;gBACf,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAElC,OAAO;oBACL,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC;oBACrE,GAAG,EAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE,qBAAqB,EAAE,CAAC;iBAClE,CAAC;aACH;AACD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC9C,YAAA,KAAK,YAAY;AACf,gBAAA,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC/C,YAAA,KAAK,aAAa;AAChB,gBAAA,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChD,YAAA,KAAK,aAAa;AAChB,gBAAA,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChD,YAAA,KAAK,cAAc;AACjB,gBAAA,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACjD,YAAA,KAAK,WAAW;AACd,gBAAA,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChD,YAAA,KAAK,aAAa;AAChB,gBAAA,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAClD,YAAA,KAAK,UAAU,CAAC;AAChB,YAAA,KAAK,YAAY;AACf,gBAAA,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC/C,YAAA;AACE,gBAAA,OAAO,IAAI,CAAC;SACf;KACF;;;IAIO,eAAe,GAAA;QACrB,MAAM,MAAM,GAA8C,EAAE,CAAC;QAE7D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AAC7B,YAAA,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;AAC5C,kBAAE,IAAI;AACN,kBAAE,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACjE,SAAC,CAAC,CAAC;AAEH,QAAA,OAAO,MAAM,CAAC;KACf;;;IAIO,cAAc,GAAA;QACpB,MAAM,KAAK,GAAoC,EAAE,CAAC;QAElD,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE;YACrC,MAAM,IAAI,GAAoB,EAAE,CAAC;AACjC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC/C,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAEvC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE;AACvE,gBAAA,IAAI,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;aACzB;YACD,IAAI,MAAM,EAAE;AACV,gBAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;aACtB;AACD,YAAA,IAAI,MAAM,CAAC,MAAM,EAAE;AACjB,gBAAA,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;aAC3B;AACD,YAAA,IAAI,KAAK,CAAC,MAAM,EAAE;AAChB,gBAAA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;aACjD;YAED,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE;AAC5B,gBAAA,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;aAC5B;SACF;AAED,QAAA,OAAO,KAAK,CAAC;KACd;;AAGO,IAAA,aAAa,CAAC,KAAwB,EAAA;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE/B,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;SACnC;aAAM;YACL,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAC/B;KACF;;IAGO,WAAW,GAAA;AACjB,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;AACxB,QAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;KACzC;;IAGO,cAAc,CAAC,SAA0B,EAAE,MAAkB,EAAA;QACnE,MAAM,IAAI,GAAG,aAAa,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;AAC1D,QAAA,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAClC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AACtD,QAAA,MAAM,SAAS,GAAG,GAAG,KAAK,IAAI;cAC1B,CAAC,OAAO;AACV,cAAE,OAAO,EAAE,IAAI,KAAK,IAAI,IAAI,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC;QAEpE,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,EAAE;AAC1C,YAAA,OAAO,KAAK,CAAC;SACd;QAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;AAE1C,QAAA,IAAI,GAAG,KAAK,IAAI,EAAE;AAChB,YAAA,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;SAC3B;aAAM;AACL,YAAA,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;SAC1C;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAE5B,QAAA,OAAO,IAAI,CAAC;KACb;;;;;;;;IASO,iBAAiB,GAAA;QACvB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;AAClC,YAAA,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC;YAC5E,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,IAAI,OAAO,EAAE,WAAW,CAAC;AAC5D,YAAA,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE;gBAC5B,OAAO;aACR;AAED,YAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YAC1F,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;YACjG,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,KAAK,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;YAC9E,IAAI,IAAI,EAAE;AACR,gBAAA,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;aACtF;iBAAM;AACL,gBAAA,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;aAC9B;YAED,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AACjD,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KACvC;;IAGO,aAAa,CAAC,WAAmB,EAAE,IAAgC,EAAA;QACzE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAErC,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;SAC7B;aAAM;AACL,YAAA,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;SAC1B;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACxB;;;AAIO,IAAA,YAAY,CAAC,SAAkC,EAAA;AACrD,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;AACpD,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAE1B,QAAA,IAAI,SAAS,KAAK,IAAI,CAAC,UAAU,EAAE;AACjC,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;SAChC;AAED,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;KAC5B;;IAGO,MAAM,GAAA;AACZ,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;AAE9B,QAAA,OAAO,MAAM;cACT,gBAAgB,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;cACvC,EAAE,CAAC;KACR;AAEO,IAAA,QAAQ,CAAC,WAAmB,EAAA;QAClC,OAAO,IAAI,CAAC,MAAM,EAAE;AACjB,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,WAAW,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;KACpF;;;;;;IAOO,iBAAiB,GAAA;QACvB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE;aAChC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;AAChD,aAAA,GAAG,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAClD,QAAA,MAAM,IAAI,GAAG,IAAI,GAAG,EAAmC,CAAC;QAExD,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,WAAW,KAAI;YACnD,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,IAAI,CAAC,SAAS,EAAE;gBACd,OAAO;aACR;AAED,YAAA,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAC/C,YAAA,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;AACrC,YAAA,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAElH,YAAA,IAAI,aAAa,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;gBAClC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACzC;AACH,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;AACzD,aAAA,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;AACjE,aAAA,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;KACxD;;;;;;AAOO,IAAA,eAAe,CAAC,MAAc,EAAA;QACpC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,MAAM,CAAC,EAAE,EAAE;AACpC,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvB,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YAC5B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACpC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC;SAC5C;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACzB,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;AACzC,aAAA,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,iBAAiB,EAAE,CAAC;;QAEzB,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAEzB,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACtF,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;SACxB;KACF;;;IAIO,uBAAuB,CAAC,KAAuB,EAAE,MAA6C,EAAA;QACpG,IAAI,KAAK,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AACjD,YAAA,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;SAC5C;QAED,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAEpC,QAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,YAAA,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;SAClB;AACD,QAAA,IAAI,GAAG,KAAK,SAAS,EAAE;AACrB,YAAA,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;SAClB;KACF;;;AAIO,IAAA,sBAAsB,CAAC,YAAgC,EAAA;AAC7D,QAAA,IAAI,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE;AACtC,YAAA,OAAO,EAAE,aAAa,EAAE,YAAY,CAAC,aAAa,EAAE,CAAC;SACtD;QAED,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAE3C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE;AAC1C,YAAA,OAAO,IAAI,CAAC;SACb;QAED,OAAO;AACL,YAAA,IAAI,GAAG,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACrC,YAAA,IAAI,GAAG,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;SACtC,CAAC;KACH;;;;AAKO,IAAA,gBAAgB,CAAC,MAAuC,EAAA;QAC9D,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACtE,aAAA,MAAM,CAAC,CAAC,WAAW,KAAI;YACtB,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACpC,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;AAErD,YAAA,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC;AAClD,SAAC,CAAC,CAAC;AAEL,QAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACjB,OAAO;SACR;QAED,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;AAC/C,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5F,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;KAClC;wGAjuCU,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAxB,wBAAwB,EAAA,CAAA,CAAA;;4FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;;;AC1LX;AACA,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,0BAA0B,CAAA;AAE7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAqC,CAAC;AACxD,IAAA,OAAO,GAAG,IAAI,GAAG,EAA+B,CAAC;;;AAGjD,IAAA,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;;;IAGxC,OAAO,GAAkB,IAAI,CAAC;;;;IAK/B,OAAO,CAAC,KAAwB,EAAE,MAAqB,EAAA;QAC5D,OAAO,KAAK,CAAC,MAAK;AAChB,YAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;YACxE,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAE1C,YAAA,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;AACpB,gBAAA,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;aACf;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACtC,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAE7D,OAAO,MAAM,CAAC,MAAM;AACjB,iBAAA,IAAI,CACH,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EACjC,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,CAC5B,CAAC;AACN,SAAC,CAAC,CAAC;KACJ;;;IAIM,KAAK,CAAC,OAAe,EAAE,KAAc,EAAA;QAC1C,IAAI,CAAC,SAAS,EAAE,CAAC;AAEjB,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC;KAC9D;;AAGM,IAAA,SAAS,CAAC,OAAe,EAAA;QAC9B,IAAI,CAAC,SAAS,EAAE,CAAC;AAEjB,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC;KACvD;;;AAIM,IAAA,MAAM,CAAC,OAAe,EAAA;QAC3B,IAAI,CAAC,SAAS,EAAE,CAAC;AAEjB,QAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC;KACpD;;;;IAKO,IAAI,CACV,MAAiC,EACjC,KAAwB,EACxB,MAAc,EACd,IAAkB,EAClB,QAAiB,EAAA;QAEjB,MAAM,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;;;AAGlE,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI,EAAE,IAAI,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAAC,CAAC;QACpH,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE;AAClC,aAAA,MAAM,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAE3G,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACrD,OAAO,MAAM,CAAC,GAAG,CAAC;SACnB;QAED,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxE,QAAA,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;AAC7B,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AAChB,QAAA,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAE3G,OAAO,MAAM,CAAC,GAAG,CAAC;KACnB;;;AAIO,IAAA,QAAQ,CAAC,KAAwB,EAAE,MAAc,EAAE,IAAkB,EAAA;QAC3E,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;AACrG,QAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,CAAC,IAAI,EAAE;YACT,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;SAClE;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;;;AAG9C,QAAA,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,KAAK,OAAO;AAC5C,cAAE,sBAAsB,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC;AAC9E,cAAE,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,gBAAgB,IAAI,EAAE,CAAC;;;AAGjE,QAAA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,MAAM,IAAI,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AACpG,cAAE,gBAAgB;cAChB,EAAE,CAAC;AACP,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACjG,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC;AACxD,aAAA,MAAM,CAAC,CAAC,KAAK,KAAI;AAChB,YAAA,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;AAEpD,YAAA,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrF,SAAC,CAAC,CAAC;QAEL,OAAO;YACL,OAAO;AACP,YAAA,IAAI,gBAAgB,CAAC,MAAM,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;AACxD,YAAA,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;SACzC,CAAC;KACH;;;IAIO,MAAM,CACZ,MAAiC,EACjC,OAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,IAAuC,EAAA;AAEvC,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;;QAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAoC,IAAI;AACnD,cAAE,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC;cAChE,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC;iBACjD,IAAI,CAAC,GAAG,CAAC,CAAC,OAA6B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAEjH,QAAA,OAAO,OAAO;AACX,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,MAAM,KAAI;YACb,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE;gBACzC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,IAAI,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;aACpF;SACF,CAAC,EACF,GAAG,CAAC,CAAC,MAAM,MAAM;YACf,GAAG;AACH,YAAA,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS;AAC9B,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AAChG,SAAA,CAAC,CAAC,EACH,UAAU,CAAC,MAAK;AACd,YAAA,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;AAExB,YAAA,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;SACjE,CAAC,CACH,CAAC;KACL;;;;;AAMO,IAAA,OAAO,CAAC,OAAe,EAAA;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,QAAQ,CAAC;SACjB;AAED,QAAA,MAAM,SAAS,GAAG,IAAI,OAAO,EAA0B,CAAC;AACxD,QAAA,MAAM,MAAM,GAA8B;AACxC,YAAA,SAAS,EAAE,IAAI;AACf,YAAA,GAAG,EAAE,CAAC;AACN,YAAA,SAAS,EAAE,KAAK;AAChB,YAAA,MAAM,EAAE,KAAK;YACb,SAAS;AACT,YAAA,MAAM,EAAE,SAAS;AACd,iBAAA,IAAI,CACH,SAAS,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,EACrC,GAAG,CAAC,CAAC,IAAI,KAAI;AACX,gBAAA,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;AAClC,gBAAA,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;aAC7B,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EACpC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAChD;SACJ,CAAC;;AAGF,QAAA,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAEnC,QAAA,OAAO,MAAM,CAAC;KACf;;;;IAKO,SAAS,GAAA;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;AAC1C,QAAA,IAAI,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE;YAC3B,OAAO;SACR;AAED,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;AAC/B,YAAA,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;AAC1B,SAAC,CAAC,CAAC;AACH,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;AACrB,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;KACrB;IAEO,SAAS,CAAC,OAAe,EAAE,OAA6B,EAAA;AAC9D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;AAEtE,QAAA,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC5B,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE;AAC9C,gBAAA,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;aAChD;SACF;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;KACnC;AAEO,IAAA,SAAS,CAAC,OAAe,EAAA;AAC/B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QAC5D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAEhC,QAAA,OAAO,KAAK,CAAC;KACd;wGA3OU,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAA1B,0BAA0B,EAAA,CAAA,CAAA;;4FAA1B,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBADtC,UAAU;;AAgPX;AACA;AACA;AACA;AACA,SAAS,WAAW,CAAC,KAAwB,EAAE,QAAiB,EAAA;IAC9D,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;AAE5E,IAAA,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5F,CAAC;AAED;AACA;AACA;AACA,SAAS,YAAY,CAAC,KAA0B,EAAA;IAC9C,OAAO,eAAe,IAAI,KAAK,CAAC;AAClC,CAAC;AAED;AACA;AACA,SAAS,UAAU,CAAC,KAAmC,EAAA;AACrD,IAAA,OAAO,CAAC,IAAI,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;AAC/D,SAAA,MAAM,CAAC,CAAC,IAAI,KAA8B,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC;AAC/F,SAAA,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;AAC5B;;ACtTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;SACgB,YAAY,CAC1B,KAA+B,EAC/B,MAAgC,EAChC,IAAY,EAAA;AAEZ,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAE/B,OAAO;QACL,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,KAAK;QAClC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,KAAK;KAClC,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,WAAW,CACzB,MAAmB,EACnB,KAA+B,EAC/B,IAAY,EACZ,IAAgB,EAAA;IAEhB,MAAM,SAAS,GAAI,MAAM,CAAC,YAAmC,IAAI,MAAM,CAAC,aAAa,CAAC;AACtF,IAAA,MAAM,IAAI,GAAG,SAAS,EAAE,qBAAqB,EAAE,CAAC;;;IAGhD,MAAM,MAAM,GAAG,IAAI;AACjB,UAAE;AACA,YAAA,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC;AACvE,YAAA,CAAC,EAAE,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC;AACtE,SAAA;UACC,KAAK,CAAC;IACV,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAEjD,IAAA,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE;AAC1B,QAAA,QAAQ,EAAE,UAAU;AACpB,QAAA,KAAK,EAAE,GAAG;AACV,QAAA,MAAM,EAAE,GAAG;AACX,QAAA,aAAa,EAAE,MAAM;AACrB,QAAA,IAAI,EAAE,CAAA,EAAG,MAAM,CAAC,IAAI,CAAI,EAAA,CAAA;AACxB,QAAA,GAAG,EAAE,CAAA,EAAG,MAAM,CAAC,GAAG,CAAI,EAAA,CAAA;AACvB,KAAA,CAAC,CAAC;IAEH,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;AACA,SAAS,UAAU,CAAC,IAAY,EAAA;AAC9B,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;AACtD;;AC3CA;AACA;AACA;AACA;MAea,oBAAoB,CAAA;AAEf,IAAA,IAAI,GAAG,MAAM,CAAwB,eAAe,CAAC,CAAC;AAEtD,IAAA,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AAE5B,IAAA,MAAM,GAAG,MAAM,CAAsB,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;;IAGhE,UAAU,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO;AACrD,SAAA,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACrD,SAAA,MAAM,CAAC,CAAC;AAEM,IAAA,UAAU,GAAG,MAAM,CAA+C,YAAY,CAAC,CAAC;;AAG1F,IAAA,WAAW,CAAC,IAAY,EAAA;AAC7B,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAC5D;IAEM,MAAM,CAAC,IAAY,EAAE,KAAc,EAAA;QACxC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AAC5B,YAAA,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;YAE7B,IAAI,KAAK,EAAE;AACT,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aACnB;iBAAM;AACL,gBAAA,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;aAChB;AAED,YAAA,OAAO,IAAI,CAAC;AACd,SAAC,CAAC,CAAC;KACJ;IAEM,IAAI,GAAA;AACT,QAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO;aAC/B,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC;AAC9B,aAAA,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KAC/C;wGAtCU,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,ECrCjC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,21BAiCA,EDJI,MAAA,EAAA,CAAA,0CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,EACT,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,WAAW,EACX,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,IAAA,EAAA,UAAA,EAAA,eAAA,EAAA,MAAA,EAAA,OAAA,EAAA,eAAA,EAAA,UAAA,EAAA,OAAA,EAAA,qBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,qBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,cAAc,EACd,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,kBAAA,EAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,wGAChB,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAf,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGL,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAdhC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,SAAS;wBACT,WAAW;wBACX,gBAAgB;wBAChB,cAAc;wBACd,gBAAgB;wBAChB,cAAc;AACf,qBAAA,EAAA,QAAA,EAAA,21BAAA,EAAA,MAAA,EAAA,CAAA,0CAAA,CAAA,EAAA,CAAA;;;AEnCH;AACA;AACA;AACA,IAAY,cAIX,CAAA;AAJD,CAAA,UAAY,cAAc,EAAA;AACxB,IAAA,cAAA,CAAA,IAAA,CAAA,GAAA,IAAS,CAAA;AACT,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACb,IAAA,cAAA,CAAA,MAAA,CAAA,GAAA,MAAa,CAAA;AACf,CAAC,EAJW,cAAc,KAAd,cAAc,GAIzB,EAAA,CAAA,CAAA;;ACaD;AACA;AACO,MAAM,iCAAiC,GAAqB,OAAO,CAAC;AACpE,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAqEhD,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,cAAc,GAAG,QAAQ,CAAC;AAChC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AACzF,MAAM,aAAa,GAAG,GAAG,CAAC;SAEV,WAAW,CACzB,MAAoC,EACpC,IAAsC,EACtC,OAAuB,EAAA;AAEvB,IAAA,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,CAAC;AAChC,IAAA,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC;IAE9B,OAAO;AACL,QAAA,KAAK,EAAE,YAAY,CAAC,GAAG,GAAG,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;AAC9G,QAAA,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE;QAC3B,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC;AACtC,QAAA,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC;QACjC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC;QAC9C,SAAS,EAAE,GAAG,EAAE,SAAS;AACvB,cAAE,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE;AACxG,cAAE,IAAI;KACT,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACgB,SAAA,oBAAoB,CAAC,MAAyB,EAAE,OAAgB,EAAA;AAC9E,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAsB,KAAK,KAAK,IAAI,CAAC,CAAC;AAE1E,IAAA,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;AACnB,QAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KAC5C;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG;QAClE,CAAC,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,aAAa,GAAG,CAAC,GAAG,KAAK,GAAG,aAAa,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACxF,CAAC,EAAE,IAAI,KAAK,GAAG,GAAG,aAAa,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,IAAI,aAAa,IAAI,IAAI,GAAG,GAAG,CAAC;AACpF,KAAA,CAAC,CAAC;AACH,IAAA,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE5C,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAG,EAAA,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAA,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/G,QAAA,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;AACzF,QAAA,IAAI,EAAE,SAAS,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI;KAC3D,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAoC,EAAA;IACzD,OAAO,MAAM,CAAC,MAAM,CAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,KAAI;QACjE,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE;AACrC,gBAAA,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aACf;AAED,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACnC;AAED,QAAA,OAAO,IAAI,CAAC;KACb,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED;AACA;AACA,SAAS,QAAQ,CAAC,MAAoC,EAAE,IAAsC,EAAA;IAC5F,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;AAC5B,IAAA,MAAM,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE,IAAA,OAAO,GAAG,GAAG,MAAM,CAAC,CAAC;AACvB,CAAC;AAED;AACA;AACA,SAAS,QAAQ,CACf,MAAoC,EACpC,IAAsC,EACtC,OAAuB,EAAA;AAEvB,IAAA,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,CAAC;AAEtB,IAAA,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE;AAC/F,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACxC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,KAAK,gBAAgB,GAAG,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC;IACjF,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAErD,IAAA,IAAI,MAAM,KAAK,IAAI,EAAE;AACnB,QAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,oBAAoB,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;KACxG;IAED,MAAM,OAAO,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,EAAE,CAAC;AACzD,IAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AACnF,IAAA,MAAM,IAAI,GAAG,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;AAC9E,IAAA,MAAM,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,cAAc,CAAC,IAAI,IAAI,MAAM,GAAG,CAAC,GAAG,cAAc,CAAC,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;AAE3G,IAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;AAC/E,CAAC;AAED;AACA;AACA;AACA,SAAS,WAAW,CAAC,GAAiB,EAAE,MAAoC,EAAA;AAC1E,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,gBAAgB,IAAI,GAAG,CAAC,aAAa,KAAK,IAAI,CAAC;IAE5E,OAAO;AACL,QAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE;AACtC,QAAA,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,QAAQ;AAC3C,QAAA,MAAM,EAAE,CAAC;AACT,QAAA,MAAM,EAAE,KAAK;AACb,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,KAAK,EAAE,IAAI;KACZ,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAAC,KAAqB,EAAE,UAAmD,EAAA;AAC3F,IAAA,MAAM,QAAQ,GAAG,UAAU,IAAI,oBAAoB,CAAC,IAAI,CAAC;AAEzD,IAAA,IAAI,KAAK,KAAK,cAAc,CAAC,IAAI,IAAI,QAAQ,KAAK,oBAAoB,CAAC,OAAO,EAAE;QAC9E,OAAO,oBAAoB,CAAC,OAAO,CAAC;KACrC;AAED,IAAA,MAAM,IAAI,GAAG,KAAK,KAAK,cAAc,CAAC,EAAE,CAAC;IAEzC,OAAO,IAAI,MAAM,QAAQ,KAAK,oBAAoB,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC;AAClH,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,YAAY,CACnB,MAAoC,EACpC,IAAmB,EACnB,OAAuB,EAAA;AAEvB,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IACnC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,GAAG,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3G,MAAM,IAAI,GAAG,KAAK,GAAGgB,iBAAe,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;AAE7F,IAAA,IAAI,KAAK,IAAI,IAAI,EAAE;AACjB,QAAA,OAAO,CAAM,GAAA,EAAA,KAAK,CAAK,EAAA,EAAA,IAAI,GAAG,CAAC;KAChC;AAED,IAAA,OAAO,KAAK,IAAI,IAAI,GAAG,CAAA,GAAA,EAAM,KAAK,IAAI,IAAI,CAAE,CAAA,GAAG,EAAE,CAAC;AACpD,CAAC;AAED;AACA;AACA,SAASA,iBAAe,CACtB,UAA+B,EAC/B,KAAuB,EACvB,MAAuB,EACvB,SAAkB,EAAA;AAElB,IAAA,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE;QAC/B,OAAO,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;KAC5D;IAED,OAAO,SAAS,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACpG,CAAC;AAED;AACA;AACA;AACA,SAAS,UAAU,CAAC,IAAsC,EAAE,OAAuB,EAAA;AACjF,IAAA,MAAM,UAAU,GAAG,IAAI,EAAE,UAAU,CAAC;AAEpC,IAAA,IAAI,UAAU,EAAE,OAAO,EAAE;QACvB,OAAO,cAAc,CAAC,UAAU,CAAC;AAC/B,cAAE,gBAAgB,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC;AACnE,cAAE,eAAe,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KACrF;IAED,OAAO,IAAI,EAAE,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;AACzG,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAChB,MAAoC,EACpC,GAAwB,EACxB,MAA2B,EAAA;AAE3B,IAAA,MAAM,MAAM,GAAG,GAAG,EAAE,MAAM,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAEjC,OAAO;QACL,IAAI,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,cAAc,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAE,CAAA;QACjG,QAAQ,EAAE,QAAQ,KAAK,IAAI,GAAG,EAAE,GAAG,CAAG,EAAA,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAY,UAAA,CAAA;QAC1H,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACnE,QAAA,IAAI,EAAE,MAAM,CAAC,GAAG,GAAG,oBAAoB,CAAC,IAAI,GAAG,oBAAoB,CAAC,OAAO;KAC5E,CAAC;AACJ,CAAC;AAGD;AACM,SAAU,eAAe,CAAC,MAAoC,EAAA;IAClE,OAAO;AACL,QAAA,UAAU,EAAE,MAAM,EAAE,UAAU,IAAI,IAAI;AACtC,QAAA,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;AAC9B,QAAA,SAAS,EAAE,MAAM,EAAE,SAAS,IAAI,IAAI;KACrC,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACgB,SAAA,mBAAmB,CAAC,CAAkB,EAAE,CAAkB,EAAA;AACxE,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,sBAAsB,CAAC,QAAyB,EAAA;IACvD,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAEnD,OAAO;AACL,QAAA,UAAU,EAAE,UAAU,KAAK,oBAAoB,CAAC,IAAI,GAAG,IAAI,IAAI,UAAU,IAAI,IAAI,CAAC;QAClF,MAAM,EAAE,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,GAAG,IAAI;AAC5E,QAAA,SAAS,EAAE,SAAS;AAClB,cAAE;AACA,gBAAA,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,iCAAiC;AACvE,gBAAA,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,6BAA6B;AAC5D,aAAA;AACD,cAAE,IAAI;KACT,CAAC;AACJ;;AC/SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACO,MAAM,kBAAkB,GAAqC;AAClE,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,WAAW,EAAE,oBAAoB;AACjC,IAAA,QAAQ,EAAE,WAAW;CACtB,CAAC;AAEF;AACA;AACA;AACM,SAAU,WAAW,CAAC,KAAyC,EAAA;IACnE,MAAM,KAAK,GAAG,KAAK,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC;IACzC,IAAI,IAAI,GAAuC,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzE,IAAA,IAAI,KAAK,EAAE,WAAW,KAAK,OAAO,IAAI,KAAK,EAAE,WAAW,KAAK,KAAK,IAAI,KAAK,EAAE,WAAW,KAAK,OAAO,EAAE;AACpG,QAAA,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC;KAC1B;IAED,OAAO;AACL,QAAA,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;AACpD,QAAA,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;QACpD,IAAI;KACL,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAC5B,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAC5B,GAAmB,EACnB,KAAyC,EAAA;AAEzC,IAAA,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACtD,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAqB,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AAE1E,IAAA,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC;AAClD,WAAA,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC,aAAa,CAAC,MAAM;YACnE,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE;AACpD,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEpE,OAAO;QACL,WAAW,EAAE,SAAS,CAAC,EAAE;QACzB,MAAM,EAAE,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAC1G,QAAA,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;QACxC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI;QAC7C,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,CAAC;QAC9C,OAAO;KACR,CAAC;AACJ,CAAC;AAED;SACgB,YAAY,CAC1B,SAA0B,EAC1B,IAA0B,EAC1B,KAAyC,EAAA;IAEzC,MAAM,MAAM,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,CAAc,CAAC;IACrD,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5E,IAAA,MAAM,KAAK,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,GAAG,SAAS,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1G,OAAO;QACL,WAAW,EAAE,SAAS,CAAC,EAAE;AACzB,QAAA,MAAM,EAAE,EAAE;QACV,OAAO;QACP,KAAK,EAAE,KAAK,IAAI,IAAI;QACpB,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,CAAC;AAC9C,QAAA,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC;KAC5B,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACM,SAAU,eAAe,CAAC,OAA0B,EAAA;IACxD,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AAC1F,CAAC;AAED;AACA;AACA;AACgB,SAAA,WAAW,CAAC,KAAsB,EAAE,OAA0B,EAAA;IAC5E,OAAO,eAAe,CAAC,OAAO,CAAC;SAC5B,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AAC/F,CAAC;AAED;AACA;AACA;AACA;SACgB,eAAe,CAC7B,KAAsB,EACtB,OAAoC,EACpC,OAAsB,EAAA;AAEtB,IAAA,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;AACnB,QAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KACxD;AAED,IAAA,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AAC3B,IAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,OAAO,KAAK,GAAG,EAAE;AAC5E,QAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;KACpE;AAED,IAAA,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAClG,CAAC;AAED;AACA;AACM,SAAU,OAAO,CAAC,KAAsB,EAAA;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC;AACpB,QAAA,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAC9D,QAAA,KAAK,CAAC,OAAO;AACd,KAAA,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACgB,SAAA,UAAU,CACxB,KAAsB,EACtB,KAA4C,EAAA;AAE5C,IAAA,OAAO,KAAK;UACR,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,IAAI;UACnF,IAAI,CAAC;AACX,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,aAAa,CAC3B,KAA4C,EAC5C,KAAsB,EAAA;IAEtB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEvC,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;AAClC,QAAA,OAAO,IAAI,CAAC;KACb;IAED,OAAO;QACL,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QAC1E,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE;KAC5C,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,SAAS,CAAC,MAAmB,EAAE,SAA+B,EAAE,GAAmB,EAAA;AAC1F,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;AAE5C,IAAA,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,EAAE;AAC5B,QAAA,OAAO,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;KACrE;AAED,IAAA,IAAI,SAAS,KAAK,WAAW,EAAE;AAC7B,QAAA,OAAO,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;KACpE;AAED,IAAA,IAAI,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE;AACrE,QAAA,OAAO,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;KAC3E;IAED,MAAM,KAAK,GAAG,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,GAAG,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAEtG,IAAA,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;AAC1E,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAClB,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAC5B,SAA+B,EAC/B,SAAiB,EACjB,MAAqB,EAAA;AAErB,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;AAC/C,IAAA,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC5D,IAAA,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAErF,IAAI,MAAM,KAAK,IAAI,IAAI,WAAW,IAAI,WAAW,KAAK,OAAO,EAAE;AAC7D,QAAA,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;KAC9G;AAED,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;AACA;AACA;AACA,SAAS,aAAa,CACpB,MAAmB,EACnB,IAAmB,EACnB,OAA4B,EAC5B,SAA+B,EAC/B,MAAc,EACd,SAAiB,EAAA;IAEjB,MAAM,GAAG,GAAG,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9C,IAAA,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAC7E,IAAA,MAAM,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;IAE1F,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;AACpC,QAAA,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;KAC/B;AAED,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,KAAK,KAAK,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,CAAC;IAEvE,OAAO;QACL,MAAM;QACN,GAAG;AACH,QAAA,KAAK,EAAE,GAAG,GAAG,KAAK,GAAG,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;QACxG,MAAM;QACN,KAAK;KACN,CAAC;AACJ,CAAC;AAED;AACA,SAAS,OAAO,CAAC,KAAc,EAAA;AAC7B,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE;AACzD,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;AACA,SAAS,MAAM,CAAC,KAAgC,EAAA;AAC9C,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;AAC5E;;ACzRA;AACA;AACA;AACO,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,SAAS,CACvB,QAA6B,EAC7B,IAAyB,EACzB,OAAqB,EAAA;AAErB,IAAA,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAACC,KAAG,CAAC,MAAM,wBAAwB,CAAC,CAAC,CAAC;SACpE,IAAI,CACHZ,WAAS,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAC5C,SAAA,IAAI,CACHA,WAAS,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CACxC,CAAC,CACL,CAAC;AACN,CAAC;AAED;AACA;AACA,SAAS,OAAO,CAAI,IAAyB,EAAE,OAAqB,EAAA;AAClE,IAAA,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC;AAEzB,IAAA,OAAO,IAAI,EAAE;SACV,IAAI,CACHY,KAAG,CAAC,CAAC,IAAI,MAAyB,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EACzDC,YAAU,CAAC,CAAC,KAAc,KAAK,EAAE,CAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EACrGC,QAAM,CAAC,MAAM,OAAO,EAAE,KAAK,MAAM,CAAC,CACnC,CAAC;AACN,CAAC;AAED;AACA;AACA,SAAS,gBAAgB,CAAC,KAAc,EAAA;IACtC,MAAM,OAAO,GAAG,KAAoE,CAAC;IACrF,MAAM,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC;AAE5D,IAAA,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,OAAO,GAAG,qBAAqB,CAAC;AAClF;;ACAA;AACA,MAAM,iBAAiB,GAAG,KAAK,CAAC;AAEhC;AACA,MAAM,sBAAsB,GAAG,0CAA0C,CAAC;AAE1E,MAAM,UAAU,GAA+B;AAC7C,IAAA,OAAO,EAAE,OAAO;AAChB,IAAA,KAAK,EAAE,aAAa;AACpB,IAAA,MAAM,EAAE,QAAQ;AAChB,IAAA,cAAc,EAAE,gBAAgB;CACjC,CAAC;AAEF;AACA;AACA;AACA;AACM,SAAU,kBAAkB,CAChC,IAA0C,EAC1C,OAA6B,EAC7B,QAA4B,EAAE,EAAA;IAE9B,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,KAAK,GAAG;AACZ,QAAA,KAAK,CAAC,OAAO,KAAK,KAAK,GAAG,EAAE,GAAG,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC;AAClE,QAAA,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC;AAClC,QAAA,IAAI,KAAK,CAAC,kBAAkB,GAAG,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC7E,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;KAC1E,CAAC;IAEF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;AACA;AACA;AACA;SACgB,gBAAgB,CAC9B,MAAc,EACd,IAA0C,EAC1C,MAAuB,EAAA;IAEvB,MAAM,KAAK,GAAG,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,MAAM,CAAC;IACrD,MAAM,MAAM,GAAG,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC,CAAC;IAEtC,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO;QACL,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC;AACnD,QAAA,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC;AAClC,QAAA,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC;AACnC,QAAA,eAAe,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC;AACrD,KAAA;SACE,MAAM,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,CAAC;SAChC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,oBAAoB,CAAC,IAAuB,EAAE,OAA6B,EAAA;AACzF,IAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;IAEnC,IAAI,UAAU,EAAE;QACd,OAAO,UAAU,CAAC,OAAO,GAAG,qBAAqB,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;KACxG;IAED,OAAO,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;AACjG,CAAC;AAED;AACA;AACA,SAAS,qBAAqB,CAC5B,UAA+B,EAC/B,aAA+B,EAC/B,MAAuB,EAAA;AAEvB,IAAA,IAAI,cAAc,CAAC,UAAU,CAAC,EAAE;AAC9B,QAAA,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;YAC9D,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAEtE,YAAA,OAAO,GAAG,GAAG,CAAG,EAAA,qBAAqB,CAAC,MAAM,CAAC,KAAK,GAAG,CAAA,CAAE,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC1F,SAAC,CAAC,CAAC;AAEH,QAAA,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;aAC9D,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC;aACxB,IAAI,CAAC,iBAAiB,CAAC,CAAC;KAC5B;AAED,IAAA,MAAM,OAAO,GAAG,eAAe,CAAC,aAAa,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC5E,IAAA,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;AAC9D,QAAA,OAAO,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC1F,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC;SACxB,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,iBAAiB,CAAC,CAAC;AAC7B,CAAC;AAED;AACA;AACA,SAAS,eAAe,CACtB,MAAwB,EACxB,KAAmC,EACnC,QAAgB,EAChB,MAAuB,EAAA;AAEvB,IAAA,MAAM,KAAK,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC5C,IAAA,MAAM,IAAI,GAAG,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAEnE,IAAA,OAAO,IAAI,GAAG,CAAG,EAAA,KAAK,CAAK,EAAA,EAAA,IAAI,CAAE,CAAA,GAAG,KAAK,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CAAC,UAAkD,EAAA;IACzE,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;AACvF,CAAC;AAED;AACA;AACA,SAAS,OAAO,CACd,GAAoC,EACpC,UAAkD,EAAA;IAElD,OAAO,GAAG,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;AACnF,CAAC;AAED;AACA,SAAS,kBAAkB,CAAC,IAAuB,EAAE,MAAuB,EAAA;AAC1E,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAEnD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAI;AACnC,QAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;AAExD,QAAA,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,CAAG,EAAA,KAAK,KAAK,IAAI,CAAA,CAAE,GAAG,IAAI,CAAC;AACzD,KAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,IAAuB,EAAE,MAAuB,EAAA;IACnE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;AACrC,SAAA,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAC/G,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,kBAAkB,CACzB,MAAkB,EAClB,UAAkD,EAClD,MAAuB,EAAA;IAEvB,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE;AAC/B,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;IACtE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAC3G,IAAA,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,WAAW,GAAG,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAE3F,IAAA,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,KAAK,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE;AAClF,QAAA,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;KAC3D;IAED,IAAI,cAAc,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,OAAO,IAAI,WAAW,EAAE;AACnE,QAAA,OAAO,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;KACzF;AAED,IAAA,OAAO,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,CAAA,EAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAI,CAAA,EAAA,qBAAqB,CAAC,MAAM,CAAC,CAAA,CAAA,CAAG,CAAC;AACpH,CAAC;AAED,SAAS,aAAa,CAAC,IAAgB,EAAE,OAAe,EAAE,KAAa,EAAE,MAA+B,EAAA;IACtG,QAAQ,IAAI;AACV,QAAA,KAAK,SAAS;YACZ,OAAO,CAAA,UAAA,EAAa,OAAO,CAAA,CAAA,CAAG,CAAC;AACjC,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,MAAM,GAAG,CAAmB,gBAAA,EAAA,KAAK,KAAK,qBAAqB,CAAC,MAAM,CAAC,IAAI,GAAG,CAAmB,gBAAA,EAAA,KAAK,GAAG,CAAC;AAC/G,QAAA;YACE,OAAO,CAAA,EAAG,UAAU,CAAC,IAAI,CAAC,SAAS,KAAK,CAAA,IAAA,EAAO,OAAO,CAAA,CAAA,CAAG,CAAC;KAC7D;AACH,CAAC;AAED;AACA;AACA,SAAS,kBAAkB,CACzB,IAAgB,EAChB,aAA+B,EAC/B,WAA6B,EAC7B,MAA+B,EAC/B,MAAuB,EAAA;IAEvB,MAAM,OAAO,GAAG,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAEpD,QAAQ,IAAI;AACV,QAAA,KAAK,SAAS;YACZ,OAAO,CAAA,MAAA,EAAS,OAAO,CAAA,CAAA,CAAG,CAAC;AAC7B,QAAA,KAAK,OAAO;AACV,YAAA,OAAO,MAAM,GAAG,CAAe,YAAA,EAAA,KAAK,KAAK,qBAAqB,CAAC,MAAM,CAAC,IAAI,GAAG,CAAe,YAAA,EAAA,KAAK,GAAG,CAAC;AACvG,QAAA;YACE,OAAO,CAAA,EAAG,UAAU,CAAC,IAAI,CAAC,mBAAmB,KAAK,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAA,CAAG,CAAC;KACjF;AACH,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,MAAkB,EAAE,OAAsD,EAAA;AAC9F,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;IAEzD,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,KAAK,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,CAAA,YAAA,EAAe,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,GAAG,iBAAiB,CAAC;AAChG,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC7D,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAA,IAAA,EAAO,MAAM,CAAC,OAAO,EAAE,CAAC;IAEvE,OAAO,CAAA,IAAA,EAAO,EAAE,CAAiB,cAAA,EAAA,GAAG,KAAK,KAAK,CAAA,4BAAA,EAA+B,IAAI,CAAK,GAAA,CAAA;AAClF,UAAA,sBAAsB,CAAC;AAC7B,CAAC;AAED;AACA;AACA;AACA,SAAS,aAAa,CAAC,MAAkB,EAAE,OAAsD,EAAA;AAC/F,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK,OAAO,GAAG,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;IAE5D,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,IAAI,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,CAAA,YAAA,EAAe,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,iBAAiB,CAAC;AAElG,QAAA,OAAO,CAAsB,mBAAA,EAAA,KAAK,CAAK,EAAA,EAAA,sBAAsB,EAAE,CAAC;KACjE;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,CAAA,aAAA,EAAgB,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAEpF,OAAO,CAAA,mBAAA,EAAsB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAA,EAAA,EAAK,sBAAsB,CAAA,CAAE,CAAC;AACnF,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,WAAW,CAAC,MAAkB,EAAE,OAAsD,EAAA;AAC7F,IAAA,OAAO,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC;AACzD,CAAC;AAED;AACA,SAAS,eAAe,CACtB,IAA4B,EAC5B,MAAuB,EACvB,IAAuB,EAAA;IAEvB,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAErG,OAAO,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAG,CAAA,CAAA,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChF,CAAC;AAED;AACA,SAAS,SAAS,CAAC,KAAe,EAAA;AAChC,IAAA,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;UACnB,CAAG,EAAA,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,KAAA,EAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAE,CAAA;AACnE,UAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrB;;AC5UA;AACA;AACA;AACA;AACA;MAQa,sBAAsB,CAAA;AAEjB,IAAA,IAAI,GAAG,KAAK,CAA2B,IAAI,CAAC,CAAC;;;AAI7C,IAAA,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;;;AAItB,IAAA,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;;;AAIlC,IAAA,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1B,KAAK,GAAG,QAAQ,CAAC,MAAM,kBAAkB,CACvD,IAAI,CAAC,IAAI,EAAE,EACX,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,EAC5F,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE,CAC5G,CAAC,CAAC;AAEc,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;wGAtBtD,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,6nBClBnC,0NAQA,EAAA,MAAA,EAAA,CAAA,sIAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDUa,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAPlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,2BAA2B,EAGpB,eAAA,EAAA,uBAAuB,CAAC,MAAM,cACnC,IAAI,EAAA,QAAA,EAAA,0NAAA,EAAA,MAAA,EAAA,CAAA,sIAAA,CAAA,EAAA,CAAA;;;AEElB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAYa,uBAAuB,CAAA;AAElB,IAAA,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAmB,CAAC;AAC9C,IAAA,IAAI,GAAG,KAAK,CAAuB,IAAI,CAAC,CAAC;;;;;;AAMzC,IAAA,cAAc,GAAG,KAAK,CAAoC,EAAE,CAAC,CAAC;;AAE9D,IAAA,OAAO,GAAG,KAAK,CAA8B,EAAE,CAAC,CAAC;IAEjD,SAAS,GAAG,MAAM,EAAmB,CAAC;;;;IAItC,QAAQ,GAAG,MAAM,EAAQ,CAAC;AAE1B,IAAA,OAAO,GAAG,QAAQ,CAAuB,MAAK;AAC5D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;AAEzB,QAAA,OAAO,IAAI;AACT,cAAE,gBAAgB,CAChB,IAAI,CAAC,SAAS,EAAE,EAChB,IAAI,EACJ,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EACjC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,EAC9B,IAAI,CAAC,OAAO,EAAE,CACf;cACC,IAAI,CAAC;AACX,KAAC,CAAC,CAAC;IAEK,MAAM,GAAmB,IAAI,CAAC;;;IAG9B,UAAU,GAAY,IAAI,CAAC;AAClB,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AAEjC,IAAA,WAAW,CAAC,KAAc,EAAA;AAC/B,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;;;;;;QAMpB,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAmB,KAAI;YAChD,cAAc,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvE,SAAC,CAAC,CAAC;KACJ;;AAGM,IAAA,qBAAqB,CAAC,KAAoD,EAAA;AAC/E,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,IAAI,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;KACzD;;;;;AAMM,IAAA,YAAY,CAAC,MAAsB,EAAA;QACxC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC;AAE9C,QAAA,IAAI,MAAM,CAAC,aAAa,KAAK,QAAQ,EAAE;AACrC,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAErB,OAAO;SACR;AAED,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;AAC/C,QAAA,MAAM,SAAS,GAAG,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;cAClD,MAAM,CAAC,SAAS;AAClB,cAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAElE,QAAA,IAAI,CAAC,KAAK,CACR,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,EACrG,MAAM,CAAC,KAAK,EAAE,KAAK,CACpB,CAAC;KACH;;IAGM,MAAM,GAAA;AACX,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;KACvB;;IAGM,UAAU,CAAC,UAAU,GAAG,CAAC,EAAA;AAC9B,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;AAC7B,YAAA,IAAI,EAAE,KAAK;YACX,UAAU;AACV,YAAA,eAAe,EAAE,SAAS;SAC3B,CAAC,IAAI,IAAI,CAAC;KACZ;;;AAIO,IAAA,YAAY,CAAC,KAAmB,EAAA;QACtC,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,EAAE;YACnC,OAAO;SACR;AAED,QAAA,IAAI,CAAC,KAAK,CACR,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EACrG,KAAK,CAAC,KAAK,CACZ,CAAC;KACH;;;;;IAMO,UAAU,CAAC,CAAqB,EAAE,CAAqB,EAAA;AAC7D,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAE1B,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;AACnG,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,MAAM,UAAU,GAAI,IAAI,CAAC,SAAS,EAAE,CAAC,MAAsB,EAAE,WAAW,KAAK,YAAY,CAAC;AAC1F,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU;AAC7B,cAAE,KAAK,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9C,cAAE,KAAK,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;AAElD,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;KAC1D;;AAGO,IAAA,SAAS,CAAC,WAA0B,EAAA;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC;QACtC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,KAAK,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;AAE1F,QAAA,OAAO,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;KAC5D;IAEO,KAAK,CAAC,GAAmB,EAAE,KAAc,EAAA;AAC/C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI;cACd,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,GAAG,EAAE,KAAwB,CAAC;cACxG,IAAI,CAAC;QAET,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC5B;aAAM;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;SACtB;KACF;wGAlJU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,ECzCpC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,SAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,iWAWA,ED0BI,MAAA,EAAA,CAAA,mHAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,sBAAsB,wIACtB,mBAAmB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,EAAA,cAAA,EAAA,YAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,oBAAA,EAAA,0BAAA,EAAA,qBAAA,EAAA,uBAAA,EAAA,4BAAA,EAAA,gCAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,wBAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,sBAAA,EAAA,0BAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,uBAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,uBAAA,EAAA,YAAA,EAAA,eAAA,EAAA,oBAAA,EAAA,wBAAA,EAAA,eAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGV,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAXnC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,4BAA4B,mBAGrB,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,sBAAsB;wBACtB,mBAAmB;AACpB,qBAAA,EAAA,QAAA,EAAA,iWAAA,EAAA,MAAA,EAAA,CAAA,mHAAA,CAAA,EAAA,CAAA;;;AErBH;AACA,MAAM,WAAW,GAAG,qBAAqB,CAAC;AAE1C;AACA;AACA,MAAM,UAAU,GAAG,6CAA6C,CAAC;AAUjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,gBAAgB,CAAA;AAYR,IAAA,WAAA,CAAA;AACA,IAAA,SAAA,CAAA;AACA,IAAA,YAAA,CAAA;;AAXH,IAAA,MAAM,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;;;AAG/C,IAAA,OAAO,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;AAEzC,IAAA,SAAS,CAAU;AACnB,IAAA,OAAO,CAAwB;AAEhD,IAAA,WAAA,CACmB,WAAuB,EACvB,SAAiB,EACjB,YAAoB,EACrC,UAAmC,EAAE,EAAA;QAHpB,IAAW,CAAA,WAAA,GAAX,WAAW,CAAY;QACvB,IAAS,CAAA,SAAA,GAAT,SAAS,CAAQ;QACjB,IAAY,CAAA,YAAA,GAAZ,YAAY,CAAQ;QAGrC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC;AAC3C,QAAA,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,KAAK,MAAM,sBAAsB,CAAC,CAAC;KACjE;IAEM,IAAI,CAAC,OAAoB,EAAE,MAAkB,EAAA;QAClD,OAAO,KAAK,CAAC,MAAK;YAChB,IAAI,OAAO,GAAsB,IAAI,CAAC;AAEtC,YAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAA0B,CAAC;AACtD,iBAAA,IAAI,CACH,QAAQ,CAAC,CAAC,KAAK,KAAI;gBACjB,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,QAAQ,EAAE;AAC3C,oBAAA,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC;AAE5C,oBAAA,OAAO,KAAK,CAAC;iBACd;gBAED,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACjC,aAAC,CAAC,EACF,UAAU,CAAC,KAAK,CAAC,MAAK;gBACpB,IAAI,CAAC,OAAO,EAAE;oBACZ,OAAO,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;iBAChD;AACD,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAE1B,gBAAA,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;aACpB,CAAC,CAAC,EACHD,YAAU,CAAC,CAAC,KAAc,KAAK,UAAU,CAAC,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CACnE,CAAC;AACN,SAAC,CAAC,CAAC;KACJ;IAEO,QAAQ,CAAC,OAAoB,EAAE,MAAwB,EAAA;AAC7D,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CACnC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,YAAY,EACjB,MAAM,CAAC,OAAO,IAAI,EAAE,EACpB,YAAY,CAAC,MAAM,CAAC,EACpB,OAAO,EACP,IAAI,CAAC,SAAS,CACf,CAAC;KACH;;;AAIO,IAAA,MAAM,CAAC,IAAa,EAAA;QAC1B,MAAM,IAAI,GAAG,IAA6B,CAAC;AAE3C,QAAA,IAAI,IAAI,EAAE,MAAM,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAE7B,YAAA,OAAO,KAAK,CAAC;SACd;QAED,OAAO,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;KAC5D;;;AAIO,IAAA,UAAU,CAAC,IAAgB,EAAA;AACjC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE;AACxB,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC7B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE9B,OAAO;AACL,YAAA,GAAG,IAAI;YACP,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAgB,KAAI;AAC3C,gBAAA,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1D,gBAAA,OAAO,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;AACxD,aAAC,CAAC;SACH,CAAC;KACH;AAEF,CAAA;AAED;AACA;AACA,SAAS,YAAY,CAAC,MAAwB,EAAA;IAC5C,OAAO;QACL,IAAI,MAAM,CAAC,gBAAgB,EAAE,MAAM,GAAG,EAAE,gBAAgB,EAAE,CAAC,GAAG,MAAM,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,CAAC;AAC9F,QAAA,IAAI,MAAM,CAAC,SAAS,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,eAAe,CAAC,KAAkB,EAAA;IACzC,OAAO,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;AAC9C,CAAC;AAED;AACA,SAAS,SAAS,CAAC,KAAc,EAAA;AAC/B,IAAA,IAAI,KAAK,YAAY,iBAAiB,EAAE;AACtC,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC;AAErC,QAAA,OAAO,IAAI,KAAK,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;KAClF;AAED,IAAA,OAAO,KAAK,YAAY,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;AACjE;;AC9JA;AACA;AACA;AACA;AACA;AACA;AACA;MAKa,kBAAkB,CAAA;;;IAItB,SAAS,CACd,KAAc,EACd,KAAuB,EACvB,MAA2C,EAC3C,IAAY,EACZ,MAA+B,EAC/B,MAA2B,EAAA;AAE3B,QAAA,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;AAC/B,QAAA,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;AACvD,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE;AACtB,YAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC9B;AAED,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,gBAAgB;cAC3E,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC;cAC/C,IAAI,CAAC;QACT,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;AAC/D,YAAA,IAAI,UAAU,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;AACpD,YAAA,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,IAAI,IAAI;AACxC,YAAA,KAAK,EAAE,EAAE;AACV,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,SAAS,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC;QAExE,OAAO,EAAE,IAAI,EAAE,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC;KACtG;wGA7BU,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;sGAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,kBAAA,EAAA,CAAA,CAAA;;4FAAlB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAJ9B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,kBAAkB;AACxB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAA;;;ACMD,MAAM,aAAa,GAAoD;AACrE,IAAA,CAAC,UAAU,CAAC,MAAM,GAAG,iBAAiB,CAAC,MAAM;AAC7C,IAAA,CAAC,UAAU,CAAC,OAAO,GAAG,iBAAiB,CAAC,OAAO;AAC/C,IAAA,CAAC,UAAU,CAAC,QAAQ,GAAG,iBAAiB,CAAC,QAAQ;CAClD,CAAC;AAEF,MAAM,YAAY,GAAmD;AACnE,IAAA,CAAC,SAAS,CAAC,IAAI,GAAG,iBAAiB,CAAC,IAAI;AACxC,IAAA,CAAC,SAAS,CAAC,SAAS,GAAG,iBAAiB,CAAC,SAAS;AAClD,IAAA,CAAC,SAAS,CAAC,QAAQ,GAAG,iBAAiB,CAAC,QAAQ;AAChD,IAAA,CAAC,SAAS,CAAC,IAAI,GAAG,iBAAiB,CAAC,IAAI;CACzC,CAAC;AAEF;AACA,MAAM,aAAa,GAAqC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAE3E,MAAM,GAAG,GAAG,KAAK,CAAC;AAClB,MAAM,EAAE,GAAG,IAAI,CAAC;AAEhB;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,mBAAmB,CAAC,OAAgC,EAAA;IAClE,OAAO;AACL,QAAA,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,KAAK,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;AACtF,QAAA,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,KAAK,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC;KACtF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,OAAgC,EAChC,KAAc,EACd,KAAgB,EAChB,SAAyB,EAAA;AAEzB,IAAA,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE;AACzD,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,QAAQ,KAAK,CAAC,IAAI;QAChB,KAAK,aAAa,CAAC,MAAM;YACvB,OAAO,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC5D,KAAK,aAAa,CAAC,IAAI;YACrB,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,KAAK,aAAa,CAAC,QAAQ;AACzB,YAAA,OAAO,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1E,KAAK,aAAa,CAAC,OAAO;YACxB,OAAO,KAAK,GAAG,GAAG,GAAG,EAAE,CAAC;AAC1B,QAAA;YACE,OAAO,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;KACrD;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,OAAgC,EAChC,KAAc,EACd,KAAgB,EAChB,SAAyB,EAAA;;IAGzB,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE;AAC/C,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;KACtB;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;AAErF,IAAA,OAAO,MAAM;AACX,UAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI;UAC3D,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CACrB,OAAgC,EAChC,KAAc,EACd,KAAgB,EAChB,SAAyB,EAAA;AAEzB,IAAA,MAAM,WAAW,GAAI,SAAgD,EAAE,WAAW,IAAI,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;AAC/G,IAAA,MAAM,gBAAgB,GAAI,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAwB;AAC7E,SAAA,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC;IAE5D,OAAO,gBAAgB,IAAI,gBAAgB,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;UAC9E,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC;AAClH,UAAE,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED;AACA;AACA,SAAS,UAAU,CAAC,KAAgB,EAAE,SAAyB,EAAA;IAC7D,MAAM,MAAM,GAAG,SAA+C,CAAC;IAC/D,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;IAE3C,OAAO;AACL,QAAA,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;AACpD,QAAA,IAAI,OAAO,SAAS,KAAK,QAAQ,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;AACvD,QAAA,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACjD,CAAC;AACJ,CAAC;AAED;AACA,SAAS,WAAW,CAAC,SAAyB,EAAA;AAC5C,IAAA,OAAO,CAAC,CAAE,SAAmC,EAAE,WAAW,CAAC;AAC7D,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,KAAgB,EAAA;IACnD,OAAO,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,KAAK,KAAK,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;AAC9E,CAAC;AAED;AACA;AACA;AACA,SAAS,cAAc,CACrB,OAAgC,EAChC,IAAY,EACZ,KAAgB,EAChB,SAAkC,EAAA;IAElC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAC1C,IAAA,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO;SACnB,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,UAAU,GAAG,GAAG,CAAC;IAE9F,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;AAC5B,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,CAAC,MAAM,MAAM,UAAU,CAAC,OAAO,CAAC;AAE7E,IAAA,OAAO,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC;AAC1E,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAA;AACjC,IAAA,OAAO,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,KAAK,IAAI,GAAG,CAAC;AAC3G;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAea,sBAAsB,CAAA;AAEjB,IAAA,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAU,CAAC;AACpC,IAAA,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAmB,CAAC;AAE9C,IAAA,MAAM,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;AAC/C,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE;QACnH,MAAM,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM;AACvD,KAAA,CAAC,CAAC,CAAC;AAEY,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AACxE,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;;AAEtF,IAAA,SAAS,GAAG,MAAM,CAA4B,SAAS,CAAC,CAAC;AAEzD,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;AAClD,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC;AAClE,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,mBAAmB,CAAC;AAC7D,QAAA,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE;AACzC,QAAA,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;AACtC,QAAA,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE;AAC/B,KAAA,CAAC,CAAC,CAAC;AAEa,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AAC5D,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;;IAE7B,SAAS,GAAG,KAAK,CAAC;;IAElB,cAAc,GAAG,CAAC,CAAC;IAEpB,QAAQ,GAAA;AACb,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,oBAAoB,EAAE,CAAC;KAC7B;AAEM,IAAA,SAAS,CAAC,MAAkB,EAAA;AACjC,QAAA,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;KAC3D;AAEM,IAAA,YAAY,CAAC,SAAoC,EAAA;AACtD,QAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;KACjE;IAEO,KAAK,GAAA;QACX,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAEpC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;AAC3C,aAAA,IAAI,CACHb,WAAS,CAAC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,EACjCe,KAAG,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,EAC9B,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;QAEf,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE;AACpC,YAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE;AACjC,iBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;iBAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;SACzC;KACF;;;;IAKO,oBAAoB,GAAA;QAC1B,MAAM,CAAC,MAAK;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;AACxC,YAAA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE;gBAC9B,OAAO;aACR;AAED,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;AACtB,YAAA,SAAS,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;AACpD,SAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;KAC3D;AAEO,IAAA,MAAM,CAAC,KAAiB,EAAA;AAC9B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAC/D,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO;SACR;QAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC;AAC/G,QAAA,IAAI,MAAM,KAAK,OAAO,EAAE;YACtB,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;SACpD;KACF;;;;IAKO,SAAS,GAAA;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;AACjD,QAAA,MAAM,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC,cAAc,CAAC;AAE9C,QAAA,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,wBAAwB,CAAC;aACpD,IAAI,CACHD,QAAM,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,OAAO,CAAC,EAC1DF,KAAG,CAAC,MAAM,SAAS,CAAC,CACrB,CAAC;KACL;IAEO,YAAY,GAAA;QAClB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;KACrC;;;IAIO,WAAW,GAAA;AACjB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AACnC,QAAA,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAE/E,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC;AACzD,YAAA,IAAI,gBAAgB,EAAE,MAAM,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;AACzD,YAAA,IAAI,SAAS,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;SACpC,CAAC;KACH;wGA7HU,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECjEnC,ouDA6CA,EAAA,MAAA,EAAA,CAAA,kLAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDaI,eAAe,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,WAAA,EAAA,OAAA,EAAA,YAAA,EAAA,WAAA,EAAA,eAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACf,mBAAmB,EAAA,QAAA,EAAA,cAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACnB,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,YAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,cAAA,EAAA,UAAA,EAAA,WAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,UAAA,EAAA,OAAA,EAAA,MAAA,EAAA,SAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,sBAAsB,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,SAAA,EAAA,oBAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EACtB,kBAAkB,EAAA,IAAA,EAAA,kBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGT,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAdlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,2BAA2B,mBAGpB,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,eAAe;wBACf,mBAAmB;wBACnB,kBAAkB;wBAClB,sBAAsB;wBACtB,kBAAkB;AACnB,qBAAA,EAAA,QAAA,EAAA,ouDAAA,EAAA,MAAA,EAAA,CAAA,kLAAA,CAAA,EAAA,CAAA;;;AE1DH;AACA;AACA;AACA;MAQa,kBAAkB,CAAA;AAEb,IAAA,MAAM,GAAG,KAAK,CAAoB,EAAE,CAAC,CAAC;AACtC,IAAA,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AAEvB,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;wGALpF,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,4VChB/B,sjBAuBA,EAAA,MAAA,EAAA,CAAA,+iBAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FDPa,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,6BAA6B,EAGtB,eAAA,EAAA,uBAAuB,CAAC,MAAM,cACnC,IAAI,EAAA,QAAA,EAAA,sjBAAA,EAAA,MAAA,EAAA,CAAA,+iBAAA,CAAA,EAAA,CAAA;;;AEIlB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAoBa,qBAAqB,CAAA;AAEhB,IAAA,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAmB,CAAC;AAC9C,IAAA,IAAI,GAAG,KAAK,CAAuB,IAAI,CAAC,CAAC;;;IAIzC,SAAS,GAAG,MAAM,EAAmB,CAAC;IAEtC,cAAc,GAAG,cAAc,CAAC;AAEhC,IAAA,MAAM,GAAG;QACvB,SAAS,EAAE,CAAG,EAAA,0BAA0B,CAAI,EAAA,CAAA;AAC5C,QAAA,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,IAAI,wBAAwB,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAE,CAAA;QAC/D,GAAG,EAAE,IAAI,wBAAwB,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAE,CAAA;QAC7D,OAAO,EAAE,IAAI,wBAAwB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAE,CAAA;QACrE,SAAS,EAAE,CAAI,CAAA,EAAA,0BAA0B,CAAE,CAAA;KAC5C,CAAC;;;;IAKc,IAAI,GAAG,QAAQ,CAAC,MAAM,WAAW,EAC9C,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,IAAI,EAAE,GAC9B,IAAI,CAAC,IAAI,EAAE,EACX,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,CACtF,CAAC,CAAC;;;IAIa,OAAO,GAAG,QAAQ,CAAC,MAAM,kBAAkB,CACzD,IAAI,CAAC,IAAI,EAAE,EACX,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,EAC5F,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAC7C,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAEG,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAE1D,IAAA,YAAY,CAAC,KAAiB,EAAA;QACnC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;KACzE;wGAzCU,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,EClDlC,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,+BAAA,EAAA,kBAAA,EAAA,iCAAA,EAAA,aAAA,EAAA,iCAAA,EAAA,aAAA,EAAA,gCAAA,EAAA,YAAA,EAAA,oCAAA,EAAA,gBAAA,EAAA,sCAAA,EAAA,kBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,2lEAoEA,ED9BI,MAAA,EAAA,CAAA,25CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,sBAAsB,wIACtB,kBAAkB,EAAA,QAAA,EAAA,6BAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,SAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAWT,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAnBjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,0BAA0B,mBAGnB,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,sBAAsB;wBACtB,kBAAkB;qBACnB,EACK,IAAA,EAAA;AACJ,wBAAA,iCAAiC,EAAE,kBAAkB;AACrD,wBAAA,mCAAmC,EAAE,aAAa;AAClD,wBAAA,mCAAmC,EAAE,aAAa;AAClD,wBAAA,kCAAkC,EAAE,YAAY;AAChD,wBAAA,sCAAsC,EAAE,gBAAgB;AACxD,wBAAA,wCAAwC,EAAE,kBAAkB;AAC7D,qBAAA,EAAA,QAAA,EAAA,2lEAAA,EAAA,MAAA,EAAA,CAAA,25CAAA,CAAA,EAAA,CAAA;;;AE1CH;AACA;AACA;AACA;MAKa,cAAc,CAAA;AAElB,IAAA,SAAS,CAAC,KAAc,EAAE,QAAgB,EAAE,MAAuB,EAAA;QACxE,OAAO,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;KAClD;wGAJU,cAAc,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;sGAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,cAAA,EAAA,CAAA,CAAA;;4FAAd,cAAc,EAAA,UAAA,EAAA,CAAA;kBAJ1B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,cAAc;AACpB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAA;;;ACPD;AACA;AACA;AACA;MAKa,gBAAgB,CAAA;AAEpB,IAAA,SAAS,CAAC,KAAc,EAAE,MAAwB,EAAE,OAA4B,EAAA;AACrF,QAAA,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE;AAC3B,YAAA,OAAO,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;SAC5D;AAED,QAAA,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;KACnE;wGARU,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;sGAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,gBAAA,EAAA,CAAA,CAAA;;4FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAJ5B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,gBAAgB;AACtB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAA;;;ACND;AACA;AACA;AACA;AACA;MAKa,gBAAgB,CAAA;AAEpB,IAAA,SAAS,CACd,GAA+C,EAC/C,MAAkB,EAClB,MAAwB,EACxB,OAA4B,EAAA;AAE5B,QAAA,OAAO,iBAAiB,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;YAC7E,WAAW,EAAE,MAAM,CAAC,WAAW;AAC/B,YAAA,KAAK,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,SAAS;YACpE,KAAK,EAAE,MAAM,CAAC,KAAK;AACnB,YAAA,KAAK,EAAE,EAAE;AACV,SAAA,CAAC,CAAC;KACJ;wGAdU,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;sGAAhB,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,IAAA,EAAA,gBAAA,EAAA,CAAA,CAAA;;4FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAJ5B,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,gBAAgB;AACtB,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAA;;;ACuCD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAiBa,sBAAsB,CAAA;AAEjB,IAAA,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAU,CAAC;AACpC,IAAA,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAmB,CAAC;AAE9C,IAAA,aAAa,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;AAEpD,IAAA,UAAU,CAAe;;;;;;;AAQzB,IAAA,OAAO,GAAG,MAAM,CAAwC,EAAE,CAAC,CAAC;;;;AAK5D,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;;;;;AAQxB,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;;AAKjB,IAAA,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;AAIzC,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;AAI3B,IAAA,MAAM,GAAG,MAAM,CAAiC,IAAI,CAAC,CAAC;AAEtD,IAAA,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;AAKzC,IAAA,QAAQ,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;;;AAIlD,IAAA,QAAQ,GAAG,MAAM,CAA0C,IAAI,CAAC,CAAC;;;;AAKjE,IAAA,QAAQ,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC;;;;AAKrD,IAAA,aAAa,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC,aAAa,CAAC;IAE/D,sBAAsB,GAAG,sBAAsB,CAAC;;AAGhD,IAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpE,aAAa,GAAG,aAAa,CAAC;;;;IAK9B,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvF,UAAU,GAAG,gBAAgB,CAAC;;;AAI9B,IAAA,aAAa,GAAG,QAAQ,CAAmC,MAAM,iBAAiB,CAChG,IAAI,CAAC,OAAO,EAAE,EACd,IAAI,CAAC,QAAQ,EAAE,EACd,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,IAAI,EAAE,EAAiB,OAAO,IAAI,EAAE,CAC9D,CAAC,CAAC;;;AAIa,IAAA,WAAW,GAAG,QAAQ,CAAyB,MAAK;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC;AAE3C,QAAA,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE;aACrC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AACjG,KAAC,CAAC,CAAC;;;AAIa,IAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAM,qBAAqB,CACtE,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EACpE,IAAI,CAAC,MAAM,EAAE,CACd,CAAC,CAAC;;;;AAKa,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACtC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC;QAC3C,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,KAAK,EAAE;YACT,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACrD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;AAClC,kBAAE,CAAA,QAAA,EAAW,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAO,IAAA,EAAA,KAAK,CAAE,CAAA;AACjE,kBAAE,CAAA,EAAG,KAAK,CAAA,OAAA,CAAS,CAAC,CAAC;SACxB;AAED,QAAA,OAAO,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;aACpD,MAAM,CAAC,CAAC,IAAI,KAAqB,CAAC,CAAC,IAAI,CAAC;aACxC,IAAI,CAAC,KAAK,CAAC,CAAC;AACjB,KAAC,CAAC,CAAC;AAEK,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,WAAW,GAAG,MAAM,CAA0B,UAAU,CAAC,CAAC;AAC1D,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,cAAc,GAA0B,IAAI,CAAC;AAErD,IAAA,WAAA,GAAA;;QAEE,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,SAAS,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAC9C,SAAC,CAAC,CAAC;KACJ;IAEM,QAAQ,GAAA;AACb,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,MAAM,MAAM,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,CAAe,CAAC;AACtD,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAC5C,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5G,QAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;;;;QAK1B,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;aAC9F,IAAI,CACHG,KAAG,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,EACzC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;AAEO,IAAA,eAAe,CAAC,MAAkB,EAAA;;;;;AAKxC,QAAA,MAAM,IAAI,GAA2B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;AAC/E,eAAA,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9B,IAAI,CAAC,UAAU,GAAG;;;AAGhB,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,MAAM,EAAE,KAAK;;;;AAIb,YAAA,UAAU,EAAE,KAAK;AACjB,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,IAAI,EAAE,IAAI;AACR,kBAAE,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,EAAE;AAC5D,kBAAE,SAAS;;;;;;;;;;;AAWb,YAAA,MAAM,EAAE;AACN,gBAAA,KAAK,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;gBAC5B,QAAQ,EAAE,kBAAkB,CAAC,MAAM;AACpC,aAAA;AACD,YAAA,QAAQ,EAAE;AACR,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,KAAK,EAAE,WAAW;AAClB,gBAAA,UAAU,EAAE,SAAS;AACtB,aAAA;YACD,KAAK,EAAE,CAAC,KAAU,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;SAC1C,CAAC;KACH;AAEO,IAAA,MAAM,CAAC,KAAU,EAAA;;;;AAIvB,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;AACnC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI;gBACjB,KAAK,CAAC,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1E,QAAA,MAAM,KAAK,GAAuB;YAChC,IAAI;YACJ,QAAQ;SACT,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QACxC,IAAI,KAAK,EAAE;AACT,YAAA,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,MAAM,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC;SAC3E;AAED,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AACnC,QAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAE7D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1D,IAAI,MAAM,EAAE;AACV,YAAA,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;SACvB;;;AAID,QAAA,MAAM,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,gBAAgB,EAAE;AACpB,YAAA,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;SAC3C;;;QAID,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAEjE,OAAO,IAAI,CAAC,WAAW;AACpB,aAAA,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC;AAC5D,aAAA,IAAI,CACHH,KAAG,CAAC,CAAC,IAAmB,KAAI;;;;AAI1B,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;AAClB,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aACtC;;;AAID,YAAA,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE;gBACpB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;gBAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;gBACrC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;AAC7C,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AACxC,gBAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;aAChC;;;YAID,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC;YACrD,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;AACjE,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;;YAGjE,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE3B,OAAO;AACL,gBAAA,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;AACrB,gBAAA,MAAM,EAAE;oBACN,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC,QAAQ;AAC9C,oBAAA,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC;oBACvD,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,KAAK,CAAC,IAAI;AACtC,iBAAA;aACF,CAAC;SACH,CAAC,CACH,CAAC;KACL;;;;;AAMO,IAAA,aAAa,CAAC,IAAmB,EAAA;AACvC,QAAA,MAAM,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,IAAI,EAAE,CAAe,CAAC;AAC7D,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAC/C,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAC3D,IAAI,EACJ,EAAE,CACH,CAAC,CAAC;AAEH,QAAA,OAAO,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC;AAC/D,aAAA,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;KACrG;AAEO,IAAA,SAAS,CAAC,IAAmB,EAAA;QACnC,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;KACH;;;;;;AAOO,IAAA,mBAAmB,CAAC,IAAmB,EAAA;QAC7C,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACnC,OAAO;SACR;AAED,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM;AACvC,YAAA,GAAG,MAAM;AACT,YAAA,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AAClE,SAAA,CAAC,CAAC,CAAC;QAEJ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE;AAC9E,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC3B;KACF;;;IAIO,kBAAkB,GAAA;AACxB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE;YAC9D,OAAO;SACR;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACtE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;KACzD;;;;IAKO,mBAAmB,GAAA;QACzB,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE;YAC5C,OAAO;SACR;AAED,QAAA,IAAI,CAAC,cAAc,GAAG,eAAe,CAAC,MAAK;AACzC,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;SAC1B,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;KAClC;;;;;IAMO,iBAAiB,GAAA;AACvB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC;QAC5C,IAAI,IAAI,GAAG,CAAC,CAAC;AAEb,QAAA,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE;YAClD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAc,CAAuB,oBAAA,EAAA,KAAK,CAAE,CAAA,CAAC,CAAC;YAE/E,IAAI,CAAC,MAAM,EAAE;gBACX,SAAS;aACV;AAED,YAAA,MAAM,IAAI,GAAG,CAAqB,kBAAA,EAAA,KAAK,EAAE,CAAC;AAC1C,YAAA,MAAM,KAAK,GAAG,CAAG,EAAA,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC;YAElD,IAAI,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;gBAC/C,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;aACrC;AAED,YAAA,IAAI,IAAI,MAAM,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;SAC9C;KACF;wGA7XU,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,mZAKS,eAAe,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECtF3D,+5IAqHA,EAAA,MAAA,EAAA,CAAA,88DAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED7CI,sBAAsB,EACtB,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,SAAA,EAAA,oBAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAjB,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,MAAA,EAAA,cAAA,EAAA,UAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,OAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,OAAA,EAAA,YAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,UAAU,iRACV,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,kBAAA,EAAA,0BAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAChB,cAAc,EACd,IAAA,EAAA,cAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,gBAAgB,kDAChB,gBAAgB,EAAA,IAAA,EAAA,gBAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGP,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBAhBlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,2BAA2B,mBAGpB,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,sBAAsB;wBACtB,YAAY;wBACZ,UAAU;wBACV,gBAAgB;wBAChB,cAAc;wBACd,gBAAgB;wBAChB,gBAAgB;AACjB,qBAAA,EAAA,QAAA,EAAA,+5IAAA,EAAA,MAAA,EAAA,CAAA,88DAAA,CAAA,EAAA,CAAA;;;AEvEH;AACA;AACA;AACA;AACA,MAAM,cAAc,GAAG,iBAAiB,CAAC;AACzC,MAAM,aAAa,GAAG,gBAAgB,CAAC;AACvC,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;AAC/C,MAAM,aAAa,GAAG,CAAI,CAAA,EAAA,aAAa,GAAG,CAAC;AAC3C,MAAM,UAAU,GAAG,OAAO,CAAC;AAE3B;AACA;AACA;AACA,MAAM,eAAe,GAAG,kBAAkB,CAAC;AAC3C,MAAM,cAAc,GAAG,CAAI,CAAA,EAAA,eAAe,GAAG,CAAC;AAC9C,MAAM,UAAU,GAAG,OAAO,CAAC;AAE3B;AACA,MAAM,cAAc,GAAG,CAAA,EAAG,aAAa,CAAK,EAAA,EAAA,cAAc,EAAE,CAAC;AAE7D;AACA;AACA,MAAM,UAAU,GAAG,qCAAqC,CAAC;AAEzD;AACO,MAAM,sBAAsB,GAAG;AACpC,IAAA,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB;CACrF,CAAC;AAEF;AACA,MAAM,sBAAsB,GAAG,mBAAmB,CAAC;AAEnD;AACA,MAAM,KAAK,GAAe,CAAC,EAAE,SAAS,EAAE,mBAAmB,EAAE,EAAE,EAAE,SAAS,EAAE,uBAAuB,EAAE,CAAC,CAAC;AACvG,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;AACA;AACA,MAAM,qBAAqB,GAAG,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAC7D,MAAM,eAAe,GAAG,YAAY,CAAC;AACrC,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAClE,MAAM,IAAI,GAAG,QAAQ,CAAC;AAEtB;AACA,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C;AACA,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAEtE;AACA,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAoE1C;AACA,SAAS,SAAS,CAAC,IAAa,EAAA;AAC9B,IAAA,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC;UACrC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;UAC9C,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,MAAO,gBAAiB,SAAQ,MAAM,CAAA;;IAMlC,OAAO,GAAQ,IAAI,CAAC;;IAEpB,SAAS,GAAG,KAAK,CAAC;;;IAGlB,aAAa,GAA8B,EAAE,CAAC;;IAE9C,WAAW,GAAG,EAAE,CAAC;;;IAGjB,OAAO,GAA+B,IAAI,CAAC;AAEnD,IAAA,WAAA,CAAY,MAA8B,EAAA;AACxC,QAAA,KAAK,EAAE,CAAC;AACR,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;KACtB;IAEM,UAAU,GAAA;AACf,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;YAChD,OAAO;SACR;AAED,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAC3B,QAAA,MAAM,EAAE,GAAgB,MAAM,CAAC,EAAE,CAAC;AAClC,QAAA,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;AAEtB,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AACpD,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3D,QAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAC5B,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,IAAY,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;;;QAGrE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,KAAoB,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC;QACpF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,KAAqB,KAAI;AACzD,YAAA,IAAI,CAAC,WAAW,GAAG,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AAEnE,YAAA,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AACrC,SAAC,CAAC,CAAC;;;;AAIH,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,KAAa,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;;;QAGrG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAK;AAC/B,YAAA,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE;gBAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;aAChB;AACH,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,GAAG;AACnB,YAAA,CAAC,aAAa,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,KAAmB,CAAC,CAAC;AACpE,YAAA,CAAC,KAAK,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,CAAC,KAAuB,CAAC,CAAC;AACxD,YAAA,CAAC,WAAW,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AACrD,YAAA,CAAC,MAAM,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,KAAuB,CAAC,CAAC;AAC1D,YAAA,CAAC,OAAO,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAmB,CAAC,CAAC;SACzD,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;QAE5F,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC,SAAS,EAAE,CAAC;KAClB;IAEM,OAAO,GAAA;AACZ,QAAA,MAAM,EAAE,GAA4B,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAChG,QAAA,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;AACxB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;KACrB;;;IAIM,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACnD,QAAA,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;KAClB;;;;;;AAOM,IAAA,MAAM,CAAC,KAAa,EAAA;QACzB,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACzC,QAAA,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;AAC1D,QAAA,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE;YACV,OAAO;SACR;;;;;;;;;QAUD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACvC,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;AAClC,QAAA,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACpB,QAAA,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAErB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AACpC,QAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;AACvB,YAAA,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC5B,SAAS,CAAC,eAAe,EAAE,CAAC;AAC5B,YAAA,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC7B,YAAA,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;SACjC;;AAGD,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACrC,QAAA,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAC1B,QAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrB,SAAS,CAAC,eAAe,EAAE,CAAC;AAC5B,QAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KAC3B;;;IAIM,WAAW,GAAA;AAChB,QAAA,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;KACzC;;;IAIM,IAAI,GAAA;AACT,QAAA,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;KAC/B;;AAGM,IAAA,SAAS,CAAC,GAAW,EAAA;QAC1B,IAAI,CAAC,MAAM,EAAE;AACV,aAAA,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC;AAC1D,aAAA,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;KACzC;;AAGM,IAAA,MAAM,CAAC,IAAiB,EAAA;AAC7B,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YACpC,OAAO;SACR;;;;AAKD,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AACrC,QAAA,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AAC3B,QAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAErB,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;AACxB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,SAAS,CAAC,eAAe,EAAE,CAAC;AAC5B,QAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;KACjB;IAEO,MAAM,GAAA;QACZ,OAAO,IAAI,CAAC,OAAO;AACjB,cAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;cAC3D,EAAE,CAAC;KACR;IAEO,WAAW,GAAA;QACjB,OAAO,IAAI,CAAC,OAAO;AACjB,cAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;cAC5D,EAAE,CAAC;KACR;;;;;;IAOO,SAAS,GAAA;AACf,QAAA,MAAM,OAAO,GAA4B,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACnE,QAAA,MAAM,MAAM,GAAG,OAAO,EAAE,aAAa,CAAC,CAA0B,uBAAA,EAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAA,EAAA,CAAI,CAAC,CAAC;QAC9F,MAAM,IAAI,GAAG,MAAM;AACjB,cAAE,OAAO,CAAC,aAAa,CAAC,CAAQ,KAAA,EAAA,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAM,GAAA,EAAA,sBAAsB,EAAE,CAAC;cACjG,IAAI,CAAC;QACT,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;AAED,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC3F;;;AAIO,IAAA,SAAS,CAAC,KAAqB,EAAA;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;AAC3C,QAAA,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC;AAChC,QAAA,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;AACrB,QAAA,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACtC,QAAA,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAChD,QAAA,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;QAEhC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAEpB,QAAA,OAAO,IAAI,CAAC;KACb;;IAGO,WAAW,GAAA;AACjB,QAAA,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,KAAI;YAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;AAC7C,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9C,SAAC,CAAC,CAAC;AAEH,QAAA,OAAO,MAAM,CAAC;KACf;;;AAIO,IAAA,cAAc,CAAC,MAAkC,EAAA;QACvD,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAC5B,OAAO;SACR;AAED,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;AACrD,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AAClB,gBAAA,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;AAC1B,gBAAA,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;AACxB,gBAAA,IAAI,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE;AACxB,aAAA,CAAC,CAAC;SACJ;KACF;;;;;AAMO,IAAA,cAAc,CAAC,MAAW,EAAA;AAChC,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,OAAe,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,MAAK;YACtC,IAAI,CAAC,QAAQ,EAAE,CAAC;AAChB,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAClC,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;AACtB,SAAC,CAAC,CAAC;;;;;AAKH,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;AACzD,QAAA,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;KAC1D;;;;AAKO,IAAA,gBAAgB,CAAC,OAAe,EAAA;AACtC,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;AAEtB,QAAA,IAAI,qBAAqB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;AAC7E,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,wEAAwE,CAAC,CAAC;AAE9F,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AAC1D,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,kFAAkF,CAAC,CAAC;AAExG,YAAA,OAAO,KAAK,CAAC;SACd;QAED,IAAI,CAAC,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;;;QAG9E,IAAI,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;SACrB;KACF;;;AAIO,IAAA,QAAQ,CAAC,QAAgB,EAAA;AAC/B,QAAA,MAAM,SAAS,GAAmB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,OAAO,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC;AAEhG,QAAA,OAAO,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;KAC3D;;;;;IAMO,QAAQ,CAAC,MAAM,GAAG,KAAK,EAAA;AAC7B,QAAA,MAAM,EAAE,GAA4B,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,EAAE;YACP,OAAO;SACR;AAED,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;QACnE,MAAM,KAAK,GAAW,EAAE,CAAC;AACzB,QAAA,OAAO,MAAM,CAAC,QAAQ,EAAE,EAAE;AACxB,YAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAmB,CAAC;AACxC,YAAA,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE;AAC5E,gBAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAClB;SACF;AAED,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;KACxD;AAEO,IAAA,YAAY,CAAC,GAAW,EAAA;QAC9B,OAAO,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;KAChF;IAEO,UAAU,CAAC,IAAU,EAAE,MAAe,EAAA;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5C,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAClB,OAAO;SACR;;;AAID,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;AACnD,QAAA,MAAM,UAAU,GAAG,CAAC,KAAa,KAAI;YACnC,IAAI,KAAK,EAAE;AACT,gBAAA,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aACxB;AACH,SAAC,CAAC;QACF,IAAI,QAAQ,GAAG,CAAC,CAAC;AACjB,QAAA,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACvB,YAAA,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YACnD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC5C,IAAI,IAAI,EAAE;AACR,gBAAA,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aACvB;YACD,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;AACxC,SAAC,CAAC,CAAC;QACH,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;AAEtC,QAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;KAC5B;;AAGO,IAAA,YAAY,CAAC,IAAY,EAAA;AAC/B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,KAAK,MAAkB;YACpF,KAAK,EAAE,KAAK,CAAC,KAAK;AAClB,YAAA,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;AACvB,YAAA,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;AAC5B,SAAA,CAAC,CAAC,CAAC;AACJ,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC,KAAK,MAAkB;YACpF,KAAK,EAAE,KAAK,CAAC,KAAK;AAClB,YAAA,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;AACvB,YAAA,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;AAC9B,SAAA,CAAC,CAAC,CAAC;QAEJ,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;KACjE;;IAGO,UAAU,CAAC,KAAiB,EAAE,MAAe,EAAA;AACnD,QAAA,IAAI,KAAK,CAAC,KAAK,EAAE;YACf,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;SAC3C;QAED,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;KACrF;;IAGO,YAAY,GAAA;AAClB,QAAA,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KAChG;AAEO,IAAA,WAAW,CAAC,GAAW,EAAA;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAC5C,QAAA,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;AACtC,QAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAElB,QAAA,OAAO,IAAI,CAAC;KACb;;;;;AAMO,IAAA,MAAM,CAAC,IAAiB,EAAA;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;AAExC,QAAA,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK;AACvB,cAAE,GAAG;cACH,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,GAAGQ,WAAS,CAAC,KAAK,CAAC,CAAC;;;QAG5D,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC;KACjD;AAEO,IAAA,gBAAgB,CAAC,KAAa,EAAA;QACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAC5C,QAAA,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;AAC9C,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AAEvB,QAAA,OAAO,IAAI,CAAC;KACb;;;;;;;AAQO,IAAA,WAAW,CAAC,IAAiB,EAAA;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,IAAI,CAAC;AAE9E,QAAA,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI;AACtB,cAAE,KAAK;cACL,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC;QACvE,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,IAAI,IAAI,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC,CAAC;KAChD;;AAGO,IAAA,SAAS,CAAC,IAAY,EAAA;AAC5B,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;AACpE,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;AACpD,QAAA,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEvG,OAAO,QAAQ,CAAC,SAAS,CAAC;KAC3B;AAEO,IAAA,UAAU,CAAC,KAAoB,EAAA;;QAErC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;AACtC,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;SACvB;AAED,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC;;;;AAKrE,QAAA,IAAI,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;AAC1E,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,UAAU,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;AAE9C,YAAA,OAAO,SAAS,CAAC;SAClB;AAED,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,EAAE;YACV,OAAO;SACR;AAED,QAAA,IAAI,KAAK,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,QAAQ,EAAE;gBACb,OAAO;aACR;AAED,YAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,KAAK,WAAW,CAAC;YAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAEvD,YAAA,OAAO,IAAI;AACT,kBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;kBAChC,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;SAC7D;;;AAID,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAC1E,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC;AACpF,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE;YAC7D,OAAO;SACR;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEnC,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC;KACpE;;;AAIO,IAAA,cAAc,CAAC,KAAiB,EAAA;AACtC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC5B,QAAA,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE;YAC5B,OAAO;SACR;AAED,QAAA,IAAI,KAAK,CAAC,SAAS,EAAE;YACnB,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACtD,IAAI,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;gBACxC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC;gBACnG,IAAI,IAAI,EAAE;oBACR,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;iBAClC;aACF;YAED,OAAO;SACR;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnC,QAAA,IAAI,KAAK,CAAC,MAAM,EAAE;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;SAClC;KACF;;AAGO,IAAA,eAAe,CAAC,KAAY,EAAA;AAClC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE;YAC/C,OAAO;SACR;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEnC,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC;KACpE;;;;;AAMO,IAAA,oBAAoB,CAAC,KAAY,EAAE,QAAiB,EAAE,WAAmB,EAAA;QAC/E,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;YAC/C,OAAO;SACR;QAED,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;AACxB,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AAEzB,QAAA,OAAO,KAAK,CAAC;KACd;;;;AAKO,IAAA,MAAM,CAAC,KAAqB,EAAA;AAClC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE;YAC3G,OAAO;SACR;AAED,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC/B,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;KAC1B;;;;AAKO,IAAA,OAAO,CAAC,KAAqB,EAAA;AACnC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC5B,QAAA,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE;YACnG,OAAO;SACR;AAED,QAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KAChC;IAEO,WAAW,CAAC,KAAqB,EAAE,KAAY,EAAA;QACrD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;QACrC,MAAM,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE7F,QAAA,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;AAC3D,QAAA,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7D,KAAK,CAAC,cAAc,EAAE,CAAC;KACxB;;;;;;AAOO,IAAA,UAAU,CAAC,MAAmB,EAAA;AACpC,QAAA,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,yCAAyC,CAAC;AACjE,QAAA,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC7B,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;QAC9B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,QAAA,OAAO,IAAI,CAAC;KACb;AAEO,IAAA,QAAQ,CAAC,KAAiB,EAAA;QAChC,MAAM,IAAI,GAAI,KAAK,CAAC,MAAkB,EAAE,OAAO,GAAG,aAAa,CAAuB,CAAC;AACvF,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC7C,OAAO;SACR;QAED,KAAK,CAAC,cAAc,EAAE,CAAC;;;QAGvB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACvC,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC;KAC3D;AAEO,IAAA,OAAO,CAAC,KAAa,EAAA;QAC3B,OAAO,CAAC,CAAE,KAAK,EAAE,MAA8B,EAAE,OAAO,GAAG,aAAa,CAAC,CAAC;KAC3E;AAEO,IAAA,MAAM,CAAC,KAAY,EAAE,KAAoB,EAAE,KAAmB,EAAA;QACpE,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;AACxB,QAAA,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEvD,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YAClB,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,IAAI,KAAK,GAAG,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;AACtE,SAAA,CAAC,CAAC;AAEH,QAAA,OAAO,KAAK,CAAC;KACd;AAEO,IAAA,YAAY,CAAC,KAAY,EAAA;AAC/B,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,OAAO;SACR;AAED,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AACpC,QAAA,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QACxB,SAAS,CAAC,eAAe,EAAE,CAAC;AAC5B,QAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE1B,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC7B,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;;;AAGtB,QAAA,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AAC/B,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;KACjB;;;IAIO,QAAQ,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;KAC/C;IAEO,UAAU,GAAA;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;KACrD;;IAGO,MAAM,GAAA;AACZ,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC;AAC1D,QAAA,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE;AAC1B,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAEtC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,uBAAuB,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;KAC/E;;;;AAKO,IAAA,SAAS,CAAC,KAAY,EAAA;AAC5B,QAAA,MAAM,IAAI,GAAgB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;AAC1C,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;QAEjC,MAAM,KAAK,GAAG,KAAK,CAAC,cAAc,KAAK,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;AACxF,QAAA,IAAI,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;AAC7C,YAAA,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;SAC7D;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;AACvF,QAAA,IAAI,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAe,EAAE,IAAI,CAAC,CAAC;YACrD,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SAC9C;AAED,QAAA,OAAO,KAAK,CAAC;KACd;;;IAIO,UAAU,CAAC,KAAc,EAAE,IAAa,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,iBAAiB,CAAC;QAEtE,OAAO,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;KACzF;AAEO,IAAA,QAAQ,CAAC,KAAY,EAAA;AAC3B,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;KACnE;AAEO,IAAA,aAAa,CAAC,KAAY,EAAA;AAChC,QAAA,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;KACxE;;IAGO,aAAa,CAAC,QAAiB,EAAE,WAAmB,EAAA;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAEjD,QAAA,OAAO,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC;KACvD;;;;;IAMO,MAAM,CAAC,QAAiB,EAAE,WAAmB,EAAA;AACnD,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AAEnD,QAAA,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,EAAE,WAAW,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC;QAEjF,SAAS,CAAC,eAAe,EAAE,CAAC;AAC5B,QAAA,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE1B,QAAA,OAAO,KAAK,CAAC;KACd;;;AAIO,IAAA,YAAY,CAAC,KAAoB,EAAA;AACvC,QAAA,IAAI,KAAK,CAAC,OAAO,EAAE;AACjB,YAAA,OAAO,cAAc,CAAC;SACvB;AAED,QAAA,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;KAC7D;AACF;;AC92BD;AACA,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAExH;AACA,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAE1C;AACA;AACA;AACA;AACA;AACA,MAAM,YAAY,GAAG;IACnB,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACpF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CACrD,CAAC;AACF,MAAM,cAAc,GAAG;AACrB,IAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY;AACrH,IAAA,gBAAgB,EAAE,OAAO;CAC1B,CAAC;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB,GAAG;AAC3B,IAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa;AAC1G,IAAA,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,OAAO;AAC1D,IAAA,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc;IACtG,QAAQ,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa;IAC1G,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa;CAC7E,CAAC;AAEF;AACA;AACA;AACA,MAAM,aAAa,GAAG,2FAA2F,CAAC;AAElH;AACA,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAExC;AACA,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAwBnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MA+Ba,sBAAsB,CAAA;;;;AAKjB,IAAA,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;AACjB,IAAA,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAoB,CAAC;AAC5C,IAAA,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;;AAGvB,IAAA,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;;;;;IAMxB,cAAc,GAAG,KAAK,CAA4B,MAAM,aAAa,CAAC,CAAC;;IAGvE,KAAK,GAAG,MAAM,EAAU,CAAC;;;IAIzB,SAAS,GAAG,MAAM,EAAQ,CAAC;;;;IAK3B,aAAa,GAAG,MAAM,EAAU,CAAC;AAEjC,IAAA,SAAS,GAAG;QAC1B,IAAI,EAAE,CAAG,EAAA,iBAAiB,CAAI,EAAA,CAAA;AAC9B,QAAA,EAAE,EAAE,CAAG,EAAA,kBAAkB,CAAC,CAAC,CAAC,CAAI,EAAA,CAAA;AAChC,QAAA,EAAE,EAAE,CAAG,EAAA,kBAAkB,CAAC,CAAC,CAAC,CAAI,EAAA,CAAA;AAChC,QAAA,EAAE,EAAE,CAAG,EAAA,kBAAkB,CAAC,CAAC,CAAC,CAAI,EAAA,CAAA;AAChC,QAAA,KAAK,EAAE,kBAAkB;KAC1B,CAAC;AAEc,IAAA,SAAS,GAAG;AAC1B,QAAA,MAAM,EAAE,CAAA,EAAG,uBAAuB,CAAA,SAAA,EAAY,uBAAuB,CAAE,CAAA;QACvE,OAAO,EAAE,GAAG,uBAAuB,CAAC,QAAQ,CAAM,GAAA,EAAA,uBAAuB,CAAC,UAAU,CAAI,EAAA,CAAA;QACxF,MAAM,EAAE,CAAG,EAAA,iBAAiB,CAAI,EAAA,CAAA;KACjC,CAAC;;AAGc,IAAA,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;AAG/B,IAAA,MAAM,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;;AAGzC,IAAA,YAAY,GAAG,MAAM,CAA4B,IAAI,CAAC,CAAC;AACvD,IAAA,iBAAiB,GAAG,QAAQ,CAAmB,MAAK;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,CAAC;QAErC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC;AAC1D,KAAC,CAAC,CAAC;IAEa,WAAW,GAAG,IAAI,gBAAgB,CAAC;AACjD,QAAA,IAAI,EAAE,mBAAmB;QACzB,IAAI,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa;QACpC,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,IAAI,EAAE;AACxC,QAAA,KAAK,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC;AACpD,QAAA,MAAM,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE;AAC3B,QAAA,IAAI,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,mBAAmB,EAAE,EAAE;AACjF,QAAA,SAAS,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE;AACtC,QAAA,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC;AACvD,QAAA,OAAO,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QAChE,OAAO,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;AACpD,QAAA,OAAO,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE;AACnC,QAAA,OAAO,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC/D,KAAA,CAAC,CAAC;AAEa,IAAA,YAAY,GAAuB;AACjD,QAAA,QAAQ,EAAE,IAAI;AACd,QAAA,SAAS,EAAE,IAAI;AACf,QAAA,WAAW,EAAE,WAAW;AACxB,QAAA,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;AAC3B,QAAA,OAAO,EAAE;AACP,YAAA;AACE,gBAAA,IAAI,EAAE,mBAAmB;AACzB,gBAAA,KAAK,EAAE,cAAc;AACrB,gBAAA,MAAM,EAAE,MAAM;;;AAGd,gBAAA,OAAO,EAAE,EAAE;AACX,gBAAA,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC;AACzD,aAAA;AACD,YAAA;AACE,gBAAA,IAAI,EAAE,kBAAkB;AACxB,gBAAA,KAAK,EAAE,kBAAkB;AACzB,gBAAA,MAAM,EAAE,UAAU;AAClB,gBAAA,KAAK,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC;AAC3D,aAAA;AACF,SAAA;AACD,QAAA,YAAY,EAAE;AACZ,YAAA,cAAc,EAAE;gBACd,iBAAiB,EAAE,UAAU,EAAE,GAAG;gBAClC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG;AAChE,gBAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG;AACnD,gBAAA,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB;AACzE,aAAA;;;AAGD,YAAA,gBAAgB,EAAE;AAChB,gBAAA,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG;AAC9D,gBAAA,YAAY,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,0BAA0B;AAC1F,aAAA;AACD,YAAA,iBAAiB,EAAE,MAAM;;;;AAIzB,YAAA,YAAY,EAAE,KAAK;AACnB,YAAA,iBAAiB,EAAE,KAAK;AACxB,YAAA,eAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE;AACnF,YAAA,wBAAwB,EAAE,IAAI;AAC9B,YAAA,QAAQ,EAAE,UAAU;AACpB,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,iBAAiB,EAAE,IAAI;AACvB,YAAA,eAAe,EAAE,YAAY;AAC7B,YAAA,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,sBAAsB,CAAC;AACrG,YAAA,qBAAqB,EAAE,cAAc;AACrC,YAAA,uBAAuB,EAAE,oBAAoB;AAC7C,YAAA,cAAc,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;;;AAGnC,YAAA,UAAU,EAAE,KAAK;;AAEjB,YAAA,UAAU,EAAE,IAAI;;;AAGhB,YAAA,WAAW,EAAE,CAAC;AACf,SAAA;KACF,CAAC;IAEc,WAAW,GAAG,QAAQ,CAAW,MAAM,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAC5F,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAC3C,CAAC,CAAC;;;AAIa,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;AACtC,QAAA,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;AAE5E,QAAA,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AACnE,KAAC,CAAC,CAAC;;IAGI,KAAK,GAAG,EAAE,CAAC;AAED,IAAA,OAAO,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;IAC3C,mBAAmB,GAAG,SAAS,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAC5E,IAAA,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,IAAA,KAAK,GAA4B,MAAM,CAAC,UAAU,CAAC,CAAC;AACpD,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO,GAAG,KAAK,CAAC;IAChB,YAAY,GAAyC,IAAI,CAAC;AAElE,IAAA,WAAA,GAAA;;;QAGE,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAE/B,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AAC5B,oBAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;AACpB,oBAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;iBAC1B;AAAM,qBAAA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE;oBACnC,IAAI,CAAC,OAAO,EAAE,CAAC;iBAChB;AACH,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;;;QAIH,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;AAC9C,SAAC,CAAC,CAAC;;;;AAKH,QAAA,MAAM,OAAO,GAAG,CAAC,KAAmB,KAAK,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACtE,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACxD,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,MAAK;YAC9B,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,iBAAiB,EAAE,CAAC;AAC3B,SAAC,CAAC,CAAC;KACJ;AAEM,IAAA,SAAS,CAAC,KAAoB,EAAA;QACnC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;YAC5C,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,EAAE,CAAC;SACf;KACF;;AAGM,IAAA,WAAW,CAAC,GAAW,EAAA;AAC5B,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;KACjC;;;AAIM,IAAA,iBAAiB,CAAC,OAAqB,EAAA;QAC5C,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,GAAG,CAAC;AACrC,QAAA,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;AACtC,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAC9B;KACF;IAEM,sBAAsB,GAAA;AAC3B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC7B,QAAA,IAAI,MAAM,EAAE,IAAI,KAAK,SAAS,EAAE;AAC9B,YAAA,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC;SAClC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;KACtB;;IAGM,gBAAgB,GAAA;AACrB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC7B,QAAA,IAAI,MAAM,EAAE,IAAI,KAAK,QAAQ,EAAE;YAC7B,MAAM,CAAC,IAAI,EAAE,CAAC;SACf;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;KACtB;IAEM,aAAa,GAAA;QAClB,IAAI,CAAC,iBAAiB,EAAE,CAAC;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACvB;;;;IAKO,mBAAmB,GAAA;AACzB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE9B,OAAO;AACL,YAAA,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;AACrF,YAAA,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;SAC9G,CAAC;KACH;IAEO,iBAAiB,CAAC,GAAW,EAAE,IAAiB,EAAA;AACtD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;AACtC,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;AAC9C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;;AAE9C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;AAEvE,QAAA,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;AAC/B,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;YACpB,GAAG;YACH,IAAI;YACJ,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK;YAC7C,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,IAAI,KAAK;AAC1C,YAAA,KAAK,EAAE,QAAQ,CAAC,KAAK,GAAG,KAAK;AAC7B,YAAA,MAAM,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK;AAChC,SAAA,CAAC,CAAC;;;AAIH,QAAA,UAAU,CAAC,MAAM,IAAI,CAAC,mBAAmB,EAAE,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;KACrE;AAEO,IAAA,WAAW,CAAC,MAAkB,EAAA;QACpC,IAAI,CAAC,iBAAiB,EAAE,CAAC;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAC;KACpF;IAEO,iBAAiB,GAAA;AACvB,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACrB,YAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAChC,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;SAC1B;KACF;;;;;AAMO,IAAA,gBAAgB,CAAC,OAA0B,EAAA;QACjD,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC;AAC1C,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AACnE,QAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;AACjE,QAAA,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;AAEnF,QAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACb,YAAA,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;SACjE;KACF;AAEO,IAAA,gBAAgB,CAAC,KAAmB,EAAA;AAC1C,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;YACnB,OAAO;SACR;AAED,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAA4B,CAAC;QAClD,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE;YAC1F,OAAO;SACR;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;KACf;;;;;IAMO,MAAM,GAAA;QACZ,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,OAAO,EAAE,CAAC;AACf,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;KACvB;;IAGO,UAAU,GAAA;AAChB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACjD,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;AAC5B,YAAA,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;SACnB;KACF;IAEO,OAAO,GAAA;AACb,QAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,OAAO;SACR;AAED,QAAA,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SAC7B;KACF;wGArVU,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,swCAsJI,qBAAqB,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,qBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EACqB,UAAU,EC5S3F,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,++HAgHA,kpFDcI,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAR,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACX,SAAS,EACT,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,aAAa,6FACb,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,UAAU,EACV,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,qBAAqB,2FACrB,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,YAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,cAAA,EAAA,UAAA,EAAA,WAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,YAAA,EAAA,UAAA,EAAA,OAAA,EAAA,MAAA,EAAA,SAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAiBT,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA9BlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,2BAA2B,mBAGpB,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,SAAS;wBACT,aAAa;wBACb,OAAO;wBACP,UAAU;wBACV,qBAAqB;wBACrB,kBAAkB;qBACnB,EACK,IAAA,EAAA;AACJ,wBAAA,WAAW,EAAE,mBAAmB;;;AAGhC,wBAAA,qBAAqB,EAAE,gBAAgB;AACvC,wBAAA,wBAAwB,EAAE,cAAc;AACxC,wBAAA,wBAAwB,EAAE,cAAc;AACxC,wBAAA,wBAAwB,EAAE,cAAc;AACxC,wBAAA,sBAAsB,EAAE,iBAAiB;;AAEzC,wBAAA,6BAA6B,EAAE,kBAAkB;AACjD,wBAAA,8BAA8B,EAAE,mBAAmB;AACnD,wBAAA,6BAA6B,EAAE,kBAAkB;AAClD,qBAAA,EAAA,QAAA,EAAA,++HAAA,EAAA,MAAA,EAAA,CAAA,2lFAAA,CAAA,EAAA,CAAA;;;AE/EH;AACA,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAU,CAAC;AAGtE,MAAM,KAAK,GAAG,GAAG,CAAC;AAClB,MAAM,KAAK,GAAG,GAAG,CAAC;AAElB;AACA;AACA,MAAM,kBAAkB,GAAmC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE5E;AACA;AACA;AACA;AACA,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAqBa,wBAAwB,CAAA;AAEnB,IAAA,QAAQ,CAAS;AACjB,IAAA,SAAS,CAAuB;AAChC,IAAA,MAAM,CAAiC;IACvC,QAAQ,GAAG,KAAK,CAAC;;IAEjB,IAAI,GAAG,CAAC,CAAC;IACT,OAAO,GAAyB,IAAI,CAAC;IACrC,QAAQ,GAAG,KAAK,CAAC;AAEhB,IAAA,eAAe,GAAG,IAAI,YAAY,EAAU,CAAC;AAC7C,IAAA,eAAe,GAAG,IAAI,YAAY,EAAoD,CAAC;AACvF,IAAA,YAAY,GAAG,IAAI,YAAY,EAAwB,CAAC;;;;AAKzD,IAAA,MAAM,GAAG,KAAK,CAAmB,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;;;AAIlF,IAAA,kBAAkB,GAAG,KAAK,CAA+D,IAAI,CAAC,CAAC;;IAG/F,OAAO,GAAG,MAAM,EAAU,CAAC;;;IAI3B,aAAa,GAAG,MAAM,EAAU,CAAC;;;IAIjC,SAAS,GAAG,MAAM,EAAU,CAAC;;;IAI7B,aAAa,GAAG,MAAM,EAAY,CAAC;;;;AAKnC,IAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;AAG5B,IAAA,QAAQ,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;AAKvC,IAAA,cAAc,GAAG,MAC/B,IAAI,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,aAAa,CAAC;AAGxD,IAAA,cAAc,CAA0B;;;;AAK/C,IAAA,IAAW,aAAa,GAAA;AACtB,QAAA,OAAO,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;KAChD;;;;;;;AAQe,IAAA,YAAY,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;AAEjD,IAAA,IAAI,GAAG,MAAM,CAAuB,IAAI,CAAC,CAAC;;;;AAI1C,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACxB,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC3B,IAAA,KAAK,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;AAKpC,IAAA,cAAc,GAAG,MAAM,CAAoC,EAAE,CAAC,CAAC;;;IAI/D,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;;;;AAK/F,IAAA,WAAW,GAAG,QAAQ,CAAqB,MAAM,eAAe,CAAC;AAC/E,QAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACjB,QAAA,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE;AAClC,KAAA,CAAC,CAAC,CAAC;;AAGY,IAAA,eAAe,GAAG,MAAM,CAAqB,EAAE,CAAC,CAAC;IACjD,gBAAgB,GAAG,kBAAkB,CAAC;;;;;AAMtC,IAAA,WAAW,GAAG,QAAQ,CAAW,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;UAC7F,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;AAClG,UAAE,EAAE,CAAC,CAAC,CAAC;IACO,cAAc,GAAG,qBAAqB,CAAC;;;IAIvC,YAAY,GAAG,QAAQ,CAAC,MAAM,mBAAmB,CAC/D,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAClB,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAClC,IAAI,SAAS,CAAC,CAAC;AAGT,IAAA,QAAQ,CAAkB;AAG1B,IAAA,UAAU,CAA0B;AAE1B,IAAA,KAAK,GAAG,SAAS,CAAC,sBAAsB,CAAC,CAAC;AACnD,IAAA,SAAS,GAAG,IAAI,OAAO,EAAQ,CAAC;;AAEvB,IAAA,cAAc,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;;;AAIpC,IAAA,MAAM,GAAG,IAAI,GAAG,EAAmC,CAAC;AAC3C,IAAA,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACpC,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,cAAc,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AACpD,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5B,UAAU,GAAG,CAAC,CAAC;AACf,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACvB,IAAA,KAAK,GAA4B,MAAM,CAAC,UAAU,CAAC,CAAC;;;AAG3C,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAM,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;;;IAGtG,YAAY,GAAkB,IAAI,CAAC;IACnC,UAAU,GAA2B,IAAI,CAAC;;;IAG1C,WAAW,GAAG,KAAK,CAAC;IAErB,QAAQ,GAAA;QACb,IAAI,CAAC,kBAAkB,EAAE,CAAC;AAE1B,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,IAAI,CAAC,wBAAwB,EAAE,CAAC;SACjC;;;;QAKD,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;;;;YAIhG,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;iBAClF,IAAI,CACHoB,KAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EACrC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,iBAAA,SAAS,EAAE,CAAC;YAEf,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;AACzC,iBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;iBAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;;;AAI1C,YAAA,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;AAClC,gBAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE;AACjC,qBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;qBAC1C,SAAS,CAAC,MAAK;AACd,oBAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AACxB,oBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACxB,iBAAC,CAAC,CAAC;aACN;;YAGD,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9C,iBAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;iBAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;SAC3C;KACF;;;;;;AAOM,IAAA,WAAW,CAAC,OAAsB,EAAA;;;QAGvC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,MAAM,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;AAChF,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC7B;;QAGD,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;AACvD,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;SACzB;AAED,QAAA,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW;gBACrE,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAErD,IAAI,cAAc,EAAE;YAClB,IAAI,CAAC,kBAAkB,EAAE,CAAC;SAC3B;KACF;;;;;;;;;;;;;AAcD,IAAA,IAAW,SAAS,GAAA;QAClB,OAAO;YACL,IAAI,CAAC,cAAc,EAAE;YACrB,IAAI,CAAC,SAAS,CAAC,KAAK;YACpB,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAG,EAAA,KAAK,CAAC,EAAE,CAAA,CAAA,EAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC1E,IAAI,CAAC,aAAa,EAAE;AACrB,SAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KACb;;;;;;;;;AAUD,IAAA,IAAW,UAAU,GAAA;AACnB,QAAA,OAAO,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;KAC7D;AAED,IAAA,IAAW,MAAM,GAAA;AACf,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;KACvC;;IAGM,QAAQ,GAAA;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAClC,OAAO;SACR;QAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC7C,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAC5B;;AAGM,IAAA,WAAW,CAAC,GAAW,EAAA;QAC5B,IAAI,CAAC,KAAK,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC;KAChC;;;;;AAMM,IAAA,WAAW,CAAC,IAAY,EAAA;AAC7B,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACzE,aAAA,IAAI,CACHH,KAAG,CAAC,CAAC,QAAQ,MAAM,OAAO,QAAQ,EAAE,MAAM,EAAE,IAAI,KAAK,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAc,GAAG,IAAI,CAAC,CAAC,EACvGG,KAAG,CAAC,CAAC,MAAM,KAAI;AACb,YAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAC1B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC7B,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;IAIM,UAAU,GAAA;AACf,QAAA,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM;AAC9D,cAAE,8DAA8D;cAC9D,EAAE,CAAC;AAEP,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,SAAS;YAChB,QAAQ,EAAE,CAAmD,gDAAA,EAAA,UAAU,CAAE,CAAA;SAC1E,CAAC;AACC,aAAA,IAAI,CACHf,WAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EACnFe,KAAG,CAAC,CAAC,QAAsC,KAAI;AAC7C,YAAA,IAAI,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE;gBACnC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;aACjD;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;SACtC,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;AAED,IAAA,IAAW,SAAS,GAAA;QAClB,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC;KACjC;;;AAID,IAAA,IAAW,WAAW,GAAA;AACpB,QAAA,OAAO,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KAC5C;;;;;;AAOD,IAAA,IAAW,qBAAqB,GAAA;AAC9B,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAChB,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,EAAE,EAAE;AACjD,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;gBACpE,SAAS;aACV;AACD,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;AACpD,YAAA,IAAI,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,EAAE;AACpE,gBAAA,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;aACxB;SACF;QAED,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;KACvE;IAEM,QAAQ,GAAA;QACb,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KACxC;;;AAID,IAAA,IAAW,YAAY,GAAA;QACrB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;KAChG;;;;IAKM,aAAa,GAAA;AAClB,QAAA,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE;aAClD,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAEtF,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAwD,oBAAoB,EAAE;YAC7F,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE;AAClF,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,QAAQ,EAAE,MAAM;AAChB,YAAA,SAAS,EAAE,KAAK;SACjB,CAAC;AACC,aAAA,WAAW,EAAE;AACb,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;;YAEpB,IAAI,MAAM,EAAE;AACV,gBAAA,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;aAC/D;AACH,SAAC,CAAC,CAAC;KACN;;;;;;;;;;AAWM,IAAA,aAAa,CAAC,QAA2B,EAAA;AAC9C,QAAA,MAAM,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG;AAC7B,eAAA,CAAC,mBAAmB,CAAC,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,MAAmB,CAAC,CAAC,CAAC;QAE7F,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;AACtC,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,QAAQ,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,CAAC;QAEzG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,IAAI,WAAW,EAAE;AACf,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;SACvB;KACF;;;;;;;;;;IAWM,SAAS,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KACrB;;;IAIM,WAAW,GAAA;AAChB,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;KACtB;AAEO,IAAA,OAAO,CAAC,MAA0B,EAAA;AACxC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AAC3G,QAAA,MAAM,KAAK,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAChG,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;AAE9B,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CACpB,aAAa,KAAK,IAAI,WAAW,CAAA,CAAE,EACnC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC;AAClG,aAAA,IAAI,CACHA,KAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAC3EH,KAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CACtB,CACJ,CAAC;KACH;;;;;;AAOM,IAAA,WAAW,CAAC,KAAsB,EAAA;AACvC,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;SACR;QAED,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;AAC7F,QAAA,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;AACpE,QAAA,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC;AAErC,QAAA,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK,EAAE;AAC9B,YAAA,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;SACjD;AAAM,aAAA,IAAI,QAAQ,CAAC,OAAO,KAAK,MAAM,EAAE;YACtC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC7C;KACF;;;IAIM,UAAU,GAAA;AACf,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;KAC1B;;AAGM,IAAA,aAAa,CAAC,MAAwB,EAAA;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;AAC9B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;SACpC;KACF;;;;AAKM,IAAA,OAAO,CAAC,KAAa,EAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,OAAO;SACR;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;KAC3G;;IAGM,OAAO,GAAA;QACZ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;KAClF;;;AAIM,IAAA,aAAa,CAAC,KAAY,EAAA;QAC/B,KAAK,CAAC,eAAe,EAAE,CAAC;KACzB;AAEM,IAAA,sBAAsB,CAAC,KAAmB,EAAA;QAC/C,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACnC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;SAC9C;KACF;;AAIM,IAAA,WAAW,CAAC,KAAmB,EAAA;QACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACxC,OAAO;SACR;;AAGD,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC;AAC9D,YAAA,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YAEtB,IAAI,aAAa,EAAE;gBACjB,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAEhB,OAAO;aACR;SACF;QAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAI;YACpC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAE3D,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE;gBAChB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;aAC1D;AAED,YAAA,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;AACrB,YAAA,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC;YACrB,IAAI,CAAC,cAAc,EAAE,CAAC;SACvB,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;KAChC;IAEM,aAAa,CAAC,KAAmB,EAAE,MAAc,EAAA;AACtD,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YAClB,OAAO;SACR;QAED,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAE7C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAI;YACpC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAChC,YAAA,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;AAElC,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;aAC1C;AACD,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,gBAAA,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;aAC1C;AACD,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;gBACrD,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;gBAC7B,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;aAC9B;AACD,YAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;gBACrD,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;gBAC7B,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;aAC9B;YAED,IAAI,QAAQ,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9B,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE;AAChB,gBAAA,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;aACtE;YAED,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACxC,IAAI,CAAC,cAAc,EAAE,CAAC;AACtB,YAAA,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;SAC/B,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;KAChC;;;;;;;;;;;;;;;;AAiBO,IAAA,YAAY,CAAC,IAAY,EAAA;AAC/B,QAAA,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AAC3D,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACzB;IAEO,kBAAkB,GAAA;AACxB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC;AAC1C,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACpE,QAAA,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QACvG,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;AAE1C,QAAA,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QACvB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAClF,QAAA,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;AAC1D,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;;;;AAIpB,YAAA,UAAU,EAAE,KAAK;AACjB,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,KAAK,EAAE;AACL,gBAAA,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAClB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACtG,IAAI,UAAU,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACzF,aAAA;;;;AAID,YAAA,MAAM,EAAE,CAAC,KAAK,KAAI;AAChB,gBAAA,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;AAE7E,gBAAA,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;oBACnE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;iBAC5C;gBAED,IAAI,UAAU,EAAE;oBACd,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;iBAC7F;aACF;;;;YAID,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;;;;;;YAMrF,YAAY,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,wBAAwB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;AAChG,SAAA,CAAC,CAAC;KACJ;;;;;;;IAQO,wBAAwB,GAAA;QAC9B,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC;aACzC,IAAI,CACHF,QAAQ,CAAC,CAAC,OAAO,MAAM,OAAO,KAAK,IAAI;cACnC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,IAAI,CAAC,cAAc,EAAE;cAC1D,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EACpCK,KAAG,CAAC,MAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC,EACpC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;AAIO,IAAA,gBAAgB,CAAC,OAAe,EAAA;AACtC,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;eAC1B,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,KAAK,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;KAC9G;AAEO,IAAA,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;;;AAIrC,IAAA,MAAM,CACZ,KAAmB,EACnB,MAAgD,EAChD,KAAiB,EAAA;QAEjB,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,KAAK,CAAC,eAAe,EAAE,CAAC;AAExB,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;AAC3C,QAAA,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE1C,IAAI,CAAC,OAAO,GAAG;AACb,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;SACpB,CAAC;AACF,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;AAC7B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC;AAE7B,QAAA,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAK;YAChC,MAAM,IAAI,GAAG,CAAC,CAAe,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;YACjF,MAAM,GAAG,GAAG,MAAK;AACf,gBAAA,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAC9C,gBAAA,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChD,gBAAA,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAC7C,gBAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAEjD,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAK;AAClB,oBAAA,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;AACtB,oBAAA,KAAK,EAAE,CAAC;AACV,iBAAC,CAAC,CAAC;AACL,aAAC,CAAC;AAEF,YAAA,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAC7C,YAAA,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAC1C,YAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAChD,SAAC,CAAC,CAAC;KACJ;IAEO,aAAa,GAAA;AACnB,QAAA,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AACjD,QAAA,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAI,CAAC,cAAc,EAAE,CAAC;AACtB,QAAA,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;AAE9B,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;AACxB,YAAA,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE;AAC9B,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACnB,YAAA,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AACpB,SAAA,CAAC,CAAC;KACJ;;;;AAKD,IAAA,IAAY,WAAW,GAAA;AACrB,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,KAAK,KAAK,CAAC;KAC5C;;;AAID,IAAA,IACW,UAAU,GAAA;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;KACzB;;AAGO,IAAA,OAAO,CAAC,MAAc,EAAA;QAC5B,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;KAC3C;;AAGO,IAAA,MAAM,CAAC,KAAa,EAAA;QAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;KACtC;;;IAIO,cAAc,GAAA;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC;AAC7C,QAAA,KAAK,CAAC,IAAI,GAAG,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;AACnD,QAAA,KAAK,CAAC,GAAG,GAAG,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;AAClD,QAAA,KAAK,CAAC,KAAK,GAAG,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;;;;AAKpD,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;AACpB,YAAA,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;SACnB;aAAM;AACL,YAAA,KAAK,CAAC,MAAM,GAAG,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;SACtD;KACF;;;;IAMO,KAAK,GAAA;AACX,QAAA,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AAE3B,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AAC5B,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAErB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;;;;;AAKtE,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE1D,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;KACzF;;;;AAKO,IAAA,OAAO,CAAC,MAAqC,EAAA;QACnD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC7B,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACxB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAE3B,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE;AACxC,YAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SAC/B;KACF;;;;;;AAOO,IAAA,WAAW,CAAC,IAAmB,EAAA;AACrC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;AACpC,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;AAEzB,QAAA,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YACjF,OAAO;SACR;AAED,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;eAC5E,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE;AAC5C,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;SAC5C;KACF;;IAIO,cAAc,CAAC,MAAwB,EAAE,KAAsB,EAAA;AACrE,QAAA,IAAI,MAAM,KAAK,OAAO,EAAE;AACtB,YAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SACxB;KACF;;;AAIO,IAAA,UAAU,CAAC,KAAsB,EAAA;AACvC,QAAA,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAEtD,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;SACrD;KACF;;;IAIO,aAAa,CAAC,OAA2B,EAAE,KAAsB,EAAA;AACvE,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC;QAE9C,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;AACxB,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;KACpF;wGAh2BU,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,kBAAA,EAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,cAAA,EAAA,OAAA,EAAA,SAAA,EAAA,aAAA,EAAA,eAAA,EAAA,SAAA,EAAA,WAAA,EAAA,aAAA,EAAA,eAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,OAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EA0HA,sBAAsB,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EArE9C,uBAAuB,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,UAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,UAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,YAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvKpC,6/RAuPC,EAAA,MAAA,EAAA,CAAA,ggIAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDlJG,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,aAAa,EAAA,QAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,kBAAkB,EAAA,QAAA,EAAA,mCAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACV,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAApB,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,uBAAuB,EAAA,QAAA,EAAA,4BAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,gBAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,sBAAA,EAAA,WAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACvB,sBAAsB,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,qBAAqB,EAAA,QAAA,EAAA,0BAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,MAAA,CAAA,EAAA,OAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACrB,sBAAsB,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,sBAAsB,EAAA,QAAA,EAAA,2BAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,UAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,OAAA,EAAA,WAAA,EAAA,eAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGb,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBApBpC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,mBAGf,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,OAAO;wBACP,aAAa;wBACb,kBAAkB;wBAClB,UAAU;wBACV,cAAc;wBACd,YAAY;wBACZ,uBAAuB;wBACvB,sBAAsB;wBACtB,qBAAqB;wBACrB,sBAAsB;wBACtB,sBAAsB;AACvB,qBAAA,EAAA,QAAA,EAAA,6/RAAA,EAAA,MAAA,EAAA,CAAA,ggIAAA,CAAA,EAAA,CAAA;8BAIe,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBACU,SAAS,EAAA,CAAA;sBAAxB,KAAK;gBACU,MAAM,EAAA,CAAA;sBAArB,KAAK;gBACU,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBAEU,IAAI,EAAA,CAAA;sBAAnB,KAAK;gBACU,OAAO,EAAA,CAAA;sBAAtB,KAAK;gBACU,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBAEW,eAAe,EAAA,CAAA;sBAA/B,MAAM;gBACU,eAAe,EAAA,CAAA;sBAA/B,MAAM;gBACU,YAAY,EAAA,CAAA;sBAA5B,MAAM;gBAyCA,cAAc,EAAA,CAAA;sBADpB,SAAS;uBAAC,uBAAuB,CAAA;gBAgE3B,QAAQ,EAAA,CAAA;sBADd,SAAS;uBAAC,UAAU,CAAA;gBAId,UAAU,EAAA,CAAA;sBADhB,SAAS;uBAAC,YAAY,CAAA;gBAqnBZ,UAAU,EAAA,CAAA;sBADpB,WAAW;uBAAC,mBAAmB,CAAA;;;AEpzBlC;AACA;AACO,MAAM,WAAW,GAAG,EAAE,CAAC;AAgE9B;AACA;AACA,SAAS,UAAU,CAAC,CAAmB,EAAE,CAAmB,EAAA;AAC1D,IAAA,OAAO,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU;AAC/B,WAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ;AACzB,WAAA,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU;AAC7B,WAAA,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW;WAC/B,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;WAClC,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAKD;AACA,SAAS,cAAc,CAAC,OAAe,EAAE,MAAiB,EAAA;AACxD,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAgBa,qBAAqB,CAAA;AAEhB,IAAA,MAAM,CAAS;IACf,QAAQ,GAAG,KAAK,CAAC;;;;;IAMjB,MAAM,GAAkB,IAAI,CAAC;;;AAI5B,IAAA,iBAAiB,GAAG,IAAI,YAAY,EAAmB,CAAC;;;AAIxD,IAAA,aAAa,GAAG,IAAI,YAAY,EAAQ,CAAC;;;AAIzC,IAAA,WAAW,GAAG,IAAI,YAAY,EAAiB,CAAC;AAG1D,IAAA,OAAO,CAAqB;;;AAK3B,IAAA,mBAAmB,CAAsC;AAGzD,IAAA,SAAS,CAA6B;AAGtC,IAAA,OAAO,CAA6B;IAE5B,EAAE,GAAG,WAAW,CAAC;;;;;;AAOjB,IAAA,KAAK,GAAG,MAAM,CAAe,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC;AACzD,IAAA,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;AAChF,IAAA,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;AAGjB,IAAA,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACpC,IAAA,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;AACrC,IAAA,mBAAmB,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;AAGlD,IAAA,oBAAoB,GAAG,QAAQ,CAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAC/E,CAAC;IAEc,gBAAgB,GAAG,QAAQ,CACzC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CACjE,CAAC;;;;;;;;;;AAWc,IAAA,UAAU,GAAG,QAAQ,CACnC,MAAM,IAAI,CAAC,aAAa,CACtB,IAAI,CAAC,oBAAoB,EAAE,EAC3B,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,EAAE,EACnB,IAAI,CAAC,YAAY,EAAE,CACpB,EACD,EAAE,KAAK,EAAE,UAAU,EAAE,CACtB,CAAC;AAEc,IAAA,YAAY,GAAG,QAAQ,CACrC,MAAM,IAAI,CAAC,aAAa,CACtB,IAAI,CAAC,sBAAsB,EAAE,EAC7B,IAAI,CAAC,aAAa,EAClB,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI,EAClC,IAAI,CACL,EACD,EAAE,KAAK,EAAE,UAAU,EAAE,CACtB,CAAC;;AAGc,IAAA,OAAO,GAAkB;AACvC,QAAA,QAAQ,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9D,QAAA,UAAU,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC;AAC1F,QAAA,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;KACjC,CAAC;;;;;;AAOc,IAAA,kBAAkB,GAAG,CAAC,IAAqB,KAAyB;QAClF,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAEpF,OAAO,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE;AACpC,aAAA,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAC5E,aAAA,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAChE,KAAC,CAAC;AAEM,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,cAAc,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AACpD,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,GAAG,KAAK,CAAC;IAChB,kBAAkB,GAAG,CAAC,CAAC;IACvB,iBAAiB,GAAkB,IAAI,CAAC;;;;IAKxC,cAAc,GAAkB,IAAI,CAAC;;;IAIrC,cAAc,GAAkB,IAAI,CAAC;;;;;AAMrC,IAAA,OAAO,GAAG,MAAM,CAAgB,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC;;IAG9D,oBAAoB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;AAC1F,IAAA,sBAAsB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;;;AAI9E,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;;AAGrG,IAAA,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;AACtD,IAAA,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;;AAGpG,IAAA,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;;AAI5B,IAAA,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;;;;;;;AAS5B,IAAA,YAAY,GAAG,MAAM,CAAgD,IAAI,GAAG,EAAE,CAAC,CAAC;AAChF,IAAA,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;;;AAItC,IAAA,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;;;AAIrD,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAmB;QACjD,IAAI,CAAC,eAAe,EAAE,CAAC;AACvB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;AAE9B,QAAA,OAAO,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE;aAC/B,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC1C,aAAA,GAAG,CAAC,CAAC,KAAK,KAAgB;AACzB,YAAA,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YAE7D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC;AACvF,SAAC,CAAC;AACD,aAAA,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1C,KAAC,CAAC,CAAC;;;AAIK,IAAA,iBAAiB,GAAG,IAAI,GAAG,EAAuB,CAAC;AAE3D,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,KAAK,EAAE,CAAC;KACd;AAEM,IAAA,WAAW,CAAC,OAAsB,EAAA;;;QAGvC,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;AACtC,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAC5B;AAED,QAAA,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3F,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;;;QAIzC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC;AACzC,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,iBAAiB,CAAC;YACzC,QAAQ;YACR,gBAAgB,EAAE,IAAI,CAAC,iBAAiB;YACxC,iBAAiB,EAAE,IAAI,CAAC,kBAAkB;AAC1C,YAAA,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YAC5C,MAAM,EAAE,IAAI,CAAC,MAAM;AACnB,YAAA,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE;AACxC,SAAA,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;;;;;;QAOlC,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,IAAI,CAAC;AACjD,QAAA,IAAI,YAAY,KAAK,IAAI,CAAC,cAAc,EAAE;AACxC,YAAA,IAAI,CAAC,cAAc,GAAG,YAAY,CAAC;AACnC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SACrC;;;;;AAMD,QAAA,IAAI,OAAO,CAAC,MAAM,EAAE;YAClB,IAAI,CAAC,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1D,YAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,sBAAsB,EAAE,CAAC;AAC9B,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AACxC,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;SAC3C;KACF;;;AAID,IAAA,IAAW,aAAa,GAAA;AACtB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,oBAAoB,CAAC;AAElF,QAAA,OAAO,MAAM,IAAI,WAAW,GAAG,EAAE,CAAC,CAAC;KACpC;IAEM,eAAe,GAAA;;;QAGpB,UAAU,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAEjC,IAAI,CAAC,mBAAmB,CAAC,OAAO;AAC7B,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;KAC7C;AAED,IAAA,IAAW,UAAU,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,IAAI,CAAC;KACrD;;AAGD,IAAA,IAAW,KAAK,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,IAAI,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;KAClF;;;AAID,IAAA,IAAW,aAAa,GAAA;QACtB,OAAO,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC;KAC5D;;AAGD,IAAA,IAAW,aAAa,GAAA;QACtB,OAAO,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;KAC5C;AAED,IAAA,IAAW,eAAe,GAAA;QACxB,OAAO,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;KAC3C;IAEM,gBAAgB,GAAA;AACrB,QAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC;AAC1C,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KACpC;;;;IAKM,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO;SACR;QAED,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;AAClD,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;AACxC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;AAC1C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AAEnC,QAAA,IAAI,QAAQ,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,YAAY,GAAG,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;QACxF,IAAI,QAAQ,EAAE;AACZ,YAAA,MAAM,UAAU,GAAG,YAAY,IAAI,YAAY,IAAI,GAAG,CAAC;YACvD,MAAM,CAAC,GAAG,YAAY;kBAClB,UAAU,GAAG,YAAY;AAC3B,mBAAG,YAAY,GAAG,CAAC,GAAG,UAAU,GAAG,UAAU,CAAC,CAAC;AACjD,YAAA,QAAQ,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,GAAG,CAAC,EAAE,CAAC;SACvG;QAED,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;AACvC,YAAA,GAAG,QAAQ;AACX,YAAA,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE;SACnD,CAAC;AACC,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;KAC/C;;;AAIM,IAAA,WAAW,CAAC,IAAU,EAAA;AAC3B,QAAA,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAE7C,QAAA,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE;aAC5B,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,GAAG,MAAM,IAAI,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;KACjF;;;;IAKM,aAAa,CAAC,IAAU,EAAE,KAAiB,EAAA;AAChD,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;YACzB,OAAO;SACR;AAED,QAAA,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC7C,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QACxC,MAAM,IAAI,GAAI,KAAK,CAAC,aAA6B,CAAC,qBAAqB,EAAE,CAAC;AAC1E,QAAA,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;AACtE,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QAErC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;AACvC,YAAA,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC;YAC/C,CAAC,EAAE,GAAG,GAAG,IAAI;YACb,CAAC;AACD,YAAA,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC;SACrC,CAAC;AACC,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,IAAqB,KAAI;AACnC,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC;AAC9B,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AAC5B,SAAC,CAAC,CAAC;KACN;;;;;AAMM,IAAA,kBAAkB,CAAC,WAAmB,EAAA;AAC3C,QAAA,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AAC9E,QAAA,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE;YAC/B,MAAM,KAAK,GAAG,UAAU,EAAE,SAAS,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACvF,YAAA,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE;AACd,gBAAA,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;aAC7B;SACF;AAED,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;KACvC;;;;;IAMM,WAAW,CAAC,IAAqB,EAAE,IAAY,EAAA;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAC/C,QAAA,MAAM,KAAK,GAAG,QAAQ,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;AACnF,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;AAChC,QAAA,MAAM,IAAI,GAAG,OAAO,EAAE,MAAM,KAAK,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AAC/D,QAAA,MAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACtF,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AAChF,aAAA,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzC,IAAI,MAAM,EAAE;AACV,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SACtB;KACF;;;IAIM,iBAAiB,CAAC,IAAqB,EAAE,GAAW,EAAA;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;;QAE3G,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAE9E,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACpC;KACF;;;;AAKM,IAAA,eAAe,CAAC,SAA0B,EAAA;QAC/C,OAAO,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;KACrF;;AAGM,IAAA,kBAAkB,CAAC,IAAgB,EAAA;AACxC,QAAA,MAAM,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;AAExC,QAAA,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC;AACnE,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1C,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAC7B,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,YAAY,GAAG,qCAAqC,GAAG,oCAAoC,CAAC,CAAC;AACrH,SAAC,CAAC,CAAC;KACN;AAEM,IAAA,UAAU,CAAC,KAAa,EAAA;AAC7B,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAChC,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;;;QAInC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,IAAI,CAAC;QAClD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KAC5C;;;IAIM,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO;SACR;QAED,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACrC,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;KAC/C;IAEM,SAAS,CAAC,IAAgB,EAAE,KAAa,EAAA;QAC9C,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAA,CAAE,CAAC;KACzC;;;;;AAMM,IAAA,UAAU,CAAC,IAAgB,EAAA;AAChC,QAAA,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;AACjB,YAAA,KAAK,EAAE,gBAAgB;AACvB,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;AACxB,YAAA,WAAW,EAAE,MAAM;AACnB,YAAA,QAAQ,EAAE,IAAI;SACf,CAAC;aACC,IAAI,CACHI,WAAS,CAAC,CAAC,IAAY,KAAK,IAAI,CAAC,WAAW;AACzC,aAAA,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AAC7C,aAAA,IAAI,CAACY,KAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EACzB,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,IAAY,KAAI;AAC1B,YAAA,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAC7B,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAC3C,SAAC,CAAC,CAAC;KACN;;;;AAKM,IAAA,UAAU,CAAC,IAAgB,EAAA;AAChC,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,SAAS;AAChB,YAAA,QAAQ,EAAE,CAA0C,uCAAA,EAAA,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAyB,uBAAA,CAAA;SAC9H,CAAC;AACC,aAAA,IAAI,CACHZ,WAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EACrE,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAClC,YAAA,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACvB,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;;AAItB,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5D,YAAA,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAC;AACvC,YAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;;;AAInC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,IAAI,CAAC,CAAC;AAEnD,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AACxC,SAAC,CAAC,CAAC;KACN;;;;AAKM,IAAA,aAAa,CAAC,KAA2B,EAAA;QAC9C,IAAI,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY,EAAE;YAC9C,OAAO;SACR;AAED,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;AACnC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAE3B,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;AAChE,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEtB,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AAC1C,YAAA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YAEnB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;AACpC,SAAC,CAAC,CAAC;QAEH,IAAI,UAAU,EAAE;AACd,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;SACrD;AAED,QAAA,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC;AAC1D,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,EAAE,CAAC;KAChB;;;;;IAMM,sBAAsB,CAAC,WAAmB,EAAE,QAA2B,EAAA;AAC5E,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB;AACtC,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;QAE/D,IAAI,QAAQ,EAAE;AACZ,YAAA,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAEjC,OAAO;SACR;AAED,QAAA,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,oBAAoB,EAAE,EAAE,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;AAC7E,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;;QAGrD,IAAI,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACnC,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACpC,YAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,GAAG,CAAC,CAAC,CAAC;SACzD;KACF;AAEM,IAAA,eAAe,CAAC,WAA0B,EAAA;AAC/C,QAAA,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;KAC3C;IAEM,mBAAmB,GAAA;;AAExB,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;AACvC,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SAC5B;KACF;;AAIM,IAAA,QAAQ,CAAC,KAAa,EAAA;AAC3B,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;KACtB;IAEM,MAAM,GAAA;AACX,QAAA,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;KACxB;IAEM,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;KACzB;IAEM,OAAO,GAAA;AACZ,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC;AAC/C,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACzD,OAAO;SACR;AAED,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAClB,CAAC,QAAQ,CAAC,WAAW,GAAG,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,WAAW,CAAC,EACnE,CAAC,QAAQ,CAAC,YAAY,GAAG,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,WAAW,CAAC,CACtE,CAAC;QAEF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;KACrB;IAEM,UAAU,GAAA;AACf,QAAA,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;KACvB;;;AAKM,IAAA,iBAAiB,CAAC,QAA0D,EAAA;QACjF,IAAI,CAAC,YAAY,EAAE,CAAC;AACpB,QAAA,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,QAAe,CAAC,CAAC;AAC9D,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,EAAE,CAAC;KAChB;;;;;;;;IAUO,KAAK,GAAA;AACX,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AACrE,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,EAAE,CAAC;KAC1B;;;;;IAMO,aAAa,GAAA;AACnB,QAAA,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;AACxB,aAAA,IAAI,CACHY,KAAG,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAClC,oBAAoB,EAAE,EACtBG,KAAG,CAAC,MAAK;YACP,IAAI,CAAC,kBAAkB,EAAE,CAAC;AAC1B,YAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,GAAG,CAAC,CAAC,CAAC;SACzD,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;IAIO,gBAAgB,GAAA;AACtB,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,IAAI,EAAE;aACtD,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;KAC3E;;;;IAKO,kBAAkB,GAAA;QACxB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;AAC5E,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAClB,OAAO;SACR;AAED,QAAA,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,KAAI;AACrB,YAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACnB,YAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrC,SAAC,CAAC,CAAC;AACH,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;KAC/B;;;;;IAMO,iBAAiB,GAAA;AACvB,QAAA,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC;aAC5B,IAAI,CACH,QAAQ,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EACxFA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACnD,QAAQ,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAClC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAC7C,IAAI,CAAC,MAAM,EACX,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAC3D;AACE,aAAA,IAAI,CAACH,KAAG,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EACpDG,KAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EAC9F,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;AAEO,IAAA,WAAW,CAAC,MAA8C,EAAA;QAChE,OAAO;YACL,MAAM;YACN,OAAO,EAAE,IAAI,OAAO,EAAQ;AAC5B,YAAA,OAAO,EAAE,MAAM,CAAqB,IAAI,CAAC;AACzC,YAAA,OAAO,EAAE,MAAM,CAA4B,IAAI,CAAC;SACjD,CAAC;KACH;;;;;;;IAQO,YAAY,CAAC,KAAiB,EAAE,SAA8B,EAAA;AACpE,QAAA,KAAK,CACH,KAAK,CAAC,OAAO,EACb,SAAS,EACT,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAC3F,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,IAAI,CAC9B,YAAY,CAAC,GAAG,CAAC,EACjBL,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAC1C,CACF;aACE,IAAI,CACH,YAAY,CAAC,CAAC,CAAC,EACfE,KAAG,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAC7CG,KAAG,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAC5Cf,WAAS,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EACjDe,KAAG,CAAC,CAAC,MAAM,KAAI;AACb,YAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC1B,YAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;SACzB,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;;;AAMO,IAAA,gBAAgB,CAAC,KAAiB,EAAA;AACxC,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;AAC7B,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SACtB;KACF;;;AAIO,IAAA,aAAa,CAAC,KAAiB,EAAA;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;AAEhD,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,KAAK,IAAI,EAAE,SAAS,CAAC;KACzE;;;;;;;;;;AAWO,IAAA,aAAa,CAAC,KAAuC,EAAA;AAC3D,QAAA,MAAM,MAAM,GAAG,KAAK,EAAE,EAAE,IAAI,IAAI,CAAC;AACjC,QAAA,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC;AAChG,QAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM;AACpC,cAAE,sBAAsB,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;cACzE,EAAE,CAAC;QAEP,OAAO;YACL,MAAM;YACN,KAAK;YACL,OAAO;YACP,gBAAgB;AAChB,YAAA,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC;gBACxB,MAAM;gBACN,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;AAC9B,gBAAA,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,OAAO;gBACP,gBAAgB;aACjB,CAAC;SACH,CAAC;KACH;;;;AAKO,IAAA,YAAY,CAAC,KAAuC,EAAA;QAC1D,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAEzF,OAAO,WAAW,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;KAChD;;;;IAKO,WAAW,CAAC,EAClB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,GAChC,EAAA;AACnB,QAAA,MAAM,MAAM,GAAG,CAAC,IAAuB,MAAmB;YACxD,MAAM;YACN,SAAS;YACT,IAAI,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;AAChD,SAAA,CAAC,CAAC;QAEH,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;AACpC,YAAA,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;SACvB;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,gBAAgB,CAAC;AAC9G,aAAA,IAAI,CACHH,KAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EACjCC,YAAU,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CACjC,CAAC;KACL;;;;;;AAOO,IAAA,aAAa,CACnB,MAAyB,EACzB,KAAiB,EACjB,WAA0B,EAC1B,YAA2B,EAAA;;QAG3B,IAAI,CAAC,eAAe,EAAE,CAAC;AAEvB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;AACjC,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;AAChC,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAEhC,OAAO;YACL,UAAU,EAAE,KAAK,GAAG,CAAC;AACrB,YAAA,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE;YACjD,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE;YACtC,MAAM,EAAE,UAAU,CAChB,MAAM,EACN,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,OAAO,GAAG,IAAI,EAChD,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,EACjC,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CACvF;YACD,WAAW;AACX,YAAA,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;SAC1C,CAAC;KACH;;;;AAKO,IAAA,aAAa,CAAC,MAAqB,EAAA;QACzC,IAAI,CAAC,eAAe,EAAE,CAAC;AACvB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;AAEnC,QAAA,OAAO,gBAAgB,CACrB,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,IAAI,EAAE,EAAE,MAAM,CAAC,EAC7D,CAAC,OAAO,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,EAC7C,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM,EACxC,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAChE,CAAC;KACH;;;;;;;IAQO,sBAAsB,GAAA;QAC5B,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC;QACjD,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,CAAC,CAAC;QAEhG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,OAAO,KAAI;AAC/C,YAAA,MAAM,QAAQ,GAAG,OAAO,KAAK,QAAQ,CAAC;YACtC,IAAI,CAAC,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC,YAAY,EAAE,EAAE;gBAChD,OAAO;aACR;YAED,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACxE,KAAK;AACF,iBAAA,MAAM,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,QAAQ,CAAC;iBAC9E,OAAO,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChF,SAAC,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;KAC/B;;AAGO,IAAA,kBAAkB,CAAC,SAA0B,EAAA;QACnD,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC;KACnG;;AAGO,IAAA,SAAS,CAAC,IAAU,EAAA;QAC1B,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAElD,OAAO,IAAI,KAAK,QAAQ;cACpB,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE;cAChC,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;KACpF;;;IAIO,gBAAgB,GAAA;AACtB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB;AAClC,aAAA,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,cAAc,CAAC,CAAC;QAErE,IAAI,IAAI,EAAE;AACR,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,QAAQ,EAAE,CAAC;SACjB;KACF;;;AAKD,IAAA,IAAY,cAAc,GAAA;AACxB,QAAA,OAAO,CAAC,IAAI,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;KACvD;AAEO,IAAA,SAAS,CAAC,SAA0B,EAAE,CAAS,EAAE,CAAS,EAAA;AAChE,QAAA,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAgB,EAAE,CAAC;AAE/B,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAC7B;AACE,YAAA,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;AACvB,YAAA,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE;AACvD,YAAA,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE;SAChD,EACD,QAAQ,CACT,CAAC;AACF,QAAA,IAAI,QAAQ,KAAK,IAAI,EAAE;AACrB,YAAA,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC;AAClB,YAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;SAC7D;AAED,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAC7B;AACE,YAAA,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;AACvB,YAAA,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE;AACvD,YAAA,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,EAAE;SAChD,EACD,UAAU,CACX,CAAC;AACF,QAAA,IAAI,QAAQ,KAAK,IAAI,EAAE;AACrB,YAAA,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC;AAClB,YAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;SAC7D;AAED,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAE3B,QAAA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACjB;AAEO,IAAA,WAAW,CACjB,SAA0B,EAC1B,QAAwD,EACxD,MAAc,EAAA;AAEd,QAAA,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAgB,EAAE,CAAC;AAC/B,QAAA,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;;AAG/B,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACjE,YAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,MAAM,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;AAChC,gBAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;aACtD;SACF;AACD,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AACpD,YAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,gBAAA,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC;AAC7C,gBAAA,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;AACnB,gBAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;aACtD;SACF;AACD,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACnE,YAAA,IAAI,OAAO,KAAK,IAAI,EAAE;gBACpB,MAAM,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;AAChC,gBAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;aACtD;SACF;AACD,QAAA,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;AACxB,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtD,YAAA,IAAI,OAAO,KAAK,IAAI,EAAE;AACpB,gBAAA,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,OAAO,CAAC;AAC7C,gBAAA,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC;AACnB,gBAAA,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;aACtD;SACF;AAED,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;AAE3B,QAAA,OAAO,MAAM,CAAC;KACf;;;;;AAMO,IAAA,WAAW,CAAC,MAAuB,EAAA;AACzC,QAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACvE,QAAA,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE3E,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAClD,IAAI,YAAY,EAAE;AAChB,YAAA,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC/B;QACD,IAAI,YAAY,EAAE;YAChB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,YAAY,CAAC,CAAC;SACxD;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACjD,QAAA,MAAM,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;AAElF,QAAA,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE;YAChC,IAAI,SAAS,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,EAAE;gBAC9B,SAAS;aACV;YAED,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACrF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;SACxF;AAED,QAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;KACjC;;;;IAKO,SAAS,CACf,KAA0C,EAC1C,UAAoB,EAAA;QAEpB,IAAI,IAAI,GAA6D,IAAI,CAAC;AAE1E,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,YAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAClC,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;AAClD,gBAAA,IAAI,QAAQ,IAAI,IAAI,CAAC,cAAc,KAAK,CAAC,IAAI,IAAI,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE;AAC1E,oBAAA,IAAI,GAAG,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;iBACtE;aACF;SACF;QAED,OAAO,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC;KAC7D;IAEO,QAAQ,CAAC,KAAa,EAAE,UAAoB,EAAA;QAClD,IAAI,IAAI,GAAkB,IAAI,CAAC;AAC/B,QAAA,IAAI,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC;AAEvC,QAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,CAAC;AAC7C,YAAA,IAAI,QAAQ,IAAI,YAAY,EAAE;gBAC5B,IAAI,GAAG,SAAS,CAAC;gBACjB,YAAY,GAAG,QAAQ,CAAC;aACzB;SACF;AAED,QAAA,OAAO,IAAI,CAAC;KACb;;;AAIO,IAAA,aAAa,CAAC,MAAmB,EAAA;AACvC,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;QAED,IAAI,CAAC,eAAe,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;YAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,CAAC,SAAS,GAAG,CAAA,YAAA,EAAe,KAAK,CAAC,WAAW,EAAE,CAAC;AACpD,YAAA,IAAI,KAAK,CAAC,WAAW,KAAK,GAAG,EAAE;AAC7B,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAA,EAAG,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;aACvD;iBAAM;AACL,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAA,EAAG,KAAK,CAAC,QAAQ,GAAG,WAAW,CAAA,EAAA,CAAI,CAAC;aACtD;AAED,YAAA,OAAO,IAAI,CAAC;SACb,CAAC,CAAC,CAAC;KACL;IAEO,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC;KAChD;wGAxkCU,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,6SAuBrB,kBAAkB,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,WAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,UAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,QAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,qBAAA,EAAA,SAAA,EAKf,wBAAwB,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClMxC,i2RAgOA,EDlEI,MAAA,EAAA,CAAA,4wKAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,cAAc,EACd,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAlB,IAAA,CAAA,WAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,MAAA,EAAA,CAAA,wBAAA,EAAA,iBAAA,EAAA,wBAAA,EAAA,IAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,4BAAA,EAAA,2BAAA,EAAA,0BAAA,EAAA,+BAAA,EAAA,2BAAA,EAAA,6BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,oBAAA,EAAA,oBAAA,EAAA,mBAAA,EAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,yBAAA,EAAA,iBAAA,EAAA,0BAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,cAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,OAAO,2IACP,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACV,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,gTACf,wBAAwB,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,SAAA,EAAA,UAAA,EAAA,QAAA,EAAA,oBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,SAAA,EAAA,eAAA,EAAA,WAAA,EAAA,eAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGf,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAfjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,mBAGZ,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,cAAc;wBACd,OAAO;wBACP,UAAU;wBACV,YAAY;wBACZ,eAAe;wBACf,wBAAwB;AACzB,qBAAA,EAAA,QAAA,EAAA,i2RAAA,EAAA,MAAA,EAAA,CAAA,4wKAAA,CAAA,EAAA,CAAA;wDAIe,MAAM,EAAA,CAAA;sBAArB,KAAK;gBACU,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBAMU,MAAM,EAAA,CAAA;sBAArB,KAAK;gBAIW,iBAAiB,EAAA,CAAA;sBAAjC,MAAM;gBAIU,aAAa,EAAA,CAAA;sBAA7B,MAAM;gBAIU,WAAW,EAAA,CAAA;sBAA3B,MAAM;gBAGA,OAAO,EAAA,CAAA;sBADb,SAAS;uBAAC,kBAAkB,CAAA;gBAMrB,mBAAmB,EAAA,CAAA;sBAD1B,YAAY;uBAAC,wBAAwB,CAAA;gBAI9B,SAAS,EAAA,CAAA;sBADhB,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,UAAU,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;gBAI/B,OAAO,EAAA,CAAA;sBADd,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;;;AE3LxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEM,MAAO,gBAAiB,SAAQ,YAAY,CAAA;;AAGzC,IAAA,QAAQ,GAAkC,OAAO,EAAE,CAAC,CAAC;AAE5C,IAAA,UAAU,CAAC,QAAgB,EAAE,IAAoB,EAAE,SAA2B,EAAE,EAAA;AAC9F,QAAA,OAAO,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;KAC5E;wGAPU,gBAAgB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAhB,gBAAgB,EAAA,CAAA,CAAA;;4FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;;;ACCX;AACO,MAAM,mBAAmB,GAA6C;AAC3E,IAAA,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;AACnC,IAAA,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE;CAC/C,CAAC;AAEK,MAAM,mBAAmB,GAAG,uCAAuC,CAAC;AACpE,MAAM,mBAAmB,GAAG,2CAA2C,CAAC;AACxE,MAAM,wBAAwB,GAAG,wBAAwB,CAAC;AAEjE;AACA;AACO,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C;AACO,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC;AACA;AACA;AACO,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AACrD,MAAM,2BAA2B,GAAG,gEAAgE,CAAC;AACrG,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAClC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C;AACA,MAAM,qBAAqB,GAA+C;AACxE,IAAA,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AAC7B,IAAA,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE;AACtC,IAAA,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE;CAC1C,CAAC;AAGF;AACA,MAAM,eAAe,GAAG,8BAA8B,CAAC;AACvD;AACA;AACA,MAAM,aAAa,GAAG,yBAAyB,CAAC;AAEhD;AACA;AACA;AACA;AACM,SAAU,iBAAiB,CAAC,GAAY,EAAA;AAC5C,IAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC3B,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;KAC1C;AAED,IAAA,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AAC3B,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC;IACjF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAC7B,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAE3B,IAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC;AAC/C,CAAC;AAED;AACA;AACgB,SAAA,WAAW,CAAC,GAAkB,EAAE,GAAkB,EAAA;AAChE,IAAA,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,EAAE;AAC9C,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,CAAQ,KAAA,EAAA,GAAG,CAAmB,gBAAA,EAAA,GAAG,IAAI,CAAC;AAC/C,CAAC;AAED;AACA;AACA;AACA;SACgB,eAAe,CAC7B,KAA4C,EAC5C,wBAAiC,EACjC,QAAkD,EAAA;IAElD,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,QAAQ,CAAC,aAAa,CAAC;WAChD,mBAAmB,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,KAAK,IAAI,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjF,IAAI,CAAC,IAAI,EAAE;AACT,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KACxD;IAED,OAAO;AACL,QAAA,IAAI,EAAE,IAAI;AACV,QAAA,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,wBAAwB,GAAG,mBAAmB,GAAG,IAAI;KAC/D,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACgB,SAAA,kBAAkB,CAChC,QAAkD,EAClD,MAAe,EAAA;IAEf,MAAM,MAAM,GAAwB,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAEpE,OAAO,MAAM,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,QAAQ,CAAC,WAAW,CAAC;AACrD,UAAE,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC;UACnB,MAAM,CAAC;AACb,CAAC;AAED;AACA;SACgB,mBAAmB,CACjC,YAAiC,EACjC,UAA8B,KAAK,EAAA;AAEnC,IAAA,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC,MAAM,KAAI;AAC7C,QAAA,QAAQ,MAAM,CAAC,KAAK;AAClB,YAAA,KAAK,OAAO;AACV,gBAAA,OAAO,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,KAAK,OAAO,CAAC;AACjG,YAAA,KAAK,MAAM;gBACT,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,OAAO,KAAK,MAAM,CAAC;AAC7D,YAAA;AACE,gBAAA,OAAO,IAAI,CAAC;SACf;AACH,KAAC,CAAC,CAAC;AACL,CAAC;AAED;AACA;AACA;AACA;AACgB,SAAA,qBAAqB,CACnC,YAAiC,EACjC,OAA6C,EAAA;AAE7C,IAAA,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,KAAK,MAAM;AAC5C,UAAE,YAAY;AACd,UAAE,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC,CAAC;IAErD,OAAO,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAC9B,SAA6B,EAC7B,OAA6C,EAAA;AAE7C,IAAA,IAAI,SAAS,KAAK,KAAK,EAAE;AACvB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,KAAK,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;KACjD;AAED,IAAA,IAAI,SAAS,KAAK,OAAO,EAAE;AACzB,QAAA,OAAO,OAAO,CAAC;KAChB;IAED,QAAQ,OAAO;AACb,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,MAAM,CAAC;AAChB,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,QAAQ,CAAC;AAClB,QAAA;AACE,YAAA,OAAO,OAAO,CAAC;KAClB;AACH,CAAC;AAED;AACA;AACM,SAAU,YAAY,CAAC,KAA2C,EAAA;IACtE,QAAQ,KAAK;AACX,QAAA,KAAK,QAAQ,CAAC;AACd,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,OAAO,CAAC;AACjB,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,MAAM,CAAC;AAChB,QAAA;AACE,YAAA,OAAO,KAAK,CAAC;KAChB;AACH,CAAC;AAED;AACM,SAAU,gBAAgB,CAAC,KAA2C,EAAA;AAC1E,IAAA,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,MAAM,CAAC;AACnD,CAAC;AAED;AACA;AACA;AACgB,SAAA,WAAW,CAAC,SAA6B,EAAE,SAAkB,EAAA;IAC3E,QAAQ,SAAS;AACf,QAAA,KAAK,MAAM;AACT,YAAA,OAAO,MAAM,CAAC;AAChB,QAAA,KAAK,OAAO;YACV,OAAO,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AACvC,QAAA;YACE,OAAO,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC;KACzC;AACH,CAAC;AAED;AACM,SAAU,oBAAoB,CAAC,SAA6B,EAAA;IAChE,OAAO,SAAS,KAAK,MAAM;UACvB,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE;UAChD,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAC7D,CAAC;AAED;AACA;AACM,SAAU,gBAAgB,CAAC,MAA8C,EAAA;AAC7E,IAAA,OAAO,CAAC,MAAM,IAAI,EAAE;SACjB,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC;AAC/F,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;AACA;AACA;AACgB,SAAA,eAAe,CAAC,KAAwB,EAAE,KAAsC,EAAA;AAC9F,IAAA,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,YAAY,IAAI,QAAQ,CAAC;AAE1E,IAAA,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE;AAC1B,QAAA,OAAO,KAAK,CAAC;KACd;IAED,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC;AAC1E,IAAA,IAAI,KAAK,GAAG,CAAC,EAAE;AACb,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,OAAO,GAAG,KAAK,CAAA,QAAA,EAAW,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,QAAQ,KAAK,GAAG,CAAC,CAAA,CAAE,IAAI,CAAC;AACzE,CAAC;AAED;AACA;AACA;SACgB,oBAAoB,CAClC,MAAiD,EACjD,SAAwB,IAAI,EAAA;AAE5B,IAAA,MAAM,OAAO,GAA2B;AACtC,QAAA,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,aAAa,EAAE;QAClD,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;KACzF,CAAC;IAEF,OAAO,MAAM,IAAI,MAAM,KAAK,kBAAkB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;AACxE,UAAE,CAAC,GAAG,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAA6B,CAAC,EAAE,CAAC;UAC5E,OAAO,CAAC;AACd,CAAC;AAED;AACA;AACM,SAAU,aAAa,CAAC,MAA6C,EAAA;AACzE,IAAA,OAAO,MAAM,EAAE,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG;UACnD,MAAM,CAAC,QAAQ;UACf,kBAAkB,CAAC;AACzB,CAAC;AAED;AACA;AACA;SACgB,gBAAgB,CAC9B,MAAc,EACd,KAAoB,EACpB,GAAkB,EAAA;AAElB,IAAA,IAAI,MAAM,KAAK,kBAAkB,EAAE;AACjC,QAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;KAC7B;AAED,IAAA,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,EAAE,IAAI,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;AACA;AACgB,SAAA,aAAa,CAAC,MAAiB,EAAE,OAAgB,EAAA;AAC/D,IAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAClB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,OAAO,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;AAC1D,CAAC;AAED;AACA;AACgB,SAAA,kBAAkB,CAAC,MAAe,EAAE,MAAe,EAAA;AACjE,IAAA,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACtC,IAAA,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAEtC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;AAChC,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,EAAE,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAChF,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAC/B,KAAwB,EACxB,QAAkD,EAAA;AAElD,IAAA,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE;AAC3E,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED;AACA;AACA;AACM,SAAU,gBAAgB,CAAC,KAA4C,EAAA;IAC3E,IAAI,CAAC,KAAK,EAAE;AACV,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,UAAU,GAAuB,EAAE,CAAC;AAC1C,IAAA,IAAI,KAAK,CAAC,KAAK,EAAE;AACf,QAAA,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;KAChC;AACD,IAAA,IAAI,KAAK,CAAC,GAAG,EAAE;AACb,QAAA,UAAU,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;KAC5B;AACD,IAAA,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE;AACxB,QAAA,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;KAClC;AACD,IAAA,IAAI,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE;AAC/B,QAAA,UAAU,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;KAChD;AACD,IAAA,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;AACjC,QAAA,UAAU,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;KAC5B;AACD,IAAA,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE;AACjC,QAAA,UAAU,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;KAC5B;AACD,IAAA,IAAI,KAAK,CAAC,KAAK,EAAE;AACf,QAAA,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;KAChC;AACD,IAAA,IAAI,KAAK,CAAC,QAAQ,EAAE;AAClB,QAAA,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;KACtC;AAED,IAAA,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;AAC5D,CAAC;AAED;AACA;AACgB,SAAA,cAAc,CAC5B,MAA6C,EAC7C,KAA4C,EAAA;AAE5C,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9F;;AC/RA;AACA,MAAM,2BAA2B,GAAoD;IACnF,EAAE,KAAK,EAAE,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,gCAAgC,EAAE;IAC5E,EAAE,KAAK,EAAE,oBAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,6BAA6B,EAAE;IACxE,EAAE,KAAK,EAAE,oBAAoB,CAAC,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE;CACpE,CAAC;AAEF;AACA,MAAM,yBAAyB,GAAG,CAAC,CAAC;AACpC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAErC;AACA;AACA;AACA,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAErC;AACA;AACA,MAAM,aAAa,GAA4D;AAC7E,IAAA,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AACzD,IAAA,CAAC,kBAAkB,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,CAAA,MAAA,EAAS,CAAC,CAAE,CAAA;AAC5E,IAAA,CAAC,kBAAkB,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;AACxD,IAAA,CAAC,kBAAkB,CAAC,GAAG,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;CACvD,CAAC;AAkBF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAiCa,0BAA0B,CAAA;;;;;AAMrB,IAAA,cAAc,GAAG,IAAI,YAAY,EAAQ,CAAC;AAEnD,IAAA,SAAS,CAAkB;AAC3B,IAAA,MAAM,CAAS;IAEf,WAAW,GAAG,UAAU,CAAC;AAEhB,IAAA,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;;;;AAKnB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;;;;AAK5D,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;AAC3B,QAAA,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAExD,QAAA,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC;AACzD,KAAC,CAAC,CAAC;;;IAIa,OAAO,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC;;;;IAKlG,UAAU,GAAoB,yBAAyB,CAAC;IACxD,YAAY,GAAoB,yBAAyB,CAAC;IAC1D,aAAa,GAAoB,yBAAyB,CAAC;IAC3D,WAAW,GAAoB,yBAAyB,CAAC;IAEzD,UAAU,GAAG,EAAE,CAAC;;IAGP,kBAAkB,GAAG,2BAA2B,CAAC;IACjD,kBAAkB,GAAG,mBAAmB,CAAC;IACzC,mBAAmB,GAAG,yBAAyB,CAAC;IAChD,mBAAmB,GAAG,yBAAyB,CAAC;AAChD,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;AAExB,IAAA,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;AAExB,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;IAG1B,WAAW,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC5E,IAAA,UAAU,GAAG,MAAM,CAAuB,oBAAoB,CAAC,IAAI,CAAC,CAAC;;;AAGrE,IAAA,WAAW,GAAG,MAAM,CAAyB,IAAI,CAAC,CAAC;AACnD,IAAA,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACzB,IAAA,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9B,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;AACtE,IAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1B,IAAA,oBAAoB,GAAG,MAAM,CAAmB,iCAAiC,CAAC,CAAC;AACnF,IAAA,gBAAgB,GAAG,MAAM,CAAkB,6BAA6B,CAAC,CAAC;;;;AAK1E,IAAA,GAAG,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;;AAKlC,IAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;AAG5B,IAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5B,IAAA,QAAQ,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;;AAMvC,IAAA,IAAI,GAAG,MAAM,CAAc,EAAE,CAAC,CAAC;AAC/B,IAAA,YAAY,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;IAG3C,WAAW,GAAG,mBAAmB,CAAC;;IAG1C,kBAAkB,GAA6B,EAAE,CAAC;IAClD,QAAQ,GAAmB,EAAE,CAAC;AAC9B,IAAA,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;;AAEnD,IAAA,YAAY,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE1C,IAAA,WAAW,GAAqC;AAC/D,QAAA,MAAM,EAAE,aAAa;AACrB,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,OAAO,EAAE,aAAa;AACtB,QAAA,WAAW,EAAE,cAAc;KAC5B,CAAC;AAEe,IAAA,KAAK,GAAgC,MAAM,CAAC,eAAe,CAAC,CAAC;AAC7D,IAAA,WAAW,GAAG,SAAS,CAA+B,YAAY,CAAC,CAAC;AACpE,IAAA,UAAU,GAAG,MAAM,CAAoE,YAAY,CAAC,CAAC;AACrG,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAE3C,QAAQ,GAAA;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QAChC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;AAEtC,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAC3C,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AAClD,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAErD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,GAAG,IAAI,yBAAyB,CAAC;QAC5D,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,KAAK,IAAI,yBAAyB,CAAC;QAChE,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,MAAM,IAAI,yBAAyB,CAAC;QAClE,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,IAAI,IAAI,yBAAyB,CAAC;AAE9D,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEvE,IAAI,CAAC,YAAY,EAAE,CAAC;AAEpB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;;;AAIlD,QAAA,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE;YACrB,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,QAAQ,EAAE,CAAC;SACjB;KACF;;AAGM,IAAA,SAAS,CAAC,IAAsB,EAAA;QACrC,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;KACvC;;;;;;;;;;;;IAaM,MAAM,GAAA;QACX,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE;AACjC,cAAE;AACA,gBAAA,KAAK,EAAE,cAAc;gBACrB,QAAQ,EAAE,qBAAqB,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,6EAA6E,IAAI,CAAC,eAAe,EAAE,CAAE,CAAA;AACjM,aAAA;AACD,cAAE;AACA,gBAAA,KAAK,EAAE,kBAAkB;gBACzB,QAAQ,EAAE,CAA0C,uCAAA,EAAA,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,gBAAgB,CAAC,CAA2B,yBAAA,CAAA;aAClI,CAAC;AACD,aAAA,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,EACpF,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,eAAe,GAAG,mBAAmB,CAAC,CAAC;YAC9E,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;SAC1C,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;;;AAMM,IAAA,WAAW,CAAC,KAAa,EAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC;QAChD,IAAI,CAAC,KAAK,EAAE;YACV,OAAO;SACR;AAED,QAAA,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC;QAC/B,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,cAAc,IAAI,GAAG,EAAE,KAAK,CAAC,YAAY,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;QACrG,KAAK,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,UAAU,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;KACjC;;;AAIM,IAAA,cAAc,GAAG,CAAC,OAAwB,KAAU;QACzD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAE1C,QAAA,IAAI,IAAI,CAAC,aAAa,EAAE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,sBAAsB,EAAE;AAC5E,YAAA,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;SAC5D;AACH,KAAC,CAAC;IAEK,IAAI,GAAG,MAAK;AACjB,QAAA,MAAM,QAAQ,GAAsB;;;YAGlC,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE;AAC1D,YAAA,OAAO,EAAE;gBACP,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC;gBACnC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;gBACvC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC;gBACzC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;AACtC,aAAA;SACF,CAAC;;;;AAKF,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC;AAC5D,QAAA,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG;AACnB,eAAA,CAAC,mBAAmB,CAAC,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,MAAmB,CAAC,CAAC,CAAC;AAEpF,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE;YACzE,KAAK,EAAE,QAAQ,CAAC,KAAK;AACrB,YAAA,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;YACxD,IAAI,UAAU,GAAG,GAAG,GAAG,EAAE,CAAC;SAC3B,CAAC;AACC,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,QAAmC,KAAI;;;;AAI1C,YAAA,MAAM,KAAK,GAAG,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;AAE/D,YAAA,IAAI,UAAU,IAAI,CAAC,KAAK,EAAE;AACxB,gBAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;aACzF;iBAAM;AACL,gBAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;aAC3E;YAED,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;SACrF,CAAC,CACH,CAAC;AACN,KAAC,CAAC;;;;IAKK,OAAO,CAAC,GAAc,EAAE,IAAsB,EAAA;QACnD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;KAC/B;;;;IAKM,YAAY,CAAC,GAAc,EAAE,SAA6B,EAAA;AAC/D,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;YAClC,SAAS;AACT,YAAA,SAAS,EAAE,SAAS,KAAK,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,SAAS;AACvD,YAAA,eAAe,EAAE,oBAAoB,CAAC,SAAS,CAAC;AACjD,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;AAClB,YAAA,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;SAChC;aAAM;AACL,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SAC3B;KACF;;IAGM,YAAY,CAAC,GAAc,EAAE,SAAkB,EAAA;AACpD,QAAA,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE;YAClB,OAAO;SACR;AAED,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;KACtD;;;;;AAMO,IAAA,WAAW,CAAC,GAAc,EAAA;AAChC,QAAA,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,YAAY,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;QAEpF,IAAI,CAAC,KAAK,EAAE;YACV,IAAI,QAAQ,EAAE;gBACZ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;aACvE;YAED,OAAO;SACR;QAED,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;SAClG;aAAM;AACL,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;SAC7B;KACF;;;;;AAMO,IAAA,gBAAgB,CAAC,GAAc,EAAA;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,YAAY,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;QACpF,MAAM,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;QAC3F,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEvD,IAAI,CAAC,KAAK,EAAE;YACV,IAAI,QAAQ,EAAE;gBACZ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;aACvE;SACF;aAAM,IAAI,CAAC,QAAQ,EAAE;AACpB,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;SAC7B;AAAM,aAAA,IAAI,KAAK,KAAK,OAAO,EAAE;YAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;SAClG;aAAM;YACL,IAAI,CAAC,YAAY,EAAE,CAAC;SACrB;KACF;;;IAIO,UAAU,CAAC,GAAc,EAAE,KAAwB,EAAA;QACzD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE;YACtE,YAAY,EAAE,GAAG,CAAC,MAAM;YACxB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,KAAK;YACL,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AACnD,SAAA,CAAC,CAAC,CAAC;KACL;;;IAIO,SAAS,CAAC,GAAc,EAAE,KAAyB,EAAA;QACzD,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;AACrC,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAE9F,QAAA,OAAO,OAAO,CAAC;KAChB;;;IAIO,WAAW,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;KAC/G;;;IAIO,YAAY,GAAA;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AAC/C,QAAA,MAAM,IAAI,GAAG,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;AAC7D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;AAEnC,QAAA,OAAO,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;KACjG;;;;IAKO,eAAe,GAAA;AACrB,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE;AACpB,YAAA,OAAO,EAAE,CAAC;SACX;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACrC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;AAC9B,aAAA,MAAM,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACnD,aAAA,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9D,QAAA,OAAO,KAAK,CAAC,MAAM,GAAG,mDAAmD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAA,CAAG,GAAG,EAAE,CAAC;KACnG;;;IAIO,YAAY,GAAA;QAClB,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;AAClC,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;AAEjG,QAAA,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;KACnD;;;IAIO,UAAU,CAAC,MAAyB,EAAE,GAAW,EAAA;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;AAE9E,QAAA,OAAO,KAAK,EAAE,KAAK,IAAI,GAAG,CAAC;KAC5B;;;IAIO,YAAY,GAAA;QAClB,MAAM,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAc,CAAC;QAE1D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AACvE,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACpE,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,KAAK,iBAAiB,CAAC,OAAO;eACtE,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AACrD,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;AACtE,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACvC,QAAA,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,IAAI,iCAAiC,CAAC,CAAC;AAClG,QAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,IAAI,6BAA6B,CAAC,CAAC;KACvF;;;AAIO,IAAA,aAAa,CAAC,QAAsD,EAAA;AAC1E,QAAA,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,CAAC;AAEhC,QAAA,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,GAAG,eAAe,CAAC,MAAmB,CAAC,GAAG,IAAI,CAAC;KAC3F;;IAGO,gBAAgB,GAAA;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;QAExC,OAAO;AACL,YAAA,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,oBAAoB,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;YACtF,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,EAAE;AAC5F,YAAA,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE;kBACvB,EAAE,WAAW,EAAE,IAAI,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE;AAC9F,kBAAE,IAAI;SACT,CAAC;KACH;;;AAIO,IAAA,YAAY,CAAC,KAAoB,EAAA;QACvC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE;AAC3C,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;KAC5C;AAEO,IAAA,aAAa,CAAC,KAAa,EAAA;AACjC,QAAA,OAAO,IAAI,CAAC,aAAa,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,CAAC;KACnD;;AAGO,IAAA,OAAO,CAAC,KAA6B,EAAA;QAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE;AAClC,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAErE,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;KAChD;;;;;AAMO,IAAA,QAAQ,CAAC,KAAsB,EAAA;AACrC,QAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;KAC9D;;AAGO,IAAA,IAAI,CAAC,OAA4B,EAAA;QACvC,OAAO,CAAC,SAAS,CAAC;AAChB,YAAA,IAAI,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE;YACjC,KAAK,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;AAC7C,SAAA,CAAC,CAAC;KACJ;;;;;;IAOO,YAAY,GAAA;AAClB,QAAA,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAEpF,QAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,KAAI;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3F,MAAM,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;YAC9E,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAE7C,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE,KAAK,EAAE,IAAI;uBACZ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;AACpC,uBAAA,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;AACjB,uBAAA,MAAM,CAAC,IAAI;gBAChB,KAAK,EAAE,MAAM,EAAE,KAAK;AACf,uBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK;AACxD,uBAAA,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;gBAClC,SAAS;AACT,gBAAA,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC;AAC5D,gBAAA,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;AAC/E,gBAAA,gBAAgB,EAAE,IAAI,CAAC,OAAO,EAAE;sBAC5B,qBAAqB,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC;AACnD,sBAAE,mBAAmB,CAAC,YAAY,EAAE,SAAS,CAAC;AAChD,gBAAA,eAAe,EAAE,oBAAoB,CAAC,SAAS,CAAC;aACjD,CAAC;SACH,CAAC,CAAC,CAAC;KACL;;;;IAKO,OAAO,GAAA;QACb,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;aAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AACjE,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;KAC/D;;;IAIO,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAE3B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACjC,aAAA,SAAS,CAAC,CAAC,MAAc,KAAI;AAC5B,YAAA,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;AAC/C,SAAC,CAAC,CAAC;KACN;AAEO,IAAA,cAAc,CAAC,KAAU,EAAA;AAC/B,QAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,IAAI,yBAAyB,CAAC,CAAC;;QAE1F,IAAI,CAAC,cAAc,EAAE,CAAC;KACvB;;;IAIO,YAAY,CAAC,MAAc,EAAE,WAAmB,EAAA;AACtD,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAE1F,QAAA,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC;AACvC,aAAA,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;QAErD,IAAI,CAAC,QAAQ,GAAG,SAAS,EAAE,OAAO,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,EAAE,CAAC;KACrB;;;;;;;;;;;IAYO,QAAQ,GAAA;AACd,QAAA,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAC7D,aAAA,SAAS,CAAC;AACT,YAAA,IAAI,EAAE,CAAC,OAA2B,KAAI;gBACpC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC;gBACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,KAAK,CAAC,CAAC;gBACjD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC,CAAC;aAC3C;AACD,YAAA,KAAK,EAAE,CAAC,KAAK,KAAI;AACf,gBAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACnB,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,kCAAkC,CAAC,CAAC;aAChF;AACF,SAAA,CAAC,CAAC;KACN;IAEO,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AACjE,aAAA,SAAS,CAAC;AACT,YAAA,IAAI,EAAE,CAAC,OAAiC,KAAI;AAC1C,gBAAA,IAAI,CAAC,kBAAkB,GAAG,OAAO,IAAI,EAAE,CAAC;gBACxC,IAAI,CAAC,YAAY,EAAE,CAAC;aACrB;AACD,YAAA,KAAK,EAAE,CAAC,KAAK,KAAI;AACf,gBAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,IAAI,sCAAsC,CAAC,CAAC;aACxF;AACF,SAAA,CAAC,CAAC;KACN;AAEO,IAAA,SAAS,CAAC,MAAc,EAAA;AAC9B,QAAA,OAAO,MAAM;AACV,aAAA,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;AACvB,aAAA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;AACpB,aAAA,IAAI,EAAE;AACN,aAAA,OAAO,CAAC,OAAO,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;KAC7D;wGAhlBU,0BAA0B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAA1B,0BAA0B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,aAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,YAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClMvC,w+iBA4bO,EDpRH,MAAA,EAAA,CAAA,orDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,mjCACX,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,cAAA,EAAA,WAAA,EAAA,SAAA,EAAA,eAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,SAAA,EAAA,OAAA,EAAA,WAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,UAAA,EAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,cAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,gaAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,aAAa,EACb,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAmB,IAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,aAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,YAAY,maACZ,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,OAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,WAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,oBAAA,EAAA,kBAAA,EAAA,eAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,qBAAA,EAAA,aAAA,EAAA,eAAA,EAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACb,cAAc,EACd,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,IAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,EAChB,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,cAAc,qLACd,YAAY,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,OAAO,EACP,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAQ,sDACR,SAAS,EAAA,QAAA,EAAA,+CAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,SAAS,EAAA,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,OAAO,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACP,aAAa,EACb,QAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAQ,EACR,QAAA,EAAA,yHAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,IAAA,EAAA,aAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,mBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,EACT,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,weACT,cAAc,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,eAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,OAAA,EAAA,UAAA,EAAA,eAAA,EAAA,UAAA,EAAA,SAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,cAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,4BAAA,EAAA,oBAAA,EAAA,qBAAA,EAAA,qBAAA,EAAA,yBAAA,EAAA,YAAA,EAAA,iBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACV,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGH,0BAA0B,EAAA,UAAA,EAAA,CAAA;kBAhCtC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,YAAY;wBACZ,YAAY;wBACZ,cAAc;wBACd,aAAa;wBACb,YAAY;wBACZ,aAAa;wBACb,cAAc;wBACd,gBAAgB;wBAChB,gBAAgB;wBAChB,cAAc;wBACd,YAAY;wBACZ,OAAO;wBACP,QAAQ;wBACR,SAAS;wBACT,SAAS;wBACT,OAAO;wBACP,aAAa;wBACb,QAAQ;wBACR,SAAS;wBACT,SAAS;wBACT,cAAc;wBACd,UAAU;wBACV,YAAY;AACb,qBAAA,EAAA,QAAA,EAAA,w+iBAAA,EAAA,MAAA,EAAA,CAAA,orDAAA,CAAA,EAAA,CAAA;;;AEpLH;AACA;AACA;AACA;AACA;AACA;MAiBa,uBAAuB,CAAA;IAElB,WAAW,GAAG,UAAU,CAAC;IACzB,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,GAAG,KAAK,CAAC;AAChB,IAAA,cAAc,GAAG,IAAI,YAAY,EAAU,CAAC;IAE7D,IAAoB,QAAQ,CAAC,KAAa,EAAA;QACxC,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,CAAC,SAAS,EAAE,EAAE;AACvC,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1B,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACjC;KACF;AAED,IAAA,IAAW,QAAQ,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;KACzB;IAEM,IAAI,GAAW,IAAI,EAAE,CAAC;AACb,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AAEtE,IAAA,SAAS,GAAG,MAAM,CAAS,EAAE,CAAC,CAAC;;;;AAKxC,IAAA,mBAAmB,CAAC,OAAe,EAAA;QACzC,MAAM,IAAI,GAAG,IAAoE,CAAC;AAClF,QAAA,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,iBAAiB,KAAK,UAAU;AACxD,cAAE,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC;cAClC,EAAE,CAAC;QAEP,OAAO,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;AACxC,cAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC;cACnB,KAAK,CAAC;KACX;wGAnCU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClCpC,+XAYA,EAAA,MAAA,EAAA,CAAA,2BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDcI,YAAY,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,QAAQ,EACR,QAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,EACT,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,eAAA,EAAA,UAAA,EAAA,8BAAA,EAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,wBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,2BAAA,EAAA,gBAAA,EAAA,IAAA,EAAA,YAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,WAAS,EACT,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,kWACX,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAvB,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,UAAA,EAAA,uBAAA,CAAA,EAAA,CAAA,EAAA,aAAA,EATC,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAYxD,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAhBnC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,8BAA8B,iBAGzB,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAClD,eAAA,EAAA,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA;wBACP,YAAY;wBACZ,QAAQ;wBACR,SAAS;wBACTuB,WAAS;wBACT,WAAW;wBACX,YAAY;AACb,qBAAA,EAAA,QAAA,EAAA,+XAAA,EAAA,MAAA,EAAA,CAAA,2BAAA,CAAA,EAAA,CAAA;8BAIe,WAAW,EAAA,CAAA;sBAA1B,KAAK;gBACU,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBACU,QAAQ,EAAA,CAAA;sBAAvB,KAAK;gBACW,cAAc,EAAA,CAAA;sBAA9B,MAAM;gBAEa,QAAQ,EAAA,CAAA;sBAA3B,KAAK;;;AEtCR;AACA;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAC/B,MAA2C,EAC3C,MAAc,EACd,QAAgB,EAAA;IAEhB,OAAO;QACL,IAAI,MAAM,MAAM,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACvD,IAAI,QAAQ,MAAM,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;KAC9D,CAAC;AACJ;;AC+HA;AACA;AACA,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACzC,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B;AACA;AACA,SAAS,WAAW,CAAC,GAAW,EAAA;IAC9B,OAAO,CAAA,EAAG,UAAU,CAAC,GAAG,CAAC,CAAK,EAAA,EAAA,GAAG,GAAG,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAA;IACjC,OAAO,CAAA,EAAG,YAAY,CAAC,IAAI,CAAC,CAAK,EAAA,EAAA,IAAI,GAAG,CAAC;AAC3C,CAAC;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAiCa,uBAAuB,CAAA;;AAGlB,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;;;AAGjC,IAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE/B,IAAI,GAAG,EAAE,CAAC;;;;;;;;AAQV,IAAA,SAAS,CAAkB;AAC3B,IAAA,UAAU,CAAkB;IACnB,gBAAgB,GAAG,kBAAkB,CAAC;IACtC,gBAAgB,GAAG,kBAAkB,CAAC;;;IAG/C,YAAY,GAAoB,CAAC,CAAC;IAClC,YAAY,GAAoB,CAAC,CAAC;IACzB,eAAe,GAAG,iBAAiB,CAAC;;;;;IAK7C,QAAQ,GAAG,EAAE,CAAC;IACd,WAAW,GAAG,oBAAoB,CAAC;;;;AAK1B,IAAA,OAAO,GAAG,MAAM,CAAuB,IAAI,CAAC,CAAC;;;AAG7C,IAAA,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;AACpB,IAAA,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;;;;;;IAMtB,KAAK,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;;;;AAKnG,IAAA,aAAa,GAAG,QAAQ,CAAuB,MAAK;AAClE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;QAE/D,OAAO;AACL,YAAA,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC;AACrE,YAAA,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA,UAAA,EAAa,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE;YACtE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACnE,CAAC;AACJ,KAAC,CAAC,CAAC;;;;AAKa,IAAA,eAAe,GAAG,QAAQ,CAAuB,MAAK;AACpE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE;AACZ,YAAA,OAAO,EAAE,CAAC;SACX;QAED,OAAO;AACL,YAAA,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,aAAa,CAAC;AACpF,YAAA,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA,UAAA,EAAa,aAAa,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,EAAE;YAC3E,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;SACnF,CAAC;AACJ,KAAC,CAAC,CAAC;;;;AAKa,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAK;QAC5C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAEhE,OAAO;YACL,YAAY,CACV,cAAc,EACd,EAAE,MAAM,EAAE,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,EAAE,EACpD,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,CACzC;AACD,YAAA,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC;AAChD,SAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChB,KAAC,CAAC,CAAC;;AAGa,IAAA,UAAU,GAAG,MAAM,CAAqB,EAAE,CAAC,CAAC;IAC5C,gBAAgB,GAAG,kBAAkB,CAAC;IACtC,UAAU,GAAG,mBAAmB,CAAC;IACjC,WAAW,GAAG,mBAAmB,CAAC;IAClC,kBAAkB,GAAG,2BAA2B,CAAC;IACjD,aAAa,GAAG,sBAAsB,CAAC;IACvC,cAAc,GAAG,uBAAuB,CAAC;IACzC,YAAY,GAAG,YAAY,CAAC;IAC5B,WAAW,GAAG,WAAW,CAAC;;;;AAK1B,IAAA,iBAAiB,GAAG,CAAC,OAAwB,EAAE,GAAY,KAAU;QACnF,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC7C,KAAC,CAAC;AAEc,IAAA,iBAAiB,GAAG,CAAC,OAAwB,EAAE,GAAY,KAAU;QACnF,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7C,KAAC,CAAC;;;;;;AAOc,IAAA,gBAAgB,GAAG,CAAC,OAAwB,EAAE,OAAkC,KAAU;AACxG,QAAA,IAAI,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,KAAK,EAAE;AACnE,YAAA,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAClC;AACH,KAAC,CAAC;AAEe,IAAA,KAAK,GAAuB,MAAM,CAAC,eAAe,CAAC,CAAC;AACpD,IAAA,UAAU,GAAG,MAAM,CAA8D,YAAY,CAAC,CAAC;AAC/F,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC3B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC7B,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;;;IAGtC,eAAe,GAAkB,IAAI,CAAC;;IAE7B,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC;;AAEnE,IAAA,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;AAEhC,IAAA,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;;AAK9B,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAC9C,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;AAC/B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAE7B,QAAA,OAAO,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC;AAChE,cAAE,MAAM;AACR,cAAE,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC;AACnC,KAAC,CAAC,CAAC;;AAGc,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AAChD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAErC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,eAAe;AACrF,eAAA,wBAAwB,CAAC;AAChC,KAAC,CAAC,CAAC;;;AAIc,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AAChD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEjC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAClD,cAAE,QAAQ;AACV,cAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;AAC9B,KAAC,CAAC,CAAC;IAEI,QAAQ,GAAA;AACb,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;AACjC,QAAA,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAClC,QAAA,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AACpC,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,IAAI,CAAC,CAAC;AACnE,QAAA,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,IAAI,CAAC,CAAC;AACnE,QAAA,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC;AAClE,QAAA,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,oBAAoB,CAAC;QAChF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEzC,QAAA,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAE9B,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,YAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;iBACvB,IAAI,CACH,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAC3C,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,EAC1B,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAC9C,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,iBAAA,SAAS,EAAE,CAAC;SAChB;KACF;;;;IAKM,QAAQ,CAAC,GAAqB,EAAE,KAAgC,EAAA;QACrE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI;AAClC,aAAA,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;KACpF;;;;IAKM,YAAY,GAAA;QACjB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC;QAEhG,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,KAAK,EAAE,CAAC;AACd,YAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;SAC7B;KACF;;;;IAKM,MAAM,GAAA;AACX,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACnB,YAAA,KAAK,EAAE,eAAe;YACtB,QAAQ,EAAE,WAAW,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAA2B,yBAAA,CAAA;SACvE,CAAC;AACC,aAAA,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAC9D,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;aACA,SAAS,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACxC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AAC/C,SAAC,CAAC,CAAC;KACN;IAEM,IAAI,GAAG,MAAK;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;;;AAItC,QAAA,MAAM,QAAQ,GAAG;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9C,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC;YAChD,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAC1B,YAAA,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvE,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,EAAE;AAC/C,YAAA,YAAY,EAAE;gBACZ,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;gBACzD,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AAC1D,aAAA;SACF,CAAC;;;;AAKF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE;aAC5B,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACzD,aAAA,MAAM,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;;;;;;;;QAS1D,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAE5E,OAAO,IAAI,CAAC,KAAK,CAAC;aACf,IAAI,CACH,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,EACpD,OAAO,EAAE,EACT,SAAS,CAAC,MAAM,QAAQ,CAAC;YACvB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC;AAC3C,YAAA,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;AACzG,SAAA,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrE,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;YAC/C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;SAC5C,CAAC,CACH,CAAC;AACN,KAAC,CAAC;;;;;;;AAQM,IAAA,cAAc,CAAC,KAAsB,EAAA;AAC3C,QAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;KAC9D;;;;;IAMO,gBAAgB,GAAA;QACtB,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAE9D,OAAO,iBAAiB,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,KAAK,iBAAiB;AAC3E,cAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;cAC3B,EAAE,CAAC;KACR;;;;AAKO,IAAA,aAAa,CACnB,MAAiC,EACjC,OAAiB,EACjB,KAAgC,EAAA;AAEhC,QAAA,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;KAC7F;;;;AAKO,IAAA,aAAa,CAAC,GAAqB,EAAA;QACzC,MAAM,OAAO,GAA6B,EAAE,CAAC;AAE7C,QAAA,IAAI,GAAG,CAAC,QAAQ,EAAE;YAChB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAC/B,YAAA,IAAI,KAAK,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE;AACrC,gBAAA,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;aACvB;YAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE;AAC3B,gBAAA,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;aACrB;SACF;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AACzC,QAAA,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE;AACzD,YAAA,OAAO,CAAC,OAAO,GAAG,UAAU,CAAC;SAC9B;AAED,QAAA,OAAO,OAAO,CAAC;KAChB;AAEO,IAAA,cAAc,CAAC,OAAiC,EAAA;QACtD,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC;KAClE;;;;AAKO,IAAA,YAAY,CAAC,KAAwB,EAAA;AAC3C,QAAA,MAAM,IAAI,GAAG,CAAC,IAAqB,KAAa;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;AAE9C,YAAA,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE;AAC3C,iBAAA,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC,CAAC;AACjG,SAAC,CAAC;AAEF,QAAA,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACrE;;;;;;IAOO,UAAU,CAAC,QAAgB,EAAE,IAAqB,EAAA;AACxD,QAAA,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;AAE9B,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CACvC,QAAQ,EACR,GAAG,CAAC,KAAK,CAAC,EAAE,EACZ,OAAO,EACP,EAAE,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,CAC3D;AACE,aAAA,IAAI,CACH,GAAG,CAAC,MAAK;AACP,YAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AACjE,SAAC,CAAC,EACF,UAAU,CAAC,CAAC,KAAc,KAAI;AAC5B,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAEvD,YAAA,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;SAChC,CAAC,CACH,CAAC;KACL;;;;AAKO,IAAA,YAAY,CAAC,GAAqB,EAAE,OAAiC,EAAE,OAAe,EAAA;AAC5F,QAAA,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE;AAC9B,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YACtE,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAClD;aAAM;YACL,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAC9E,IAAI,CAAC,eAAe,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SACnD;AAED,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAChC,QAAA,eAAe,CAAC,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;KAC1E;IAEO,iBAAiB,CAAC,GAAY,EAAE,GAAY,EAAA;AAClD,QAAA,MAAM,KAAK,GAAG,WAAW,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;QAE1E,IAAI,KAAK,EAAE;AACT,YAAA,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;SACxB;KACF;;;AAIO,IAAA,gBAAgB,CAAC,MAAc,EAAA;AACrC,QAAA,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,YAAY,CAAC;AAChD,aAAA,GAAG,CAAC,CAAC,KAAK,KAAI;AACb,YAAA,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;;;AAG3C,YAAA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AACtE,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;AAErD,YAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,IAAI,YAAY,EAAE,aAAa,IAAI,EAAE,EAAE,CAAC;AAC9F,SAAC,CAAC,CAAC;AAEL,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;AAC7C,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;;;AAI5D,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAClB,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAE9B,OAAO;SACR;;;;;;QAOD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;aAC/E,IAAI,CACH,UAAU,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAC1G,GAAG,CAAC,CAAC,QAAQ,KAAI;YACf,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AACvE,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;SAC/B,CAAC,EACF,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,EAAE,CAAC;KAChB;;;;AAKO,IAAA,UAAU,CAChB,MAAc,EACd,KAAwB,EACxB,QAAwD,EAAA;AAExD,QAAA,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;QAE3C,OAAO;YACL,KAAK;YACL,OAAO,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;AAC7C,YAAA,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;AACxB,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;AACtB,YAAA,QAAQ,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;AACxC,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC;YACnC,aAAa,EAAE,oBAAoB,CAAC,aAAa,EAAE,YAAY,EAAE,QAAQ,IAAI,IAAI,CAAC;AAClF,YAAA,KAAK,EAAE,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC;AACzC,YAAA,GAAG,EAAE,aAAa,CAAC,YAAY,EAAE,GAAG,CAAC;AACrC,YAAA,MAAM,EAAE,EAAE;AACV,YAAA,OAAO,EAAE,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,MAAM;;YAE9C,WAAW,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;AAC5D,YAAA,KAAK,EAAE,YAAY,EAAE,KAAK,IAAI,EAAE;AAChC,YAAA,GAAG,EAAE,YAAY,EAAE,GAAG,IAAI,IAAI;AAC9B,YAAA,GAAG,EAAE,YAAY,EAAE,GAAG,IAAI,IAAI;;;YAG9B,KAAK,EAAE,CAAC,OAAgB,KAAK,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC;SAC7D,CAAC;KACH;AAEO,IAAA,kBAAkB,CAAC,IAAwB,EAAA;AACjD,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;KAC9B;;;AAIO,IAAA,WAAW,CAAC,GAAqB,EAAA;AACvC,QAAA,QAAQ,GAAG,CAAC,KAAK,CAAC,IAAI;AACpB,YAAA,KAAK,WAAW;gBACd,OAAO,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAEpF,YAAA,KAAK,QAAQ;;gBAEX,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;AAEjG,YAAA,KAAK,aAAa;gBAChB,OAAO,kBAAkB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AAE9C,YAAA,KAAK,SAAS,CAAC;YACf,SAAS;gBACP,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAE/B,OAAO,KAAK,GAAG,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;aACjC;SACF;KACF;wGA5gBU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAvB,uBAAuB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3MpC,omfAsXO,EDrMH,MAAA,EAAA,CAAA,yDAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,WAAW,ilDACX,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAvB,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,eAAA,EAAA,cAAA,EAAA,WAAA,EAAA,SAAA,EAAA,eAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,cAAA,EAAA,YAAA,EAAA,mBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,SAAA,EAAA,OAAA,EAAA,WAAA,EAAA,SAAA,EAAA,SAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,UAAA,EAAA,uBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,wBAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,wBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,cAAA,EAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,gaAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,yEAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,aAAa,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,aAAA,EAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACb,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,IAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,cAAc,EACd,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAmB,EAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,uBAAA,EAAA,aAAA,EAAA,MAAA,EAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,eAAe,mHACf,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,EAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,cAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,oBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACZ,gBAAgB,EAChB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,gBAAA,EAAA,qBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,kBAAkB,EAClB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,qBAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,SAAA,EAAA,YAAA,EAAA,MAAA,EAAA,QAAA,EAAA,SAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,yBAAyB,EACzB,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,GAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,UAAA,EAAA,MAAA,EAAA,OAAA,EAAA,aAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,eAAA,EAAA,WAAA,EAAA,aAAA,EAAA,OAAA,EAAA,MAAA,EAAA,WAAA,EAAA,aAAA,EAAA,OAAA,EAAA,eAAA,EAAA,gBAAA,EAAA,cAAA,EAAA,WAAA,EAAA,YAAA,EAAA,OAAA,EAAA,YAAA,EAAA,WAAA,EAAA,SAAA,EAAA,aAAA,EAAA,cAAA,EAAA,UAAA,EAAA,aAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,YAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,SAAA,EAAA,WAAA,EAAA,OAAA,EAAA,aAAA,EAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,GAAA,CAAA,6BAAA,EAAA,QAAA,EAAA,sDAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,aAAa,6oBACb,SAAS,EAAA,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,cAAc,EACd,QAAA,EAAA,sCAAA,EAAA,MAAA,EAAA,CAAA,IAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,gBAAgB,yGAChB,gBAAgB,EAAA,QAAA,EAAA,8DAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,YAAY,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,EAAA,OAAA,EAAA,YAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACZ,QAAQ,EAAA,QAAA,EAAA,WAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACR,OAAO,EACP,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,EACT,QAAA,EAAA,+CAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,QAAQ,EACR,QAAA,EAAA,yHAAA,EAAA,MAAA,EAAA,CAAA,UAAA,EAAA,IAAA,EAAA,aAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,mBAAA,EAAA,kBAAA,EAAA,OAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,SAAS,weACT,SAAS,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,IAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACT,cAAc,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,IAAA,EAAA,eAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,UAAA,EAAA,OAAA,EAAA,UAAA,EAAA,eAAA,EAAA,UAAA,EAAA,SAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,cAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACd,uBAAuB,EAAA,QAAA,EAAA,8BAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGd,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBAhCnC,SAAS;AAGS,YAAA,IAAA,EAAA,CAAA,EAAA,eAAA,EAAA,uBAAuB,CAAC,MAAM,EACnC,UAAA,EAAA,IAAI,EACP,OAAA,EAAA;wBACP,WAAW;wBACX,YAAY;wBACZ,aAAa;wBACb,YAAY;wBACZ,cAAc;wBACd,eAAe;wBACf,YAAY;wBACZ,gBAAgB;wBAChB,kBAAkB;wBAClB,yBAAyB;wBACzB,aAAa;wBACb,SAAS;wBACT,cAAc;wBACd,gBAAgB;wBAChB,gBAAgB;wBAChB,YAAY;wBACZ,QAAQ;wBACR,OAAO;wBACP,SAAS;wBACT,QAAQ;wBACR,SAAS;wBACT,SAAS;wBACT,cAAc;wBACd,uBAAuB;AACxB,qBAAA,EAAA,QAAA,EAAA,omfAAA,EAAA,MAAA,EAAA,CAAA,yDAAA,CAAA,EAAA,CAAA;;AAmhBH;AACA;AACA,SAAS,cAAc,CAAC,KAAc,EAAA;IACpC,MAAM,OAAO,GAAG,KAAoE,CAAC;IACrF,MAAM,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC;AAE5D,IAAA,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,GAAG,OAAO,GAAG,gCAAgC,CAAC;AAC7F,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,KAAwB,EAAE,OAAiC,EAAA;IAC9E,OAAO;AACL,QAAA,GAAG,KAAK;QACR,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;QAC7D,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;AAChE,QAAA,MAAM,EAAE,OAAO,CAAC,OAAO,KAAK,SAAS;AACnC,cAAE,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,SAAS,EAAE;cAC1D,KAAK,CAAC,MAAM;KACjB,CAAC;AACJ,CAAC;AAED;AACA;AACA,SAAS,YAAY,CAAC,OAAe,EAAA;IACnC,OAAO,CAAA,WAAA,EAAc,OAAO,CAAA,CAAE,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,OAAe,EAAA;IAClC,OAAO,CAAA,UAAA,EAAa,OAAO,CAAA,CAAE,CAAC;AAChC;;AE1vBA;AACA;AACA;AACA;AAQA;AACO,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAyBtC;AACA;AACM,SAAU,eAAe,CAAC,KAAgB,EAAA;AAC9C,IAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC;AAC9D,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,KAAK,CAAC,QAAQ;SAC3F,MAAM,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,GAAG,KAAK,GAAG,CAAC;AACxC,SAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;AACnC,SAAA,GAAG,CAAC,CAAC,OAAO,KAAKE,YAAU,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtH,IAAA,MAAM,IAAI,GAAG,CAAC,GAA8B,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;QAC7E,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC;AAEjD,QAAA,OAAOA,YAAU,CACf,OAAO,IAAI,GAAG,CAAC,KAAK,GAAG,CAAG,EAAA,IAAI,CAAC,IAAI,CAAA,EAAA,EAAK,GAAG,CAAC,KAAK,CAAA,CAAA,CAAG,GAAG,IAAI,CAAC,IAAI,EAChE,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EACnE,OAAO,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,EACvB,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CACxB,CAAC;AACJ,KAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AAC1B,QAAA,IAAI,EAAE,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI;QAClD,OAAO;QACP,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC;AACJ,CAAC;AAED;AACA;AACA;SACgB,eAAe,CAAC,KAAgB,EAAE,MAAkB,EAAE,MAAqC,EAAA;IACzG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE;AAClC,SAAA,GAAG,CAAC,CAAC,MAAM,KAAK,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;SAC/H,MAAM,CAAC,CAAC,IAAI,KAAqB,CAAC,CAAC,IAAI,CAAC,CAAC;IAE5C,OAAO;QACL,GAAG,KAAK,CAAC,KAAK;QACd,IAAI,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,GAAG,CAAC,CAAA,kBAAA,EAAqB,KAAK,CAAC,YAAY,CAAO,IAAA,EAAA,KAAK,CAAC,WAAW,CAAU,QAAA,CAAA,CAAC,GAAG,EAAE,CAAC;AAC9H,QAAA,GAAG,OAAO;KACX,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,OAAyB,EAAA;IAC5C,OAAO,OAAO,CAAC,IAAI,GAAG,CAAA,EAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,IAAI,CAAG,CAAA,CAAA,GAAG,OAAO,CAAC,KAAK,CAAC;AAC7E,CAAC;AAED,SAASA,YAAU,CAAC,IAAY,EAAE,IAAa,EAAE,MAAc,EAAE,OAAgB,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAA;AACzG,IAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC3D;;ACgHA;AACA;AACA,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;AACA;AACA;AACO,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAEpD;AACA;AACA,MAAM,uBAAuB,GAAG,EAAE,CAAC;AA0BnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,UAAU,CAAC,IAAwB,EAAA;IACjD,OAAO,IAAI,CAAC,IAAI,GAAG,SAAS,GAAG,wBAAwB,CAAC;AAC1D,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,WAAW,CACzB,SAA0B,EAC1B,MAAwB,EACxB,MAAsB,EACtB,MAAiC,EACjC,QAAQ,GAAG,KAAK,EAAA;AAEhB,IAAA,MAAM,KAAK,GAAG,YAAY,CAAC,eAAe,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;IAEnF,IAAI,QAAQ,EAAE;QACZ,OAAO,KAAK,GAAG,CAAA,EAAG,KAAK,CAAA,WAAA,CAAa,GAAG,UAAU,CAAC;KACnD;IAED,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,KAAK,CAAC;KACd;AAED,IAAA,OAAO,KAAK,GAAG,GAAG,KAAK,CAAA,YAAA,EAAe,MAAM,CAAA,EAAA,CAAI,GAAG,CAAa,UAAA,EAAA,MAAM,GAAG,CAAC;AAC5E,CAAC;AAED;AACM,SAAU,QAAQ,CAAC,IAAwB,EAAA;AAC/C,IAAA,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;AACtD,CAAC;AAED;AACA;AACA;SACgB,YAAY,CAAC,SAA0B,EAAE,IAAY,EAAE,MAAwB,EAAA;IAC7F,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAEzF,OAAO;QACL,WAAW,EAAE,SAAS,CAAC,EAAE;QACzB,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,uBAAuB,GAAG,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC,OAAO,EAAE,CAAG,CAAA,CAAA,GAAG,IAAI;KAC/G,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,UAAU,CAAC,SAA0B,EAAA;IACnD,OAAO;AACL,QAAA,eAAe,CACb,IAAI,IAAI,EAAE,EACV,SAAS,CAAC,aAAa,CAAC,MAAM,EAC9B,QAAQ,EACR,qBAAqB,CAAC,SAAS,CAAC,MAAM,CAAC,CACxC;QACD,GAAG,SAAS,CAAC,aAAa;QAC1B,GAAG,SAAS,CAAC,YAAY;KAC1B,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,UAAU,CACxB,KAAc,EACd,MAAkD,EAClD,QAAgB,EAChB,OAA4B,EAC5B,GAAoC,EAAA;AAEpC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,IAAI,MAAM,EAAE;QACV,OAAO,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;YAC9D,WAAW,EAAE,MAAM,CAAC,WAAW;AAC/B,YAAA,KAAK,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,SAAS;YACpE,KAAK,EAAE,MAAM,CAAC,KAAK;AACnB,YAAA,KAAK,EAAE,EAAE;SACV,CAAC,CAAC,IAAI,CAAC;KACT;IAED,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;AACzC,QAAA,OAAO,EAAE,CAAC;KACX;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,sBAAsB,CAAC,IAAI,EAAE;QACjD,OAAO,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;KAC1D;AAED,IAAA,OAAO,eAAe,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;AACvG,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,WAAW,CACzB,SAA0B,EAC1B,IAAmB,EACnB,MAAuB,EACvB,MAAA,GAA4B,EAAE,EAAA;IAE9B,MAAM,MAAM,IAAI,SAAS,CAAC,MAAM,IAAI,EAAE,CAAe,CAAC;AAEtD,IAAA,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE;AAC1B,QAAA,OAAO,iBAAiB,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;KAC5E;AAED,IAAA,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE;QAC1B,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEtD,QAAA,OAAO,iBAAiB,CACtB,MAAM,CAAC,OAAO;AACX,aAAA,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;aACxD,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EACrE,IAAI,EACJ,MAAM,CAAC,OAAO,CACf,CAAC;KACH;AAED,IAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;AACjG,CAAC;AAED;AACA;AACA;AACA,SAAS,iBAAiB,CACxB,OAA2B,EAC3B,IAAmB,EACnB,QAA+B,EAAA;AAE/B,IAAA,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;AACjB,QAAA,OAAO,OAAO,CAAC;KAChB;IAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAE3D,IAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;AACpD,UAAE,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;AAC9D,UAAE,MAAM,CAAC,CAAC,CAAC;AACf,CAAC;AAED;AACA;AACM,SAAU,YAAY,CAC1B,SAA0B,EAC1B,IAAmB,EACnB,MAAuB,EACvB,MAAA,GAA4B,EAAE,EAAA;IAE9B,OAAO,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AACrG,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,aAAa,CAC3B,IAAmB,EACnB,OAAoC,EACpC,QAAgB,EAChB,OAA4B,EAAA;AAE5B,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE3B,IAAI,CAAC,MAAM,EAAE;AACX,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAErD,IAAA,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK;AACrD,UAAE,gBAAgB;UAChB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,iBAAiB,CAAC,IAAwB,EAAE,QAAgB,EAAE,MAAuB,EAAA;AACnG,IAAA,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,EAAE;AAC/C,QAAA,OAAO,EAAE,CAAC;KACX;AAED,IAAA,OAAO,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED;AACA;AACA;AACA;AACA;SACgB,eAAe,CAAC,IAAwB,EAAE,QAAgB,EAAE,MAAuB,EAAA;IACjG,OAAO;QACL,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;AACpG,QAAA,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;KAC3B,CAAC;AACJ,CAAC;AAED;AACM,SAAU,WAAW,CAAC,IAAwB,EAAA;IAClD,OAAO,IAAI,CAAC,KAAK;AACf,UAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;UAC/C,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC;AAC/B,CAAC;AAED;AACA;AACgB,SAAA,gBAAgB,CAAC,IAAiB,EAAE,KAAwB,EAAA;IAC1E,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;AACxF,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,cAAc,CAC5B,IAAiB,EACjB,KAAwB,EACxB,SAAiB,EACjB,OAAyB,EAAA;AAEzB,IAAA,MAAM,KAAK,GAAmB;AAC5B,QAAA,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK;AACnB,QAAA,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;AACrB,QAAA,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;AACrB,QAAA,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AACnE,QAAA,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC;AACjB,QAAA,KAAK,EAAE,CAAC;KACT,CAAC;AACF,IAAA,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAE3D,IAAA,IAAI,MAAM,EAAE,GAAG,SAAS,EAAE;AACxB,QAAA,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC;KACzB;AAED,IAAA,IAAI,MAAM,EAAE,GAAG,SAAS,EAAE;AACxB,QAAA,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;KACtB;IAED,OAAO,MAAM,EAAE,GAAG,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE;AACjD,QAAA,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;KACnB;IAED,IAAI,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;AACxC,QAAA,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;KACtB;AAED,IAAA,IAAI,MAAM,EAAE,GAAG,SAAS,EAAE;QACxB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;KACjF;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAED;AACA;AACgB,SAAA,gBAAgB,CAAC,OAAyB,EAAE,KAAa,EAAA;IACvE,OAAO;AACL,QAAA,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,KAAK;AAC5B,QAAA,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,KAAK;AAC5B,QAAA,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,KAAK;AAC5B,QAAA,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,KAAK;AAC9B,QAAA,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,KAAK;AAC9B,QAAA,SAAS,EAAE,OAAO,CAAC,SAAS,GAAG,KAAK;AACpC,QAAA,IAAI,EAAE,OAAO,CAAC,IAAI,GAAG,KAAK;KAC3B,CAAC;AACJ,CAAC;AAED;SACgB,eAAe,CAAC,IAAiB,EAAE,KAAqB,EAAE,OAAyB,EAAA;IACjG,OAAO,OAAO,CAAC,KAAK;AAChB,WAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;AAChC,WAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;AACjC,WAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AACnC,WAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AACnC,WAAC,KAAK,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;UACzC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;AACxC,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,cAAc,CAAC,SAAiB,EAAA;IAC9C,OAAO,CAAA,EAAA,EAAK,SAAS,CAAA,kEAAA,CAAoE,CAAC;AAC5F,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACM,SAAU,eAAe,CAAC,SAA0B,EAAA;;;AAGxD,IAAA,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK;AAC1B,SAAA,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;AACnD,SAAA,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;WAC/C,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;SACvF,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,QAAQ,MAAM,CAAA,CAAE,CAAC,CAAC;AACjE,IAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAE3E,IAAA,IAAI,MAAM,IAAI,WAAW,IAAI,gBAAgB,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,kBAAkB,CAAC,EAAE;AAC9F,QAAA,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;KAChC;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAED;AACA,SAAS,gBAAgB,CAAC,UAA6B,EAAE,MAAyB,EAAA;AAChF,IAAA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU;SAC7B,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;AAChD,SAAA,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAE9D,IAAA,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;AACA;AACA;AACA;AACA;AACM,SAAU,gBAAgB,CAC9B,QAA8B,EAC9B,KAAkC,EAClC,KAAmD,EACnD,MAAA,GAA2C,EAAE,EAAA;IAE7C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC1G,MAAM,OAAO,GAAG,KAAK;SAClB,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC;AAClC,SAAA,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AACvC,SAAA,GAAG,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/F,OAAO;QACL,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC;AACzE,QAAA,GAAG,OAAO;QACV,KAAK;AACN,KAAA;SACE,MAAM,CAAC,CAAC,IAAI,KAAqB,CAAC,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC;AAED;AACA;AACA;AACA;AACM,SAAU,YAAY,CAAC,SAA0B,EAAA;IACrD,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;AACxD,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,4BAA4B,CAAA;AAE/B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,cAAc,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;;;;;;;;IASrD,OAAO,CAAC,MAAc,EAAE,QAAgB,EAAA;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACvC,QAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;;;;;;AAO7C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM;cACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;iBAC/C,IAAI,CACHC,UAAQ,CACN,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC;iBAC9D,IAAI,CAACT,KAAG,CAAC,CAAC,MAAM,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAC7C,kBAAkB,CACnB,EACD,OAAO,EAAE,CACV;AACH,cAAE,EAAE,CAAC,EAAgD,CAAC,CAAC;;;;AAKzD,QAAA,OAAO,QAAQ,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;aAChF,IAAI,CACHA,KAAG,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAI;AAC7B,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;YAE1D,OAAO;gBACL,MAAM;AACN,gBAAA,GAAG,IAAI;AACP,gBAAA,aAAa,EAAE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;gBACpF,YAAY,EAAE,OAAO,CAAC,YAAY;AAClC,gBAAA,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;gBACxC,aAAa;aACd,CAAC;SACH,CAAC,CACH,CAAC;KACL;;;;;;;AAQM,IAAA,QAAQ,CAAC,MAAc,EAAA;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;aAC9B,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;aACxC,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5C,QAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;AACpC,aAAA,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAErD,OAAO;YACL,KAAK;AACL,YAAA,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;AAC5B,YAAA,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxG,YAAA,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM;iBACpC,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC5E,YAAA,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAChG,YAAA,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK;iBACrC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAU,CAAC;AACxE,iBAAA,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;AAC1C,YAAA,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;AACxC,YAAA,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC,cAAc,CAAC;AACtD,YAAA,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE;SACjD,CAAC;KACH;;;;;;;AAQM,IAAA,aAAa,CAClB,MAAc,EACd,QAA8B,EAC9B,SAAwB,IAAI,EAAA;QAE5B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEtC,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;AAC/C,aAAA,IAAI,CACH,SAAS,CAAC,CAAC,YAAY,KAAI;AACzB,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;AAEhE,YAAA,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC5D,iBAAA,IAAI,CAACA,KAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;SAC5D,CAAC,CACH,CAAC;KACL;;;;;AAMO,IAAA,aAAa,CACnB,MAAc,EACd,MAAqB,EACrB,MAAuC,EAAA;QAEvC,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;AAC1C,aAAA,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACvC,aAAA,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC;aACnD,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAI;AAC3B,YAAA,MAAM,MAAM,GAAqB;gBAC/B,UAAU,EAAE,KAAK,GAAG,CAAC;gBACrB,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,CAAQ,KAAA,EAAA,KAAK,GAAG,CAAC,CAAE,CAAA;gBAC1C,UAAU,EAAE,MAAM,CAAC,IAAI;AACvB,gBAAA,OAAO,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;aACvE,CAAC;AAEF,YAAA,OAAO,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE;AAC1B,iBAAA,MAAM,CAAC,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;iBAC7D,GAAG,CAAC,CAAC,SAAS,KAAuB,CAAC,SAAS,CAAC,EAAE,EAAE,eAAe,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;SACnG,CAAC,CAAC,CAAC;KACP;;;;;;;;AASO,IAAA,KAAK,CAAC,MAAc,EAAA;QAC1B,MAAM,IAAI,GAAiB,EAAE,CAAC;QAE9B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,KAAI;AACvC,YAAA,IAAI,CAAC,UAAU;iBACZ,MAAM,CAAC,YAAY,CAAC;iBACpB,OAAO,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAClF,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AAClD,SAAC,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE;AACpE,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;SACrD;AAED,QAAA,OAAO,IAAI,CAAC;KACb;;IAGO,WAAW,CAAC,KAAgC,EAAE,SAAwB,EAAA;AAC5E,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;AAChF,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAEzC,OAAO,KAAK,CAAC,MAAM;cACf,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;cAC5E,EAAE,CAAC;KACR;;AAGO,IAAA,OAAO,CACb,MAAc,EACd,GAAe,EACf,QAAgB,EAChB,QAA8B,EAAA;AAE9B,QAAA,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE;AAC5B,YAAA,OAAO,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;iBAClE,IAAI,CAACA,KAAG,CAAC,CAAC,IAAI,MAAqB,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;SAChG;AAED,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC;aAC9E,IAAI,CAACA,KAAG,CAAC,CAAC,SAAS,MAAqB,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;KACvG;AAEO,IAAA,cAAc,CACpB,MAAc,EACd,SAA0B,EAC1B,QAAgB,EAChB,QAA8B,EAAA;AAE9B,QAAA,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE;AAC7B,YAAA,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;SACzD;AAED,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AAErD,QAAA,IAAI,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE;YAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;SAC7G;;;;;;AAOD,QAAA,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;AACtD,QAAA,MAAM,KAAK,GAAuB,SAAS,CAAC,IAAI,KAAK,MAAM;AACzD,cAAE,EAAE,GAAG,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE;AAC/C,cAAE,EAAE,GAAG,SAAS,EAAE,CAAC;;;;AAIrB,QAAA,MAAM,aAAa,GAAG,CAAC,IAAI,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;;;;QAKvD,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;aACtG,IAAI,CACHA,KAAG,CAAC,CAAC,IAAmB,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,EACrG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAC/D,CAAC;KACL;;;AAIO,IAAA,UAAU,CAAC,MAAc,EAAE,IAAqB,EAAE,KAA0B,EAAA;QAClF,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAEvF,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KACjF;;;;;;;;IASO,UAAU,CAChB,MAAc,EACd,SAA0B,EAC1B,OAA8B,EAC9B,KAAyB,EACzB,IAAY,EACZ,QAA8B,EAAA;AAE9B,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC;AAC7C,QAAA,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,CAAC,CAAC;AACzH,QAAA,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;YACvC,MAAM,EAAE,QAAQ,CAAC,aAAa;AAC9B,YAAA,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;AACtC,YAAA,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;AACxB,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,SAAS,GAAkB;YAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,KAAK,MAAM,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;YAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,KAAK,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC;SAChF,CAAC;QACF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAC7D,QAAA,MAAM,MAAM,GAAG;YACb,OAAO;YACP,IAAI,KAAK,CAAC,gBAAgB,EAAE,MAAM,GAAG,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC;AACvF,YAAA,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC;SAC3D,CAAC;QAEF,OAAO,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,cAAc,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,mBAAmB,EAAE,EAAE,SAAS,CAAC;aACrI,IAAI,CACHA,KAAG,CAAC,CAAC,KAAK,MAA0B;YAClC,SAAS;AACT,YAAA,IAAI,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAmB;AAC5E,YAAA,aAAa,EAAE,EAAE;YACjB,KAAK;YACL,UAAU,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;SAC7D,CAAC,CAAC,EACH,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC,CACnE,CAAC;KACL;;;;;IAMO,UAAU,CAChB,SAA0B,EAC1B,IAAmB,EACnB,MAA0B,EAC1B,aAAuB,EACvB,QAA8B,EAAA;QAE9B,MAAM,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;QAErC,OAAO;YACL,SAAS;YACT,IAAI;AACJ,YAAA,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YAClD,aAAa;YACb,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;SACnF,CAAC;KACH;;;;AAKO,IAAA,YAAY,CAAC,MAAc,EAAA;QACjC,MAAM,MAAM,GAAqC,EAAE,CAAC;QACpD,MAAM,OAAO,GAAwC,EAAE,CAAC;AAExD,QAAA,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC,KAAK,KAAI;AAC5C,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAChD,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAEtD,IAAI,KAAK,EAAE;AACT,gBAAA,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG;AACjB,oBAAA,GAAG,KAAK;oBACR,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;oBACtD,IAAI,KAAK,CAAC,aAAa,GAAG,EAAE,aAAa,EAAE,CAAC,GAAG,KAAK,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;iBAC5E,CAAC;aACH;YACD,IAAI,MAAM,EAAE;AACV,gBAAA,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;aAC5B;AACH,SAAC,CAAC,CAAC;AAEH,QAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;KAC5B;;;;;;;;;;;;IAaO,WAAW,CACjB,MAAc,EACd,MAAc,EACd,MAAyB,EACzB,KAAwB,EACxB,QAA8B,EAAA;AAE9B,QAAA,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AACzF,QAAA,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEhF,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,gBAAgB,CAAC;aACxG,IAAI,CACHA,KAAG,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAChE,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,EAA2B,CAAC,CAAC,EACxDA,KAAG,CAAC,CAAC,IAAI,MAAM;YACb,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,aAAa,CAAC;AACnD,YAAA,YAAY,EAAE,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC;SAC3C,CAAC,CAAC,CACJ,CAAC;KACL;;;;AAKO,IAAA,KAAK,CACX,MAAc,EACd,OAAmD,EACnD,aAAkC,EAAA;AAElC,QAAA,MAAM,MAAM,GAAG,CAAC,MAAqC,MAAuB;AAC1E,YAAA,MAAM,EAAE,UAAU,CAAC,MAAM,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,aAAa,CAAC;AACpE,YAAA,YAAY,EAAE,EAAE;AACjB,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,KAAK,GAAoB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9G,IAAI,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE3C,CAAC,GAAG,OAAO,CAAC;AACT,aAAA,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;AACjC,aAAA,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,KAAI;AACtB,YAAA,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE;AAC/B,gBAAA,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;aACtD;AAAM,iBAAA,IAAI,MAAM,CAAC,SAAS,KAAK,IAAI,EAAE;AACpC,gBAAA,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC;aAC3B;iBAAM;AACL,gBAAA,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;aAC1D;AACH,SAAC,CAAC,CAAC;AAEL,QAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;KACxF;;;;;;AAOO,IAAA,aAAa,CAAC,MAAc,EAAA;QAClC,OAAO;AACL,YAAA,IAAI,MAAM,CAAC,iBAAiB,GAAG,CAAC,CAAA,UAAA,EAAa,MAAM,CAAC,iBAAiB,CAAE,CAAA,CAAC,GAAG,EAAE,CAAC;AAC9E,YAAA,IAAI,MAAM,CAAC,iBAAiB,GAAG,CAAC,CAAA,UAAA,EAAa,MAAM,CAAC,iBAAiB,CAAE,CAAA,CAAC,GAAG,EAAE,CAAC;SAC/E,CAAC;KACH;;;;;;AAOO,IAAA,aAAa,CACnB,MAAc,EACd,QAA8B,EAC9B,KAAsC,EAAA;AAEtC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM;aAClB,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;aAC1E,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AAC3E,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM;cACxB,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AACnE,cAAE,EAAE,CAAC,EAAgB,CAAC,CAAC;QAEzB,OAAO,MAAM,CAAC,IAAI,CAChBA,KAAG,CAAC,CAAC,KAAK,KAAI;AACZ,YAAA,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpF,YAAA,OAAO,gBAAgB,CACrB,MAAM,EACN,CAAC,OAAO,KAAK,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EACrC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAC7B,CAAC,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CACjC,CAAC;SACH,CAAC,CACH,CAAC;KACH;;;;;;;;;;;;;;AAeO,IAAA,UAAU,CAAC,MAAc,EAAA;QAC/B,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAErD,QAAA,OAAO,CAAC,KAAK,EAAE,MAAM,KAAK,mBAAmB,CAC3C,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,EACzB,MAAM,EACN,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CACtD;aACE,IAAI,CACHA,KAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,EACpD,UAAU,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACzD,CAAC;KACL;wGA7cU,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAA5B,4BAA4B,EAAA,CAAA,CAAA;;4FAA5B,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBADxC,UAAU;;;ACjoBX;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,gBAAgB,CACpC,SAA0B,EAC1B,IAAmB,EACnB,KAAa,EACb,MAAc,EACd,OAA4B,EAC5B,UAAU,GAAG,CAAC,EAAA;;IAGd,MAAM,OAAO,GAAG,CAAC,MAAM,OAAO,0CAAkB,CAAC,EAAE,OAAO,CAAC;IAE3D,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAG,EAAA,KAAK,IAAI,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAG,EAAA,MAAM,IAAI,CAAC;IAElC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE;AACzC,QAAA,QAAQ,EAAE,QAAQ;QAClB,KAAK;QACL,MAAM;AACP,KAAA,CAAC,CAAC;AAEH,IAAA,IAAI;QACF,KAAK,CAAC,SAAS,CAAC;AACd,YAAA,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;AAC7C,YAAA,SAAS,EAAE,KAAK;AACjB,SAAA,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,UAAU,CAAC;AACtB,YAAA,IAAI,EAAE,KAAK;YACX,UAAU;AACV,YAAA,eAAe,EAAE,SAAS;AAC3B,SAAA,CAAC,CAAC;KACJ;YAAS;QACR,KAAK,CAAC,OAAO,EAAE,CAAC;KACjB;AACH;;ACIA;AACA;AACA;AACO,MAAM,cAAc,GAAG,CAAC,GAAG,WAAW,CAAC;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,uBAAuB,CAAA;AAEjB,IAAA,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AACjC,IAAA,oBAAoB,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AACnD,IAAA,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC7B,IAAA,QAAQ,GAAG,IAAI,GAAG,EAAoC,CAAC;;;;AAKjE,IAAA,MAAM,OAAO,CAAC,SAA0B,EAAE,MAAwB,EAAA;QACvE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;AAC1C,QAAA,MAAM,GAAG,GAAG;AACV,YAAA,SAAS,CAAC,EAAE;AACZ,YAAA,SAAS,CAAC,CAAC;AACX,YAAA,SAAS,CAAC,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC;AACjD,YAAA,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC;AAC7B,SAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEZ,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;;AAE/B,YAAA,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;SAC/C;AAED,QAAA,OAAO,MAAM,CAAC;KACf;AAEO,IAAA,MAAM,OAAO,CAAC,SAA0B,EAAE,IAAY,EAAE,MAAwB,EAAA;AACtF,QAAA,MAAM,IAAI,GAAG,eAAe,CAAC,sBAAsB,EAAE;YACnD,mBAAmB,EAAE,IAAI,CAAC,oBAAoB;YAC9C,eAAe,EAAE,IAAI,CAAC,SAAS;AAChC,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AAE7D,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC5B,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAChC,YAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAChC,YAAA,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1B,YAAA,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;;;YAG3B,GAAG,CAAC,qBAAqB,EAAE,CAAC;AAC5B,YAAA,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;AAE3B,YAAA,OAAO,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;SACjF;gBAAS;;YAER,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,EAAE,CAAC;SACd;KACF;;;;;;AAOO,IAAA,SAAS,CAAC,IAA0C,EAAA;AAC1D,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;AAC7B,YAAA,eAAe,CAAC,MAAM,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;YAC1E,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzC,SAAC,CAAC,CAAC;KACJ;wGAnEU,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAvB,uBAAuB,EAAA,CAAA,CAAA;;4FAAvB,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBADnC,UAAU;;AAuEX;AACA;AACA;AACA,SAAS,QAAQ,CAAC,SAA0B,EAAE,IAAiB,EAAA;IAC7D,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAE3C,IAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE;AACvB,QAAA,QAAQ,EAAE,OAAO;AACjB,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,GAAG,EAAE,GAAG;AACR,QAAA,UAAU,EAAE,QAAQ;AACpB,QAAA,KAAK,EAAE,CAAG,EAAA,SAAS,CAAC,CAAC,GAAG,WAAW,CAAI,EAAA,CAAA;AACvC,QAAA,MAAM,EAAE,CAAG,EAAA,SAAS,CAAC,CAAC,GAAG,WAAW,CAAI,EAAA,CAAA;AACxC,QAAA,SAAS,EAAE,YAAY;AACvB,QAAA,MAAM,EAAE,uBAAuB;AAC/B,QAAA,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC;AACxC,KAAA,CAAC,CAAC;AACH,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;AAC3B,IAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAClB,IAAA,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAEjB,IAAA,OAAO,GAAG,CAAC;AACb,CAAC;AAED;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,OAAoB,EAAA;AACxC,IAAA,MAAM,GAAG,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;AAC5C,IAAA,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAiC,EAAE,CAAC;IAClD,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AAC5B,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;AACvB,YAAA,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClF,YAAA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,YAAA,UAAU,GAAG,OAAO,EAAE,MAAM,IAAI,UAAU,CAAC;SAC5C;aAAM;YACL,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACtC,YAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,UAAU,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;SACvC;AACH,KAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEzC,OAAO;AACL,QAAA,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;QAC/B,aAAa;QACb,UAAU;AACV,QAAA,QAAQ,EAAE,UAAU,GAAG,aAAa,GAAG,cAAc;QACrD,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,KAAa,EAAE,QAAiB,EAAA;IAClD,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;AACd,IAAA,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;AAEvB,IAAA,OAAO,KAAK,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;AAC1C,QAAA,KAAK,EAAE,CAAC;KACT;AACD,IAAA,OAAO,GAAG,GAAG,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE;AAC/C,QAAA,GAAG,EAAE,CAAC;KACP;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtC,IAAA,IAAI,QAAQ,IAAI,KAAK,CAAC,MAAM,EAAE;QAC5B,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;KACzC;AAED,IAAA,OAAO,KAAK,CAAC;AACf,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc,CAAC,IAAU,EAAA;AAChC,IAAA,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;AAC3B,IAAA,OAAO,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;AAC9B,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,eAAe,CAAC;AACvC,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAClB,KAAK,CAAC,MAAM,EAAE,CAAC;SAChB;QACD,KAAK,GAAG,QAAQ,CAAC;KAClB;IAED,IAAI,KAAK,EAAE;QACT,cAAc,CAAC,KAAK,CAAC,CAAC;KACvB;AACH,CAAC;AAED;AACA,SAAS,MAAM,CAAC,IAAU,EAAA;AACxB,IAAA,OAAO,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS;UACnC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;UAC5C,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,CAAC;AAC1C,CAAC;AAED;AACA;AACA,SAAS,OAAO,CAAC,IAAU,EAAA;IACzB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC;AAC3C,CAAC;AAED;AACA;AACA,SAAS,cAAc,CAAC,KAAa,EAAE,GAAY,EAAA;AACjD,IAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;AACjB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,IAAA,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3C,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC;IAE3C,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,SAAS,YAAY,CAAC,KAAuB,EAAE,GAAY,EAAA;AACzD,IAAA,MAAM,IAAI,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC;IAE3C,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAClC,QAAA,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;AACzB,QAAA,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,CAAC;AACvF,QAAA,YAAY,EAAE,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED;AACA;AACA;AACA;AACA;AACA,SAAS,YAAY,CAAC,KAAuB,EAAE,KAAa,EAAA;AAC1D,IAAA,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAC/B,IAAA,MAAM,MAAM,GAAsB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,IAAI,CAAC,CAAC;IAEnF,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,KAAI;AACzE,QAAA,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;YACtD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC;SAC3F;KACF,CAAC,CAAC,CAAC;AAEJ,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAsB,KAAK,KAAK,IAAI,CAAC,CAAC;AACxE,IAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC1F,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC;AACrD,IAAA,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IAE1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,GAAG,CAAC,MAAgB,EAAA;AAC3B,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,MAAM,CAAC,MAAc,EAAA;IAC5B,OAAO,MAAM,GAAG,WAAW,CAAC;AAC9B;;ACjRA;AACA,MAAM,EAAE,GAAG,EAAE,CAAC;AAEd;AACA,MAAMU,SAAO,GAAG,EAAE,CAAC;AAEnB;AACA;AACA;AACA;AACA,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAMC,YAAU,GAAG,EAAE,CAAC;AACtB,MAAMC,aAAW,GAAG,EAAE,CAAC;AACvB,MAAMC,YAAU,GAAG,EAAE,CAAC;AACtB,MAAMC,aAAW,GAAG,CAAI,CAAA,EAAA,uBAAuB,EAAE,CAAC;AAElD;AACA;AACA;AACA,MAAMC,aAAW,GAAqB;AACpC,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,MAAM,EAAEH,aAAW;IACnB,MAAM,EAAEA,aAAW,GAAG,CAAC;AACvB,IAAA,SAAS,EAAE,EAAE;AACb,IAAA,IAAI,EAAEA,aAAW;CAClB,CAAC;AACF,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,cAAc,GAAG,CAAC,CAAC;AACzB;AACA,MAAMI,WAAS,GAAG,CAAC,CAAC;AACpB,MAAMC,eAAa,GAAG,CAAC,CAAC;AACxB;AACA,MAAMC,WAAS,GAAG,GAAG,CAAC;AACtB,MAAMC,WAAS,GAAG,CAAC,CAAC;AACpB,MAAMC,iBAAe,GAAG,CAAI,CAAA,EAAA,sBAAsB,EAAE,CAAC;AACrD;AACA,MAAMC,iBAAe,GAAG,GAAG,CAAC;AAC5B,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB;AACA;AACA;AACA;AACO,MAAM,aAAa,GAAG,GAAG,CAAC;AAEjC;AACA;AACA;AACA,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAC;AACnC,MAAM,cAAc,GAAG,GAAG,GAAG,EAAE,CAAC;AAChC,MAAM,QAAQ,GAAuB,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;AAE1E;AACA,MAAM,gBAAgB,GAAG,kCAAkC,CAAC;AAE5D;AACA;AACA;AACA,MAAM,cAAc,GAAG,mDAAmD,CAAC;AAE3E;AACA,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;AACA,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAE1C;AACA;AACA,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAE5D;AACA;AACA,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;AACA;AACA,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;AACA;AACA,MAAM,iBAAiB,GAAG,+CAA+C,CAAC;AAsF1E;AACA,MAAMC,aAAW,GAAG,CAAC,CAAC;AAqCtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,gBAAgB,CAAA;AAEV,IAAA,WAAW,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAExD,MAAM,KAAK,CAAC,SAA0B,EAAA;QAC3C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAE/C,QAAA,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;;;QAItE,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,QAAA,KAAK,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE;YAC9D,MAAM,SAAS,GAAuB,EAAE,CAAC;YACzC,UAAU,IAAI,CAAC,CAAC;AAEhB,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;;;AAI7E,YAAA,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;AAChC,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;gBAEhF,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAW;AAC1F,oBAAA,UAAU,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AACxG,iBAAC,CAAC,CAAC;aACJ;SACF;QAED,OAAO;YACL,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;AAC9C,YAAA,YAAY,EAAE,iBAAiB;YAC/B,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACtC,IAAI,EAAE,MAAK;AACT,gBAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA,EAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,IAAA,CAAM,CAAC,CAAC;aAC9D;SACF,CAAC;KACH;IAEO,MAAM,QAAQ,CAAC,SAA0B,EAAA;AAC/C,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAChC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,OAAO,CAAC,CAAC;AACxC,QAAA,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAE3F,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;AACpC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;AACrC,QAAA,MAAM,WAAW,GAAG,KAAK,IAAI,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;QAE9D,OAAO;AACL,YAAA,GAAG,EAAE,IAAI,KAAK,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;YACnE,SAAS;YACT,WAAW;YACX,KAAK;YACL,MAAM;AACN,YAAA,QAAQ,EAAE,qBAAqB,CAAC,MAAM,CAAC;YACvC,aAAa,EAAE,SAAS,CAAC,aAAa;YACtC,KAAK;YACL,KAAK;YACL,WAAW;YACX,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC;YACrD,YAAY,EAAE,SAAS,CAAC,YAAY;AACpC,YAAA,aAAa,EAAE,iBAAiB,CAAC,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC;YACzF,aAAa,EAAE,IAAI,GAAG,EAAE;YACxB,OAAO,EAAE,IAAI,GAAG,EAAE;SACnB,CAAC;KACH;;;;IAKO,MAAM,WAAW,CACvB,OAAyB,EACzB,aAA4B,EAC5B,KAAa,EACb,UAAkB,EAClB,SAA6B,EAAA;AAE7B,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AACxB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;AAC5E,QAAA,MAAM,UAAU,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;AAEhF,QAAA,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;AACjE,QAAA,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAE9D,QAAA,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,UAAU,EAAE;YAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,YAAW;gBACzF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE;AAClC,oBAAA,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;iBACnF;AAAM,qBAAA,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;AACtE,oBAAA,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;iBAC5E;AACH,aAAC,CAAC,CAAC;SACJ;KACF;;;;;AAMO,IAAA,MAAM,QAAQ,CACpB,OAAyB,EACzB,SAA0B,EAC1B,IAAY,EACZ,MAAwB,EACxB,KAAc,EACd,IAAyB,EAAA;AAEzB,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QACxB,MAAM,OAAO,GAAG,GAAG,CAAC,kBAAkB,EAAE,CAAC,UAAU,CAAC;AACpD,QAAA,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC;AAErC,QAAA,IAAI;YACF,MAAM,IAAI,EAAE,CAAC;SACd;QAAC,OAAO,KAAK,EAAE;;AAEd,YAAA,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAErB,YAAA,OAAO,GAAG,CAAC,gBAAgB,EAAE,GAAG,KAAK,EAAE;gBACrC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;aACxC;AAED,YAAA,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAErB,IAAI,KAAK,EAAE;AACT,gBAAA,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;aAClC;AAED,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;gBACtC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE;oBAChC,WAAW,EAAE,SAAS,CAAC,EAAE;oBACzB,IAAI;AACJ,oBAAA,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,MAAM;0BAC3B,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO;AAC/C,0BAAE,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC;AACnC,iBAAA,CAAC,CAAC;aACJ;SACF;KACF;;;IAIO,WAAW,CAAC,GAAQ,EAAE,SAA0B,EAAA;AACtD,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAE3B,QAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAC5B,QAAA,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1B,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;KAC9C;;;;AAKO,IAAA,MAAM,aAAa,CAAC,OAAyB,EAAE,IAAgB,EAAE,MAAwB,EAAA;AAC/F,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;YACrB,OAAO;SACR;AAED,QAAA,MAAM,YAAY,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QAEjG,KAAK,MAAM,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;AACjF,YAAA,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,IAAI,EAAE,YAAW;AACzF,gBAAA,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;oBAC5D,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAC;iBAC5E;AACH,aAAC,CAAC,CAAC;SACJ;KACF;;;;AAKO,IAAA,eAAe,CACrB,OAAyB,EACzB,SAA0B,EAC1B,IAAY,EACZ,MAAwB,EAAA;AAExB,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;AAC5C,YAAA,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;SAChF;KACF;AAEO,IAAA,UAAU,CAAC,GAAQ,EAAE,SAA0B,EAAE,KAAa,EAAE,KAAa,EAAA;AACnF,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjC,QAAA,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACpB,QAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAC5B,QAAA,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;AAElD,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACpB,QAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAE5B,QAAA,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;KAC3F;;;;;;;;AASO,IAAA,MAAM,WAAW,CACvB,OAAyB,EACzB,SAA0B,EAC1B,MAAwB,EAAA;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACrC,QAAA,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;AAChE,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC;cACzD,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;cACjD,IAAI,CAAC;AACT,QAAA,IAAI,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;QACtB,IAAI,UAAU,GAAG,CAAC,CAAC;;;;QAInB,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,QAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC1B,YAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM;AACjC,kBAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC;AACnE,kBAAE,IAAI,CAAC,cAAc,CACnB,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,IAAI,IAAI,EAAE,GAAG,EAC/D,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,iBAAiB,CACjD,CAAC;AAEJ,YAAA,IAAI,KAAK,CAAC,GAAG,EAAE;AACb,gBAAA,OAAO,IAAI,CAAC;aACb;AAED,YAAA,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AACxB,YAAA,QAAQ,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SAC7E;AAED,QAAA,OAAO,KAAK,CAAC;KACd;;;AAIO,IAAA,QAAQ,CAAC,SAA0B,EAAA;AACzC,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AAC1C,QAAA,MAAM,KAAK,GAAG,CAAC,KAAyB,KAAK,CAAC,KAAK,IAAI,yBAAyB,IAAI,EAAE,CAAC;QAEvF,OAAO;AACL,YAAA,IAAI,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AAC7C,YAAA,GAAG,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC;AAC3C,YAAA,KAAK,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC;AACtE,YAAA,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC;SAClE,CAAC;KACH;;;;;AAMO,IAAA,eAAe,CAAC,GAAQ,EAAE,UAA2B,EAAE,GAAe,EAAE,OAAe,EAAA;QAC7F,IAAI,CAAC,GAAG,OAAO,CAAC;QAChB,IAAI,UAAU,GAAG,CAAC,CAAC;AAEnB,QAAA,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;AAClC,YAAA,UAAU,GAAG,SAAS,CAAC,MAAM,KAAK,QAAQ,GAAG,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;AAChE,YAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,WAAW,GAAG,CAAC,CAAC;AAClD,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC;AAE7D,YAAA,KAAK,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE;gBAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC7C,gBAAA,IAAI,CAAC,GAAG,IAAI,GAAG,gBAAgB,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE;oBAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;iBAClC;gBAED,IAAI,SAAS,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE;oBACvC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;oBACpD,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,QAAQ,GAAG,CAAG,EAAA,UAAU,CAAG,CAAA,CAAA,GAAG,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;iBACtF;gBAED,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;AAC5F,gBAAA,CAAC,IAAI,IAAI,GAAG,gBAAgB,CAAC;aAC9B;;AAGD,YAAA,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;AACjB,gBAAA,CAAC,IAAI,iBAAiB,GAAG,gBAAgB,CAAC;aAC3C;SACF;QAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;KACnC;;;AAIO,IAAA,iBAAiB,CAAC,GAAQ,EAAE,UAA2B,EAAE,KAAa,EAAA;QAC5E,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,SAAS,KAAI;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,IAAI,SAAS,CAAC,MAAM,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;AAEvF,YAAA,OAAO,MAAM,IAAI,KAAK,CAAC,MAAM;kBACzB,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,gBAAgB,EAAE,CAAC,CAAC;AAC1F,kBAAE,iBAAiB,GAAG,gBAAgB,CAAC,CAAC;SAC3C,EAAE,CAAC,CAAC,CAAC;KACP;;;IAIO,SAAS,CAAC,SAAwB,EAAE,IAAe,EAAA;AACzD,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,iBAAiB,CAAC,CAAC;KACrG;;IAGO,SAAS,CACf,GAAQ,EACR,IAAe,EACf,KAA6B,EAC7B,IAAY,EAAE,KAAa,EAAE,QAAgB,EAAA;QAE7C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAClE,QAAA,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAE1D,QAAA,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE;YACvB,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;AACvC,YAAA,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;SACjB;KACF;;;;;;;;;;;IAYO,cAAc,CACpB,OAAyB,EACzB,KAAgB,EAChB,MAA8B,EAC9B,GAAe,EACf,GAAW,EAAA;AAEX,QAAA,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE;YACrB,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;SACpC;AAED,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;AACjD,QAAA,MAAM,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;QACrD,MAAM,YAAY,GAAG,MAAM,EAAE,YAAY,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO;AAChE,cAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,WAAW,GAAG,EAAE,CAAC;cAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;AACvE,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;QACpH,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5F,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhG,OAAO;AACL,YAAA,OAAO,EAAE,GAAG,IAAI,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,iBAAiB,GAAG,GAAG;YAClF,GAAG,EAAE,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM;SACvC,CAAC;KACH;;;;AAKO,IAAA,cAAc,CAAC,GAAQ,EAAE,IAAmB,EAAE,YAAsB,EAAA;QAC1E,MAAM,OAAO,GAAG,uBAAuB,CAAC;QACxC,MAAM,KAAK,GAAG,YAAY;AACvB,aAAA,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;aAC9C,MAAM,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,GAAG,GAAG,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;QAE/E,OAAO;AACL,YAAA,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;AACrB,YAAA,QAAQ,EAAE,IAAI;AACd,YAAA,MAAM,EAAE;AACN,gBAAA,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;AAC9C,gBAAA,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;sBAClB,EAAE,aAAa,EAAE,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE;sBAC7F,EAAE,CAAC;AACR,aAAA;SACF,CAAC;KACH;;;;;;IAOO,iBAAiB,CACvB,OAAyB,EACzB,YAAsB,EACtB,IAAY,EAAE,GAAW,EAAE,KAAa,EAAE,MAAc,EAAA;QAExD,MAAM,OAAO,GAAG,uBAAuB,CAAC;QAExC,OAAO;AACL,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,YAAA,MAAM,EAAE,GAAG;YACX,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,GAAG,MAAM,EAAE;AACrF,YAAA,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AAChG,YAAA,YAAY,EAAE,OAAO;AACrB,YAAA,MAAM,EAAE;AACN,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,SAAS,EAAE,QAAQ;AACnB,gBAAA,QAAQ,EAAE,iBAAiB;AAC3B,gBAAA,WAAW,EAAE;oBACX,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU;AACrG,iBAAA;AACD,gBAAA,SAAS,EAAE,uBAAuB;AAClC,gBAAA,SAAS,EAAE,uBAAuB;AAClC,gBAAA,MAAM,EAAE,QAAQ;AAChB,gBAAA,SAAS,EAAE,kBAAkB;AAC9B,aAAA;YACD,WAAW,EAAE,CAAC,IAAS,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;SACrD,CAAC;KACH;;;AAIO,IAAA,aAAa,CAAC,OAAyB,EAAE,OAAgC,EAAE,GAAW,EAAE,MAAc,EAAA;QAC5G,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;KACxG;;;IAIO,SAAS,CAAC,IAA0B,EAAE,GAAW,EAAA;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,KAAI;AACvD,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAElE,YAAA,OAAO,OAAO,KAAK,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;SAClE,CAAC,CAAC,CAAC;KACL;;;;AAKO,IAAA,aAAa,CAAC,IAAS,EAAA;QAC7B,MAAM,IAAI,GAA8B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC;QAChE,IAAI,CAAC,IAAI,EAAE;YACT,OAAO;SACR;AAED,QAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;AAC1C,QAAA,MAAM,GAAG,GAAe;YACtB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YACnC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACjC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;AAC9C,YAAA,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;SACjD,CAAC;AACF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/G,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;AAE1F,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC;KACxE;;;;;;AAOO,IAAA,KAAK,CAAC,GAAQ,EAAE,SAAwB,EAAE,KAAa,EAAA;QAC7D,MAAM,KAAK,GAAgB,EAAE,CAAC;QAC9B,IAAI,IAAI,GAAc,EAAE,CAAC;QACzB,IAAI,SAAS,GAAG,CAAC,CAAC;AAElB,QAAA,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE;AAChC,YAAA,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,IAAI,iBAAiB,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;AAE3B,YAAA,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,6CAA6C,CAAC,IAAI,EAAE,EAAE;gBACtF,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AAEzC,gBAAA,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,KAAK,EAAE;AACjF,oBAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACjB,IAAI,GAAG,EAAE,CAAC;oBACV,SAAS,GAAG,CAAC,CAAC;iBACf;AAED,gBAAA,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;gBACjD,SAAS,IAAI,SAAS,CAAC;aACxB;SACF;AAED,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClB;AAED,QAAA,OAAO,KAAK,CAAC;KACd;AAEO,IAAA,SAAS,CAAC,GAAQ,EAAE,IAAa,EAAE,CAAS,EAAE,QAAgB,EAAA;AACpE,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;AAErB,QAAA,IAAI,GAAG,CAAC,SAAS,EAAE;AACjB,YAAA,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC;SAC5E;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;AAEjC,QAAA,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,kBAAkB,CAAC;AAC9C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAClE,QAAA,IAAI,GAAG,CAAC,SAAS,EAAE;AACjB,YAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACxB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;SACrF;AACD,QAAA,IAAI,GAAG,CAAC,MAAM,EAAE;AACd,YAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACxB,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,EAAE,CAAC,GAAG,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;SACnF;AAED,QAAA,IAAI,GAAG,CAAC,IAAI,EAAE;YACZ,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;SACjF;KACF;;;AAIO,IAAA,KAAK,CAAC,GAAQ,EAAE,GAAY,EAAE,IAAY,EAAA;AAChD,QAAA,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC;AAChD,QAAA,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,cAAE,SAAS;eACR,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,WAAW,CAAC,CAAC;QACzF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM;AAClC,cAAE,YAAY;eACX,GAAG,CAAC,IAAI,GAAG,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;AAE7D,QAAA,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC3B,QAAA,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACtB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,IAAI,kBAAkB,CAAC,CAAC;KACnD;IAEO,cAAc,CAAC,GAAQ,EAAE,IAAY,EAAA;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC;AAErD,QAAA,OAAO,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;KACxD;AAEO,IAAA,YAAY,CAAC,KAA6B,EAAE,KAAa,EAAE,SAAiB,EAAA;QAClF,QAAQ,KAAK;AACX,YAAA,KAAK,QAAQ;AACX,gBAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC;AAC9C,YAAA,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,CAAC;AACxC,YAAA;AACE,gBAAA,OAAO,CAAC,CAAC;SACZ;KACF;;;;;;;AAQO,IAAA,OAAO,CAAC,OAAyB,EAAE,IAAgB,EAAE,KAAa,EAAE,UAAkB,EAAA;QAC5F,OAAO;YACL,UAAU;YACV,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,CAAQ,KAAA,EAAA,KAAK,GAAG,CAAC,CAAE,CAAA;AAC1C,YAAA,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI;AAC/B,YAAA,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;SAC7F,CAAC;KACH;;IAGO,MAAM,gBAAgB,CAC5B,OAAyB,EACzB,IAAgB,EAChB,IAAwB,EACxB,MAAwB,EACxB,SAA6B,EAAA;AAE7B,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AACxB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;;AAEjC,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAC3B,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;QAE3B,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,KAAK,EAAE;AACT,YAAA,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAC3C;;;;AAKD,QAAA,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC;AAC5C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;QAClF,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC9F,QAAA,MAAM,GAAG,GAAG,CAAC,GAAGZ,SAAO,IAAI,QAAQ,GAAGC,YAAU,GAAG,CAAC,CAAC,CAAC;AACtD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACvC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAGE,YAAU,IAAID,aAAW,CAAC,CAAC,CAAC,CAAC;QAExF,IAAI,QAAQ,EAAE;AACZ,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,GAAGF,SAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;SACrE;QAED,MAAM,KAAK,GAAG,GAAG,CAAC;AAClB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,GAAGE,aAAW,CAAC,CAAC;QAE7D,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AAC3B,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAGA,aAAW,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACzG,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;AACnC,YAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YAEzD,OAAO;SACR;AAED,QAAA,QAAQ,SAAS,CAAC,IAAI;YACpB,KAAK,OAAO,EAAE;AACZ,gBAAA,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;AAC5F,gBAAA,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC/C,MAAM;aACP;AACD,YAAA,KAAK,MAAM,CAAC;AACZ,YAAA,KAAK,MAAM;AACT,gBAAA,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;gBACtE,MAAM;AACR,YAAA,KAAK,KAAK;AACR,gBAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnD,MAAM;SACT;KACF;;;;AAKO,IAAA,UAAU,CAChB,GAAQ,EACR,IAAY,EACZ,CAAS,EAAE,CAAS,EAAE,CAAS,EAC/B,KAAwB,EACxB,KAA0B,EAC1B,KAAK,GAAG,CAAC,EAAA;AAET,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAChC,QAAA,GAAG,CAAC,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC,CAAC;AACpC,QAAA,GAAG,CAAC,YAAY,CAACE,aAAW,CAAC,CAAC;AAC9B,QAAA,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;KAC1G;;AAGO,IAAA,IAAI,CAAC,GAAQ,EAAE,IAAY,EAAE,KAAa,EAAA;QAChD,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE;AACnC,YAAA,OAAO,IAAI,CAAC;SACb;QAED,IAAI,GAAG,GAAG,IAAI,CAAC;AACf,QAAA,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,GAAG,CAAA,CAAA,CAAG,CAAC,GAAG,KAAK,EAAE;YAC5D,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;SACxB;AAED,QAAA,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC;KAC5B;;;;;IAMO,eAAe,CAAC,GAAQ,EAAE,KAAa,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAC9E,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjC,QAAA,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnB,QAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;KAC5D;;;IAIO,QAAQ,CAAC,GAAQ,EAAE,IAAY,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AACjF,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnB,QAAA,GAAG,CAAC,YAAY,CAACA,aAAW,CAAC,CAAC;QAC9B,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;KACxE;;;;;;;;;AAUO,IAAA,YAAY,CAClB,OAAyB,EACzB,IAAgB,EAChB,IAAwB,EACxB,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAC1C,SAA6B,EAAA;QAE7B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;AAC7C,QAAA,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpH,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACvC,QAAA,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAE7G,IAAI,GAAG,KAAK,KAAK,CAAC,MAAM,IAAI,OAAO,KAAK,CAAC,EAAE;AACzC,YAAA,IAAI,CAAC,UAAU,CACb,OAAO,EACP,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,CACvF,CAAC;YAEF,OAAO;SACR;;;AAID,QAAA,MAAM,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,cAAc,CAAC;;;;;AAM7D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;AAElC,QAAA,IAAI,GAAG,IAAI,CAAC,EAAE;YACZ,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACtF,YAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;SAC3G;aAAM;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;SAChD;QAED,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,IAAI,CAAC;AACb,gBAAA,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC7G,YAAY;AACb,aAAA,CAAC,CAAC;SACJ;KACF;;IAGO,UAAU,CAAC,OAAyB,EAAE,IAAwB,EAAA;AACpE,QAAA,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;AAC1C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAqB,CAAC;AACxC,QAAA,MAAM,IAAI,GAAG,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnI,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;AAE3F,QAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;KAClH;;;;AAKO,IAAA,UAAU,CAAC,IAAwB,EAAA;QACzC,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAM,CAAC,CAAC;AAC3C,QAAA,MAAM,IAAI,GAAG,CAAC,QAAwB,MAAoB;YACxD,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC;YACrC,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;AACzB,YAAA,MAAM,EAAE;AACN,gBAAA,IAAI,QAAQ,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;gBAC/C,IAAI,QAAQ,CAAC,MAAM;AACjB,sBAAE;AACA,wBAAA,WAAW,EAAE;AACX,4BAAA,GAAG,EAAE,kBAAkB;AACvB,4BAAA,KAAK,EAAE,kBAAkB;AACzB,4BAAA,MAAM,EAAE,kBAAkB;AAC1B,4BAAA,IAAI,EAAE,kBAAkB,GAAG,QAAQ,CAAC,MAAM,GAAGQ,aAAW;AACzD,yBAAA;AACF,qBAAA;sBACC,EAAE,CAAC;AACR,aAAA;AACF,SAAA,CAAC,CAAC;QAEH,OAAO;AACL,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5C,YAAA,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7C,OAAO,EAAE,KAAK,CAAC,OAAO;AACtB,YAAA,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI;YACpF,OAAO,EAAE,KAAK,CAAC,QAAQ;SACxB,CAAC;KACH;;;;AAKO,IAAA,WAAW,CACjB,OAAyB,EACzB,SAA0B,EAC1B,IAAmB,EACnB,aAAgC,EAAA;AAEhC,QAAA,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,QAAQ,CACxE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CACrF,CAAC,CAAC,CAAC;AACJ,QAAA,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;QAEnF,OAAO;YACL,KAAK;AACL,YAAA,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC;YAChD,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI;SAC5D,CAAC;KACH;;;;;;;;;;;AAYO,IAAA,aAAa,CACnB,OAAyB,EACzB,IAAsB,EACtB,OAAkB,EAClB,IAAsB,EACtB,CAAS,EAAE,MAAc,EAAE,CAAS,EAAE,MAAc,EACpD,YAA8B,EAC9B,IAAsB,EAAA;QAEtB,OAAO;AACL,YAAA,KAAK,EAAE,MAAM;YACb,IAAI;YACJ,IAAI;YACJ,MAAM;AACN,YAAA,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE;AACzD,YAAA,UAAU,EAAE,CAAC;AACb,YAAA,YAAY,EAAE,OAAO;AACrB,YAAA,MAAM,EAAE;AACN,gBAAA,IAAI,EAAE,WAAW;AACjB,gBAAA,SAAS,EAAE,QAAQ;AACnB,gBAAA,QAAQ,EAAE,eAAe;AACzB,gBAAA,WAAW,EAAE,kBAAkB;AAC/B,gBAAA,SAAS,EAAE,SAAS;AACrB,aAAA;AACD,YAAA,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE;AAC7E,YAAA,kBAAkB,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE;AAC5C,YAAA,IAAI,YAAY,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;AACzC,YAAA,IAAI,IAAI;AACN,kBAAE;oBACA,IAAI,EAAE,CAAC,IAAI,CAAC;AACZ,oBAAA,QAAQ,EAAE,UAAU;AACpB,oBAAA,UAAU,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE;AAC9E,iBAAA;kBACC,EAAE,CAAC;AACP,YAAA,YAAY,EAAE,CAAC,IAAS,KAAI;gBAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBACtF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC;iBACnC;aACF;SACF,CAAC;KACH;;;;;AAMO,IAAA,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,UAAmB,EAAA;AAChE,QAAA,OAAO,CAAC;AACN,gBAAA,OAAO,EAAE,IAAI;AACb,gBAAA,OAAO,EAAE,IAAI;;;AAGb,gBAAA,MAAM,EAAE;AACN,oBAAA,SAAS,EAAE,QAAQ;AACnB,oBAAA,SAAS,EAAER,aAAW;AACtB,oBAAA,MAAM,EAAE,MAAM;AACd,oBAAA,IAAI,UAAU,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;AACjD,iBAAA;AACF,aAAA,CAAC,CAAC;KACJ;;;;;;;;;;;AAYO,IAAA,QAAQ,CACd,OAAyB,EACzB,IAAsB,EACtB,KAAuB,EACvB,OAAkB,EAClB,IAAqB,EACrB,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,MAAc,EAAA;QAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC/C,QAAA,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAC/B,OAAO,EACP,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CACpF,CAAC;AACF,QAAA,MAAM,OAAO,GAAwB,KAAK,CAAC,OAAO,CAAC;QACnD,MAAM,YAAY,GAAoB,EAAE,CAAC;QACzC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;AAChC,YAAA,YAAY,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC;kBAChC,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;kBAC5C,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AAClC,SAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtD,OAAO;AACL,YAAA,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,EAAE,OAAO,CAAC,KAAK,GAAG,MAAM,EAAE,UAAU,CAAC;YACjF,YAAY;;;AAGZ,YAAA,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,GAAG,kBAAkB;SAC9G,CAAC;KACH;;;;;;AAOO,IAAA,YAAY,CAAC,KAAU,EAAE,GAAW,EAAE,MAAc,EAAE,UAAkB,EAAA;QAC9E,IAAI,MAAM,GAAG,GAAG,CAAC;QACjB,IAAI,GAAG,GAAG,CAAC,CAAC;AAEZ,QAAA,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAC7E,YAAA,IAAI,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,EAAE;gBACxD,MAAM;aACP;AAED,YAAA,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC;YACrB,GAAG,IAAI,CAAC,CAAC;SACV;AAED,QAAA,OAAO,GAAG,CAAC;KACZ;;;AAIO,IAAA,gBAAgB,CAAC,OAAyB,EAAA;AAChD,QAAA,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;AACvB,YAAA,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC;YACtC,WAAW,EAAE,OAAO,CAAC,WAAW;AACjC,SAAA,CAAC,CAAC;KACJ;;;;;;;;IASO,UAAU,CAAC,OAAyB,EAAE,OAAgC,EAAA;AAC5E,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QACxB,MAAM,IAAI,GAAG,GAAG,CAAC,kBAAkB,EAAE,CAAC,UAAU,CAAC;AACjD,QAAA,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACrC,IAAI,KAAK,GAAG,IAAI,CAAC;AAEjB,QAAA,IAAI;AACF,YAAA,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;AACrB,gBAAA,GAAG,OAAO;;;;gBAIV,YAAY,EAAE,MAAK;oBACjB,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC,UAAU,KAAK,IAAI,EAAE;AAChD,wBAAA,MAAM,UAAU,CAAC;qBAClB;iBACF;AACF,aAAA,CAAC,CAAC;SACJ;QAAC,OAAO,KAAK,EAAE;AACd,YAAA,IAAI,KAAK,KAAK,UAAU,EAAE;AACxB,gBAAA,MAAM,KAAK,CAAC;aACb;YAED,KAAK,GAAG,KAAK,CAAC;SACf;AAED,QAAA,OAAO,GAAG,CAAC,gBAAgB,EAAE,GAAG,KAAK,EAAE;YACrC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;SACxC;AAED,QAAA,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAElB,QAAA,OAAO,KAAK,CAAC;KACd;;;;;;IAOO,MAAM,mBAAmB,CAC/B,OAAyB,EACzB,IAAgB,EAChB,KAAa,EACb,UAAkB,EAClB,QAA0B,EAAA;AAE1B,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AACxB,QAAA,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACjE,QAAA,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC;AAC1B,QAAA,MAAM,IAAI,GAAqB,QAAQ,CAAC,OAAO,GAAG,CAAC;cAC/C,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACvG,cAAE,QAAQ,CAAC,IAAI,CAAC;;QAElB,MAAM,KAAK,GAAa,EAAE,CAAC;AAE3B,QAAA,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;AACjE,QAAA,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;AACrB,YAAA,GAAG,IAAI,CAAC,aAAa,CACnB,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAGJ,SAAO,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,YAAY,EAClG,QAAQ,CAAC,IAAI,CACd;YACD,MAAM,EAAE,EAAE,GAAG,EAAE,GAAG,GAAGA,SAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE;AAC7E,YAAA,QAAQ,EAAE,WAAW;;YAErB,YAAY,EAAE,MAAK;gBACjB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,UAAU,CAAC,CAAC;AAChD,gBAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAC7E,gBAAA,IAAI,CAAC,eAAe,CAClB,GAAG,EACH,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,EACrG,CAAC,EACD,GAAG,EACH,CAAC,CACF,CAAC;aACH;AACF,SAAA,CAAC,CAAC;AAEH,QAAA,MAAM,IAAI,CAAC,0BAA0B,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAE/E,QAAA,OAAO,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;KAClC;;;;;IAMO,MAAM,0BAA0B,CACtC,OAAyB,EACzB,IAAgB,EAChB,KAAa,EACb,UAAkB,EAClB,KAAe,EAAA;AAEf,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AAExB,QAAA,KAAK,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE;AACpD,YAAA,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC1B,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;SACtG;QAED,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,CAAC;KACrC;;;IAIO,oBAAoB,CAAC,OAAyB,EAAE,IAAgB,EAAA;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,IAAI,QAAQ,CAAC;QAE7F,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,YAAY,CAAC;YACjD,MAAM,EAAE,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,YAAY,CAAC;SACrD,CAAC;KACH;;;IAIO,iBAAiB,CAAC,OAAyB,EAAE,IAAgB,EAAA;AACnE,QAAA,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAEjE,OAAO,OAAO,CAAC,KAAK,GAAG,GAAG,GAAGA,SAAO,GAAG,MAAM,CAAC;KAC/C;;;AAIO,IAAA,mBAAmB,CAAC,IAAY,EAAA;AACtC,QAAA,OAAO,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG,gBAAgB,GAAG,cAAc,CAAC;KAC7D;IAEO,eAAe,CACrB,SAA0B,EAC1B,MAAwB,EACxB,MAAe,EACf,MAAiB,EACjB,QAAkB,EAAA;AAElB,QAAA,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEvE,OAAO,KAAK,GAAG,CAAA,EAAG,KAAK,CAAA,YAAA,CAAc,GAAG,WAAW,CAAC;KACrD;;;;IAKO,UAAU,CAChB,OAAyB,EACzB,IAAwB,EACxB,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAE1C,QAAA,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;AACxB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAmB,CAAC;QAClD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3G,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACxC,QAAA,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEpF,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;AAClC,YAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjC,YAAA,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AACpB,YAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YAC5B,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAE3D,YAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,gBAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACnC,gBAAA,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AACnB,gBAAA,GAAG,CAAC,YAAY,CAACI,aAAW,CAAC,CAAC;gBAC9B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;aACtE;YAED,OAAO;SACR;;AAGD,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAEC,aAAW,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,gBAAgB,CAACA,aAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3D,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAE3E,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACjC,GAAG,CAAC,WAAW,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AAClC,QAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,kBAAkB,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AACxF,QAAA,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;AAErB,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,YAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACnC,GAAG,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;AACjC,YAAA,GAAG,CAAC,YAAY,CAACD,aAAW,CAAC,CAAC;AAC9B,YAAA,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC9G,YAAA,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB;QAED,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;AAC7B,YAAA,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AACxD,YAAA,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB;AAED,QAAA,IAAI,KAAK,CAAC,MAAM,EAAE;AAChB,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7F,YAAA,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB;QAED,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;AAC/B,YAAA,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC7C,YAAA,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB;QAED,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE;YACrC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAClF,YAAA,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B;AAED,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE;YAC9B,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACzE,YAAA,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;SACrB;KACF;;;;AAKO,IAAA,SAAS,CAAC,GAAQ,EAAE,KAAmB,EAAE,CAAS,EAAE,GAAW,EAAE,CAAS,EAAE,KAAK,GAAG,CAAC,EAAA;QAC3F,MAAM,KAAK,GAAG,CAAA,CAAA,EAAI,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA,CAAE,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACzC,QAAA,MAAM,IAAI,GAAG,cAAc,GAAG,KAAK,CAAC;AACpC,QAAA,MAAM,IAAI,GAAGE,WAAS,GAAG,KAAK,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAGC,eAAa,GAAG,KAAK,CAAC;AAErF,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjC,QAAA,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACtB,MAAM,WAAW,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;AAE7C,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACnC,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ;AAC7B,cAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAA,CAAA,EAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA,CAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,GAAG,WAAW,CAAC,CAAC;cACzF,EAAE,CAAC;QACP,MAAM,KAAK,GAAG,KAAK,GAAG,WAAW,IAAI,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,QAAA,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC;AAC5B,QAAA,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC;QAE5C,IAAI,KAAK,EAAE;YACT,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,EAAE,CAAC;AAC7C,YAAA,MAAM,GAAG,GAAG,EAAE,GAAG,QAAQ,GAAG,IAAI,GAAG,QAAQ,CAAC;AAC5C,YAAA,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;AAE7C,YAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACxB,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACvE,IAAI,IAAI,KAAK,CAAC;SACf;AAED,QAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACjC,QAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QACxB,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAEjC,IAAI,QAAQ,EAAE;AACZ,YAAA,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AACnC,YAAA,GAAG,CAAC,YAAY,CAACH,aAAW,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,WAAW,EAAE,QAAQ,CAAC,CAAC;SAClD;KACF;;;IAIO,UAAU,CAAC,GAAQ,EAAE,MAAqB,EAAE,CAAS,EAAE,GAAW,EAAE,CAAS,EAAA;QACnF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAA,EAAG,MAAM,CAAC,IAAI,CAAM,GAAA,EAAA,MAAM,CAAC,QAAQ,CAAE,CAAA,GAAG,MAAM,CAAC,IAAI,CAAC;QAEnF,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEzE,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE;YACxB,OAAO;SACR;AAED,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAEI,WAAS,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAChC,QAAA,MAAM,IAAI,GAAG,GAAG,GAAGN,aAAW,GAAG,CAAC,CAAC;AAEnC,QAAA,GAAG,CAAC,YAAY,CAACQ,iBAAe,CAAC,CAAC;AAClC,QAAA,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAED,WAAS,EAAE,GAAG,CAAC,CAAC;AAE3C,QAAA,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE;AACnB,YAAA,GAAG,CAAC,YAAY,CAAC,CAAA,CAAA,EAAI,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAE,CAAA,CAAC,CAAC;AAC9D,YAAA,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,IAAI,EAAEA,WAAS,EAAE,GAAG,CAAC,CAAC;SAC1D;KACF;;;;;IAMO,aAAa,CACnB,GAAQ,EACR,MAAyB,EACzB,OAAgB,EAChB,CAAS,EAAE,GAAW,EAAE,CAAS,EAAA;QAEjC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACvD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAEE,iBAAe,CAAC,CAAC;QAChD,MAAM,IAAI,GAAGN,aAAW,CAAC,SAAS,GAAG,CAAC,GAAG,mBAAmB,CAAC;QAC7D,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAChC,QAAA,MAAM,EAAE,GAAG,CAAC,KAAwB,MAAM;YACxC,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG;YAC9B,CAAC,EAAE,GAAG,GAAG,mBAAmB,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG;AACpD,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,KAAK,GAAG,CAAI,CAAA,EAAA,0BAA0B,EAAE,CAAC;AAE/C,QAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACxB,QAAA,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;AACxB,QAAA,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAEpB,QAAA,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE;AACjC,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAI;AAC1C,gBAAA,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAE7C,gBAAA,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC9B,aAAC,CAAC,CAAC;AACH,YAAA,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5G,YAAA,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;SAChE;AAED,QAAA,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE;AAC/B,YAAA,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;AACtB,YAAA,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;SAC9C;AAED,QAAA,IAAI,QAAQ,CAAC,IAAI,EAAE;YACjB,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAEhC,YAAA,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE;AACxB,gBAAA,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAC5B,gBAAA,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;aAC/C;iBAAM;AACL,gBAAA,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;aAC9C;SACF;KACF;;;;;;;;;;;AAYO,IAAA,QAAQ,CAAC,IAAY,EAAA;AAC3B,QAAA,OAAO,IAAI;AACR,aAAA,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC;AAC5B,aAAA,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;AAC/B,aAAA,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;AACvB,aAAA,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;AAC1B,aAAA,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;KAC/B;;;AAIO,IAAA,UAAU,CAAC,MAAiC,EAAA;QAClD,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK;YACrE,GAAG;YACH,KAAK,CAAC,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;AACjF,SAAA,CAAC,CAAC,CAAC;KACL;AAEO,IAAA,KAAK,CAAC,IAAY,EAAA;QACxB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC;KAC3F;wGA9yCU,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAhB,gBAAgB,EAAA,CAAA,CAAA;;4FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B,UAAU;;;AC/KX;AACA,MAAM,OAAO,GAAG,IAAI,CAAC;AAErB;AACA;AACA;AACA;AACA,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,UAAU,GAAG,IAAI,CAAC;AACxB,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;AACA;AACA,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,WAAW,GAAqB;AACpC,IAAA,KAAK,EAAE,IAAI;AACX,IAAA,KAAK,EAAE,IAAI;AACX,IAAA,KAAK,EAAE,IAAI;AACX,IAAA,MAAM,EAAE,IAAI;AACZ,IAAA,MAAM,EAAE,iBAAiB,GAAG,WAAW,GAAG,SAAS,GAAG,IAAI;AAC1D,IAAA,SAAS,EAAE,IAAI;AACf,IAAA,IAAI,EAAE,WAAW;CAClB,CAAC;AACF;AACA,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B;AACA,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B;AACA;AACA,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B;AACA,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,eAAe,GAAG,sBAAsB,CAAC;AAC/C;AACA;AACA,MAAM,eAAe,GAAG,CAAC,CAAC;AAC1B,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAEnC;AACA;AACA;AACA,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAC5C,MAAM,yBAAyB,GAAG,EAAE,CAAC;AACrC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC;AACA,MAAM,WAAW,GAAG,IAAI,CAAC;AAEzB;AACA;AACA,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEzC;AACA;AACA;AACO,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;AACA;AACA;AACA,MAAM,eAAe,GAAkD;AACrE,IAAA,GAAG,EAAE,GAAG;AACR,IAAA,MAAM,EAAE,GAAG;AACX,IAAA,IAAI,EAAE,GAAG;AACT,IAAA,KAAK,EAAE,GAAG;AACV,IAAA,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF;AACA;AACA;AACA,MAAM,sBAAsB,GAAsC;AAChE,IAAA,IAAI,EAAE,UAAU;AAChB,IAAA,IAAI,EAAE,UAAU;AAChB,IAAA,KAAK,EAAE,OAAO;CACf,CAAC;AAEF;AACA;AACA;AACA,MAAM,cAAc,GAAG,EAAE,eAAe,EAAE,KAAK,EAAW,CAAC;AAE3D;AACA;AACA,MAAM,eAAe,GAAG,EAAE,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,oBAAoB,EAAE,EAAE,EAAW,CAAC;AAEhH;AACA;AACA,MAAM,cAAc,GAAyC;AAC3D,IAAA,CAAC,oBAAoB,CAAC,KAAK,GAAG,OAAO;AACrC,IAAA,CAAC,oBAAoB,CAAC,MAAM,GAAG,MAAM;AACrC,IAAA,CAAC,oBAAoB,CAAC,MAAM,GAAG,QAAQ;CACxC,CAAC;AAEF;AACA,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC;AACA;AACA,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAEtC;AACA;AACA,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAEpC;AACA;AACO,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAE7C;AACA;AACA,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAElC;AACA;AACA,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAE1C;AACA;AACA,MAAM,kBAAkB,GAAG,mFAAmF;AAC1G,MAAA,WAAW,CAAC;AAEhB;AACA;AACA,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;AACA;AACA;AACA;AACA,MAAM,sBAAsB,GAAG;AAC7B,IAAA,uBAAuB,CAAC,QAAQ;AAChC,IAAA,uBAAuB,CAAC,UAAU;AAClC,IAAA,uBAAuB,CAAC,QAAQ;AAChC,IAAA,uBAAuB,CAAC,UAAU;CACnC,CAAC;AAEF;AACA;AACA,MAAM,oBAAoB,GAAmB,KAAK,CAAC;AA+BnD;AACA;AACA;AACA;AACA;AACA;AACA;AACgB,SAAA,cAAc,CAC5B,OAAgC,EAChC,WAA6B,EAAA;AAE7B,IAAA,OAAO,WAAW,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;AACnE,CAAC;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,iBAAiB,CAAA;AAEX,IAAA,WAAW,GAAG,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAExD,MAAM,KAAK,CAAC,SAA0B,EAAA;QAC3C,MAAM,SAAS,GAAG,CAAC,MAAM,OAAO,WAAW,CAAC,EAAE,OAAO,CAAC;AAEtD,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;AAChC,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;AAC/B,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;AAEhC,QAAA,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;AAC7B,QAAA,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,QAAA,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;AACvB,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QAEzB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;;;AAIhD,QAAA,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;QAElD,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE;AAC1C,YAAA,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;SAC3D;QAED,OAAO;AACL,YAAA,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;AAClC,YAAA,YAAY,EAAE,kBAAkB;;;AAGhC,YAAA,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,YAAW;AACf,gBAAA,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAG,EAAA,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAO,KAAA,CAAA,EAAE,CAAC,CAAC;aACvE;SACF,CAAC;KACH;;;;;IAMO,MAAM,WAAW,CACvB,IAAS,EACT,SAA0B,EAC1B,KAAa,EACb,SAAoC,EAAA;AAEpC,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAChC,MAAM,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC7C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAClE,QAAA,MAAM,UAAU,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC;AAC/D,QAAA,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAE/C,QAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE;AACpC,YAAA,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;SAC/D;AAED,QAAA,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,UAAU,EAAE;YAC3C,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE;AAClC,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;aACrF;AAAM,iBAAA,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;AACpE,gBAAA,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;aAC9E;SACF;KACF;;;IAIO,MAAM,aAAa,CACzB,KAAU,EACV,SAA0B,EAC1B,MAAwB,EACxB,SAAoC,EAAA;AAEpC,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,GAAG,MAAM;YACT,MAAM,EAAE,SAAS,CAAC,YAAY;AAC9B,YAAA,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC;SAC9F,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;AACnF,YAAA,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE;gBAC1D,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,CAAC,CAAC;aAC9E;SACF;KACF;;;;AAKO,IAAA,eAAe,CACrB,SAAoC,EACpC,SAA0B,EAC1B,IAAY,EACZ,MAAwB,EAAA;QAExB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE;AAChC,YAAA,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;SACpE;KACF;AAEO,IAAA,WAAW,CAAC,IAAS,EAAE,SAA0B,EAAE,KAAa,EAAE,KAAa,EAAA;AACrF,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE9B,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE;AACnC,YAAA,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG;YAC5C,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ;AAC1C,SAAA,CAAC,CAAC;;;AAIH,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;AACpC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;AACvC,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,OAAO,EAAE,cAAc,CACrB,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EACvC,KAAK,KAAK,CAAC,GAAG,SAAS,CAAC,aAAa,CAAC,MAAM,GAAG,SAAS,CACzD;AACF,SAAA,CAAC,CAAC,CAAC;AAEJ,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;AAClB,YAAA,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;AACjF,YAAA,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ;AAC9B,SAAA,CAAC,CAAC;KACJ;;;;;;;AAQO,IAAA,MAAM,WAAW,CAAC,KAAU,EAAE,SAA0B,EAAE,MAAwB,EAAA;QACxF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACxC,QAAA,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACjE,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;AACzE,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;;;;AAK7C,QAAA,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE;AAC9F,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YAE5D,OAAO,MAAM,CAAC,QAAQ,CAAC;SACxB;AAED,QAAA,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC;KACnF;;;AAIO,IAAA,WAAW,CAAC,KAAU,EAAE,SAA0B,EAAE,UAA2B,EAAA;QACrF,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;AAC7C,QAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAChB,OAAO;SACR;AAED,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AAC1C,QAAA,MAAM,KAAK,GAAG,CAAC,KAAyB,KAAK,CAAC,KAAK,IAAI,yBAAyB,IAAI,EAAE,CAAC;AAEvF,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;YAClB,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;AAC9D,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAClG,YAAA,GAAG,EAAE,MAAM;AACZ,SAAA,CAAC,CAAC;KACJ;;;;;;;AAQO,IAAA,gBAAgB,CACtB,KAAU,EACV,SAA0B,EAC1B,MAAmB,EACnB,MAAuB,EAAA;AAEvB,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;AAC1C,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,OAAO,EAAE,IAAI,IAAI,yBAAyB,CAAC,CAAC;AACrE,QAAA,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,OAAO,EAAE,GAAG,IAAI,yBAAyB,CAAC,CAAC;QACpE,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,QAAA,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;AAC1B,YAAA,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM;kBACjC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;kBAC5F,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtF,YAAA,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC;SAC9B;AAED,QAAA,OAAO,OAAO,CAAC;KAChB;;;;;IAMO,eAAe,CACrB,KAAU,EACV,UAA2B,EAC3B,OAAiC,EACjC,MAAuB,EACvB,CAAS,EAAE,CAAS,EAAA;QAEpB,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;AACtE,YAAA,OAAO,KAAK,CAAC;SACd;QAED,IAAI,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,aAAa,EAAE;AACvC,YAAA,OAAO,IAAI,CAAC;SACb;QAED,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE;AAC7C,YAAA,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;AAC5G,YAAA,MAAM,EAAE,CAAC;AACT,YAAA,MAAM,EAAE,KAAK;AACb,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,GAAG,EAAE,MAAM;AACZ,SAAA,CAAC,CAAC;AAEH,QAAA,OAAO,KAAK,CAAC;KACd;;;;;IAMO,aAAa,CACnB,KAAU,EACV,KAAgB,EAChB,WAA4B,EAC5B,MAAuB,EACvB,CAAS,EAAE,CAAS,EAAA;AAEpB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QAE/D,IAAI,IAAI,EAAE;YACR,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE;AAC3C,gBAAA,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,IAAI;AACvB,gBAAA,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,GAAG;gBACtB,CAAC,EAAE,WAAW,CAAC,KAAK;gBACpB,IAAI,EAAE,WAAW,CAAC,YAAY;gBAC9B,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;AAC3C,gBAAA,QAAQ,EAAE,KAAK;AACf,gBAAA,QAAQ,EAAE,OAAO;AACjB,gBAAA,QAAQ,EAAE,iBAAiB;gBAC3B,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,uBAAuB,EAAE,KAAK,EAAE,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;AACvG,gBAAA,MAAM,EAAE,sBAAsB;AAC/B,aAAA,CAAC,CAAC;SACJ;AAED,QAAA,OAAO,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;KACjC;;IAGO,SAAS,CAAC,WAA4B,EAAE,aAAqB,EAAA;AACnE,QAAA,IAAI,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC;QAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;AAEb,QAAA,KAAK,MAAM,SAAS,IAAI,WAAW,CAAC,UAAU,EAAE;YAC9C,MAAM,IAAI,SAAS,CAAC;AACpB,YAAA,IAAI,MAAM,GAAG,aAAa,GAAG,cAAc,EAAE;gBAC3C,MAAM;aACP;AAED,YAAA,IAAI,EAAE,CAAC;SACR;AAED,QAAA,OAAO,IAAI,CAAC;KACb;;;;;;;;IASO,UAAU,CAAC,KAAgB,EAAE,IAAY,EAAA;QAC/C,MAAM,KAAK,GAA+B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9G,QAAA,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAEjG,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,KAAI;YAC/D,IAAI,CAAC,IAAI,EAAE;AACT,gBAAA,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;aACvB;YAED,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;SACvF,CAAC,CAAC,CAAC;KACL;;;;AAKO,IAAA,UAAU,CAAC,IAAmB,EAAA;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAElD,OAAO;;YAEL,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE;AAC7B,YAAA,OAAO,EAAE;gBACP,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,SAAS;gBACnE,KAAK,EAAE,IAAI,CAAC,KAAK;AACjB,gBAAA,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,QAAQ;AAC/B,gBAAA,MAAM,EAAE,sBAAsB;AAC/B,aAAA;SACF,CAAC;KACH;;;;AAKO,IAAA,cAAc,CAAC,UAA2B,EAAA;QAChD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,KAAI;YAC7C,MAAM,MAAM,GAAG,KAAK,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/C,YAAA,MAAM,gBAAgB,GAAG;gBACvB,KAAK,EAAE,SAAS,CAAC,KAAK;AACtB,gBAAA,MAAM,EAAE,SAAS,CAAC,MAAM,KAAK,QAAQ;AACnC,sBAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;AACpB,uBAAG,SAAS,CAAC,MAAM,KAAK,QAAQ,GAAG,IAAI,GAAG,SAAS,CAAC;aACvD,CAAC;YACF,MAAM,IAAI,GAAc,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAEhF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,MAAM;gBAClC,IAAI,EAAE,GAAG,CAAC,IAAI;AACd,gBAAA,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,gBAAgB,EAAE,QAAQ,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;AAC1F,aAAA,CAAC,CAAC,CAAC;AACN,SAAC,CAAC,CAAC;KACJ;;;AAIO,IAAA,WAAW,CACjB,GAAY,EACZ,gBAAyC,EACzC,SAAkB,EAAA;QAElB,OAAO;AACL,YAAA,GAAG,gBAAgB;YACnB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,MAAM;AAClB,YAAA,SAAS,EAAE,GAAG,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS;YACvD,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,WAAW,GAAG,SAAS;AAC5C,YAAA,KAAK,EAAE,CAAC,GAAG,CAAC,KAAK,IAAI,kBAAkB,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;YACzD,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC;AAC1C,YAAA,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,iBAAiB;YAC3C,QAAQ,EAAE,GAAG,CAAC,QAAQ;AACtB,YAAA,SAAS,EAAE,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,SAAS;YACnD,SAAS;SACV,CAAC;KACH;;;;;AAMO,IAAA,OAAO,CAAC,SAA0B,EAAE,IAAgB,EAAE,KAAa,EAAA;QACzE,OAAO;YACL,UAAU,EAAE,KAAK,GAAG,CAAC;YACrB,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,CAAQ,KAAA,EAAA,KAAK,GAAG,CAAC,CAAE,CAAA;AAC1C,YAAA,UAAU,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI;AACjC,YAAA,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC;SACjG,CAAC;KACH;;IAGO,gBAAgB,CACtB,IAAS,EACT,KAAU,EACV,IAAwB,EACxB,MAAwB,EACxB,QAAgB,EAChB,OAA4B,EAAA;AAE5B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;;QAEjC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC;QAEjC,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtF,IAAI,KAAK,EAAE;AACT,YAAA,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE;AACnB,gBAAA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO;AACnB,gBAAA,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK;AACzD,aAAA,CAAC,CAAC;SACJ;;;;AAKD,QAAA,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;AAC9F,QAAA,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,IAAI,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC;AACtD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AACxC,QAAA,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAExF,IAAI,QAAQ,EAAE;AACZ,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC,EAAE;gBAC7D,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU;AACnC,gBAAA,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM;AACrF,aAAA,CAAC,CAAC;SACJ;QAED,MAAM,KAAK,GAAG,GAAG,CAAC;AAClB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,CAAC;AAE9D,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YACf,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;AAElF,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE;AACzD,gBAAA,CAAC,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,WAAW;AACpD,gBAAA,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM;AACrF,aAAA,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE;AACnC,YAAA,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;gBAC9B,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK;AACxB,gBAAA,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ;AAClF,aAAA,CAAC,CAAC;YAEH,OAAO;SACR;AAED,QAAA,QAAQ,SAAS,CAAC,IAAI;AACpB,YAAA,KAAK,OAAO;gBACV,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAClF,MAAM;AACR,YAAA,KAAK,MAAM;gBACT,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC1G,MAAM;AACR,YAAA,KAAK,MAAM;AACT,gBAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAChE,MAAM;AACR,YAAA,KAAK,KAAK;gBACR,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC1E,MAAM;SACT;KACF;;AAGO,IAAA,SAAS,CAAC,KAAwB,EAAE,OAAA,GAAmC,EAAE,EAAA;AAC/E,QAAA,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;KACnH;AAEO,IAAA,YAAY,CAClB,IAAS,EACT,KAAU,EACV,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAC5B,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAE1C,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;AAC/C,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;AAE5C,QAAA,IAAI,SAAS,KAAK,WAAW,EAAE;YAC7B,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAEzE,OAAO;SACR;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEtD,QAAA,MAAM,OAAO,GAAwB;AACnC,YAAA,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;AACvB,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;AACzB,YAAA,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;AACzB,YAAA,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;AACvB,YAAA,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ;SAC/B,CAAC;QAEF,MAAM,GAAG,GAAG,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,CAAC;AACzD,QAAA,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CACjC,SAAS,CAAC,UAAU,EACpB,IAAI,CAAC,WAAW,EAChB,OAAO,CAAC,MAAM,EACd,cAAc,CAAC,MAAM,CAAC,CACvB,CAAC;;;;;QAKF,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;;;;;;QAOvD,MAAM,WAAW,GAAG,OAAO;AACzB,cAAE,CAAC;AACD,oBAAA,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChE,MAAM;AACN,oBAAA,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC;iBACjC,CAAC;cACA,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;iBACrD,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM;gBACvB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM;;;AAGN,gBAAA,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC;AAC/F,aAAA,CAAC,CAAC,CAAC;;;QAIR,MAAM,eAAe,GAAa,GAAG;cACjC,CAAC,SAAS,CAAC;cACX,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;AACxE,QAAA,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,GAAG,eAAe,GAAG,CAAC,SAAS,CAAC,CAAC;;;QAGzE,MAAM,WAAW,GAAG,GAAG,IAAI,OAAO,GAAG,CAAC,CAAmB,CAAC,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAClG,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,WAAW,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;;;QAGrH,MAAM,QAAQ,GAAG,GAAG,IAAI,OAAO,IAAI,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACpG,MAAM,SAAS,GAAI,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,cAAc,CACnE,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,EACtG,KAAK,CACN,CAAC,CAAC;;;QAIH,MAAM,SAAS,GAAG,GAAG;AACnB,cAAE,EAAE;AACJ,cAAE;AACA,gBAAA,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC;gBACnC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;aAChG,CAAC;QACJ,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;AACxG,QAAA,MAAM,SAAS,GAAG;AAChB,YAAA,GAAG,WAAW;AACd,YAAA,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAChG,CAAC;;;AAIF,QAAA,MAAM,OAAO,GAAG;AACd,YAAA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACV,UAAU,EAAE,cAAc,KAAK,QAAQ;AACvC,YAAA,SAAS,EAAE,eAAe,CAAC,cAAc,CAAC;AAC1C,YAAA,cAAc,EAAE,CAAC;AACjB,YAAA,MAAM,EAAE,MAAM,CAAC,WAAW,KAAK,YAAY,GAAG,KAAK,GAAG,KAAK;AAC3D,YAAA,WAAW,EAAE,MAAM,CAAC,OAAO,IAAI,MAAM,GAAG,SAAS,GAAG,WAAW;YAC/D,QAAQ,EAAE,SAAS,KAAK,OAAO,GAAG,EAAE,GAAG,SAAS;AAChD,YAAA,IAAI,OAAO;AACT,kBAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC;kBAC5E,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;AAC7C,YAAA,GAAG,cAAc;;;;YAIjB,IAAI,GAAG,IAAI,OAAO,GAAG,EAAE,IAAI,MAAM,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,GAAG;AACrE,gBAAA,sBAAsB,EAAE,WAAW,CAAC,CAAC,CAAC;AACvC,aAAA,CAAC,CAAC;AACH,YAAA,IAAI,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC7D,YAAA,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG;AACjC,gBAAA,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AACxD,gBAAA,eAAe,EAAE,4BAA4B;aAC9C,CAAC;YACF,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE;SACvC,CAAC;AAEF,QAAA,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAC5E,QAAA,MAAM,OAAO,GAAG;AACd,YAAA,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC;iBACjG,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1F,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;SAC3G,CAAC;AAEF,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;KAC7D;;;;;;;;AASO,IAAA,eAAe,CACrB,MAAmB,EACnB,OAAgB,EAChB,WAAmB,EACnB,aAAqB,EAAA;QAErB,IAAI,aAAa,EAAE;AACjB,YAAA,OAAO,MAAM,CAAC,MAAM,IAAI,oBAAoB,CAAC;SAC9C;AAED,QAAA,OAAO,OAAO,GAAG,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;KACxE;;;;;AAMO,IAAA,eAAe,CAAC,UAA4B,EAAA;AAClD,QAAA,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,KAAI;YACtC,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YAElI,OAAO,SAAS,CAAC,IAAI;kBACjB,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAG,EAAA,SAAS,CAAC,KAAK,CAAA,EAAG,sBAAsB,CAAA,CAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC;AACjG,kBAAE,CAAC,IAAI,CAAC,CAAC;AACb,SAAC,CAAC,CAAC;KACJ;;;;;;IAOO,UAAU,CAChB,MAAmB,EACnB,SAA+B,EAC/B,WAA6B,EAC7B,MAA4B,EAC5B,OAAgB,EAChB,WAAmB,EAAA;AAEnB,QAAA,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE;AAC3B,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,MAAM,IAAI,GAAG,CACX,IAAY,EACZ,MAAyB,EACzB,IAAyB,EACzB,KAAa,EACb,SAAkB,KACI;YACtB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACvC,YAAA,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAElC,OAAO,KAAK,KAAK,IAAI;AACnB,kBAAE,EAAE;AACJ,kBAAE,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAC,WAAW,EAAE,CAAE,CAAA,GAAG,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACjG,SAAC,CAAC;QAEF,IAAI,OAAO,EAAE;AACX,YAAA,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAE3D,OAAO,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC;SACrG;QAED,OAAO,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,KAAI;YAChD,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAE7C,YAAA,OAAO,IAAI;AACT,kBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;kBAChH,EAAE,CAAC;AACT,SAAC,CAAC,CAAC;KACJ;;;;AAKO,IAAA,cAAc,CAAC,IAAsB,EAAE,KAAa,EAAE,SAAiB,EAAA;QAC7E,OAAO;AACL,YAAA,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,CAAC,KAAK,CAAC;YAChB,SAAS,EAAE,IAAI,CAAC,SAAS;AACzB,YAAA,OAAO,EAAE;gBACP,WAAW,EAAE,KAAK,CAAS,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACtD,gBAAA,QAAQ,EAAE,cAAc,CAAC,oBAAoB,CAAC,MAAM,CAAC;AACrD,gBAAA,cAAc,EAAE,MAAM;AACtB,gBAAA,QAAQ,EAAE,uBAAuB;AACjC,gBAAA,SAAS,EAAE,KAAK;gBAChB,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAC9E,aAAA;SACF,CAAC;KACH;;;;;;;;IASO,mBAAmB,CACzB,MAAmB,EACnB,SAA+B,EAC/B,WAA6B,EAC7B,OAA4B,EAC5B,MAA4B,EAC5B,UAA4B,EAAA;QAE5B,MAAM,KAAK,GAAG,CAAC,SAAyB,MAAM,MAAM,IAAI,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC;QAEpH,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;AAC5B,YAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAEhF,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACjF;QAED,OAAQ,CAAC,CAAC,EAAE,CAAC,CAAW,CAAC,GAAG,CAAC,CAAC,SAAS,KAAI;YACzC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,WAAW,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;YAEvF,OAAO,IAAI,CAAC,cAAc,CACxB,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,EACxD,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,EACrC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,EAC3B,OAAO,EACP,KAAK,CAAC,SAAS,CAAC,CACjB,CAAC;AACJ,SAAC,CAAC,CAAC;KACJ;;;;;;;;;;;;;;;;;IAkBO,eAAe,CACrB,KAAgB,EAChB,MAAmB,EACnB,WAAqB,EACrB,MAA4B,EAC5B,aAAqB,EAAA;AAErB,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,QAAA,MAAM,IAAI,GAAG,IAAI,KAAK,qBAAqB,CAAC,GAAG;gBACzC,IAAI,KAAK,qBAAqB,CAAC,IAAI,IAAI,aAAa,IAAI,0BAA0B,CAAC;gBACnF,IAAI,KAAK,qBAAqB,CAAC,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;AAChE,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;QAE5C,IAAI,CAAC,IAAI,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,EAAE;AACzD,YAAA,OAAO,KAAK,CAAC;SACd;AAED,QAAA,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC5E,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE9D,OAAO;AACL,YAAA,GAAG,KAAK;AACR,YAAA,OAAO,EAAE;gBACP,GAAG,KAAK,CAAC,OAAO;AAChB,gBAAA,SAAS,EAAE,IAAI;gBACf,mBAAmB,EAAE,KAAK,GAAG,wBAAwB,GAAG,WAAW,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;AAC5F,gBAAA,iBAAiB,EAAE,yBAAyB;AAC5C,gBAAA,IAAI,QAAQ,GAAG,EAAE,iBAAiB,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;AACrD,aAAA;SACF,CAAC;KACH;;;AAIO,IAAA,mBAAmB,CAAC,MAAqB,EAAA;QAC/C,OAAO;AACL,YAAA,aAAa,EAAE,cAAc,CAAC,MAAM,CAAC;AACrC,YAAA,aAAa,EAAE,gBAAgB;AAC/B,YAAA,gBAAgB,EAAE,qBAAqB;AACvC,YAAA,sBAAsB,EAAE,wBAAwB;SACjD,CAAC;KACH;;;;;;;;;;IAWO,eAAe,CACrB,MAAmB,EACnB,IAAmB,EACnB,WAAqB,EACrB,MAA4B,EAC5B,QAAmB,EACnB,SAAmB,EAAA;AAEnB,QAAA,MAAM,SAAS,GAAG,CAAC,SAAyB,KAAI;AAC9C,YAAA,MAAM,IAAI,GAAG,SAAS,KAAK,CAAC,GAAG,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC;AACvE,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC;AAE1F,YAAA,IAAI,MAAM,IAAI,SAAS,KAAK,CAAC,EAAE;AAC7B,gBAAA,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D;AAED,YAAA,OAAO,EAAE,GAAG,KAAK,EAAE,sBAAsB,EAAE,WAAW,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;AAC/E,SAAC,CAAC;;;AAGF,QAAA,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC;AAC1B,cAAE,EAAE,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,EAAE,4BAA4B,EAAE;cAC9F,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE7C,OAAO;AACL,YAAA,GAAG,eAAe;YAClB,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;YAC5E,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC7C,CAAC;KACH;;;;;IAMO,gBAAgB,CAAC,IAAgC,EAAE,IAAY,EAAA;AACrE,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,IAAI,yBAAyB,CAAC;QAErF,OAAO;AACL,YAAA,kBAAkB,EAAE,QAAQ;AAC5B,YAAA,aAAa,EAAE,KAAK,CAAC,GAAG,IAAI,aAAa;AACzC,YAAA,sBAAsB,EAAE,qBAAqB;AAC7C,YAAA,IAAI,UAAU,GAAG,EAAE,gBAAgB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;SAC/C,CAAC;KACH;;;;;;;;IASO,qBAAqB,CAAC,MAAmB,EAAE,KAAe,EAAA;QAChE,IAAI,MAAM,CAAC,WAAW,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,EAAE;AAC/E,YAAA,OAAO,EAAE,CAAC;SACX;AAED,QAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC;KAC7F;;;;;;;IAQO,cAAc,CACpB,IAA6B,EAC7B,MAA2B,EAC3B,OAAgB,EAChB,OAA4B,EAC5B,KAAa,EAAA;AAEb,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AAC9D,QAAA,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAE5B,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,OAAO,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;SAC/C;QAED,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAE5D,QAAA,OAAO,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;KAClE;;;;IAKO,SAAS,CACf,KAAU,EACV,OAA4B,EAC5B,OAAoB,EACpB,SAAoB,EACpB,OAAgC,EAAA;AAEhC,QAAA,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;AACxB,YAAA,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AACzB,YAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAEtH,OAAO;SACR;AAED,QAAA,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AACrC,YAAA,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;AACzB,YAAA,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC;YACpD,OAAO,EAAE,KAAK,CAAC,OAAO;AACvB,SAAA,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;KACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BO,IAAA,UAAU,CAChB,SAAmB,EACnB,SAA+B,EAC/B,MAAmB,EACnB,WAA6B,EAC7B,MAA4B,EAC5B,SAAiB,EACjB,WAA2D,EAAA;AAE3D,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;AAC5C,QAAA,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE;AACrE,YAAA,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC;SAChH;QAED,MAAM,OAAO,GAAgB,EAAE,CAAC;AAChC,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;QAC7C,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;YAChC,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3C,YAAA,MAAM,GAAG,GAAG,CAAA,EAAG,IAAI,CAAI,CAAA,EAAA,SAAS,EAAE,CAAC;AACnC,YAAA,IAAI,KAAK,GAAG,IAAI,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAE3D,IAAI,CAAC,KAAK,EAAE;AACV,gBAAA,KAAK,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACtD,gBAAA,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpB,gBAAA,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;aACzB;AAED,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,SAAC,CAAC,CAAC;AAEH,QAAA,MAAM,GAAG,GAAG,CAAC,KAAa,KAAI;YAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBAC5B,OAAO,mBAAmB,CAAC,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;aAChE;AAED,YAAA,OAAO,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;AACjF,SAAC,CAAC;QAEF,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AAC7B,YAAA,GAAG,KAAK;AACR,YAAA,OAAO,EAAE;AACP,gBAAA,WAAW,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM;AAChC,sBAAE,KAAK,CAAS,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;sBACpD,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;AAC1B,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;AACvB,sBAAE,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;sBACvG,EAAE,CAAC;gBACP,IAAI,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,sBAAE,EAAE,WAAW,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,GAAG,UAAU,GAAG,WAAW,EAAE;sBACjE,EAAE,CAAC;gBACP,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAC/E,aAAA;AACF,SAAA,CAAC,CAAC,CAAC;KACL;;;IAIO,kBAAkB,CAAC,IAAY,EAAE,UAAmB,EAAA;AAC1D,QAAA,IAAI,IAAI,KAAK,MAAM,EAAE;AACnB,YAAA,OAAO,GAAG,CAAC;SACZ;QAED,OAAO,UAAU,GAAG,KAAK,GAAG,SAAS,CAAC;KACvC;;;AAIO,IAAA,YAAY,CAAC,OAAiC,EAAE,KAAK,GAAG,KAAK,EAAA;QACnE,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,KAAK,GAAG,oBAAoB,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAE7F,OAAO;AACL,YAAA,QAAQ,EAAE,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,oBAAoB,CAAC,KAAK,CAAC;AACpF,YAAA,cAAc,EAAE,OAAO,EAAE,OAAO,KAAK,KAAK,GAAG,MAAM,GAAG,QAAQ;AAC9D,YAAA,kBAAkB,EAAE,qBAAqB;SAC1C,CAAC;KACH;;;;AAKO,IAAA,gBAAgB,CACtB,IAAS,EACT,KAAU,EACV,SAA0B,EAC1B,IAAmB,EACnB,OAA4B,EAC5B,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAE1C,QAAA,MAAM,MAAM,GAAG,SAAS,CAAC,MAAqB,CAAC;QAC/C,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;AACrC,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CACjC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,EAC5C,IAAI,CAAC,WAAW,EAChB,OAAO,CAAC,MAAM,EACd,cAAc,CAAC,MAAM,CAAC,CACvB,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;;;;;QAKtD,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AACnD,QAAA,MAAM,cAAc,GAAmB,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,oBAAoB,GAAG,QAAQ,CAAC;AAC3G,QAAA,MAAM,SAAS,GAAG;YAChB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9E,YAAA,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAChG,CAAC;AACF,QAAA,MAAM,OAAO,GAAgB;AAC3B,YAAA;AACE,gBAAA,IAAI,EAAE,KAAK;AACX,gBAAA,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,CAAC;AACxC,gBAAA,SAAS,EAAE,KAAK;gBAChB,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE;AACrF,aAAA;YACD,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;SACtG,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;AAChG,YAAA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;YACV,UAAU,EAAE,cAAc,KAAK,QAAQ;AACvC,YAAA,SAAS,EAAE,eAAe,CAAC,cAAc,CAAC;AAC1C,YAAA,cAAc,EAAE,CAAC;AACjB,YAAA,MAAM,EAAE,MAAM,CAAC,WAAW,KAAK,YAAY,GAAG,KAAK,GAAG,KAAK;YAC3D,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC;AAC7C,YAAA,GAAG,cAAc;;;;;YAKjB,sBAAsB,EAAE,IAAI,CAAC,cAAc,CACzC,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,EACpD,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,EAChE,KAAK,EACL,OAAO,EACP,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,CAC7B;YACD,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;;;AAG9C,YAAA,eAAe,EAAE,KAAK;AACvB,SAAA,CAAC,CAAC;KACJ;;;;;;;;AASO,IAAA,gBAAgB,CAAC,KAAsB,EAAA;AAC7C,QAAA,MAAM,IAAI,GAAoB,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAwB,CAAC;AACzE,QAAA,MAAM,KAAK,GAAG,CAAC,IAAuB,MAAM;AAC1C,YAAA,IAAI,EAAE,IAAI,EAAE,sBAAsB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAuB;AAChH,SAAA,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,MAAM,SAAS,GAAG,CAAC,KAAa,MAAM,KAAK,KAAK,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC;AAElE,QAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;AACxB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5C,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtC,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAEvC,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACnE,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CACxC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAClF,CAAC,CAAC;YACH,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CACxC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAClF,CAAC,CAAC;SACJ;AAED,QAAA,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;KACxG;;;;;AAMO,IAAA,eAAe,CACrB,UAAoB,EACpB,WAAgD,EAChD,MAAuB,EACvB,SAA+B,EAAA;QAE/B,IAAI,CAAC,WAAW,EAAE;AAChB,YAAA,OAAO,UAAU,CAAC;SACnB;AAED,QAAA,MAAM,SAAS,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;QAEjD,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,KAAK,iBAAiB,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;KAC7G;;;;;;;AAQO,IAAA,gBAAgB,CAAC,MAAmB,EAAE,IAAmB,EAAE,GAAY,EAAA;QAC7E,OAAO;AACL,YAAA,GAAG,eAAe;AAClB,YAAA,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC;AAC3C,YAAA,IAAI,GAAG;AACL,kBAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE;AAC7B,kBAAE,IAAI,CAAC,sBAAsB,CAC3B,MAAM,CAAC,SAAS,EAChB,MAAM,CAAC,SAAS,EAAE,KAAK,KAAK,MAAM,CAAC,cAAc,KAAK,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CACtG,CAAC;SACL,CAAC;KACH;;;;IAKO,qBAAqB,CAAC,MAAmB,EAAE,IAAmB,EAAA;QACpE,MAAM,KAAK,GAAG,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAE9C,OAAO;YACL,gBAAgB,EAAE,CAAC,CAAC,KAAK;AACzB,YAAA,YAAY,EAAE,KAAK;AACnB,YAAA,oBAAoB,EAAE,EAAE;SACzB,CAAC;KACH;;;;IAKO,sBAAsB,CAAC,IAAgC,EAAE,KAAyB,EAAA;AACxF,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAEnC,OAAO;YACL,gBAAgB,EAAE,CAAC,CAAC,KAAK;YACzB,YAAY,EAAE,KAAK,IAAI,SAAS;YAChC,aAAa,EAAE,KAAK,CAAC,GAAG;YACxB,aAAa,EAAE,KAAK,CAAC,GAAG;YACxB,gBAAgB,EAAE,KAAK,CAAC,QAAQ;SACjC,CAAC;KACH;;;AAIO,IAAA,YAAY,CAClB,KAAU,EACV,SAA0B,EAC1B,IAAmB,EACnB,aAAgC,EAChC,QAAgB,EAChB,OAA4B,EAC5B,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAE1C,QAAA,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAC5E,QAAA,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE/D,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC5E,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACrC,QAAA,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;;;QAIzE,MAAM,KAAK,GAAG,CAAC,KAAa,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QAErF,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,MAAM;AACnG,YAAA,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE;AACrF,SAAA,CAAC,CAAC,CAAC;;;AAIJ,QAAA,MAAM,WAAW,GAAG,CAAC,KAAa,KAAI;AACpC,YAAA,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAE9B,OAAO,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,sBAAsB,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;AACtG,SAAC,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM;AAC7D,YAAA,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC;AACpE,YAAA,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;SAC1D,CAAC,CAAC,CAAC,CAAC;AAEL,QAAA,IAAI,SAAS,GAAG,CAAC,EAAE;YACjB,IAAI,CAAC,IAAI,CAAC,CAAC;AACT,oBAAA,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC;AAC/B,oBAAA,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAS;AAC9E,iBAAA,CAAC,CAAC,CAAC;SACL;;QAGD,IAAI,MAAM,EAAE;YACV,MAAM,WAAW,GAAG,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAEhE,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM;gBACrC,IAAI;AACJ,gBAAA,OAAO,EAAE,cAAc,CACrB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAC1D,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,CACvE;aACF,CAAC,CAAC,CAAC,CAAC;SACN;QAED,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;YAChC,CAAC,EAAE,CAAC,EAAE,CAAC;AACP,YAAA,QAAQ,EAAE,CAAC;AACX,YAAA,KAAK,EAAE,QAAQ;AACf,YAAA,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;AACnD,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,WAAW;AACjB,YAAA,MAAM,EAAE,QAAQ;AACjB,SAAA,CAAC,CAAC;KACJ;;;;;;AAOO,IAAA,gBAAgB,CACtB,KAAU,EACV,IAAwB,EACxB,OAA4B,EAC5B,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;QAE1C,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAM,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,CAAC,QAAwB,EAAE,UAAmC,EAAE,MAAM;AACjF,YAAA,IAAI,EAAE,CAAA,EAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA,EAAG,QAAQ,CAAC,IAAI,CAAE,CAAA;YAC9D,OAAO,EAAE,cAAc,CAAC;gBACtB,IAAI,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;gBAC9D,IAAI,QAAQ,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;AAC9D,gBAAA,IAAI,QAAQ,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACxC,gBAAA,IAAI,QAAQ,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAC/C,gBAAA,GAAG,OAAO;AACX,aAAA,EAAE,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;AAClD,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,WAAW,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChG,QAAA,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvC,QAAA,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC;QAEpE,KAAK,CAAC,QAAQ,CAAC;AACb,YAAA,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;YAC/G,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,IAAI,SAAS,GAAG,CAAC;AACf,kBAAE,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;kBACrH,EAAE,CAAC;AACP,YAAA,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;SAC3G,EAAE;YACD,CAAC,EAAE,CAAC,EAAE,CAAC;AACP,YAAA,QAAQ,EAAE,CAAC;AACX,YAAA,KAAK,EAAE,QAAQ;AACf,YAAA,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE;AACnD,YAAA,QAAQ,EAAE,KAAK;AACf,YAAA,IAAI,EAAE,WAAW;AACjB,YAAA,MAAM,EAAE,QAAQ;AACjB,SAAA,CAAC,CAAC;KACJ;;;;;AAMO,IAAA,UAAU,CAChB,IAAS,EACT,KAAU,EACV,IAAwB,EACxB,QAAgB,EAChB,OAA4B,EAC5B,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,CAAS,EAAA;AAE1C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAmB,CAAC;AAClD,QAAA,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC3E,QAAA,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAE9D,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;YAClC,KAAK,CAAC,OAAO,CAAC;AACZ,gBAAA;oBACE,IAAI,EAAE,IAAI,CAAC,KAAK;oBAChB,OAAO,EAAE,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC;AACxG,iBAAA;AACD,gBAAA,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;aACpE,EAAE;AACD,gBAAA,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;AACV,gBAAA,KAAK,EAAE,QAAQ;AACf,gBAAA,MAAM,EAAE,QAAQ;AACjB,aAAA,CAAC,CAAC;YAEH,OAAO;SACR;;AAGD,QAAA,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC3D,QAAA,MAAM,YAAY,GAAG,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC;QACtD,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,OAAgC,KAAI;AACpF,YAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;gBAClB,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI;AACrB,gBAAA,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO;AACtE,aAAA,CAAC,CAAC;YACH,GAAG,IAAI,IAAI,CAAC;AACd,SAAC,CAAC;QAEF,IAAI,CACF,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAChG,OAAO,CAAC,KAAK,EACb,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAC/B,CAAC;AAEF,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE;YACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;SACrF;QAED,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;YAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AACzE,YAAA,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB;AAED,QAAA,IAAI,KAAK,CAAC,MAAM,EAAE;AAChB,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YAE7D,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE;AAClF,gBAAA,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW;AAC3C,aAAA,CAAC,CAAC;SACJ;QAED,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE;AAC/B,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACrD,YAAA,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB;QAED,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE;YACrC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AACpF,YAAA,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B;AAED,QAAA,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE;YACtB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;YAEtF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE;AAChF,gBAAA,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW;AAC9C,aAAA,CAAC,CAAC;SACJ;KACF;;;;;;AAOO,IAAA,SAAS,CACf,IAAS,EACT,KAAU,EACV,KAAmB,EACnB,OAA4B,EAC5B,CAAS,EAAE,GAAW,EAAE,CAAS,EACjC,KAAK,GAAG,CAAC,EAAA;QAET,MAAM,KAAK,GAAG,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACnD,QAAA,MAAM,QAAQ,GAAG,kBAAkB,GAAG,KAAK,CAAC;AAC5C,QAAA,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;AACvC,QAAA,MAAM,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,aAAa,GAAG,KAAK,CAAC;AACrF,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC3D,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ;AAC7B,cAAE,IAAI,CAAC,YAAY,CAAC,CAAA,CAAA,EAAI,KAAK,CAAC,QAAQ,CAAE,CAAA,EAAE,QAAQ,EAAE,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC;cACtE,EAAE,CAAC;QACP,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtF,QAAA,MAAM,IAAI,GAAG;YACX,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE;YACpF,IAAI,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC;SAC3E,CAAC;AAEF,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;YAClB,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,IAAI;AAC1D,YAAA,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM;AACpE,SAAA,CAAC,CAAC;QAEH,IAAI,KAAK,EAAE;YACT,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;AACtC,gBAAA,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,IAAI,CAAC,CAAC;gBAC3C,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC;AAC1B,gBAAA,CAAC,EAAE,IAAI;AACP,gBAAA,CAAC,EAAE,IAAI;gBACP,IAAI,EAAE,EAAE,KAAK,EAAE;AACf,gBAAA,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE;AACzB,gBAAA,KAAK,EAAE,KAAK,CAAC,KAAK,KAAK,cAAc,CAAC,IAAI;AAC3C,aAAA,CAAC,CAAC;SACJ;KACF;;;IAIO,eAAe,CAAC,IAAY,EAAE,QAAgB,EAAA;QACpD,OAAO,IAAI,CAAC,MAAM,GAAG,QAAQ,GAAG,eAAe,GAAG,EAAE,CAAC;KACtD;;;AAIO,IAAA,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAa,EAAA;QAChE,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,KAAK,EAAE;AACjD,YAAA,OAAO,IAAI,CAAC;SACb;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,IAAI,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAErF,OAAO,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;KAC1D;;;IAIO,UAAU,CAAC,IAAS,EAAE,KAAU,EAAE,MAAqB,EAAE,CAAS,EAAE,GAAW,EAAE,CAAS,EAAA;QAChG,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,GAAG,CAAA,EAAG,MAAM,CAAC,IAAI,CAAM,GAAA,EAAA,MAAM,CAAC,QAAQ,CAAE,CAAA,GAAG,MAAM,CAAC,IAAI,CAAC;AAEnF,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC,EAAE;YAC5D,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,iBAAiB;YAClC,QAAQ,EAAE,kBAAkB,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM;AAC5G,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE;YACxB,OAAO;SACR;AAED,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;AAChC,QAAA,MAAM,IAAI,GAAG,GAAG,GAAG,iBAAiB,GAAG,WAAW,CAAC;AACnD,QAAA,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,KAAa,KAAK,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;AAChF,YAAA,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE;AACrF,SAAA,CAAC,CAAC;AAEH,QAAA,GAAG,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;AAE3B,QAAA,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,EAAE;AACnB,YAAA,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;SAChE;KACF;;;;;;AAOO,IAAA,aAAa,CACnB,IAAS,EACT,KAAU,EACV,IAAwB,EACxB,MAAyB,EACzB,KAAa,EACb,CAAS,EAAE,GAAW,EAAE,CAAS,EAAA;AAEjC,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,KAAsB,KAAK,KAAK,IAAI,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AAC3D,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,eAAe,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;;;QAGrD,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI;AACrD,gBAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtF,MAAM,KAAK,GAAG,0BAA0B,CAAC;AAEzC,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;AACpD,gBAAA,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,CAAC,CAAC,CAAC;AACZ,gBAAA,SAAS,EAAE,KAAK;AAChB,gBAAA,OAAO,EAAE;oBACP,WAAW,EAAE,CAAC,KAAK,CAAC;AACpB,oBAAA,QAAQ,EAAE,GAAG;AACb,oBAAA,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,eAAe,GAAG,QAAQ,GAAG,MAAM;AAC3E,oBAAA,kBAAkB,EAAE,CAAC;AACtB,iBAAA;AACF,aAAA,CAAC,EAAE,CAAC;gBACH,IAAI,EAAE,KAAK,IAAI,kBAAkB;gBACjC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBACrE,MAAM;AACP,aAAA,CAAC,EAAE;YACF,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,WAAW,CAAC,SAAS;AAChE,YAAA,UAAU,EAAE,KAAK;AACjB,YAAA,SAAS,EAAE,KAAK;AAChB,YAAA,aAAa,EAAE,IAAI;AACnB,YAAA,aAAa,EAAE,IAAI;AACnB,YAAA,eAAe,EAAE,KAAK;AACtB,YAAA,eAAe,EAAE,KAAK;AACtB,YAAA,gBAAgB,EAAE,KAAK;AACvB,YAAA,gBAAgB,EAAE,KAAK;AACvB,YAAA,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;AAC9B,YAAA,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YAC9B,aAAa,EAAE,GAAG,GAAG,GAAG;YACxB,aAAa,EAAE,IAAI,GAAG,GAAG;AACzB,YAAA,GAAG,cAAc;AAClB,SAAA,CAAC,CAAC;KACJ;AAEO,IAAA,KAAK,CAAC,IAAY,EAAA;QACxB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC;KAC3F;wGA//CU,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAjB,iBAAiB,EAAA,CAAA,CAAA;;4FAAjB,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAD7B,UAAU;;AAmgDX;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU,CAAC,KAAiC,EAAE,IAAmB,EAAA;AACxE,IAAA,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,MAAc,KAAK,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AACtH,IAAA,MAAM,OAAO,GAAG,CAAC,KAAa,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACtG,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;AAEhB,IAAA,OAAO,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE;AACtE,QAAA,OAAO,EAAE,CAAC;KACX;AACD,IAAA,OAAO,OAAO,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,EAAE;AAChH,QAAA,OAAO,EAAE,CAAC;KACX;IAED,MAAM,OAAO,GAAG,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9C,IAAA,KAAK,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,OAAO,EAAE,GAAG,EAAE,EAAE;AACxD,QAAA,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;KAC9D;AACH;;AClzDA;AACA;AACA;AACA;AACA,MAAM,KAAK,GAAG,OAAO,CAAC;AACtB,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MAEa,mBAAmB,CAAA;AAEtB,IAAA,UAAU,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AAClD,IAAA,WAAW,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AACvC,IAAA,YAAY,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AACzC,IAAA,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAE5B,IAAA,GAAG,CAAC,MAAc,EAAA;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;KAC3F;AAEM,IAAA,UAAU,CAAC,MAAc,EAAA;QAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;KAC7F;;;;;;;;AASO,IAAA,IAAI,CACV,MAAc,EACd,QAAgB,EAChB,KAA2D,EAAA;QAE3D,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC;AAC7C,aAAA,IAAI,CACH,SAAS,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC;aAClD,IAAI,CACH,SAAS,CAAC,CAAC,MAAM,KAAK,MAAM,KAAK,KAAK;cAClC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;AACpC,cAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAC1C,CAAC,CACL,CAAC;KACL;;;IAIO,aAAa,CACnB,SAA0B,EAC1B,KAA2D,EAAA;AAE3D,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAC1B,aAAA,IAAI,CACH,SAAS,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;AAC1C,aAAA,IAAI,CACH,SAAS,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAC1C,SAAS,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CACrD,CAAC,CACL,CAAC;KACL;;;;;AAMO,IAAA,YAAY,CAAC,SAA0B,EAAA;QAC7C,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1D,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AAClB,YAAA,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;SACrB;AAED,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC;AAC/B,cAAE,CAAW,QAAA,EAAA,MAAM,CAAC,CAAC,CAAC,CAAkC,gCAAA,CAAA;AACxD,cAAE,CAAA,EAAG,MAAM,CAAC,MAAM,CAAA,uCAAA,EAA0C,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC;AAE5G,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC1B,YAAA,KAAK,EAAE,sBAAsB;YAC7B,QAAQ,EAAE,CAAG,EAAA,KAAK,CAAoE,kEAAA,CAAA;kBAClF,iEAAiE;AACrE,YAAA,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;gBAClD,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;gBACxD,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;AAC7C,aAAA;SACF,CAAC;aACC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;KAClC;;;;;;;AAQO,IAAA,YAAY,CAAC,KAAkB,EAAA;AACrC,QAAA,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE;AACzB,YAAA,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;SACrB;AAED,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO;AAC7B,aAAA,GAAG,CAAC,CAAC,OAAO,KAAK,CAAW,QAAA,EAAA,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAW,SAAA,CAAA;eAC3D,OAAO,CAAC,IAAI,GAAG,CAAA,GAAA,EAAM,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;AAEhE,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC1B,YAAA,KAAK,EAAE,+BAA+B;YACtC,QAAQ,EAAE,kCAAkC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAI,EAAA,CAAA;kBACjE,oDAAoD;AACxD,YAAA,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE;gBAC/D,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;AAC7C,aAAA;SACF,CAAC;aACC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;KAClC;;;;;;;AAQO,IAAA,aAAa,CAAC,KAAkB,EAAA;AACtC,QAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE;AAC3B,YAAA,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;SACrB;;;AAID,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS;AAC3B,aAAA,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAW,QAAA,EAAA,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAW,SAAA,CAAA;eAC7D,QAAQ,CAAC,OAAO,GAAG,CAAA,GAAA,EAAM,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;AAExE,QAAA,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AAC1B,YAAA,KAAK,EAAE,mBAAmB;AAC1B,YAAA,QAAQ,EAAE,CAAA,gCAAA,EAAmC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAK,EAAA,EAAA,KAAK,CAAC,YAAY,CAAE,CAAA;AACvF,YAAA,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE;gBAC/D,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;AAC7C,aAAA;SACF,CAAC;aACC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;KAClC;wGAtIU,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;4GAAnB,mBAAmB,EAAA,CAAA,CAAA;;4FAAnB,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAD/B,UAAU;;;ACvBJ,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,cAAc,GAAG,GAAG,CAAC;AAGlC;AACA;AACM,SAAU,eAAe,CAAC,QAA6B,EAAA;AAC3D,IAAA,OAAO,QAAQ,CAAC,KAAK,KAAK,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC1D,CAAC;AAGD;AACA;AACA;AACA;AACA;AACgB,SAAA,gBAAgB,CAAC,QAA6B,EAAE,MAAuB,EAAA;IACrF,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;AACxC,SAAA,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC;AAC3C,SAAA,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM;AAC7B,QAAA,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC;AAChC,QAAA,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;AACpB,aAAA,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;AACzB,aAAA,GAAG,CAAC,CAAC,IAAI,MAAM;YACd,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3E,SAAA,CAAC,CAAC;AACN,KAAA,CAAC,CAAC,CAAC;AACR,CAAC;AAGD;AACA;AACA;AACA;AACA;SACgB,eAAe,CAC7B,MAAqB,EACrB,MAAqB,EACrB,QAA2D,EAAA;IAE3D,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;AACtE,IAAA,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE;AACpB,QAAA,OAAO,EAAE,CAAC;KACX;IAED,OAAO;AACL,QAAA,IAAI,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;AAC1B,QAAA,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,CAAC;AAC9D,KAAA;SACE,MAAM,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC;AAChD,SAAA,GAAG,CAAC,CAAC,SAAS,KAAI;AACjB,QAAA,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QAEnC,OAAO,MAAM,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC;AACxF,KAAC,CAAC,CAAC;AACP;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;SACgB,uBAAuB,GAAA;AACrC,IAAA,MAAM,MAAM,GAAwB;AAClC,QAAA,GAAG,4BAA4B;AAC/B,QAAA,YAAY,EAAE,qBAAqB;AACnC,QAAA,MAAM,EAAE,IAAI;KACb,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC7D;;ACNA;AACM,SAAU,iBAAiB,CAAC,MAAuD,EAAA;IACvF,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;AAC9F,CAAC;AAED;AACA;AACA;AACA;AACA;AACgB,SAAA,iBAAiB,CAC/B,OAAmD,EACnD,MAAoC,EAAA;IAEpC,MAAM,IAAI,GAA4B,EAAE,CAAC;AAEzC,IAAA,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACvB,QAAA,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;AAClC,QAAA,MAAM,KAAK,GAAG,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC;cACxE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;cAC/B,IAAI,CAAC;AAET,QAAA,IAAI,KAAK,KAAK,IAAI,EAAE;AAClB,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;SACpB;AACH,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,IAAI,CAAC;AACd,CAAC;AAED;AACA,SAAS,SAAS,CAAC,KAAwB,EAAE,KAAc,EAAA;AACzD,IAAA,QAAQ,KAAK,CAAC,IAAI;AAChB,QAAA,KAAK,WAAW;AACd,YAAA,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;AAE/B,QAAA,KAAK,QAAQ;AACX,YAAA,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;AAE5B,QAAA,KAAK,aAAa;;;AAGhB,YAAA,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;AAErE,QAAA;AACE,YAAA,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;KAC3B;AACH,CAAC;AAED;AACA,SAAS,cAAc,CAAC,KAAc,EAAA;AACpC,IAAA,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;AACzB,QAAA,OAAO,IAAI,CAAC;KACb;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAE7B,IAAA,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE;AAChB,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;AACA;AACA,SAAS,WAAW,CAAC,KAAc,EAAA;AACjC,IAAA,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE;QACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAEvC,QAAA,OAAO,QAAQ,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;KACxE;AAED,IAAA,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAED;AACA,SAAS,UAAU,CAAC,KAA8B,EAAA;IAChD,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE;AAC1C,QAAA,OAAO,IAAI,CAAC;KACb;AAED,IAAA,OAAO,EAAE,IAAI,GAAG,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,KAAK,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAA;IAC/B,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;IAEhG,OAAO,IAAI,IAAI,IAAI,CAAC;AACtB,CAAC;AAED;AACA,SAAS,KAAK,CAAC,KAAc,EAAA;AAC3B,IAAA,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE;SAC5C,MAAM,CAAC,CAAC,IAAI,KAAsC,aAAa,CAAC,IAAI,CAAC;AACjE,WAAA,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAE7E,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,CAAC;AAED;AACA;AACA,SAAS,OAAO,CAAC,KAAc,EAAA;AAC7B,IAAA,IAAI,KAAK,YAAY,IAAI,EAAE;QACzB,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;KAC9E;IAED,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC;AACnG,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAA;IACnC,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,YAAY,IAAI,CAAC,CAAC;AAC1G;;AC1EA;AACA;AACA;AACA;MAuCa,mBAAmB,CAAA;;AAGd,IAAA,QAAQ,GAAG,KAAK,CAAgB,IAAI,CAAC,CAAC;;AAGtC,IAAA,QAAQ,GAAG,KAAK,CAAS,SAAS,CAAC,CAAC;;;;;;;AAQpC,IAAA,cAAc,GAAG,KAAK,CAAgB,MAAM,CAAC,CAAC;;;IAI9C,OAAO,GAAG,MAAM,EAAU,CAAC;;;IAI3B,OAAO,GAAG,MAAM,EAAU,CAAC;;;IAI3B,WAAW,GAAG,MAAM,EAAiB,CAAC;AAEtC,IAAA,MAAM,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;AACrC,IAAA,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;;;;AAKzB,IAAA,MAAM,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;;;;AAQrC,IAAA,UAAU,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;;;;;;;;;AAUzC,IAAA,YAAY,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,UAAU,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;AAC5E,KAAC,CAAC,CAAC;;;;AAKa,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AAC1C,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE7B,OAAO,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,CAAC;AAClD,KAAC,CAAC,CAAC;;;AAIa,IAAA,kBAAkB,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;;;AAIvD,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AAC/C,QAAA,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;AAClE,KAAC,CAAC,CAAC;;;;AAKa,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;QAC9C,OAAO;;;YAGL,IAAI,CAAC,WAAW,EAAE;;;AAGlB,YAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;;;;AAI5B,YAAA,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AAC/B,YAAA,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG,KAAK,CAAC,EAAE,CAAA,CAAA,EAAI,KAAK,CAAC,KAAK,CAAA,CAAA,EAAI,KAAK,CAAC,KAAK,CAAA,CAAA,EAAI,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;;;YAG9G,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAQ,KAAA,EAAA,IAAI,CAAC,UAAU,EAAE,CAAA,CAAE,CAAC,GAAG,EAAE,CAAC;AACtE,SAAA,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,KAAC,CAAC,CAAC;AAGK,IAAA,MAAM,CAA8B;;AAIpC,IAAA,UAAU,CAA2B;;;AAKrC,IAAA,OAAO,CAAyB;;;AAKhC,IAAA,UAAU,CAAmB;AAE7B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAC7C,IAAA,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAChC,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AACzB,IAAA,YAAY,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AAChD,IAAA,cAAc,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AACpD,IAAA,cAAc,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAC7C,IAAA,UAAU,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AAClD,IAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC7B,IAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAC5B,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AACjC,IAAA,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;;AAGd,IAAA,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;;;;;IAOjC,gBAAgB,GAAmC,IAAI,CAAC;;;IAIxD,4BAA4B,GAAkB,IAAI,CAAC;AAE3D,IAAA,WAAA,GAAA;;;AAGE,QAAA,IAAI,CAAC,iBAAiB,CAAC,QAAQ,GAAG,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;;;QAInF,MAAM,CAAC,MAAK;YACV,IAAI,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AAC9C,SAAC,CAAC,CAAC;;QAGH,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;;;;AAKjC,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;;;YAIrC,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;;AAIzB,gBAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAExB,gBAAA,IAAI,QAAQ,IAAI,IAAI,EAAE;AACpB,oBAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;iBAC5B;qBAAM;AACL,oBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBACtB,IAAI,CAAC,kBAAkB,EAAE,CAAC;iBAC3B;AACH,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;;;;QAKH,MAAM,CAAC,MAAK;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;YAEjD,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,OAAO,KAAK,IAAI,CAAC,WAAW,EAAE,EAAE;oBAClC,IAAI,CAAC,kBAAkB,EAAE,CAAC;iBAC3B;AACH,aAAC,CAAC,CAAC;AACL,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,EAAE,CAAC;KAC3B;IAEM,cAAc,GAAA;AACnB,QAAA,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,CAAC,QAAQ,CAAC,CAAC;KAC/C;;;AAID,IAAA,IAAW,YAAY,GAAA;QACrB,OAAO,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,KAAK,CAAC;KAC5C;IAEM,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;KACzB;IAEM,gBAAgB,GAAA;AACrB,QAAA,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC;KAClC;;;IAIM,cAAc,GAAA;AACnB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;QAE3B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAyD,uBAAuB,EAAE;YACnH,IAAI,EAAE,EAAE,MAAM,EAAE;AAChB,YAAA,KAAK,EAAE,OAAO;AACf,SAAA,CAAC,CAAC;AACH,QAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,iBAAiB,CAAC;QAE7C,SAAS,CAAC,WAAW,EAAE;AACpB,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AACpB,YAAA,IAAI,MAAM,EAAE,MAAM,KAAK,SAAS,EAAE;AAChC,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAE5B,OAAO;aACR;;;YAID,IAAI,MAAM,EAAE,MAAM,KAAK,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,EAAE;AAClD,gBAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;aAClC;AACH,SAAC,CAAC,CAAC;KACN;;;AAIM,IAAA,iBAAiB,CAAC,SAA+B,EAAA;AACtD,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAC5B,OAAO;SACR;AAED,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,CAAC;;;QAI3B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CACjC,0BAA0B,EAC1B;AACE,YAAA,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;AAC5E,YAAA,KAAK,EAAE,OAAO;AACf,SAAA,CACF,CAAC;;;;;QAMF,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,SAAS,CAAC,iBAAiB,CAAC,cAAc;aACvC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;aACxC,SAAS,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC,CAAC;QAE1C,SAAS,CAAC,WAAW,EAAE;AACpB,aAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC1C,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;;;;AAIpB,YAAA,IAAI,MAAM,EAAE,OAAO,EAAE;AACnB,gBAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAE3B,OAAO;aACR;;;YAID,IAAI,cAAc,EAAE;AAClB,gBAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAE3B,OAAO;aACR;;;;AAKD,YAAA,IAAI,MAAM,EAAE,QAAQ,EAAE;AACpB,gBAAA,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;aACrE;AACH,SAAC,CAAC,CAAC;KACN;;;AAIM,IAAA,mBAAmB,CAAC,MAAqB,EAAA;;AAE9C,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtB,QAAA,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;;AAE5B,QAAA,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;;QAG7B,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;YAC/B,IAAI,CAAC,kBAAkB,EAAE,CAAC;SAC3B;KACF;;;IAIM,qBAAqB,GAAA;AAC1B,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SAC7B;KACF;;;IAIM,gBAAgB,GAAA;AACrB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CACf,sBAAsB,EACtB,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,CACvC,CAAC;KACH;;IAGM,SAAS,GAAA;AACd,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CACf,eAAe,EACf,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAChC,CAAC;KACH;;;;;;;;;;;;;;;AAgBM,IAAA,UAAU,CAAC,QAAQ,GAAG,KAAK,EAAE,SAA6B,KAAK,EAAA;AACpE,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE;YACX,OAAO;SACR;AAED,QAAA,MAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,IAAI,GAAG,IAAI,CAAC;AACtE,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,SAAS,KAAK,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;AAE9H,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CACpB,MAAM,KAAK,MAAM,GAAG,iBAAiB,GAAG,gBAAgB,EACxD,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;AACpD,aAAA,IAAI,CACH,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,WAAW,CAAC,YAAY,CAC5D,MAAM,CAAC,EAAE,EACT,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,EACN,EAAE,EACF,MAAM,CACP,CAAC,CACH,CACJ,CAAC;KACH;;;AAIM,IAAA,cAAc,CAAC,QAA0B,EAAA;AAC9C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;AACjC,QAAA,IAAI,QAAQ,IAAI,IAAI,EAAE;YACpB,OAAO;SACR;QAED,MAAM,cAAc,GAAG,QAAiD,CAAC;;;;QAKzE,IAAI,cAAc,CAAC,aAAa,IAAI,cAAc,CAAC,aAAa,EAAE;YAChE,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;SAC5D;KACF;;;AAIM,IAAA,aAAa,CAAC,KAAmB,EAAA;QACtC,KAAK,CAAC,cAAc,EAAE,CAAC;AAEvB,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;AAC3C,QAAA,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAEpD,QAAA,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAK;AAChC,YAAA,MAAM,IAAI,GAAG,CAAC,CAAe,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,MAAK;AACf,gBAAA,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAC9C,gBAAA,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChD,gBAAA,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAC7C,gBAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;gBACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACzD,aAAC,CAAC;AAEF,YAAA,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAC7C,YAAA,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAC1C,YAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;AAChD,SAAC,CAAC,CAAC;KACJ;;;;;;;IAQO,gBAAgB,GAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;AAC9C,QAAA,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC;AACpF,QAAA,MAAM,KAAK,GAAG,eAAe,CAC3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAC1B,IAAI,CAAC,UAAU,EAAE,EACjB,CAAC,SAAS,KAAK,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAC9D,CAAC;QAEF,OAAO;AACL,YAAA,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE;AAC1C,YAAA,mBAAmB,EAAE,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,IAAI,GAAG,IAAI;AACzF,YAAA,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE;YAC1C,GAAG,eAAe,CAAC,QAAQ,CAAC;AAC5B,YAAA,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACpC,YAAA,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;SACnC,CAAC;KACH;AAEO,IAAA,SAAS,CAAC,OAAe,EAAA;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,qBAAqB,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACxC,OAAO;SACR;AAED,QAAA,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC;AACjD,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AACpD,QAAA,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,GAAG,CAAG,EAAA,OAAO,GAAG,GAAG,GAAG,CAAC;KACrE;;;;;;AAOO,IAAA,eAAe,CAAC,MAAqB,EAAA;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;AACpC,QAAA,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,EAAE;YACzD,OAAO;SACR;AAED,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE;YACxB,UAAU,EAAE,IAAI,CAAC,MAAM;AACvB,YAAA,WAAW,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,EAAE;AAChC,YAAA,mBAAmB,EAAE,OAAO;AAC5B,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA,CAAC,CAAC;KACJ;;;IAIO,cAAc,GAAA;AACpB,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,OAAO,IAAI,CAAC;SACb;AAED,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAErE,QAAA,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;KAC9D;;;;AAKO,IAAA,WAAW,CAAC,QAAgB,EAAE,WAAW,GAAG,KAAK,EAAA;AACvD,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC;aAC3B,IAAI,CACH,GAAG,CAAC,CAAC,MAAc,KAAK,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EACvD,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,CACrC;AACA,aAAA,SAAS,CAAC,CAAC,MAAc,KAAI;AAC5B,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxB,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAE1B,IAAI,WAAW,EAAE;AACf,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aAC3B;AACH,SAAC,CAAC,CAAC;KACN;;;;IAKO,aAAa,GAAA;AACnB,QAAA,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;KAC1D;;;IAIO,kBAAkB,GAAA;AACxB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAC7B,QAAA,MAAM,QAAQ,GAAG,MAAM,EAAE,EAAE,IAAI,IAAI,CAAC;;;AAIpC,QAAA,IAAI,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC,EAAE;AAC1E,YAAA,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;SACtC;AAED,QAAA,MAAM,QAAQ,GAAG,MAAM,EAAE,cAAc,IAAI,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,QAAQ;AACpB,cAAE,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAC/B,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;cACpG,EAAE,CAAC;;;;;AAMP,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACxC,IAAI,WAAW,EAAE;AACf,YAAA,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;SAC5B;;AAGD,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,IAAI,SAAS,EAAE;AACb,YAAA,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;SACvB;AAED,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAEhD,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;AACvD,QAAA,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC;;;AAG1B,YAAA,UAAU,EAAE,KAAK;AACjB,YAAA,OAAO,EAAE,KAAK;AACd,YAAA,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,KAAK;AACrD,YAAA,MAAM,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC;;;;YAI7D,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;;;YAGhD,YAAY,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE;YAC3D,YAAY;;YAEZ,IAAI,YAAY,IAAI,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;AAC5F,SAAA,CAAC,CAAC;KACJ;;;;;;;AAQO,IAAA,uBAAuB,CAAC,QAAgB,EAAA;AAC9C,QAAA,MAAM,qBAAqB,GAAG,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC;QAErE,IAAI,IAAI,CAAC,4BAA4B,KAAK,QAAQ,IAAI,CAAC,qBAAqB,EAAE;YAC5E,OAAO;SACR;AAED,QAAA,IAAI,CAAC,4BAA4B,GAAG,QAAQ,CAAC;AAE7C,QAAA,MAAM,CAAC,KAAK,CAAC,GAAG,qBAAqB,CAAC,YAAY,CAAC;QACnD,IAAI,KAAK,EAAE;AACT,YAAA,qBAAqB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;SAC9C;KACF;;;;;;;;;;IAWO,mBAAmB,GAAA;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,IAAI,CAAC;AAE3C,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE;AAChE,YAAA,OAAO,SAAS,CAAC;SAClB;QAED,OAAO;AACL,YAAA,IAAI,EAAE,MAAM,IAAI,CAAC,WAAW;AACzB,iBAAA,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,WAAW,EAAE,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;AAClF,iBAAA,IAAI,CACH,UAAU,CAAC,MAAM,EAAE,CAAC,EAAyB,CAAC,CAAC,EAC/C,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,YAAY,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CACpG;AACH,YAAA,IAAI,EAAE,CAAC,WAAW,KAAI;AACpB,gBAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;AAClF,gBAAA,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE;AAC1B,sBAAE,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE;AACrE,wBAAA,IAAI,WAAW,CAAC,IAAI,GAAG,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC;wBACvD,OAAO;qBACR,CAAC;sBACA,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AAE5F,gBAAA,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aAChE;YACD,KAAK,EAAE,CAAC,YAAY,KAAK,IAAI,CAAC,WAAW;AACtC,iBAAA,wBAAwB,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7F,iBAAA,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YAClG,MAAM,EAAE,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW;iBACtC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;iBACnD,IAAI,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC;SAChC,CAAC;KACH;;IAGO,kBAAkB,GAAA;QACxB,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC;KACvD;;;;;;;;AASO,IAAA,eAAe,CAAC,WAA8B,EAAA;AACpD,QAAA,MAAM,OAAO,GAAG,iBAAiB,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAE5C,OAAO;YACL,EAAE,EAAE,WAAW,CAAC,EAAE;YAClB,IAAI,EAAE,WAAW,CAAC,IAAI;AACtB,YAAA,IAAI,OAAO,GAAA;AACT,gBAAA,OAAO,EAAE,CAAC;gBAEV,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;aAC5C;SACF,CAAC;KACH;;;;;;IAOO,cAAc,GAAA;AACpB,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACpB,OAAO;SACR;QAED,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACtD,cAAc,CAAC,MAAM,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;KACpD;;;;;;;;;AAUO,IAAA,WAAW,CAAC,KAA0B,EAAA;QAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAErF,QAAA,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;AAC7C,cAAE,IAAI;cACJ,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,OAAoC,KAAK,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;KACpG;AAEO,IAAA,eAAe,CAAC,IAAiC,EAAA;AACvD,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,YAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;SACxD;KACF;;;IAIO,WAAW,CAAC,KAA8B,EAAE,QAAiB,EAAA;AACnE,QAAA,KAAK,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE;YAClF,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SAC5C;;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,YAAY,CAAE,KAAK,CAAC,aAAa,CAAsB,IAAI,IAAI,CAAC,CAAC;;QAEnF,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;SACnD;KACF;;;;IAKO,YAAY,GAAA;AAClB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;AAE7B,QAAA,OAAO,MAAM;cACT,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;cACxD,IAAI,CAAC;KACV;;;IAIO,UAAU,GAAA;QAChB,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;KAC3G;wGAhvBU,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,EA/BnB,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,EAAA,iBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,gBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,SAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,SAAA,EAAA;;;YAGT,wBAAwB;;YAExB,0BAA0B;YAC1B,4BAA4B;YAC5B,iBAAiB;YACjB,gBAAgB;YAChB,uBAAuB;YACvB,mBAAmB;;;YAGnB,gBAAgB;AAChB,YAAA,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE;;YAExD,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,0CAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;;;AAGrG,YAAA,uBAAuB,EAAE;SAC1B,EAgH+B,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,QAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,OAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,WAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EAAA,UAAU,uDAK/B,qBAAqB,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,YAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAKrB,eAAe,ECnN5B,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAAA,q3JAuJA,qlDD5DI,cAAc,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAhC,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACd,YAAY,EACZ,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,IAAA,CAAA,eAAA,EAAA,QAAA,EAAA,SAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,aAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,8BAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,sBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,iBAAiB,iLACjB,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,IAAA,CAAA,SAAA,EAAA,QAAA,EAAA,6GAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,aAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EACf,aAAa,EACb,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,gBAAgB,+TAChB,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,UAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,EAAA,eAAA,EAAA,aAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAGZ,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAtC/B,SAAS;+BACE,cAAc,EAAA,eAAA,EAGP,uBAAuB,CAAC,MAAM,EAAA,UAAA,EACnC,IAAI,EACP,OAAA,EAAA,CAAC,sBAAsB,CAAC,EACtB,SAAA,EAAA;;;wBAGT,wBAAwB;;wBAExB,0BAA0B;wBAC1B,4BAA4B;wBAC5B,iBAAiB;wBACjB,gBAAgB;wBAChB,uBAAuB;wBACvB,mBAAmB;;;wBAGnB,gBAAgB;AAChB,wBAAA,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE;;wBAExD,kBAAkB,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,0CAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;;;AAGrG,wBAAA,uBAAuB,EAAE;qBAC1B,EACQ,OAAA,EAAA;wBACP,cAAc;wBACd,YAAY;wBACZ,iBAAiB;wBACjB,eAAe;wBACf,aAAa;wBACb,gBAAgB;wBAChB,qBAAqB;AACtB,qBAAA,EAAA,QAAA,EAAA,q3JAAA,EAAA,MAAA,EAAA,CAAA,8hDAAA,CAAA,EAAA,CAAA;wDAoGO,MAAM,EAAA,CAAA;sBADb,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;gBAK5B,UAAU,EAAA,CAAA;sBADjB,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,WAAW,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;gBAMpC,OAAO,EAAA,CAAA;sBADd,SAAS;uBAAC,qBAAqB,CAAA;gBAMxB,UAAU,EAAA,CAAA;sBADjB,SAAS;uBAAC,eAAe,CAAA;;;AE1M5B;AACA;AACA;MAIa,aAAa,CAAA;AAEhB,IAAA,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAEjC,IAAA,SAAS,GAAG,IAAI,eAAe,CAAmB,EAAE,CAAC,CAAC;AAE9D,IAAA,IAAW,QAAQ,GAAA;AACjB,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;KACtC;IAEM,IAAI,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;aAC9B,IAAI,CACH,GAAG,CAAC,CAAC,OAAyB,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CACvE,CAAC;KACL;;AAGM,IAAA,MAAM,CAAC,OAAe,EAAA;AAC3B,QAAA,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAE1C,IAAI,CAAC,IAAI,EAAE;AACT,YAAA,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC;SACpB;QAED,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjF;AAEM,IAAA,MAAM,CAAC,IAAY,EAAA;AACxB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;AACjC,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,MAAsB,KAAI;AAC7B,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;SAC7D,CAAC,CACH,CAAC;KACL;IAEM,MAAM,CAAC,QAAgB,EAAE,IAAY,EAAA;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC;AAC3C,aAAA,IAAI,CACH,GAAG,CAAC,CAAC,MAAsB,KAAI;YAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE;iBACtB,GAAG,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC,CACtE,CAAC;SACH,CAAC,CACH,CAAC;KACL;AAEM,IAAA,MAAM,CAAC,QAAgB,EAAA;AAC5B,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC;AACrC,aAAA,IAAI,CACH,GAAG,CAAC,MAAK;YACP,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,QAAQ,CAAC,CACrE,CAAC;SACH,CAAC,EACF,GAAG,CAAC,MAAM,SAAS,CAAC,CACrB,CAAC;KACL;wGA5DU,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cAFZ,MAAM,EAAA,CAAA,CAAA;;4FAEP,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;AACnB,iBAAA,CAAA;;;ACdD;;;;;;AAMG;AACH;AACA;;ACRA;;AAEG;;;;"}
|