@firestitch/report 18.12.0 → 18.14.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.
Files changed (56) hide show
  1. package/app/reports/components/component-grid/component-grid.component.d.ts +9 -1
  2. package/app/reports/components/component-grid/report-grid-cell.pipe.d.ts +11 -0
  3. package/app/reports/components/report-component/report-component.component.d.ts +0 -1
  4. package/app/reports/data/report-grid-source.d.ts +1 -0
  5. package/app/reports/export/report-export-collector.service.d.ts +8 -1
  6. package/app/reports/export/report-filter-lines.d.ts +2 -0
  7. package/app/reports/export/report-grid-export.d.ts +20 -0
  8. package/app/reports/export/report-pdf.service.d.ts +2 -0
  9. package/app/reports/export/report-pptx.service.d.ts +1 -0
  10. package/app/reports/group-by.d.ts +3 -0
  11. package/app/reports/interfaces/{report-chat-viewer-detail.interface.d.ts → report-chat-viewer-show-rows.interface.d.ts} +1 -1
  12. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +2 -2
  13. package/app/reports/interfaces/report-export-snapshot.interface.d.ts +2 -0
  14. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -1
  15. package/app/reports/interfaces/report-temporary-state.interface.d.ts +1 -1
  16. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -1
  17. package/app/reports/interfaces/report.interface.d.ts +7 -0
  18. package/app/reports/report-filter-items.d.ts +1 -1
  19. package/app/reports/report-grid-layout.d.ts +9 -2
  20. package/app/reports/services/report-filter-state.service.d.ts +8 -1
  21. package/app/reports/tile-data-state.d.ts +2 -2
  22. package/esm2022/app/reports/components/component-grid/component-grid.component.mjs +70 -8
  23. package/esm2022/app/reports/components/component-grid/report-grid-cell.pipe.mjs +41 -0
  24. package/esm2022/app/reports/components/report-component/report-component.component.mjs +15 -19
  25. package/esm2022/app/reports/data/report-grid-source.mjs +11 -2
  26. package/esm2022/app/reports/data/report.data.mjs +3 -3
  27. package/esm2022/app/reports/export/report-export-collector.service.mjs +72 -7
  28. package/esm2022/app/reports/export/report-filter-lines.mjs +68 -1
  29. package/esm2022/app/reports/export/report-grid-export.mjs +48 -0
  30. package/esm2022/app/reports/export/report-pdf.service.mjs +47 -17
  31. package/esm2022/app/reports/export/report-pptx.service.mjs +48 -4
  32. package/esm2022/app/reports/group-by.mjs +13 -0
  33. package/esm2022/app/reports/interfaces/report-chat-viewer-show-rows.interface.mjs +2 -0
  34. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  35. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +1 -1
  36. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +1 -1
  37. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +1 -1
  38. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +1 -1
  39. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  40. package/esm2022/app/reports/mark-click.mjs +2 -2
  41. package/esm2022/app/reports/option-builder.mjs +4 -4
  42. package/esm2022/app/reports/report-filter-items.mjs +9 -7
  43. package/esm2022/app/reports/report-grid-layout.mjs +98 -4
  44. package/esm2022/app/reports/report-viewer-features.mjs +4 -2
  45. package/esm2022/app/reports/services/report-filter-state.service.mjs +125 -39
  46. package/esm2022/app/reports/tile-data-state.mjs +12 -17
  47. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +2 -2
  48. package/esm2022/app/reports/views/report/report.component.mjs +2 -2
  49. package/fesm2022/{firestitch-report-echarts-CoaGXKET.mjs → firestitch-report-echarts-DMflI6jp.mjs} +2 -2
  50. package/fesm2022/{firestitch-report-echarts-CoaGXKET.mjs.map → firestitch-report-echarts-DMflI6jp.mjs.map} +1 -1
  51. package/fesm2022/{firestitch-report-firestitch-report-CHPA7sla.mjs → firestitch-report-firestitch-report-C94rjx24.mjs} +660 -125
  52. package/fesm2022/firestitch-report-firestitch-report-C94rjx24.mjs.map +1 -0
  53. package/fesm2022/firestitch-report.mjs +1 -1
  54. package/package.json +2 -2
  55. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +0 -2
  56. package/fesm2022/firestitch-report-firestitch-report-CHPA7sla.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { OnInit } from '@angular/core';
2
- import { GridLayout } from '@firestitch/grid';
2
+ import { GridExpansion, GridLayout } from '@firestitch/grid';
3
3
  import { ReportGridSource } from '../../data/report-grid-source';
4
4
  import { ReportGridParams } from '../../interfaces/report-grid-params.interface';
5
5
  import { ReportComponent } from '../../interfaces/report.interface';
