@rosoftlab/ionic 1.0.0-alpha-17 → 1.0.1-alpha-2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. package/fesm2022/rosoftlab-ionic.mjs +41 -43
  2. package/fesm2022/rosoftlab-ionic.mjs.map +1 -1
  3. package/package.json +4 -6
  4. package/esm2022/lib/components/index.mjs +0 -5
  5. package/esm2022/lib/components/rsl-ionic-crud.component/rsl-ionic-crud.component.mjs +0 -266
  6. package/esm2022/lib/components/rsl-ionic-data-table/rsl-ionic-data-table.component.mjs +0 -292
  7. package/esm2022/lib/components/rsl-ionic-grid/rsl-ionic-grid.component.mjs +0 -269
  8. package/esm2022/lib/components/rsl-ionic-sm-buttons/ionic-sm-buttons.component.mjs +0 -65
  9. package/esm2022/lib/decorators/index.mjs +0 -3
  10. package/esm2022/lib/decorators/ionic-datatable-layout.mjs +0 -10
  11. package/esm2022/lib/decorators/ionic-list.decorator.mjs +0 -9
  12. package/esm2022/lib/interfaces/index.mjs +0 -2
  13. package/esm2022/lib/interfaces/ionic-list-layout-config.mjs +0 -2
  14. package/esm2022/lib/ionic-dialog.service.mjs +0 -51
  15. package/esm2022/lib/rsl-ionic-module.module.mjs +0 -96
  16. package/esm2022/lib/translate.extension.mjs +0 -48
  17. package/esm2022/lib/types/index.mjs +0 -2
  18. package/esm2022/lib/types/repeat/repeat-section.type.mjs +0 -135
  19. package/esm2022/lib/types/repeat-datatable/repeat-datatable.component.mjs +0 -190
  20. package/esm2022/lib/validators/index.mjs +0 -2
  21. package/esm2022/lib/validators/must-match.mjs +0 -12
  22. package/esm2022/lib/wrappers/accordion-wrapper.component.mjs +0 -50
  23. package/esm2022/lib/wrappers/index.mjs +0 -3
  24. package/esm2022/lib/wrappers/panel-wrapper.component.mjs +0 -37
  25. package/esm2022/lib/wrappers/wrappers.module.mjs +0 -59
  26. package/esm2022/public-api.mjs +0 -12
  27. package/esm2022/rosoftlab-ionic.mjs +0 -5
