@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
107 lines • 18.2 kB
JavaScript
import { Directive, EventEmitter, forwardRef, Inject, Input, Optional, Output, Self } from '@angular/core';
import { NG_ASYNC_VALIDATORS } from '@angular/forms';
import { forkJoin, of, Subject } from 'rxjs';
import { delay, map, mergeMap } from 'rxjs/operators';
import { FormAsyncValidatorBase } from '../validators/base-async-validator';
import { SME_ASYNC_VALIDATORS } from '../validators/sme-async-validator';
import * as i0 from "@angular/core";
/**
* Provider for the FormFieldAsyncValidatorDirective directive
*/
export const FORM_FIELD_ASYNC_VALIDATOR = {
provide: NG_ASYNC_VALIDATORS,
useExisting: forwardRef(() => FormFieldAsyncValidatorDirective),
multi: true
};
export const defaultAsyncValidationDebounceTime = 800;
/**
* Implementation of Async Validator for sme-form-field
* The selector for this directive must match @see FormFieldComponent.selector. see FormFieldComponent for details.
*/
export class FormFieldAsyncValidatorDirective extends FormAsyncValidatorBase {
/**
* Instantiates a new instance of FormFieldAsyncValidatorDirective
*/
constructor(asyncValidators) {
super();
this.asyncValidators = asyncValidators;
/**
* EventEmitter for checking validation and raising alerts
* Subscribers are expected to populate the 'alerts' map with their own validation alerts
*/
this.customAsyncValidate = new EventEmitter();
/**
* Subject to emit when new alerts are available
*/
this.asyncAlert = new Subject();
}
/**
* Implementation of Validator interface.
* Validates the value of this elements form control. Use the @see checkValidate event to hook into this function.
* @param c The FormControl attached to this element
* @return null when valid, otherwise returns a validation object in the form of "{ errorType: {valid: false} }".
*/
validate(c) {
const asyncAlerts = [];
if (!this.customAsyncValidateDisabled) {
// collect custom validation observables
this.customAsyncValidate.emit({ formControl: c, alerts: asyncAlerts });
// incorporate our super validation
asyncAlerts.unshift(super.validate(c));
// collect SmeValidator alerts
if (this.asyncValidators && this.asyncValidators.length > 0) {
const injectedAlerts = this.asyncValidators.map(validator => validator.validate(c));
asyncAlerts.push(...injectedAlerts);
}
// determine our debounce time so that we dont fire to often
let delayTime = defaultAsyncValidationDebounceTime;
if (MsftSme.isNumber(this.customAsyncValidateDebounceTime) && this.customAsyncValidateDebounceTime >= 0) {
delayTime = this.customAsyncValidateDebounceTime;
}
// delay all of our validators by the debounce time.
// if the value changes in this time frame, the observable subscriptions are canceled and should cease.
// we do this by injecting a delay in the pipeline before returning the original validation logic
const debouncedAlerts = asyncAlerts.map(originalObservable => of(null).pipe(delay(delayTime), mergeMap(() => originalObservable)));
return forkJoin(debouncedAlerts).pipe(map((recievedAlerts) => {
const alerts = recievedAlerts.reduce((result, next) => ({ ...result, ...next }), {});
// notify any listeners that we have alerts available
this.asyncAlert.next(alerts);
// get the errors list from the alerts. return that as our errors collection for angulars internal processing
const errors = {};
// pull out the error alerts to return to angular. Only these alerts should actually invalidate the control
Object.keys(alerts).forEach(key => {
const alert = alerts[key];
if (!alert || !alert.valid) {
errors[key] = alert;
}
});
return this.alertsOrNull(errors);
}));
}
return of(null);
}
}
/** @nocollapse */ FormFieldAsyncValidatorDirective.ɵfac = function FormFieldAsyncValidatorDirective_Factory(t) { return new (t || FormFieldAsyncValidatorDirective)(i0.ɵɵdirectiveInject(SME_ASYNC_VALIDATORS, 10)); };
/** @nocollapse */ FormFieldAsyncValidatorDirective.ɵdir = /** @pureOrBreakMyCode */ i0.ɵɵdefineDirective({ type: FormFieldAsyncValidatorDirective, selectors: [["sme-form-field", "customAsyncValidate", ""]], inputs: { customAsyncValidateDisabled: "customAsyncValidateDisabled", customAsyncValidateDebounceTime: "customAsyncValidateDebounceTime" }, outputs: { customAsyncValidate: "customAsyncValidate" }, features: [i0.ɵɵProvidersFeature([FORM_FIELD_ASYNC_VALIDATOR]), i0.ɵɵInheritDefinitionFeature] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FormFieldAsyncValidatorDirective, [{
type: Directive,
args: [{
// eslint-disable-next-line @angular-eslint/directive-selector
selector: 'sme-form-field[customAsyncValidate]',
providers: [FORM_FIELD_ASYNC_VALIDATOR]
}]
}], function () { return [{ type: Array, decorators: [{
type: Optional
}, {
type: Self
}, {
type: Inject,
args: [SME_ASYNC_VALIDATORS]
}] }]; }, { customAsyncValidateDisabled: [{
type: Input
}], customAsyncValidateDebounceTime: [{
type: Input
}], customAsyncValidate: [{
type: Output
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1maWVsZC1hc3luYy12YWxpZGF0b3IuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vYW5ndWxhci9zcmMvY29udHJvbHMvZm9ybS9mb3JtLWZpZWxkL2Zvcm0tZmllbGQtYXN5bmMtdmFsaWRhdG9yLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBa0IsTUFBTSxlQUFlLENBQUM7QUFDM0gsT0FBTyxFQUErQixtQkFBbUIsRUFBb0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRyxPQUFPLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekQsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDNUUsT0FBTyxFQUFxQixvQkFBb0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOztBQWlCNUY7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBbUI7SUFDdEQsT0FBTyxFQUFFLG1CQUFtQjtJQUM1QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLGdDQUFnQyxDQUFDO0lBQy9ELEtBQUssRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLEdBQUcsQ0FBQztBQUV0RDs7O0dBR0c7QUFNSCxNQUFNLE9BQU8sZ0NBQWlDLFNBQVEsc0JBQXNCO0lBMEJ4RTs7T0FFRztJQUNILFlBQzhELGVBQXlDO1FBQ25HLEtBQUssRUFBRSxDQUFDO1FBRGtELG9CQUFlLEdB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QjNDLGdDQUFnQyxvU0FGOUIsQ0FBQywwQkFBMEIsQ0FBQzt1RkFFOUIsZ0NBQWdDO2NBTDVDLFNBQVM7ZUFBQztnQkFDUCw4REFBOEQ7Z0JBQzlELFFBQVEsRUFBRSxxQ0FBcUM7Z0JBQy9DLFNBQVMsRUFBRSxDQUFDLDBCQUEwQixDQUFDO2FBQzFDOztzQkErQlEsUUFBUTs7c0JBQUksSUFBSTs7c0JBQUksTUFBTTt1QkFBQyxvQkFBb0I7d0JBckI3QywyQkFBMkI7a0JBUGpDLEtBQUs7WUFVQywrQkFBK0I7a0JBRHJDLEtBQUs7WUFRQyxtQkFBbUI7a0JBRHpCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEV2ZW50RW1pdHRlciwgZm9yd2FyZFJlZiwgSW5qZWN0LCBJbnB1dCwgT3B0aW9uYWwsIE91dHB1dCwgU2VsZiwgU3RhdGljUHJvdmlkZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQXN5bmNWYWxpZGF0b3IsIEZvcm1Db250cm9sLCBOR19BU1lOQ19WQUxJREFUT1JTLCBWYWxpZGF0aW9uRXJyb3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBmb3JrSm9pbiwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVsYXksIG1hcCwgbWVyZ2VNYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IEFzeW5jVmFsaWRhdGlvbkFsZXJ0cywgVmFsaWRhdGlvbkFsZXJ0LCBWYWxpZGF0aW9uQWxlcnRzIH0gZnJvbSAnLi4vdmFsaWRhdGlvbi1hbGVydC92YWxpZGF0aW9uLWFsZXJ0JztcclxuaW1wb3J0IHsgRm9ybUFzeW5jVmFsaWRhdG9yQmFzZSB9IGZyb20gJy4uL3ZhbGlkYXRvcnMvYmFzZS1hc3luYy12YWxpZGF0b3InO1xyXG5pbXBvcnQgeyBTbWVBc3luY1ZhbGlkYXRvciwgU01FX0FTWU5DX1ZBTElEQVRPUlMgfSBmcm9tICcuLi92YWxpZGF0b3JzL3NtZS1hc3luYy12YWxpZGF0b3InO1xyXG5cclxuLyoqXHJcbiAqIEFyZ3VtZW50cyBmb3IgdGhlIEBzZWUgRm9ybUZpZWxkQXN5bmNWYWxpZGF0b3JEaXJlY3RpdmUuY3VzdG9tQXN5bmNWYWxpZGF0ZSBPdXRwdXQgZXZlbnRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgQ2hlY2tBc3luY1ZhbGlkYXRpb25FdmVudEFyZ3Mge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUaGUgZm9ybSBjb250cm9sIHRoYXQgd2UgYXJlIHZhbGlkYXRpbmdcclxuICAgICAqL1xyXG4gICAgZm9ybUNvbnRyb2w6IEZvcm1Db250cm9sO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQW4gb2JzZXJ2YWJsZSB0aGF0IGVtaXRzIGFuIGFsZXJ0IG9iamVjdCB3aGVuIGNvbXBsZXRlXHJcbiAgICAgKi9cclxuICAgIGFsZXJ0czogQXN5bmNWYWxpZGF0aW9uQWxlcnRzO1xyXG59XHJcblxyXG4vKipcclxuICogUHJvdmlkZXIgZm9yIHRoZSBGb3JtRmllbGRBc3luY1ZhbGlkYXRvckRpcmVjdGl2ZSBkaXJlY3RpdmVcclxuICovXHJcbmV4cG9ydCBjb25zdCBGT1JNX0ZJRUxEX0FTWU5DX1ZBTElEQVRPUjogU3RhdGljUHJvdmlkZXIgPSB7XHJcbiAgICBwcm92aWRlOiBOR19BU1lOQ19WQUxJREFUT1JTLFxyXG4gICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRm9ybUZpZWxkQXN5bmNWYWxpZGF0b3JEaXJlY3RpdmUpLFxyXG4gICAgbXVsdGk6IHRydWVcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBkZWZhdWx0QXN5bmNWYWxpZGF0aW9uRGVib3VuY2VUaW1lID0gODAwO1xyXG5cclxuLyoqXHJcbiAqIEltcGxlbWVudGF0aW9uIG9mIEFzeW5jIFZhbGlkYXRvciBmb3Igc21lLWZvcm0tZmllbGRcclxuICogVGhlIHNlbGVjdG9yIGZvciB0aGlzIGRpcmVjdGl2ZSBtdXN0IG1hdGNoIEBzZWUgRm9ybUZpZWxkQ29tcG9uZW50LnNlbGVjdG9yLiBzZWUgRm9ybUZpZWxkQ29tcG9uZW50IGZvciBkZXRhaWxzLlxyXG4gKi9cclxuQERpcmVjdGl2ZSh7XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2RpcmVjdGl2ZS1zZWxlY3RvclxyXG4gICAgc2VsZWN0b3I6ICdzbWUtZm9ybS1maWVsZFtjdXN0b21Bc3luY1ZhbGlkYXRlXScsXHJcbiAgICBwcm92aWRlcnM6IFtGT1JNX0ZJRUxEX0FTWU5DX1ZBTElEQVRPUl1cclxufSlcclxuZXhwb3J0IGNsYXNzIEZvcm1GaWVsZEFzeW5jVmFsaWRhdG9yRGlyZWN0aXZlIGV4dGVuZHMgRm9ybUFzeW5jVmFsaWRhdG9yQmFzZSBpbXBsZW1lbnRzIEFzeW5jVmFsaWRhdG9yIHtcclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgLyoqXHJcbiAgICAgKiBJdCBpbmRpY2F0ZXMgd2hldGhlciB0byBkaXNhYmxlIHRoaXMgdmFsaWRhdG9yLlxyXG4gICAgICogSW4gc29tZSBzY2VuYXJpb3Mgd2Ugd2FudCB0byBwcm9ncmFtbWF0aWNhbGx5IGNvbnRyb2wgd2hldGhlciB0aGlzIHZhbGlkYXRvclxyXG4gICAgICogc2hvdWxkIGJlIHVzZWQgbGlrZSBpbiBzY2hlbWEgZHJpdmVuIGZvcm0uXHJcbiAgICAgKiBUaGVuIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1c2VkLlxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3VzdG9tQXN5bmNWYWxpZGF0ZURpc2FibGVkOiBib29sZWFuO1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgY3VzdG9tQXN5bmNWYWxpZGF0ZURlYm91bmNlVGltZTogbnVtYmVyO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRXZlbnRFbWl0dGVyIGZvciBjaGVja2luZyB2YWxpZGF0aW9uIGFuZCByYWlzaW5nIGFsZXJ0c1xyXG4gICAgICogU3Vic2NyaWJlcnMgYXJlIGV4cGVjdGVkIHRvIHBvcHVsYXRlIHRoZSAnYWxlcnRzJyBtYXAgd2l0aCB0aGVpciBvd24gdmFsaWRhdGlvbiBhbGVydHNcclxuICAgICAqL1xyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgY3VzdG9tQXN5bmNWYWxpZGF0ZTogRXZlbnRFbWl0dGVyPENoZWNrQXN5bmNWYWxpZGF0aW9uRXZlbnRBcmdzPiA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hlY2tBc3luY1ZhbGlkYXRpb25FdmVudEFyZ3M+KCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBTdWJqZWN0IHRvIGVtaXQgd2hlbiBuZXcgYWxlcnRzIGFyZSBhdmFpbGFibGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGFzeW5jQWxlcnQgPSBuZXcgU3ViamVjdDxWYWxpZGF0aW9uQWxlcnRzPigpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogSW5zdGFudGlhdGVzIGEgbmV3IGluc3RhbmNlIG9mIEZvcm1GaWVsZEFzeW5jVmFsaWRhdG9yRGlyZWN0aXZlXHJcbiAgICAgKi9cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBPcHRpb25hbCgpIEBTZWxmKCkgQEluamVjdChTTUVfQVNZTkNfVkFMSURBVE9SUykgcHJpdmF0ZSBhc3luY1ZhbGlkYXRvcnM6IEFycmF5PFNtZUFzeW5jVmFsaWRhdG9yPikge1xyXG4gICAgICAgIHN1cGVyKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbXBsZW1lbnRhdGlvbiBvZiBWYWxpZGF0b3IgaW50ZXJmYWNlLlxyXG4gICAgICogVmFsaWRhdGVzIHRoZSB2YWx1ZSBvZiB0aGlzIGVsZW1lbnRzIGZvcm0gY29udHJvbC4gVXNlIHRoZSBAc2VlIGNoZWNrVmFsaWRhdGUgZXZlbnQgdG8gaG9vayBpbnRvIHRoaXMgZnVuY3Rpb24uXHJcbiAgICAgKiBAcGFyYW0gYyBUaGUgRm9ybUNvbnRyb2wgYXR0YWNoZWQgdG8gdGhpcyBlbGVtZW50XHJcbiAgICAgKiBAcmV0dXJuIG51bGwgd2hlbiB2YWxpZCwgb3RoZXJ3aXNlIHJldHVybnMgYSB2YWxpZGF0aW9uIG9iamVjdCBpbiB0aGUgZm9ybSBvZiBcInsgZXJyb3JUeXBlOiB7dmFsaWQ6IGZhbHNlfSB9XCIuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyB2YWxpZGF0ZShjOiBGb3JtQ29udHJvbCk6IE9ic2VydmFibGU8VmFsaWRhdGlvbkVycm9ycyB8IG51bGw+IHtcclxuICAgICAgICBjb25zdCBhc3luY0FsZXJ0czogQXN5bmNWYWxpZGF0aW9uQWxlcnRzID0gW107XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5jdXN0b21Bc3luY1ZhbGlkYXRlRGlzYWJsZWQpIHtcclxuICAgICAgICAgICAgLy8gY29sbGVjdCBjdXN0b20gdmFsaWRhdGlvbiBvYnNlcnZhYmxlc1xyXG4gICAgICAgICAgICB0aGlzLmN1c3RvbUFzeW5jVmFsaWRhdGUuZW1pdCh7IGZvcm1Db250cm9sOiBjLCBhbGVydHM6IGFzeW5jQWxlcnRzIH0pO1xyXG5cclxuICAgICAgICAgICAgLy8gaW5jb3Jwb3JhdGUgb3VyIHN1cGVyIHZhbGlkYXRpb25cclxuICAgICAgICAgICAgYXN5bmNBbGVydHMudW5zaGlmdChzdXBlci52YWxpZGF0ZShjKSk7XHJcblxyXG4gICAgICAgICAgICAvLyBjb2xsZWN0IFNtZVZhbGlkYXRvciBhbGVydHNcclxuICAgICAgICAgICAgaWYgKHRoaXMuYXN5bmNWYWxpZGF0b3JzICYmIHRoaXMuYXN5bmNWYWxpZGF0b3JzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGluamVjdGVkQWxlcnRzID0gdGhpcy5hc3luY1ZhbGlkYXRvcnMubWFwKHZhbGlkYXRvciA9PiB2YWxpZGF0b3IudmFsaWRhdGUoYykpO1xyXG4gICAgICAgICAgICAgICAgYXN5bmNBbGVydHMucHVzaCguLi5pbmplY3RlZEFsZXJ0cyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGRldGVybWluZSBvdXIgZGVib3VuY2UgdGltZSBzbyB0aGF0IHdlIGRvbnQgZmlyZSB0byBvZnRlblxyXG4gICAgICAgICAgICBsZXQgZGVsYXlUaW1lID0gZGVmYXVsdEFzeW5jVmFsaWRhdGlvbkRlYm91bmNlVGltZTtcclxuICAgICAgICAgICAgaWYgKE1zZnRTbWUuaXNOdW1iZXIodGhpcy5jdXN0b21Bc3luY1ZhbGlkYXRlRGVib3VuY2VUaW1lKSAmJiB0aGlzLmN1c3RvbUFzeW5jVmFsaWRhdGVEZWJvdW5jZVRpbWUgPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lID0gdGhpcy5jdXN0b21Bc3luY1ZhbGlkYXRlRGVib3VuY2VUaW1lO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBkZWxheSBhbGwgb2Ygb3VyIHZhbGlkYXRvcnMgYnkgdGhlIGRlYm91bmNlIHRpbWUuXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSB2YWx1ZSBjaGFuZ2VzIGluIHRoaXMgdGltZSBmcmFtZSwgdGhlIG9ic2VydmFibGUgc3Vic2NyaXB0aW9ucyBhcmUgY2FuY2VsZWQgYW5kIHNob3VsZCBjZWFzZS5cclxuICAgICAgICAgICAgLy8gd2UgZG8gdGhpcyBieSBpbmplY3RpbmcgYSBkZWxheSBpbiB0aGUgcGlwZWxpbmUgYmVmb3JlIHJldHVybmluZyB0aGUgb3JpZ2luYWwgdmFsaWRhdGlvbiBsb2dpY1xyXG4gICAgICAgICAgICBjb25zdCBkZWJvdW5jZWRBbGVydHMgPSBhc3luY0FsZXJ0cy5tYXAoXHJcbiAgICAgICAgICAgICAgICBvcmlnaW5hbE9ic2VydmFibGUgPT4gb2YobnVsbCkucGlwZShcclxuICAgICAgICAgICAgICAgICAgICBkZWxheShkZWxheVRpbWUpLFxyXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlTWFwKCgpID0+IG9yaWdpbmFsT2JzZXJ2YWJsZSkpXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZm9ya0pvaW4oZGVib3VuY2VkQWxlcnRzKS5waXBlKFxyXG4gICAgICAgICAgICAgICAgbWFwKChyZWNpZXZlZEFsZXJ0cykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFsZXJ0cyA9IHJlY2lldmVkQWxlcnRzLnJlZHVjZSgocmVzdWx0LCBuZXh0KSA9PiAoeyAuLi5yZXN1bHQsIC4uLm5leHQgfSksIDxWYWxpZGF0aW9uQWxlcnRzPnt9KTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBub3RpZnkgYW55IGxpc3RlbmVycyB0aGF0IHdlIGhhdmUgYWxlcnRzIGF2YWlsYWJsZVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYXN5bmNBbGVydC5uZXh0KGFsZXJ0cyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZXJyb3JzIGxpc3QgZnJvbSB0aGUgYWxlcnRzLiByZXR1cm4gdGhhdCBhcyBvdXIgZXJyb3JzIGNvbGxlY3Rpb24gZm9yIGFuZ3VsYXJzIGludGVybmFsIHByb2Nlc3NpbmdcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvcnM6IFZhbGlkYXRpb25BbGVydHMgPSB7fTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcHVsbCBvdXQgdGhlIGVycm9yIGFsZXJ0cyB0byByZXR1cm4gdG8gYW5ndWxhci4gT25seSB0aGVzZSBhbGVydHMgc2hvdWxkIGFjdHVhbGx5IGludmFsaWRhdGUgdGhlIGNvbnRyb2xcclxuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhhbGVydHMpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWxlcnQgPSBhbGVydHNba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFhbGVydCB8fCAhKDxWYWxpZGF0aW9uQWxlcnQ+YWxlcnQpLnZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnNba2V5XSA9IGFsZXJ0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFsZXJ0c09yTnVsbChlcnJvcnMpO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBvZihudWxsKTtcclxuICAgIH1cclxufVxyXG4iXX0=