@@ -11,16 +11,24 @@ export declare class ComponentGridComponent implements OnInit {
11
11
  readonly controls: import("@angular/core").Signal<import("@firestitch/grid").GridControls>;
12
12
  readonly source: import("@angular/core").Signal<ReportGridSource>;
13
13
  readonly layout: import("@angular/core").Signal<GridLayout>;
14
+ readonly clearedFilter: import("@angular/core").Signal<import("@firestitch/grid").GridClearedFilter>;
15
+ readonly expansion: import("@angular/core").WritableSignal<GridExpansion>;
14
16
  readonly noteData: import("@angular/core").Signal<import("../../interfaces/report-grid-report.interface").ReportGridReport>;
17
+ readonly formatContext: import("@angular/core").Signal<import("../../interfaces/report.interface").ReportFormatContext>;
15
18
  readonly formatter: import("@angular/core").Signal<import("@firestitch/grid").GridFormatter>;
16
19
  private readonly _componentId;
17
20
  private _reportData;
18
21
  private _filterState;
19
22
  private _destroyRef;
23
+ private _injector;
24
+ private _isPruned;
20
25
  private _paramsVersion;
21
26
  ngOnInit(): void;
22
27
  setLayout(layout: GridLayout): void;
28
+ setExpansion(expansion: GridExpansion | undefined): void;
23
29
  private _init;
30
+ private _pruneAfterFirstRead;
31
+ private _prune;
24
32
  private _settled$;
25
33
  private _applyParams;
26
34
  private _readParams;
@@ -0,0 +1,11 @@
1
+ import { PipeTransform } from '@angular/core';
2
+ import { GridField } from '@firestitch/grid';
3
+ import { FormattedOutputValue } from '../../format';
4
+ import { ReportGridReport } from '../../interfaces/report-grid-report.interface';
5
+ import { ReportFormatContext } from '../../interfaces/report.interface';
6
+ import * as i0 from "@angular/core";
7
+ export declare class ReportGridCellPipe implements PipeTransform {
8
+ transform(value: unknown, field: GridField | null, record: Record<string, unknown> | undefined, text: string, report: ReportGridReport | null, format: ReportFormatContext): FormattedOutputValue;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReportGridCellPipe, never>;
10
+ static ɵpipe: i0.ɵɵPipeDeclaration<ReportGridCellPipe, "fsReportGridCell", true>;
11
+ }
@@ -102,7 +102,6 @@ export declare class ReportComponentComponent implements OnInit, OnChanges {
102
102
  private _origin;
103
103
  private _track;
104
104
  private _emitGeometry;
105
- private get _isTimeSeries();
106
105
  private get _heightAuto();
107
106
  get heightAuto(): boolean;
108
107
  private _inches;
@@ -12,6 +12,7 @@ export declare class ReportGridSource implements GridSource {
12
12
  private readonly _reportId;
13
13
  private readonly _componentId;
14
14
  readonly report: import("@angular/core").WritableSignal<ReportGridReport>;
15
+ readonly summary: import("@angular/core").WritableSignal<GridResult>;
15
16
  private readonly _isExport;
16
17
  private readonly _locale;
17
18
  constructor(_reportData: ReportData, _reportId: number, _componentId: number, options?: ReportGridSourceOptions);
@@ -1,3 +1,4 @@
1
+ import { GridTable } from '@firestitch/grid';
1
2
  import { Observable } from 'rxjs';
2
3
  import { ReportExportLine } from '../interfaces/report-export-line.interface';
3
4
  import { ReportExportSnapshot } from '../interfaces/report-export-snapshot.interface';
@@ -12,6 +13,9 @@ export interface CollectedComponent {
12
13
  search?: string;
13
14
  hiddenColumns: string[];
14
15
  crumbs?: string[];
16
+ table?: GridTable;
17
+ tableNotes?: string[];
18
+ filtered?: boolean;
15
19
  }
16
20
  export interface CollectedPage {
17
21
  page: ReportPage;
@@ -67,7 +71,7 @@ export interface KpiExportParts {
67
71
  }
68
72
  export declare const HEADER_FOOTER_NAME = "Header & footer";
69
73
  export declare function emptyLabel(item: CollectedComponent): string;
70
- export declare function exportTitle(component: ReportComponent, tokens: TextTokenContext, search?: string | null, crumbs?: readonly string[] | null): string;
74
+ export declare function exportTitle(component: ReportComponent, tokens: TextTokenContext, search?: string | null, crumbs?: readonly string[] | null, filtered?: boolean): string;
71
75
  export declare function isFailed(item: CollectedComponent): boolean;
72
76
  export declare function textOverflow(component: ReportComponent, page: string, tokens: TextTokenContext): TextOverflow;
73
77
  export declare function coverLines(collected: CollectedReport): string[];
@@ -79,6 +83,7 @@ export declare function listHeadings(component: ReportComponent, data: Component
79
83
  export declare function listTotalsRow(data: ComponentData, columns: readonly ExportListColumn[], timezone: string, context: ReportFormatContext): string[] | null;
80
84
  export declare function exportWindowsLine(item: CollectedComponent, timezone: string, locale: ReportLocaleTag): string;
81
85
  export declare function exportNoteLines(item: CollectedComponent, timezone: string, locale: ReportLocaleTag): string[];
86
+ export declare function isEmptyTile(item: CollectedComponent): boolean;
82
87
  export declare function kpiCardHasExtras(view: KpiCardView, notes: readonly string[]): boolean;
83
88
  export declare function kpiExportParts(view: KpiCardView, notes: readonly string[], available: number, heights: KpiExportHeights): KpiExportParts;
84
89
  export declare function scaledKpiHeights(heights: KpiExportHeights, scale: number): KpiExportHeights;
@@ -99,6 +104,8 @@ export declare class ReportExportCollectorService {
99
104
  private _valuesJobs;
100
105
  private _runJob;
101
106
  private _componentData;
107
+ private _tileState;
108
+ private _gridTable;
102
109
  private _collected;
103
110
  private _groupValues;
104
111
  private _pageValues;
@@ -1,3 +1,4 @@
1
+ import { GridField, GridFilter } from '@firestitch/grid';
1
2
  import { Observable } from 'rxjs';
2
3
  import { ReportDrillStep } from '../interfaces/report-drill-step.interface';
3
4
  import { ReportExportLine } from '../interfaces/report-export-line.interface';
@@ -17,3 +18,4 @@ export declare function matchLineText(match: ReportFilterMatch | null | undefine
17
18
  export declare function drillLineText(component: Pick<ReportComponent, 'title'>, path: readonly ReportDrillStep[], formatContext: Pick<ReportFormatContext, 'locale'>): string;
18
19
  export declare function exportLines(input: ReportExportLinesInput): Observable<ReportExportLine[]>;
19
20
  export declare function exportGroups(report: Report, pageId: number | null): ReportFilterGroup[];
21
+ export declare function gridFilterLineText(label: string, filter: GridFilter, field: GridField | undefined, locale: ReportFormatContext['locale']): string | null;
@@ -0,0 +1,20 @@
1
+ import { GridLayout, GridTable } from '@firestitch/grid';
2
+ import { ReportFormatContext } from '../interfaces/report.interface';
3
+ export declare const GRID_EXPORT_COLUMNS = 60;
4
+ export interface GridExportCell {
5
+ text: string;
6
+ colSpan: number;
7
+ rowSpan: number;
8
+ bold: boolean;
9
+ indent: number;
10
+ numeric: boolean;
11
+ }
12
+ export interface GridExportTable {
13
+ head: GridExportCell[][];
14
+ body: GridExportCell[][];
15
+ foot: GridExportCell[] | null;
16
+ numeric: boolean[];
17
+ moreRows: number;
18
+ }
19
+ export declare function gridExportTable(table: GridTable): GridExportTable;
20
+ export declare function gridExportNotes(table: GridTable, layout: GridLayout, locale: ReportFormatContext['locale']): string[];
@@ -33,6 +33,8 @@ export declare class ReportPdfService {
33
33
  private _componentTitle;
34
34
  private _boxNote;
35
35
  private _renderTable;
36
+ private _listCells;
37
+ private _gridCells;
36
38
  private _tableCells;
37
39
  private _tableOptions;
38
40
  private _noticeRow;
@@ -47,6 +47,7 @@ export declare class ReportPptxService {
47
47
  private _categoryTitleOptions;
48
48
  private _valueAxisRangeOptions;
49
49
  private _renderTable;
50
+ private _renderGridTable;
50
51
  private _renderKpi;
51
52
  private _kpiDelta;
52
53
  private _estimatedWidth;
@@ -0,0 +1,3 @@
1
+ import { ReportComponent } from './interfaces/report.interface';
2
+ export declare function isTimeSeriesChart(component: ReportComponent): boolean;
3
+ export declare function followsGroupBy(component: ReportComponent): boolean;
@@ -1,4 +1,4 @@
1
- export interface ReportChatViewerDetail {
1
+ export interface ReportChatViewerShowRows {
2
2
  componentId: number;
3
3
  label: string;
4
4
  }
@@ -1,5 +1,5 @@
1
1
  import { ReportChatViewerCrossFilter } from './report-chat-viewer-cross-filter.interface';
2
- import { ReportChatViewerDetail } from './report-chat-viewer-detail.interface';
2
+ import { ReportChatViewerShowRows } from './report-chat-viewer-show-rows.interface';
3
3
  import { ReportChatViewerDrill } from './report-chat-viewer-drill.interface';
4
4
  import { ReportChatViewerFilter } from './report-chat-viewer-filter.interface';
5
5
  import { ReportChatViewerSelection } from './report-chat-viewer-selection.interface';
@@ -13,7 +13,7 @@ export interface ReportChatViewerState {
13
13
  match?: ReportFilterMatch;
14
14
  crossFilters?: ReportChatViewerCrossFilter[];
15
15
  drills?: ReportChatViewerDrill[];
16
- detail?: ReportChatViewerDetail | null;
16
+ showRows?: ReportChatViewerShowRows | null;
17
17
  tiles?: ReportChatViewerTile[];
18
18
  selection?: ReportChatViewerSelection;
19
19
  }
@@ -1,3 +1,4 @@
1
+ import { GridExpansion } from '@firestitch/grid';
1
2
  import { ReportStateSnapshot } from './report-state-snapshot.interface';
2
3
  import { ReportViewerFeature } from './report-viewer-feature.type';
3
4
  import { ChartGranularity, ComponentDataState, FilterGroupValue, ReportFormatContext, ReportRelativeRange, ResolvedFilterValue } from './report.interface';
@@ -8,6 +9,7 @@ export interface ReportExportSnapshot {
8
9
  filters: Record<number, ResolvedFilterValue[]>;
9
10
  valueFilters: Record<number, ResolvedFilterValue[]>;
10
11
  states: Record<number, ComponentDataState>;
12
+ gridExpansions?: Record<number, GridExpansion>;
11
13
  frequency: ChartGranularity | null;
12
14
  features: ReportViewerFeature[];
13
15
  formatContext: ReportFormatContext;
@@ -1 +1 @@
1
- export type ReportMarkAction = 'drill' | 'crossFilter' | 'detail';
1
+ export type ReportMarkAction = 'drill' | 'crossFilter' | 'showRows';
@@ -1,4 +1,4 @@
1
1
  export interface ReportTemporaryState {
2
2
  crossFilters: unknown[];
3
- detail: unknown;
3
+ showRows: unknown;
4
4
  }
@@ -1 +1 @@
1
- export type ReportViewerFeature = 'excludeValues' | 'numberRange' | 'matchAny' | 'pageScope' | 'cascadingOptions' | 'scopeFilters' | 'drill' | 'crossFilter' | 'detail';
1
+ export type ReportViewerFeature = 'excludeValues' | 'numberRange' | 'matchAny' | 'pageScope' | 'cascadingOptions' | 'scopeFilters' | 'drill' | 'crossFilter' | 'showRows' | 'grid';
@@ -1,3 +1,4 @@
1
+ import { GridLayout } from '@firestitch/grid';
1
2
  import { ReportChangePolarity } from '../enums/report-change-polarity.enum';
2
3
  import { ReportChartColor } from '../enums/report-chart-color.enum';
3
4
  import { ReportChartDataLabels } from '../enums/report-chart-data-labels.enum';
@@ -98,6 +99,11 @@ export interface ReportComponent {
98
99
  sql: string | null;
99
100
  config: ChartConfig & ListConfig & GridConfig & KpiConfig & TextConfig & ValueConfig & ComponentLayoutConfig & Record<string, unknown>;
100
101
  filters: ReportFilter[];
102
+ followsGroupBy?: ReportGroupByField | null;
103
+ }
104
+ export interface ReportGroupByField {
105
+ field: string;
106
+ granularity: ChartGranularity | null;
101
107
  }
102
108
  export interface ReportComponentSql {
103
109
  sql: string | null;
@@ -324,6 +330,7 @@ export interface ComponentDataState {
324
330
  hiddenColumns?: string[];
325
331
  drill?: ReportDrillStep[];
326
332
  matchAnyGroupIds?: number[];
333
+ layout?: GridLayout;
327
334
  unchangedIfUnreached?: true;
328
335
  }
329
336
  export interface ComponentData {
@@ -39,7 +39,7 @@ export declare function matchFromQuery(query: Record<string, unknown>): ReportFi
39
39
  export declare const LIST_SEARCH_ITEM = "listSearch";
40
40
  export declare const LIST_SEARCH_MAX_LENGTH = 100;
41
41
  export declare function listSearchItem(value: string | null): IFilterConfigItem;
42
- export declare function hasTimeSeriesChart(report: Report | null): boolean;
42
+ export declare function hasGroupByTile(report: Report | null): boolean;
43
43
  export declare function isGranularityOffered(report: Report, granularity: ChartGranularity | null): boolean;
44
44
  export declare function groupByFilterItem(report: Report, initial?: ChartGranularity | null): IFilterConfigItem | null;
45
45
  export declare function groupBySignature(report: Report | null): string;
@@ -1,4 +1,11 @@
1
- import { GridLayout } from '@firestitch/grid';
2
- import { ReportComponent } from './interfaces/report.interface';
1
+ import { GridClearedFilter, GridControlState, GridFilter, GridGranularity, GridLayout, GridNote } from '@firestitch/grid';
2
+ import { ChartGranularity, ReportComponent } from './interfaces/report.interface';
3
+ export declare const GRID_GRANULARITIES: Record<ChartGranularity, GridGranularity>;
3
4
  export declare function authoredGridLayout(component: ReportComponent): GridLayout;
4
5
  export declare function gridLayoutKey(layout: GridLayout): string;
6
+ export declare function rebasedGridLayout(session: GridLayout, base: string, authored: GridLayout): GridLayout;
7
+ export declare function grainedGridLayout(layout: GridLayout, field: string, granularity: ChartGranularity): {
8
+ layout: GridLayout;
9
+ cleared: GridClearedFilter | null;
10
+ };
11
+ export declare function prunedGridLayout(layout: GridLayout, notes: readonly GridNote[], filter?: GridControlState, authored?: readonly GridFilter[]): GridLayout;
@@ -1,4 +1,4 @@
1
- import { GridLayout } from '@firestitch/grid';
1
+ import { GridClearedFilter, GridExpansion, GridLayout } from '@firestitch/grid';
2
2
  import { Observable } from 'rxjs';
3
3
  import { ReportChatViewerFilter } from '../interfaces/report-chat-viewer-filter.interface';
4
4
  import { ReportDrillStep } from '../interfaces/report-drill-step.interface';
@@ -51,6 +51,8 @@ export declare class ReportFilterStateService {
51
51
  private _drills;
52
52
  private _drillChanged$;
53
53
  private _gridLayouts;
54
+ private _gridExpansions;
55
+ private _gridClearedFilters;
54
56
  private _temporary;
55
57
  init(report: Report): void;
56
58
  value(groupId: number): FilterGroupValue | undefined;
@@ -87,6 +89,9 @@ export declare class ReportFilterStateService {
87
89
  gridLayout(component: ReportComponent): GridLayout;
88
90
  gridSessionLayout(component: ReportComponent): GridLayout | null;
89
91
  setGridLayout(component: ReportComponent, layout: GridLayout): void;
92
+ gridClearedFilter(component: ReportComponent): GridClearedFilter | null;
93
+ gridExpansion(component: ReportComponent): GridExpansion | undefined;
94
+ setGridExpansion(component: ReportComponent, expansion: GridExpansion | undefined): void;
90
95
  snapshot(): ReportStateSnapshot;
91
96
  authoredConfig(): ReportStateSnapshot;
92
97
  resetToDefaults(): void;
@@ -108,6 +113,8 @@ export declare class ReportFilterStateService {
108
113
  private _snapshotTiles;
109
114
  private _seedAuthored;
110
115
  private _clearTiles;
116
+ private _putGridLayout;
117
+ private _grainGridLayouts;
111
118
  private _setDrillPath;
112
119
  private _notifyReset;
113
120
  private _tiles;
@@ -1,7 +1,7 @@
1
+ import { GridLayout } from '@firestitch/grid';
1
2
  import { ReportStateSnapshot } from './interfaces/report-state-snapshot.interface';
2
3
  import { ComponentDataState, Report, ReportComponent } from './interfaces/report.interface';
3
- export declare function isTimeSeriesChart(component: ReportComponent): boolean;
4
4
  export declare function tileDataState(report: Report | null, component: ReportComponent, snapshot: ReportStateSnapshot): ComponentDataState;
5
- export declare function zipExportStates(report: Report, snapshot: ReportStateSnapshot, pageId?: number | null): Record<number, ComponentDataState>;
5
+ export declare function zipExportStates(report: Report, snapshot: ReportStateSnapshot, pageId?: number | null, gridLayout?: (component: ReportComponent) => GridLayout | null): Record<number, ComponentDataState>;
6
6
  export declare function valuesMatchAnyGroupIds(report: Report | null, layerId: number | null, snapshot: ReportStateSnapshot): number[];
7
7
  export declare function tilePageId(report: Report, component: ReportComponent, snapshot: ReportStateSnapshot): number | null;
@@ -1,12 +1,16 @@
1
- import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject, input, signal, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, Injector, computed, effect, inject, input, signal, untracked, } from '@angular/core';
2
2
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
- import { FsGridComponent } from '@firestitch/grid';
3
+ import { FsGridCellDirective, FsGridComponent } from '@firestitch/grid';
4
+ import { FsPopoverDirective } from '@firestitch/popover';
4
5
  import { filter, map, of, switchMap, tap, timer } from 'rxjs';
5
6
  import { ReportData } from '../../data/report.data';
6
7
  import { ReportGridSource } from '../../data/report-grid-source';
8
+ import { followsGroupBy } from '../../group-by';
9
+ import { authoredGridLayout, prunedGridLayout } from '../../report-grid-layout';
7
10
  import { ReportFilterStateService } from '../../services/report-filter-state.service';
8
11
  import { TILE_REFRESH_DEBOUNCE_MS } from '../../tile-loads';
9
12
  import { ComponentNoteComponent } from '../component-note/component-note.component';
13
+ import { ReportGridCellPipe } from './report-grid-cell.pipe';
10
14
  import { reportGridFormatter } from './report-grid-formatter';
11
15
  import * as i0 from "@angular/core";
12
16
  // A grid tile: fs-grid over the tile's rows, read through ReportGridSource.
@@ -18,12 +22,24 @@ import * as i0 from "@angular/core";
18
22
  // under an older state version is dropped.
19
23
  // - The layout on screen is the state service's (gridLayout): the viewer's
20
24
  // own while they changed it from the layout authored now, else the
21
- // authored one. It outlives a page switch, and the chat reads it.
25
+ // authored one. It outlives a page switch, and the chat reads it. So do
26
+ // the groups the viewer left open (gridExpansion), which a Clear leaves.
22
27
  // - A state version move (Clear filters, a saved filter) skips the wait; the
23
28
  // reset has put the authored layout back in the same tick, so it costs one
24
29
  // read.
30
+ // - A table that follows the report's group-by (followsGroupBy) sends its
31
+ // grain, and reads again at once when it changes. The state service has
32
+ // moved its filter on the group-by's field to the new grain by then, or
33
+ // taken it out (clearedFilter, which the status line names), so one read
34
+ // goes out and nothing paints unfiltered.
25
35
  // - fs-grid compares the layout and params by value: a cloned value never
26
36
  // reads again.
37
+ // - An output's detail cell is drawn by fsReportGridCell, so a change tells
38
+ // a missing prior from a zero one, as a list does; a click on it opens
39
+ // why, as no cell carries a native tooltip.
40
+ // - After the tile's first read, the viewer's layout loses the filters and
41
+ // sort terms that read refused (prunedGridLayout), so stale tile state
42
+ // (a field the AI took out of the query) does not linger.
27
43
  export class ComponentGridComponent {
28
44
  reportId = input.required();
29
45
  component = input.required();
@@ -33,7 +49,11 @@ export class ComponentGridComponent {
33
49
  locale: () => this._filterState.formatContext().locale,
34
50
  }));
35
51
  layout = computed(() => this._filterState.gridLayout(this.component()));
52
+ clearedFilter = computed(() => this._filterState.gridClearedFilter(this.component()));
53
+ // Read once: fs-grid owns the open groups from then on and writes them out.
54
+ expansion = signal(undefined);
36
55
  noteData = computed(() => this.source().report());
56
+ formatContext = computed(() => this._filterState.formatContext());
37
57
  formatter = computed(() => reportGridFormatter({
38
58
  format: this._filterState.formatContext(),
39
59
  timezone: this._filterState.timezone(),
@@ -43,20 +63,57 @@ export class ComponentGridComponent {
43
63
  _reportData = inject(ReportData);
44
64
  _filterState = inject(ReportFilterStateService);
45
65
  _destroyRef = inject(DestroyRef);
66
+ _injector = inject(Injector);
67
+ // Whether the first read's notes have pruned the viewer's layout.
68
+ _isPruned = false;
46
69
  // The state version the params on screen were read under.
47
70
  _paramsVersion = 0;
48
71
  ngOnInit() {
72
+ this.expansion.set(this._filterState.gridExpansion(this.component()));
49
73
  this._init();
74
+ this._pruneAfterFirstRead();
50
75
  }
51
76
  setLayout(layout) {
52
77
  this._filterState.setGridLayout(this.component(), layout);
53
78
  }
79
+ setExpansion(expansion) {
80
+ this._filterState.setGridExpansion(this.component(), expansion);
81
+ }
54
82
  _init() {
55
83
  this._paramsVersion = this._filterState.stateVersion();
56
84
  this.params.set(this._readParams());
57
85
  this._filterState.changesFor(this.component())
58
86
  .pipe(switchMap(() => this._settled$()), tap(() => this._applyParams()), takeUntilDestroyed(this._destroyRef))
59
87
  .subscribe();
88
+ if (followsGroupBy(this.component())) {
89
+ this._filterState.frequencyChanges()
90
+ .pipe(takeUntilDestroyed(this._destroyRef))
91
+ .subscribe(() => this._applyParams());
92
+ }
93
+ }
94
+ // Once the tile's first read is in, its notes prune the viewer's layout
95
+ // (prunedGridLayout). A tile showing its authored layout has nothing to
96
+ // prune.
97
+ _pruneAfterFirstRead() {
98
+ effect(() => {
99
+ const summary = this.source().summary();
100
+ if (!summary || this._isPruned) {
101
+ return;
102
+ }
103
+ this._isPruned = true;
104
+ untracked(() => this._prune(summary.notes ?? []));
105
+ }, { injector: this._injector, allowSignalWrites: true });
106
+ }
107
+ _prune(notes) {
108
+ const component = this.component();
109
+ const session = this._filterState.gridSessionLayout(component);
110
+ if (!session) {
111
+ return;
112
+ }
113
+ const pruned = prunedGridLayout(session, notes, this.controls().filter, authoredGridLayout(component).filters);
114
+ if (pruned !== session) {
115
+ this._filterState.setGridLayout(component, pruned);
116
+ }
60
117
  }
61
118
  // A change, once it has settled: at once when the state version moved,
62
119
  // else after the debounce; dropped when the version moves while it waits,
@@ -71,23 +128,28 @@ export class ComponentGridComponent {
71
128
  this._paramsVersion = this._filterState.stateVersion();
72
129
  this.params.set(this._readParams());
73
130
  }
74
- // The tile's report filters and 'any' groups as they stand.
131
+ // The tile's report filters, 'any' groups and group-by grain as they stand
132
+ // (tileState()).
75
133
  _readParams() {
76
134
  const component = this.component();
77
- const matchAnyGroupIds = this._filterState.tileState(component).matchAnyGroupIds;
135
+ const { matchAnyGroupIds, frequency } = this._filterState.tileState(component);
78
136
  return {
79
137
  filters: this._filterState.resolveForComponent(component),
80
138
  ...(matchAnyGroupIds?.length ? { matchAnyGroupIds } : {}),
139
+ ...(frequency ? { frequency } : {}),
81
140
  };
82
141
  }
83
142
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
84
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentGridComponent, isStandalone: true, selector: "app-report-component-grid", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: true, isRequired: true, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<!-- 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 [params]=\"params\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n </fs-grid>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}\n"], dependencies: [{ kind: "component", type: FsGridComponent, selector: "fs-grid", inputs: ["source", "layout", "controls", "params", "expansion", "panel", "editorOpen", "formatter", "clearedFilter"], outputs: ["layoutChange", "expansionChange", "panelChange", "editorOpenChange"] }, { kind: "component", type: ComponentNoteComponent, selector: "app-report-component-note", inputs: ["data", "windows", "windowDescriptions", "windowNotes"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
143
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentGridComponent, isStandalone: true, selector: "app-report-component-grid", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: true, isRequired: true, transformFunction: null }, component: { classPropertyName: "component", publicName: "component", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<!-- 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", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}.explained{cursor:pointer;text-decoration:underline dotted;text-underline-offset:2px}\n"], dependencies: [{ kind: "component", type: FsGridComponent, selector: "fs-grid", inputs: ["source", "layout", "controls", "params", "expansion", "panel", "editorOpen", "formatter", "clearedFilter"], outputs: ["layoutChange", "expansionChange", "panelChange", "editorOpenChange"] }, { kind: "directive", type: FsGridCellDirective, selector: "[fsGridCell]" }, { kind: "directive", type: FsPopoverDirective, selector: "[fsPopover]", inputs: ["text", "template", "data", "leaveDelay", "showDelay", "maxWidth", "maxHeight", "wrapperClass", "autoShow", "autoClose", "loadingDiameter", "loading", "indication", "position", "theme", "size", "trigger", "enabled", "panel"], outputs: ["closed"], exportAs: ["fsPopover"] }, { kind: "component", type: ComponentNoteComponent, selector: "app-report-component-note", inputs: ["data", "windows", "windowDescriptions", "windowNotes"] }, { kind: "pipe", type: ReportGridCellPipe, name: "fsReportGridCell" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
85
144
  }
86
145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentGridComponent, decorators: [{
87
146
  type: Component,
88
147
  args: [{ selector: 'app-report-component-grid', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
89
148
  FsGridComponent,
149
+ FsGridCellDirective,
150
+ FsPopoverDirective,
90
151
  ComponentNoteComponent,
91
- ], template: "<!-- 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 [params]=\"params\"\n [controls]=\"controls()\"\n [formatter]=\"formatter()\"\n (layoutChange)=\"setLayout($event)\">\n </fs-grid>\n }\n</div>\n", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}\n"] }]
152
+ ReportGridCellPipe,
153
+ ], template: "<!-- 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", styles: [":host{display:block;height:100%}.grid-pane{height:100%;min-height:0}fs-grid{min-height:0}.explained{cursor:pointer;text-decoration:underline dotted;text-underline-offset:2px}\n"] }]
92
154
  }] });
93
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUN4RixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sa0JBQWtCLENBQUM7QUFFL0QsT0FBTyxFQUFjLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUdqRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUN0RixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVwRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7QUFHOUQsNEVBQTRFO0FBQzVFLEVBQUU7QUFDRixzRUFBc0U7QUFDdEUsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3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QixvV0M5Q25DLGt4QkFzQkEscUpEb0JJLGVBQWUsMlBBQ2Ysc0JBQXNCOzs0RkFHYixzQkFBc0I7a0JBWGxDLFNBQVM7K0JBQ0UsMkJBQTJCLG1CQUdwQix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxlQUFlO3dCQUNmLHNCQUFzQjtxQkFDdkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBPbkluaXQsIGNvbXB1dGVkLCBpbmplY3QsIGlucHV0LCBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBGc0dyaWRDb21wb25lbnQsIEdyaWRMYXlvdXQgfSBmcm9tICdAZmlyZXN0aXRjaC9ncmlkJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZmlsdGVyLCBtYXAsIG9mLCBzd2l0Y2hNYXAsIHRhcCwgdGltZXIgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZFNvdXJjZSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LWdyaWQtc291cmNlJztcbmltcG9ydCB7IFJlcG9ydEdyaWRQYXJhbXMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC1ncmlkLXBhcmFtcy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMgfSBmcm9tICcuLi8uLi90aWxlLWxvYWRzJztcbmltcG9ydCB7IENvbXBvbmVudE5vdGVDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtbm90ZS9jb21wb25lbnQtbm90ZS5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyByZXBvcnRHcmlkRm9ybWF0dGVyIH0gZnJvbSAnLi9yZXBvcnQtZ3JpZC1mb3JtYXR0ZXInO1xuXG5cbi8vIEEgZ3JpZCB0aWxlOiBmcy1ncmlkIG92ZXIgdGhlIHRpbGUncyByb3dzLCByZWFkIHRocm91Z2ggUmVwb3J0R3JpZFNvdXJjZS5cbi8vXG4vLyAtIFRoZSBwYXJhbXMgKHRoZSByZXBvcnQgZmlsdGVycyB0aGUgdGlsZSByZXNvbHZlcyB0byBhbmQgdGhlICdhbnknXG4vLyAgIGdyb3VwcykgYXJlIHNlZWRlZCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciwgc28gbm8gcmVhZCBnb2VzIG91dCB3aXRob3V0XG4vLyAgIHRoZW0uIEFmdGVyIHRoYXQgYSBjaGFuZ2UgdG8gb25lIG9mIHRoZSB0aWxlJ3MgZmlsdGVyIGdyb3VwcyBzZXR0bGVzIGZvclxuLy8gICBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMsIHNvIGEgc3dlZXAgb2YgY2hhbmdlcyBjb3N0cyBvbmUgcmVhZDsgb25lIHNlbnRcbi8vICAgdW5kZXIgYW4gb2xkZXIgc3RhdGUgdmVyc2lvbiBpcyBkcm9wcGVkLlxuLy8gLSBUaGUgbGF5b3V0IG9uIHNjcmVlbiBpcyB0aGUgc3RhdGUgc2VydmljZSdzIChncmlkTGF5b3V0KTogdGhlIHZpZXdlcidzXG4vLyAgIG93biB3aGlsZSB0aGV5IGNoYW5nZWQgaXQgZnJvbSB0aGUgbGF5b3V0IGF1dGhvcmVkIG5vdywgZWxzZSB0aGVcbi8vICAgYXV0aG9yZWQgb25lLiBJdCBvdXRsaXZlcyBhIHBhZ2Ugc3dpdGNoLCBhbmQgdGhlIGNoYXQgcmVhZHMgaXQuXG4vLyAtIEEgc3RhdGUgdmVyc2lvbiBtb3ZlIChDbGVhciBmaWx0ZXJzLCBhIHNhdmVkIGZpbHRlcikgc2tpcHMgdGhlIHdhaXQ7IHRoZVxuLy8gICByZXNldCBoYXMgcHV0IHRoZSBhdXRob3JlZCBsYXlvdXQgYmFjayBpbiB0aGUgc2FtZSB0aWNrLCBzbyBpdCBjb3N0cyBvbmVcbi8vICAgcmVhZC5cbi8vIC0gZnMtZ3JpZCBjb21wYXJlcyB0aGUgbGF5b3V0IGFuZCBwYXJhbXMgYnkgdmFsdWU6IGEgY2xvbmVkIHZhbHVlIG5ldmVyXG4vLyAgIHJlYWRzIGFnYWluLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXJlcG9ydC1jb21wb25lbnQtZ3JpZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jb21wb25lbnQtZ3JpZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRnNHcmlkQ29tcG9uZW50LFxuICAgIENvbXBvbmVudE5vdGVDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudEdyaWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnRJZCA9IGlucHV0LnJlcXVpcmVkPG51bWJlcj4oKTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbXBvbmVudCA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudD4oKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgcGFyYW1zID0gc2lnbmFsPFJlcG9ydEdyaWRQYXJhbXMgfCBudWxsPihudWxsKTtcbiAgcHVibGljIHJlYWRvbmx5IGNvbnRyb2xzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wb25lbnQoKS5jb25maWc/LmNvbnRyb2xzID8/IHt9KTtcbiAgcHVibGljIHJlYWRvbmx5IHNvdXJjZSA9IGNvbXB1dGVkKCgpID0+IG5ldyBSZXBvcnRHcmlkU291cmNlKHRoaXMuX3JlcG9ydERhdGEsIHRoaXMucmVwb3J0SWQoKSwgdGhpcy5fY29tcG9uZW50SWQoKSwge1xuICAgIGxvY2FsZTogKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuZm9ybWF0Q29udGV4dCgpLmxvY2FsZSxcbiAgfSkpO1xuXG4gIHB1YmxpYyByZWFkb25seSBsYXlvdXQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5ncmlkTGF5b3V0KHRoaXMuY29tcG9uZW50KCkpKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbm90ZURhdGEgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnNvdXJjZSgpLnJlcG9ydCgpKTtcbiAgcHVibGljIHJlYWRvbmx5IGZvcm1hdHRlciA9IGNvbXB1dGVkKCgpID0+IHJlcG9ydEdyaWRGb3JtYXR0ZXIoe1xuICAgIGZvcm1hdDogdGhpcy5fZmlsdGVyU3RhdGUuZm9ybWF0Q29udGV4dCgpLFxuICAgIHRpbWV6b25lOiB0aGlzLl9maWx0ZXJTdGF0ZS50aW1lem9uZSgpLFxuICAgIHJlcG9ydDogdGhpcy5zb3VyY2UoKS5yZXBvcnQoKSxcbiAgfSkpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2NvbXBvbmVudElkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wb25lbnQoKS5pZCk7XG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIC8vIFRoZSBzdGF0ZSB2ZXJzaW9uIHRoZSBwYXJhbXMgb24gc2NyZWVuIHdlcmUgcmVhZCB1bmRlci5cbiAgcHJpdmF0ZSBfcGFyYW1zVmVyc2lvbiA9IDA7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX2luaXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXlvdXQobGF5b3V0OiBHcmlkTGF5b3V0KTogdm9pZCB7XG4gICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0R3JpZExheW91dCh0aGlzLmNvbXBvbmVudCgpLCBsYXlvdXQpO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9wYXJhbXNWZXJzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCk7XG4gICAgdGhpcy5wYXJhbXMuc2V0KHRoaXMuX3JlYWRQYXJhbXMoKSk7XG5cbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jaGFuZ2VzRm9yKHRoaXMuY29tcG9uZW50KCkpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3NldHRsZWQkKCkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fYXBwbHlQYXJhbXMoKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIEEgY2hhbmdlLCBvbmNlIGl0IGhhcyBzZXR0bGVkOiBhdCBvbmNlIHdoZW4gdGhlIHN0YXRlIHZlcnNpb24gbW92ZWQsXG4gIC8vIGVsc2UgYWZ0ZXIgdGhlIGRlYm91bmNlOyBkcm9wcGVkIHdoZW4gdGhlIHZlcnNpb24gbW92ZXMgd2hpbGUgaXQgd2FpdHMsXG4gIC8vIHNpbmNlIHRoYXQgbW92ZSBicmluZ3MgaXRzIG93biBjaGFuZ2UuXG4gIHByaXZhdGUgX3NldHRsZWQkKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGNvbnN0IHZlcnNpb24gPSB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKTtcbiAgICBjb25zdCBtb3ZlZCA9IHZlcnNpb24gIT09IHRoaXMuX3BhcmFtc1ZlcnNpb247XG5cbiAgICByZXR1cm4gKG1vdmVkID8gb2YoMCkgOiB0aW1lcihUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKSA9PT0gdmVyc2lvbiksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwcGx5UGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMuX3BhcmFtc1ZlcnNpb24gPSB0aGlzLl9maWx0ZXJTdGF0ZS5zdGF0ZVZlcnNpb24oKTtcbiAgICB0aGlzLnBhcmFtcy5zZXQodGhpcy5fcmVhZFBhcmFtcygpKTtcbiAgfVxuXG4gIC8vIFRoZSB0aWxlJ3MgcmVwb3J0IGZpbHRlcnMgYW5kICdhbnknIGdyb3VwcyBhcyB0aGV5IHN0YW5kLlxuICBwcml2YXRlIF9yZWFkUGFyYW1zKCk6IFJlcG9ydEdyaWRQYXJhbXMge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50KCk7XG4gICAgY29uc3QgbWF0Y2hBbnlHcm91cElkcyA9IHRoaXMuX2ZpbHRlclN0YXRlLnRpbGVTdGF0ZShjb21wb25lbnQpLm1hdGNoQW55R3JvdXBJZHM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgZmlsdGVyczogdGhpcy5fZmlsdGVyU3RhdGUucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpLFxuICAgICAgLi4uKG1hdGNoQW55R3JvdXBJZHM/Lmxlbmd0aCA/IHsgbWF0Y2hBbnlHcm91cElkcyB9IDoge30pLFxuICAgIH07XG4gIH1cblxufVxuIiwiPCEtLSBUaGUgY29tcGFyaXNvbiBhbmQgd2luZG93IG5vdGUgc3RyaXAgYWJvdmUgdGhlIHRhYmxlLCBmcm9tIHRoZSByZXBvcnRcbiAgICAgbGluZSBvZiB0aGUgbGF0ZXN0IHJlYWQ7IHRoZSB3aW5kb3dzJyBkZXNjcmlwdGlvbnMgYW5kIG5vdGVzIGdvIGluIGVhY2hcbiAgICAgY29sdW1uJ3MgXCJBYm91dCB0aGlzIGNvbHVtblwiIGluc3RlYWQuIC0tPlxuPGRpdiBjbGFzcz1cImZzLWNvbHVtbiBncmlkLXBhbmVcIj5cbiAgPGFwcC1yZXBvcnQtY29tcG9uZW50LW5vdGVcbiAgICBbZGF0YV09XCJub3RlRGF0YSgpXCJcbiAgICBbd2luZG93Tm90ZXNdPVwiZmFsc2VcIj5cbiAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudC1ub3RlPlxuICA8IS0tIFRoZSBwYXJhbXMgYXJlIHNlZWRlZCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciwgc28gdGhlIGdyaWQncyBmaXJzdCByZWFkXG4gICAgICAgY2FycmllcyB0aGUgdGlsZSdzIHJlcG9ydCBmaWx0ZXJzLiAtLT5cbiAgQGlmIChwYXJhbXMoKTsgYXMgcGFyYW1zKSB7XG4gICAgPGZzLWdyaWRcbiAgICAgIGNsYXNzPVwiZnMtZmxleFwiXG4gICAgICBbc291cmNlXT1cInNvdXJjZSgpXCJcbiAgICAgIFtsYXlvdXRdPVwibGF5b3V0KClcIlxuICAgICAgW3BhcmFtc109XCJwYXJhbXNcIlxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzKClcIlxuICAgICAgW2Zvcm1hdHRlcl09XCJmb3JtYXR0ZXIoKVwiXG4gICAgICAobGF5b3V0Q2hhbmdlKT1cInNldExheW91dCgkZXZlbnQpXCI+XG4gICAgPC9mcy1ncmlkPlxuICB9XG48L2Rpdj5cbiJdfQ==
155
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvY29tcG9uZW50LWdyaWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFVLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxHQUNySCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsZUFBZSxFQUF1QyxNQUFNLGtCQUFrQixDQUFDO0FBQzdHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXpELE9BQU8sRUFBYyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUxRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR2hELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQ3RGLE9BQU8sRUFB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LEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFL0UsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FBQztZQUN6RCxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN6RCxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDcEMsQ0FBQztJQUNKLENBQUM7d0dBN0hVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLG9XQ2pFbkMsb3VEQTZDQSwwT0RhSSxlQUFlLDJQQUNmLG1CQUFtQix5REFDbkIsa0JBQWtCLGlWQUNsQixzQkFBc0IsbUlBQ3RCLGtCQUFrQjs7NEZBR1Qsc0JBQXNCO2tCQWRsQyxTQUFTOytCQUNFLDJCQUEyQixtQkFHcEIsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ1AsZUFBZTt3QkFDZixtQkFBbUI7d0JBQ25CLGtCQUFrQjt3QkFDbEIsc0JBQXNCO3dCQUN0QixrQkFBa0I7cUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgSW5qZWN0b3IsIE9uSW5pdCwgY29tcHV0ZWQsIGVmZmVjdCwgaW5qZWN0LCBpbnB1dCwgc2lnbmFsLCB1bnRyYWNrZWQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBGc0dyaWRDZWxsRGlyZWN0aXZlLCBGc0dyaWRDb21wb25lbnQsIEdyaWRFeHBhbnNpb24sIEdyaWRMYXlvdXQsIEdyaWROb3RlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZ3JpZCc7XG5pbXBvcnQgeyBGc1BvcG92ZXJEaXJlY3RpdmUgfSBmcm9tICdAZmlyZXN0aXRjaC9wb3BvdmVyJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgZmlsdGVyLCBtYXAsIG9mLCBzd2l0Y2hNYXAsIHRhcCwgdGltZXIgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZFNvdXJjZSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LWdyaWQtc291cmNlJztcbmltcG9ydCB7IGZvbGxvd3NHcm91cEJ5IH0gZnJvbSAnLi4vLi4vZ3JvdXAtYnknO1xuaW1wb3J0IHsgUmVwb3J0R3JpZFBhcmFtcyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LWdyaWQtcGFyYW1zLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgYXV0aG9yZWRHcmlkTGF5b3V0LCBwcnVuZWRHcmlkTGF5b3V0IH0gZnJvbSAnLi4vLi4vcmVwb3J0LWdyaWQtbGF5b3V0JztcbmltcG9ydCB7IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMgfSBmcm9tICcuLi8uLi90aWxlLWxvYWRzJztcbmltcG9ydCB7IENvbXBvbmVudE5vdGVDb21wb25lbnQgfSBmcm9tICcuLi9jb21wb25lbnQtbm90ZS9jb21wb25lbnQtbm90ZS5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBSZXBvcnRHcmlkQ2VsbFBpcGUgfSBmcm9tICcuL3JlcG9ydC1ncmlkLWNlbGwucGlwZSc7XG5pbXBvcnQgeyByZXBvcnRHcmlkRm9ybWF0dGVyIH0gZnJvbSAnLi9yZXBvcnQtZ3JpZC1mb3JtYXR0ZXInO1xuXG5cbi8vIEEgZ3JpZCB0aWxlOiBmcy1ncmlkIG92ZXIgdGhlIHRpbGUncyByb3dzLCByZWFkIHRocm91Z2ggUmVwb3J0R3JpZFNvdXJjZS5cbi8vXG4vLyAtIFRoZSBwYXJhbXMgKHRoZSByZXBvcnQgZmlsdGVycyB0aGUgdGlsZSByZXNvbHZlcyB0byBhbmQgdGhlICdhbnknXG4vLyAgIGdyb3VwcykgYXJlIHNlZWRlZCBiZWZvcmUgdGhlIGZpcnN0IHJlbmRlciwgc28gbm8gcmVhZCBnb2VzIG91dCB3aXRob3V0XG4vLyAgIHRoZW0uIEFmdGVyIHRoYXQgYSBjaGFuZ2UgdG8gb25lIG9mIHRoZSB0aWxlJ3MgZmlsdGVyIGdyb3VwcyBzZXR0bGVzIGZvclxuLy8gICBUSUxFX1JFRlJFU0hfREVCT1VOQ0VfTVMsIHNvIGEgc3dlZXAgb2YgY2hhbmdlcyBjb3N0cyBvbmUgcmVhZDsgb25lIHNlbnRcbi8vICAgdW5kZXIgYW4gb2xkZXIgc3RhdGUgdmVyc2lvbiBpcyBkcm9wcGVkLlxuLy8gLSBUaGUgbGF5b3V0IG9uIHNjcmVlbiBpcyB0aGUgc3RhdGUgc2VydmljZSdzIChncmlkTGF5b3V0KTogdGhlIHZpZXdlcidzXG4vLyAgIG93biB3aGlsZSB0aGV5IGNoYW5nZWQgaXQgZnJvbSB0aGUgbGF5b3V0IGF1dGhvcmVkIG5vdywgZWxzZSB0aGVcbi8vICAgYXV0aG9yZWQgb25lLiBJdCBvdXRsaXZlcyBhIHBhZ2Ugc3dpdGNoLCBhbmQgdGhlIGNoYXQgcmVhZHMgaXQuIFNvIGRvXG4vLyAgIHRoZSBncm91cHMgdGhlIHZpZXdlciBsZWZ0IG9wZW4gKGdyaWRFeHBhbnNpb24pLCB3aGljaCBhIENsZWFyIGxlYXZlcy5cbi8vIC0gQSBzdGF0ZSB2ZXJzaW9uIG1vdmUgKENsZWFyIGZpbHRlcnMsIGEgc2F2ZWQgZmlsdGVyKSBza2lwcyB0aGUgd2FpdDsgdGhlXG4vLyAgIHJlc2V0IGhhcyBwdXQgdGhlIGF1dGhvcmVkIGxheW91dCBiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIGl0IGNvc3RzIG9uZVxuLy8gICByZWFkLlxuLy8gLSBBIHRhYmxlIHRoYXQgZm9sbG93cyB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgKGZvbGxvd3NHcm91cEJ5KSBzZW5kcyBpdHNcbi8vICAgZ3JhaW4sIGFuZCByZWFkcyBhZ2FpbiBhdCBvbmNlIHdoZW4gaXQgY2hhbmdlcy4gVGhlIHN0YXRlIHNlcnZpY2UgaGFzXG4vLyAgIG1vdmVkIGl0cyBmaWx0ZXIgb24gdGhlIGdyb3VwLWJ5J3MgZmllbGQgdG8gdGhlIG5ldyBncmFpbiBieSB0aGVuLCBvclxuLy8gICB0YWtlbiBpdCBvdXQgKGNsZWFyZWRGaWx0ZXIsIHdoaWNoIHRoZSBzdGF0dXMgbGluZSBuYW1lcyksIHNvIG9uZSByZWFkXG4vLyAgIGdvZXMgb3V0IGFuZCBub3RoaW5nIHBhaW50cyB1bmZpbHRlcmVkLlxuLy8gLSBmcy1ncmlkIGNvbXBhcmVzIHRoZSBsYXlvdXQgYW5kIHBhcmFtcyBieSB2YWx1ZTogYSBjbG9uZWQgdmFsdWUgbmV2ZXJcbi8vICAgcmVhZHMgYWdhaW4uXG4vLyAtIEFuIG91dHB1dCdzIGRldGFpbCBjZWxsIGlzIGRyYXduIGJ5IGZzUmVwb3J0R3JpZENlbGwsIHNvIGEgY2hhbmdlIHRlbGxzXG4vLyAgIGEgbWlzc2luZyBwcmlvciBmcm9tIGEgemVybyBvbmUsIGFzIGEgbGlzdCBkb2VzOyBhIGNsaWNrIG9uIGl0IG9wZW5zXG4vLyAgIHdoeSwgYXMgbm8gY2VsbCBjYXJyaWVzIGEgbmF0aXZlIHRvb2x0aXAuXG4vLyAtIEFmdGVyIHRoZSB0aWxlJ3MgZmlyc3QgcmVhZCwgdGhlIHZpZXdlcidzIGxheW91dCBsb3NlcyB0aGUgZmlsdGVycyBhbmRcbi8vICAgc29ydCB0ZXJtcyB0aGF0IHJlYWQgcmVmdXNlZCAocHJ1bmVkR3JpZExheW91dCksIHNvIHN0YWxlIHRpbGUgc3RhdGVcbi8vICAgKGEgZmllbGQgdGhlIEFJIHRvb2sgb3V0IG9mIHRoZSBxdWVyeSkgZG9lcyBub3QgbGluZ2VyLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXJlcG9ydC1jb21wb25lbnQtZ3JpZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jb21wb25lbnQtZ3JpZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1ncmlkLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRnNHcmlkQ29tcG9uZW50LFxuICAgIEZzR3JpZENlbGxEaXJlY3RpdmUsXG4gICAgRnNQb3BvdmVyRGlyZWN0aXZlLFxuICAgIENvbXBvbmVudE5vdGVDb21wb25lbnQsXG4gICAgUmVwb3J0R3JpZENlbGxQaXBlLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBDb21wb25lbnRHcmlkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwdWJsaWMgcmVhZG9ubHkgcmVwb3J0SWQgPSBpbnB1dC5yZXF1aXJlZDxudW1iZXI+KCk7XG4gIHB1YmxpYyByZWFkb25seSBjb21wb25lbnQgPSBpbnB1dC5yZXF1aXJlZDxSZXBvcnRDb21wb25lbnQ+KCk7XG5cbiAgcHVibGljIHJlYWRvbmx5IHBhcmFtcyA9IHNpZ25hbDxSZXBvcnRHcmlkUGFyYW1zIHwgbnVsbD4obnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSBjb250cm9scyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcG9uZW50KCkuY29uZmlnPy5jb250cm9scyA/PyB7fSk7XG4gIHB1YmxpYyByZWFkb25seSBzb3VyY2UgPSBjb21wdXRlZCgoKSA9PiBuZXcgUmVwb3J0R3JpZFNvdXJjZSh0aGlzLl9yZXBvcnREYXRhLCB0aGlzLnJlcG9ydElkKCksIHRoaXMuX2NvbXBvbmVudElkKCksIHtcbiAgICBsb2NhbGU6ICgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLmZvcm1hdENvbnRleHQoKS5sb2NhbGUsXG4gIH0pKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbGF5b3V0ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuZ3JpZExheW91dCh0aGlzLmNvbXBvbmVudCgpKSk7XG4gIHB1YmxpYyByZWFkb25seSBjbGVhcmVkRmlsdGVyID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuZ3JpZENsZWFyZWRGaWx0ZXIodGhpcy5jb21wb25lbnQoKSkpO1xuICAvLyBSZWFkIG9uY2U6IGZzLWdyaWQgb3ducyB0aGUgb3BlbiBncm91cHMgZnJvbSB0aGVuIG9uIGFuZCB3cml0ZXMgdGhlbSBvdXQuXG4gIHB1YmxpYyByZWFkb25seSBleHBhbnNpb24gPSBzaWduYWw8R3JpZEV4cGFuc2lvbiB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbm90ZURhdGEgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnNvdXJjZSgpLnJlcG9ydCgpKTtcbiAgcHVibGljIHJlYWRvbmx5IGZvcm1hdENvbnRleHQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5mb3JtYXRDb250ZXh0KCkpO1xuICBwdWJsaWMgcmVhZG9ubHkgZm9ybWF0dGVyID0gY29tcHV0ZWQoKCkgPT4gcmVwb3J0R3JpZEZvcm1hdHRlcih7XG4gICAgZm9ybWF0OiB0aGlzLl9maWx0ZXJTdGF0ZS5mb3JtYXRDb250ZXh0KCksXG4gICAgdGltZXpvbmU6IHRoaXMuX2ZpbHRlclN0YXRlLnRpbWV6b25lKCksXG4gICAgcmVwb3J0OiB0aGlzLnNvdXJjZSgpLnJlcG9ydCgpLFxuICB9KSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfY29tcG9uZW50SWQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbXBvbmVudCgpLmlkKTtcbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgcHJpdmF0ZSBfaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuICAvLyBXaGV0aGVyIHRoZSBmaXJzdCByZWFkJ3Mgbm90ZXMgaGF2ZSBwcnVuZWQgdGhlIHZpZXdlcidzIGxheW91dC5cbiAgcHJpdmF0ZSBfaXNQcnVuZWQgPSBmYWxzZTtcbiAgLy8gVGhlIHN0YXRlIHZlcnNpb24gdGhlIHBhcmFtcyBvbiBzY3JlZW4gd2VyZSByZWFkIHVuZGVyLlxuICBwcml2YXRlIF9wYXJhbXNWZXJzaW9uID0gMDtcblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5leHBhbnNpb24uc2V0KHRoaXMuX2ZpbHRlclN0YXRlLmdyaWRFeHBhbnNpb24odGhpcy5jb21wb25lbnQoKSkpO1xuICAgIHRoaXMuX2luaXQoKTtcbiAgICB0aGlzLl9wcnVuZUFmdGVyRmlyc3RSZWFkKCk7XG4gIH1cblxuICBwdWJsaWMgc2V0TGF5b3V0KGxheW91dDogR3JpZExheW91dCk6IHZvaWQge1xuICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldEdyaWRMYXlvdXQodGhpcy5jb21wb25lbnQoKSwgbGF5b3V0KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRFeHBhbnNpb24oZXhwYW5zaW9uOiBHcmlkRXhwYW5zaW9uIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0R3JpZEV4cGFuc2lvbih0aGlzLmNvbXBvbmVudCgpLCBleHBhbnNpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9wYXJhbXNWZXJzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCk7XG4gICAgdGhpcy5wYXJhbXMuc2V0KHRoaXMuX3JlYWRQYXJhbXMoKSk7XG5cbiAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jaGFuZ2VzRm9yKHRoaXMuY29tcG9uZW50KCkpXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3NldHRsZWQkKCkpLFxuICAgICAgICB0YXAoKCkgPT4gdGhpcy5fYXBwbHlQYXJhbXMoKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcblxuICAgIGlmIChmb2xsb3dzR3JvdXBCeSh0aGlzLmNvbXBvbmVudCgpKSkge1xuICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuZnJlcXVlbmN5Q2hhbmdlcygpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9hcHBseVBhcmFtcygpKTtcbiAgICB9XG4gIH1cblxuICAvLyBPbmNlIHRoZSB0aWxlJ3MgZmlyc3QgcmVhZCBpcyBpbiwgaXRzIG5vdGVzIHBydW5lIHRoZSB2aWV3ZXIncyBsYXlvdXRcbiAgLy8gKHBydW5lZEdyaWRMYXlvdXQpLiBBIHRpbGUgc2hvd2luZyBpdHMgYXV0aG9yZWQgbGF5b3V0IGhhcyBub3RoaW5nIHRvXG4gIC8vIHBydW5lLlxuICBwcml2YXRlIF9wcnVuZUFmdGVyRmlyc3RSZWFkKCk6IHZvaWQge1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBzdW1tYXJ5ID0gdGhpcy5zb3VyY2UoKS5zdW1tYXJ5KCk7XG4gICAgICBpZiAoIXN1bW1hcnkgfHwgdGhpcy5faXNQcnVuZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9pc1BydW5lZCA9IHRydWU7XG4gICAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5fcHJ1bmUoc3VtbWFyeS5ub3RlcyA/PyBbXSkpO1xuICAgIH0sIHsgaW5qZWN0b3I6IHRoaXMuX2luamVjdG9yLCBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3BydW5lKG5vdGVzOiBHcmlkTm90ZVtdKTogdm9pZCB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnQoKTtcbiAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuZ3JpZFNlc3Npb25MYXlvdXQoY29tcG9uZW50KTtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwcnVuZWQgPSBwcnVuZWRHcmlkTGF5b3V0KHNlc3Npb24sIG5vdGVzLCB0aGlzLmNvbnRyb2xzKCkuZmlsdGVyLCBhdXRob3JlZEdyaWRMYXlvdXQoY29tcG9uZW50KS5maWx0ZXJzKTtcbiAgICBpZiAocHJ1bmVkICE9PSBzZXNzaW9uKSB7XG4gICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRHcmlkTGF5b3V0KGNvbXBvbmVudCwgcHJ1bmVkKTtcbiAgICB9XG4gIH1cblxuICAvLyBBIGNoYW5nZSwgb25jZSBpdCBoYXMgc2V0dGxlZDogYXQgb25jZSB3aGVuIHRoZSBzdGF0ZSB2ZXJzaW9uIG1vdmVkLFxuICAvLyBlbHNlIGFmdGVyIHRoZSBkZWJvdW5jZTsgZHJvcHBlZCB3aGVuIHRoZSB2ZXJzaW9uIG1vdmVzIHdoaWxlIGl0IHdhaXRzLFxuICAvLyBzaW5jZSB0aGF0IG1vdmUgYnJpbmdzIGl0cyBvd24gY2hhbmdlLlxuICBwcml2YXRlIF9zZXR0bGVkJCgpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICBjb25zdCB2ZXJzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCk7XG4gICAgY29uc3QgbW92ZWQgPSB2ZXJzaW9uICE9PSB0aGlzLl9wYXJhbXNWZXJzaW9uO1xuXG4gICAgcmV0dXJuIChtb3ZlZCA/IG9mKDApIDogdGltZXIoVElMRV9SRUZSRVNIX0RFQk9VTkNFX01TKSlcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCkgPT09IHZlcnNpb24pLFxuICAgICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcbiAgICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9hcHBseVBhcmFtcygpOiB2b2lkIHtcbiAgICB0aGlzLl9wYXJhbXNWZXJzaW9uID0gdGhpcy5fZmlsdGVyU3RhdGUuc3RhdGVWZXJzaW9uKCk7XG4gICAgdGhpcy5wYXJhbXMuc2V0KHRoaXMuX3JlYWRQYXJhbXMoKSk7XG4gIH1cblxuICAvLyBUaGUgdGlsZSdzIHJlcG9ydCBmaWx0ZXJzLCAnYW55JyBncm91cHMgYW5kIGdyb3VwLWJ5IGdyYWluIGFzIHRoZXkgc3RhbmRcbiAgLy8gKHRpbGVTdGF0ZSgpKS5cbiAgcHJpdmF0ZSBfcmVhZFBhcmFtcygpOiBSZXBvcnRHcmlkUGFyYW1zIHtcbiAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudCgpO1xuICAgIGNvbnN0IHsgbWF0Y2hBbnlHcm91cElkcywgZnJlcXVlbmN5IH0gPSB0aGlzLl9maWx0ZXJTdGF0ZS50aWxlU3RhdGUoY29tcG9uZW50KTtcblxuICAgIHJldHVybiB7XG4gICAgICBmaWx0ZXJzOiB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KGNvbXBvbmVudCksXG4gICAgICAuLi4obWF0Y2hBbnlHcm91cElkcz8ubGVuZ3RoID8geyBtYXRjaEFueUdyb3VwSWRzIH0gOiB7fSksXG4gICAgICAuLi4oZnJlcXVlbmN5ID8geyBmcmVxdWVuY3kgfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbn1cbiIsIjwhLS0gVGhlIGNvbXBhcmlzb24gYW5kIHdpbmRvdyBub3RlIHN0cmlwIGFib3ZlIHRoZSB0YWJsZSwgZnJvbSB0aGUgcmVwb3J0XG4gICAgIGxpbmUgb2YgdGhlIGxhdGVzdCByZWFkOyB0aGUgd2luZG93cycgZGVzY3JpcHRpb25zIGFuZCBub3RlcyBnbyBpbiBlYWNoXG4gICAgIGNvbHVtbidzIFwiQWJvdXQgdGhpcyBjb2x1bW5cIiBpbnN0ZWFkLiAtLT5cbjxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gZ3JpZC1wYW5lXCI+XG4gIDxhcHAtcmVwb3J0LWNvbXBvbmVudC1ub3RlXG4gICAgW2RhdGFdPVwibm90ZURhdGEoKVwiXG4gICAgW3dpbmRvd05vdGVzXT1cImZhbHNlXCI+XG4gIDwvYXBwLXJlcG9ydC1jb21wb25lbnQtbm90ZT5cbiAgPCEtLSBUaGUgcGFyYW1zIGFyZSBzZWVkZWQgYmVmb3JlIHRoZSBmaXJzdCByZW5kZXIsIHNvIHRoZSBncmlkJ3MgZmlyc3QgcmVhZFxuICAgICAgIGNhcnJpZXMgdGhlIHRpbGUncyByZXBvcnQgZmlsdGVycy4gLS0+XG4gIEBpZiAocGFyYW1zKCk7IGFzIHBhcmFtcykge1xuICAgIDxmcy1ncmlkXG4gICAgICBjbGFzcz1cImZzLWZsZXhcIlxuICAgICAgW3NvdXJjZV09XCJzb3VyY2UoKVwiXG4gICAgICBbbGF5b3V0XT1cImxheW91dCgpXCJcbiAgICAgIFtleHBhbnNpb25dPVwiZXhwYW5zaW9uKClcIlxuICAgICAgW2NsZWFyZWRGaWx0ZXJdPVwiY2xlYXJlZEZpbHRlcigpXCJcbiAgICAgIChleHBhbnNpb25DaGFuZ2UpPVwic2V0RXhwYW5zaW9uKCRldmVudClcIlxuICAgICAgW3BhcmFtc109XCJwYXJhbXNcIlxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzKClcIlxuICAgICAgW2Zvcm1hdHRlcl09XCJmb3JtYXR0ZXIoKVwiXG4gICAgICAobGF5b3V0Q2hhbmdlKT1cInNldExheW91dCgkZXZlbnQpXCI+XG4gICAgICA8bmctdGVtcGxhdGUgZnNHcmlkQ2VsbCBsZXQtdmFsdWUgbGV0LWZpZWxkPVwiZmllbGRcIiBsZXQtcmVjb3JkPVwicmVjb3JkXCIgbGV0LXRleHQ9XCJ0ZXh0XCI+XG4gICAgICAgIEBpZiAodmFsdWUgfCBmc1JlcG9ydEdyaWRDZWxsOiBmaWVsZCA6IHJlY29yZCA6IHRleHQgOiBub3RlRGF0YSgpIDogZm9ybWF0Q29udGV4dCgpOyBhcyBzaG93bikge1xuICAgICAgICAgIDwhLS0gQSBjZWxsIHRoYXQgc2F5cyB3aHkgKGEgbWlzc2luZyBvciB6ZXJvIHByaW9yKSBvcGVucyBpdCBvbiBhXG4gICAgICAgICAgICAgICBjbGljazsgbm8gY2VsbCBjYXJyaWVzIGEgbmF0aXZlIHRvb2x0aXAuIC0tPlxuICAgICAgICAgIEBpZiAoc2hvd24udGl0bGUpIHtcbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJleHBsYWluZWRcIlxuICAgICAgICAgICAgICAgIGZzUG9wb3ZlclxuICAgICAgICAgICAgICAgIHRyaWdnZXI9XCJjbGlja1wiXG4gICAgICAgICAgICAgICAgW3RlbXBsYXRlXT1cImV4cGxhbmF0aW9uXCJcbiAgICAgICAgICAgICAgICBbaW5kaWNhdGlvbl09XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgW21heFdpZHRoXT1cIjMyMFwiPlxuICAgICAgICAgICAgICB7eyBzaG93bi50ZXh0IH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2V4cGxhbmF0aW9uPnt7IHNob3duLnRpdGxlIH19PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxzcGFuPnt7IHNob3duLnRleHQgfX08L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvZnMtZ3JpZD5cbiAgfVxuPC9kaXY+XG4iXX0=
@@ -0,0 +1,41 @@
1
+ import { Pipe } from '@angular/core';
2
+ import { formatOutputValue, laneOutputAlias } from '../../format';
3
+ import * as i0 from "@angular/core";
4
+ // A detail cell of an output field (a prior, a change, a % change, a rank)
5
+ // as a list writes it: a change reads its prior beside it on the line, so a
6
+ // missing baseline reads '—' and a zero one 'n/a', and the cell's title says
7
+ // why, as the list's hover does. A value it holds keeps the grid's own text
8
+ // (its placement's format); a rank change is written whole, since a new rank
9
+ // reads apart from an unranked line. Every other cell is the grid's text,
10
+ // with no title.
11
+ export class ReportGridCellPipe {
12
+ // The cell's raw value, its field, its line's record (absent on a group or
13
+ // total row) and the grid's own text, from the fsGridCell context.
14
+ transform(value, field, record, text, report, format) {
15
+ const name = field?.name ?? '';
16
+ const output = record ? report?.outputs?.[name] : null;
17
+ if (!output || !record) {
18
+ return { text, title: null };
19
+ }
20
+ const priorAlias = output.role === 'change' || output.role === 'percent_change'
21
+ ? laneOutputAlias(report?.outputs, name, 'prior')
22
+ : null;
23
+ const formatted = formatOutputValue(value, output, null, format, {
24
+ ...(priorAlias ? { prior: record[priorAlias] } : {}),
25
+ floor: report?.comparison?.floor ?? null,
26
+ empty: '',
27
+ });
28
+ const isMissing = value === null || value === undefined || value === '';
29
+ return { text: isMissing || output.kind === 'rank' ? formatted.text : text, title: formatted.title };
30
+ }
31
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportGridCellPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
32
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ReportGridCellPipe, isStandalone: true, name: "fsReportGridCell" });
33
+ }
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportGridCellPipe, decorators: [{
35
+ type: Pipe,
36
+ args: [{
37
+ name: 'fsReportGridCell',
38
+ standalone: true,
39
+ }]
40
+ }] });
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWdyaWQtY2VsbC5waXBlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvY29tcG9uZW50LWdyaWQvcmVwb3J0LWdyaWQtY2VsbC5waXBlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQWlCLE1BQU0sZUFBZSxDQUFDO0FBSXBELE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sY0FBYyxDQUFDOztBQUt4RiwyRUFBMkU7QUFDM0UsNEVBQTRFO0FBQzVFLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsNkVBQTZFO0FBQzdFLDBFQUEwRTtBQUMxRSxpQkFBaUI7QUFLakIsTUFBTSxPQUFPLGtCQUFrQjtJQUU3QiwyRUFBMkU7SUFDM0UsbUVBQW1FO0lBQzVELFNBQVMsQ0FDZCxLQUFjLEVBQ2QsS0FBdUIsRUFDdkIsTUFBMkMsRUFDM0MsSUFBWSxFQUNaLE1BQStCLEVBQy9CLE1BQTJCO1FBRTNCLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDO1FBQy9CLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDdkQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO1FBQy9CLENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGdCQUFnQjtZQUM3RSxDQUFDLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQztZQUNqRCxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ1QsTUFBTSxTQUFTLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO1lBQy9ELEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDcEQsS0FBSyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsS0FBSyxJQUFJLElBQUk7WUFDeEMsS0FBSyxFQUFFLEVBQUU7U0FDVixDQUFDLENBQUM7UUFDSCxNQUFNLFNBQVMsR0FBRyxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztRQUV4RSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdkcsQ0FBQzt3R0E3QlUsa0JBQWtCO3NHQUFsQixrQkFBa0I7OzRGQUFsQixrQkFBa0I7a0JBSjlCLElBQUk7bUJBQUM7b0JBQ0osSUFBSSxFQUFFLGtCQUFrQjtvQkFDeEIsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBHcmlkRmllbGQgfSBmcm9tICdAZmlyZXN0aXRjaC9ncmlkJztcblxuaW1wb3J0IHsgRm9ybWF0dGVkT3V0cHV0VmFsdWUsIGZvcm1hdE91dHB1dFZhbHVlLCBsYW5lT3V0cHV0QWxpYXMgfSBmcm9tICcuLi8uLi9mb3JtYXQnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZFJlcG9ydCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LWdyaWQtcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGb3JtYXRDb250ZXh0IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcblxuXG4vLyBBIGRldGFpbCBjZWxsIG9mIGFuIG91dHB1dCBmaWVsZCAoYSBwcmlvciwgYSBjaGFuZ2UsIGEgJSBjaGFuZ2UsIGEgcmFuaylcbi8vIGFzIGEgbGlzdCB3cml0ZXMgaXQ6IGEgY2hhbmdlIHJlYWRzIGl0cyBwcmlvciBiZXNpZGUgaXQgb24gdGhlIGxpbmUsIHNvIGFcbi8vIG1pc3NpbmcgYmFzZWxpbmUgcmVhZHMgJ+KAlCcgYW5kIGEgemVybyBvbmUgJ24vYScsIGFuZCB0aGUgY2VsbCdzIHRpdGxlIHNheXNcbi8vIHdoeSwgYXMgdGhlIGxpc3QncyBob3ZlciBkb2VzLiBBIHZhbHVlIGl0IGhvbGRzIGtlZXBzIHRoZSBncmlkJ3Mgb3duIHRleHRcbi8vIChpdHMgcGxhY2VtZW50J3MgZm9ybWF0KTsgYSByYW5rIGNoYW5nZSBpcyB3cml0dGVuIHdob2xlLCBzaW5jZSBhIG5ldyByYW5rXG4vLyByZWFkcyBhcGFydCBmcm9tIGFuIHVucmFua2VkIGxpbmUuIEV2ZXJ5IG90aGVyIGNlbGwgaXMgdGhlIGdyaWQncyB0ZXh0LFxuLy8gd2l0aCBubyB0aXRsZS5cbkBQaXBlKHtcbiAgbmFtZTogJ2ZzUmVwb3J0R3JpZENlbGwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRHcmlkQ2VsbFBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblxuICAvLyBUaGUgY2VsbCdzIHJhdyB2YWx1ZSwgaXRzIGZpZWxkLCBpdHMgbGluZSdzIHJlY29yZCAoYWJzZW50IG9uIGEgZ3JvdXAgb3JcbiAgLy8gdG90YWwgcm93KSBhbmQgdGhlIGdyaWQncyBvd24gdGV4dCwgZnJvbSB0aGUgZnNHcmlkQ2VsbCBjb250ZXh0LlxuICBwdWJsaWMgdHJhbnNmb3JtKFxuICAgIHZhbHVlOiB1bmtub3duLFxuICAgIGZpZWxkOiBHcmlkRmllbGQgfCBudWxsLFxuICAgIHJlY29yZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQsXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIHJlcG9ydDogUmVwb3J0R3JpZFJlcG9ydCB8IG51bGwsXG4gICAgZm9ybWF0OiBSZXBvcnRGb3JtYXRDb250ZXh0LFxuICApOiBGb3JtYXR0ZWRPdXRwdXRWYWx1ZSB7XG4gICAgY29uc3QgbmFtZSA9IGZpZWxkPy5uYW1lID8/ICcnO1xuICAgIGNvbnN0IG91dHB1dCA9IHJlY29yZCA/IHJlcG9ydD8ub3V0cHV0cz8uW25hbWVdIDogbnVsbDtcbiAgICBpZiAoIW91dHB1dCB8fCAhcmVjb3JkKSB7XG4gICAgICByZXR1cm4geyB0ZXh0LCB0aXRsZTogbnVsbCB9O1xuICAgIH1cblxuICAgIGNvbnN0IHByaW9yQWxpYXMgPSBvdXRwdXQucm9sZSA9PT0gJ2NoYW5nZScgfHwgb3V0cHV0LnJvbGUgPT09ICdwZXJjZW50X2NoYW5nZSdcbiAgICAgID8gbGFuZU91dHB1dEFsaWFzKHJlcG9ydD8ub3V0cHV0cywgbmFtZSwgJ3ByaW9yJylcbiAgICAgIDogbnVsbDtcbiAgICBjb25zdCBmb3JtYXR0ZWQgPSBmb3JtYXRPdXRwdXRWYWx1ZSh2YWx1ZSwgb3V0cHV0LCBudWxsLCBmb3JtYXQsIHtcbiAgICAgIC4uLihwcmlvckFsaWFzID8geyBwcmlvcjogcmVjb3JkW3ByaW9yQWxpYXNdIH0gOiB7fSksXG4gICAgICBmbG9vcjogcmVwb3J0Py5jb21wYXJpc29uPy5mbG9vciA/PyBudWxsLFxuICAgICAgZW1wdHk6ICcnLFxuICAgIH0pO1xuICAgIGNvbnN0IGlzTWlzc2luZyA9IHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09ICcnO1xuXG4gICAgcmV0dXJuIHsgdGV4dDogaXNNaXNzaW5nIHx8IG91dHB1dC5raW5kID09PSAncmFuaycgPyBmb3JtYXR0ZWQudGV4dCA6IHRleHQsIHRpdGxlOiBmb3JtYXR0ZWQudGl0bGUgfTtcbiAgfVxuXG59XG4iXX0=