@firestitch/report 18.0.3 → 18.0.4

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.
@@ -169,6 +169,7 @@ export interface ComponentData {
169
169
  export interface ReportListItem {
170
170
  id: number;
171
171
  name: string;
172
+ modifyDate: string;
172
173
  }
173
174
  export interface ReportChatResponse {
174
175
  reportChanged?: boolean;
@@ -0,0 +1,43 @@
1
+ import { FilterConfig } from '@firestitch/filter';
2
+ import { FsAiChatResponse } from '@firestitch/ai';
3
+ import { Report, ReportComponent as ReportComponentModel } from '../../interfaces/report.interface';
4
+ import * as i0 from "@angular/core";
5
+ export declare class FsAiReportComponent {
6
+ readonly reportId: import("@angular/core").InputSignal<number>;
7
+ readonly basePath: import("@angular/core").InputSignal<string>;
8
+ readonly deleted: import("@angular/core").OutputEmitterRef<number>;
9
+ readonly renamed: import("@angular/core").OutputEmitterRef<Report>;
10
+ report: Report | null;
11
+ editMode: boolean;
12
+ reportFilterConfig: FilterConfig;
13
+ private _split;
14
+ private _chatPanel;
15
+ private _reportData;
16
+ private _filterState;
17
+ private _exportCollector;
18
+ private _pptxService;
19
+ private _pdfService;
20
+ private _process;
21
+ private _dialog;
22
+ private _destroyRef;
23
+ private _cdRef;
24
+ private _zone;
25
+ constructor();
26
+ toggleEditMode(): void;
27
+ reportSettings(): void;
28
+ componentSettings(component: ReportComponentModel): void;
29
+ onCanvasReportChanged(): void;
30
+ exportPowerpoint(): void;
31
+ exportPdf(): void;
32
+ onChatResponse(response: FsAiChatResponse): void;
33
+ onResizeStart(event: PointerEvent): void;
34
+ private _resizeTo;
35
+ private _loadReport;
36
+ private _reportGroups;
37
+ get reportHasFilters(): boolean;
38
+ get reportFilterKey(): string;
39
+ private _buildReportConfig;
40
+ private _hasTimeSeriesChart;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<FsAiReportComponent, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<FsAiReportComponent, "fs-ai-report", never, { "reportId": { "alias": "reportId"; "required": false; "isSignal": true; }; "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; }, { "deleted": "deleted"; "renamed": "renamed"; }, never, never, true, never>;
43
+ }
@@ -0,0 +1,23 @@
1
+ import { FsListComponent, FsListConfig } from '@firestitch/list';
2
+ import { ReportListItem } from '../../interfaces/report.interface';
3
+ import * as i0 from "@angular/core";
4
+ export declare class FsAiReportsComponent {
5
+ readonly basePath: import("@angular/core").InputSignal<string>;
6
+ readonly openPattern: import("@angular/core").InputSignal<string>;
7
+ readonly createPattern: import("@angular/core").InputSignal<string>;
8
+ readonly semantic: import("@angular/core").OutputEmitterRef<void>;
9
+ list: FsListComponent;
10
+ listConfig: FsListConfig<ReportListItem>;
11
+ private _reportData;
12
+ private _router;
13
+ private _route;
14
+ private _prompt;
15
+ private _destroyRef;
16
+ constructor();
17
+ openLink(report: ReportListItem): unknown[];
18
+ createReport(): void;
19
+ private _patternCommands;
20
+ private _initListConfig;
21
+ static ɵfac: i0.ɵɵFactoryDeclaration<FsAiReportsComponent, never>;
22
+ static ɵcmp: i0.ɵɵComponentDeclaration<FsAiReportsComponent, "fs-ai-reports", never, { "basePath": { "alias": "basePath"; "required": false; "isSignal": true; }; "openPattern": { "alias": "openPattern"; "required": false; "isSignal": true; }; "createPattern": { "alias": "createPattern"; "required": false; "isSignal": true; }; }, { "semantic": "semantic"; }, never, never, true, never>;
23
+ }
@@ -13,4 +13,4 @@ export const FREQUENCY_OPTIONS = [
13
13
  { value: 'quarter', name: 'Quarter' },
14
14
  { value: 'year', name: 'Annually' },
15
15
  ];
16
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG1DQUFtQztBQXdGbkMsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQWdEO0lBQzVFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO0lBQzdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQy9CLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0lBQ2pDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO0lBQ3JDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO0NBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgYXNzZW1ibGVkIHJlcG9ydCBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgR0VUIC9hcGkvcmVwb3J0cy86aWQg4oCUIGNvbXBvc2VkXG4vLyBzZXJ2ZXItc2lkZSBmcm9tIHRoZSBub3JtYWxpemVkIHRhYmxlcyAocmVwb3J0cyDihpIgcmVwb3J0X3BhZ2VzIOKGklxuLy8gcmVwb3J0X2NvbXBvbmVudHMgKyByZXBvcnRfZmlsdGVycywgcGx1cyByZXBvcnRfZmlsdGVyX2dyb3VwcykuIEFsbCBrZXlzIGFyZVxuLy8gY2FtZWxDYXNlOyBjb21wb25lbnQgYGNvbmZpZ2AgaXMgdGhlIHN0YW5kYXJkIGZvcm1hdCB0aGUgcmVuZGVyZXIgbWFwcyB0b1xuLy8gRUNoYXJ0cyBvcHRpb25zIC8gRnNMaXN0IGNvbmZpZy5cblxuLy8gTGF5b3V0IG1vZGVzOiBGcmVlZm9ybSA9IGFic29sdXRlbHkgcG9zaXRpb25lZCBjb21wb25lbnRzIChkcmFnIGFueXdoZXJlKTtcbi8vIEZsb3cgPSBjb21wb25lbnRzIGZsb3cgbGlrZSByb3dzLCBlYWNoIHRha2luZyBmbG93V2lkdGggJSBvZiB0aGUgcGFnZSB3aWR0aC5cbmV4cG9ydCB0eXBlIFJlcG9ydExheW91dCA9ICdmcmVlZm9ybScgfCAnZmxvdyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwYWdlU2l6ZTogJ3dpZGVzY3JlZW4nIHwgJ2xldHRlcic7XG4gIHBhZ2VPcmllbnRhdGlvbjogJ2xhbmRzY2FwZScgfCAncG9ydHJhaXQnO1xuICBsYXlvdXQ6IFJlcG9ydExheW91dDtcbiAgLy8gSUFOQSB0aW1lem9uZSAoZS5nLiBBbWVyaWNhL05ld19Zb3JrKSBhbmNob3JpbmcgZGF0ZSBmaWx0ZXJpbmcgKyBjaGFydCBkYXRlXG4gIC8vIGJ1Y2tldGluZy4gbnVsbCBmYWxscyBiYWNrIHRvIHRoZSBhY2NvdW50IHpvbmUgdGhlbiBVVEMgKHJlc29sdmVkIHNlcnZlci1zaWRlKS5cbiAgdGltZXpvbmU6IHN0cmluZyB8IG51bGw7XG4gIC8vIFJlcG9ydC1sZXZlbCBjb25maWc6IHR5cG9ncmFwaGljIHN0eWxlcywgZXRjLiAoY2FtZWxDYXNlIEpTT04gY29sdW1uKS5cbiAgY29uZmlnOiBSZXBvcnRDb25maWc7XG4gIC8vIENhbnZhcyBkaW1lbnNpb25zIGluIElOQ0hFUyAodGhlIHJlcG9ydCdzIG5hdGl2ZSB1bml0IOKAlCBQREZzIGFuZFxuICAvLyBQb3dlclBvaW50IGFyZSBpbmNoLWJhc2VkLCBzbyBleHBvcnRzIGFyZSBkaW1lbnNpb25hbGx5IGV4YWN0KS5cbiAgcGFnZVdpZHRoOiBudW1iZXI7XG4gIHBhZ2VIZWlnaHQ6IG51bWJlcjtcbiAgcGFnZXM6IFJlcG9ydFBhZ2VbXTtcbiAgZmlsdGVyR3JvdXBzOiBSZXBvcnRGaWx0ZXJHcm91cFtdO1xufVxuXG4vLyBSZXBvcnQtbGV2ZWwgc3R5bGluZy4gU2l6ZXMgYXJlIGluIFBPSU5UUyAoMS83MlwiKSDigJQgdGhlIHJlcG9ydCdzIHR5cG9ncmFwaHlcbi8vIG1hcHMgMToxIHRvIFBERiAoNzJwdC9pbikgYW5kIFBvd2VyUG9pbnQgKHBvaW50IGZvbnQgc2l6ZXMpLCBzbyBhIHBvaW50XG4vLyB2YWx1ZSBpcyBkaW1lbnNpb25hbGx5IGV4YWN0IG9uIHNjcmVlbiBhbmQgaW4gZXZlcnkgZXhwb3J0LlxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRDb25maWcge1xuICBzdHlsZXM/OiBSZXBvcnRTdHlsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0U3R5bGVzIHtcbiAgaGVhZGluZz86IHsgc2l6ZT86IG51bWJlciB9O1xufVxuXG4vLyBDb250ZW50IHBhZGRpbmcgYXJvdW5kIGEgY29tcG9uZW50J3MgYm9keSwgaW4gSU5DSEVTICh0aGUgZ2VvbWV0cnkgdW5pdCkuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudFBhZGRpbmcge1xuICB0b3A/OiBudW1iZXI7XG4gIHJpZ2h0PzogbnVtYmVyO1xuICBib3R0b20/OiBudW1iZXI7XG4gIGxlZnQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0UGFnZSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIG9yZGVyOiBudW1iZXI7XG4gIGNvbXBvbmVudHM6IFJlcG9ydENvbXBvbmVudFtdO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRDb21wb25lbnRUeXBlID0gJ2NoYXJ0JyB8ICdsaXN0JyB8ICdrcGknO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENvbXBvbmVudCB7XG4gIGlkOiBudW1iZXI7XG4gIHR5cGU6IFJlcG9ydENvbXBvbmVudFR5cGU7XG4gIHRpdGxlOiBzdHJpbmcgfCBudWxsO1xuICAvLyBHZW9tZXRyeSBpbiBJTkNIRVMuIEZyZWVmb3JtOiBhYnNvbHV0ZSBwb3NpdGlvbiBvbiB0aGUgcGFnZSBjYW52YXMuXG4gIC8vIEZsb3c6IG9ubHkgZmxvd1dpZHRoL29yZGVyIGFwcGx5OyB4L3kgYXJlIHJlbWVtYmVyZWQgZm9yIGEgc3dpdGNoIGJhY2sgdG9cbiAgLy8gZnJlZWZvcm0uXG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3OiBudW1iZXI7XG4gIGg6IG51bWJlcjtcbiAgLy8gSGVpZ2h0IG1vZGUsIERFUklWRUQgZnJvbSB0eXBlIHNlcnZlci1zaWRlIChub3Qgc3RvcmVkLCByZWFkLW9ubHkpOiBsaXN0c1xuICAvLyBhbmQgS1BJIHRpbGVzIGFyZSBhdXRvICh0aGUgYm94IHNpemVzIHRvIGl0cyBjb250ZW50LCBgaGAgaWdub3JlZCk7IGNoYXJ0c1xuICAvLyBhcmUgYWx3YXlzIGZpeGVkICh1c2UgYGhgKSBzbyB0aGV5IGZpdCB0aGUgYm94IGFuZCBuZXZlciBvdmVyZmxvdy5cbiAgYXV0b0hlaWdodDogYm9vbGVhbjtcbiAgLy8gRmxvdyBsYXlvdXQ6ICUgb2YgdGhlIHBhZ2UgY29udGVudCB3aWR0aCB0aGlzIGNvbXBvbmVudCB0YWtlcy5cbiAgZmxvd1dpZHRoOiBudW1iZXI7XG4gIC8vIEZsb3cgbGF5b3V0IG9yZGVyaW5nLlxuICBvcmRlcjogbnVtYmVyO1xuICBzcWw6IHN0cmluZyB8IG51bGw7XG4gIGNvbmZpZzogQ2hhcnRDb25maWcgJiBMaXN0Q29uZmlnICYgS3BpQ29uZmlnICYgQ29tcG9uZW50TGF5b3V0Q29uZmlnICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBDcm9zcy10eXBlIGxheW91dC9zdHlsZSBrZXlzIGNhcnJpZWQgaW4gYSBjb21wb25lbnQncyBjb25maWcgKGFsb25nc2lkZSB0aGVcbi8vIHR5cGUtc3BlY2lmaWMgY2hhcnQvbGlzdC9rcGkga2V5cykuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExheW91dENvbmZpZyB7XG4gIHBhZGRpbmc/OiBDb21wb25lbnRQYWRkaW5nO1xufVxuXG4vLyBXaGVyZSBhIGNoYXJ0J3MgbGVnZW5kIHNpdHMgcmVsYXRpdmUgdG8gdGhlIHBsb3QsIG9yICdoaWRkZW4nIHRvIGRyb3AgaXQuXG5leHBvcnQgdHlwZSBMZWdlbmRQb3NpdGlvbiA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ2hpZGRlbic7XG5cbmV4cG9ydCB0eXBlIENoYXJ0R3JhbnVsYXJpdHkgPSAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAncXVhcnRlcicgfCAneWVhcic7XG5cbi8vIFRoZSBydW50aW1lIEZyZXF1ZW5jeSBjb250cm9sJ3MgY2hvaWNlcyDigJQgcmUtYnVja2V0cyBldmVyeSB0aW1lLXNlcmllcyBjaGFydFxuLy8gYXQgdmlldyB0aW1lLCBvdmVycmlkaW5nIGVhY2ggY2hhcnQncyBhdXRob3JlZCBncmFudWxhcml0eS4gJ3llYXInIHJlYWRzIGFzXG4vLyBcIkFubnVhbGx5XCIgaW4gdGhlIGNvbnRyb2wuXG5leHBvcnQgY29uc3QgRlJFUVVFTkNZX09QVElPTlM6IHsgdmFsdWU6IENoYXJ0R3JhbnVsYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6ICdkYXknLCBuYW1lOiAnRGF5JyB9LFxuICB7IHZhbHVlOiAnd2VlaycsIG5hbWU6ICdXZWVrJyB9LFxuICB7IHZhbHVlOiAnbW9udGgnLCBuYW1lOiAnTW9udGgnIH0sXG4gIHsgdmFsdWU6ICdxdWFydGVyJywgbmFtZTogJ1F1YXJ0ZXInIH0sXG4gIHsgdmFsdWU6ICd5ZWFyJywgbmFtZTogJ0FubnVhbGx5JyB9LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBDaGFydENvbmZpZyB7XG4gIGNoYXJ0VHlwZT86ICdiYXInIHwgJ2xpbmUnIHwgJ2FyZWEnIHwgJ3BpZScgfCAnZG9udXQnO1xuICAvLyBGb3Iga2luZCAndGltZScsIHRoZSBzZXJ2ZXIgYnVja2V0cyB0aGUgcmF3IGRhdGV0aW1lIGNvbHVtbiB0byBgZ3JhbnVsYXJpdHlgXG4gIC8vIGluIHRoZSByZXBvcnQncyB0aW1lem9uZSAodGhlIFNRTCBleHBvc2VzIHRoZSByYXcgY29sdW1uLCB1bmJ1Y2tldGVkKS5cbiAgeEF4aXM/OiB7IGNvbHVtbjogc3RyaW5nOyBraW5kPzogJ2NhdGVnb3J5JyB8ICd0aW1lJzsgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5OyBsYWJlbD86IHN0cmluZyB9O1xuICBtZWFzdXJlcz86IENoYXJ0TWVhc3VyZVtdO1xuICBzcGxpdEJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgLy8gU2luZ2xlLWRpbWVuc2lvbiBiYXIgY2hhcnRzIG9ubHk6IGNvbG9yIGVhY2ggYmFyIGJ5IGl0cyBvd24gY2F0ZWdvcnkgYW5kXG4gIC8vIHNob3cgYSBsZWdlbmQsIFdJVEhPVVQgc3BsaXR0aW5nIGludG8gbXVsdGlwbGUgc2VyaWVzICh3aGljaCBzbGl2ZXJzIHRoZVxuICAvLyBiYXJzKS4gdjEgZXhwZWN0cyBjb2xvckJ5LmNvbHVtbiA9PT0geEF4aXMuY29sdW1uLiBJZ25vcmVkIHdoZW4gc3BsaXRCeSBpc1xuICAvLyBzZXQgb3IgdGhlIGNoYXJ0IGlzbid0IGEgYmFyIGNoYXJ0LlxuICBjb2xvckJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgb3JpZW50YXRpb24/OiAndmVydGljYWwnIHwgJ2hvcml6b250YWwnO1xuICBzdGFja2VkPzogYm9vbGVhbjtcbiAgbGVnZW5kPzogTGVnZW5kUG9zaXRpb247XG4gIHNvcnQ/OiBSZXBvcnRTb3J0O1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDaGFydE1lYXN1cmUge1xuICBjb2x1bW46IHN0cmluZztcbiAgYWdncmVnYXRpb24/OiAnc3VtJyB8ICdjb3VudCcgfCAnYXZnJyB8ICdtaW4nIHwgJ21heCc7XG4gIGxhYmVsPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAnbnVtYmVyJyB8ICdwZXJjZW50JyB8ICdjdXJyZW5jeSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdENvbmZpZyB7XG4gIGNvbHVtbnM/OiB7IGNvbHVtbjogc3RyaW5nOyBsYWJlbD86IHN0cmluZzsgZm9ybWF0PzogJ2RhdGUnIHwgJ251bWJlcicgfVtdO1xuICBzb3J0PzogUmVwb3J0U29ydDtcbiAgcGFnZVNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpQ29uZmlnIHtcbiAgbWVhc3VyZT86IENoYXJ0TWVhc3VyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRTb3J0IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIGRpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJUeXBlID0gJ2RhdGVSYW5nZScgfCAnc2VsZWN0JyB8ICdrZXl3b3JkJztcblxuLy8gV2hlcmUgYSBmaWx0ZXIgZ3JvdXAncyBjb250cm9sIGlzIGV4cG9zZWQuIEEgZ3JvdXAgY2FuIGJlIHNob3duIG9uIGl0c1xuLy8gY29tcG9uZW50cywgaW4gdGhlIHJlcG9ydCBiYXIsIG9yIEJPVEggYXQgb25jZSAodGhlIHR3byBhcmUgaW5kZXBlbmRlbnRcbi8vIHRvZ2dsZXMgaW4gdGhlIFVJKTsgYSBjb2x1bW4gd2l0aCBuZWl0aGVyIGV4cG9zZWQgc2ltcGx5IGhhcyBubyBmaWx0ZXIuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJMZXZlbCA9ICdjb21wb25lbnQnIHwgJ3JlcG9ydCcgfCAnYm90aCc7XG5cbi8vIE9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gb2YgYSBjb21wb25lbnQncyBTUUwsIHdpdGggdGhlIGZpbHRlciBpbnRlcmZhY2Vcbi8vIElORkVSUkVEIGZyb20gaXRzIGRhdGEgKHRoZSBodW1hbiBuZXZlciBwaWNrcyB0aGUgaW50ZXJmYWNlIOKAlCBpdCBmb2xsb3dzIHRoZVxuLy8gY29sdW1uJ3MgdHlwZSkuIERyaXZlcyB0aGUgRmlsdGVycyB0YWIgbGlzdGluZy5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyYWJsZUNvbHVtbiB7XG4gIGNvbHVtbjogc3RyaW5nO1xuICB0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlO1xufVxuXG4vLyBHcm91bmQgdHJ1dGg6IG9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gT04gb25lIGNvbXBvbmVudCdzIFNRTC4gQWx3YXlzIGFcbi8vIG1lbWJlciBvZiBhIGZpbHRlciBncm91cCDigJQgdGhlIHVuaXQgdGhhdCBsaW5rcyBlcXVpdmFsZW50IGZpbHRlcnMgYWNyb3NzXG4vLyBjb21wb25lbnRzIGFuZCBkZWNpZGVzIHdoZXJlIHRoZSBjb250cm9sIHJlbmRlcnMgKGNvbXBvbmVudCB2cyByZXBvcnQgYmFyKS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29tcG9uZW50SWQ6IG51bWJlcjtcbiAgZmlsdGVyR3JvdXBJZDogbnVtYmVyO1xuICBmaWx0ZXJDb2x1bW46IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZyB8IG51bGw7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGhhc09wdGlvbnM6IGJvb2xlYW47XG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyR3JvdXAge1xuICBpZDogbnVtYmVyO1xuICBsYWJlbDogc3RyaW5nIHwgbnVsbDtcbiAgdHlwZTogUmVwb3J0RmlsdGVyVHlwZTtcbiAgbGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsO1xuICBvcmRlcjogbnVtYmVyO1xuICBjb25maWc6IHsgZGVmYXVsdD86IEZpbHRlckdyb3VwRGVmYXVsdCB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBBIGZpbHRlciBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQg4oCUIHRoZSB2YWx1ZSB0aGF0IHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uXG4vLyBldmVyeSBvcGVuLiBTaGFwZSBmb2xsb3dzIHRoZSBncm91cCdzIHR5cGU6IGRhdGVSYW5nZSB1c2VzIHN0YXJ0L2VuZCAoYSBmaXhlZFxuLy8gY2FsZW5kYXItZGF5IHJhbmdlKSBvciBhIHJlbGF0aXZlIHByZXNldDsgc2VsZWN0IHVzZXMgdmFsdWVzOyBrZXl3b3JkIHVzZXNcbi8vIHZhbHVlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cERlZmF1bHQge1xuICByZWxhdGl2ZT86IHN0cmluZzsgLy8gZGF0ZVJhbmdlIHJlbGF0aXZlIHByZXNldCwgZS5nLiBsYXN0MTJNb250aHMsIHllYXJUb0RhdGVcbiAgc3RhcnQ/OiBzdHJpbmc7IC8vIGRhdGVSYW5nZSBmaXhlZCBzdGFydCAoeXl5eS1NTS1kZClcbiAgZW5kPzogc3RyaW5nOyAvLyBkYXRlUmFuZ2UgZml4ZWQgZW5kICh5eXl5LU1NLWRkKVxuICB2YWx1ZXM/OiB1bmtub3duW107IC8vIHNlbGVjdCBkZWZhdWx0IHBpY2tlZCB2YWx1ZXNcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmQgZGVmYXVsdCB0ZXh0XG59XG5cbi8vIFRoZSBzZXNzaW9uIHZhbHVlIG9mIGEgZmlsdGVyIGdyb3VwIChuZXZlciBwZXJzaXN0ZWQpOiBzaGFwZSBkZXBlbmRzIG9uIHRoZVxuLy8gZ3JvdXAncyB0eXBlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cFZhbHVlIHtcbiAgc3RhcnQ/OiBEYXRlIHwgc3RyaW5nIHwgbnVsbDsgLy8gZGF0ZVJhbmdlXG4gIGVuZD86IERhdGUgfCBzdHJpbmcgfCBudWxsOyAvLyBkYXRlUmFuZ2VcbiAgdmFsdWVzPzogdW5rbm93bltdOyAvLyBzZWxlY3RcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmRcbn1cblxuLy8gT25lIHJlc29sdmVkIGZpbHRlciBzZW50IHdpdGggYSBjb21wb25lbnQncyBkYXRhIHJlcXVlc3QuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkRmlsdGVyVmFsdWUge1xuICBmaWx0ZXJJZDogbnVtYmVyO1xuICBzdGFydD86IHN0cmluZztcbiAgZW5kPzogc3RyaW5nO1xuICB2YWx1ZXM/OiB1bmtub3duW107XG4gIHZhbHVlPzogc3RyaW5nO1xufVxuXG4vLyBQZXItY29tcG9uZW50IGludGVyYWN0aW9uIHN0YXRlIHNlbnQgd2l0aCB0aGUgZGF0YSByZXF1ZXN0OiBsaXN0cyBzZW5kXG4vLyBzb3J0L3BhZ2luZzsgdGltZS1zZXJpZXMgY2hhcnRzIHNlbmQgdGhlIHZpZXdlcidzIGNob3NlbiBGcmVxdWVuY3ksIHdoaWNoXG4vLyBvdmVycmlkZXMgdGhlIGF1dGhvcmVkIGdyYW51bGFyaXR5IGZvciB0aGF0IHJlcXVlc3Qgb25seS5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50RGF0YVN0YXRlIHtcbiAgc29ydD86IFJlcG9ydFNvcnQ7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBhZ2VTaXplPzogbnVtYmVyO1xuICBmcmVxdWVuY3k/OiBDaGFydEdyYW51bGFyaXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudERhdGEge1xuICBjb2x1bW5zOiBzdHJpbmdbXTtcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgcGFnaW5nPzogeyB0b3RhbDogbnVtYmVyOyBwYWdlOiBudW1iZXI7IHBhZ2VTaXplOiBudW1iZXIgfTtcbiAgdHJ1bmNhdGVkOiBib29sZWFuO1xuICAvLyBUaGUgZWZmZWN0aXZlIHRpbWUgYnVja2V0IHRoZSByb3dzIHdlcmUgZ3JvdXBlZCBpbnRvIChhZnRlciBhbnkgRnJlcXVlbmN5XG4gIC8vIG92ZXJyaWRlKSwgb3IgbnVsbCBmb3IgYSBub24tdGltZSBheGlzLiBEcml2ZXMgdGhlIGNvbXBhY3QgeC1heGlzIGxhYmVscy5cbiAgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRMaXN0SXRlbSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuLy8gVGhlIGNoYXQgdHVybiBmbGFncyB0aGlzIGNvbnRleHQncyBiYWNrZW5kIGFkZHMgKFJlcG9ydHNcXEFpVmlldykuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENoYXRSZXNwb25zZSB7XG4gIHJlcG9ydENoYW5nZWQ/OiBib29sZWFuO1xuICByZXBvcnRSZW5hbWVkPzogYm9vbGVhbjtcbn1cbiJdfQ==
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkVBQTZFO0FBQzdFLG1FQUFtRTtBQUNuRSwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLG1DQUFtQztBQXdGbkMsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQWdEO0lBQzVFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO0lBQzdCLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFO0lBQy9CLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFO0lBQ2pDLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO0lBQ3JDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO0NBQ3BDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgYXNzZW1ibGVkIHJlcG9ydCBzdHJ1Y3R1cmUgcmV0dXJuZWQgYnkgR0VUIC9hcGkvcmVwb3J0cy86aWQg4oCUIGNvbXBvc2VkXG4vLyBzZXJ2ZXItc2lkZSBmcm9tIHRoZSBub3JtYWxpemVkIHRhYmxlcyAocmVwb3J0cyDihpIgcmVwb3J0X3BhZ2VzIOKGklxuLy8gcmVwb3J0X2NvbXBvbmVudHMgKyByZXBvcnRfZmlsdGVycywgcGx1cyByZXBvcnRfZmlsdGVyX2dyb3VwcykuIEFsbCBrZXlzIGFyZVxuLy8gY2FtZWxDYXNlOyBjb21wb25lbnQgYGNvbmZpZ2AgaXMgdGhlIHN0YW5kYXJkIGZvcm1hdCB0aGUgcmVuZGVyZXIgbWFwcyB0b1xuLy8gRUNoYXJ0cyBvcHRpb25zIC8gRnNMaXN0IGNvbmZpZy5cblxuLy8gTGF5b3V0IG1vZGVzOiBGcmVlZm9ybSA9IGFic29sdXRlbHkgcG9zaXRpb25lZCBjb21wb25lbnRzIChkcmFnIGFueXdoZXJlKTtcbi8vIEZsb3cgPSBjb21wb25lbnRzIGZsb3cgbGlrZSByb3dzLCBlYWNoIHRha2luZyBmbG93V2lkdGggJSBvZiB0aGUgcGFnZSB3aWR0aC5cbmV4cG9ydCB0eXBlIFJlcG9ydExheW91dCA9ICdmcmVlZm9ybScgfCAnZmxvdyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0IHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBwYWdlU2l6ZTogJ3dpZGVzY3JlZW4nIHwgJ2xldHRlcic7XG4gIHBhZ2VPcmllbnRhdGlvbjogJ2xhbmRzY2FwZScgfCAncG9ydHJhaXQnO1xuICBsYXlvdXQ6IFJlcG9ydExheW91dDtcbiAgLy8gSUFOQSB0aW1lem9uZSAoZS5nLiBBbWVyaWNhL05ld19Zb3JrKSBhbmNob3JpbmcgZGF0ZSBmaWx0ZXJpbmcgKyBjaGFydCBkYXRlXG4gIC8vIGJ1Y2tldGluZy4gbnVsbCBmYWxscyBiYWNrIHRvIHRoZSBhY2NvdW50IHpvbmUgdGhlbiBVVEMgKHJlc29sdmVkIHNlcnZlci1zaWRlKS5cbiAgdGltZXpvbmU6IHN0cmluZyB8IG51bGw7XG4gIC8vIFJlcG9ydC1sZXZlbCBjb25maWc6IHR5cG9ncmFwaGljIHN0eWxlcywgZXRjLiAoY2FtZWxDYXNlIEpTT04gY29sdW1uKS5cbiAgY29uZmlnOiBSZXBvcnRDb25maWc7XG4gIC8vIENhbnZhcyBkaW1lbnNpb25zIGluIElOQ0hFUyAodGhlIHJlcG9ydCdzIG5hdGl2ZSB1bml0IOKAlCBQREZzIGFuZFxuICAvLyBQb3dlclBvaW50IGFyZSBpbmNoLWJhc2VkLCBzbyBleHBvcnRzIGFyZSBkaW1lbnNpb25hbGx5IGV4YWN0KS5cbiAgcGFnZVdpZHRoOiBudW1iZXI7XG4gIHBhZ2VIZWlnaHQ6IG51bWJlcjtcbiAgcGFnZXM6IFJlcG9ydFBhZ2VbXTtcbiAgZmlsdGVyR3JvdXBzOiBSZXBvcnRGaWx0ZXJHcm91cFtdO1xufVxuXG4vLyBSZXBvcnQtbGV2ZWwgc3R5bGluZy4gU2l6ZXMgYXJlIGluIFBPSU5UUyAoMS83MlwiKSDigJQgdGhlIHJlcG9ydCdzIHR5cG9ncmFwaHlcbi8vIG1hcHMgMToxIHRvIFBERiAoNzJwdC9pbikgYW5kIFBvd2VyUG9pbnQgKHBvaW50IGZvbnQgc2l6ZXMpLCBzbyBhIHBvaW50XG4vLyB2YWx1ZSBpcyBkaW1lbnNpb25hbGx5IGV4YWN0IG9uIHNjcmVlbiBhbmQgaW4gZXZlcnkgZXhwb3J0LlxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRDb25maWcge1xuICBzdHlsZXM/OiBSZXBvcnRTdHlsZXM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0U3R5bGVzIHtcbiAgaGVhZGluZz86IHsgc2l6ZT86IG51bWJlciB9O1xufVxuXG4vLyBDb250ZW50IHBhZGRpbmcgYXJvdW5kIGEgY29tcG9uZW50J3MgYm9keSwgaW4gSU5DSEVTICh0aGUgZ2VvbWV0cnkgdW5pdCkuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudFBhZGRpbmcge1xuICB0b3A/OiBudW1iZXI7XG4gIHJpZ2h0PzogbnVtYmVyO1xuICBib3R0b20/OiBudW1iZXI7XG4gIGxlZnQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0UGFnZSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZyB8IG51bGw7XG4gIG9yZGVyOiBudW1iZXI7XG4gIGNvbXBvbmVudHM6IFJlcG9ydENvbXBvbmVudFtdO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRDb21wb25lbnRUeXBlID0gJ2NoYXJ0JyB8ICdsaXN0JyB8ICdrcGknO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydENvbXBvbmVudCB7XG4gIGlkOiBudW1iZXI7XG4gIHR5cGU6IFJlcG9ydENvbXBvbmVudFR5cGU7XG4gIHRpdGxlOiBzdHJpbmcgfCBudWxsO1xuICAvLyBHZW9tZXRyeSBpbiBJTkNIRVMuIEZyZWVmb3JtOiBhYnNvbHV0ZSBwb3NpdGlvbiBvbiB0aGUgcGFnZSBjYW52YXMuXG4gIC8vIEZsb3c6IG9ubHkgZmxvd1dpZHRoL29yZGVyIGFwcGx5OyB4L3kgYXJlIHJlbWVtYmVyZWQgZm9yIGEgc3dpdGNoIGJhY2sgdG9cbiAgLy8gZnJlZWZvcm0uXG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICB3OiBudW1iZXI7XG4gIGg6IG51bWJlcjtcbiAgLy8gSGVpZ2h0IG1vZGUsIERFUklWRUQgZnJvbSB0eXBlIHNlcnZlci1zaWRlIChub3Qgc3RvcmVkLCByZWFkLW9ubHkpOiBsaXN0c1xuICAvLyBhbmQgS1BJIHRpbGVzIGFyZSBhdXRvICh0aGUgYm94IHNpemVzIHRvIGl0cyBjb250ZW50LCBgaGAgaWdub3JlZCk7IGNoYXJ0c1xuICAvLyBhcmUgYWx3YXlzIGZpeGVkICh1c2UgYGhgKSBzbyB0aGV5IGZpdCB0aGUgYm94IGFuZCBuZXZlciBvdmVyZmxvdy5cbiAgYXV0b0hlaWdodDogYm9vbGVhbjtcbiAgLy8gRmxvdyBsYXlvdXQ6ICUgb2YgdGhlIHBhZ2UgY29udGVudCB3aWR0aCB0aGlzIGNvbXBvbmVudCB0YWtlcy5cbiAgZmxvd1dpZHRoOiBudW1iZXI7XG4gIC8vIEZsb3cgbGF5b3V0IG9yZGVyaW5nLlxuICBvcmRlcjogbnVtYmVyO1xuICBzcWw6IHN0cmluZyB8IG51bGw7XG4gIGNvbmZpZzogQ2hhcnRDb25maWcgJiBMaXN0Q29uZmlnICYgS3BpQ29uZmlnICYgQ29tcG9uZW50TGF5b3V0Q29uZmlnICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBDcm9zcy10eXBlIGxheW91dC9zdHlsZSBrZXlzIGNhcnJpZWQgaW4gYSBjb21wb25lbnQncyBjb25maWcgKGFsb25nc2lkZSB0aGVcbi8vIHR5cGUtc3BlY2lmaWMgY2hhcnQvbGlzdC9rcGkga2V5cykuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudExheW91dENvbmZpZyB7XG4gIHBhZGRpbmc/OiBDb21wb25lbnRQYWRkaW5nO1xufVxuXG4vLyBXaGVyZSBhIGNoYXJ0J3MgbGVnZW5kIHNpdHMgcmVsYXRpdmUgdG8gdGhlIHBsb3QsIG9yICdoaWRkZW4nIHRvIGRyb3AgaXQuXG5leHBvcnQgdHlwZSBMZWdlbmRQb3NpdGlvbiA9ICd0b3AnIHwgJ2JvdHRvbScgfCAnbGVmdCcgfCAncmlnaHQnIHwgJ2hpZGRlbic7XG5cbmV4cG9ydCB0eXBlIENoYXJ0R3JhbnVsYXJpdHkgPSAnZGF5JyB8ICd3ZWVrJyB8ICdtb250aCcgfCAncXVhcnRlcicgfCAneWVhcic7XG5cbi8vIFRoZSBydW50aW1lIEZyZXF1ZW5jeSBjb250cm9sJ3MgY2hvaWNlcyDigJQgcmUtYnVja2V0cyBldmVyeSB0aW1lLXNlcmllcyBjaGFydFxuLy8gYXQgdmlldyB0aW1lLCBvdmVycmlkaW5nIGVhY2ggY2hhcnQncyBhdXRob3JlZCBncmFudWxhcml0eS4gJ3llYXInIHJlYWRzIGFzXG4vLyBcIkFubnVhbGx5XCIgaW4gdGhlIGNvbnRyb2wuXG5leHBvcnQgY29uc3QgRlJFUVVFTkNZX09QVElPTlM6IHsgdmFsdWU6IENoYXJ0R3JhbnVsYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6ICdkYXknLCBuYW1lOiAnRGF5JyB9LFxuICB7IHZhbHVlOiAnd2VlaycsIG5hbWU6ICdXZWVrJyB9LFxuICB7IHZhbHVlOiAnbW9udGgnLCBuYW1lOiAnTW9udGgnIH0sXG4gIHsgdmFsdWU6ICdxdWFydGVyJywgbmFtZTogJ1F1YXJ0ZXInIH0sXG4gIHsgdmFsdWU6ICd5ZWFyJywgbmFtZTogJ0FubnVhbGx5JyB9LFxuXTtcblxuZXhwb3J0IGludGVyZmFjZSBDaGFydENvbmZpZyB7XG4gIGNoYXJ0VHlwZT86ICdiYXInIHwgJ2xpbmUnIHwgJ2FyZWEnIHwgJ3BpZScgfCAnZG9udXQnO1xuICAvLyBGb3Iga2luZCAndGltZScsIHRoZSBzZXJ2ZXIgYnVja2V0cyB0aGUgcmF3IGRhdGV0aW1lIGNvbHVtbiB0byBgZ3JhbnVsYXJpdHlgXG4gIC8vIGluIHRoZSByZXBvcnQncyB0aW1lem9uZSAodGhlIFNRTCBleHBvc2VzIHRoZSByYXcgY29sdW1uLCB1bmJ1Y2tldGVkKS5cbiAgeEF4aXM/OiB7IGNvbHVtbjogc3RyaW5nOyBraW5kPzogJ2NhdGVnb3J5JyB8ICd0aW1lJzsgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5OyBsYWJlbD86IHN0cmluZyB9O1xuICBtZWFzdXJlcz86IENoYXJ0TWVhc3VyZVtdO1xuICBzcGxpdEJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgLy8gU2luZ2xlLWRpbWVuc2lvbiBiYXIgY2hhcnRzIG9ubHk6IGNvbG9yIGVhY2ggYmFyIGJ5IGl0cyBvd24gY2F0ZWdvcnkgYW5kXG4gIC8vIHNob3cgYSBsZWdlbmQsIFdJVEhPVVQgc3BsaXR0aW5nIGludG8gbXVsdGlwbGUgc2VyaWVzICh3aGljaCBzbGl2ZXJzIHRoZVxuICAvLyBiYXJzKS4gdjEgZXhwZWN0cyBjb2xvckJ5LmNvbHVtbiA9PT0geEF4aXMuY29sdW1uLiBJZ25vcmVkIHdoZW4gc3BsaXRCeSBpc1xuICAvLyBzZXQgb3IgdGhlIGNoYXJ0IGlzbid0IGEgYmFyIGNoYXJ0LlxuICBjb2xvckJ5PzogeyBjb2x1bW46IHN0cmluZzsgbGFiZWw/OiBzdHJpbmcgfTtcbiAgb3JpZW50YXRpb24/OiAndmVydGljYWwnIHwgJ2hvcml6b250YWwnO1xuICBzdGFja2VkPzogYm9vbGVhbjtcbiAgbGVnZW5kPzogTGVnZW5kUG9zaXRpb247XG4gIHNvcnQ/OiBSZXBvcnRTb3J0O1xuICBsaW1pdD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDaGFydE1lYXN1cmUge1xuICBjb2x1bW46IHN0cmluZztcbiAgYWdncmVnYXRpb24/OiAnc3VtJyB8ICdjb3VudCcgfCAnYXZnJyB8ICdtaW4nIHwgJ21heCc7XG4gIGxhYmVsPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAnbnVtYmVyJyB8ICdwZXJjZW50JyB8ICdjdXJyZW5jeSc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdENvbmZpZyB7XG4gIGNvbHVtbnM/OiB7IGNvbHVtbjogc3RyaW5nOyBsYWJlbD86IHN0cmluZzsgZm9ybWF0PzogJ2RhdGUnIHwgJ251bWJlcicgfVtdO1xuICBzb3J0PzogUmVwb3J0U29ydDtcbiAgcGFnZVNpemU/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgS3BpQ29uZmlnIHtcbiAgbWVhc3VyZT86IENoYXJ0TWVhc3VyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRTb3J0IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIGRpcmVjdGlvbj86ICdhc2MnIHwgJ2Rlc2MnO1xufVxuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJUeXBlID0gJ2RhdGVSYW5nZScgfCAnc2VsZWN0JyB8ICdrZXl3b3JkJztcblxuLy8gV2hlcmUgYSBmaWx0ZXIgZ3JvdXAncyBjb250cm9sIGlzIGV4cG9zZWQuIEEgZ3JvdXAgY2FuIGJlIHNob3duIG9uIGl0c1xuLy8gY29tcG9uZW50cywgaW4gdGhlIHJlcG9ydCBiYXIsIG9yIEJPVEggYXQgb25jZSAodGhlIHR3byBhcmUgaW5kZXBlbmRlbnRcbi8vIHRvZ2dsZXMgaW4gdGhlIFVJKTsgYSBjb2x1bW4gd2l0aCBuZWl0aGVyIGV4cG9zZWQgc2ltcGx5IGhhcyBubyBmaWx0ZXIuXG5leHBvcnQgdHlwZSBSZXBvcnRGaWx0ZXJMZXZlbCA9ICdjb21wb25lbnQnIHwgJ3JlcG9ydCcgfCAnYm90aCc7XG5cbi8vIE9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gb2YgYSBjb21wb25lbnQncyBTUUwsIHdpdGggdGhlIGZpbHRlciBpbnRlcmZhY2Vcbi8vIElORkVSUkVEIGZyb20gaXRzIGRhdGEgKHRoZSBodW1hbiBuZXZlciBwaWNrcyB0aGUgaW50ZXJmYWNlIOKAlCBpdCBmb2xsb3dzIHRoZVxuLy8gY29sdW1uJ3MgdHlwZSkuIERyaXZlcyB0aGUgRmlsdGVycyB0YWIgbGlzdGluZy5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyYWJsZUNvbHVtbiB7XG4gIGNvbHVtbjogc3RyaW5nO1xuICB0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlO1xufVxuXG4vLyBHcm91bmQgdHJ1dGg6IG9uZSBmaWx0ZXJhYmxlIG91dHB1dCBjb2x1bW4gT04gb25lIGNvbXBvbmVudCdzIFNRTC4gQWx3YXlzIGFcbi8vIG1lbWJlciBvZiBhIGZpbHRlciBncm91cCDigJQgdGhlIHVuaXQgdGhhdCBsaW5rcyBlcXVpdmFsZW50IGZpbHRlcnMgYWNyb3NzXG4vLyBjb21wb25lbnRzIGFuZCBkZWNpZGVzIHdoZXJlIHRoZSBjb250cm9sIHJlbmRlcnMgKGNvbXBvbmVudCB2cyByZXBvcnQgYmFyKS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29tcG9uZW50SWQ6IG51bWJlcjtcbiAgZmlsdGVyR3JvdXBJZDogbnVtYmVyO1xuICBmaWx0ZXJDb2x1bW46IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZyB8IG51bGw7XG4gIGVuYWJsZWQ6IGJvb2xlYW47XG4gIGhhc09wdGlvbnM6IGJvb2xlYW47XG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0RmlsdGVyR3JvdXAge1xuICBpZDogbnVtYmVyO1xuICBsYWJlbDogc3RyaW5nIHwgbnVsbDtcbiAgdHlwZTogUmVwb3J0RmlsdGVyVHlwZTtcbiAgbGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsO1xuICBvcmRlcjogbnVtYmVyO1xuICBjb25maWc6IHsgZGVmYXVsdD86IEZpbHRlckdyb3VwRGVmYXVsdCB9ICYgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGZpbHRlcnM6IFJlcG9ydEZpbHRlcltdO1xufVxuXG4vLyBBIGZpbHRlciBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQg4oCUIHRoZSB2YWx1ZSB0aGF0IHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uXG4vLyBldmVyeSBvcGVuLiBTaGFwZSBmb2xsb3dzIHRoZSBncm91cCdzIHR5cGU6IGRhdGVSYW5nZSB1c2VzIHN0YXJ0L2VuZCAoYSBmaXhlZFxuLy8gY2FsZW5kYXItZGF5IHJhbmdlKSBvciBhIHJlbGF0aXZlIHByZXNldDsgc2VsZWN0IHVzZXMgdmFsdWVzOyBrZXl3b3JkIHVzZXNcbi8vIHZhbHVlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cERlZmF1bHQge1xuICByZWxhdGl2ZT86IHN0cmluZzsgLy8gZGF0ZVJhbmdlIHJlbGF0aXZlIHByZXNldCwgZS5nLiBsYXN0MTJNb250aHMsIHllYXJUb0RhdGVcbiAgc3RhcnQ/OiBzdHJpbmc7IC8vIGRhdGVSYW5nZSBmaXhlZCBzdGFydCAoeXl5eS1NTS1kZClcbiAgZW5kPzogc3RyaW5nOyAvLyBkYXRlUmFuZ2UgZml4ZWQgZW5kICh5eXl5LU1NLWRkKVxuICB2YWx1ZXM/OiB1bmtub3duW107IC8vIHNlbGVjdCBkZWZhdWx0IHBpY2tlZCB2YWx1ZXNcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmQgZGVmYXVsdCB0ZXh0XG59XG5cbi8vIFRoZSBzZXNzaW9uIHZhbHVlIG9mIGEgZmlsdGVyIGdyb3VwIChuZXZlciBwZXJzaXN0ZWQpOiBzaGFwZSBkZXBlbmRzIG9uIHRoZVxuLy8gZ3JvdXAncyB0eXBlLlxuZXhwb3J0IGludGVyZmFjZSBGaWx0ZXJHcm91cFZhbHVlIHtcbiAgc3RhcnQ/OiBEYXRlIHwgc3RyaW5nIHwgbnVsbDsgLy8gZGF0ZVJhbmdlXG4gIGVuZD86IERhdGUgfCBzdHJpbmcgfCBudWxsOyAvLyBkYXRlUmFuZ2VcbiAgdmFsdWVzPzogdW5rbm93bltdOyAvLyBzZWxlY3RcbiAgdmFsdWU/OiBzdHJpbmc7IC8vIGtleXdvcmRcbn1cblxuLy8gT25lIHJlc29sdmVkIGZpbHRlciBzZW50IHdpdGggYSBjb21wb25lbnQncyBkYXRhIHJlcXVlc3QuXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkRmlsdGVyVmFsdWUge1xuICBmaWx0ZXJJZDogbnVtYmVyO1xuICBzdGFydD86IHN0cmluZztcbiAgZW5kPzogc3RyaW5nO1xuICB2YWx1ZXM/OiB1bmtub3duW107XG4gIHZhbHVlPzogc3RyaW5nO1xufVxuXG4vLyBQZXItY29tcG9uZW50IGludGVyYWN0aW9uIHN0YXRlIHNlbnQgd2l0aCB0aGUgZGF0YSByZXF1ZXN0OiBsaXN0cyBzZW5kXG4vLyBzb3J0L3BhZ2luZzsgdGltZS1zZXJpZXMgY2hhcnRzIHNlbmQgdGhlIHZpZXdlcidzIGNob3NlbiBGcmVxdWVuY3ksIHdoaWNoXG4vLyBvdmVycmlkZXMgdGhlIGF1dGhvcmVkIGdyYW51bGFyaXR5IGZvciB0aGF0IHJlcXVlc3Qgb25seS5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50RGF0YVN0YXRlIHtcbiAgc29ydD86IFJlcG9ydFNvcnQ7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBhZ2VTaXplPzogbnVtYmVyO1xuICBmcmVxdWVuY3k/OiBDaGFydEdyYW51bGFyaXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudERhdGEge1xuICBjb2x1bW5zOiBzdHJpbmdbXTtcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXTtcbiAgcGFnaW5nPzogeyB0b3RhbDogbnVtYmVyOyBwYWdlOiBudW1iZXI7IHBhZ2VTaXplOiBudW1iZXIgfTtcbiAgdHJ1bmNhdGVkOiBib29sZWFuO1xuICAvLyBUaGUgZWZmZWN0aXZlIHRpbWUgYnVja2V0IHRoZSByb3dzIHdlcmUgZ3JvdXBlZCBpbnRvIChhZnRlciBhbnkgRnJlcXVlbmN5XG4gIC8vIG92ZXJyaWRlKSwgb3IgbnVsbCBmb3IgYSBub24tdGltZSBheGlzLiBEcml2ZXMgdGhlIGNvbXBhY3QgeC1heGlzIGxhYmVscy5cbiAgZ3JhbnVsYXJpdHk/OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvcnRMaXN0SXRlbSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgbW9kaWZ5RGF0ZTogc3RyaW5nO1xufVxuXG4vLyBUaGUgY2hhdCB0dXJuIGZsYWdzIHRoaXMgY29udGV4dCdzIGJhY2tlbmQgYWRkcyAoUmVwb3J0c1xcQWlWaWV3KS5cbmV4cG9ydCBpbnRlcmZhY2UgUmVwb3J0Q2hhdFJlc3BvbnNlIHtcbiAgcmVwb3J0Q2hhbmdlZD86IGJvb2xlYW47XG4gIHJlcG9ydFJlbmFtZWQ/OiBib29sZWFuO1xufVxuIl19
@@ -0,0 +1,312 @@
1
+ import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, NgZone, ViewChild, effect, inject, input, output, } from '@angular/core';
2
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
+ import { MatButtonModule } from '@angular/material/button';
4
+ import { MatDialog } from '@angular/material/dialog';
5
+ import { MatIconModule } from '@angular/material/icon';
6
+ import { MatTooltipModule } from '@angular/material/tooltip';
7
+ import { FsFilterModule, ItemType } from '@firestitch/filter';
8
+ import { FsMenuModule } from '@firestitch/menu';
9
+ import { FsProcess } from '@firestitch/process';
10
+ import { from } from 'rxjs';
11
+ import { switchMap } from 'rxjs/operators';
12
+ import { provideEchartsCore } from 'ngx-echarts';
13
+ import { FsAiChatComponent } from '@firestitch/ai';
14
+ import { ReportCanvasComponent } from '../../components/report-canvas/report-canvas.component';
15
+ import { ReportData } from '../../data/report.data';
16
+ import { ComponentSettingsComponent } from '../../dialogs/component-settings/component-settings.component';
17
+ import { ReportSettingsComponent } from '../../dialogs/report-settings/report-settings.component';
18
+ import { ReportExportCollectorService } from '../../export/report-export-collector.service';
19
+ import { ReportPdfService } from '../../export/report-pdf.service';
20
+ import { ReportPptxService } from '../../export/report-pptx.service';
21
+ import { FREQUENCY_OPTIONS, } from '../../interfaces/report.interface';
22
+ import { filterItemForGroup, groupValuesFromQuery } from '../../report-filter-items';
23
+ import { ReportFilterStateService } from '../../services/report-filter-state.service';
24
+ import * as i0 from "@angular/core";
25
+ import * as i1 from "@firestitch/filter";
26
+ import * as i2 from "@firestitch/menu";
27
+ import * as i3 from "@angular/material/button";
28
+ import * as i4 from "@angular/material/icon";
29
+ import * as i5 from "@angular/material/tooltip";
30
+ // fs-filter query key for the runtime Frequency control (a render-layer bucket
31
+ // override, not a filter group — so it's read straight off the query).
32
+ const FREQUENCY_ITEM = 'frequency';
33
+ // A single report: the AI chat on the left, the report canvas on the right,
34
+ // under an H2 title + settings gear. The host supplies [reportId] (from its
35
+ // route) and switches reports by navigating — this component never picks one.
36
+ export class FsAiReportComponent {
37
+ // The report this view is focused on — supplied by the host from the route.
38
+ reportId = input(null);
39
+ // API base for the reports + chat endpoints; override to mount elsewhere.
40
+ basePath = input('reports');
41
+ // The report was deleted from its settings dialog — the host routes back to
42
+ // the listing.
43
+ deleted = output();
44
+ // The report was renamed (settings, or the agent) — the host can refresh a
45
+ // breadcrumb / document title.
46
+ renamed = output();
47
+ report = null;
48
+ editMode = false;
49
+ // The report-level filter toolbar (fs-filter). Rebuilt whenever the loaded
50
+ // report (and thus its groups) changes.
51
+ reportFilterConfig;
52
+ _split;
53
+ _chatPanel;
54
+ _reportData = inject(ReportData);
55
+ _filterState = inject(ReportFilterStateService);
56
+ _exportCollector = inject(ReportExportCollectorService);
57
+ _pptxService = inject(ReportPptxService);
58
+ _pdfService = inject(ReportPdfService);
59
+ _process = inject(FsProcess);
60
+ _dialog = inject(MatDialog);
61
+ _destroyRef = inject(DestroyRef);
62
+ _cdRef = inject(ChangeDetectorRef);
63
+ _zone = inject(NgZone);
64
+ constructor() {
65
+ // Point the shared data gateway at the configured base first (before any
66
+ // load below reads it).
67
+ effect(() => {
68
+ this._reportData.basePath = this.basePath();
69
+ });
70
+ // (Re)load whenever the host switches the report id.
71
+ effect(() => {
72
+ const reportId = this.reportId();
73
+ this.editMode = false;
74
+ if (reportId != null) {
75
+ this._loadReport(reportId);
76
+ }
77
+ else {
78
+ this.report = null;
79
+ this._buildReportConfig();
80
+ this._cdRef.markForCheck();
81
+ }
82
+ });
83
+ this._buildReportConfig();
84
+ }
85
+ toggleEditMode() {
86
+ this.editMode = !this.editMode;
87
+ }
88
+ // Report settings — name, page size, orientation, layout mode, delete. The
89
+ // dialog performs the delete itself; we react to what it reports back.
90
+ reportSettings() {
91
+ if (!this.report) {
92
+ return;
93
+ }
94
+ const reportId = this.report.id;
95
+ this._dialog.open(ReportSettingsComponent, {
96
+ data: { report: this.report },
97
+ width: '460px',
98
+ })
99
+ .afterClosed()
100
+ .pipe(takeUntilDestroyed(this._destroyRef))
101
+ .subscribe((result) => {
102
+ if (result?.action === 'deleted') {
103
+ this.deleted.emit(reportId);
104
+ return;
105
+ }
106
+ if (result?.action === 'saved') {
107
+ this._loadReport(reportId, true);
108
+ }
109
+ });
110
+ }
111
+ // Component settings — title, exact geometry, and the diagnostic views
112
+ // (SQL, config, filter wiring).
113
+ componentSettings(component) {
114
+ if (!this.report) {
115
+ return;
116
+ }
117
+ const reportId = this.report.id;
118
+ this._dialog.open(ComponentSettingsComponent, {
119
+ data: { report: this.report, component },
120
+ width: '640px',
121
+ })
122
+ .afterClosed()
123
+ .pipe(takeUntilDestroyed(this._destroyRef))
124
+ .subscribe(() => {
125
+ // Always reload: filter add/remove/level changes persist immediately
126
+ // inside the dialog (no "save"), so the canvas + report bar must
127
+ // refresh however the dialog was closed.
128
+ this._loadReport(reportId);
129
+ });
130
+ }
131
+ // The canvas changed the report's structure (added a page) — re-fetch so the
132
+ // new page renders; the canvas lands the view on it.
133
+ onCanvasReportChanged() {
134
+ if (this.report) {
135
+ this._loadReport(this.report.id);
136
+ }
137
+ }
138
+ // Export the report to PowerPoint, entirely client-side (native editable
139
+ // charts; page = slide). The dock shows progress until the file saves.
140
+ exportPowerpoint() {
141
+ if (!this.report) {
142
+ return;
143
+ }
144
+ const report = this.report;
145
+ this._process.run('Exporting PowerPoint', this._exportCollector.collect(report)
146
+ .pipe(switchMap((collected) => from(this._pptxService.export(collected)))));
147
+ }
148
+ // Export to PDF, entirely client-side (offscreen ECharts at 3×; page = PDF page).
149
+ exportPdf() {
150
+ if (!this.report) {
151
+ return;
152
+ }
153
+ const report = this.report;
154
+ this._process.run('Exporting PDF', this._exportCollector.collect(report)
155
+ .pipe(switchMap((collected) => from(this._pdfService.export(collected)))));
156
+ }
157
+ // React to each chat turn (fs-chat handles the request + persistence); we
158
+ // only care about the report side effects this context's backend flags.
159
+ onChatResponse(response) {
160
+ const reportId = this.reportId();
161
+ if (reportId == null) {
162
+ return;
163
+ }
164
+ const reportResponse = response;
165
+ // A structural change or a rename both re-fetch the report (session filter
166
+ // values survive); a rename additionally notifies the host so it can
167
+ // refresh a breadcrumb / title.
168
+ if (reportResponse.reportChanged || reportResponse.reportRenamed) {
169
+ this._loadReport(reportId, !!reportResponse.reportRenamed);
170
+ }
171
+ }
172
+ // Drag the divider between the chat and canvas panes (pointer-capture loop
173
+ // outside Angular).
174
+ onResizeStart(event) {
175
+ event.preventDefault();
176
+ const handle = event.target;
177
+ handle.setPointerCapture(event.pointerId);
178
+ this._split.nativeElement.classList.add('resizing');
179
+ this._zone.runOutsideAngular(() => {
180
+ const move = (e) => this._resizeTo(e.clientX);
181
+ const end = () => {
182
+ handle.releasePointerCapture(event.pointerId);
183
+ handle.removeEventListener('pointermove', move);
184
+ handle.removeEventListener('pointerup', end);
185
+ handle.removeEventListener('pointercancel', end);
186
+ this._split.nativeElement.classList.remove('resizing');
187
+ };
188
+ handle.addEventListener('pointermove', move);
189
+ handle.addEventListener('pointerup', end);
190
+ handle.addEventListener('pointercancel', end);
191
+ });
192
+ }
193
+ _resizeTo(clientX) {
194
+ const rect = this._split.nativeElement.getBoundingClientRect();
195
+ if (rect.width === 0) {
196
+ return;
197
+ }
198
+ const ratio = (clientX - rect.left) / rect.width;
199
+ const clamped = Math.min(0.8, Math.max(0.2, ratio));
200
+ this._chatPanel.nativeElement.style.flexBasis = `${clamped * 100}%`;
201
+ }
202
+ _loadReport(reportId, emitRenamed = false) {
203
+ this._reportData.get(reportId)
204
+ .pipe(takeUntilDestroyed(this._destroyRef))
205
+ .subscribe((report) => {
206
+ this.report = report;
207
+ this._filterState.init(report);
208
+ this._buildReportConfig();
209
+ if (emitRenamed) {
210
+ this.renamed.emit(report);
211
+ }
212
+ this._cdRef.markForCheck();
213
+ });
214
+ }
215
+ // Report-level filter groups in their saved order — the ones that render in
216
+ // the toolbar (component-level groups render on their components).
217
+ _reportGroups() {
218
+ return (this.report?.filterGroups ?? [])
219
+ .filter((group) => group.level === 'report' || group.level === 'both')
220
+ .sort((a, b) => a.order - b.order);
221
+ }
222
+ // Whether the loaded report has any report-level filters OR a time-series
223
+ // chart (which earns the runtime Frequency control) — gates the toolbar.
224
+ get reportHasFilters() {
225
+ return this._reportGroups().length > 0 || this._hasTimeSeriesChart();
226
+ }
227
+ // fs-filter reads its config only once (at init). The template keys the
228
+ // toolbar fs-filter on this signature so it's recreated (and re-reads the
229
+ // rebuilt config) whenever the report-level filter set changes.
230
+ get reportFilterKey() {
231
+ return [
232
+ ...this._reportGroups().map((group) => `${group.id}:${group.level}:${group.label}`),
233
+ this._hasTimeSeriesChart() ? 'frequency' : '',
234
+ ].join('|');
235
+ }
236
+ // (Re)build the toolbar fs-filter config — report-level filter items, plus
237
+ // the runtime Frequency control when the report has a time-series chart.
238
+ _buildReportConfig() {
239
+ const reportId = this.report?.id ?? null;
240
+ const items = reportId
241
+ ? this._reportGroups().map((group) => filterItemForGroup(group, this._reportData, reportId, this._filterState.value(group.id)))
242
+ : [];
243
+ if (reportId && this._hasTimeSeriesChart()) {
244
+ items.push({
245
+ name: FREQUENCY_ITEM,
246
+ type: ItemType.Select,
247
+ label: 'Frequency',
248
+ multiple: false,
249
+ values: () => FREQUENCY_OPTIONS,
250
+ default: this._filterState.frequency() ?? undefined,
251
+ });
252
+ }
253
+ this.reportFilterConfig = {
254
+ // Never touch the URL or persist filter state — report filters are
255
+ // session-only, owned by ReportFilterStateService.
256
+ queryParam: false,
257
+ persist: false,
258
+ items,
259
+ change: (query) => {
260
+ for (const { groupId, value } of groupValuesFromQuery(query ?? {}, this._reportGroups())) {
261
+ this._filterState.setValue(groupId, value);
262
+ }
263
+ // Frequency isn't a filter group — it's a render-layer bucket override.
264
+ this._filterState.setFrequency(query?.[FREQUENCY_ITEM] || null);
265
+ },
266
+ };
267
+ }
268
+ // The report has at least one time-series chart (x-axis is a time axis) — the
269
+ // only kind the Frequency control affects.
270
+ _hasTimeSeriesChart() {
271
+ return (this.report?.pages ?? []).some((page) => page.components.some((component) => component.type === 'chart' && component.config?.xAxis?.kind === 'time'));
272
+ }
273
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FsAiReportComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
274
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: FsAiReportComponent, isStandalone: true, selector: "fs-ai-report", inputs: { reportId: { classPropertyName: "reportId", publicName: "reportId", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { deleted: "deleted", renamed: "renamed" }, providers: [
275
+ // Session filter state is per-open-report, not app-global; the export
276
+ // services resolve filters through it, so they live at the same level.
277
+ ReportFilterStateService,
278
+ ReportExportCollectorService,
279
+ ReportPptxService,
280
+ ReportPdfService,
281
+ // Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
282
+ provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),
283
+ ], viewQueries: [{ propertyName: "_split", first: true, predicate: ["split"], descendants: true, static: true }, { propertyName: "_chatPanel", first: true, predicate: ["chatPanel"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<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 <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"editMode ? 'Done' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>{{ editMode ? 'lock' : 'open_with' }}</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 </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 <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"basePath()\"\n [requestData]=\"{ reportId: reportId() }\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the header\n above). fs-filter reads its config once at init, so it's keyed on\n the 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 [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n", styles: [".fs-ai-report{height:100%;min-height:500px;display:flex;flex-direction:column}.fs-ai-report__header{flex:0 0 auto;margin-bottom:10px}.fs-ai-report__title{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fs-ai-report__split{flex:1 1 auto;min-height:0}.fs-ai-report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:400px;min-width:0;border:none}.fs-ai-report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.fs-ai-report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.fs-ai-report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.fs-ai-report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.fs-ai-report .resizer:before{content:\"\";width:1px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.fs-ai-report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.fs-ai-report__split.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing .chat,.fs-ai-report__split.resizing .viewer{pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: FsFilterModule }, { kind: "component", type: i1.FilterComponent, selector: "fs-filter", inputs: ["config"], outputs: ["closed", "opened", "ready"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "component", type: FsAiChatComponent, selector: "fs-ai-chat", inputs: ["basePath", "requestData", "introMessage"], outputs: ["response"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: ReportCanvasComponent, selector: "app-report-canvas", inputs: ["report", "editMode"], outputs: ["componentSettings", "reportChanged", "editDone"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
284
+ }
285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: FsAiReportComponent, decorators: [{
286
+ type: Component,
287
+ args: [{ selector: 'fs-ai-report', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [
288
+ // Session filter state is per-open-report, not app-global; the export
289
+ // services resolve filters through it, so they live at the same level.
290
+ ReportFilterStateService,
291
+ ReportExportCollectorService,
292
+ ReportPptxService,
293
+ ReportPdfService,
294
+ // Tree-shaken ECharts core + the 'report' house theme, loaded lazily.
295
+ provideEchartsCore({ echarts: () => import('../../theme/echarts').then((module) => module.default) }),
296
+ ], imports: [
297
+ FsFilterModule,
298
+ FsMenuModule,
299
+ FsAiChatComponent,
300
+ MatButtonModule,
301
+ MatIconModule,
302
+ MatTooltipModule,
303
+ ReportCanvasComponent,
304
+ ], template: "<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 <button\n mat-icon-button\n type=\"button\"\n [matTooltip]=\"editMode ? 'Done' : 'Edit layout'\"\n (click)=\"toggleEditMode()\">\n <mat-icon>{{ editMode ? 'lock' : 'open_with' }}</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 </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 <fs-ai-chat\n #chatPanel\n class=\"chat\"\n [basePath]=\"basePath()\"\n [requestData]=\"{ reportId: reportId() }\"\n (response)=\"onChatResponse($event)\">\n </fs-ai-chat>\n\n <div\n class=\"resizer\"\n (pointerdown)=\"onResizeStart($event)\">\n </div>\n\n <div class=\"viewer fs-flex fs-column\">\n @if (report) {\n <!-- Report-level filters only (the report's actions live in the header\n above). fs-filter reads its config once at init, so it's keyed on\n the 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 [config]=\"reportFilterConfig\"></fs-filter>\n }\n }\n <app-report-canvas\n [report]=\"report\"\n [editMode]=\"editMode\"\n (componentSettings)=\"componentSettings($event)\"\n (reportChanged)=\"onCanvasReportChanged()\"\n (editDone)=\"toggleEditMode()\">\n </app-report-canvas>\n }\n </div>\n </div>\n</div>\n", styles: [".fs-ai-report{height:100%;min-height:500px;display:flex;flex-direction:column}.fs-ai-report__header{flex:0 0 auto;margin-bottom:10px}.fs-ai-report__title{margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fs-ai-report__split{flex:1 1 auto;min-height:0}.fs-ai-report .chat{display:block;flex:0 0 25%;width:100%;height:100%;min-height:400px;min-width:0;border:none}.fs-ai-report .viewer{display:flex;flex-direction:column;min-width:0;height:100%;overflow:hidden}.fs-ai-report .viewer fs-filter{flex:0 0 auto;margin-top:10px;margin-bottom:0}.fs-ai-report .viewer ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.fs-ai-report .resizer{flex:0 0 11px;align-self:stretch;display:flex;justify-content:center;cursor:col-resize;touch-action:none;-webkit-user-select:none;user-select:none}.fs-ai-report .resizer:before{content:\"\";width:1px;background:#0000001f;transition:width .12s ease,background-color .12s ease}.fs-ai-report .resizer:hover:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing{cursor:col-resize;-webkit-user-select:none;user-select:none}.fs-ai-report__split.resizing .resizer:before{width:3px;background:var(--brand-primary-color)}.fs-ai-report__split.resizing .chat,.fs-ai-report__split.resizing .viewer{pointer-events:none}\n"] }]
305
+ }], ctorParameters: () => [], propDecorators: { _split: [{
306
+ type: ViewChild,
307
+ args: ['split', { static: true }]
308
+ }], _chatPanel: [{
309
+ type: ViewChild,
310
+ args: ['chatPanel', { static: true, read: ElementRef }]
311
+ }] } });
312
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnMtYWktcmVwb3J0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvZnMtYWktcmVwb3J0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy92aWV3cy9yZXBvcnQvZnMtYWktcmVwb3J0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxzQkFBc0IsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQzdFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEdBQ3pFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTdELE9BQU8sRUFBZ0IsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFaEQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM1QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWpELE9BQU8sRUFBRSxpQkFBaUIsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUMvRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sK0RBQStELENBQUM7QUFDM0csT0FBTyxFQUFFLHVCQUF1QixFQUF3QixNQUFNLHlEQUF5RCxDQUFDO0FBQ3hILE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzVGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3JFLE9BQU8sRUFDYSxpQkFBaUIsR0FFcEMsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUNyRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQzs7Ozs7OztBQUd0RiwrRUFBK0U7QUFDL0UsdUVBQXVFO0FBQ3ZFLE1BQU0sY0FBYyxHQUFHLFdBQVcsQ0FBQztBQUVuQyw0RUFBNEU7QUFDNUUsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQTRCOUUsTUFBTSxPQUFPLG1CQUFtQjtJQUU5Qiw0RUFBNEU7SUFDNUQsUUFBUSxHQUFHLEtBQUssQ0FBZ0IsSUFBSSxDQUFDLENBQUM7SUFFdEQsMEVBQTBFO0lBQzFELFFBQVEsR0FBRyxLQUFLLENBQVMsU0FBUyxDQUFDLENBQUM7SUFFcEQsNEVBQTRFO0lBQzVFLGVBQWU7SUFDQyxPQUFPLEdBQUcsTUFBTSxFQUFVLENBQUM7SUFFM0MsMkVBQTJFO0lBQzNFLCtCQUErQjtJQUNmLE9BQU8sR0FBRyxNQUFNLEVBQVUsQ0FBQztJQUVwQyxNQUFNLEdBQWtCLElBQUksQ0FBQztJQUM3QixRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRXhCLDJFQUEyRTtJQUMzRSx3Q0FBd0M7SUFDakMsa0JBQWtCLENBQWdCO0lBR2pDLE1BQU0sQ0FBOEI7SUFHcEMsVUFBVSxDQUEyQjtJQUVyQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLFlBQVksR0FBRyxNQUFNLENBQUMsd0JBQXdCLENBQUMsQ0FBQztJQUNoRCxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUN4RCxZQUFZLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDekMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3ZDLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0IsT0FBTyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM1QixXQUFXLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUNuQyxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRS9CO1FBQ0UseUVBQXlFO1FBQ3pFLHdCQUF3QjtRQUN4QixNQUFNLENBQUMsR0FBRyxFQUFFO1lBQ1YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzlDLENBQUMsQ0FBQyxDQUFDO1FBRUgscURBQXFEO1FBQ3JELE1BQU0sQ0FBQyxHQUFHLEVBQUU7WUFDVixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7WUFFdEIsSUFBSSxRQUFRLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDN0IsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO2dCQUNuQixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUM3QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRU0sY0FBYztRQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLHVFQUF1RTtJQUNoRSxjQUFjO1FBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUVoQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBeUQsdUJBQXVCLEVBQUU7WUFDakcsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDN0IsS0FBSyxFQUFFLE9BQU87U0FDZixDQUFDO2FBQ0MsV0FBVyxFQUFFO2FBQ2IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUMxQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNwQixJQUFJLE1BQU0sRUFBRSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUU1QixPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksTUFBTSxFQUFFLE1BQU0sS0FBSyxPQUFPLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbkMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELHVFQUF1RTtJQUN2RSxnQ0FBZ0M7SUFDekIsaUJBQWlCLENBQUMsU0FBK0I7UUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNqQixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBRWhDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFO1lBQzVDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRTtZQUN4QyxLQUFLLEVBQUUsT0FBTztTQUNmLENBQUM7YUFDQyxXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQzFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZCxxRUFBcUU7WUFDckUsaUVBQWlFO1lBQ2pFLHlDQUF5QztZQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELDZFQUE2RTtJQUM3RSxxREFBcUQ7SUFDOUMscUJBQXFCO1FBQzFCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2hCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQUVELHlFQUF5RTtJQUN6RSx1RUFBdUU7SUFDaEUsZ0JBQWdCO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDakIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzNCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUNmLHNCQUFzQixFQUN0QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQzthQUNsQyxJQUFJLENBQ0gsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUNwRSxDQUNKLENBQUM7SUFDSixDQUFDO0lBRUQsa0ZBQWtGO0lBQzNFLFNBQVM7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2pCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FDZixlQUFlLEVBQ2YsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7YUFDbEMsSUFBSSxDQUNILFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FDbkUsQ0FDSixDQUFDO0lBQ0osQ0FBQztJQUVELDBFQUEwRTtJQUMxRSx3RUFBd0U7SUFDakUsY0FBYyxDQUFDLFFBQTBCO1FBQzlDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNqQyxJQUFJLFFBQVEsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNyQixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sY0FBYyxHQUFHLFFBQWlELENBQUM7UUFFekUsMkVBQTJFO1FBQzNFLHFFQUFxRTtRQUNyRSxnQ0FBZ0M7UUFDaEMsSUFBSSxjQUFjLENBQUMsYUFBYSxJQUFJLGNBQWMsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNqRSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdELENBQUM7SUFDSCxDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLG9CQUFvQjtJQUNiLGFBQWEsQ0FBQyxLQUFtQjtRQUN0QyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFdkIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQXFCLENBQUM7UUFDM0MsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXBELElBQUksQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQ2hDLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBZSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM1RCxNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7Z0JBQ2YsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDOUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDN0MsTUFBTSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6RCxDQUFDLENBQUM7WUFFRixNQUFNLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDMUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNoRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxTQUFTLENBQUMsT0FBZTtRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9ELElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNyQixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ2pELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxHQUFHLE9BQU8sR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUN0RSxDQUFDO0lBRU8sV0FBVyxDQUFDLFFBQWdCLEVBQUUsV0FBVyxHQUFHLEtBQUs7UUFDdkQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO2FBQzNCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDMUMsU0FBUyxDQUFDLENBQUMsTUFBYyxFQUFFLEVBQUU7WUFDNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7WUFDckIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFFMUIsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUIsQ0FBQztZQUVELElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsNEVBQTRFO0lBQzVFLG1FQUFtRTtJQUMzRCxhQUFhO1FBQ25CLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFlBQVksSUFBSSxFQUFFLENBQUM7YUFDckMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsS0FBSyxLQUFLLE1BQU0sQ0FBQzthQUNyRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsMEVBQTBFO0lBQzFFLHlFQUF5RTtJQUN6RSxJQUFXLGdCQUFnQjtRQUN6QixPQUFPLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQ3ZFLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsMEVBQTBFO0lBQzFFLGdFQUFnRTtJQUNoRSxJQUFXLGVBQWU7UUFDeEIsT0FBTztZQUNMLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25GLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUU7U0FDOUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDZCxDQUFDO0lBRUQsMkVBQTJFO0lBQzNFLHlFQUF5RTtJQUNqRSxrQkFBa0I7UUFDeEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDO1FBRXpDLE1BQU0sS0FBSyxHQUFHLFFBQVE7WUFDcEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNuQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0YsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUVQLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUM7WUFDM0MsS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDVCxJQUFJLEVBQUUsY0FBYztnQkFDcEIsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNO2dCQUNyQixLQUFLLEVBQUUsV0FBVztnQkFDbEIsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLGlCQUFpQjtnQkFDL0IsT0FBTyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLElBQUksU0FBUzthQUNwRCxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxDQUFDLGtCQUFrQixHQUFHO1lBQ3hCLG1FQUFtRTtZQUNuRSxtREFBbUQ7WUFDbkQsVUFBVSxFQUFFLEtBQUs7WUFDakIsT0FBTyxFQUFFLEtBQUs7WUFDZCxLQUFLO1lBQ0wsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ2hCLEtBQUssTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxvQkFBb0IsQ0FBQyxLQUFLLElBQUksRUFBRSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ3pGLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDN0MsQ0FBQztnQkFDRCx3RUFBd0U7Z0JBQ3hFLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFFLEtBQUssRUFBRSxDQUFDLGNBQWMsQ0FBc0IsSUFBSSxJQUFJLENBQUMsQ0FBQztZQUN4RixDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCw4RUFBOEU7SUFDOUUsMkNBQTJDO0lBQ25DLG1CQUFtQjtRQUN6QixPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNqQyxTQUFTLENBQUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMvRSxDQUFDO3dHQXpTVSxtQkFBbUI7NEZBQW5CLG1CQUFtQiw4WEFwQm5CO1lBQ1Qsc0VBQXNFO1lBQ3RFLHVFQUF1RTtZQUN2RSx3QkFBd0I7WUFDeEIsNEJBQTRCO1lBQzVCLGlCQUFpQjtZQUNqQixnQkFBZ0I7WUFDaEIsc0VBQXNFO1lBQ3RFLGtCQUFrQixDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7U0FDdEcsOE1BcUM2QyxVQUFVLDJDQ2pHMUQsMjhFQWtGQSx5MUNEcEJJLGNBQWMsa0tBQ2QsWUFBWSx3WkFDWixpQkFBaUIsa0lBQ2pCLGVBQWUsMklBQ2YsYUFBYSxtTEFDYixnQkFBZ0IsNlRBQ2hCLHFCQUFxQjs7NEZBR1osbUJBQW1CO2tCQTNCL0IsU0FBUzsrQkFDRSxjQUFjLG1CQUdQLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQLENBQUMsc0JBQXNCLENBQUMsYUFDdEI7d0JBQ1Qsc0VBQXNFO3dCQUN0RSx1RUFBdUU7d0JBQ3ZFLHdCQUF3Qjt3QkFDeEIsNEJBQTRCO3dCQUM1QixpQkFBaUI7d0JBQ2pCLGdCQUFnQjt3QkFDaEIsc0VBQXNFO3dCQUN0RSxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3FCQUN0RyxXQUNRO3dCQUNQLGNBQWM7d0JBQ2QsWUFBWTt3QkFDWixpQkFBaUI7d0JBQ2pCLGVBQWU7d0JBQ2YsYUFBYTt3QkFDYixnQkFBZ0I7d0JBQ2hCLHFCQUFxQjtxQkFDdEI7d0RBMEJPLE1BQU07c0JBRGIsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUk1QixVQUFVO3NCQURqQixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENVU1RPTV9FTEVNRU5UU19TQ0hFTUEsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLCBFbGVtZW50UmVmLCBOZ1pvbmUsIFZpZXdDaGlsZCwgZWZmZWN0LCBpbmplY3QsIGlucHV0LCBvdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuXG5pbXBvcnQgeyBNYXRCdXR0b25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRvb2x0aXBNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcblxuaW1wb3J0IHsgRmlsdGVyQ29uZmlnLCBGc0ZpbHRlck1vZHVsZSwgSXRlbVR5cGUgfSBmcm9tICdAZmlyZXN0aXRjaC9maWx0ZXInO1xuaW1wb3J0IHsgRnNNZW51TW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVudSc7XG5pbXBvcnQgeyBGc1Byb2Nlc3MgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9jZXNzJztcblxuaW1wb3J0IHsgZnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBwcm92aWRlRWNoYXJ0c0NvcmUgfSBmcm9tICduZ3gtZWNoYXJ0cyc7XG5cbmltcG9ydCB7IEZzQWlDaGF0Q29tcG9uZW50LCBGc0FpQ2hhdFJlc3BvbnNlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYWknO1xuXG5pbXBvcnQgeyBSZXBvcnRDYW52YXNDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL3JlcG9ydC1jYW52YXMvcmVwb3J0LWNhbnZhcy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgQ29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50JztcbmltcG9ydCB7IFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCBSZXBvcnRTZXR0aW5nc1Jlc3VsdCB9IGZyb20gJy4uLy4uL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSB9IGZyb20gJy4uLy4uL2V4cG9ydC9yZXBvcnQtZXhwb3J0LWNvbGxlY3Rvci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBkZlNlcnZpY2UgfSBmcm9tICcuLi8uLi9leHBvcnQvcmVwb3J0LXBkZi5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFBwdHhTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vZXhwb3J0L3JlcG9ydC1wcHR4LnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSwgRlJFUVVFTkNZX09QVElPTlMsIFJlcG9ydCwgUmVwb3J0Q2hhdFJlc3BvbnNlLFxuICBSZXBvcnRDb21wb25lbnQgYXMgUmVwb3J0Q29tcG9uZW50TW9kZWwsIFJlcG9ydEZpbHRlckdyb3VwLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgZmlsdGVySXRlbUZvckdyb3VwLCBncm91cFZhbHVlc0Zyb21RdWVyeSB9IGZyb20gJy4uLy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvcmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlJztcblxuXG4vLyBmcy1maWx0ZXIgcXVlcnkga2V5IGZvciB0aGUgcnVudGltZSBGcmVxdWVuY3kgY29udHJvbCAoYSByZW5kZXItbGF5ZXIgYnVja2V0XG4vLyBvdmVycmlkZSwgbm90IGEgZmlsdGVyIGdyb3VwIOKAlCBzbyBpdCdzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBxdWVyeSkuXG5jb25zdCBGUkVRVUVOQ1lfSVRFTSA9ICdmcmVxdWVuY3knO1xuXG4vLyBBIHNpbmdsZSByZXBvcnQ6IHRoZSBBSSBjaGF0IG9uIHRoZSBsZWZ0LCB0aGUgcmVwb3J0IGNhbnZhcyBvbiB0aGUgcmlnaHQsXG4vLyB1bmRlciBhbiBIMiB0aXRsZSArIHNldHRpbmdzIGdlYXIuIFRoZSBob3N0IHN1cHBsaWVzIFtyZXBvcnRJZF0gKGZyb20gaXRzXG4vLyByb3V0ZSkgYW5kIHN3aXRjaGVzIHJlcG9ydHMgYnkgbmF2aWdhdGluZyDigJQgdGhpcyBjb21wb25lbnQgbmV2ZXIgcGlja3Mgb25lLlxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZnMtYWktcmVwb3J0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZzLWFpLXJlcG9ydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZzLWFpLXJlcG9ydC5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgc2NoZW1hczogW0NVU1RPTV9FTEVNRU5UU19TQ0hFTUFdLFxuICBwcm92aWRlcnM6IFtcbiAgICAvLyBTZXNzaW9uIGZpbHRlciBzdGF0ZSBpcyBwZXItb3Blbi1yZXBvcnQsIG5vdCBhcHAtZ2xvYmFsOyB0aGUgZXhwb3J0XG4gICAgLy8gc2VydmljZXMgcmVzb2x2ZSBmaWx0ZXJzIHRocm91Z2ggaXQsIHNvIHRoZXkgbGl2ZSBhdCB0aGUgc2FtZSBsZXZlbC5cbiAgICBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2UsXG4gICAgUmVwb3J0RXhwb3J0Q29sbGVjdG9yU2VydmljZSxcbiAgICBSZXBvcnRQcHR4U2VydmljZSxcbiAgICBSZXBvcnRQZGZTZXJ2aWNlLFxuICAgIC8vIFRyZWUtc2hha2VuIEVDaGFydHMgY29yZSArIHRoZSAncmVwb3J0JyBob3VzZSB0aGVtZSwgbG9hZGVkIGxhemlseS5cbiAgICBwcm92aWRlRWNoYXJ0c0NvcmUoeyBlY2hhcnRzOiAoKSA9PiBpbXBvcnQoJy4uLy4uL3RoZW1lL2VjaGFydHMnKS50aGVuKChtb2R1bGUpID0+IG1vZHVsZS5kZWZhdWx0KSB9KSxcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIEZzRmlsdGVyTW9kdWxlLFxuICAgIEZzTWVudU1vZHVsZSxcbiAgICBGc0FpQ2hhdENvbXBvbmVudCxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gICAgTWF0SWNvbk1vZHVsZSxcbiAgICBNYXRUb29sdGlwTW9kdWxlLFxuICAgIFJlcG9ydENhbnZhc0NvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRnNBaVJlcG9ydENvbXBvbmVudCB7XG5cbiAgLy8gVGhlIHJlcG9ydCB0aGlzIHZpZXcgaXMgZm9jdXNlZCBvbiDigJQgc3VwcGxpZWQgYnkgdGhlIGhvc3QgZnJvbSB0aGUgcm91dGUuXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnRJZCA9IGlucHV0PG51bWJlciB8IG51bGw+KG51bGwpO1xuXG4gIC8vIEFQSSBiYXNlIGZvciB0aGUgcmVwb3J0cyArIGNoYXQgZW5kcG9pbnRzOyBvdmVycmlkZSB0byBtb3VudCBlbHNld2hlcmUuXG4gIHB1YmxpYyByZWFkb25seSBiYXNlUGF0aCA9IGlucHV0PHN0cmluZz4oJ3JlcG9ydHMnKTtcblxuICAvLyBUaGUgcmVwb3J0IHdhcyBkZWxldGVkIGZyb20gaXRzIHNldHRpbmdzIGRpYWxvZyDigJQgdGhlIGhvc3Qgcm91dGVzIGJhY2sgdG9cbiAgLy8gdGhlIGxpc3RpbmcuXG4gIHB1YmxpYyByZWFkb25seSBkZWxldGVkID0gb3V0cHV0PG51bWJlcj4oKTtcblxuICAvLyBUaGUgcmVwb3J0IHdhcyByZW5hbWVkIChzZXR0aW5ncywgb3IgdGhlIGFnZW50KSDigJQgdGhlIGhvc3QgY2FuIHJlZnJlc2ggYVxuICAvLyBicmVhZGNydW1iIC8gZG9jdW1lbnQgdGl0bGUuXG4gIHB1YmxpYyByZWFkb25seSByZW5hbWVkID0gb3V0cHV0PFJlcG9ydD4oKTtcblxuICBwdWJsaWMgcmVwb3J0OiBSZXBvcnQgfCBudWxsID0gbnVsbDtcbiAgcHVibGljIGVkaXRNb2RlID0gZmFsc2U7XG5cbiAgLy8gVGhlIHJlcG9ydC1sZXZlbCBmaWx0ZXIgdG9vbGJhciAoZnMtZmlsdGVyKS4gUmVidWlsdCB3aGVuZXZlciB0aGUgbG9hZGVkXG4gIC8vIHJlcG9ydCAoYW5kIHRodXMgaXRzIGdyb3VwcykgY2hhbmdlcy5cbiAgcHVibGljIHJlcG9ydEZpbHRlckNvbmZpZyE6IEZpbHRlckNvbmZpZztcblxuICBAVmlld0NoaWxkKCdzcGxpdCcsIHsgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgX3NwbGl0ITogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZCgnY2hhdFBhbmVsJywgeyBzdGF0aWM6IHRydWUsIHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgcHJpdmF0ZSBfY2hhdFBhbmVsITogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XG5cbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfZXhwb3J0Q29sbGVjdG9yID0gaW5qZWN0KFJlcG9ydEV4cG9ydENvbGxlY3RvclNlcnZpY2UpO1xuICBwcml2YXRlIF9wcHR4U2VydmljZSA9IGluamVjdChSZXBvcnRQcHR4U2VydmljZSk7XG4gIHByaXZhdGUgX3BkZlNlcnZpY2UgPSBpbmplY3QoUmVwb3J0UGRmU2VydmljZSk7XG4gIHByaXZhdGUgX3Byb2Nlc3MgPSBpbmplY3QoRnNQcm9jZXNzKTtcbiAgcHJpdmF0ZSBfZGlhbG9nID0gaW5qZWN0KE1hdERpYWxvZyk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgX2NkUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHJpdmF0ZSBfem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIFBvaW50IHRoZSBzaGFyZWQgZGF0YSBnYXRld2F5IGF0IHRoZSBjb25maWd1cmVkIGJhc2UgZmlyc3QgKGJlZm9yZSBhbnlcbiAgICAvLyBsb2FkIGJlbG93IHJlYWRzIGl0KS5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgdGhpcy5fcmVwb3J0RGF0YS5iYXNlUGF0aCA9IHRoaXMuYmFzZVBhdGgoKTtcbiAgICB9KTtcblxuICAgIC8vIChSZSlsb2FkIHdoZW5ldmVyIHRoZSBob3N0IHN3aXRjaGVzIHRoZSByZXBvcnQgaWQuXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnRJZCgpO1xuICAgICAgdGhpcy5lZGl0TW9kZSA9IGZhbHNlO1xuXG4gICAgICBpZiAocmVwb3J0SWQgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydElkKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVwb3J0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fYnVpbGRSZXBvcnRDb25maWcoKTtcbiAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUVkaXRNb2RlKCk6IHZvaWQge1xuICAgIHRoaXMuZWRpdE1vZGUgPSAhdGhpcy5lZGl0TW9kZTtcbiAgfVxuXG4gIC8vIFJlcG9ydCBzZXR0aW5ncyDigJQgbmFtZSwgcGFnZSBzaXplLCBvcmllbnRhdGlvbiwgbGF5b3V0IG1vZGUsIGRlbGV0ZS4gVGhlXG4gIC8vIGRpYWxvZyBwZXJmb3JtcyB0aGUgZGVsZXRlIGl0c2VsZjsgd2UgcmVhY3QgdG8gd2hhdCBpdCByZXBvcnRzIGJhY2suXG4gIHB1YmxpYyByZXBvcnRTZXR0aW5ncygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmVwb3J0SWQgPSB0aGlzLnJlcG9ydC5pZDtcblxuICAgIHRoaXMuX2RpYWxvZy5vcGVuPFJlcG9ydFNldHRpbmdzQ29tcG9uZW50LCB1bmtub3duLCBSZXBvcnRTZXR0aW5nc1Jlc3VsdD4oUmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIHtcbiAgICAgIGRhdGE6IHsgcmVwb3J0OiB0aGlzLnJlcG9ydCB9LFxuICAgICAgd2lkdGg6ICc0NjBweCcsXG4gICAgfSlcbiAgICAgIC5hZnRlckNsb3NlZCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdD8uYWN0aW9uID09PSAnZGVsZXRlZCcpIHtcbiAgICAgICAgICB0aGlzLmRlbGV0ZWQuZW1pdChyZXBvcnRJZCk7XG5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0Py5hY3Rpb24gPT09ICdzYXZlZCcpIHtcbiAgICAgICAgICB0aGlzLl9sb2FkUmVwb3J0KHJlcG9ydElkLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBDb21wb25lbnQgc2V0dGluZ3Mg4oCUIHRpdGxlLCBleGFjdCBnZW9tZXRyeSwgYW5kIHRoZSBkaWFnbm9zdGljIHZpZXdzXG4gIC8vIChTUUwsIGNvbmZpZywgZmlsdGVyIHdpcmluZykuXG4gIHB1YmxpYyBjb21wb25lbnRTZXR0aW5ncyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudE1vZGVsKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnQuaWQ7XG5cbiAgICB0aGlzLl9kaWFsb2cub3BlbihDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwge1xuICAgICAgZGF0YTogeyByZXBvcnQ6IHRoaXMucmVwb3J0LCBjb21wb25lbnQgfSxcbiAgICAgIHdpZHRoOiAnNjQwcHgnLFxuICAgIH0pXG4gICAgICAuYWZ0ZXJDbG9zZWQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIC8vIEFsd2F5cyByZWxvYWQ6IGZpbHRlciBhZGQvcmVtb3ZlL2xldmVsIGNoYW5nZXMgcGVyc2lzdCBpbW1lZGlhdGVseVxuICAgICAgICAvLyBpbnNpZGUgdGhlIGRpYWxvZyAobm8gXCJzYXZlXCIpLCBzbyB0aGUgY2FudmFzICsgcmVwb3J0IGJhciBtdXN0XG4gICAgICAgIC8vIHJlZnJlc2ggaG93ZXZlciB0aGUgZGlhbG9nIHdhcyBjbG9zZWQuXG4gICAgICAgIHRoaXMuX2xvYWRSZXBvcnQocmVwb3J0SWQpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBUaGUgY2FudmFzIGNoYW5nZWQgdGhlIHJlcG9ydCdzIHN0cnVjdHVyZSAoYWRkZWQgYSBwYWdlKSDigJQgcmUtZmV0Y2ggc28gdGhlXG4gIC8vIG5ldyBwYWdlIHJlbmRlcnM7IHRoZSBjYW52YXMgbGFuZHMgdGhlIHZpZXcgb24gaXQuXG4gIHB1YmxpYyBvbkNhbnZhc1JlcG9ydENoYW5nZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVwb3J0KSB7XG4gICAgICB0aGlzLl9sb2FkUmVwb3J0KHRoaXMucmVwb3J0LmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBFeHBvcnQgdGhlIHJlcG9ydCB0byBQb3dlclBvaW50LCBlbnRpcmVseSBjbGllbnQtc2lkZSAobmF0aXZlIGVkaXRhYmxlXG4gIC8vIGNoYXJ0czsgcGFnZSA9IHNsaWRlKS4gVGhlIGRvY2sgc2hvd3MgcHJvZ3Jlc3MgdW50aWwgdGhlIGZpbGUgc2F2ZXMuXG4gIHB1YmxpYyBleHBvcnRQb3dlcnBvaW50KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5yZXBvcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXBvcnQgPSB0aGlzLnJlcG9ydDtcbiAgICB0aGlzLl9wcm9jZXNzLnJ1bihcbiAgICAgICdFeHBvcnRpbmcgUG93ZXJQb2ludCcsXG4gICAgICB0aGlzLl9leHBvcnRDb2xsZWN0b3IuY29sbGVjdChyZXBvcnQpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHN3aXRjaE1hcCgoY29sbGVjdGVkKSA9PiBmcm9tKHRoaXMuX3BwdHhTZXJ2aWNlLmV4cG9ydChjb2xsZWN0ZWQpKSksXG4gICAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8vIEV4cG9ydCB0byBQREYsIGVudGlyZWx5IGNsaWVudC1zaWRlIChvZmZzY3JlZW4gRUNoYXJ0cyBhdCAzw5c7IHBhZ2UgPSBQREYgcGFnZSkuXG4gIHB1YmxpYyBleHBvcnRQZGYoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMucmVwb3J0O1xuICAgIHRoaXMuX3Byb2Nlc3MucnVuKFxuICAgICAgJ0V4cG9ydGluZyBQREYnLFxuICAgICAgdGhpcy5fZXhwb3J0Q29sbGVjdG9yLmNvbGxlY3QocmVwb3J0KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKGNvbGxlY3RlZCkgPT4gZnJvbSh0aGlzLl9wZGZTZXJ2aWNlLmV4cG9ydChjb2xsZWN0ZWQpKSksXG4gICAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlYWN0IHRvIGVhY2ggY2hhdCB0dXJuIChmcy1jaGF0IGhhbmRsZXMgdGhlIHJlcXVlc3QgKyBwZXJzaXN0ZW5jZSk7IHdlXG4gIC8vIG9ubHkgY2FyZSBhYm91dCB0aGUgcmVwb3J0IHNpZGUgZWZmZWN0cyB0aGlzIGNvbnRleHQncyBiYWNrZW5kIGZsYWdzLlxuICBwdWJsaWMgb25DaGF0UmVzcG9uc2UocmVzcG9uc2U6IEZzQWlDaGF0UmVzcG9uc2UpOiB2b2lkIHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMucmVwb3J0SWQoKTtcbiAgICBpZiAocmVwb3J0SWQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcG9ydFJlc3BvbnNlID0gcmVzcG9uc2UgYXMgRnNBaUNoYXRSZXNwb25zZSAmIFJlcG9ydENoYXRSZXNwb25zZTtcblxuICAgIC8vIEEgc3RydWN0dXJhbCBjaGFuZ2Ugb3IgYSByZW5hbWUgYm90aCByZS1mZXRjaCB0aGUgcmVwb3J0IChzZXNzaW9uIGZpbHRlclxuICAgIC8vIHZhbHVlcyBzdXJ2aXZlKTsgYSByZW5hbWUgYWRkaXRpb25hbGx5IG5vdGlmaWVzIHRoZSBob3N0IHNvIGl0IGNhblxuICAgIC8vIHJlZnJlc2ggYSBicmVhZGNydW1iIC8gdGl0bGUuXG4gICAgaWYgKHJlcG9ydFJlc3BvbnNlLnJlcG9ydENoYW5nZWQgfHwgcmVwb3J0UmVzcG9uc2UucmVwb3J0UmVuYW1lZCkge1xuICAgICAgdGhpcy5fbG9hZFJlcG9ydChyZXBvcnRJZCwgISFyZXBvcnRSZXNwb25zZS5yZXBvcnRSZW5hbWVkKTtcbiAgICB9XG4gIH1cblxuICAvLyBEcmFnIHRoZSBkaXZpZGVyIGJldHdlZW4gdGhlIGNoYXQgYW5kIGNhbnZhcyBwYW5lcyAocG9pbnRlci1jYXB0dXJlIGxvb3BcbiAgLy8gb3V0c2lkZSBBbmd1bGFyKS5cbiAgcHVibGljIG9uUmVzaXplU3RhcnQoZXZlbnQ6IFBvaW50ZXJFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG4gICAgdGhpcy5fc3BsaXQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdyZXNpemluZycpO1xuXG4gICAgdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICBjb25zdCBtb3ZlID0gKGU6IFBvaW50ZXJFdmVudCkgPT4gdGhpcy5fcmVzaXplVG8oZS5jbGllbnRYKTtcbiAgICAgIGNvbnN0IGVuZCA9ICgpID0+IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuICAgICAgICBoYW5kbGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICAgICAgdGhpcy5fc3BsaXQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdyZXNpemluZycpO1xuICAgICAgfTtcblxuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3Jlc2l6ZVRvKGNsaWVudFg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlY3QgPSB0aGlzLl9zcGxpdC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGlmIChyZWN0LndpZHRoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmF0aW8gPSAoY2xpZW50WCAtIHJlY3QubGVmdCkgLyByZWN0LndpZHRoO1xuICAgIGNvbnN0IGNsYW1wZWQgPSBNYXRoLm1pbigwLjgsIE1hdGgubWF4KDAuMiwgcmF0aW8pKTtcbiAgICB0aGlzLl9jaGF0UGFuZWwubmF0aXZlRWxlbWVudC5zdHlsZS5mbGV4QmFzaXMgPSBgJHtjbGFtcGVkICogMTAwfSVgO1xuICB9XG5cbiAgcHJpdmF0ZSBfbG9hZFJlcG9ydChyZXBvcnRJZDogbnVtYmVyLCBlbWl0UmVuYW1lZCA9IGZhbHNlKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5nZXQocmVwb3J0SWQpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChyZXBvcnQ6IFJlcG9ydCkgPT4ge1xuICAgICAgICB0aGlzLnJlcG9ydCA9IHJlcG9ydDtcbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuaW5pdChyZXBvcnQpO1xuICAgICAgICB0aGlzLl9idWlsZFJlcG9ydENvbmZpZygpO1xuXG4gICAgICAgIGlmIChlbWl0UmVuYW1lZCkge1xuICAgICAgICAgIHRoaXMucmVuYW1lZC5lbWl0KHJlcG9ydCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmVwb3J0LWxldmVsIGZpbHRlciBncm91cHMgaW4gdGhlaXIgc2F2ZWQgb3JkZXIg4oCUIHRoZSBvbmVzIHRoYXQgcmVuZGVyIGluXG4gIC8vIHRoZSB0b29sYmFyIChjb21wb25lbnQtbGV2ZWwgZ3JvdXBzIHJlbmRlciBvbiB0aGVpciBjb21wb25lbnRzKS5cbiAgcHJpdmF0ZSBfcmVwb3J0R3JvdXBzKCk6IFJlcG9ydEZpbHRlckdyb3VwW10ge1xuICAgIHJldHVybiAodGhpcy5yZXBvcnQ/LmZpbHRlckdyb3VwcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5sZXZlbCA9PT0gJ3JlcG9ydCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJylcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBsb2FkZWQgcmVwb3J0IGhhcyBhbnkgcmVwb3J0LWxldmVsIGZpbHRlcnMgT1IgYSB0aW1lLXNlcmllc1xuICAvLyBjaGFydCAod2hpY2ggZWFybnMgdGhlIHJ1bnRpbWUgRnJlcXVlbmN5IGNvbnRyb2wpIOKAlCBnYXRlcyB0aGUgdG9vbGJhci5cbiAgcHVibGljIGdldCByZXBvcnRIYXNGaWx0ZXJzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9yZXBvcnRHcm91cHMoKS5sZW5ndGggPiAwIHx8IHRoaXMuX2hhc1RpbWVTZXJpZXNDaGFydCgpO1xuICB9XG5cbiAgLy8gZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25seSBvbmNlIChhdCBpbml0KS4gVGhlIHRlbXBsYXRlIGtleXMgdGhlXG4gIC8vIHRvb2xiYXIgZnMtZmlsdGVyIG9uIHRoaXMgc2lnbmF0dXJlIHNvIGl0J3MgcmVjcmVhdGVkIChhbmQgcmUtcmVhZHMgdGhlXG4gIC8vIHJlYnVpbHQgY29uZmlnKSB3aGVuZXZlciB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcy5cbiAgcHVibGljIGdldCByZXBvcnRGaWx0ZXJLZXkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gW1xuICAgICAgLi4udGhpcy5fcmVwb3J0R3JvdXBzKCkubWFwKChncm91cCkgPT4gYCR7Z3JvdXAuaWR9OiR7Z3JvdXAubGV2ZWx9OiR7Z3JvdXAubGFiZWx9YCksXG4gICAgICB0aGlzLl9oYXNUaW1lU2VyaWVzQ2hhcnQoKSA/ICdmcmVxdWVuY3knIDogJycsXG4gICAgXS5qb2luKCd8Jyk7XG4gIH1cblxuICAvLyAoUmUpYnVpbGQgdGhlIHRvb2xiYXIgZnMtZmlsdGVyIGNvbmZpZyDigJQgcmVwb3J0LWxldmVsIGZpbHRlciBpdGVtcywgcGx1c1xuICAvLyB0aGUgcnVudGltZSBGcmVxdWVuY3kgY29udHJvbCB3aGVuIHRoZSByZXBvcnQgaGFzIGEgdGltZS1zZXJpZXMgY2hhcnQuXG4gIHByaXZhdGUgX2J1aWxkUmVwb3J0Q29uZmlnKCk6IHZvaWQge1xuICAgIGNvbnN0IHJlcG9ydElkID0gdGhpcy5yZXBvcnQ/LmlkID8/IG51bGw7XG5cbiAgICBjb25zdCBpdGVtcyA9IHJlcG9ydElkXG4gICAgICA/IHRoaXMuX3JlcG9ydEdyb3VwcygpLm1hcCgoZ3JvdXApID0+XG4gICAgICAgIGZpbHRlckl0ZW1Gb3JHcm91cChncm91cCwgdGhpcy5fcmVwb3J0RGF0YSwgcmVwb3J0SWQsIHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSkpXG4gICAgICA6IFtdO1xuXG4gICAgaWYgKHJlcG9ydElkICYmIHRoaXMuX2hhc1RpbWVTZXJpZXNDaGFydCgpKSB7XG4gICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgbmFtZTogRlJFUVVFTkNZX0lURU0sXG4gICAgICAgIHR5cGU6IEl0ZW1UeXBlLlNlbGVjdCxcbiAgICAgICAgbGFiZWw6ICdGcmVxdWVuY3knLFxuICAgICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlczogKCkgPT4gRlJFUVVFTkNZX09QVElPTlMsXG4gICAgICAgIGRlZmF1bHQ6IHRoaXMuX2ZpbHRlclN0YXRlLmZyZXF1ZW5jeSgpID8/IHVuZGVmaW5lZCxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucmVwb3J0RmlsdGVyQ29uZmlnID0ge1xuICAgICAgLy8gTmV2ZXIgdG91Y2ggdGhlIFVSTCBvciBwZXJzaXN0IGZpbHRlciBzdGF0ZSDigJQgcmVwb3J0IGZpbHRlcnMgYXJlXG4gICAgICAvLyBzZXNzaW9uLW9ubHksIG93bmVkIGJ5IFJlcG9ydEZpbHRlclN0YXRlU2VydmljZS5cbiAgICAgIHF1ZXJ5UGFyYW06IGZhbHNlLFxuICAgICAgcGVyc2lzdDogZmFsc2UsXG4gICAgICBpdGVtcyxcbiAgICAgIGNoYW5nZTogKHF1ZXJ5KSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgeyBncm91cElkLCB2YWx1ZSB9IG9mIGdyb3VwVmFsdWVzRnJvbVF1ZXJ5KHF1ZXJ5ID8/IHt9LCB0aGlzLl9yZXBvcnRHcm91cHMoKSkpIHtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRWYWx1ZShncm91cElkLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRnJlcXVlbmN5IGlzbid0IGEgZmlsdGVyIGdyb3VwIOKAlCBpdCdzIGEgcmVuZGVyLWxheWVyIGJ1Y2tldCBvdmVycmlkZS5cbiAgICAgICAgdGhpcy5fZmlsdGVyU3RhdGUuc2V0RnJlcXVlbmN5KChxdWVyeT8uW0ZSRVFVRU5DWV9JVEVNXSBhcyBDaGFydEdyYW51bGFyaXR5KSB8fCBudWxsKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8vIFRoZSByZXBvcnQgaGFzIGF0IGxlYXN0IG9uZSB0aW1lLXNlcmllcyBjaGFydCAoeC1heGlzIGlzIGEgdGltZSBheGlzKSDigJQgdGhlXG4gIC8vIG9ubHkga2luZCB0aGUgRnJlcXVlbmN5IGNvbnRyb2wgYWZmZWN0cy5cbiAgcHJpdmF0ZSBfaGFzVGltZVNlcmllc0NoYXJ0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAodGhpcy5yZXBvcnQ/LnBhZ2VzID8/IFtdKS5zb21lKChwYWdlKSA9PlxuICAgICAgcGFnZS5jb21wb25lbnRzLnNvbWUoKGNvbXBvbmVudCkgPT5cbiAgICAgICAgY29tcG9uZW50LnR5cGUgPT09ICdjaGFydCcgJiYgY29tcG9uZW50LmNvbmZpZz8ueEF4aXM/LmtpbmQgPT09ICd0aW1lJykpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZnMtYWktcmVwb3J0IGZzLWNvbHVtblwiPlxuXG4gIDxkaXYgY2xhc3M9XCJmcy1haS1yZXBvcnRfX2hlYWRlciBmcy1yb3cuYWxpZ24tY2VudGVyXCI+XG4gICAgPGgyIGNsYXNzPVwiZnMtYWktcmVwb3J0X190aXRsZSBmcy1mbGV4XCI+e3sgcmVwb3J0Py5uYW1lIH19PC9oMj5cblxuICAgIEBpZiAocmVwb3J0KSB7XG4gICAgICA8YnV0dG9uXG4gICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiZWRpdE1vZGUgPyAnRG9uZScgOiAnRWRpdCBsYXlvdXQnXCJcbiAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlRWRpdE1vZGUoKVwiPlxuICAgICAgICA8bWF0LWljb24+e3sgZWRpdE1vZGUgPyAnbG9jaycgOiAnb3Blbl93aXRoJyB9fTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG1hdFRvb2x0aXA9XCJFeHBvcnRcIlxuICAgICAgICAgIFtmc01lbnVUcmlnZ2VyRm9yXT1cImV4cG9ydE1lbnVcIj5cbiAgICAgICAgPG1hdC1pY29uPmRvd25sb2FkPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGZzLW1lbnUgI2V4cG9ydE1lbnU+XG4gICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAoY2xpY2spPVwiZXhwb3J0UG93ZXJwb2ludCgpXCI+XG4gICAgICAgICAgRXhwb3J0IFBvd2VyUG9pbnRcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgIChjbGljayk9XCJleHBvcnRQZGYoKVwiPlxuICAgICAgICAgIEV4cG9ydCBQREZcbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvZnMtbWVudT5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG1hdFRvb2x0aXA9XCJSZXBvcnQgc2V0dGluZ3NcIlxuICAgICAgICAgIChjbGljayk9XCJyZXBvcnRTZXR0aW5ncygpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5zZXR0aW5nczwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICB9XG4gIDwvZGl2PlxuXG4gIDxkaXZcbiAgICAgICNzcGxpdFxuICAgICAgY2xhc3M9XCJmcy1haS1yZXBvcnRfX3NwbGl0IGZzLXJvdy5hbGlnbi1zdGFydFwiPlxuICAgIDxmcy1haS1jaGF0XG4gICAgICAgICNjaGF0UGFuZWxcbiAgICAgICAgY2xhc3M9XCJjaGF0XCJcbiAgICAgICAgW2Jhc2VQYXRoXT1cImJhc2VQYXRoKClcIlxuICAgICAgICBbcmVxdWVzdERhdGFdPVwieyByZXBvcnRJZDogcmVwb3J0SWQoKSB9XCJcbiAgICAgICAgKHJlc3BvbnNlKT1cIm9uQ2hhdFJlc3BvbnNlKCRldmVudClcIj5cbiAgICA8L2ZzLWFpLWNoYXQ+XG5cbiAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwicmVzaXplclwiXG4gICAgICAgIChwb2ludGVyZG93bik9XCJvblJlc2l6ZVN0YXJ0KCRldmVudClcIj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJ2aWV3ZXIgZnMtZmxleCBmcy1jb2x1bW5cIj5cbiAgICAgIEBpZiAocmVwb3J0KSB7XG4gICAgICAgIDwhLS0gUmVwb3J0LWxldmVsIGZpbHRlcnMgb25seSAodGhlIHJlcG9ydCdzIGFjdGlvbnMgbGl2ZSBpbiB0aGUgaGVhZGVyXG4gICAgICAgICAgICAgYWJvdmUpLiBmcy1maWx0ZXIgcmVhZHMgaXRzIGNvbmZpZyBvbmNlIGF0IGluaXQsIHNvIGl0J3Mga2V5ZWQgb25cbiAgICAgICAgICAgICB0aGUgZmlsdGVyIHNpZ25hdHVyZTogd2hlbiB0aGUgcmVwb3J0LWxldmVsIGZpbHRlciBzZXQgY2hhbmdlcyB0aGVcbiAgICAgICAgICAgICBibG9jayBpcyByZWNyZWF0ZWQgYW5kIHJlLXJlYWRzIHRoZSByZWJ1aWx0IGNvbmZpZy4gLS0+XG4gICAgICAgIEBpZiAocmVwb3J0SGFzRmlsdGVycykge1xuICAgICAgICAgIEBmb3IgKGtleSBvZiBbcmVwb3J0RmlsdGVyS2V5XTsgdHJhY2sga2V5KSB7XG4gICAgICAgICAgICA8ZnMtZmlsdGVyIFtjb25maWddPVwicmVwb3J0RmlsdGVyQ29uZmlnXCI+PC9mcy1maWx0ZXI+XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIDxhcHAtcmVwb3J0LWNhbnZhc1xuICAgICAgICAgICAgW3JlcG9ydF09XCJyZXBvcnRcIlxuICAgICAgICAgICAgW2VkaXRNb2RlXT1cImVkaXRNb2RlXCJcbiAgICAgICAgICAgIChjb21wb25lbnRTZXR0aW5ncyk9XCJjb21wb25lbnRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgIChyZXBvcnRDaGFuZ2VkKT1cIm9uQ2FudmFzUmVwb3J0Q2hhbmdlZCgpXCJcbiAgICAgICAgICAgIChlZGl0RG9uZSk9XCJ0b2dnbGVFZGl0TW9kZSgpXCI+XG4gICAgICAgIDwvYXBwLXJlcG9ydC1jYW52YXM+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=