@iotize/ionic
Version:
Iotize specific building blocks on top of @ionic/angular.
160 lines • 24.3 kB
JavaScript
import { Injectable } from '@angular/core';
import { FormControl } from '@angular/forms';
import { deepCopy, deepEqual } from '@iotize/common/utility';
import { TapInfo, TapInfoCacheService, TapInfoConfigService, TapInfoDAOService, createCacheKey, toTapInfoKeyObject, } from '@iotize/ionic';
import { BehaviorSubject, Subject, concat, defer, of } from 'rxjs';
import { distinctUntilChanged, map, shareReplay, switchMap, tap, } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@iotize/ionic";
export class TapConfigItemStateService {
/**
* Value change taking into acccount the edited value.
* If no editaded value for the key, it will take the lasted fetched value from the Tap
* @param key
* @returns
*/
valueChange(key) {
return this._pendingChanges.pipe(switchMap((changes) => {
const hashKey = createCacheKey(toTapInfoKeyObject(key));
const editedValue = changes.find((entry) => createCacheKey(entry.key) === hashKey);
if (editedValue !== undefined) {
return of(editedValue.value);
}
else {
return this.tapInfoCacheService.valueChange(key);
}
}), distinctUntilChanged(deepEqual), shareReplay(1));
}
getPendingChangeForKey(key) {
return this._pendingChanges.pipe(map((changes) => {
const hashKey = createCacheKey(toTapInfoKeyObject(key));
return changes.find((entry) => createCacheKey(entry.key) === hashKey)
?.value;
}), distinctUntilChanged(deepEqual), shareReplay(1));
}
get pendingChangesChange() {
return this._pendingChanges.asObservable();
}
get saveProgress() {
return this._saveProgress.asObservable();
}
constructor(tapInfoDAOService, tapInfoCacheService, tapInfoConfigService) {
this.tapInfoDAOService = tapInfoDAOService;
this.tapInfoCacheService = tapInfoCacheService;
this.tapInfoConfigService = tapInfoConfigService;
this._pendingChanges = new BehaviorSubject([]);
this.loading = false;
this.hasPendingChanges = this._pendingChanges.pipe(map((changes) => changes.length > 0));
this.validationErrorsChange = this._pendingChanges.pipe(map((changes) => {
return changes.reduce((acc, change) => {
const tapConfigItem = this.tapInfoConfigService.findByKey(change.key);
if (!tapConfigItem) {
console.warn(`Failed to find Tap Config Item Key "${change.key}"`);
return acc;
}
tapConfigItem.input?.formValidators?.forEach((validator) => {
const error = validator(new FormControl(change.value));
if (error) {
acc.set(change.key, {
value: change.value,
errors: error,
});
}
});
return acc;
}, new Map());
}));
this.validationErrorsCountChange = this.validationErrorsChange.pipe(map((changeErrors) => {
return Array.from(changeErrors.keys()).length;
}), shareReplay({ bufferSize: 1, refCount: true }));
this.hasValidationErrors = this.validationErrorsCountChange.pipe(map((count) => {
return count > 0;
}));
this._saveProgress = new Subject();
}
async savePendingChanges() {
try {
this.loading = true;
await this._savePendingChangesWithProgress().toPromise();
}
finally {
this.loading = false;
}
}
_savePendingChangesWithProgress() {
const configItemStateChanges = this.getPendingChangesSnapshot().filter(({ key }) => {
return key.key !== TapInfo.configVersion;
});
const observables = configItemStateChanges.map(({ key, value }) => {
return defer(async () => {
await this.tapInfoDAOService.put(key, value);
this.tapInfoDAOService.get(key).catch((err) => { });
});
});
const total = configItemStateChanges.length;
const saveProgress = concat(...observables).pipe(map((info, index) => {
return {
total,
loaded: index + 1,
payload: info,
};
}), tap(this._saveProgress));
return saveProgress;
}
clearPendingChanges() {
this._pendingChanges.next([]);
}
getPendingChangesSnapshot() {
return deepCopy(this._pendingChanges.value);
}
clearPendingChange(tapInfoKey) {
const hashKey = createCacheKey(tapInfoKey);
const pendingChangesSnapshot = this._pendingChanges.value;
const pendingChangeIndex = pendingChangesSnapshot.findIndex((entry) => createCacheKey(entry.key) === hashKey);
if (pendingChangeIndex >= 0) {
pendingChangesSnapshot.splice(pendingChangeIndex, 1);
this._pendingChanges.next(pendingChangesSnapshot);
}
}
setPendingChange(info, newValue) {
// Make sure we don't store any other info otherwise deepCopy may failed
info = {
key: info.key,
params: info.params,
};
const hashKey = createCacheKey(info);
const pendingChangesSnapshot = this._pendingChanges.value;
const item = pendingChangesSnapshot.find((entry) => createCacheKey(entry.key) === hashKey);
if (!item) {
pendingChangesSnapshot.push({
key: info,
value: newValue,
});
this._pendingChanges.next(pendingChangesSnapshot);
}
else {
if (!deepEqual(item.value, newValue)) {
item.value = newValue;
this._pendingChanges.next(pendingChangesSnapshot);
}
}
}
removePendingChange(info) {
const hashKey = createCacheKey(info);
const pendingChangesSnapshot = this._pendingChanges.value;
const indexOfItem = pendingChangesSnapshot.findIndex((entry) => createCacheKey(entry.key) === hashKey);
if (indexOfItem >= 0) {
pendingChangesSnapshot.splice(indexOfItem, 1);
this._pendingChanges.next(pendingChangesSnapshot);
}
}
}
/** @nocollapse */ TapConfigItemStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapConfigItemStateService, deps: [{ token: i1.TapInfoDAOService }, { token: i1.TapInfoCacheService }, { token: i1.TapInfoConfigService }], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ TapConfigItemStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapConfigItemStateService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TapConfigItemStateService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.TapInfoDAOService }, { type: i1.TapInfoCacheService }, { type: i1.TapInfoConfigService }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFwLWNvbmZpZy1pdGVtLXN0YXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pb3RpemUtaW9uaWMvY29uZmlnL3NyYy9saWIvdGFwLWNvbmZpZy1pdGVtLXN0YXRlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsV0FBVyxFQUFvQixNQUFNLGdCQUFnQixDQUFDO0FBRS9ELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0QsT0FBTyxFQUNMLE9BQU8sRUFDUCxtQkFBbUIsRUFDbkIsb0JBQW9CLEVBQ3BCLGlCQUFpQixFQUdqQixjQUFjLEVBQ2Qsa0JBQWtCLEdBQ25CLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9FLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsR0FBRyxFQUNILFdBQVcsRUFDWCxTQUFTLEVBQ1QsR0FBRyxHQUNKLE1BQU0sZ0JBQWdCLENBQUM7OztBQUt4QixNQUFNLE9BQU8seUJBQXlCO0lBeURwQzs7Ozs7T0FLRztJQUNILFdBQVcsQ0FBSSxHQUE2QjtRQUMxQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUM5QixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQWlCLEVBQUU7WUFDbkMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDeEQsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FDOUIsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtB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c0IsQ0FBQyxDQUFDO2FBQ25EO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsbUJBQW1CLENBQUMsSUFBZ0I7UUFDbEMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7UUFDMUQsTUFBTSxXQUFXLEdBQUcsc0JBQXNCLENBQUMsU0FBUyxDQUNsRCxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxPQUFPLENBQ2pELENBQUM7UUFFRixJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUU7WUFDcEIsc0JBQXNCLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM5QyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ25EO0lBQ0gsQ0FBQzs7MElBMU1VLHlCQUF5Qjs4SUFBekIseUJBQXlCLGNBRnhCLE1BQU07NEZBRVAseUJBQXlCO2tCQUhyQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBWYWxpZGF0aW9uRXJyb3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUHJvZ3Jlc3NTdGF0ZSB9IGZyb20gJ0Bpb3RpemUvY29tbW9uL3Byb2dyZXNzL2FwaSc7XG5pbXBvcnQgeyBkZWVwQ29weSwgZGVlcEVxdWFsIH0gZnJvbSAnQGlvdGl6ZS9jb21tb24vdXRpbGl0eSc7XG5pbXBvcnQge1xuICBUYXBJbmZvLFxuICBUYXBJbmZvQ2FjaGVTZXJ2aWNlLFxuICBUYXBJbmZvQ29uZmlnU2VydmljZSxcbiAgVGFwSW5mb0RBT1NlcnZpY2UsXG4gIFRhcEluZm9LZXksXG4gIFRhcEluZm9LZXlPYmplY3RPclN0cmluZyxcbiAgY3JlYXRlQ2FjaGVLZXksXG4gIHRvVGFwSW5mb0tleU9iamVjdCxcbn0gZnJvbSAnQGlvdGl6ZS9pb25pYyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUsIFN1YmplY3QsIGNvbmNhdCwgZGVmZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgbWFwLFxuICBzaGFyZVJlcGxheSxcbiAgc3dpdGNoTWFwLFxuICB0YXAsXG59IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFRhcENvbmZpZ0l0ZW1TdGF0ZVNlcnZpY2Uge1xuICBwcml2YXRlIF9wZW5kaW5nQ2hhbmdlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XG4gICAge1xuICAgICAga2V5OiBUYXBJbmZvS2V5O1xuICAgICAgdmFsdWU6IGFueTtcbiAgICB9W11cbiAgPihbXSk7XG5cbiAgbG9hZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIGhhc1BlbmRpbmdDaGFuZ2VzOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5fcGVuZGluZ0NoYW5nZXMucGlwZShcbiAgICBtYXAoKGNoYW5nZXMpID0+IGNoYW5nZXMubGVuZ3RoID4gMClcbiAgKTtcblxuICB2YWxpZGF0aW9uRXJyb3JzQ2hhbmdlID0gdGhpcy5fcGVuZGluZ0NoYW5nZXMucGlwZShcbiAgICBtYXAoKGNoYW5nZXMpID0+IHtcbiAgICAgIHJldHVybiBjaGFuZ2VzLnJlZHVjZTxcbiAgICAgICAgTWFwPFxuICAgICAgICAgIFRhcEluZm9LZXksXG4gICAgICAgICAge1xuICAgICAgICAgICAgdmFsdWU6IGFueTtcbiAgICAgICAgICAgIGVycm9yczogVmFsaWRhdGlvbkVycm9ycztcbiAgICAgICAgICB9XG4gICAgICAgID5cbiAgICAgID4oKGFjYywgY2hhbmdlKSA9PiB7XG4gICAgICAgIGNvbnN0IHRhcENvbmZpZ0l0ZW0gPSB0aGlzLnRhcEluZm9Db25maWdTZXJ2aWNlLmZpbmRCeUtleShjaGFuZ2Uua2V5KTtcbiAgICAgICAgaWYgKCF0YXBDb25maWdJdGVtKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKGBGYWlsZWQgdG8gZmluZCBUYXAgQ29uZmlnIEl0ZW0gS2V5IFwiJHtjaGFuZ2Uua2V5fVwiYCk7XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfVxuICAgICAgICB0YXBDb25maWdJdGVtLmlucHV0Py5mb3JtVmFsaWRhdG9ycz8uZm9yRWFjaCgodmFsaWRhdG9yKSA9PiB7XG4gICAgICAgICAgY29uc3QgZXJyb3IgPSB2YWxpZGF0b3IobmV3IEZvcm1Db250cm9sKGNoYW5nZS52YWx1ZSkpO1xuICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgYWNjLnNldChjaGFuZ2Uua2V5LCB7XG4gICAgICAgICAgICAgIHZhbHVlOiBjaGFuZ2UudmFsdWUsXG4gICAgICAgICAgICAgIGVycm9yczogZXJyb3IsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IE1hcCgpKTtcbiAgICB9KVxuICApO1xuXG4gIHZhbGlkYXRpb25FcnJvcnNDb3VudENoYW5nZSA9IHRoaXMudmFsaWRhdGlvbkVycm9yc0NoYW5nZS5waXBlKFxuICAgIG1hcCgoY2hhbmdlRXJyb3JzKSA9PiB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbShjaGFuZ2VFcnJvcnMua2V5cygpKS5sZW5ndGg7XG4gICAgfSksXG4gICAgc2hhcmVSZXBsYXkoeyBidWZmZXJTaXplOiAxLCByZWZDb3VudDogdHJ1ZSB9KVxuICApO1xuXG4gIGhhc1ZhbGlkYXRpb25FcnJvcnMgPSB0aGlzLnZhbGlkYXRpb25FcnJvcnNDb3VudENoYW5nZS5waXBlKFxuICAgIG1hcCgoY291bnQpID0+IHtcbiAgICAgIHJldHVybiBjb3VudCA+IDA7XG4gICAgfSlcbiAgKTtcblxuICAvKipcbiAgICogVmFsdWUgY2hhbmdlIHRha2luZyBpbnRvIGFjY2NvdW50IHRoZSBlZGl0ZWQgdmFsdWUuXG4gICAqIElmIG5vIGVkaXRhZGVkIHZhbHVlIGZvciB0aGUga2V5LCBpdCB3aWxsIHRha2UgdGhlIGxhc3RlZCBmZXRjaGVkIHZhbHVlIGZyb20gdGhlIFRhcFxuICAgKiBAcGFyYW0ga2V5XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICB2YWx1ZUNoYW5nZTxUPihrZXk6IFRhcEluZm9LZXlPYmplY3RPclN0cmluZyk6IE9ic2VydmFibGU8VD4ge1xuICAgIHJldHVybiB0aGlzLl9wZW5kaW5nQ2hhbmdlcy5waXBlKFxuICAgICAgc3dpdGNoTWFwKChjaGFuZ2VzKTogT2JzZXJ2YWJsZTxUPiA9PiB7XG4gICAgICAgIGNvbnN0IGhhc2hLZXkgPSBjcmVhdGVDYWNoZUtleSh0b1RhcEluZm9LZXlPYmplY3Qoa2V5KSk7XG4gICAgICAgIGNvbnN0IGVkaXRlZFZhbHVlID0gY2hhbmdlcy5maW5kKFxuICAgICAgICAgIChlbnRyeSkgPT4gY3JlYXRlQ2FjaGVLZXkoZW50cnkua2V5KSA9PT0gaGFzaEtleVxuICAgICAgICApO1xuICAgICAgICBpZiAoZWRpdGVkVmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBvZihlZGl0ZWRWYWx1ZS52YWx1ZSBhcyBUKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy50YXBJbmZvQ2FjaGVTZXJ2aWNlLnZhbHVlQ2hhbmdlPFQ+KGtleSk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoZGVlcEVxdWFsKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIGdldFBlbmRpbmdDaGFuZ2VGb3JLZXk8VCA9IHVua25vd24+KFxuICAgIGtleTogVGFwSW5mb0tleU9iamVjdE9yU3RyaW5nXG4gICk6IE9ic2VydmFibGU8VCB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVybiB0aGlzLl9wZW5kaW5nQ2hhbmdlcy5waXBlKFxuICAgICAgbWFwKChjaGFuZ2VzKSA9PiB7XG4gICAgICAgIGNvbnN0IGhhc2hLZXkgPSBjcmVhdGVDYWNoZUtleSh0b1RhcEluZm9LZXlPYmplY3Qoa2V5KSk7XG4gICAgICAgIHJldHVybiBjaGFuZ2VzLmZpbmQoKGVudHJ5KSA9PiBjcmVhdGVDYWNoZUtleShlbnRyeS5rZXkpID09PSBoYXNoS2V5KVxuICAgICAgICAgID8udmFsdWU7XG4gICAgICB9KSxcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKGRlZXBFcXVhbCksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICBnZXQgcGVuZGluZ0NoYW5nZXNDaGFuZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BlbmRpbmdDaGFuZ2VzLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2F2ZVByb2dyZXNzID0gbmV3IFN1YmplY3Q8UHJvZ3Jlc3NTdGF0ZT4oKTtcblxuICBnZXQgc2F2ZVByb2dyZXNzKCkge1xuICAgIHJldHVybiB0aGlzLl9zYXZlUHJvZ3Jlc3MuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRhcEluZm9EQU9TZXJ2aWNlOiBUYXBJbmZvREFPU2VydmljZSxcbiAgICBwcml2YXRlIHRhcEluZm9DYWNoZVNlcnZpY2U6IFRhcEluZm9DYWNoZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSB0YXBJbmZvQ29uZmlnU2VydmljZTogVGFwSW5mb0NvbmZpZ1NlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIHNhdmVQZW5kaW5nQ2hhbmdlcygpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgIGF3YWl0IHRoaXMuX3NhdmVQZW5kaW5nQ2hhbmdlc1dpdGhQcm9ncmVzcygpLnRvUHJvbWlzZSgpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9zYXZlUGVuZGluZ0NoYW5nZXNXaXRoUHJvZ3Jlc3MoKSB7XG4gICAgY29uc3QgY29uZmlnSXRlbVN0YXRlQ2hhbmdlcyA9IHRoaXMuZ2V0UGVuZGluZ0NoYW5nZXNTbmFwc2hvdCgpLmZpbHRlcihcbiAgICAgICh7IGtleSB9KSA9PiB7XG4gICAgICAgIHJldHVybiBrZXkua2V5ICE9PSBUYXBJbmZvLmNvbmZpZ1ZlcnNpb247XG4gICAgICB9XG4gICAgKTtcbiAgICBjb25zdCBvYnNlcnZhYmxlcyA9IGNvbmZpZ0l0ZW1TdGF0ZUNoYW5nZXMubWFwKCh7IGtleSwgdmFsdWUgfSkgPT4ge1xuICAgICAgcmV0dXJuIGRlZmVyKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy50YXBJbmZvREFPU2VydmljZS5wdXQoa2V5LCB2YWx1ZSk7XG4gICAgICAgIHRoaXMudGFwSW5mb0RBT1NlcnZpY2UuZ2V0KGtleSkuY2F0Y2goKGVycikgPT4ge30pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgY29uc3QgdG90YWwgPSBjb25maWdJdGVtU3RhdGVDaGFuZ2VzLmxlbmd0aDtcbiAgICBjb25zdCBzYXZlUHJvZ3Jlc3MgPSBjb25jYXQoLi4ub2JzZXJ2YWJsZXMpLnBpcGUoXG4gICAgICBtYXAoKGluZm8sIGluZGV4KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdG90YWwsXG4gICAgICAgICAgbG9hZGVkOiBpbmRleCArIDEsXG4gICAgICAgICAgcGF5bG9hZDogaW5mbyxcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgICAgdGFwKHRoaXMuX3NhdmVQcm9ncmVzcylcbiAgICApO1xuICAgIHJldHVybiBzYXZlUHJvZ3Jlc3M7XG4gIH1cblxuICBjbGVhclBlbmRpbmdDaGFuZ2VzKCkge1xuICAgIHRoaXMuX3BlbmRpbmdDaGFuZ2VzLm5leHQoW10pO1xuICB9XG5cbiAgZ2V0UGVuZGluZ0NoYW5nZXNTbmFwc2hvdCgpIHtcbiAgICByZXR1cm4gZGVlcENvcHkodGhpcy5fcGVuZGluZ0NoYW5nZXMudmFsdWUpO1xuICB9XG5cbiAgY2xlYXJQZW5kaW5nQ2hhbmdlKHRhcEluZm9LZXk6IFRhcEluZm9LZXkpIHtcbiAgICBjb25zdCBoYXNoS2V5ID0gY3JlYXRlQ2FjaGVLZXkodGFwSW5mb0tleSk7XG4gICAgY29uc3QgcGVuZGluZ0NoYW5nZXNTbmFwc2hvdCA9IHRoaXMuX3BlbmRpbmdDaGFuZ2VzLnZhbHVlO1xuICAgIGNvbnN0IHBlbmRpbmdDaGFuZ2VJbmRleCA9IHBlbmRpbmdDaGFuZ2VzU25hcHNob3QuZmluZEluZGV4KFxuICAgICAgKGVudHJ5KSA9PiBjcmVhdGVDYWNoZUtleShlbnRyeS5rZXkpID09PSBoYXNoS2V5XG4gICAgKTtcbiAgICBpZiAocGVuZGluZ0NoYW5nZUluZGV4ID49IDApIHtcbiAgICAgIHBlbmRpbmdDaGFuZ2VzU25hcHNob3Quc3BsaWNlKHBlbmRpbmdDaGFuZ2VJbmRleCwgMSk7XG4gICAgICB0aGlzLl9wZW5kaW5nQ2hhbmdlcy5uZXh0KHBlbmRpbmdDaGFuZ2VzU25hcHNob3QpO1xuICAgIH1cbiAgfVxuXG4gIHNldFBlbmRpbmdDaGFuZ2UoaW5mbzogVGFwSW5mb0tleSwgbmV3VmFsdWU6IGFueSkge1xuICAgIC8vIE1ha2Ugc3VyZSB3ZSBkb24ndCBzdG9yZSBhbnkgb3RoZXIgaW5mbyBvdGhlcndpc2UgZGVlcENvcHkgbWF5IGZhaWxlZFxuICAgIGluZm8gPSB7XG4gICAgICBrZXk6IGluZm8ua2V5LFxuICAgICAgcGFyYW1zOiBpbmZvLnBhcmFtcyxcbiAgICB9O1xuICAgIGNvbnN0IGhhc2hLZXkgPSBjcmVhdGVDYWNoZUtleShpbmZvKTtcbiAgICBjb25zdCBwZW5kaW5nQ2hhbmdlc1NuYXBzaG90ID0gdGhpcy5fcGVuZGluZ0NoYW5nZXMudmFsdWU7XG4gICAgY29uc3QgaXRlbSA9IHBlbmRpbmdDaGFuZ2VzU25hcHNob3QuZmluZChcbiAgICAgIChlbnRyeSkgPT4gY3JlYXRlQ2FjaGVLZXkoZW50cnkua2V5KSA9PT0gaGFzaEtleVxuICAgICk7XG4gICAgaWYgKCFpdGVtKSB7XG4gICAgICBwZW5kaW5nQ2hhbmdlc1NuYXBzaG90LnB1c2goe1xuICAgICAgICBrZXk6IGluZm8sXG4gICAgICAgIHZhbHVlOiBuZXdWYWx1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5fcGVuZGluZ0NoYW5nZXMubmV4dChwZW5kaW5nQ2hhbmdlc1NuYXBzaG90KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFkZWVwRXF1YWwoaXRlbS52YWx1ZSwgbmV3VmFsdWUpKSB7XG4gICAgICAgIGl0ZW0udmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5fcGVuZGluZ0NoYW5nZXMubmV4dChwZW5kaW5nQ2hhbmdlc1NuYXBzaG90KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVQZW5kaW5nQ2hhbmdlKGluZm86IFRhcEluZm9LZXkpIHtcbiAgICBjb25zdCBoYXNoS2V5ID0gY3JlYXRlQ2FjaGVLZXkoaW5mbyk7XG4gICAgY29uc3QgcGVuZGluZ0NoYW5nZXNTbmFwc2hvdCA9IHRoaXMuX3BlbmRpbmdDaGFuZ2VzLnZhbHVlO1xuICAgIGNvbnN0IGluZGV4T2ZJdGVtID0gcGVuZGluZ0NoYW5nZXNTbmFwc2hvdC5maW5kSW5kZXgoXG4gICAgICAoZW50cnkpID0+IGNyZWF0ZUNhY2hlS2V5KGVudHJ5LmtleSkgPT09IGhhc2hLZXlcbiAgICApO1xuXG4gICAgaWYgKGluZGV4T2ZJdGVtID49IDApIHtcbiAgICAgIHBlbmRpbmdDaGFuZ2VzU25hcHNob3Quc3BsaWNlKGluZGV4T2ZJdGVtLCAxKTtcbiAgICAgIHRoaXMuX3BlbmRpbmdDaGFuZ2VzLm5leHQocGVuZGluZ0NoYW5nZXNTbmFwc2hvdCk7XG4gICAgfVxuICB9XG59XG4iXX0=