http-request-manager 0.0.20 → 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -258
- package/esm2022/lib/http-request-manager.module.mjs +145 -0
- package/esm2022/lib/http-request-services-demo/http-request-services-demo.component.mjs +41 -0
- package/esm2022/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.mjs +175 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.mjs +80 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.mjs +42 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.mjs +85 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.mjs +11 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.mjs +29 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.mjs +9 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.mjs +12 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.mjs +10 -0
- package/esm2022/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.mjs +276 -0
- package/esm2022/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.mjs +268 -0
- package/esm2022/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.mjs +75 -0
- package/esm2022/lib/index.mjs +4 -0
- package/esm2022/lib/interceptors/proxy-debugger.interceptor.mjs +47 -0
- package/esm2022/lib/interceptors/request-error.interceptor.mjs +5 -5
- package/esm2022/lib/models/config-http-options.model.mjs +18 -0
- package/esm2022/lib/models/config-local-storage-options.model.mjs +12 -0
- package/esm2022/lib/models/config-options.model.mjs +12 -0
- package/esm2022/lib/models/config-token.model.mjs +8 -0
- package/esm2022/lib/models/index.mjs +4 -1
- package/esm2022/lib/models/retry-options.model.mjs +3 -3
- package/esm2022/lib/services/index.mjs +1 -1
- package/esm2022/lib/services/local-storage-manager-service/local-storage-manager.service.mjs +34 -9
- package/esm2022/lib/services/local-storage-manager-service/models/index.mjs +1 -2
- package/esm2022/lib/services/local-storage-manager-service/models/setting-options.model.mjs +2 -2
- package/esm2022/lib/services/local-storage-manager-service/models/storage-option.model.mjs +3 -3
- package/esm2022/lib/services/request-manager-services/http-manager.service.mjs +87 -51
- package/esm2022/lib/services/request-manager-services/request.service.mjs +70 -28
- package/esm2022/lib/services/request-manager-services/rxjs-operators/delay-retry.mjs +7 -5
- package/esm2022/lib/services/request-manager-services/rxjs-operators/request-streaming.mjs +1 -1
- package/esm2022/lib/services/request-manager-state-service/http-manager-state.store.mjs +6 -39
- package/esm2022/lib/services/utils/app.service.mjs +7 -1
- package/esm2022/lib/services/utils/object-merger.service.mjs +34 -0
- package/esm2022/lib/services/utils/path-query.service.mjs +2 -1
- package/esm2022/lib/services/utils/utils.service.mjs +23 -2
- package/esm2022/public-api.mjs +4 -4
- package/fesm2022/http-request-manager.mjs +1782 -435
- package/fesm2022/http-request-manager.mjs.map +1 -1
- package/http-request-manager-4.1.3.tgz +0 -0
- package/lib/http-request-manager.module.d.ts +33 -0
- package/lib/http-request-services-demo/http-request-services-demo.component.d.ts +24 -0
- package/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.d.ts +56 -0
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/download-file/download-file.component.d.ts +26 -0
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-download.module.d.ts +13 -0
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/file-downloader.component.d.ts +26 -0
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/models/download-labels-model.d.ts +12 -0
- package/lib/http-request-services-demo/request-manager-demo/file-downloader/spinner/spinner.component.d.ts +16 -0
- package/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.d.ts +8 -0
- package/lib/http-request-services-demo/request-manager-demo/models/sample-client-info.d.ts +14 -0
- package/lib/http-request-services-demo/request-manager-demo/models/sample-mapper-client-info.d.ts +10 -0
- package/lib/http-request-services-demo/request-manager-demo/request-manager-demo.component.d.ts +98 -0
- package/lib/http-request-services-demo/request-manager-state-demo/request-manager-state-demo.component.d.ts +110 -0
- package/lib/http-request-services-demo/request-manager-state-demo/services/state-manager-demo.service.d.ts +16 -0
- package/lib/index.d.ts +3 -0
- package/lib/interceptors/proxy-debugger.interceptor.d.ts +12 -0
- package/lib/interceptors/request-error.interceptor.d.ts +1 -1
- package/lib/models/config-http-options.model.d.ts +21 -0
- package/lib/models/config-local-storage-options.model.d.ts +13 -0
- package/lib/models/config-options.model.d.ts +12 -0
- package/lib/models/config-token.model.d.ts +8 -0
- package/lib/models/index.d.ts +3 -0
- package/lib/services/local-storage-manager-service/local-storage-manager.service.d.ts +7 -2
- package/lib/services/local-storage-manager-service/models/index.d.ts +0 -1
- package/lib/services/local-storage-manager-service/models/setting-options.model.d.ts +2 -2
- package/lib/services/local-storage-manager-service/models/storage-option.model.d.ts +4 -4
- package/lib/services/request-manager-services/http-manager.service.d.ts +12 -7
- package/lib/services/request-manager-services/request.service.d.ts +1 -0
- package/lib/services/request-manager-services/rxjs-operators/delay-retry.d.ts +1 -1
- package/lib/services/request-manager-state-service/http-manager-state.store.d.ts +11 -15
- package/lib/services/utils/object-merger.service.d.ts +7 -0
- package/lib/services/utils/utils.service.d.ts +1 -1
- package/package.json +27 -18
- package/public-api.d.ts +3 -3
- package/esm2022/lib/services/local-storage-manager-service/models/storage-option-settings.model.mjs +0 -13
- package/http-request-manager-0.0.20.tgz +0 -0
- package/lib/services/local-storage-manager-service/models/storage-option-settings.model.d.ts +0 -15
package/esm2022/lib/http-request-services-demo/local-storage-demo/local-storage-demo.component.mjs
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Component, Inject, inject, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { LocalStorageManagerService, SettingOptions, StorageType } from '../../services/local-storage-manager-service';
|
|
3
|
+
import { FormBuilder, Validators } from '@angular/forms';
|
|
4
|
+
import { BehaviorSubject, EMPTY, of } from 'rxjs';
|
|
5
|
+
import { UtilsService } from '../../services';
|
|
6
|
+
import { switchMap, tap, map } from 'rxjs/operators';
|
|
7
|
+
import { CONFIG_SETTINGS_TOKEN } from '../../models/config-token.model';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/common";
|
|
10
|
+
import * as i2 from "@angular/forms";
|
|
11
|
+
import * as i3 from "@angular/material/button";
|
|
12
|
+
import * as i4 from "@angular/material/form-field";
|
|
13
|
+
import * as i5 from "@angular/material/select";
|
|
14
|
+
import * as i6 from "@angular/material/core";
|
|
15
|
+
import * as i7 from "@angular/material/menu";
|
|
16
|
+
import * as i8 from "@angular/material/icon";
|
|
17
|
+
import * as i9 from "@angular/material/table";
|
|
18
|
+
import * as i10 from "@angular/material/button-toggle";
|
|
19
|
+
import * as i11 from "@angular/material/slide-toggle";
|
|
20
|
+
import * as i12 from "@angular/material/divider";
|
|
21
|
+
import * as i13 from "@angular/material/input";
|
|
22
|
+
import * as i14 from "../../services";
|
|
23
|
+
export class LocalStorageDemoComponent {
|
|
24
|
+
get type() {
|
|
25
|
+
return (this.typeControl.value) ? +this.typeControl.value : 0;
|
|
26
|
+
}
|
|
27
|
+
get isValid() {
|
|
28
|
+
return this.newStoreForm.valid;
|
|
29
|
+
}
|
|
30
|
+
get isValidData() {
|
|
31
|
+
return this.storageForm.valid;
|
|
32
|
+
}
|
|
33
|
+
constructor(configOptions) {
|
|
34
|
+
this.configOptions = configOptions;
|
|
35
|
+
this.fb = inject(FormBuilder);
|
|
36
|
+
this.utils = inject(UtilsService);
|
|
37
|
+
this.type$ = new BehaviorSubject(StorageType.GLOBAL);
|
|
38
|
+
this.typeControl = this.fb.control(StorageType.GLOBAL.toString());
|
|
39
|
+
this.localStorageManagerService = inject(LocalStorageManagerService);
|
|
40
|
+
this.settings$ = this.localStorageManagerService.settings$;
|
|
41
|
+
this.setting$ = (store) => this.localStorageManagerService.setting$(store);
|
|
42
|
+
this.storageForm = this.fb.group({
|
|
43
|
+
store: this.fb.control(null),
|
|
44
|
+
type: 'local',
|
|
45
|
+
settingType: 'local',
|
|
46
|
+
encrypted: false,
|
|
47
|
+
data: this.fb.control('', Validators.required),
|
|
48
|
+
});
|
|
49
|
+
this.newStoreForm = this.fb.group({
|
|
50
|
+
name: this.fb.control(null, Validators.required),
|
|
51
|
+
storage: 'local',
|
|
52
|
+
encrypted: false,
|
|
53
|
+
data: this.fb.control('', Validators.required),
|
|
54
|
+
expiresIn: this.fb.control('0')
|
|
55
|
+
});
|
|
56
|
+
this.storeData$ = this.storageForm.get('store')?.valueChanges
|
|
57
|
+
.pipe(switchMap((data) => {
|
|
58
|
+
return data
|
|
59
|
+
? this.localStorageManagerService.store$(data.name)
|
|
60
|
+
: of('');
|
|
61
|
+
}), tap(data => {
|
|
62
|
+
this.storageForm.get('data')?.patchValue(data, { emitEvent: false });
|
|
63
|
+
}));
|
|
64
|
+
this.expiresIn = (epoch) => this.utils.expiresIn(epoch);
|
|
65
|
+
this.isValidJSON = (str) => {
|
|
66
|
+
try {
|
|
67
|
+
JSON.parse(str);
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
this.displayedColumns = ['name', 'id', 'encrypted', 'expires', "option"];
|
|
75
|
+
this.filterData = (values) => {
|
|
76
|
+
if (!values)
|
|
77
|
+
return [];
|
|
78
|
+
return values.filter((item) => item.options.storage === +this.type);
|
|
79
|
+
};
|
|
80
|
+
this.create = false;
|
|
81
|
+
}
|
|
82
|
+
ngOnInit() {
|
|
83
|
+
this.storeProps = this.configOptions?.LocalStorageOptions;
|
|
84
|
+
this.options = this.storeProps?.options;
|
|
85
|
+
if (this.options?.storage) {
|
|
86
|
+
this.typeControl.patchValue(this.options.storage.toString());
|
|
87
|
+
this.typeControl.disable();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.typeControl.enable();
|
|
91
|
+
}
|
|
92
|
+
if (this.options?.expiresIn) {
|
|
93
|
+
this.newStoreForm.get('expiresIn')?.patchValue(this.options.expiresIn);
|
|
94
|
+
this.newStoreForm.get('expiresIn')?.disable();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.newStoreForm.get('expiresIn')?.enable();
|
|
98
|
+
}
|
|
99
|
+
if (this.options?.encrypted) {
|
|
100
|
+
this.newStoreForm.get('encrypted')?.patchValue(this.options.encrypted);
|
|
101
|
+
this.newStoreForm.get('encrypted')?.disable();
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.newStoreForm.get('encrypted')?.enable();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
onCreateStore() {
|
|
108
|
+
if (!this.isValid)
|
|
109
|
+
return;
|
|
110
|
+
const store = this.newStoreForm.value;
|
|
111
|
+
if (!store.name || store.name === '')
|
|
112
|
+
return;
|
|
113
|
+
const options = { storage: this.type, encrypted: store.encrypted, expiresIn: store.expiresIn };
|
|
114
|
+
this.localStorageManagerService.createStore({
|
|
115
|
+
name: store.name,
|
|
116
|
+
data: store.data,
|
|
117
|
+
options: SettingOptions.adapt(options)
|
|
118
|
+
});
|
|
119
|
+
this.newStoreForm.reset();
|
|
120
|
+
this.create = false;
|
|
121
|
+
}
|
|
122
|
+
onUpdateStore(store) {
|
|
123
|
+
if (!this.storageForm.valid)
|
|
124
|
+
return;
|
|
125
|
+
const storeData = this.storageForm.value;
|
|
126
|
+
const data = JSON.parse(storeData.data || '');
|
|
127
|
+
const type = (storeData.type === 'local') ? StorageType.GLOBAL : StorageType.SESSION;
|
|
128
|
+
const options = { storage: type, encrypted: storeData.encrypted };
|
|
129
|
+
this.localStorageManagerService.updateStore({
|
|
130
|
+
name: store.name,
|
|
131
|
+
data
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
onSelectedRow(store) {
|
|
135
|
+
this.store = store;
|
|
136
|
+
this.data$ = this.localStorageManagerService.store$(store.name).pipe(map(item => JSON.stringify(item)));
|
|
137
|
+
this.create = false;
|
|
138
|
+
}
|
|
139
|
+
onCreate() {
|
|
140
|
+
this.onCancel();
|
|
141
|
+
this.create = true;
|
|
142
|
+
}
|
|
143
|
+
onDelete(store) {
|
|
144
|
+
console.log('DELETED STORE:', store);
|
|
145
|
+
this.localStorageManagerService.deleteStore({
|
|
146
|
+
name: store.name,
|
|
147
|
+
});
|
|
148
|
+
this.onCancel();
|
|
149
|
+
}
|
|
150
|
+
onCancel() {
|
|
151
|
+
this.data$ = EMPTY;
|
|
152
|
+
this.store = null;
|
|
153
|
+
this.create = false;
|
|
154
|
+
}
|
|
155
|
+
onUpdate(store, data) {
|
|
156
|
+
this.localStorageManagerService.updateStore({
|
|
157
|
+
name: store.name,
|
|
158
|
+
data: JSON.parse(data)
|
|
159
|
+
});
|
|
160
|
+
this.onCancel();
|
|
161
|
+
}
|
|
162
|
+
onReset() {
|
|
163
|
+
this.localStorageManagerService.resetStore();
|
|
164
|
+
}
|
|
165
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageDemoComponent, deps: [{ token: CONFIG_SETTINGS_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
166
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: LocalStorageDemoComponent, selector: "app-local-storage-demo", ngImport: i0, template: "<div style=\"margin: 2rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n <h2 style=\"padding-top: .5rem; display: flex;\">\n <div style=\"padding-top: .5rem;\">Local Storage Manager</div>\n <div>\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>info</mat-icon>\n </button>\n </div>\n </h2>\n <span style=\"flex:1\"></span>\n <div style=\"padding-top: .25rem;\">\n <mat-button-toggle-group name=\"storage\" [formControl]=\"typeControl\" (change)=\"onCancel()\">\n <mat-button-toggle value=\"0\">Local Storage</mat-button-toggle>\n <mat-button-toggle value=\"1\">Session Storage</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"margin-top: .25rem;\">\n <button mat-icon-button (click)=\"onCreate()\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"storeProps?.storageName || storeProps?.storageSettingsName\">\n <div style=\"display: flex; gap: .5rem; flex-direction: column; border: gray solid thin; background-color: whitesmoke; padding: 1rem;\"\n >\n <div style=\"display: flex;\">\n <div *ngIf=\"storeProps?.storageSettingsName\" style=\"flex:1\">\n Database: <b>{{ storeProps?.storageSettingsName }}</b>\n </div>\n <div *ngIf=\"storeProps?.storageName\" style=\"flex:1\">\n Data: <b>{{ storeProps?.storageName }}</b>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div style=\"margin-top: 2rem;\" [formGroup]=\"newStoreForm\" *ngIf=\"create; else LIST\">\n\n <h2>Create Store</h2>\n\n <div style=\"display: flex; gap: 1rem;\">\n <div style=\"flex:1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Store Name</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"name\">\n </mat-form-field>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In...</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"0\">None</mat-option>\n <mat-option value=\"30s\">30 Seconds</mat-option>\n <mat-option value=\"1mn\">1 Minute</mat-option>\n <mat-option value=\"1hr\">1 Hour</mat-option>\n <mat-option value=\"1d\">1 Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"margin-top: 1rem;\">\n <mat-slide-toggle formControlName=\"encrypted\">Encrypted</mat-slide-toggle>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" formControlName=\"data\" #json></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCreateStore()\" [disabled]=\"!(isValid && isValidJSON(json.value))\">\n Save Store\n </button>\n </div>\n\n </div>\n\n <ng-template #LIST>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n{{ settings$ | async | json }}\n <div *ngIf=\"filterData(settings$ | async) as data\">\n <ng-container *ngIf=\"data.length > 0; else NO_DATA\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Store </th>\n <td mat-cell *matCellDef=\"let element\" style=\"font-weight: bold; text-transform: uppercase;\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"encrypted\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Encrypted </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.encrypted; else NO\">YES</ng-container>\n <ng-template #NO><span style=\"color:gray\">NO</span></ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Expires </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.expires !== 0; else NO_DATA\">\n {{expiresIn(element.options.expires)}}\n </ng-container>\n <ng-template #NO_DATA>\n \u221E\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"option\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let element\" style=\"padding-right: 0;\">\n <div style=\"display: flex;justify-content: flex-end;\">\n <button mat-icon-button color=\"warn\" (click)=\"onDelete(element); $event.stopPropagation()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"onSelectedRow(row)\"></tr>\n </table>\n </ng-container>\n\n <ng-template #NO_DATA>\n <h3 style=\"margin-top: 1rem;\">No Data</h3>\n </ng-template>\n\n <div *ngIf=\"(data$ | async) as data\" style=\"margin-top: 2rem;\">\n <div style=\"margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h3>STORE: <span style=\"font-weight: bold;\">{{ store.name | uppercase }}</span></h3>\n <h3>SETTINGS: {{ setting$(store.name) | async | json }}</h3>\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" #json [value]=\"data\"></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex; gap: .5rem;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCancel()\">Cancel</button>\n <button mat-stroked-button (click)=\"onUpdate(store, json.value)\" [disabled]=\"!(isValidJSON(json.value))\">Update</button>\n </div>\n </div>\n </div>\n\n </ng-template>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <button mat-stroked-button (click)=\"onReset()\">Delete All Stores</button>\n </div>\n\n</div>\n\n\n<mat-menu #menu=\"matMenu\">\n <div style=\"padding: 1rem;\">\n <p>Please note that the LocalStorage (encryption) and management of data is dependant on initializing the APP_ID</p>\n <p>Must provide a value for <b>APP_ID</b> in AppModule->Providers</p>\n <mat-divider></mat-divider>\n <div style=\"font-size: smaller; margin-top: .5rem;\">\n <p>Example: UUID (self.crypto.randomUUID() to generate)</p>\n <div style=\"background-color: whitesmoke; padding: 1rem;\">\n {<br>\n provide: APP_ID,<br>\n useValue: \"056991ac-3537-43ab-b5b9-83edf6554eff\",<br>\n }\n </div>\n </div>\n </div>\n</mat-menu>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.demo-row-is-clicked{font-weight:700}.mat-mdc-menu-panel.mat-mdc-menu-panel{max-width:280px!important}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i3.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "panelWidth", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i10.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i10.MatButtonToggle, selector: "mat-button-toggle", inputs: ["disableRipple", "aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "appearance", "checked", "disabled"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: i11.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matSlideToggle"] }, { kind: "component", type: i12.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i13.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1.JsonPipe, name: "json" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
167
|
+
}
|
|
168
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: LocalStorageDemoComponent, decorators: [{
|
|
169
|
+
type: Component,
|
|
170
|
+
args: [{ selector: 'app-local-storage-demo', encapsulation: ViewEncapsulation.None, template: "<div style=\"margin: 2rem;\">\n\n <div style=\"display: flex; gap: 1rem\">\n <h2 style=\"padding-top: .5rem; display: flex;\">\n <div style=\"padding-top: .5rem;\">Local Storage Manager</div>\n <div>\n <button mat-icon-button [matMenuTriggerFor]=\"menu\">\n <mat-icon>info</mat-icon>\n </button>\n </div>\n </h2>\n <span style=\"flex:1\"></span>\n <div style=\"padding-top: .25rem;\">\n <mat-button-toggle-group name=\"storage\" [formControl]=\"typeControl\" (change)=\"onCancel()\">\n <mat-button-toggle value=\"0\">Local Storage</mat-button-toggle>\n <mat-button-toggle value=\"1\">Session Storage</mat-button-toggle>\n </mat-button-toggle-group>\n </div>\n <div style=\"margin-top: .25rem;\">\n <button mat-icon-button (click)=\"onCreate()\">\n <mat-icon>add</mat-icon>\n </button>\n </div>\n </div>\n\n <ng-container *ngIf=\"storeProps?.storageName || storeProps?.storageSettingsName\">\n <div style=\"display: flex; gap: .5rem; flex-direction: column; border: gray solid thin; background-color: whitesmoke; padding: 1rem;\"\n >\n <div style=\"display: flex;\">\n <div *ngIf=\"storeProps?.storageSettingsName\" style=\"flex:1\">\n Database: <b>{{ storeProps?.storageSettingsName }}</b>\n </div>\n <div *ngIf=\"storeProps?.storageName\" style=\"flex:1\">\n Data: <b>{{ storeProps?.storageName }}</b>\n </div>\n </div>\n </div>\n </ng-container>\n\n <div style=\"margin-top: 2rem;\" [formGroup]=\"newStoreForm\" *ngIf=\"create; else LIST\">\n\n <h2>Create Store</h2>\n\n <div style=\"display: flex; gap: 1rem;\">\n <div style=\"flex:1\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Store Name</mat-label>\n <input matInput placeholder=\"sample\" formControlName=\"name\">\n </mat-form-field>\n </div>\n <div>\n <mat-form-field appearance=\"outline\">\n <mat-label>Expires In...</mat-label>\n <mat-select formControlName=\"expiresIn\">\n <mat-option value=\"0\">None</mat-option>\n <mat-option value=\"30s\">30 Seconds</mat-option>\n <mat-option value=\"1mn\">1 Minute</mat-option>\n <mat-option value=\"1hr\">1 Hour</mat-option>\n <mat-option value=\"1d\">1 Day</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n <div style=\"margin-top: 1rem;\">\n <mat-slide-toggle formControlName=\"encrypted\">Encrypted</mat-slide-toggle>\n </div>\n </div>\n\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" formControlName=\"data\" #json></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCreateStore()\" [disabled]=\"!(isValid && isValidJSON(json.value))\">\n Save Store\n </button>\n </div>\n\n </div>\n\n <ng-template #LIST>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n{{ settings$ | async | json }}\n <div *ngIf=\"filterData(settings$ | async) as data\">\n <ng-container *ngIf=\"data.length > 0; else NO_DATA\">\n <table mat-table [dataSource]=\"data\">\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef> Store </th>\n <td mat-cell *matCellDef=\"let element\" style=\"font-weight: bold; text-transform: uppercase;\"> {{element.name}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"id\">\n <th mat-header-cell *matHeaderCellDef> ID </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.id}} </td>\n </ng-container>\n\n <ng-container matColumnDef=\"encrypted\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Encrypted </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.encrypted; else NO\">YES</ng-container>\n <ng-template #NO><span style=\"color:gray\">NO</span></ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expires\">\n <th mat-header-cell *matHeaderCellDef style=\"text-align: center;\"> Expires </th>\n <td mat-cell *matCellDef=\"let element\" style=\"text-align: center;\">\n <ng-container *ngIf=\"element.options.expires !== 0; else NO_DATA\">\n {{expiresIn(element.options.expires)}}\n </ng-container>\n <ng-template #NO_DATA>\n \u221E\n </ng-template>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"option\">\n <th mat-header-cell *matHeaderCellDef></th>\n <td mat-cell *matCellDef=\"let element\" style=\"padding-right: 0;\">\n <div style=\"display: flex;justify-content: flex-end;\">\n <button mat-icon-button color=\"warn\" (click)=\"onDelete(element); $event.stopPropagation()\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\" (click)=\"onSelectedRow(row)\"></tr>\n </table>\n </ng-container>\n\n <ng-template #NO_DATA>\n <h3 style=\"margin-top: 1rem;\">No Data</h3>\n </ng-template>\n\n <div *ngIf=\"(data$ | async) as data\" style=\"margin-top: 2rem;\">\n <div style=\"margin-bottom: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <h3>STORE: <span style=\"font-weight: bold;\">{{ store.name | uppercase }}</span></h3>\n <h3>SETTINGS: {{ setting$(store.name) | async | json }}</h3>\n <div style=\"display: flex;\">\n <mat-form-field appearance=\"outline\" style=\"flex: 1;\">\n <mat-label>Data (Must be an Object or Array of any)</mat-label>\n <textarea matInput placeholder=\"[]\" #json [value]=\"data\"></textarea>\n </mat-form-field>\n </div>\n <mat-error *ngIf=\"!isValidJSON(json.value)\">Not Valid Data</mat-error>\n\n <div style=\"display: flex; gap: .5rem;\">\n <span style=\"flex:1\"></span>\n <button mat-stroked-button (click)=\"onCancel()\">Cancel</button>\n <button mat-stroked-button (click)=\"onUpdate(store, json.value)\" [disabled]=\"!(isValidJSON(json.value))\">Update</button>\n </div>\n </div>\n </div>\n\n </ng-template>\n\n <div style=\"margin-top: 1rem;\">\n <mat-divider></mat-divider>\n </div>\n\n <div style=\"margin-top: 1rem;\">\n <button mat-stroked-button (click)=\"onReset()\">Delete All Stores</button>\n </div>\n\n</div>\n\n\n<mat-menu #menu=\"matMenu\">\n <div style=\"padding: 1rem;\">\n <p>Please note that the LocalStorage (encryption) and management of data is dependant on initializing the APP_ID</p>\n <p>Must provide a value for <b>APP_ID</b> in AppModule->Providers</p>\n <mat-divider></mat-divider>\n <div style=\"font-size: smaller; margin-top: .5rem;\">\n <p>Example: UUID (self.crypto.randomUUID() to generate)</p>\n <div style=\"background-color: whitesmoke; padding: 1rem;\">\n {<br>\n provide: APP_ID,<br>\n useValue: \"056991ac-3537-43ab-b5b9-83edf6554eff\",<br>\n }\n </div>\n </div>\n </div>\n</mat-menu>\n", styles: [".mat-mdc-row .mat-mdc-cell{border-bottom:1px solid transparent;border-top:1px solid transparent;cursor:pointer}.mat-mdc-row:hover .mat-mdc-cell{border-color:currentColor}.demo-row-is-clicked{font-weight:700}.mat-mdc-menu-panel.mat-mdc-menu-panel{max-width:280px!important}\n"] }]
|
|
171
|
+
}], ctorParameters: function () { return [{ type: i14.ConfigOptions, decorators: [{
|
|
172
|
+
type: Inject,
|
|
173
|
+
args: [CONFIG_SETTINGS_TOKEN]
|
|
174
|
+
}] }]; } });
|
|
175
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYWwtc3RvcmFnZS1kZW1vLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2h0dHAtcmVxdWVzdC1tYW5hZ2VyL3NyYy9saWIvaHR0cC1yZXF1ZXN0LXNlcnZpY2VzLWRlbW8vbG9jYWwtc3RvcmFnZS1kZW1vL2xvY2FsLXN0b3JhZ2UtZGVtby5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9odHRwLXJlcXVlc3QtbWFuYWdlci9zcmMvbGliL2h0dHAtcmVxdWVzdC1zZXJ2aWNlcy1kZW1vL2xvY2FsLXN0b3JhZ2UtZGVtby9sb2NhbC1zdG9yYWdlLWRlbW8uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFVLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JGLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxjQUFjLEVBQWlCLFdBQVcsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3RJLE9BQU8sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQWMsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBc0MsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEYsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFReEUsTUFBTSxPQUFPLHlCQUF5QjtJQU1wQyxJQUFJLElBQUk7UUFDTixPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQy9ELENBQUM7SUEwQ0QsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQTtJQUNoQyxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQTtJQUMvQixDQUFDO0lBMkJELFlBQW1ELGFBQTZCO1FBQTdCLGtCQUFhLEdBQWIsYUFBYSxDQUFnQjtRQWpGaEYsT0FBRSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUN4QixVQUFLLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRTVCLFVBQUssR0FBRyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7UUFLL0MsZ0JBQVcsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7UUFFNUQsK0JBQTBCLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUE7UUFFL0QsY0FBUyxHQUFvQixJQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxDQUFBO1FBRXRFLGFBQVEsR0FBRyxDQUFDLEtBQWEsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUU3RSxnQkFBVyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQzFCLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBYyxJQUFJLENBQUM7WUFDekMsSUFBSSxFQUFFLE9BQU87WUFDYixXQUFXLEVBQUUsT0FBTztZQUNwQixTQUFTLEVBQUUsS0FBSztZQUNoQixJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQVMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7U0FDdkQsQ0FBQyxDQUFBO1FBRUYsaUJBQVksR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQWMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxRQUFRLENBQUM7WUFDN0QsT0FBTyxFQUFFLE9BQU87WUFDaEIsU0FBUyxFQUFFLEtBQUs7WUFDaEIsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFTLEVBQUUsRUFBRSxVQUFVLENBQUMsUUFBUSxDQUFDO1lBQ3RELFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7U0FDaEMsQ0FBQyxDQUFBO1FBSUYsZUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFlBQVk7YUFDdkQsSUFBSSxDQUNILFNBQVMsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQ3RCLE9BQU8sSUFBSTtnQkFDVCxDQUFDLENBQUMsSUFBSSxDQUFDLDBCQUEwQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNuRCxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ1osQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFBO1FBQ3RFLENBQUMsQ0FBQyxDQUNILENBQUE7UUFFRCxjQUFTLEdBQUcsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBVTFELGdCQUFXLEdBQUcsQ0FBQyxHQUFXLEVBQUUsRUFBRTtZQUM1QixJQUFJO2dCQUNGLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2YsT0FBTyxJQUFJLENBQUE7YUFDWjtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNWLE9BQU8sS0FBSyxDQUFBO2FBQ2I7UUFDSCxDQUFDLENBQUE7UUFFRCxxQkFBZ0IsR0FBYSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUU5RSxlQUFVLEdBQUcsQ0FBQyxNQUF3QixFQUFFLEVBQUU7WUFDeEMsSUFBRyxDQUFDLE1BQU07Z0JBQUUsT0FBTyxFQUFFLENBQUE7WUFDckIsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMxRSxDQUFDLENBQUE7UUFNRCxXQUFNLEdBQUcsS0FBSyxDQUFBO0lBS3NFLENBQUM7SUFFckYsUUFBUTtRQUVOLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxtQkFBbUIsQ0FBQTtRQUN6RCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFBO1FBRXZDLElBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUU7WUFDeEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtZQUM1RCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFBO1NBQzNCO2FBQU07WUFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFBO1NBQzFCO1FBRUQsSUFBRyxJQUFJLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRTtZQUMxQixJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtZQUN0RSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQTtTQUM5QzthQUFNO1lBQ0wsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUE7U0FDN0M7UUFFRCxJQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFO1lBQzFCLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQ3RFLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFBO1NBQzlDO2FBQU07WUFDTCxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQTtTQUM3QztJQUVILENBQUM7SUFFRCxhQUFhO1FBRVgsSUFBRyxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTTtRQUV4QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQTtRQUNyQyxJQUFHLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEVBQUU7WUFBRSxPQUFNO1FBRTNDLE1BQU0sT0FBTyxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxTQUFTLEVBQUUsQ0FBQTtRQUU5RixJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBVyxDQUFDO1lBQzFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtZQUNoQixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7WUFDaEIsT0FBTyxFQUFFLGNBQWMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO1NBQ3ZDLENBQUMsQ0FBQTtRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDekIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUE7SUFDckIsQ0FBQztJQUVELGFBQWEsQ0FBQyxLQUFVO1FBRXRCLElBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUs7WUFBRSxPQUFNO1FBRWxDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFBO1FBRXhDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUU3QyxNQUFNLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUE7UUFDcEYsTUFBTSxPQUFPLEdBQUcsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUE7UUFFakUsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFdBQVcsQ0FBQztZQUMxQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7WUFDaEIsSUFBSTtTQUNMLENBQUMsQ0FBQTtJQUVKLENBQUM7SUFFRCxhQUFhLENBQUMsS0FBVTtRQUN0QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTtRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUN2RyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQTtJQUNyQixDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQTtRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFBO0lBQ3BCLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBb0I7UUFFM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBQyxLQUFLLENBQUMsQ0FBQTtRQUVuQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBVyxDQUFDO1lBQzFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtTQUNqQixDQUFDLENBQUE7UUFFRixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUE7SUFDakIsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQTtRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQTtRQUNqQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQTtJQUNyQixDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQW9CLEVBQUUsSUFBUztRQUV0QyxJQUFJLENBQUMsMEJBQTBCLENBQUMsV0FBVyxDQUFDO1lBQzFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtZQUNoQixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7U0FDdkIsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFBO0lBRWpCLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFVBQVUsRUFBRSxDQUFBO0lBQzlDLENBQUM7K0dBL0xVLHlCQUF5QixrQkFtRmhCLHFCQUFxQjttR0FuRjlCLHlCQUF5Qiw4RENkdEMsK3RQQW1NQTs7NEZEckxhLHlCQUF5QjtrQkFOckMsU0FBUzsrQkFDRSx3QkFBd0IsaUJBR25CLGlCQUFpQixDQUFDLElBQUk7OzBCQXFGeEIsTUFBTTsyQkFBQyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEluamVjdCwgaW5qZWN0LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBMb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZSwgU2V0dGluZ09wdGlvbnMsIFN0b3JhZ2VPcHRpb24sIFN0b3JhZ2VUeXBlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbG9jYWwtc3RvcmFnZS1tYW5hZ2VyLXNlcnZpY2UnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIEVNUFRZLCBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ29uZmlnT3B0aW9ucywgTG9jYWxTdG9yYWdlT3B0aW9ucywgVXRpbHNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCB0YXAsIG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENPTkZJR19TRVRUSU5HU19UT0tFTiB9IGZyb20gJy4uLy4uL21vZGVscy9jb25maWctdG9rZW4ubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtbG9jYWwtc3RvcmFnZS1kZW1vJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2xvY2FsLXN0b3JhZ2UtZGVtby5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2xvY2FsLXN0b3JhZ2UtZGVtby5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIExvY2FsU3RvcmFnZURlbW9Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIGZiID0gaW5qZWN0KEZvcm1CdWlsZGVyKVxuICB1dGlscyA9IGluamVjdChVdGlsc1NlcnZpY2UpXG5cbiAgdHlwZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KFN0b3JhZ2VUeXBlLkdMT0JBTClcbiAgZ2V0IHR5cGUoKSB7XG4gICAgcmV0dXJuICh0aGlzLnR5cGVDb250cm9sLnZhbHVlKSA/ICt0aGlzLnR5cGVDb250cm9sLnZhbHVlIDogMFxuICB9XG5cbiAgdHlwZUNvbnRyb2wgPSB0aGlzLmZiLmNvbnRyb2woU3RvcmFnZVR5cGUuR0xPQkFMLnRvU3RyaW5nKCkpXG5cbiAgbG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UgPSBpbmplY3QoTG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UpXG5cbiAgc2V0dGluZ3MkOiBPYnNlcnZhYmxlPGFueT4gPSB0aGlzLmxvY2FsU3RvcmFnZU1hbmFnZXJTZXJ2aWNlLnNldHRpbmdzJFxuXG4gIHNldHRpbmckID0gKHN0b3JlOiBzdHJpbmcpID0+IHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2Uuc2V0dGluZyQoc3RvcmUpXG5cbiAgc3RvcmFnZUZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICBzdG9yZTogdGhpcy5mYi5jb250cm9sPHN0cmluZ3xudWxsPihudWxsKSxcbiAgICB0eXBlOiAnbG9jYWwnLFxuICAgIHNldHRpbmdUeXBlOiAnbG9jYWwnLFxuICAgIGVuY3J5cHRlZDogZmFsc2UsXG4gICAgZGF0YTogdGhpcy5mYi5jb250cm9sPHN0cmluZz4oJycsIFZhbGlkYXRvcnMucmVxdWlyZWQpLFxuICB9KVxuXG4gIG5ld1N0b3JlRm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgIG5hbWU6IHRoaXMuZmIuY29udHJvbDxzdHJpbmd8bnVsbD4obnVsbCwgVmFsaWRhdG9ycy5yZXF1aXJlZCksXG4gICAgc3RvcmFnZTogJ2xvY2FsJyxcbiAgICBlbmNyeXB0ZWQ6IGZhbHNlLFxuICAgIGRhdGE6IHRoaXMuZmIuY29udHJvbDxzdHJpbmc+KCcnLCBWYWxpZGF0b3JzLnJlcXVpcmVkKSxcbiAgICBleHBpcmVzSW46IHRoaXMuZmIuY29udHJvbCgnMCcpXG4gIH0pXG5cbiAgc3RvcmUkPzogT2JzZXJ2YWJsZTxhbnk+XG5cbiAgc3RvcmVEYXRhJCA9IHRoaXMuc3RvcmFnZUZvcm0uZ2V0KCdzdG9yZScpPy52YWx1ZUNoYW5nZXNcbiAgLnBpcGUoXG4gICAgc3dpdGNoTWFwKChkYXRhOiBhbnkpID0+IHtcbiAgICAgIHJldHVybiBkYXRhXG4gICAgICAgID8gdGhpcy5sb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZS5zdG9yZSQoZGF0YS5uYW1lKVxuICAgICAgICA6IG9mKCcnKVxuICAgIH0pLFxuICAgIHRhcChkYXRhID0+IHtcbiAgICAgIHRoaXMuc3RvcmFnZUZvcm0uZ2V0KCdkYXRhJyk/LnBhdGNoVmFsdWUoZGF0YSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pXG4gICAgfSlcbiAgKVxuXG4gIGV4cGlyZXNJbiA9IChlcG9jaDogbnVtYmVyKSA9PiB0aGlzLnV0aWxzLmV4cGlyZXNJbihlcG9jaClcblxuICBnZXQgaXNWYWxpZCgpIHtcbiAgICByZXR1cm4gdGhpcy5uZXdTdG9yZUZvcm0udmFsaWRcbiAgfVxuXG4gIGdldCBpc1ZhbGlkRGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlRm9ybS52YWxpZFxuICB9XG5cbiAgaXNWYWxpZEpTT04gPSAoc3RyOiBzdHJpbmcpID0+IHtcbiAgICB0cnkge1xuICAgICAgSlNPTi5wYXJzZShzdHIpXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIGRpc3BsYXllZENvbHVtbnM6IHN0cmluZ1tdID0gWyduYW1lJywgJ2lkJywgJ2VuY3J5cHRlZCcsICdleHBpcmVzJywgXCJvcHRpb25cIl07XG5cbiAgZmlsdGVyRGF0YSA9ICh2YWx1ZXM6IFNldHRpbmdPcHRpb25zW10pID0+IHtcbiAgICBpZighdmFsdWVzKSByZXR1cm4gW11cbiAgICByZXR1cm4gdmFsdWVzLmZpbHRlcigoaXRlbTogYW55KSA9PiBpdGVtLm9wdGlvbnMuc3RvcmFnZSA9PT0gK3RoaXMudHlwZSlcbiAgfVxuXG4gIGRhdGEkPzogT2JzZXJ2YWJsZTxhbnk+XG5cbiAgc3RvcmU6IGFueVxuXG4gIGNyZWF0ZSA9IGZhbHNlXG5cbiAgc3RvcmVQcm9wcz86IExvY2FsU3RvcmFnZU9wdGlvbnNcbiAgb3B0aW9ucz86IFNldHRpbmdPcHRpb25zXG5cbiAgY29uc3RydWN0b3IoQEluamVjdChDT05GSUdfU0VUVElOR1NfVE9LRU4pIHByaXZhdGUgY29uZmlnT3B0aW9ucz86IENvbmZpZ09wdGlvbnMpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuXG4gICAgdGhpcy5zdG9yZVByb3BzID0gdGhpcy5jb25maWdPcHRpb25zPy5Mb2NhbFN0b3JhZ2VPcHRpb25zXG4gICAgdGhpcy5vcHRpb25zID0gdGhpcy5zdG9yZVByb3BzPy5vcHRpb25zXG5cbiAgICBpZih0aGlzLm9wdGlvbnM/LnN0b3JhZ2UpIHtcbiAgICAgIHRoaXMudHlwZUNvbnRyb2wucGF0Y2hWYWx1ZSh0aGlzLm9wdGlvbnMuc3RvcmFnZS50b1N0cmluZygpKVxuICAgICAgdGhpcy50eXBlQ29udHJvbC5kaXNhYmxlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50eXBlQ29udHJvbC5lbmFibGUoKVxuICAgIH1cblxuICAgIGlmKHRoaXMub3B0aW9ucz8uZXhwaXJlc0luKSB7XG4gICAgICB0aGlzLm5ld1N0b3JlRm9ybS5nZXQoJ2V4cGlyZXNJbicpPy5wYXRjaFZhbHVlKHRoaXMub3B0aW9ucy5leHBpcmVzSW4pXG4gICAgICB0aGlzLm5ld1N0b3JlRm9ybS5nZXQoJ2V4cGlyZXNJbicpPy5kaXNhYmxlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5uZXdTdG9yZUZvcm0uZ2V0KCdleHBpcmVzSW4nKT8uZW5hYmxlKClcbiAgICB9XG5cbiAgICBpZih0aGlzLm9wdGlvbnM/LmVuY3J5cHRlZCkge1xuICAgICAgdGhpcy5uZXdTdG9yZUZvcm0uZ2V0KCdlbmNyeXB0ZWQnKT8ucGF0Y2hWYWx1ZSh0aGlzLm9wdGlvbnMuZW5jcnlwdGVkKVxuICAgICAgdGhpcy5uZXdTdG9yZUZvcm0uZ2V0KCdlbmNyeXB0ZWQnKT8uZGlzYWJsZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubmV3U3RvcmVGb3JtLmdldCgnZW5jcnlwdGVkJyk/LmVuYWJsZSgpXG4gICAgfVxuXG4gIH1cblxuICBvbkNyZWF0ZVN0b3JlKCkge1xuXG4gICAgaWYoIXRoaXMuaXNWYWxpZCkgcmV0dXJuXG5cbiAgICBjb25zdCBzdG9yZSA9IHRoaXMubmV3U3RvcmVGb3JtLnZhbHVlXG4gICAgaWYoIXN0b3JlLm5hbWUgfHwgc3RvcmUubmFtZSA9PT0gJycpIHJldHVyblxuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgc3RvcmFnZTogdGhpcy50eXBlLCBlbmNyeXB0ZWQ6IHN0b3JlLmVuY3J5cHRlZCwgZXhwaXJlc0luOiBzdG9yZS5leHBpcmVzSW4gfVxuXG4gICAgdGhpcy5sb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZS5jcmVhdGVTdG9yZSh7XG4gICAgICBuYW1lOiBzdG9yZS5uYW1lLFxuICAgICAgZGF0YTogc3RvcmUuZGF0YSxcbiAgICAgIG9wdGlvbnM6IFNldHRpbmdPcHRpb25zLmFkYXB0KG9wdGlvbnMpXG4gICAgfSlcblxuICAgIHRoaXMubmV3U3RvcmVGb3JtLnJlc2V0KClcbiAgICB0aGlzLmNyZWF0ZSA9IGZhbHNlXG4gIH1cblxuICBvblVwZGF0ZVN0b3JlKHN0b3JlOiBhbnkpIHtcblxuICAgIGlmKCF0aGlzLnN0b3JhZ2VGb3JtLnZhbGlkKSByZXR1cm5cblxuICAgIGNvbnN0IHN0b3JlRGF0YSA9IHRoaXMuc3RvcmFnZUZvcm0udmFsdWVcblxuICAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKHN0b3JlRGF0YS5kYXRhIHx8ICcnKVxuXG4gICAgY29uc3QgdHlwZSA9IChzdG9yZURhdGEudHlwZSA9PT0gJ2xvY2FsJykgPyBTdG9yYWdlVHlwZS5HTE9CQUwgOiBTdG9yYWdlVHlwZS5TRVNTSU9OXG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgc3RvcmFnZTogdHlwZSwgZW5jcnlwdGVkOiBzdG9yZURhdGEuZW5jcnlwdGVkIH1cblxuICAgIHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UudXBkYXRlU3RvcmUoe1xuICAgICAgbmFtZTogc3RvcmUubmFtZSxcbiAgICAgIGRhdGFcbiAgICB9KVxuXG4gIH1cblxuICBvblNlbGVjdGVkUm93KHN0b3JlOiBhbnkpIHtcbiAgICB0aGlzLnN0b3JlID0gc3RvcmVcbiAgICB0aGlzLmRhdGEkID0gdGhpcy5sb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZS5zdG9yZSQoc3RvcmUubmFtZSkucGlwZShtYXAoaXRlbSA9PiBKU09OLnN0cmluZ2lmeShpdGVtKSkpXG4gICAgdGhpcy5jcmVhdGUgPSBmYWxzZVxuICB9XG5cbiAgb25DcmVhdGUoKSB7XG4gICAgdGhpcy5vbkNhbmNlbCgpXG4gICAgdGhpcy5jcmVhdGUgPSB0cnVlXG4gIH1cblxuICBvbkRlbGV0ZShzdG9yZTogU3RvcmFnZU9wdGlvbikge1xuXG4gICAgY29uc29sZS5sb2coJ0RFTEVURUQgU1RPUkU6JyxzdG9yZSlcblxuICAgIHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UuZGVsZXRlU3RvcmUoe1xuICAgICAgbmFtZTogc3RvcmUubmFtZSxcbiAgICB9KVxuXG4gICAgdGhpcy5vbkNhbmNlbCgpXG4gIH1cblxuICBvbkNhbmNlbCgpIHtcbiAgICB0aGlzLmRhdGEkID0gRU1QVFlcbiAgICB0aGlzLnN0b3JlID0gbnVsbFxuICAgIHRoaXMuY3JlYXRlID0gZmFsc2VcbiAgfVxuXG4gIG9uVXBkYXRlKHN0b3JlOiBTdG9yYWdlT3B0aW9uLCBkYXRhOiBhbnkpIHtcblxuICAgIHRoaXMubG9jYWxTdG9yYWdlTWFuYWdlclNlcnZpY2UudXBkYXRlU3RvcmUoe1xuICAgICAgbmFtZTogc3RvcmUubmFtZSxcbiAgICAgIGRhdGE6IEpTT04ucGFyc2UoZGF0YSlcbiAgICB9KVxuXG4gICAgdGhpcy5vbkNhbmNlbCgpXG5cbiAgfVxuXG4gIG9uUmVzZXQoKSB7XG4gICAgdGhpcy5sb2NhbFN0b3JhZ2VNYW5hZ2VyU2VydmljZS5yZXNldFN0b3JlKClcbiAgfVxuXG59XG4iLCI8ZGl2IHN0eWxlPVwibWFyZ2luOiAycmVtO1wiPlxuXG4gIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDFyZW1cIj5cbiAgICA8aDIgc3R5bGU9XCJwYWRkaW5nLXRvcDogLjVyZW07IGRpc3BsYXk6IGZsZXg7XCI+XG4gICAgICA8ZGl2IHN0eWxlPVwicGFkZGluZy10b3A6IC41cmVtO1wiPkxvY2FsIFN0b3JhZ2UgTWFuYWdlcjwvZGl2PlxuICAgICAgPGRpdj5cbiAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gW21hdE1lbnVUcmlnZ2VyRm9yXT1cIm1lbnVcIj5cbiAgICAgICAgICA8bWF0LWljb24+aW5mbzwvbWF0LWljb24+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9oMj5cbiAgICA8c3BhbiBzdHlsZT1cImZsZXg6MVwiPjwvc3Bhbj5cbiAgICA8ZGl2IHN0eWxlPVwicGFkZGluZy10b3A6IC4yNXJlbTtcIj5cbiAgICAgIDxtYXQtYnV0dG9uLXRvZ2dsZS1ncm91cCBuYW1lPVwic3RvcmFnZVwiIFtmb3JtQ29udHJvbF09XCJ0eXBlQ29udHJvbFwiIChjaGFuZ2UpPVwib25DYW5jZWwoKVwiPlxuICAgICAgICA8bWF0LWJ1dHRvbi10b2dnbGUgdmFsdWU9XCIwXCI+TG9jYWwgU3RvcmFnZTwvbWF0LWJ1dHRvbi10b2dnbGU+XG4gICAgICAgIDxtYXQtYnV0dG9uLXRvZ2dsZSB2YWx1ZT1cIjFcIj5TZXNzaW9uIFN0b3JhZ2U8L21hdC1idXR0b24tdG9nZ2xlPlxuICAgICAgPC9tYXQtYnV0dG9uLXRvZ2dsZS1ncm91cD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLXRvcDogLjI1cmVtO1wiPlxuICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cIm9uQ3JlYXRlKClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN0b3JlUHJvcHM/LnN0b3JhZ2VOYW1lIHx8IHN0b3JlUHJvcHM/LnN0b3JhZ2VTZXR0aW5nc05hbWVcIj5cbiAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgZ2FwOiAuNXJlbTsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgYm9yZGVyOiBncmF5IHNvbGlkIHRoaW47IGJhY2tncm91bmQtY29sb3I6IHdoaXRlc21va2U7IHBhZGRpbmc6IDFyZW07XCJcbiAgICA+XG4gICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDtcIj5cbiAgICAgICAgPGRpdiAqbmdJZj1cInN0b3JlUHJvcHM/LnN0b3JhZ2VTZXR0aW5nc05hbWVcIiBzdHlsZT1cImZsZXg6MVwiPlxuICAgICAgICAgIERhdGFiYXNlOiA8Yj57eyBzdG9yZVByb3BzPy5zdG9yYWdlU2V0dGluZ3NOYW1lIH19PC9iPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cInN0b3JlUHJvcHM/LnN0b3JhZ2VOYW1lXCIgc3R5bGU9XCJmbGV4OjFcIj5cbiAgICAgICAgICBEYXRhOiA8Yj57eyBzdG9yZVByb3BzPy5zdG9yYWdlTmFtZSB9fTwvYj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDJyZW07XCIgW2Zvcm1Hcm91cF09XCJuZXdTdG9yZUZvcm1cIiAqbmdJZj1cImNyZWF0ZTsgZWxzZSBMSVNUXCI+XG5cbiAgICA8aDI+Q3JlYXRlIFN0b3JlPC9oMj5cblxuICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IDFyZW07XCI+XG4gICAgICA8ZGl2IHN0eWxlPVwiZmxleDoxXCI+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiPlxuICAgICAgICAgIDxtYXQtbGFiZWw+U3RvcmUgTmFtZTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cInNhbXBsZVwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGFwcGVhcmFuY2U9XCJvdXRsaW5lXCI+XG4gICAgICAgICAgPG1hdC1sYWJlbD5FeHBpcmVzIEluLi4uPC9tYXQtbGFiZWw+XG4gICAgICAgICAgPG1hdC1zZWxlY3QgZm9ybUNvbnRyb2xOYW1lPVwiZXhwaXJlc0luXCI+XG4gICAgICAgICAgICA8bWF0LW9wdGlvbiB2YWx1ZT1cIjBcIj5Ob25lPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCIzMHNcIj4zMCBTZWNvbmRzPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCIxbW5cIj4xIE1pbnV0ZTwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDxtYXQtb3B0aW9uIHZhbHVlPVwiMWhyXCI+MSBIb3VyPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgPG1hdC1vcHRpb24gdmFsdWU9XCIxZFwiPjEgRGF5PC9tYXQtb3B0aW9uPlxuICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDFyZW07XCI+XG4gICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlIGZvcm1Db250cm9sTmFtZT1cImVuY3J5cHRlZFwiPkVuY3J5cHRlZDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7XCI+XG4gICAgICA8bWF0LWZvcm0tZmllbGQgYXBwZWFyYW5jZT1cIm91dGxpbmVcIiBzdHlsZT1cImZsZXg6IDE7XCI+XG4gICAgICAgIDxtYXQtbGFiZWw+RGF0YSAoTXVzdCBiZSBhbiBPYmplY3Qgb3IgQXJyYXkgb2YgYW55KTwvbWF0LWxhYmVsPlxuICAgICAgICA8dGV4dGFyZWEgbWF0SW5wdXQgcGxhY2Vob2xkZXI9XCJbXVwiIGZvcm1Db250cm9sTmFtZT1cImRhdGFcIiAjanNvbj48L3RleHRhcmVhPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Rpdj5cbiAgICA8bWF0LWVycm9yICpuZ0lmPVwiIWlzVmFsaWRKU09OKGpzb24udmFsdWUpXCI+Tm90IFZhbGlkIERhdGE8L21hdC1lcnJvcj5cblxuICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4O1wiPlxuICAgICAgPHNwYW4gc3R5bGU9XCJmbGV4OjFcIj48L3NwYW4+XG4gICAgICA8YnV0dG9uIG1hdC1zdHJva2VkLWJ1dHRvbiAoY2xpY2spPVwib25DcmVhdGVTdG9yZSgpXCIgW2Rpc2FibGVkXT1cIiEoaXNWYWxpZCAmJiBpc1ZhbGlkSlNPTihqc29uLnZhbHVlKSlcIj5cbiAgICAgICAgU2F2ZSBTdG9yZVxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgPC9kaXY+XG5cbiAgPG5nLXRlbXBsYXRlICNMSVNUPlxuXG4gICAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDFyZW07XCI+XG4gICAgICA8bWF0LWRpdmlkZXI+PC9tYXQtZGl2aWRlcj5cbiAgICA8L2Rpdj5cbnt7IHNldHRpbmdzJCB8IGFzeW5jIHwganNvbiB9fVxuICAgIDxkaXYgKm5nSWY9XCJmaWx0ZXJEYXRhKHNldHRpbmdzJCB8IGFzeW5jKSBhcyBkYXRhXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGF0YS5sZW5ndGggPiAwOyBlbHNlIE5PX0RBVEFcIj5cbiAgICAgICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJkYXRhXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJuYW1lXCI+XG4gICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPiBTdG9yZSA8L3RoPlxuICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIiBzdHlsZT1cImZvbnQtd2VpZ2h0OiBib2xkOyB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1wiPiB7e2VsZW1lbnQubmFtZX19IDwvdGQ+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImlkXCI+XG4gICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPiBJRCA8L3RoPlxuICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj4ge3tlbGVtZW50LmlkfX0gPC90ZD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZW5jcnlwdGVkXCI+XG4gICAgICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIHN0eWxlPVwidGV4dC1hbGlnbjogY2VudGVyO1wiPiBFbmNyeXB0ZWQgPC90aD5cbiAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCIgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlbGVtZW50Lm9wdGlvbnMuZW5jcnlwdGVkOyBlbHNlIE5PXCI+WUVTPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjTk8+PHNwYW4gc3R5bGU9XCJjb2xvcjpncmF5XCI+Tk88L3NwYW4+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImV4cGlyZXNcIj5cbiAgICAgICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7XCI+IEV4cGlyZXMgPC90aD5cbiAgICAgICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCIgc3R5bGU9XCJ0ZXh0LWFsaWduOiBjZW50ZXI7XCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlbGVtZW50Lm9wdGlvbnMuZXhwaXJlcyAhPT0gMDsgZWxzZSBOT19EQVRBXCI+XG4gICAgICAgICAgICAgICAge3tleHBpcmVzSW4oZWxlbWVudC5vcHRpb25zLmV4cGlyZXMpfX1cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjTk9fREFUQT5cbiAgICAgICAgICAgICAgICDiiJ5cbiAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm9wdGlvblwiPlxuICAgICAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj48L3RoPlxuICAgICAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIiBzdHlsZT1cInBhZGRpbmctcmlnaHQ6IDA7XCI+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4O2p1c3RpZnktY29udGVudDogZmxleC1lbmQ7XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBtYXQtaWNvbi1idXR0b24gY29sb3I9XCJ3YXJuXCIgKGNsaWNrKT1cIm9uRGVsZXRlKGVsZW1lbnQpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnM7XCIgKGNsaWNrKT1cIm9uU2VsZWN0ZWRSb3cocm93KVwiPjwvdHI+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLXRlbXBsYXRlICNOT19EQVRBPlxuICAgICAgICA8aDMgc3R5bGU9XCJtYXJnaW4tdG9wOiAxcmVtO1wiPk5vIERhdGE8L2gzPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgICAgPGRpdiAqbmdJZj1cIihkYXRhJCB8IGFzeW5jKSBhcyBkYXRhXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAycmVtO1wiPlxuICAgICAgICA8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMXJlbTtcIj5cbiAgICAgICAgICA8bWF0LWRpdmlkZXI+PC9tYXQtZGl2aWRlcj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGgzPlNUT1JFOiA8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OiBib2xkO1wiPnt7IHN0b3JlLm5hbWUgfCB1cHBlcmNhc2UgfX08L3NwYW4+PC9oMz5cbiAgICAgICAgPGgzPlNFVFRJTkdTOiB7eyBzZXR0aW5nJChzdG9yZS5uYW1lKSB8IGFzeW5jIHwganNvbiB9fTwvaDM+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4O1wiPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBhcHBlYXJhbmNlPVwib3V0bGluZVwiIHN0eWxlPVwiZmxleDogMTtcIj5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+RGF0YSAoTXVzdCBiZSBhbiBPYmplY3Qgb3IgQXJyYXkgb2YgYW55KTwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgPHRleHRhcmVhIG1hdElucHV0IHBsYWNlaG9sZGVyPVwiW11cIiAjanNvbiBbdmFsdWVdPVwiZGF0YVwiPjwvdGV4dGFyZWE+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCIhaXNWYWxpZEpTT04oanNvbi52YWx1ZSlcIj5Ob3QgVmFsaWQgRGF0YTwvbWF0LWVycm9yPlxuXG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBnYXA6IC41cmVtO1wiPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZmxleDoxXCI+PC9zcGFuPlxuICAgICAgICAgIDxidXR0b24gbWF0LXN0cm9rZWQtYnV0dG9uIChjbGljayk9XCJvbkNhbmNlbCgpXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBtYXQtc3Ryb2tlZC1idXR0b24gKGNsaWNrKT1cIm9uVXBkYXRlKHN0b3JlLCBqc29uLnZhbHVlKVwiIFtkaXNhYmxlZF09XCIhKGlzVmFsaWRKU09OKGpzb24udmFsdWUpKVwiPlVwZGF0ZTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gIDwvbmctdGVtcGxhdGU+XG5cbiAgPGRpdiBzdHlsZT1cIm1hcmdpbi10b3A6IDFyZW07XCI+XG4gICAgPG1hdC1kaXZpZGVyPjwvbWF0LWRpdmlkZXI+XG4gIDwvZGl2PlxuXG4gIDxkaXYgc3R5bGU9XCJtYXJnaW4tdG9wOiAxcmVtO1wiPlxuICAgIDxidXR0b24gbWF0LXN0cm9rZWQtYnV0dG9uIChjbGljayk9XCJvblJlc2V0KClcIj5EZWxldGUgQWxsIFN0b3JlczwvYnV0dG9uPlxuICA8L2Rpdj5cblxuPC9kaXY+XG5cblxuPG1hdC1tZW51ICNtZW51PVwibWF0TWVudVwiPlxuICA8ZGl2IHN0eWxlPVwicGFkZGluZzogMXJlbTtcIj5cbiAgICA8cD5QbGVhc2Ugbm90ZSB0aGF0IHRoZSBMb2NhbFN0b3JhZ2UgKGVuY3J5cHRpb24pIGFuZCBtYW5hZ2VtZW50IG9mIGRhdGEgaXMgZGVwZW5kYW50IG9uIGluaXRpYWxpemluZyB0aGUgQVBQX0lEPC9wPlxuICAgIDxwPk11c3QgcHJvdmlkZSBhIHZhbHVlIGZvciA8Yj5BUFBfSUQ8L2I+IGluIEFwcE1vZHVsZS0+UHJvdmlkZXJzPC9wPlxuICAgIDxtYXQtZGl2aWRlcj48L21hdC1kaXZpZGVyPlxuICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOiBzbWFsbGVyOyBtYXJnaW4tdG9wOiAuNXJlbTtcIj5cbiAgICA8cD5FeGFtcGxlOiBVVUlEIChzZWxmLmNyeXB0by5yYW5kb21VVUlEKCkgdG8gZ2VuZXJhdGUpPC9wPlxuICAgIDxkaXYgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZXNtb2tlOyBwYWRkaW5nOiAxcmVtO1wiPlxuICAgICAgJiMxMjM7PGJyPlxuICAgICAgICBwcm92aWRlOiBBUFBfSUQsPGJyPlxuICAgICAgICB1c2VWYWx1ZTogXCIwNTY5OTFhYy0zNTM3LTQzYWItYjViOS04M2VkZjY1NTRlZmZcIiw8YnI+XG4gICAgICAmIzEyNTtcbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwvZGl2PlxuPC9tYXQtbWVudT5cbiJdfQ==
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { Subscription, timer } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "@angular/common";
|
|
5
|
+
import * as i2 from "@angular/material/icon";
|
|
6
|
+
import * as i3 from "@angular/material/progress-spinner";
|
|
7
|
+
import * as i4 from "@angular/material/button";
|
|
8
|
+
export class DownloadFileComponent {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.subscriptions = new Subscription();
|
|
11
|
+
this.displayError = 3; // seconds
|
|
12
|
+
this.diameter = 32;
|
|
13
|
+
this.mode = 'determinate';
|
|
14
|
+
this.isPending = false;
|
|
15
|
+
this.active = false;
|
|
16
|
+
this.disabled = false;
|
|
17
|
+
this.error = new EventEmitter();
|
|
18
|
+
this._progress = 0;
|
|
19
|
+
this._hasError = false;
|
|
20
|
+
this.errorTimerActive = false;
|
|
21
|
+
}
|
|
22
|
+
set progress(value) {
|
|
23
|
+
this._progress = value ?? 0;
|
|
24
|
+
}
|
|
25
|
+
get progress() {
|
|
26
|
+
return this._progress;
|
|
27
|
+
}
|
|
28
|
+
set hasError(value) {
|
|
29
|
+
this._hasError = !!value;
|
|
30
|
+
if (this._hasError && !this.errorTimerActive) {
|
|
31
|
+
this.errorTimerActive = true;
|
|
32
|
+
this.active = false;
|
|
33
|
+
this.error.emit();
|
|
34
|
+
this.subscriptions.add(timer(this.displayError * 1000)
|
|
35
|
+
.subscribe((err) => {
|
|
36
|
+
this._hasError = false;
|
|
37
|
+
this.errorTimerActive = false;
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get hasError() {
|
|
42
|
+
return this._hasError;
|
|
43
|
+
}
|
|
44
|
+
ngOnInit() { }
|
|
45
|
+
onAction() {
|
|
46
|
+
this.isPending = false;
|
|
47
|
+
if (this.event)
|
|
48
|
+
this.event();
|
|
49
|
+
}
|
|
50
|
+
ngOnDestroy() {
|
|
51
|
+
this.subscriptions.unsubscribe();
|
|
52
|
+
}
|
|
53
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DownloadFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
54
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DownloadFileComponent, selector: "app-download-file", inputs: { event: "event", displayError: "displayError", diameter: "diameter", mode: "mode", isPending: "isPending", active: "active", disabled: "disabled", progress: "progress", hasError: "hasError" }, outputs: { error: "error" }, ngImport: i0, template: "<ng-container *ngIf=\"!isPending; else DOWNLOADING\">\n <ng-container *ngIf=\"hasError; else NORMAL\">\n <div class=\"width center-txt\" style=\"margin-bottom: 4px;\">\n <mat-icon color=\"warn\" class=\"warn-icon\">warning</mat-icon>\n </div>\n </ng-container>\n <ng-template #NORMAL>\n <ng-container *ngIf=\"active; else ACTION\">\n\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n\n </ng-container>\n <ng-template #ACTION>\n <button data-tracking=\"export-btn\" mat-icon-button (click)=\"onAction()\" class=\"icon-button\" [disabled]=\"disabled\">\n <mat-icon class=\"custom-icon\">file_download</mat-icon>\n </button>\n </ng-template>\n </ng-template>\n</ng-container>\n\n<ng-template #DOWNLOADING>\n <div\n class=\"spinner-container\"\n *ngIf=\"(progress > 0 && progress < 100); else INDETERMINATE\"\n >\n <div class=\"spinner-background\">\n {{progress}}%\n </div>\n <mat-progress-spinner\n color=\"primary\"\n [mode]=\"mode\"\n [value]=\"progress\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n <ng-template #INDETERMINATE>\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n </ng-template>\n\n</ng-template>\n\n\n\n", styles: [":not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:44px;height:44px;font-size:12px;line-height:32px;text-align:center;overflow:hidden;border-radius:50%;border:solid 5px whitesmoke}.center-txt{align-content:center;text-align:-webkit-center}.width{width:48px;height:48px}.icon-button{display:flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0}.container-obj{display:flex;justify-content:center;align-items:center;width:48px;height:48px}.centered-obj-div{text-align:center}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
55
|
+
}
|
|
56
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DownloadFileComponent, decorators: [{
|
|
57
|
+
type: Component,
|
|
58
|
+
args: [{ selector: 'app-download-file', encapsulation: ViewEncapsulation.None, template: "<ng-container *ngIf=\"!isPending; else DOWNLOADING\">\n <ng-container *ngIf=\"hasError; else NORMAL\">\n <div class=\"width center-txt\" style=\"margin-bottom: 4px;\">\n <mat-icon color=\"warn\" class=\"warn-icon\">warning</mat-icon>\n </div>\n </ng-container>\n <ng-template #NORMAL>\n <ng-container *ngIf=\"active; else ACTION\">\n\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n\n </ng-container>\n <ng-template #ACTION>\n <button data-tracking=\"export-btn\" mat-icon-button (click)=\"onAction()\" class=\"icon-button\" [disabled]=\"disabled\">\n <mat-icon class=\"custom-icon\">file_download</mat-icon>\n </button>\n </ng-template>\n </ng-template>\n</ng-container>\n\n<ng-template #DOWNLOADING>\n <div\n class=\"spinner-container\"\n *ngIf=\"(progress > 0 && progress < 100); else INDETERMINATE\"\n >\n <div class=\"spinner-background\">\n {{progress}}%\n </div>\n <mat-progress-spinner\n color=\"primary\"\n [mode]=\"mode\"\n [value]=\"progress\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n <ng-template #INDETERMINATE>\n <div class=\"container-obj\">\n <div class=\"centered-obj-div\">\n <mat-progress-spinner\n color=\"primary\"\n mode=\"indeterminate\"\n [diameter]=\"44\"\n ></mat-progress-spinner>\n </div>\n </div>\n </ng-template>\n\n</ng-template>\n\n\n\n", styles: [":not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:44px;height:44px;font-size:12px;line-height:32px;text-align:center;overflow:hidden;border-radius:50%;border:solid 5px whitesmoke}.center-txt{align-content:center;text-align:-webkit-center}.width{width:48px;height:48px}.icon-button{display:flex;align-items:center;justify-content:center;width:48px;height:48px;padding:0}.container-obj{display:flex;justify-content:center;align-items:center;width:48px;height:48px}.centered-obj-div{text-align:center}\n"] }]
|
|
59
|
+
}], propDecorators: { event: [{
|
|
60
|
+
type: Input
|
|
61
|
+
}], displayError: [{
|
|
62
|
+
type: Input
|
|
63
|
+
}], diameter: [{
|
|
64
|
+
type: Input
|
|
65
|
+
}], mode: [{
|
|
66
|
+
type: Input
|
|
67
|
+
}], isPending: [{
|
|
68
|
+
type: Input
|
|
69
|
+
}], active: [{
|
|
70
|
+
type: Input
|
|
71
|
+
}], disabled: [{
|
|
72
|
+
type: Input
|
|
73
|
+
}], error: [{
|
|
74
|
+
type: Output
|
|
75
|
+
}], progress: [{
|
|
76
|
+
type: Input
|
|
77
|
+
}], hasError: [{
|
|
78
|
+
type: Input
|
|
79
|
+
}] } });
|
|
80
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtZmlsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9odHRwLXJlcXVlc3QtbWFuYWdlci9zcmMvbGliL2h0dHAtcmVxdWVzdC1zZXJ2aWNlcy1kZW1vL3JlcXVlc3QtbWFuYWdlci1kZW1vL2ZpbGUtZG93bmxvYWRlci9kb3dubG9hZC1maWxlL2Rvd25sb2FkLWZpbGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LW1hbmFnZXIvc3JjL2xpYi9odHRwLXJlcXVlc3Qtc2VydmljZXMtZGVtby9yZXF1ZXN0LW1hbmFnZXItZGVtby9maWxlLWRvd25sb2FkZXIvZG93bmxvYWQtZmlsZS9kb3dubG9hZC1maWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbEcsT0FBTyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7OztBQVEzQyxNQUFNLE9BQU8scUJBQXFCO0lBTmxDO1FBUVUsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBR2xDLGlCQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVTtRQUM1QixhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2QsU0FBSSxHQUF3QixhQUFhLENBQUM7UUFDMUMsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUVsQixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ2YsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUVoQixVQUFLLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUVuQyxjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBU2QsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7S0FtQ2xDO0lBNUNDLElBQWEsUUFBUSxDQUFDLEtBQVU7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUtELElBQWEsUUFBUSxDQUFDLEtBQW9CO1FBRXhDLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUV6QixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDNUMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztZQUM3QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztZQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFBO1lBQ2pCLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNwQixLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7aUJBQzlCLFNBQVMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztZQUNoQyxDQUFDLENBQUMsQ0FDSCxDQUFDO1NBQ0g7SUFFSCxDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxRQUFRLEtBQUksQ0FBQztJQUViLFFBQVE7UUFDTixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQTtRQUN0QixJQUFJLElBQUksQ0FBQyxLQUFLO1lBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQzlCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUNsQyxDQUFDOytHQTNEVSxxQkFBcUI7bUdBQXJCLHFCQUFxQixnU0NWbEMscW5EQTJEQTs7NEZEakRhLHFCQUFxQjtrQkFOakMsU0FBUzsrQkFDRSxtQkFBbUIsaUJBR2QsaUJBQWlCLENBQUMsSUFBSTs4QkFNNUIsS0FBSztzQkFBYixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFFRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFFSSxLQUFLO3NCQUFkLE1BQU07Z0JBR00sUUFBUTtzQkFBcEIsS0FBSztnQkFXTyxRQUFRO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFByb2dyZXNzU3Bpbm5lck1vZGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wcm9ncmVzcy1zcGlubmVyJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgdGltZXIgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWRvd25sb2FkLWZpbGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZG93bmxvYWQtZmlsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2Rvd25sb2FkLWZpbGUuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgRG93bmxvYWRGaWxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgQElucHV0KCkgZXZlbnQ/OiBGdW5jdGlvbjtcbiAgQElucHV0KCkgZGlzcGxheUVycm9yID0gMzsgLy8gc2Vjb25kc1xuICBASW5wdXQoKSBkaWFtZXRlciA9IDMyO1xuICBASW5wdXQoKSBtb2RlOiBQcm9ncmVzc1NwaW5uZXJNb2RlID0gJ2RldGVybWluYXRlJztcbiAgQElucHV0KCkgaXNQZW5kaW5nID0gZmFsc2U7XG5cbiAgQElucHV0KCkgYWN0aXZlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpIGVycm9yID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByaXZhdGUgX3Byb2dyZXNzID0gMDtcbiAgQElucHV0KCkgc2V0IHByb2dyZXNzKHZhbHVlOiBhbnkpIHtcbiAgICB0aGlzLl9wcm9ncmVzcyA9IHZhbHVlID8/IDA7XG4gIH1cblxuICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Byb2dyZXNzO1xuICB9XG5cbiAgcHJpdmF0ZSBfaGFzRXJyb3IgPSBmYWxzZTtcbiAgcHJpdmF0ZSBlcnJvclRpbWVyQWN0aXZlID0gZmFsc2U7XG5cbiAgQElucHV0KCkgc2V0IGhhc0Vycm9yKHZhbHVlOiBib29sZWFuIHwgYW55KSB7XG5cbiAgICB0aGlzLl9oYXNFcnJvciA9ICEhdmFsdWU7XG5cbiAgICBpZiAodGhpcy5faGFzRXJyb3IgJiYgIXRoaXMuZXJyb3JUaW1lckFjdGl2ZSkge1xuICAgICAgdGhpcy5lcnJvclRpbWVyQWN0aXZlID0gdHJ1ZTtcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmVycm9yLmVtaXQoKVxuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgICAgdGltZXIodGhpcy5kaXNwbGF5RXJyb3IgKiAxMDAwKVxuICAgICAgICAuc3Vic2NyaWJlKChlcnIpID0+IHtcbiAgICAgICAgICB0aGlzLl9oYXNFcnJvciA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuZXJyb3JUaW1lckFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgfVxuXG4gIGdldCBoYXNFcnJvcigpIHtcbiAgICByZXR1cm4gdGhpcy5faGFzRXJyb3I7XG4gIH1cblxuICBuZ09uSW5pdCgpIHt9XG5cbiAgb25BY3Rpb24oKSB7XG4gICAgdGhpcy5pc1BlbmRpbmcgPSBmYWxzZVxuICAgIGlmICh0aGlzLmV2ZW50KSB0aGlzLmV2ZW50KClcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpXG4gIH1cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNQZW5kaW5nOyBlbHNlIERPV05MT0FESU5HXCI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNFcnJvcjsgZWxzZSBOT1JNQUxcIj5cbiAgICA8ZGl2IGNsYXNzPVwid2lkdGggY2VudGVyLXR4dFwiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTogNHB4O1wiPlxuICAgICAgPG1hdC1pY29uIGNvbG9yPVwid2FyblwiIGNsYXNzPVwid2Fybi1pY29uXCI+d2FybmluZzwvbWF0LWljb24+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuICA8bmctdGVtcGxhdGUgI05PUk1BTD5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYWN0aXZlOyBlbHNlIEFDVElPTlwiPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyLW9ialwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2VudGVyZWQtb2JqLWRpdlwiPlxuICAgICAgICAgIDxtYXQtcHJvZ3Jlc3Mtc3Bpbm5lclxuICAgICAgICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgIG1vZGU9XCJpbmRldGVybWluYXRlXCJcbiAgICAgICAgICAgIFtkaWFtZXRlcl09XCI0NFwiXG4gICAgICAgICAgPjwvbWF0LXByb2dyZXNzLXNwaW5uZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxuZy10ZW1wbGF0ZSAjQUNUSU9OPlxuICAgIDxidXR0b24gZGF0YS10cmFja2luZz1cImV4cG9ydC1idG5cIiBtYXQtaWNvbi1idXR0b24gKGNsaWNrKT1cIm9uQWN0aW9uKClcIiBjbGFzcz1cImljb24tYnV0dG9uXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCI+XG4gICAgICA8bWF0LWljb24gY2xhc3M9XCJjdXN0b20taWNvblwiPmZpbGVfZG93bmxvYWQ8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuICA8L25nLXRlbXBsYXRlPlxuICA8L25nLXRlbXBsYXRlPlxuPC9uZy1jb250YWluZXI+XG5cbjxuZy10ZW1wbGF0ZSAjRE9XTkxPQURJTkc+XG4gIDxkaXZcbiAgICBjbGFzcz1cInNwaW5uZXItY29udGFpbmVyXCJcbiAgICAqbmdJZj1cIihwcm9ncmVzcyA+IDAgJiYgcHJvZ3Jlc3MgPCAxMDApOyBlbHNlIElOREVURVJNSU5BVEVcIlxuICA+XG4gICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYmFja2dyb3VuZFwiPlxuICAgICAge3twcm9ncmVzc319JVxuICAgIDwvZGl2PlxuICAgIDxtYXQtcHJvZ3Jlc3Mtc3Bpbm5lclxuICAgICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgIFttb2RlXT1cIm1vZGVcIlxuICAgICAgW3ZhbHVlXT1cInByb2dyZXNzXCJcbiAgICAgIFtkaWFtZXRlcl09XCI0NFwiXG4gICAgPjwvbWF0LXByb2dyZXNzLXNwaW5uZXI+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgI0lOREVURVJNSU5BVEU+XG4gICAgPGRpdiBjbGFzcz1cImNvbnRhaW5lci1vYmpcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjZW50ZXJlZC1vYmotZGl2XCI+XG4gICAgICAgIDxtYXQtcHJvZ3Jlc3Mtc3Bpbm5lclxuICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgbW9kZT1cImluZGV0ZXJtaW5hdGVcIlxuICAgICAgICAgIFtkaWFtZXRlcl09XCI0NFwiXG4gICAgICAgID48L21hdC1wcm9ncmVzcy1zcGlubmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG5cbjwvbmctdGVtcGxhdGU+XG5cblxuXG4iXX0=
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { DownloadFileComponent } from './download-file/download-file.component';
|
|
4
|
+
import { FileDownloaderComponent } from './file-downloader.component';
|
|
5
|
+
import { SpinnerComponent } from './spinner/spinner.component';
|
|
6
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
7
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
8
|
+
import { MatButtonModule } from '@angular/material/button';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
export class FileDownloaderModule {
|
|
11
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
12
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, declarations: [SpinnerComponent,
|
|
13
|
+
DownloadFileComponent,
|
|
14
|
+
FileDownloaderComponent], imports: [CommonModule,
|
|
15
|
+
MatIconModule,
|
|
16
|
+
MatProgressSpinnerModule,
|
|
17
|
+
MatButtonModule], exports: [FileDownloaderComponent] }); }
|
|
18
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, imports: [CommonModule,
|
|
19
|
+
MatIconModule,
|
|
20
|
+
MatProgressSpinnerModule,
|
|
21
|
+
MatButtonModule] }); }
|
|
22
|
+
}
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderModule, decorators: [{
|
|
24
|
+
type: NgModule,
|
|
25
|
+
args: [{
|
|
26
|
+
imports: [
|
|
27
|
+
CommonModule,
|
|
28
|
+
MatIconModule,
|
|
29
|
+
MatProgressSpinnerModule,
|
|
30
|
+
MatButtonModule,
|
|
31
|
+
],
|
|
32
|
+
declarations: [
|
|
33
|
+
SpinnerComponent,
|
|
34
|
+
DownloadFileComponent,
|
|
35
|
+
FileDownloaderComponent,
|
|
36
|
+
],
|
|
37
|
+
exports: [
|
|
38
|
+
FileDownloaderComponent
|
|
39
|
+
]
|
|
40
|
+
}]
|
|
41
|
+
}] });
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1kb3dubG9hZC5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9odHRwLXJlcXVlc3QtbWFuYWdlci9zcmMvbGliL2h0dHAtcmVxdWVzdC1zZXJ2aWNlcy1kZW1vL3JlcXVlc3QtbWFuYWdlci1kZW1vL2ZpbGUtZG93bmxvYWRlci9maWxlLWRvd25sb2FkLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdkQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDOUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDBCQUEwQixDQUFDOztBQWtCM0QsTUFBTSxPQUFPLG9CQUFvQjsrR0FBcEIsb0JBQW9CO2dIQUFwQixvQkFBb0IsaUJBUjdCLGdCQUFnQjtZQUNoQixxQkFBcUI7WUFDckIsdUJBQXVCLGFBUnZCLFlBQVk7WUFDWixhQUFhO1lBQ2Isd0JBQXdCO1lBQ3hCLGVBQWUsYUFRZix1QkFBdUI7Z0hBR2Qsb0JBQW9CLFlBZDdCLFlBQVk7WUFDWixhQUFhO1lBQ2Isd0JBQXdCO1lBQ3hCLGVBQWU7OzRGQVdOLG9CQUFvQjtrQkFoQmhDLFFBQVE7bUJBQUM7b0JBQ1IsT0FBTyxFQUFFO3dCQUNQLFlBQVk7d0JBQ1osYUFBYTt3QkFDYix3QkFBd0I7d0JBQ3hCLGVBQWU7cUJBQ2hCO29CQUNELFlBQVksRUFBRTt3QkFDWixnQkFBZ0I7d0JBQ2hCLHFCQUFxQjt3QkFDckIsdUJBQXVCO3FCQUN4QjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsdUJBQXVCO3FCQUN4QjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5pbXBvcnQgeyBEb3dubG9hZEZpbGVDb21wb25lbnQgfSBmcm9tICcuL2Rvd25sb2FkLWZpbGUvZG93bmxvYWQtZmlsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgRmlsZURvd25sb2FkZXJDb21wb25lbnQgfSBmcm9tICcuL2ZpbGUtZG93bmxvYWRlci5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBTcGlubmVyQ29tcG9uZW50IH0gZnJvbSAnLi9zcGlubmVyL3NwaW5uZXIuY29tcG9uZW50JztcbmltcG9ydCB7IE1hdEljb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Byb2dyZXNzLXNwaW5uZXInO1xuaW1wb3J0IHsgTWF0QnV0dG9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBNYXRJY29uTW9kdWxlLFxuICAgIE1hdFByb2dyZXNzU3Bpbm5lck1vZHVsZSxcbiAgICBNYXRCdXR0b25Nb2R1bGUsXG4gIF0sXG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFNwaW5uZXJDb21wb25lbnQsXG4gICAgRG93bmxvYWRGaWxlQ29tcG9uZW50LFxuICAgIEZpbGVEb3dubG9hZGVyQ29tcG9uZW50LFxuICBdLFxuICBleHBvcnRzOiBbXG4gICAgRmlsZURvd25sb2FkZXJDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBGaWxlRG93bmxvYWRlck1vZHVsZSB7IH1cbiJdfQ==
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
|
|
2
|
+
import { catchError, distinctUntilChanged } from 'rxjs/operators';
|
|
3
|
+
import { DownloadLabels } from './models/download-labels-model';
|
|
4
|
+
import { HTTPManagerService } from '../../../services/request-manager-services';
|
|
5
|
+
import { ApiRequest } from '../../../services';
|
|
6
|
+
import { Subscription } from 'rxjs';
|
|
7
|
+
import { ToastColors, ToastDisplay } from 'toast-message-display';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "./download-file/download-file.component";
|
|
10
|
+
import * as i2 from "@angular/common";
|
|
11
|
+
export class FileDownloaderComponent extends HTTPManagerService {
|
|
12
|
+
set labels(value) {
|
|
13
|
+
this._labels = (value) ? DownloadLabels.adapt(value) : DownloadLabels.adapt();
|
|
14
|
+
}
|
|
15
|
+
get labels() {
|
|
16
|
+
return this._labels;
|
|
17
|
+
}
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.delayError = 3;
|
|
21
|
+
this.apiRequest = ApiRequest.adapt();
|
|
22
|
+
this.displayErrorMessage = false;
|
|
23
|
+
this._labels = DownloadLabels.adapt();
|
|
24
|
+
this.active = false;
|
|
25
|
+
this.subscription = new Subscription();
|
|
26
|
+
this.completed = new EventEmitter();
|
|
27
|
+
this.failed = new EventEmitter();
|
|
28
|
+
this.disabled = false;
|
|
29
|
+
}
|
|
30
|
+
ngOnInit() {
|
|
31
|
+
}
|
|
32
|
+
onDownloadStreaming() {
|
|
33
|
+
if (this.active)
|
|
34
|
+
return;
|
|
35
|
+
this.active = true;
|
|
36
|
+
return this.downloadRequest(this.apiRequest)
|
|
37
|
+
.pipe(distinctUntilChanged(), catchError((err) => {
|
|
38
|
+
this.onError(err.message);
|
|
39
|
+
this.active = false;
|
|
40
|
+
this.failed.emit(err);
|
|
41
|
+
return err;
|
|
42
|
+
})).subscribe((res) => {
|
|
43
|
+
if (res === 100) {
|
|
44
|
+
this.active = false;
|
|
45
|
+
this.completed.emit();
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
onError(message) {
|
|
50
|
+
if (!message || !this.displayErrorMessage)
|
|
51
|
+
return;
|
|
52
|
+
const display = ToastDisplay.adapt({
|
|
53
|
+
message,
|
|
54
|
+
action: 'Ok',
|
|
55
|
+
color: ToastColors.ERROR,
|
|
56
|
+
icon: 'error',
|
|
57
|
+
});
|
|
58
|
+
this.active = false;
|
|
59
|
+
this.toastMessage.toastMessage(display);
|
|
60
|
+
}
|
|
61
|
+
OnDestroy() {
|
|
62
|
+
this.subscription.unsubscribe();
|
|
63
|
+
}
|
|
64
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
65
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FileDownloaderComponent, selector: "app-file-downloader", inputs: { delayError: "delayError", apiRequest: "apiRequest", displayErrorMessage: "displayErrorMessage", labels: "labels", disabled: "disabled" }, outputs: { completed: "completed", failed: "failed" }, usesInheritance: true, ngImport: i0, template: "<app-download-file\n [disabled]=\"disabled\"\n [displayError]=\"3\"\n [event]=\"onDownloadStreaming.bind(this)\"\n [isPending]=\"(isPending$ | async) || false\"\n [progress]=\"(progress$ | async)\"\n [hasError]=\"(error$ | async)\"\n (error)=\"onError(labels.error)\"\n [active]=\"active\"\n></app-download-file>\n", styles: [".snackBarInfo{background-color:#f44336;color:#fff}.mat-simple-snackbar>span{font-weight:700}.mat-simple-snackbar-action .mat-button .mat-button-wrapper{color:#fff}.cdk-overlay-pane>.mat-snack-bar-container{width:100%}.mat-snack-bar-container{max-width:100%!important;width:100%}\n"], dependencies: [{ kind: "component", type: i1.DownloadFileComponent, selector: "app-download-file", inputs: ["event", "displayError", "diameter", "mode", "isPending", "active", "disabled", "progress", "hasError"], outputs: ["error"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
66
|
+
}
|
|
67
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FileDownloaderComponent, decorators: [{
|
|
68
|
+
type: Component,
|
|
69
|
+
args: [{ selector: 'app-file-downloader', encapsulation: ViewEncapsulation.None, template: "<app-download-file\n [disabled]=\"disabled\"\n [displayError]=\"3\"\n [event]=\"onDownloadStreaming.bind(this)\"\n [isPending]=\"(isPending$ | async) || false\"\n [progress]=\"(progress$ | async)\"\n [hasError]=\"(error$ | async)\"\n (error)=\"onError(labels.error)\"\n [active]=\"active\"\n></app-download-file>\n", styles: [".snackBarInfo{background-color:#f44336;color:#fff}.mat-simple-snackbar>span{font-weight:700}.mat-simple-snackbar-action .mat-button .mat-button-wrapper{color:#fff}.cdk-overlay-pane>.mat-snack-bar-container{width:100%}.mat-snack-bar-container{max-width:100%!important;width:100%}\n"] }]
|
|
70
|
+
}], ctorParameters: function () { return []; }, propDecorators: { delayError: [{
|
|
71
|
+
type: Input
|
|
72
|
+
}], apiRequest: [{
|
|
73
|
+
type: Input
|
|
74
|
+
}], displayErrorMessage: [{
|
|
75
|
+
type: Input
|
|
76
|
+
}], labels: [{
|
|
77
|
+
type: Input
|
|
78
|
+
}], completed: [{
|
|
79
|
+
type: Output
|
|
80
|
+
}], failed: [{
|
|
81
|
+
type: Output
|
|
82
|
+
}], disabled: [{
|
|
83
|
+
type: Input
|
|
84
|
+
}] } });
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1kb3dubG9hZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2h0dHAtcmVxdWVzdC1tYW5hZ2VyL3NyYy9saWIvaHR0cC1yZXF1ZXN0LXNlcnZpY2VzLWRlbW8vcmVxdWVzdC1tYW5hZ2VyLWRlbW8vZmlsZS1kb3dubG9hZGVyL2ZpbGUtZG93bmxvYWRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9odHRwLXJlcXVlc3QtbWFuYWdlci9zcmMvbGliL2h0dHAtcmVxdWVzdC1zZXJ2aWNlcy1kZW1vL3JlcXVlc3QtbWFuYWdlci1kZW1vL2ZpbGUtZG93bmxvYWRlci9maWxlLWRvd25sb2FkZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRyxPQUFPLEVBQUUsVUFBVSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBDLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7QUFRbEUsTUFBTSxPQUFPLHVCQUF3QixTQUFRLGtCQUF1QjtJQU9sRSxJQUFhLE1BQU0sQ0FBQyxLQUFxQjtRQUN2QyxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUMvRSxDQUFDO0lBTUQsSUFBSSxNQUFNO1FBQ1IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7SUFPRDtRQUNFLEtBQUssRUFBRSxDQUFBO1FBdkJBLGVBQVUsR0FBRyxDQUFDLENBQUE7UUFDZCxlQUFVLEdBQWUsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQzNDLHdCQUFtQixHQUFHLEtBQUssQ0FBQTtRQUVwQyxZQUFPLEdBQUcsY0FBYyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBS2hDLFdBQU0sR0FBRyxLQUFLLENBQUE7UUFFZCxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUE7UUFNdkIsY0FBUyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUE7UUFDcEMsV0FBTSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUE7UUFFcEMsYUFBUSxHQUFHLEtBQUssQ0FBQTtJQUl6QixDQUFDO0lBRUQsUUFBUTtJQUVSLENBQUM7SUFFRCxtQkFBbUI7UUFFakIsSUFBRyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU07UUFDdEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUE7UUFFbEIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7YUFDM0MsSUFBSSxDQUNILG9CQUFvQixFQUFFLEVBQ3RCLFVBQVUsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFBO1lBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3JCLE9BQU8sR0FBRyxDQUFBO1FBQ1osQ0FBQyxDQUFDLENBQ0gsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtZQUV2QixJQUFHLEdBQUcsS0FBSyxHQUFHLEVBQUU7Z0JBQ2QsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUE7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUE7YUFDdEI7UUFFSCxDQUFDLENBQUMsQ0FBQTtJQUVKLENBQUM7SUFFRCxPQUFPLENBQUMsT0FBZTtRQUVyQixJQUFHLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQjtZQUFFLE9BQU07UUFFaEQsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQztZQUNqQyxPQUFPO1lBQ1AsTUFBTSxFQUFFLElBQUk7WUFDWixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7WUFDeEIsSUFBSSxFQUFFLE9BQU87U0FDZCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQTtRQUVuQixJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUUxQyxDQUFDO0lBRUQsU0FBUztRQUNQLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDakMsQ0FBQzsrR0E1RVUsdUJBQXVCO21HQUF2Qix1QkFBdUIsNlJDaEJwQyxvVUFVQTs7NEZETWEsdUJBQXVCO2tCQU5uQyxTQUFTOytCQUNFLHFCQUFxQixpQkFHaEIsaUJBQWlCLENBQUMsSUFBSTswRUFJNUIsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFHTyxNQUFNO3NCQUFsQixLQUFLO2dCQVlJLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQUVFLFFBQVE7c0JBQWhCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IERvd25sb2FkTGFiZWxzIH0gZnJvbSAnLi9tb2RlbHMvZG93bmxvYWQtbGFiZWxzLW1vZGVsJztcbmltcG9ydCB7IEhUVFBNYW5hZ2VyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3JlcXVlc3QtbWFuYWdlci1zZXJ2aWNlcyc7XG5pbXBvcnQgeyBBcGlSZXF1ZXN0IH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFRvYXN0Q29sb3JzLCBUb2FzdERpc3BsYXkgfSBmcm9tICd0b2FzdC1tZXNzYWdlLWRpc3BsYXknO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZmlsZS1kb3dubG9hZGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2ZpbGUtZG93bmxvYWRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ZpbGUtZG93bmxvYWRlci5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBGaWxlRG93bmxvYWRlckNvbXBvbmVudCBleHRlbmRzIEhUVFBNYW5hZ2VyU2VydmljZTxhbnk+IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBASW5wdXQoKSBkZWxheUVycm9yID0gM1xuICBASW5wdXQoKSBhcGlSZXF1ZXN0OiBBcGlSZXF1ZXN0ID0gQXBpUmVxdWVzdC5hZGFwdCgpXG4gIEBJbnB1dCgpIGRpc3BsYXlFcnJvck1lc3NhZ2UgPSBmYWxzZVxuXG4gIF9sYWJlbHMgPSBEb3dubG9hZExhYmVscy5hZGFwdCgpXG4gIEBJbnB1dCgpIHNldCBsYWJlbHModmFsdWU6IERvd25sb2FkTGFiZWxzKSB7XG4gICAgdGhpcy5fbGFiZWxzID0gKHZhbHVlKSA/IERvd25sb2FkTGFiZWxzLmFkYXB0KHZhbHVlKSA6IERvd25sb2FkTGFiZWxzLmFkYXB0KClcbiAgfVxuXG4gIGFjdGl2ZSA9IGZhbHNlXG5cbiAgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpXG5cbiAgZ2V0IGxhYmVscygpIHtcbiAgICByZXR1cm4gdGhpcy5fbGFiZWxzXG4gIH1cblxuICBAT3V0cHV0KCkgY29tcGxldGVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpXG4gIEBPdXRwdXQoKSBmYWlsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKVxuXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2VcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpXG4gIH1cblxuICBuZ09uSW5pdCgpIHtcblxuICB9XG5cbiAgb25Eb3dubG9hZFN0cmVhbWluZygpIHtcblxuICAgIGlmKHRoaXMuYWN0aXZlKSByZXR1cm5cbiAgICB0aGlzLmFjdGl2ZSA9IHRydWVcblxuICAgIHJldHVybiB0aGlzLmRvd25sb2FkUmVxdWVzdCh0aGlzLmFwaVJlcXVlc3QpXG4gICAgLnBpcGUoXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgICAgY2F0Y2hFcnJvcigoZXJyKSA9PiB7XG4gICAgICAgIHRoaXMub25FcnJvcihlcnIubWVzc2FnZSlcbiAgICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZVxuICAgICAgICB0aGlzLmZhaWxlZC5lbWl0KGVycilcbiAgICAgICAgcmV0dXJuIGVyclxuICAgICAgfSlcbiAgICApLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcblxuICAgICAgaWYocmVzID09PSAxMDApIHtcbiAgICAgICAgdGhpcy5hY3RpdmUgPSBmYWxzZVxuICAgICAgICB0aGlzLmNvbXBsZXRlZC5lbWl0KClcbiAgICAgIH1cblxuICAgIH0pXG5cbiAgfVxuXG4gIG9uRXJyb3IobWVzc2FnZTogc3RyaW5nKSB7XG5cbiAgICBpZighbWVzc2FnZSB8fCAhdGhpcy5kaXNwbGF5RXJyb3JNZXNzYWdlKSByZXR1cm5cblxuICAgIGNvbnN0IGRpc3BsYXkgPSBUb2FzdERpc3BsYXkuYWRhcHQoe1xuICAgICAgbWVzc2FnZSxcbiAgICAgIGFjdGlvbjogJ09rJyxcbiAgICAgIGNvbG9yOiBUb2FzdENvbG9ycy5FUlJPUixcbiAgICAgIGljb246ICdlcnJvcicsXG4gICAgfSk7XG5cbiAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlXG5cbiAgICB0aGlzLnRvYXN0TWVzc2FnZS50b2FzdE1lc3NhZ2UoZGlzcGxheSk7XG5cbiAgfVxuXG4gIE9uRGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpXG4gIH1cblxufVxuIiwiPGFwcC1kb3dubG9hZC1maWxlXG4gIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gIFtkaXNwbGF5RXJyb3JdPVwiM1wiXG4gIFtldmVudF09XCJvbkRvd25sb2FkU3RyZWFtaW5nLmJpbmQodGhpcylcIlxuICBbaXNQZW5kaW5nXT1cIihpc1BlbmRpbmckIHwgYXN5bmMpIHx8IGZhbHNlXCJcbiAgW3Byb2dyZXNzXT1cIihwcm9ncmVzcyQgfCBhc3luYylcIlxuICBbaGFzRXJyb3JdPVwiKGVycm9yJCB8IGFzeW5jKVwiXG4gIChlcnJvcik9XCJvbkVycm9yKGxhYmVscy5lcnJvcilcIlxuICBbYWN0aXZlXT1cImFjdGl2ZVwiXG4+PC9hcHAtZG93bmxvYWQtZmlsZT5cbiJdfQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class DownloadLabels {
|
|
2
|
+
constructor(error = '', action = '', icon = 'error') {
|
|
3
|
+
this.error = error;
|
|
4
|
+
this.action = action;
|
|
5
|
+
this.icon = icon;
|
|
6
|
+
}
|
|
7
|
+
static adapt(item) {
|
|
8
|
+
return new DownloadLabels(item?.error, item?.action, item?.icon);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQtbGFiZWxzLW1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LW1hbmFnZXIvc3JjL2xpYi9odHRwLXJlcXVlc3Qtc2VydmljZXMtZGVtby9yZXF1ZXN0LW1hbmFnZXItZGVtby9maWxlLWRvd25sb2FkZXIvbW9kZWxzL2Rvd25sb2FkLWxhYmVscy1tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxNQUFNLE9BQU8sY0FBYztJQUN6QixZQUNTLFFBQVEsRUFBRSxFQUNWLFNBQVMsRUFBRSxFQUNYLE9BQU8sT0FBTztRQUZkLFVBQUssR0FBTCxLQUFLLENBQUs7UUFDVixXQUFNLEdBQU4sTUFBTSxDQUFLO1FBQ1gsU0FBSSxHQUFKLElBQUksQ0FBVTtJQUNwQixDQUFDO0lBRUwsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFVO1FBQ3BCLE9BQU8sSUFBSSxjQUFjLENBQ3ZCLElBQUksRUFBRSxLQUFLLEVBQ1gsSUFBSSxFQUFFLE1BQU0sRUFDWixJQUFJLEVBQUUsSUFBSSxDQUNYLENBQUE7SUFFSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIERvd25sb2FkTGFiZWxzSW50ZXJmYWNlIHtcbiAgZXJyb3I6IHN0cmluZztcbiAgYWN0aW9uOiBzdHJpbmc7XG4gIGljb246IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIERvd25sb2FkTGFiZWxzIGltcGxlbWVudHMgRG93bmxvYWRMYWJlbHNJbnRlcmZhY2Uge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZXJyb3IgPSAnJyxcbiAgICBwdWJsaWMgYWN0aW9uID0gJycsXG4gICAgcHVibGljIGljb24gPSAnZXJyb3InLFxuICApIHt9XG5cbiBzdGF0aWMgYWRhcHQoaXRlbT86IGFueSk6IERvd25sb2FkTGFiZWxzSW50ZXJmYWNlIHtcbiAgICByZXR1cm4gbmV3IERvd25sb2FkTGFiZWxzKFxuICAgICAgaXRlbT8uZXJyb3IsXG4gICAgICBpdGVtPy5hY3Rpb24sXG4gICAgICBpdGVtPy5pY29uLFxuICAgIClcblxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/material/progress-spinner";
|
|
4
|
+
export class SpinnerComponent {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.value = 0;
|
|
7
|
+
}
|
|
8
|
+
ngOnInit() {
|
|
9
|
+
}
|
|
10
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
11
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpinnerComponent, selector: "app-spinner", inputs: { color: "color", diameter: "diameter", display: "display", mode: "mode", strokeWidth: "strokeWidth", value: "value" }, ngImport: i0, template: "<div class=\"spinner-background\">{{display}}</div>\n<mat-progress-spinner\n [color]=\"color\"\n [diameter]=\"diameter\"\n [mode]=\"mode || 'indeterminate'\"\n [strokeWidth]=\"strokeWidth\"\n [value]=\"value\">\n</mat-progress-spinner>\n", styles: [".example-h2{margin:24px 0}:not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:80px;height:80px;line-height:80px;text-align:center;overflow:hidden;border-color:#673ab71f;border-radius:50%;border-style:solid;border-width:10px}\n"], dependencies: [{ kind: "component", type: i1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
12
|
+
}
|
|
13
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpinnerComponent, decorators: [{
|
|
14
|
+
type: Component,
|
|
15
|
+
args: [{ selector: 'app-spinner', template: "<div class=\"spinner-background\">{{display}}</div>\n<mat-progress-spinner\n [color]=\"color\"\n [diameter]=\"diameter\"\n [mode]=\"mode || 'indeterminate'\"\n [strokeWidth]=\"strokeWidth\"\n [value]=\"value\">\n</mat-progress-spinner>\n", styles: [".example-h2{margin:24px 0}:not(spinner-container).spinner-container{position:relative}:not(spinner-container).spinner-container .spinner-background{position:absolute;width:80px;height:80px;line-height:80px;text-align:center;overflow:hidden;border-color:#673ab71f;border-radius:50%;border-style:solid;border-width:10px}\n"] }]
|
|
16
|
+
}], ctorParameters: function () { return []; }, propDecorators: { color: [{
|
|
17
|
+
type: Input
|
|
18
|
+
}], diameter: [{
|
|
19
|
+
type: Input
|
|
20
|
+
}], display: [{
|
|
21
|
+
type: Input
|
|
22
|
+
}], mode: [{
|
|
23
|
+
type: Input
|
|
24
|
+
}], strokeWidth: [{
|
|
25
|
+
type: Input
|
|
26
|
+
}], value: [{
|
|
27
|
+
type: Input
|
|
28
|
+
}] } });
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bpbm5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9odHRwLXJlcXVlc3QtbWFuYWdlci9zcmMvbGliL2h0dHAtcmVxdWVzdC1zZXJ2aWNlcy1kZW1vL3JlcXVlc3QtbWFuYWdlci1kZW1vL2ZpbGUtZG93bmxvYWRlci9zcGlubmVyL3NwaW5uZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LW1hbmFnZXIvc3JjL2xpYi9odHRwLXJlcXVlc3Qtc2VydmljZXMtZGVtby9yZXF1ZXN0LW1hbmFnZXItZGVtby9maWxlLWRvd25sb2FkZXIvc3Bpbm5lci9zcGlubmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDOzs7QUFTekQsTUFBTSxPQUFPLGdCQUFnQjtJQVUzQjtRQUZTLFVBQUssR0FBRyxDQUFDLENBQUE7SUFFRixDQUFDO0lBRWpCLFFBQVE7SUFDUixDQUFDOytHQWJVLGdCQUFnQjttR0FBaEIsZ0JBQWdCLG1MQ1Q3Qiw4UEFRQTs7NEZEQ2EsZ0JBQWdCO2tCQUw1QixTQUFTOytCQUNFLGFBQWE7MEVBTWQsS0FBSztzQkFBYixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVGhlbWVQYWxldHRlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQgeyBQcm9ncmVzc1NwaW5uZXJNb2RlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcHJvZ3Jlc3Mtc3Bpbm5lcic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zcGlubmVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwaW5uZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGlubmVyLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgU3Bpbm5lckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgQElucHV0KCkgY29sb3I6IFRoZW1lUGFsZXR0ZTtcblxuICBASW5wdXQoKSBkaWFtZXRlcj86IG51bWJlcjtcbiAgQElucHV0KCkgZGlzcGxheT86IHN0cmluZyB8IG51bWJlcjtcbiAgQElucHV0KCkgbW9kZT86IFByb2dyZXNzU3Bpbm5lck1vZGU7XG4gIEBJbnB1dCgpIHN0cm9rZVdpZHRoPzogbnVtYmVyO1xuICBASW5wdXQoKSB2YWx1ZSA9IDBcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICB9XG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJzcGlubmVyLWJhY2tncm91bmRcIj57e2Rpc3BsYXl9fTwvZGl2PlxuPG1hdC1wcm9ncmVzcy1zcGlubmVyXG4gICAgW2NvbG9yXT1cImNvbG9yXCJcbiAgICBbZGlhbWV0ZXJdPVwiZGlhbWV0ZXJcIlxuICAgIFttb2RlXT1cIm1vZGUgfHwgJ2luZGV0ZXJtaW5hdGUnXCJcbiAgICBbc3Ryb2tlV2lkdGhdPVwic3Ryb2tlV2lkdGhcIlxuICAgIFt2YWx1ZV09XCJ2YWx1ZVwiPlxuPC9tYXQtcHJvZ3Jlc3Mtc3Bpbm5lcj5cbiJdfQ==
|
package/esm2022/lib/http-request-services-demo/request-manager-demo/models/sample-ai-prompt.mjs
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export class AIPrompt {
|
|
2
|
+
constructor(response = '') {
|
|
3
|
+
this.response = response;
|
|
4
|
+
}
|
|
5
|
+
static adapt(item) {
|
|
6
|
+
return new AIPrompt(item?.response);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FtcGxlLWFpLXByb21wdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2h0dHAtcmVxdWVzdC1tYW5hZ2VyL3NyYy9saWIvaHR0cC1yZXF1ZXN0LXNlcnZpY2VzLWRlbW8vcmVxdWVzdC1tYW5hZ2VyLWRlbW8vbW9kZWxzL3NhbXBsZS1haS1wcm9tcHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsTUFBTSxPQUFPLFFBQVE7SUFFbkIsWUFDUyxXQUFXLEVBQUU7UUFBYixhQUFRLEdBQVIsUUFBUSxDQUFLO0lBQ25CLENBQUM7SUFFSixNQUFNLENBQUMsS0FBSyxDQUFDLElBQVU7UUFFckIsT0FBTyxJQUFJLFFBQVEsQ0FDakIsSUFBSSxFQUFFLFFBQVEsQ0FDZixDQUFBO0lBRUgsQ0FBQztDQUVGIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBBSVByb21wdEludGVyZmFjZSB7XG4gIHJlc3BvbnNlOiBzdHJpbmdcbn1cblxuZXhwb3J0IGNsYXNzIEFJUHJvbXB0IGltcGxlbWVudHMgQUlQcm9tcHRJbnRlcmZhY2Uge1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZXNwb25zZSA9ICcnLFxuICApIHt9XG5cbiAgc3RhdGljIGFkYXB0KGl0ZW0/OiBhbnkpOiBBSVByb21wdCB7XG5cbiAgICByZXR1cm4gbmV3IEFJUHJvbXB0KFxuICAgICAgaXRlbT8ucmVzcG9uc2UsXG4gICAgKVxuXG4gIH1cblxufVxuIl19
|