@@ -1,292 +0,0 @@
1
- import { Location } from '@angular/common';
2
- import { Component, ElementRef, Injector, Input, TemplateRef, ViewChild } from '@angular/core';
3
- import { ActivatedRoute, NavigationStart, Router, UrlSegment } from '@angular/router';
4
- import { NavController } from '@ionic/angular';
5
- import { TranslateService } from '@ngx-translate/core';
6
- import { ColumnMode, SelectionType } from '@swimlane/ngx-datatable';
7
- import * as jsonLogic from 'json-logic-js/logic.js';
8
- import { IonicDialogService } from '../../ionic-dialog.service';
9
- import { RslIonicModuleModule } from '../../rsl-ionic-module.module';
10
- import * as i0 from "@angular/core";
11
- import * as i1 from "@angular/router";
12
- import * as i2 from "@ngx-translate/core";
13
- import * as i3 from "@angular/common";
14
- import * as i4 from "@ionic/angular";
15
- import * as i5 from "../../ionic-dialog.service";
16
- import * as i6 from "@swimlane/ngx-datatable";
17
- export class RslIonicDataTableComponent {
18
- constructor(router, route, translate, location, injector, navCtrl, dialogService, el) {
19
- this.router = router;
20
- this.route = route;
21
- this.translate = translate;
22
- this.location = location;
23
- this.injector = injector;
24
- this.navCtrl = navCtrl;
25
- this.dialogService = dialogService;
26
- this.el = el;
27
- this.data = [];
28
- this.pageIndex = 1;
29
- this.pageSize = 30;
30
- this.columns = [];
31
- this.allColumns = [];
32
- this.ColumnMode = ColumnMode;
33
- this.SelectionType = SelectionType;
34
- this.headerHeight = 50;
35
- this.rowHeight = 50;
36
- }
37
- ngOnInit() {
38
- this.setValueFromSnapshot(this, this.route.snapshot, 'showSerach', false);
39
- this.setValueFromSnapshot(this, this.route.snapshot, 'searchFields', null);
40
- this.setValueFromSnapshot(this, this.route.snapshot, 'customInclude', null);
41
- this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSort', null);
42
- this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSortDirection', '');
43
- this.setValueFromSnapshot(this, this.route.snapshot, 'deletePropertyName', 'name');
44
- this.setValueFromSnapshot(this, this.route.snapshot, 'defaultFilter', null);
45
- this.setValueFromSnapshot(this, this.route.snapshot, 'showHeader', true);
46
- this.setValueFromSnapshot(this, this.route.snapshot, 'deleteDisableRule', null);
47
- this.setValueFromSnapshot(this, this.route.snapshot, 'hasAdd', true);
48
- this.setValueFromSnapshot(this, this.route.snapshot, 'canDelete', true);
49
- this.setValueFromSnapshot(this, this.route.snapshot, 'canEdit', true);
50
- if (!this.modelService) {
51
- const SERVICE_TOKEN = this.route.snapshot.data['requiredService'];
52
- this.modelService = this.injector.get(SERVICE_TOKEN);
53
- }
54
- this.model = this.modelService.newModel();
55
- this.title = this.model.modelConfig.formTitle;
56
- this.getListLayout();
57
- const currentUrlSegments = this.router.url.split('/').map(segment => new UrlSegment(segment, {}));
58
- this.basePath = currentUrlSegments.map(segment => segment.path).join('/');
59
- this.router.events.subscribe(event => {
60
- if (event instanceof NavigationStart) {
61
- // Navigation to another page is about to occur
62
- this.data = [];
63
- this.pageIndex = 1;
64
- // Perform actions or update component as needed
65
- }
66
- });
67
- // this.isLoading = true;
68
- // this.onScroll(0);
69
- }
70
- setValueFromSnapshot(component, snapshot, key, defaultValue) {
71
- if (component[key] === undefined) {
72
- let dataFromSnapshot = snapshot.data[key];
73
- if (dataFromSnapshot === null || dataFromSnapshot === undefined) {
74
- dataFromSnapshot = snapshot.params[key];
75
- }
76
- component[key] = dataFromSnapshot !== undefined ? dataFromSnapshot : defaultValue;
77
- }
78
- }
79
- onScroll(offsetY) {
80
- if (offsetY) {
81
- if (this.oldOffsetY !== offsetY) {
82
- this.oldOffsetY = offsetY;
83
- const viewHeight = this.el.nativeElement.getBoundingClientRect().height - this.headerHeight;
84
- if (!this.isLoading && offsetY + viewHeight >= this.data.length * this.rowHeight) {
85
- // total number of results to load
86
- let limit = this.pageSize;
87
- // check if we haven't fetched any results yet
88
- if (this.data.length === 0) {
89
- // calculate the number of rows that fit within viewport
90
- const pageSize = Math.ceil(viewHeight / this.rowHeight);
91
- // change the limit to pageSize such that we fill the first page entirely
92
- // (otherwise, we won't be able to scroll past it)
93
- limit = Math.max(pageSize, this.pageSize);
94
- }
95
- // this.pageIndex
96
- this.pageSize = limit;
97
- this.loadData();
98
- // this.loadPage(limit);
99
- }
100
- }
101
- }
102
- }
103
- async ionViewWillEnter() {
104
- this.data = [];
105
- this.loadData();
106
- }
107
- async handleChange(event) {
108
- this.filterValue = event.target.value.toLowerCase();
109
- this.data = [];
110
- this.pageIndex = 1;
111
- this.loadData();
112
- }
113
- loadData(event = null) {
114
- const filters = [];
115
- let sorts = '';
116
- this.isLoading = true;
117
- if (this.defaultSort) {
118
- if (this.defaultSortDirection === 'desc') {
119
- sorts = '-' + this.defaultSort;
120
- }
121
- else {
122
- sorts = this.defaultSort;
123
- }
124
- }
125
- if (this.showSerach) {
126
- if (this.filterValue) {
127
- const y = '(' + this.searchFields.replace(',', '|') + ')';
128
- filters.push(y + '@=*' + this.filterValue);
129
- }
130
- }
131
- if (this.defaultFilter) {
132
- filters.push(this.defaultFilter);
133
- }
134
- setTimeout(() => {
135
- const filtersValue = filters.join(', ');
136
- this.modelService.getAll(this.pageIndex, this.pageSize, sorts, filtersValue, this.customInclude).subscribe((response) => {
137
- if (this.pageIndex !== response.getMeta().meta.count) {
138
- this.pageIndex++;
139
- }
140
- else {
141
- if (event)
142
- event.target.disabled = true;
143
- }
144
- // if (this.filterValue)
145
- // this.data = response.getModels();
146
- // else
147
- const rows = [...this.data, ...response.getModels()];
148
- this.data = rows;
149
- // this.data = this.data.concat();
150
- if (event)
151
- event.target.complete();
152
- this.isLoading = false;
153
- });
154
- }, 700);
155
- }
156
- async handleRefresh(event) {
157
- this.pageIndex = 1;
158
- this.data = [];
159
- this.loadData();
160
- event.target.complete();
161
- }
162
- onAdd() {
163
- console.log(this.basePath);
164
- this.router.navigate([this.basePath + '/add']);
165
- // this.navCtrl.navigateForward(this.basePath + '/add');
166
- }
167
- editModel(model) {
168
- if (this.canEdit)
169
- this.router.navigate([this.basePath + '/edit/', model.id]);
170
- // this.navCtrl.navigateForward(this.basePath + '/edit/' + model.id);
171
- }
172
- getListLayout() {
173
- if (!this.model) {
174
- this.model = this.modelService.newModel();
175
- }
176
- this.allColumns = [];
177
- this.columns = [];
178
- this.allColumns = Reflect.getMetadata('IonicDataTableLayout', this.model).map((item) => {
179
- if (!item.isTranslated) {
180
- item.name = this.translate.instant(item.name);
181
- item.isTranslated = true;
182
- }
183
- return item;
184
- });
185
- this.allColumns.sort((a, b) => a.order - b.order);
186
- if (this.canDelete || this.canEdit) {
187
- this.allColumns.push({
188
- cellTemplate: this.actionsTmpl,
189
- name: '',
190
- cellClass: 'actions-cell',
191
- draggable: false,
192
- sortable: false,
193
- visible: true
194
- // width: 100,
195
- // maxWidth: 100,
196
- // minWidth: 100
197
- });
198
- }
199
- this.columns = this.allColumns.filter((item) => item.visible);
200
- // Sort the columns array by the order property
201
- }
202
- deleteModel(model) {
203
- const msg = 'Do you want to delete ' + model[this.deletePropertyName] + '?';
204
- this.dialogService.confirm(msg).then((value) => {
205
- if (value.data) {
206
- this.modelService.delete(model.id).subscribe(() => {
207
- const tempData = [];
208
- // this.selectedObject.emit(null);
209
- this.data.map((item) => {
210
- if (item.id !== model.id) {
211
- tempData.push(item);
212
- }
213
- });
214
- this.data = tempData;
215
- });
216
- }
217
- });
218
- }
219
- deleteEnabled(model) {
220
- if (this.canDelete) {
221
- if (this.deleteDisableRule) {
222
- return this.evaluateRule(this.deleteDisableRule, model);
223
- }
224
- else {
225
- return true;
226
- }
227
- }
228
- else {
229
- return false;
230
- }
231
- }
232
- evaluateRule(rules, model) {
233
- let result = true;
234
- rules.forEach(rule => {
235
- let jsonRule;
236
- if (typeof rule.rule === 'string') {
237
- jsonRule = JSON.parse(rule.rule);
238
- }
239
- else {
240
- jsonRule = rule.rule;
241
- }
242
- if (rule.parameters) {
243
- const data = '{' + rule.parameters.map((item) => {
244
- return '"' + item + '":"' + model[item] + '"';
245
- }).join(',') + '}';
246
- result = jsonLogic.apply(jsonRule, JSON.parse(data));
247
- }
248
- else {
249
- result = jsonLogic.apply(jsonRule);
250
- }
251
- });
252
- return result;
253
- }
254
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: RslIonicDataTableComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.TranslateService }, { token: i3.Location }, { token: i0.Injector }, { token: i4.NavController }, { token: i5.IonicDialogService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
255
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: RslIonicDataTableComponent, isStandalone: true, selector: "app-rsl-ionic-data-table", inputs: { showSerach: "showSerach", searchFields: "searchFields", customInclude: "customInclude", defaultSort: "defaultSort", defaultSortDirection: "defaultSortDirection", deletePropertyName: "deletePropertyName", defaultFilter: "defaultFilter", showHeader: "showHeader", deleteDisableRule: "deleteDisableRule", hasAdd: "hasAdd", canDelete: "canDelete", canEdit: "canEdit", model: "model", modelService: "modelService" }, viewQueries: [{ propertyName: "actionsTmpl", first: true, predicate: ["actionsTmpl"], descendants: true, static: true }], ngImport: i0, template: "<ion-header *ngIf=\"showHeader\">\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ion-menu-button></ion-menu-button>\r\n <ion-back-button></ion-back-button>\r\n </ion-buttons>\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n </ion-toolbar>\r\n <ng-container [ngTemplateOutlet]=\"search\"></ng-container>\r\n</ion-header>\r\n\r\n<ion-content [fullscreen]=\"true\">\r\n\r\n <ion-refresher slot=\"fixed\" (ionRefresh)=\"handleRefresh($event)\">\r\n <ion-refresher-content></ion-refresher-content>\r\n </ion-refresher>\r\n\r\n <ngx-datatable class=\"material fullscreen rls-server-scrolling\" style=\"top: 115px\" [rows]=\"data\" [columns]=\"columns\"\r\n [columnMode]=\"ColumnMode.standard\" [headerHeight]=\"headerHeight\" [rowHeight]=\"rowHeight\" [scrollbarV]=\"true\"\r\n [loadingIndicator]=\"isLoading\" [scrollbarH]=\"true\" (scroll)=\"onScroll($event.offsetY)\"\r\n >\r\n </ngx-datatable>\r\n \r\n <ng-template #actionsTmpl let-row=\"row\" let-value=\"value\">\r\n <ion-button fill=\"clear\" *ngIf=\"canEdit\" (click)='editModel(row)'>\r\n <ion-icon slot=\"icon-only\" name=\"create\" (click)='editModel(row)'></ion-icon>\r\n </ion-button>\r\n <ion-button fill=\"clear\" *ngIf=\"deleteEnabled(row)\" (click)='deleteModel(row)'>\r\n <ion-icon color=\"danger\" slot=\"icon-only\" name=\"trash\" (click)='deleteModel(row)'></ion-icon>\r\n </ion-button>\r\n </ng-template>\r\n\r\n</ion-content>\r\n\r\n<ng-template #header>\r\n <ion-title class=\"ion-text-center\">{{title}}</ion-title>\r\n <ion-button slot=\"end\" (click)=\"onAdd()\" fill=\"clear\" *ngIf=\"hasAdd\">\r\n <ion-icon size=\"large\" name=\"add\"></ion-icon>\r\n </ion-button>\r\n</ng-template>\r\n\r\n<ng-template #search>\r\n <ion-toolbar *ngIf=\"showSerach\">\r\n <ion-searchbar [debounce]=\"1000\" (ionChange)=\"handleChange($event)\"></ion-searchbar>\r\n </ion-toolbar>\r\n</ng-template>", styles: [".rls-server-scrolling{height:calc(100vh - 110px)}::ng-deep .progress-linear{position:fixed!important;bottom:0}::ng-deep .actions-cell{padding:5px 0 0 .9rem!important}::ng-deep .align-right{text-align:right!important}\n"], dependencies: [{ kind: "ngmodule", type: RslIonicModuleModule }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonMenuButton, selector: "ion-menu-button", inputs: ["autoHide", "color", "disabled", "menu", "mode", "type"] }, { kind: "component", type: i4.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonSearchbar, selector: "ion-searchbar", inputs: ["animated", "autocapitalize", "autocomplete", "autocorrect", "cancelButtonIcon", "cancelButtonText", "clearIcon", "color", "debounce", "disabled", "enterkeyhint", "inputmode", "maxlength", "minlength", "mode", "name", "placeholder", "searchIcon", "showCancelButton", "showClearButton", "spellcheck", "type", "value"] }, { kind: "component", type: i4.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i4.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i4.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar,ion-range" }, { kind: "component", type: i4.IonBackButton, selector: "ion-back-button" }, { kind: "component", type: i6.DatatableComponent, selector: "ngx-datatable", inputs: ["targetMarkerTemplate", "rows", "groupRowsBy", "groupedRows", "columns", "selected", "scrollbarV", "scrollbarH", "rowHeight", "columnMode", "headerHeight", "footerHeight", "externalPaging", "externalSorting", "limit", "count", "offset", "loadingIndicator", "selectionType", "reorderable", "swapColumns", "sortType", "sorts", "cssClasses", "messages", "rowClass", "selectCheck", "displayCheck", "groupExpansionDefault", "trackByProp", "selectAllRowsOnPage", "virtualization", "treeFromRelation", "treeToRelation", "summaryRow", "summaryHeight", "summaryPosition", "rowIdentity"], outputs: ["scroll", "activate", "select", "sort", "page", "reorder", "resize", "tableContextmenu", "treeAction"] }] }); }
256
- }
257
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: RslIonicDataTableComponent, decorators: [{
258
- type: Component,
259
- args: [{ standalone: true, selector: 'app-rsl-ionic-data-table', imports: [RslIonicModuleModule], template: "<ion-header *ngIf=\"showHeader\">\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ion-menu-button></ion-menu-button>\r\n <ion-back-button></ion-back-button>\r\n </ion-buttons>\r\n <ng-container [ngTemplateOutlet]=\"header\"></ng-container>\r\n </ion-toolbar>\r\n <ng-container [ngTemplateOutlet]=\"search\"></ng-container>\r\n</ion-header>\r\n\r\n<ion-content [fullscreen]=\"true\">\r\n\r\n <ion-refresher slot=\"fixed\" (ionRefresh)=\"handleRefresh($event)\">\r\n <ion-refresher-content></ion-refresher-content>\r\n </ion-refresher>\r\n\r\n <ngx-datatable class=\"material fullscreen rls-server-scrolling\" style=\"top: 115px\" [rows]=\"data\" [columns]=\"columns\"\r\n [columnMode]=\"ColumnMode.standard\" [headerHeight]=\"headerHeight\" [rowHeight]=\"rowHeight\" [scrollbarV]=\"true\"\r\n [loadingIndicator]=\"isLoading\" [scrollbarH]=\"true\" (scroll)=\"onScroll($event.offsetY)\"\r\n >\r\n </ngx-datatable>\r\n \r\n <ng-template #actionsTmpl let-row=\"row\" let-value=\"value\">\r\n <ion-button fill=\"clear\" *ngIf=\"canEdit\" (click)='editModel(row)'>\r\n <ion-icon slot=\"icon-only\" name=\"create\" (click)='editModel(row)'></ion-icon>\r\n </ion-button>\r\n <ion-button fill=\"clear\" *ngIf=\"deleteEnabled(row)\" (click)='deleteModel(row)'>\r\n <ion-icon color=\"danger\" slot=\"icon-only\" name=\"trash\" (click)='deleteModel(row)'></ion-icon>\r\n </ion-button>\r\n </ng-template>\r\n\r\n</ion-content>\r\n\r\n<ng-template #header>\r\n <ion-title class=\"ion-text-center\">{{title}}</ion-title>\r\n <ion-button slot=\"end\" (click)=\"onAdd()\" fill=\"clear\" *ngIf=\"hasAdd\">\r\n <ion-icon size=\"large\" name=\"add\"></ion-icon>\r\n </ion-button>\r\n</ng-template>\r\n\r\n<ng-template #search>\r\n <ion-toolbar *ngIf=\"showSerach\">\r\n <ion-searchbar [debounce]=\"1000\" (ionChange)=\"handleChange($event)\"></ion-searchbar>\r\n </ion-toolbar>\r\n</ng-template>", styles: [".rls-server-scrolling{height:calc(100vh - 110px)}::ng-deep .progress-linear{position:fixed!important;bottom:0}::ng-deep .actions-cell{padding:5px 0 0 .9rem!important}::ng-deep .align-right{text-align:right!important}\n"] }]
260
- }], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i3.Location }, { type: i0.Injector }, { type: i4.NavController }, { type: i5.IonicDialogService }, { type: i0.ElementRef }], propDecorators: { actionsTmpl: [{
261
- type: ViewChild,
262
- args: ['actionsTmpl', { static: true }]
263
- }], showSerach: [{
264
- type: Input
265
- }], searchFields: [{
266
- type: Input
267
- }], customInclude: [{
268
- type: Input
269
- }], defaultSort: [{
270
- type: Input
271
- }], defaultSortDirection: [{
272
- type: Input
273
- }], deletePropertyName: [{
274
- type: Input
275
- }], defaultFilter: [{
276
- type: Input
277
- }], showHeader: [{
278
- type: Input
279
- }], deleteDisableRule: [{
280
- type: Input
281
- }], hasAdd: [{
282
- type: Input
283
- }], canDelete: [{
284
- type: Input
285
- }], canEdit: [{
286
- type: Input
287
- }], model: [{
288
- type: Input
289
- }], modelService: [{
290
- type: Input
291
- }] } });
292
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnNsLWlvbmljLWRhdGEtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcm9zb2Z0bGFiL2lvbmljL3NyYy9saWIvY29tcG9uZW50cy9yc2wtaW9uaWMtZGF0YS10YWJsZS9yc2wtaW9uaWMtZGF0YS10YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9yb3NvZnRsYWIvaW9uaWMvc3JjL2xpYi9jb21wb25lbnRzL3JzbC1pb25pYy1kYXRhLXRhYmxlL3JzbC1pb25pYy1kYXRhLXRhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFVLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkcsT0FBTyxFQUFFLGNBQWMsRUFBMEIsZUFBZSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5RyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHdkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRSxPQUFPLEtBQUssU0FBUyxNQUFNLHdCQUF3QixDQUFDO0FBRXBELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLCtCQUErQixDQUFDOzs7Ozs7OztBQVNyRSxNQUFNLE9BQU8sMEJBQTBCO0lBbUNyQyxZQUNTLE1BQWMsRUFDZCxLQUFxQixFQUNyQixTQUEyQixFQUMzQixRQUFrQixFQUNqQixRQUFrQixFQUNsQixPQUFzQixFQUN2QixhQUFpQyxFQUNoQyxFQUFjO1FBUGYsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLGNBQVMsR0FBVCxTQUFTLENBQWtCO1FBQzNCLGFBQVEsR0FBUixRQUFRLENBQVU7UUFDakIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQixZQUFPLEdBQVAsT0FBTyxDQUFlO1FBQ3ZCLGtCQUFhLEdBQWIsYUFBYSxDQUFvQjtRQUNoQyxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBeEJ4QixTQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ2pCLGNBQVMsR0FBVyxDQUFDLENBQUM7UUFDdEIsYUFBUSxHQUFXLEVBQUUsQ0FBQTtRQUlyQixZQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsZUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNoQixlQUFVLEdBQUcsVUFBVSxDQUFDO1FBQ3hCLGtCQUFhLEdBQUcsYUFBYSxDQUFDO1FBRXJCLGlCQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLGNBQVMsR0FBRyxFQUFFLENBQUM7SUFjeEIsQ0FBQztJQUNELFFBQVE7UUFDTixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM1RSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLHNCQUFzQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbkYsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxtQkFBbUIsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNyRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN4RSxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQVMsYUFBYSxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQTtRQUN6QyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQTtRQUM3QyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUE7UUFFcEIsTUFBTSxrQkFBa0IsR0FBaUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hILElBQUksQ0FBQyxRQUFRLEdBQUcsa0JBQWtCLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDbkMsSUFBSSxLQUFLLFlBQVksZUFBZSxFQUFFLENBQUM7Z0JBQ3JDLCtDQUErQztnQkFDL0MsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUE7Z0JBQ2xCLGdEQUFnRDtZQUNsRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCx5QkFBeUI7UUFDekIsb0JBQW9CO0lBQ3RCLENBQUM7SUFDRCxvQkFBb0IsQ0FBSSxTQUFjLEVBQUUsUUFBZ0MsRUFBRSxHQUFXLEVBQUUsWUFBZTtRQUNwRyxJQUFJLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUMsSUFBSSxnQkFBZ0IsS0FBSyxJQUFJLElBQUksZ0JBQWdCLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2hFLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUNELFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxnQkFBZ0IsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUM7UUFDcEYsQ0FBQztJQUNILENBQUM7SUFDRCxRQUFRLENBQUMsT0FBZTtRQUN0QixJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQztnQkFDMUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztnQkFDNUYsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksT0FBTyxHQUFHLFVBQVUsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQ2pGLGtDQUFrQztvQkFDbEMsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztvQkFFMUIsOENBQThDO29CQUM5QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO3dCQUMzQix3REFBd0Q7d0JBQ3hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzt3QkFFeEQseUVBQXlFO3dCQUN6RSxrREFBa0Q7d0JBQ2xELEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQzVDLENBQUM7b0JBQ0QsaUJBQWlCO29CQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQTtvQkFDckIsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUNoQix3QkFBd0I7Z0JBQzFCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxLQUFLLENBQUMsZ0JBQWdCO1FBQ3BCLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFDRCxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUs7UUFDdEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNwRCxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNmLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFBO1FBQ2xCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBQ0QsUUFBUSxDQUFDLEtBQUssR0FBRyxJQUFJO1FBQ25CLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNuQixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDekMsS0FBSyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQ2pDLENBQUM7aUJBQU0sQ0FBQztnQkFDTixLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztnQkFDMUQsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM3QyxDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQ2xDLENBQUM7UUFDRCxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsU0FBUyxDQUN4RyxDQUFDLFFBQTBCLEVBQUUsRUFBRTtnQkFDN0IsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ3JELElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQTtnQkFDbEIsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksS0FBSzt3QkFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7Z0JBQzFDLENBQUM7Z0JBQ0Qsd0JBQXdCO2dCQUN4QixzQ0FBc0M7Z0JBQ3RDLE9BQU87Z0JBQ1AsTUFBTSxJQUFJLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDckQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBQ2pCLGtDQUFrQztnQkFFbEMsSUFBSSxLQUFLO29CQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQztJQUNELEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQTtRQUNsQixJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNmLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFDRCxLQUFLO1FBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7UUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDOUMsd0RBQXdEO0lBQzFELENBQUM7SUFDRCxTQUFTLENBQUMsS0FBc0I7UUFDOUIsSUFBSSxJQUFJLENBQUMsT0FBTztZQUNkLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDN0QscUVBQXFFO0lBQ3ZFLENBQUM7SUFDRCxhQUFhO1FBQ1gsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDNUMsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEdBQUMsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxPQUFPLEdBQUMsRUFBRSxDQUFDO1FBQ2hCLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBZ0MsRUFBRSxFQUFFO1lBQ2pILElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM5QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQTtZQUMxQixDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztnQkFDbkIsWUFBWSxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM5QixJQUFJLEVBQUUsRUFBRTtnQkFDUixTQUFTLEVBQUUsY0FBYztnQkFDekIsU0FBUyxFQUFFLEtBQUs7Z0JBQ2hCLFFBQVEsRUFBRSxLQUFLO2dCQUNmLE9BQU8sRUFBRSxJQUFJO2dCQUNiLGNBQWM7Z0JBQ2QsaUJBQWlCO2dCQUNqQixnQkFBZ0I7YUFDakIsQ0FBQyxDQUFBO1FBQ0osQ0FBQztRQUNELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFnQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUYsK0NBQStDO0lBRWpELENBQUM7SUFDRCxXQUFXLENBQUMsS0FBSztRQUNmLE1BQU0sR0FBRyxHQUFHLHdCQUF3QixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDNUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUNsQyxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQ2IsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7b0JBQ2hELE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQztvQkFDcEIsa0NBQWtDO29CQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO3dCQUNyQixJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDOzRCQUN6QixRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO3dCQUN0QixDQUFDO29CQUNILENBQUMsQ0FBQyxDQUFDO29CQUNILElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO2dCQUN2QixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUM7SUFFRCxhQUFhLENBQUMsS0FBUTtRQUNwQixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuQixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2dCQUMzQixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzFELENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFDTyxZQUFZLENBQUMsS0FBYSxFQUFFLEtBQVE7UUFDMUMsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDbkIsSUFBSSxRQUFhLENBQUM7WUFDbEIsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ2xDLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDdkIsQ0FBQztZQUNELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLElBQUksR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRTtvQkFDdEQsT0FBTyxHQUFHLEdBQUcsSUFBSSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO2dCQUNoRCxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO2dCQUNuQixNQUFNLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3ZELENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNyQyxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOzhHQXpRVSwwQkFBMEI7a0dBQTFCLDBCQUEwQixvbkJDcEJ2Qyx1NkRBNkNjLG1SRDNCRixvQkFBb0I7OzJGQUVuQiwwQkFBMEI7a0JBUHRDLFNBQVM7aUNBQ0ksSUFBSSxZQUNOLDBCQUEwQixXQUczQixDQUFDLG9CQUFvQixDQUFDOzJRQUdhLFdBQVc7c0JBQXRELFNBQVM7dUJBQUMsYUFBYSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFFakMsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxvQkFBb0I7c0JBQTVCLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9jYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEluamVjdG9yLCBJbnB1dCwgT25Jbml0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LCBOYXZpZ2F0aW9uU3RhcnQsIFJvdXRlciwgVXJsU2VnbWVudCB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XHJcbmltcG9ydCB7IE5hdkNvbnRyb2xsZXIgfSBmcm9tICdAaW9uaWMvYW5ndWxhcic7XHJcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcclxuaW1wb3J0IHsgQmFzZVF1ZXJ5RGF0YSwgQmFzZVNlcnZpY2UsIFJ1bGUgfSBmcm9tICdAcm9zb2Z0bGFiL2NvcmUnO1xyXG5pbXBvcnQgeyBCYXNlTW9kZWxGb3JtbHkgfSBmcm9tICdAcm9zb2Z0bGFiL2Zvcm1seSc7XHJcbmltcG9ydCB7IENvbHVtbk1vZGUsIFNlbGVjdGlvblR5cGUgfSBmcm9tICdAc3dpbWxhbmUvbmd4LWRhdGF0YWJsZSc7XHJcbmltcG9ydCAqIGFzIGpzb25Mb2dpYyBmcm9tICdqc29uLWxvZ2ljLWpzL2xvZ2ljLmpzJztcclxuaW1wb3J0IHsgSW9uaWNEYXRhVGFibGVMYXlvdXRDb25maWcgfSBmcm9tICcuLi8uLi9kZWNvcmF0b3JzL2lvbmljLWRhdGF0YWJsZS1sYXlvdXQnO1xyXG5pbXBvcnQgeyBJb25pY0RpYWxvZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9pb25pYy1kaWFsb2cuc2VydmljZSc7XHJcbmltcG9ydCB7IFJzbElvbmljTW9kdWxlTW9kdWxlIH0gZnJvbSAnLi4vLi4vcnNsLWlvbmljLW1vZHVsZS5tb2R1bGUnO1xyXG5leHBvcnQgZGVjbGFyZSB0eXBlIFNvcnREaXJlY3Rpb24gPSAnYXNjJyB8ICdkZXNjJyB8ICcnO1xyXG5AQ29tcG9uZW50KHtcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIHNlbGVjdG9yOiAnYXBwLXJzbC1pb25pYy1kYXRhLXRhYmxlJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcnNsLWlvbmljLWRhdGEtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3JzbC1pb25pYy1kYXRhLXRhYmxlLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgaW1wb3J0czogW1JzbElvbmljTW9kdWxlTW9kdWxlXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIFJzbElvbmljRGF0YVRhYmxlQ29tcG9uZW50PFQgZXh0ZW5kcyBCYXNlTW9kZWxGb3JtbHksIFUgZXh0ZW5kcyBCYXNlU2VydmljZTxUPj4gaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIEBWaWV3Q2hpbGQoJ2FjdGlvbnNUbXBsJywgeyBzdGF0aWM6IHRydWUgfSkgYWN0aW9uc1RtcGw6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgcHVibGljIHRpdGxlOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgc2hvd1NlcmFjaDogYm9vbGVhbjtcclxuICBASW5wdXQoKSBzZWFyY2hGaWVsZHM6IHN0cmluZztcclxuICBASW5wdXQoKSBjdXN0b21JbmNsdWRlOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgZGVmYXVsdFNvcnQ6IHN0cmluZztcclxuICBASW5wdXQoKSBkZWZhdWx0U29ydERpcmVjdGlvbjogU29ydERpcmVjdGlvbjtcclxuICBASW5wdXQoKSBkZWxldGVQcm9wZXJ0eU5hbWU6IHN0cmluZztcclxuICBASW5wdXQoKSBkZWZhdWx0RmlsdGVyOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgc2hvd0hlYWRlcjogYm9vbGVhbjtcclxuICBASW5wdXQoKSBkZWxldGVEaXNhYmxlUnVsZTogUnVsZVtdO1xyXG4gIEBJbnB1dCgpIGhhc0FkZDogYm9vbGVhbjtcclxuICBASW5wdXQoKSBjYW5EZWxldGU6IGJvb2xlYW47XHJcbiAgQElucHV0KCkgY2FuRWRpdDogYm9vbGVhbjtcclxuXHJcbiAgQElucHV0KCkgbW9kZWw6IFQ7XHJcbiAgQElucHV0KCkgbW9kZWxTZXJ2aWNlOiBVXHJcblxyXG4gIGRhdGE6IGFueVtdID0gW107XHJcbiAgcGFnZUluZGV4OiBudW1iZXIgPSAxO1xyXG4gIHBhZ2VTaXplOiBudW1iZXIgPSAzMFxyXG5cclxuICBiYXNlUGF0aDogc3RyaW5nO1xyXG5cclxuICBjb2x1bW5zID0gW107XHJcbiAgYWxsQ29sdW1ucyA9IFtdO1xyXG4gIENvbHVtbk1vZGUgPSBDb2x1bW5Nb2RlO1xyXG4gIFNlbGVjdGlvblR5cGUgPSBTZWxlY3Rpb25UeXBlO1xyXG5cclxuICByZWFkb25seSBoZWFkZXJIZWlnaHQgPSA1MDtcclxuICByZWFkb25seSByb3dIZWlnaHQgPSA1MDtcclxuICBpc0xvYWRpbmc6IGJvb2xlYW47XHJcbiAgZmlsdGVyVmFsdWU6IHN0cmluZztcclxuICBvbGRPZmZzZXRZOiBudW1iZXI7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgcm91dGVyOiBSb3V0ZXIsXHJcbiAgICBwdWJsaWMgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxyXG4gICAgcHVibGljIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcclxuICAgIHB1YmxpYyBsb2NhdGlvbjogTG9jYXRpb24sXHJcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcclxuICAgIHByaXZhdGUgbmF2Q3RybDogTmF2Q29udHJvbGxlcixcclxuICAgIHB1YmxpYyBkaWFsb2dTZXJ2aWNlOiBJb25pY0RpYWxvZ1NlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmKSB7XHJcblxyXG4gIH1cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuc2V0VmFsdWVGcm9tU25hcHNob3QodGhpcywgdGhpcy5yb3V0ZS5zbmFwc2hvdCwgJ3Nob3dTZXJhY2gnLCBmYWxzZSk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdzZWFyY2hGaWVsZHMnLCBudWxsKTtcclxuICAgIHRoaXMuc2V0VmFsdWVGcm9tU25hcHNob3QodGhpcywgdGhpcy5yb3V0ZS5zbmFwc2hvdCwgJ2N1c3RvbUluY2x1ZGUnLCBudWxsKTtcclxuICAgIHRoaXMuc2V0VmFsdWVGcm9tU25hcHNob3QodGhpcywgdGhpcy5yb3V0ZS5zbmFwc2hvdCwgJ2RlZmF1bHRTb3J0JywgbnVsbCk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdkZWZhdWx0U29ydERpcmVjdGlvbicsICcnKTtcclxuICAgIHRoaXMuc2V0VmFsdWVGcm9tU25hcHNob3QodGhpcywgdGhpcy5yb3V0ZS5zbmFwc2hvdCwgJ2RlbGV0ZVByb3BlcnR5TmFtZScsICduYW1lJyk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdkZWZhdWx0RmlsdGVyJywgbnVsbCk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdzaG93SGVhZGVyJywgdHJ1ZSk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdkZWxldGVEaXNhYmxlUnVsZScsIG51bGwpO1xyXG4gICAgdGhpcy5zZXRWYWx1ZUZyb21TbmFwc2hvdCh0aGlzLCB0aGlzLnJvdXRlLnNuYXBzaG90LCAnaGFzQWRkJywgdHJ1ZSk7XHJcbiAgICB0aGlzLnNldFZhbHVlRnJvbVNuYXBzaG90KHRoaXMsIHRoaXMucm91dGUuc25hcHNob3QsICdjYW5EZWxldGUnLCB0cnVlKTtcclxuICAgIHRoaXMuc2V0VmFsdWVGcm9tU25hcHNob3QodGhpcywgdGhpcy5yb3V0ZS5zbmFwc2hvdCwgJ2NhbkVkaXQnLCB0cnVlKTtcclxuICAgIGlmICghdGhpcy5tb2RlbFNlcnZpY2UpIHtcclxuICAgICAgY29uc3QgU0VSVklDRV9UT0tFTiA9IHRoaXMucm91dGUuc25hcHNob3QuZGF0YVsncmVxdWlyZWRTZXJ2aWNlJ107XHJcbiAgICAgIHRoaXMubW9kZWxTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQ8VT4oPGFueT5TRVJWSUNFX1RPS0VOKTtcclxuICAgIH1cclxuICAgIHRoaXMubW9kZWwgPSB0aGlzLm1vZGVsU2VydmljZS5uZXdNb2RlbCgpXHJcbiAgICB0aGlzLnRpdGxlID0gdGhpcy5tb2RlbC5tb2RlbENvbmZpZy5mb3JtVGl0bGVcclxuICAgIHRoaXMuZ2V0TGlzdExheW91dCgpXHJcblxyXG4gICAgY29uc3QgY3VycmVudFVybFNlZ21lbnRzOiBVcmxTZWdtZW50W10gPSB0aGlzLnJvdXRlci51cmwuc3BsaXQoJy8nKS5tYXAoc2VnbWVudCA9PiBuZXcgVXJsU2VnbWVudChzZWdtZW50LCB7fSkpO1xyXG4gICAgdGhpcy5iYXNlUGF0aCA9IGN1cnJlbnRVcmxTZWdtZW50cy5tYXAoc2VnbWVudCA9PiBzZWdtZW50LnBhdGgpLmpvaW4oJy8nKTtcclxuICAgIHRoaXMucm91dGVyLmV2ZW50cy5zdWJzY3JpYmUoZXZlbnQgPT4ge1xyXG4gICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uU3RhcnQpIHtcclxuICAgICAgICAvLyBOYXZpZ2F0aW9uIHRvIGFub3RoZXIgcGFnZSBpcyBhYm91dCB0byBvY2N1clxyXG4gICAgICAgIHRoaXMuZGF0YSA9IFtdO1xyXG4gICAgICAgIHRoaXMucGFnZUluZGV4ID0gMVxyXG4gICAgICAgIC8vIFBlcmZvcm0gYWN0aW9ucyBvciB1cGRhdGUgY29tcG9uZW50IGFzIG5lZWRlZFxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIC8vIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgIC8vIHRoaXMub25TY3JvbGwoMCk7XHJcbiAgfVxyXG4gIHNldFZhbHVlRnJvbVNuYXBzaG90PFQ+KGNvbXBvbmVudDogYW55LCBzbmFwc2hvdDogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwga2V5OiBzdHJpbmcsIGRlZmF1bHRWYWx1ZTogVCk6IHZvaWQge1xyXG4gICAgaWYgKGNvbXBvbmVudFtrZXldID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgbGV0IGRhdGFGcm9tU25hcHNob3QgPSBzbmFwc2hvdC5kYXRhW2tleV07XHJcbiAgICAgIGlmIChkYXRhRnJvbVNuYXBzaG90ID09PSBudWxsIHx8IGRhdGFGcm9tU25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgIGRhdGFGcm9tU25hcHNob3QgPSBzbmFwc2hvdC5wYXJhbXNba2V5XTtcclxuICAgICAgfVxyXG4gICAgICBjb21wb25lbnRba2V5XSA9IGRhdGFGcm9tU25hcHNob3QgIT09IHVuZGVmaW5lZCA/IGRhdGFGcm9tU25hcHNob3QgOiBkZWZhdWx0VmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIG9uU2Nyb2xsKG9mZnNldFk6IG51bWJlcikge1xyXG4gICAgaWYgKG9mZnNldFkpIHtcclxuICAgICAgaWYgKHRoaXMub2xkT2Zmc2V0WSAhPT0gb2Zmc2V0WSkge1xyXG4gICAgICAgIHRoaXMub2xkT2Zmc2V0WSA9IG9mZnNldFk7XHJcbiAgICAgICAgY29uc3Qgdmlld0hlaWdodCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQgLSB0aGlzLmhlYWRlckhlaWdodDtcclxuICAgICAgICBpZiAoIXRoaXMuaXNMb2FkaW5nICYmIG9mZnNldFkgKyB2aWV3SGVpZ2h0ID49IHRoaXMuZGF0YS5sZW5ndGggKiB0aGlzLnJvd0hlaWdodCkge1xyXG4gICAgICAgICAgLy8gdG90YWwgbnVtYmVyIG9mIHJlc3VsdHMgdG8gbG9hZFxyXG4gICAgICAgICAgbGV0IGxpbWl0ID0gdGhpcy5wYWdlU2l6ZTtcclxuXHJcbiAgICAgICAgICAvLyBjaGVjayBpZiB3ZSBoYXZlbid0IGZldGNoZWQgYW55IHJlc3VsdHMgeWV0XHJcbiAgICAgICAgICBpZiAodGhpcy5kYXRhLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiByb3dzIHRoYXQgZml0IHdpdGhpbiB2aWV3cG9ydFxyXG4gICAgICAgICAgICBjb25zdCBwYWdlU2l6ZSA9IE1hdGguY2VpbCh2aWV3SGVpZ2h0IC8gdGhpcy5yb3dIZWlnaHQpO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hhbmdlIHRoZSBsaW1pdCB0byBwYWdlU2l6ZSBzdWNoIHRoYXQgd2UgZmlsbCB0aGUgZmlyc3QgcGFnZSBlbnRpcmVseVxyXG4gICAgICAgICAgICAvLyAob3RoZXJ3aXNlLCB3ZSB3b24ndCBiZSBhYmxlIHRvIHNjcm9sbCBwYXN0IGl0KVxyXG4gICAgICAgICAgICBsaW1pdCA9IE1hdGgubWF4KHBhZ2VTaXplLCB0aGlzLnBhZ2VTaXplKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIHRoaXMucGFnZUluZGV4XHJcbiAgICAgICAgICB0aGlzLnBhZ2VTaXplID0gbGltaXRcclxuICAgICAgICAgIHRoaXMubG9hZERhdGEoKTtcclxuICAgICAgICAgIC8vIHRoaXMubG9hZFBhZ2UobGltaXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBhc3luYyBpb25WaWV3V2lsbEVudGVyKCkge1xyXG4gICAgdGhpcy5kYXRhID0gW107XHJcbiAgICB0aGlzLmxvYWREYXRhKCk7XHJcbiAgfVxyXG4gIGFzeW5jIGhhbmRsZUNoYW5nZShldmVudCkge1xyXG4gICAgdGhpcy5maWx0ZXJWYWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgdGhpcy5kYXRhID0gW107XHJcbiAgICB0aGlzLnBhZ2VJbmRleCA9IDFcclxuICAgIHRoaXMubG9hZERhdGEoKTtcclxuICB9XHJcbiAgbG9hZERhdGEoZXZlbnQgPSBudWxsKSB7XHJcbiAgICBjb25zdCBmaWx0ZXJzID0gW107XHJcbiAgICBsZXQgc29ydHMgPSAnJztcclxuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuICAgIGlmICh0aGlzLmRlZmF1bHRTb3J0KSB7XHJcbiAgICAgIGlmICh0aGlzLmRlZmF1bHRTb3J0RGlyZWN0aW9uID09PSAnZGVzYycpIHtcclxuICAgICAgICBzb3J0cyA9ICctJyArIHRoaXMuZGVmYXVsdFNvcnQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc29ydHMgPSB0aGlzLmRlZmF1bHRTb3J0O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5zaG93U2VyYWNoKSB7XHJcbiAgICAgIGlmICh0aGlzLmZpbHRlclZhbHVlKSB7XHJcbiAgICAgICAgY29uc3QgeSA9ICcoJyArIHRoaXMuc2VhcmNoRmllbGRzLnJlcGxhY2UoJywnLCAnfCcpICsgJyknO1xyXG4gICAgICAgIGZpbHRlcnMucHVzaCh5ICsgJ0A9KicgKyB0aGlzLmZpbHRlclZhbHVlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuZGVmYXVsdEZpbHRlcikge1xyXG4gICAgICBmaWx0ZXJzLnB1c2godGhpcy5kZWZhdWx0RmlsdGVyKVxyXG4gICAgfVxyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGZpbHRlcnNWYWx1ZSA9IGZpbHRlcnMuam9pbignLCAnKTtcclxuICAgICAgdGhpcy5tb2RlbFNlcnZpY2UuZ2V0QWxsKHRoaXMucGFnZUluZGV4LCB0aGlzLnBhZ2VTaXplLCBzb3J0cywgZmlsdGVyc1ZhbHVlLCB0aGlzLmN1c3RvbUluY2x1ZGUpLnN1YnNjcmliZShcclxuICAgICAgICAocmVzcG9uc2U6IEJhc2VRdWVyeURhdGE8VD4pID0+IHtcclxuICAgICAgICAgIGlmICh0aGlzLnBhZ2VJbmRleCAhPT0gcmVzcG9uc2UuZ2V0TWV0YSgpLm1ldGEuY291bnQpIHtcclxuICAgICAgICAgICAgdGhpcy5wYWdlSW5kZXgrK1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKGV2ZW50KSBldmVudC50YXJnZXQuZGlzYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgLy8gaWYgKHRoaXMuZmlsdGVyVmFsdWUpXHJcbiAgICAgICAgICAvLyAgIHRoaXMuZGF0YSA9IHJlc3BvbnNlLmdldE1vZGVscygpO1xyXG4gICAgICAgICAgLy8gZWxzZVxyXG4gICAgICAgICAgY29uc3Qgcm93cyA9IFsuLi50aGlzLmRhdGEsIC4uLnJlc3BvbnNlLmdldE1vZGVscygpXTtcclxuICAgICAgICAgIHRoaXMuZGF0YSA9IHJvd3M7XHJcbiAgICAgICAgICAvLyB0aGlzLmRhdGEgPSB0aGlzLmRhdGEuY29uY2F0KCk7XHJcblxyXG4gICAgICAgICAgaWYgKGV2ZW50KSBldmVudC50YXJnZXQuY29tcGxldGUoKTtcclxuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgfSlcclxuICAgIH0sIDcwMCk7XHJcbiAgfVxyXG4gIGFzeW5jIGhhbmRsZVJlZnJlc2goZXZlbnQpIHtcclxuICAgIHRoaXMucGFnZUluZGV4ID0gMVxyXG4gICAgdGhpcy5kYXRhID0gW107XHJcbiAgICB0aGlzLmxvYWREYXRhKCk7XHJcbiAgICBldmVudC50YXJnZXQuY29tcGxldGUoKTtcclxuICB9XHJcbiAgb25BZGQoKSB7XHJcbiAgICBjb25zb2xlLmxvZyh0aGlzLmJhc2VQYXRoKVxyXG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3RoaXMuYmFzZVBhdGggKyAnL2FkZCddKVxyXG4gICAgLy8gdGhpcy5uYXZDdHJsLm5hdmlnYXRlRm9yd2FyZCh0aGlzLmJhc2VQYXRoICsgJy9hZGQnKTtcclxuICB9XHJcbiAgZWRpdE1vZGVsKG1vZGVsOiBCYXNlTW9kZWxGb3JtbHkpIHtcclxuICAgIGlmICh0aGlzLmNhbkVkaXQpXHJcbiAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFt0aGlzLmJhc2VQYXRoICsgJy9lZGl0LycsIG1vZGVsLmlkXSk7XHJcbiAgICAvLyB0aGlzLm5hdkN0cmwubmF2aWdhdGVGb3J3YXJkKHRoaXMuYmFzZVBhdGggKyAnL2VkaXQvJyArIG1vZGVsLmlkKTtcclxuICB9XHJcbiAgZ2V0TGlzdExheW91dCgpIHtcclxuICAgIGlmICghdGhpcy5tb2RlbCkge1xyXG4gICAgICB0aGlzLm1vZGVsID0gdGhpcy5tb2RlbFNlcnZpY2UubmV3TW9kZWwoKTsgICAgXHJcbiAgICB9XHJcbiAgICB0aGlzLmFsbENvbHVtbnM9W107XHJcbiAgICB0aGlzLmNvbHVtbnM9W107XHJcbiAgICB0aGlzLmFsbENvbHVtbnMgPSBSZWZsZWN0LmdldE1ldGFkYXRhKCdJb25pY0RhdGFUYWJsZUxheW91dCcsIHRoaXMubW9kZWwpLm1hcCgoaXRlbTogSW9uaWNEYXRhVGFibGVMYXlvdXRDb25maWcpID0+IHtcclxuICAgICAgaWYgKCFpdGVtLmlzVHJhbnNsYXRlZCkge1xyXG4gICAgICAgIGl0ZW0ubmFtZSA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoaXRlbS5uYW1lKTtcclxuICAgICAgICBpdGVtLmlzVHJhbnNsYXRlZCA9IHRydWVcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gaXRlbTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWxsQ29sdW1ucy5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XHJcblxyXG4gICAgaWYgKHRoaXMuY2FuRGVsZXRlIHx8IHRoaXMuY2FuRWRpdCkge1xyXG4gICAgICB0aGlzLmFsbENvbHVtbnMucHVzaCh7XHJcbiAgICAgICAgY2VsbFRlbXBsYXRlOiB0aGlzLmFjdGlvbnNUbXBsLFxyXG4gICAgICAgIG5hbWU6ICcnLFxyXG4gICAgICAgIGNlbGxDbGFzczogJ2FjdGlvbnMtY2VsbCcsXHJcbiAgICAgICAgZHJhZ2dhYmxlOiBmYWxzZSxcclxuICAgICAgICBzb3J0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgdmlzaWJsZTogdHJ1ZVxyXG4gICAgICAgIC8vIHdpZHRoOiAxMDAsXHJcbiAgICAgICAgLy8gbWF4V2lkdGg6IDEwMCxcclxuICAgICAgICAvLyBtaW5XaWR0aDogMTAwXHJcbiAgICAgIH0pXHJcbiAgICB9XHJcbiAgICB0aGlzLmNvbHVtbnMgPSB0aGlzLmFsbENvbHVtbnMuZmlsdGVyKChpdGVtOiBJb25pY0RhdGFUYWJsZUxheW91dENvbmZpZykgPT4gaXRlbS52aXNpYmxlKTtcclxuICAgIC8vIFNvcnQgdGhlIGNvbHVtbnMgYXJyYXkgYnkgdGhlIG9yZGVyIHByb3BlcnR5XHJcblxyXG4gIH1cclxuICBkZWxldGVNb2RlbChtb2RlbCkge1xyXG4gICAgY29uc3QgbXNnID0gJ0RvIHlvdSB3YW50IHRvIGRlbGV0ZSAnICsgbW9kZWxbdGhpcy5kZWxldGVQcm9wZXJ0eU5hbWVdICsgJz8nO1xyXG4gICAgdGhpcy5kaWFsb2dTZXJ2aWNlLmNvbmZpcm0obXNnKS50aGVuKFxyXG4gICAgICAodmFsdWU6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmICh2YWx1ZS5kYXRhKSB7XHJcbiAgICAgICAgICB0aGlzLm1vZGVsU2VydmljZS5kZWxldGUobW9kZWwuaWQpLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRlbXBEYXRhID0gW107XHJcbiAgICAgICAgICAgIC8vIHRoaXMuc2VsZWN0ZWRPYmplY3QuZW1pdChudWxsKTtcclxuICAgICAgICAgICAgdGhpcy5kYXRhLm1hcCgoaXRlbSkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmIChpdGVtLmlkICE9PSBtb2RlbC5pZCkge1xyXG4gICAgICAgICAgICAgICAgdGVtcERhdGEucHVzaChpdGVtKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLmRhdGEgPSB0ZW1wRGF0YTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgZGVsZXRlRW5hYmxlZChtb2RlbDogVCkge1xyXG4gICAgaWYgKHRoaXMuY2FuRGVsZXRlKSB7XHJcbiAgICAgIGlmICh0aGlzLmRlbGV0ZURpc2FibGVSdWxlKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZhbHVhdGVSdWxlKHRoaXMuZGVsZXRlRGlzYWJsZVJ1bGUsIG1vZGVsKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuICBwcml2YXRlIGV2YWx1YXRlUnVsZShydWxlczogUnVsZVtdLCBtb2RlbDogVCk6IGJvb2xlYW4ge1xyXG4gICAgbGV0IHJlc3VsdCA9IHRydWU7XHJcbiAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xyXG4gICAgICBsZXQganNvblJ1bGU6IGFueTtcclxuICAgICAgaWYgKHR5cGVvZiBydWxlLnJ1bGUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAganNvblJ1bGUgPSBKU09OLnBhcnNlKHJ1bGUucnVsZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAganNvblJ1bGUgPSBydWxlLnJ1bGU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHJ1bGUucGFyYW1ldGVycykge1xyXG4gICAgICAgIGNvbnN0IGRhdGEgPSAneycgKyBydWxlLnBhcmFtZXRlcnMubWFwKChpdGVtOiBzdHJpbmcpID0+IHtcclxuICAgICAgICAgIHJldHVybiAnXCInICsgaXRlbSArICdcIjpcIicgKyBtb2RlbFtpdGVtXSArICdcIic7XHJcbiAgICAgICAgfSkuam9pbignLCcpICsgJ30nO1xyXG4gICAgICAgIHJlc3VsdCA9IGpzb25Mb2dpYy5hcHBseShqc29uUnVsZSwgSlNPTi5wYXJzZShkYXRhKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmVzdWx0ID0ganNvbkxvZ2ljLmFwcGx5KGpzb25SdWxlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcblxyXG59XHJcbiIsIjxpb24taGVhZGVyICpuZ0lmPVwic2hvd0hlYWRlclwiPlxyXG4gIDxpb24tdG9vbGJhcj5cclxuICAgIDxpb24tYnV0dG9ucyBzbG90PVwic3RhcnRcIj5cclxuICAgICAgPGlvbi1tZW51LWJ1dHRvbj48L2lvbi1tZW51LWJ1dHRvbj5cclxuICAgICAgPGlvbi1iYWNrLWJ1dHRvbj48L2lvbi1iYWNrLWJ1dHRvbj5cclxuICAgIDwvaW9uLWJ1dHRvbnM+XHJcbiAgICA8bmctY29udGFpbmVyIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImhlYWRlclwiPjwvbmctY29udGFpbmVyPlxyXG4gIDwvaW9uLXRvb2xiYXI+XHJcbiAgPG5nLWNvbnRhaW5lciBbbmdUZW1wbGF0ZU91dGxldF09XCJzZWFyY2hcIj48L25nLWNvbnRhaW5lcj5cclxuPC9pb24taGVhZGVyPlxyXG5cclxuPGlvbi1jb250ZW50IFtmdWxsc2NyZWVuXT1cInRydWVcIj5cclxuXHJcbiAgPGlvbi1yZWZyZXNoZXIgc2xvdD1cImZpeGVkXCIgKGlvblJlZnJlc2gpPVwiaGFuZGxlUmVmcmVzaCgkZXZlbnQpXCI+XHJcbiAgICA8aW9uLXJlZnJlc2hlci1jb250ZW50PjwvaW9uLXJlZnJlc2hlci1jb250ZW50PlxyXG4gIDwvaW9uLXJlZnJlc2hlcj5cclxuXHJcbiAgPG5neC1kYXRhdGFibGUgY2xhc3M9XCJtYXRlcmlhbCBmdWxsc2NyZWVuIHJscy1zZXJ2ZXItc2Nyb2xsaW5nXCIgc3R5bGU9XCJ0b3A6IDExNXB4XCIgW3Jvd3NdPVwiZGF0YVwiIFtjb2x1bW5zXT1cImNvbHVtbnNcIlxyXG4gICAgW2NvbHVtbk1vZGVdPVwiQ29sdW1uTW9kZS5zdGFuZGFyZFwiIFtoZWFkZXJIZWlnaHRdPVwiaGVhZGVySGVpZ2h0XCIgW3Jvd0hlaWdodF09XCJyb3dIZWlnaHRcIiBbc2Nyb2xsYmFyVl09XCJ0cnVlXCJcclxuICAgIFtsb2FkaW5nSW5kaWNhdG9yXT1cImlzTG9hZGluZ1wiIFtzY3JvbGxiYXJIXT1cInRydWVcIiAoc2Nyb2xsKT1cIm9uU2Nyb2xsKCRldmVudC5vZmZzZXRZKVwiXHJcbiAgID5cclxuICA8L25neC1kYXRhdGFibGU+XHJcbiAgXHJcbiAgPG5nLXRlbXBsYXRlICNhY3Rpb25zVG1wbCBsZXQtcm93PVwicm93XCIgbGV0LXZhbHVlPVwidmFsdWVcIj5cclxuICAgIDxpb24tYnV0dG9uICBmaWxsPVwiY2xlYXJcIiAqbmdJZj1cImNhbkVkaXRcIiAoY2xpY2spPSdlZGl0TW9kZWwocm93KSc+XHJcbiAgICAgIDxpb24taWNvbiBzbG90PVwiaWNvbi1vbmx5XCIgbmFtZT1cImNyZWF0ZVwiIChjbGljayk9J2VkaXRNb2RlbChyb3cpJz48L2lvbi1pY29uPlxyXG4gICAgPC9pb24tYnV0dG9uPlxyXG4gICAgPGlvbi1idXR0b24gZmlsbD1cImNsZWFyXCIgKm5nSWY9XCJkZWxldGVFbmFibGVkKHJvdylcIiAoY2xpY2spPSdkZWxldGVNb2RlbChyb3cpJz5cclxuICAgICAgPGlvbi1pY29uIGNvbG9yPVwiZGFuZ2VyXCIgc2xvdD1cImljb24tb25seVwiIG5hbWU9XCJ0cmFzaFwiIChjbGljayk9J2RlbGV0ZU1vZGVsKHJvdyknPjwvaW9uLWljb24+XHJcbiAgICA8L2lvbi1idXR0b24+XHJcbiAgPC9uZy10ZW1wbGF0ZT5cclxuXHJcbjwvaW9uLWNvbnRlbnQ+XHJcblxyXG48bmctdGVtcGxhdGUgI2hlYWRlcj5cclxuICA8aW9uLXRpdGxlIGNsYXNzPVwiaW9uLXRleHQtY2VudGVyXCI+e3t0aXRsZX19PC9pb24tdGl0bGU+XHJcbiAgPGlvbi1idXR0b24gc2xvdD1cImVuZFwiIChjbGljayk9XCJvbkFkZCgpXCIgZmlsbD1cImNsZWFyXCIgKm5nSWY9XCJoYXNBZGRcIj5cclxuICAgIDxpb24taWNvbiBzaXplPVwibGFyZ2VcIiBuYW1lPVwiYWRkXCI+PC9pb24taWNvbj5cclxuICA8L2lvbi1idXR0b24+XHJcbjwvbmctdGVtcGxhdGU+XHJcblxyXG48bmctdGVtcGxhdGUgI3NlYXJjaD5cclxuICA8aW9uLXRvb2xiYXIgKm5nSWY9XCJzaG93U2VyYWNoXCI+XHJcbiAgICA8aW9uLXNlYXJjaGJhciBbZGVib3VuY2VdPVwiMTAwMFwiIChpb25DaGFuZ2UpPVwiaGFuZGxlQ2hhbmdlKCRldmVudClcIj48L2lvbi1zZWFyY2hiYXI+XHJcbiAgPC9pb24tdG9vbGJhcj5cclxuPC9uZy10ZW1wbGF0ZT4iXX0=