UNPKG

@ui-tool/core

Version:
263 lines 41.2 kB
import { ChangeDetectionStrategy, Component, ContentChildren, Inject, Input } from '@angular/core'; import { AbstractControl, NgControl } from '@angular/forms'; import { Subscription } from 'rxjs'; import { MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS, MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, MULTIPLE_VALIDATION_SUMMARIZER_SERVICE } from '../../../constants/injectors/multiple-validation-summarizer-injectors'; import { VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, VALIDATION_SUMMARIZER_SERVICE } from '../../../constants/injectors/validation-summarizer-injectors'; import { v4 as uuid } from 'uuid'; import { MultipleValidationSummarizerItemContextDirective } from './directives/multiple-validation-summarizer-item-context.directive'; import { VALIDATION_SUMMARIZER_OPTIONS } from '../../../constants/injectors/internal-injectors'; import * as i0 from "@angular/core"; import * as i1 from "../validation-summarizer/validation-summarizer.component"; import * as i2 from "@angular/common"; const basicValidationHandler = (ngControl) => { if (!ngControl) { return false; } return (ngControl.invalid && (ngControl.dirty || ngControl.touched)) || false; }; export class MultipleValidationSummarizerComponent { //#endregion //#region Constructor constructor(validationSummarizerService, optionsProvider, changeDetectorRef) { this.validationSummarizerService = validationSummarizerService; this.optionsProvider = optionsProvider; this.changeDetectorRef = changeDetectorRef; // Id to control status change subscription. this._idToControlStatusChangeSubscription = {}; // Subscription about validation context changes. this._validationContextChangesSubscription = null; // Context directive watch list. this.itemContexts = null; const options = this.optionsProvider.getOption(); this._groupId = options?.groupId || uuid(); this._idToLabel = {}; this._idToTemplate = {}; this._idToInstance = {}; this._idToValidationError = {}; this._visibilityHandler = options.visibilityHandler || basicValidationHandler; this._hasInvalidField = false; this._subscription = new Subscription(); } //#endregion //#region Accessors // Id to label mapping. get idToLabel() { return this._idToLabel; } // Id to template mapping. get idToTemplate() { return this._idToTemplate; } get idToInstance() { return this._idToInstance; } get groupId() { return this._groupId; } // Id of group the multiple validation summarizer belongs to. set groupId(value) { this._groupId = value; } // Whether there is any invalid field or not. get hasInvalidField() { return this._hasInvalidField; } // tslint:disable-next-line:no-input-rename set visibilityHandler(value) { if (!value) { this._visibilityHandler = basicValidationHandler; return; } this._visibilityHandler = value; } get visibilityHandler() { return this._visibilityHandler; } //#endregion //#region Life cycle hooks ngOnInit() { } // Called when content has been initialized. ngAfterContentInit() { // Handle control initial changes. this.handleControlChanges(); this.changeDetectorRef.markForCheck(); // Hook control changes. const hookControlChangesSubscription = this.itemContexts ?.changes .subscribe(() => { this.handleControlChanges(); this.changeDetectorRef.markForCheck(); }); this._subscription.add(hookControlChangesSubscription); } // Called when component is destroyed. ngOnDestroy() { this.deleteControlStatusChangeSubscriptions(); this._validationContextChangesSubscription?.unsubscribe(); this._subscription?.unsubscribe(); } //#endregion //#region Methods // Whether control has validation error or not. shouldControlHasValidationError(id) { if (!id || !this._idToValidationError) { return false; } const validationError = this._idToValidationError[id]; return validationError !== null && validationError !== undefined; } //#endregion //#region Internal methods handleControlChanges() { // Unsubscribe the previous control status. this._validationContextChangesSubscription?.unsubscribe(); // Clear the mapping. this._idToLabel = {}; this._idToTemplate = {}; this._hasInvalidField = false; this._idToValidationError = {}; // Invalid item collection. if (!this.itemContexts || !this.itemContexts.length) { return; } // Handle control changes. for (const itemContext of this.itemContexts) { this.handleContextChangedEvent(itemContext, { name: 'label', value: itemContext.label }); this.handleContextChangedEvent(itemContext, { name: 'template', value: itemContext.template }); this.handleContextChangedEvent(itemContext, { name: 'instance', value: itemContext.instance }); const validationContextChangeSubscription = itemContext.updateEvent .subscribe((context) => { this.handleContextChangedEvent(itemContext, context, true); }); this._validationContextChangesSubscription?.add(validationContextChangeSubscription); } // Check whether there is any invalid field or not. this._hasInvalidField = this.shouldAnyFieldInvalid(); this.changeDetectorRef.markForCheck(); } // Handle context change event. handleContextChangedEvent(itemContext, context, markAsChanged) { switch (context.name) { case 'label': this._idToLabel[itemContext.id] = context.value; break; case 'template': this._idToTemplate[itemContext.id] = context.value; break; case 'instance': // Unsubscribe this instance subscription. let controlChangesSubscription = this._idToControlStatusChangeSubscription[itemContext.id]; controlChangesSubscription?.unsubscribe(); delete this._idToInstance[itemContext.id]; let valueChangesObservable = null; if (itemContext.instance instanceof AbstractControl) { valueChangesObservable = itemContext.instance.statusChanges; } else if (itemContext.instance instanceof NgControl) { valueChangesObservable = itemContext.instance.statusChanges; } if (valueChangesObservable) { this._idToInstance[itemContext.id] = context.value; controlChangesSubscription = valueChangesObservable .subscribe(() => { const instance = this._idToInstance[itemContext.id]; if (!instance) { return; } this._hasInvalidField = this.shouldAnyFieldInvalid(); this.changeDetectorRef.markForCheck(); }); this._subscription.add(controlChangesSubscription); } break; } if (markAsChanged) { this.changeDetectorRef.markForCheck(); } } // Remove control status change subscription. deleteControlStatusChangeSubscriptions() { const ids = Object.keys(this._idToControlStatusChangeSubscription); for (const id of ids) { const controlStatusChangeSubscription = this._idToControlStatusChangeSubscription[id]; controlStatusChangeSubscription?.unsubscribe(); } this._idToControlStatusChangeSubscription = {}; } // Whether there is any invalid field or not. shouldAnyFieldInvalid() { const ids = Object.keys(this._idToInstance); if (!ids || !ids.length) { return false; } let hasValidationError = false; for (const id of ids) { const instance = this.idToInstance[id]; if (!instance) { continue; } const validationErrors = this.validationSummarizerService.loadControlValidationErrors(instance); if (!validationErrors) { continue; } this._idToValidationError[id] = validationErrors; const shouldValidationErrorVisible = this.visibilityHandler ? this._visibilityHandler(instance) : false; if (!shouldValidationErrorVisible) { continue; } hasValidationError = true; } return hasValidationError; } } MultipleValidationSummarizerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: MultipleValidationSummarizerComponent, deps: [{ token: MULTIPLE_VALIDATION_SUMMARIZER_SERVICE }, { token: MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); MultipleValidationSummarizerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: MultipleValidationSummarizerComponent, selector: "cms-multiple-validation-summarizer", inputs: { groupId: ["group-id", "groupId"], visibilityHandler: ["visibility-handler", "visibilityHandler"] }, providers: [ { provide: VALIDATION_SUMMARIZER_SERVICE, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_SERVICE }, { provide: VALIDATION_SUMMARIZER_OPTIONS, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS }, { provide: VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, multi: false } ], queries: [{ propertyName: "itemContexts", predicate: MultipleValidationSummarizerItemContextDirective }], ngImport: i0, template: "<ul *ngIf=\"hasInvalidField\">\n <ng-container *ngFor=\"let itemContext of itemContexts\">\n <cms-validation-summarizer *ngIf=\"idToInstance[itemContext.id] && shouldControlHasValidationError(itemContext.id)\"\n [instance]=\"idToInstance[itemContext.id]\"\n [label]=\"idToLabel[itemContext.id]\"\n [validation-template]=\"idToTemplate[itemContext.id] || validationSummarizerTemplate\">\n </cms-validation-summarizer>\n </ng-container>\n</ul>\n\n\n<!--Default validation summary template-->\n<ng-template\n #validationSummarizerTemplate\n let-ngControl=\"ngControl\"\n let-controlLabel=\"controlLabel\"\n let-validationMessages=\"validationMessages\"\n>\n <li *ngFor=\"let validationMessage of validationMessages;\">\n {{controlLabel}} {{validationMessage | json}}\n </li>\n</ng-template>\n", components: [{ type: i1.ValidationSummarizerComponent, selector: "cms-validation-summarizer", inputs: ["group-id", "instance", "label", "validation-template", "maximum-messages", "visibility-handler"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "json": i2.JsonPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: MultipleValidationSummarizerComponent, decorators: [{ type: Component, args: [{ selector: 'cms-multiple-validation-summarizer', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: VALIDATION_SUMMARIZER_SERVICE, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_SERVICE }, { provide: VALIDATION_SUMMARIZER_OPTIONS, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS }, { provide: VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, useExisting: MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER, multi: false } ], template: "<ul *ngIf=\"hasInvalidField\">\n <ng-container *ngFor=\"let itemContext of itemContexts\">\n <cms-validation-summarizer *ngIf=\"idToInstance[itemContext.id] && shouldControlHasValidationError(itemContext.id)\"\n [instance]=\"idToInstance[itemContext.id]\"\n [label]=\"idToLabel[itemContext.id]\"\n [validation-template]=\"idToTemplate[itemContext.id] || validationSummarizerTemplate\">\n </cms-validation-summarizer>\n </ng-container>\n</ul>\n\n\n<!--Default validation summary template-->\n<ng-template\n #validationSummarizerTemplate\n let-ngControl=\"ngControl\"\n let-controlLabel=\"controlLabel\"\n let-validationMessages=\"validationMessages\"\n>\n <li *ngFor=\"let validationMessage of validationMessages;\">\n {{controlLabel}} {{validationMessage | json}}\n </li>\n</ng-template>\n" }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [MULTIPLE_VALIDATION_SUMMARIZER_SERVICE] }] }, { type: undefined, decorators: [{ type: Inject, args: [MULTIPLE_VALIDATION_SUMMARIZER_OPTIONS_PROVIDER] }] }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { itemContexts: [{ type: ContentChildren, args: [MultipleValidationSummarizerItemContextDirective] }], groupId: [{ type: Input, args: ['group-id'] }], visibilityHandler: [{ type: Input, args: ['visibility-handler'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGlwbGUtdmFsaWRhdGlvbi1zdW1tYXJpemVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy92YWxpZGF0b3IvbXVsdGlwbGUtdmFsaWRhdGlvbi1zdW1tYXJpemVyL211bHRpcGxlLXZhbGlkYXRpb24tc3VtbWFyaXplci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvcmUvc3JjL21vZHVsZXMvdmFsaWRhdG9yL211bHRpcGxlLXZhbGlkYXRpb24tc3VtbWFyaXplci9tdWx0aXBsZS12YWxpZGF0aW9uLXN1bW1hcml6ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsZUFBZSxFQUNmLE1BQU0sRUFDTixLQUFLLEVBS04sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGVBQWUsRUFBbUMsU0FBUyxFQUFtQixNQUFNLGdCQUFnQixDQUFDO0FBQzdHLE9BQU8sRUFBYSxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDOUMsT0FBTyxFQUNMLHNDQUFzQyxFQUN0QywrQ0FBK0MsRUFDL0Msc0NBQXNDLEVBQ3ZDLE1BQU0sdUVBQXVFLENBQUM7QUFDL0UsT0FBTyxFQUFDLHNDQUFzQyxFQUM1Qyw2QkFBNkIsRUFBQyxNQUFNLDhEQUE4RCxDQUFDO0FBR3JHLE9BQU8sRUFBQyxFQUFFLElBQUksSUFBSSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ2hDLE9BQU8sRUFBQyxnREFBZ0QsRUFBQyxNQUFNLG9FQUFvRSxDQUFDO0FBR3BJLE9BQU8sRUFBQyw2QkFBNkIsRUFBQyxNQUFNLGlEQUFpRCxDQUFDOzs7O0FBRTlGLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxTQUFzQyxFQUFXLEVBQUU7SUFDakYsSUFBSSxDQUFDLFNB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WTtzQkFEbEIsZUFBZTt1QkFBQyxnREFBZ0Q7Z0JBMkJ0RCxPQUFPO3NCQURqQixLQUFLO3VCQUFDLFVBQVU7Z0JBWU4saUJBQWlCO3NCQUQzQixLQUFLO3VCQUFDLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBRdWVyeUxpc3QsXG4gIFRlbXBsYXRlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBYnN0cmFjdENvbnRyb2wsIEZvcm1Db250cm9sRGlyZWN0aXZlLCBGb3JtR3JvdXAsIE5nQ29udHJvbCwgVmFsaWRhdGlvbkVycm9yc30gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgTVVMVElQTEVfVkFMSURBVElPTl9TVU1NQVJJWkVSX09QVElPTlMsXG4gIE1VTFRJUExFX1ZBTElEQVRJT05fU1VNTUFSSVpFUl9PUFRJT05TX1BST1ZJREVSLFxuICBNVUxUSVBMRV9WQUxJREFUSU9OX1NVTU1BUklaRVJfU0VSVklDRVxufSBmcm9tICcuLi8uLi8uLi9jb25zdGFudHMvaW5qZWN0b3JzL211bHRpcGxlLXZhbGlkYXRpb24tc3VtbWFyaXplci1pbmplY3RvcnMnO1xuaW1wb3J0IHtWQUxJREFUSU9OX1NVTU1BUklaRVJfT1BUSU9OU19QUk9WSURFUixcbiAgVkFMSURBVElPTl9TVU1NQVJJWkVSX1NFUlZJQ0V9IGZyb20gJy4uLy4uLy4uL2NvbnN0YW50cy9pbmplY3RvcnMvdmFsaWRhdGlvbi1zdW1tYXJpemVyLWluamVjdG9ycyc7XG5pbXBvcnQge01VTFRJUExFX1ZBTElEQVRJT05fU1VNTUFSSVpFUl9DT05URVhUX0NIQU5HRURfRVZFTlR9IGZyb20gJy4uLy4uLy4uL2NvbnN0YW50cy9tdWx0aXBsZS12YWxpZGF0aW9uLXN1bW1hcml6ZXItY29uc3RhbnRzJztcbmltcG9ydCB7SVZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvaW50ZXJmYWNlcy92YWxpZGF0aW9uLXN1bW1hcml6ZXJzL3ZhbGlkYXRpb24tc3VtbWFyaXplci1zZXJ2aWNlLmludGVyZmFjZSc7XG5pbXBvcnQge3Y0IGFzIHV1aWR9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHtNdWx0aXBsZVZhbGlkYXRpb25TdW1tYXJpemVySXRlbUNvbnRleHREaXJlY3RpdmV9IGZyb20gJy4vZGlyZWN0aXZlcy9tdWx0aXBsZS12YWxpZGF0aW9uLXN1bW1hcml6ZXItaXRlbS1jb250ZXh0LmRpcmVjdGl2ZSc7XG5pbXBvcnQge011bHRpcGxlVmFsaWRhdGlvblN1bW1hcml6ZXJJdGVtQ29udGV4dH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2ludGVyZmFjZXMvbXVsdGlwbGUtdmFsaWRhdGlvbi1zdW1tYXJpemVycy9tdWx0aXBsZS12YWxpZGF0aW9uLXN1bW1hcml6ZXItaXRlbS1jb250ZXh0JztcbmltcG9ydCB7SVZhbGlkYXRpb25TdW1tYXJpemVyT3B0aW9uUHJvdmlkZXJ9IGZyb20gJy4uLy4uLy4uL3Byb3ZpZGVycy9pbnRlcmZhY2VzL3ZhbGlkYXRpb24tc3VtbWFyaXplci1vcHRpb25zLXByb3ZpZGVyLmludGVyZmFjZSc7XG5pbXBvcnQge1ZBTElEQVRJT05fU1VNTUFSSVpFUl9PUFRJT05TfSBmcm9tICcuLi8uLi8uLi9jb25zdGFudHMvaW5qZWN0b3JzL2ludGVybmFsLWluamVjdG9ycyc7XG5cbmNvbnN0IGJhc2ljVmFsaWRhdGlvbkhhbmRsZXIgPSAobmdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wpOiBib29sZWFuID0+IHtcbiAgaWYgKCFuZ0NvbnRyb2wpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gKG5nQ29udHJvbC5pbnZhbGlkICYmIChuZ0NvbnRyb2wuZGlydHkgfHwgbmdDb250cm9sLnRvdWNoZWQpKSB8fCBmYWxzZTtcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Ntcy1tdWx0aXBsZS12YWxpZGF0aW9uLXN1bW1hcml6ZXInLFxuICB0ZW1wbGF0ZVVybDogJ211bHRpcGxlLXZhbGlkYXRpb24tc3VtbWFyaXplci5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBWQUxJREFUSU9OX1NVTU1BUklaRVJfU0VSVklDRSxcbiAgICAgIHVzZUV4aXN0aW5nOiBNVUxUSVBMRV9WQUxJREFUSU9OX1NVTU1BUklaRVJfU0VSVklDRVxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogVkFMSURBVElPTl9TVU1NQVJJWkVSX09QVElPTlMsXG4gICAgICB1c2VFeGlzdGluZzogTVVMVElQTEVfVkFMSURBVElPTl9TVU1NQVJJWkVSX09QVElPTlNcbiAgICB9LFxuICAgIHtcbiAgICAgIHByb3ZpZGU6IFZBTElEQVRJT05fU1VNTUFSSVpFUl9PUFRJT05TX1BST1ZJREVSLFxuICAgICAgdXNlRXhpc3Rpbmc6IE1VTFRJUExFX1ZBTElEQVRJT05fU1VNTUFSSVpFUl9PUFRJT05TX1BST1ZJREVSLFxuICAgICAgbXVsdGk6IGZhbHNlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE11bHRpcGxlVmFsaWRhdGlvblN1bW1hcml6ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG5cbiAgLy8jcmVnaW9uIFByb3BlcnRpZXNcblxuICAvLyBHcm91cCBpZC5cbiAgcHJpdmF0ZSBfZ3JvdXBJZDogc3RyaW5nO1xuXG4gIC8vIElkIHRvIGxhYmVsLlxuICBwcml2YXRlIF9pZFRvTGFiZWw6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfTtcblxuICAvLyBJZCB0byB0ZW1wbGF0ZS5cbiAgcHJpdmF0ZSBfaWRUb1RlbXBsYXRlOiB7IFtpZDogc3RyaW5nXTogVGVtcGxhdGVSZWY8TXVsdGlwbGVWYWxpZGF0aW9uU3VtbWFyaXplckl0ZW1Db250ZXh0PiB8IG51bGwgfTtcblxuICAvLyBJZCB0byBpbnN0YW5jZS5cbiAgcHJpdmF0ZSBfaWRUb0luc3RhbmNlOiB7IFtpZDogc3RyaW5nXTogQWJzdHJhY3RDb250cm9sIHwgRm9ybUdyb3VwIHwgRm9ybUNvbnRyb2xEaXJlY3RpdmUgfCBudWxsIH07XG5cbiAgLy8gSWQgdG8gdmFsaWRhdGlvbiBlcnJvcnMuXG4gIHByaXZhdGUgX2lkVG9WYWxpZGF0aW9uRXJyb3I6IHsgW2lkOiBzdHJpbmddOiBWYWxpZGF0aW9uRXJyb3JzIH07XG5cbiAgLy8gSGFuZGxlciBmb3IgaGFuZGxpbmcgc3VtbWFyaXplciB2aXNpYmlsaXR5LlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFyaWFibGUtbmFtZVxuICBwcml2YXRlIF92aXNpYmlsaXR5SGFuZGxlcjogKChuZ0NvbnRyb2w6IEFic3RyYWN0Q29udHJvbCB8IE5nQ29udHJvbCkgPT4gYm9vbGVhbik7XG5cbiAgLy8gV2hldGhlciB0aGVyZSBpcyBhbnkgaW52YWxpZCBmaWVsZCBvciBub3QuXG4gIHByaXZhdGUgX2hhc0ludmFsaWRGaWVsZDogYm9vbGVhbjtcblxuICAvLyBJZCB0byBjb250cm9sIHN0YXR1cyBjaGFuZ2Ugc3Vic2NyaXB0aW9uLlxuICBwcml2YXRlIF9pZFRvQ29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbjogeyBbaWQ6IHN0cmluZ106IFN1YnNjcmlwdGlvbiB8IG51bGwgfSA9IHt9O1xuXG4gIC8vIFN1YnNjcmlwdGlvbiBhYm91dCB2YWxpZGF0aW9uIGNvbnRleHQgY2hhbmdlcy5cbiAgcHJpdmF0ZSBfdmFsaWRhdGlvbkNvbnRleHRDaGFuZ2VzU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcblxuICAvLyBTdWJzY3JpcHRpb24gd2F0Y2ggbGlzdC5cbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgLy8gQ29udGV4dCBkaXJlY3RpdmUgd2F0Y2ggbGlzdC5cbiAgQENvbnRlbnRDaGlsZHJlbihNdWx0aXBsZVZhbGlkYXRpb25TdW1tYXJpemVySXRlbUNvbnRleHREaXJlY3RpdmUpXG4gIHB1YmxpYyBpdGVtQ29udGV4dHM6IFF1ZXJ5TGlzdDxNdWx0aXBsZVZhbGlkYXRpb25TdW1tYXJpemVySXRlbUNvbnRleHREaXJlY3RpdmU+IHwgbnVsbCA9IG51bGw7XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIEFjY2Vzc29yc1xuXG4gIC8vIElkIHRvIGxhYmVsIG1hcHBpbmcuXG4gIHB1YmxpYyBnZXQgaWRUb0xhYmVsKCk6IHsgW2lkOiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gICAgcmV0dXJuIHRoaXMuX2lkVG9MYWJlbDtcbiAgfVxuXG4gIC8vIElkIHRvIHRlbXBsYXRlIG1hcHBpbmcuXG4gIHB1YmxpYyBnZXQgaWRUb1RlbXBsYXRlKCk6IHsgW2lkOiBzdHJpbmddOiBUZW1wbGF0ZVJlZjxNdWx0aXBsZVZhbGlkYXRpb25TdW1tYXJpemVySXRlbUNvbnRleHQ+IHwgbnVsbCB9IHtcbiAgICByZXR1cm4gdGhpcy5faWRUb1RlbXBsYXRlO1xuICB9XG5cbiAgcHVibGljIGdldCBpZFRvSW5zdGFuY2UoKTogeyBbaWQ6IHN0cmluZ106IEFic3RyYWN0Q29udHJvbCB8IEZvcm1Hcm91cCB8IEZvcm1Db250cm9sRGlyZWN0aXZlIHwgbnVsbCB9IHtcbiAgICByZXR1cm4gdGhpcy5faWRUb0luc3RhbmNlO1xuICB9XG5cbiAgcHVibGljIGdldCBncm91cElkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX2dyb3VwSWQ7XG4gIH1cblxuICAvLyBJZCBvZiBncm91cCB0aGUgbXVsdGlwbGUgdmFsaWRhdGlvbiBzdW1tYXJpemVyIGJlbG9uZ3MgdG8uXG4gIEBJbnB1dCgnZ3JvdXAtaWQnKVxuICBwdWJsaWMgc2V0IGdyb3VwSWQodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2dyb3VwSWQgPSB2YWx1ZTtcbiAgfVxuXG4gIC8vIFdoZXRoZXIgdGhlcmUgaXMgYW55IGludmFsaWQgZmllbGQgb3Igbm90LlxuICBwdWJsaWMgZ2V0IGhhc0ludmFsaWRGaWVsZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGFzSW52YWxpZEZpZWxkO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWlucHV0LXJlbmFtZVxuICBASW5wdXQoJ3Zpc2liaWxpdHktaGFuZGxlcicpXG4gIHB1YmxpYyBzZXQgdmlzaWJpbGl0eUhhbmRsZXIodmFsdWU6ICgobmdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wpID0+IGJvb2xlYW4pIHwgbnVsbCkge1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHRoaXMuX3Zpc2liaWxpdHlIYW5kbGVyID0gYmFzaWNWYWxpZGF0aW9uSGFuZGxlcjtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fdmlzaWJpbGl0eUhhbmRsZXIgPSB2YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdmlzaWJpbGl0eUhhbmRsZXIoKTogKCgobmdDb250cm9sOiBBYnN0cmFjdENvbnRyb2wgfCBOZ0NvbnRyb2wpID0+IGJvb2xlYW4pIHwgbnVsbCkge1xuICAgIHJldHVybiB0aGlzLl92aXNpYmlsaXR5SGFuZGxlcjtcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxuXG4gIC8vI3JlZ2lvbiBDb25zdHJ1Y3RvclxuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihASW5qZWN0KE1VTFRJUExFX1ZBTElEQVRJT05fU1VNTUFSSVpFUl9TRVJWSUNFKVxuICAgICAgICAgICAgICAgICAgICAgcHJvdGVjdGVkIHJlYWRvbmx5IHZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZTogSVZhbGlkYXRpb25TdW1tYXJpemVyU2VydmljZSxcbiAgICAgICAgICAgICAgICAgICAgIEBJbmplY3QoTVVMVElQTEVfVkFMSURBVElPTl9TVU1NQVJJWkVSX09QVElPTlNfUFJPVklERVIpXG4gICAgICAgICAgICAgICAgICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgb3B0aW9uc1Byb3ZpZGVyOiBJVmFsaWRhdGlvblN1bW1hcml6ZXJPcHRpb25Qcm92aWRlcixcbiAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZCByZWFkb25seSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLm9wdGlvbnNQcm92aWRlci5nZXRPcHRpb24oKTtcbiAgICB0aGlzLl9ncm91cElkID0gb3B0aW9ucz8uZ3JvdXBJZCB8fCB1dWlkKCk7XG4gICAgdGhpcy5faWRUb0xhYmVsID0ge307XG4gICAgdGhpcy5faWRUb1RlbXBsYXRlID0ge307XG4gICAgdGhpcy5faWRUb0luc3RhbmNlID0ge307XG4gICAgdGhpcy5faWRUb1ZhbGlkYXRpb25FcnJvciA9IHt9O1xuICAgIHRoaXMuX3Zpc2liaWxpdHlIYW5kbGVyID0gb3B0aW9ucy52aXNpYmlsaXR5SGFuZGxlciB8fCBiYXNpY1ZhbGlkYXRpb25IYW5kbGVyO1xuICAgIHRoaXMuX2hhc0ludmFsaWRGaWVsZCA9IGZhbHNlO1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxuXG4gIC8vI3JlZ2lvbiBMaWZlIGN5Y2xlIGhvb2tzXG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICB9XG5cbiAgLy8gQ2FsbGVkIHdoZW4gY29udGVudCBoYXMgYmVlbiBpbml0aWFsaXplZC5cbiAgcHVibGljIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICAvLyBIYW5kbGUgY29udHJvbCBpbml0aWFsIGNoYW5nZXMuXG4gICAgdGhpcy5oYW5kbGVDb250cm9sQ2hhbmdlcygpO1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG5cbiAgICAvLyBIb29rIGNvbnRyb2wgY2hhbmdlcy5cbiAgICBjb25zdCBob29rQ29udHJvbENoYW5nZXNTdWJzY3JpcHRpb24gPSB0aGlzLml0ZW1Db250ZXh0c1xuICAgICAgPy5jaGFuZ2VzXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVDb250cm9sQ2hhbmdlcygpO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChob29rQ29udHJvbENoYW5nZXNTdWJzY3JpcHRpb24pO1xuICB9XG5cbiAgLy8gQ2FsbGVkIHdoZW4gY29tcG9uZW50IGlzIGRlc3Ryb3llZC5cbiAgcHVibGljIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVsZXRlQ29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbnMoKTtcbiAgICB0aGlzLl92YWxpZGF0aW9uQ29udGV4dENoYW5nZXNTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIE1ldGhvZHNcblxuICAvLyBXaGV0aGVyIGNvbnRyb2wgaGFzIHZhbGlkYXRpb24gZXJyb3Igb3Igbm90LlxuICBwdWJsaWMgc2hvdWxkQ29udHJvbEhhc1ZhbGlkYXRpb25FcnJvcihpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFpZCB8fCAhdGhpcy5faWRUb1ZhbGlkYXRpb25FcnJvcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvciA9IHRoaXMuX2lkVG9WYWxpZGF0aW9uRXJyb3JbaWRdO1xuICAgIHJldHVybiB2YWxpZGF0aW9uRXJyb3IgIT09IG51bGwgJiYgdmFsaWRhdGlvbkVycm9yICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gSW50ZXJuYWwgbWV0aG9kc1xuXG4gIHByaXZhdGUgaGFuZGxlQ29udHJvbENoYW5nZXMoKTogdm9pZCB7XG5cbiAgICAvLyBVbnN1YnNjcmliZSB0aGUgcHJldmlvdXMgY29udHJvbCBzdGF0dXMuXG4gICAgdGhpcy5fdmFsaWRhdGlvbkNvbnRleHRDaGFuZ2VzU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuXG4gICAgLy8gQ2xlYXIgdGhlIG1hcHBpbmcuXG4gICAgdGhpcy5faWRUb0xhYmVsID0ge307XG4gICAgdGhpcy5faWRUb1RlbXBsYXRlID0ge307XG4gICAgdGhpcy5faGFzSW52YWxpZEZpZWxkID0gZmFsc2U7XG4gICAgdGhpcy5faWRUb1ZhbGlkYXRpb25FcnJvciA9IHt9O1xuXG4gICAgLy8gSW52YWxpZCBpdGVtIGNvbGxlY3Rpb24uXG4gICAgaWYgKCF0aGlzLml0ZW1Db250ZXh0cyB8fCAhdGhpcy5pdGVtQ29udGV4dHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGNvbnRyb2wgY2hhbmdlcy5cbiAgICBmb3IgKGNvbnN0IGl0ZW1Db250ZXh0IG9mIHRoaXMuaXRlbUNvbnRleHRzKSB7XG4gICAgICB0aGlzLmhhbmRsZUNvbnRleHRDaGFuZ2VkRXZlbnQoaXRlbUNvbnRleHQsIHtuYW1lOiAnbGFiZWwnLCB2YWx1ZTogaXRlbUNvbnRleHQubGFiZWx9KTtcbiAgICAgIHRoaXMuaGFuZGxlQ29udGV4dENoYW5nZWRFdmVudChpdGVtQ29udGV4dCwge25hbWU6ICd0ZW1wbGF0ZScsIHZhbHVlOiBpdGVtQ29udGV4dC50ZW1wbGF0ZX0pO1xuICAgICAgdGhpcy5oYW5kbGVDb250ZXh0Q2hhbmdlZEV2ZW50KGl0ZW1Db250ZXh0LCB7bmFtZTogJ2luc3RhbmNlJywgdmFsdWU6IGl0ZW1Db250ZXh0Lmluc3RhbmNlfSk7XG5cbiAgICAgIGNvbnN0IHZhbGlkYXRpb25Db250ZXh0Q2hhbmdlU3Vic2NyaXB0aW9uID0gaXRlbUNvbnRleHQudXBkYXRlRXZlbnRcbiAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAoY29udGV4dDogTVVMVElQTEVfVkFMSURBVElPTl9TVU1NQVJJWkVSX0NPTlRFWFRfQ0hBTkdFRF9FVkVOVCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVDb250ZXh0Q2hhbmdlZEV2ZW50KGl0ZW1Db250ZXh0LCBjb250ZXh0LCB0cnVlKTtcbiAgICAgICAgICB9KTtcbiAgICAgIHRoaXMuX3ZhbGlkYXRpb25Db250ZXh0Q2hhbmdlc1N1YnNjcmlwdGlvbj8uYWRkKHZhbGlkYXRpb25Db250ZXh0Q2hhbmdlU3Vic2NyaXB0aW9uKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZXJlIGlzIGFueSBpbnZhbGlkIGZpZWxkIG9yIG5vdC5cbiAgICB0aGlzLl9oYXNJbnZhbGlkRmllbGQgPSB0aGlzLnNob3VsZEFueUZpZWxkSW52YWxpZCgpO1xuICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvLyBIYW5kbGUgY29udGV4dCBjaGFuZ2UgZXZlbnQuXG4gIHByaXZhdGUgaGFuZGxlQ29udGV4dENoYW5nZWRFdmVudChpdGVtQ29udGV4dDogTXVsdGlwbGVWYWxpZGF0aW9uU3VtbWFyaXplckl0ZW1Db250ZXh0RGlyZWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dDogTVVMVElQTEVfVkFMSURBVElPTl9TVU1NQVJJWkVSX0NPTlRFWFRfQ0hBTkdFRF9FVkVOVCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtBc0NoYW5nZWQ/OiBib29sZWFuKTogdm9pZCB7XG4gICAgc3dpdGNoIChjb250ZXh0Lm5hbWUpIHtcbiAgICAgIGNhc2UgJ2xhYmVsJzpcbiAgICAgICAgdGhpcy5faWRUb0xhYmVsW2l0ZW1Db250ZXh0LmlkXSA9IGNvbnRleHQudmFsdWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICd0ZW1wbGF0ZSc6XG4gICAgICAgIHRoaXMuX2lkVG9UZW1wbGF0ZVtpdGVtQ29udGV4dC5pZF0gPSBjb250ZXh0LnZhbHVlO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaW5zdGFuY2UnOlxuXG4gICAgICAgIC8vIFVuc3Vic2NyaWJlIHRoaXMgaW5zdGFuY2Ugc3Vic2NyaXB0aW9uLlxuICAgICAgICBsZXQgY29udHJvbENoYW5nZXNTdWJzY3JpcHRpb24gPSB0aGlzLl9pZFRvQ29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbltpdGVtQ29udGV4dC5pZF07XG4gICAgICAgIGNvbnRyb2xDaGFuZ2VzU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICBkZWxldGUgdGhpcy5faWRUb0luc3RhbmNlW2l0ZW1Db250ZXh0LmlkXTtcblxuICAgICAgICBsZXQgdmFsdWVDaGFuZ2VzT2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxhbnk+IHwgbnVsbCA9IG51bGw7XG4gICAgICAgIGlmIChpdGVtQ29udGV4dC5pbnN0YW5jZSBpbnN0YW5jZW9mIEFic3RyYWN0Q29udHJvbCkge1xuICAgICAgICAgIHZhbHVlQ2hhbmdlc09ic2VydmFibGUgPSAoaXRlbUNvbnRleHQuaW5zdGFuY2UgYXMgQWJzdHJhY3RDb250cm9sKS5zdGF0dXNDaGFuZ2VzO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW1Db250ZXh0Lmluc3RhbmNlIGluc3RhbmNlb2YgTmdDb250cm9sKSB7XG4gICAgICAgICAgdmFsdWVDaGFuZ2VzT2JzZXJ2YWJsZSA9IChpdGVtQ29udGV4dC5pbnN0YW5jZSBhcyBOZ0NvbnRyb2wpLnN0YXR1c0NoYW5nZXM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWVDaGFuZ2VzT2JzZXJ2YWJsZSkge1xuICAgICAgICAgIHRoaXMuX2lkVG9JbnN0YW5jZVtpdGVtQ29udGV4dC5pZF0gPSBjb250ZXh0LnZhbHVlO1xuICAgICAgICAgIGNvbnRyb2xDaGFuZ2VzU3Vic2NyaXB0aW9uID0gdmFsdWVDaGFuZ2VzT2JzZXJ2YWJsZVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5faWRUb0luc3RhbmNlW2l0ZW1Db250ZXh0LmlkXTtcbiAgICAgICAgICAgICAgaWYgKCFpbnN0YW5jZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHRoaXMuX2hhc0ludmFsaWRGaWVsZCA9IHRoaXMuc2hvdWxkQW55RmllbGRJbnZhbGlkKCk7XG4gICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgIHRoaXMuX3N1YnNjcmlwdGlvbi5hZGQoY29udHJvbENoYW5nZXNTdWJzY3JpcHRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKG1hcmtBc0NoYW5nZWQpIHtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVtb3ZlIGNvbnRyb2wgc3RhdHVzIGNoYW5nZSBzdWJzY3JpcHRpb24uXG4gIHByaXZhdGUgZGVsZXRlQ29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbnMoKTogdm9pZCB7XG4gICAgY29uc3QgaWRzID0gT2JqZWN0LmtleXModGhpcy5faWRUb0NvbnRyb2xTdGF0dXNDaGFuZ2VTdWJzY3JpcHRpb24pO1xuICAgIGZvciAoY29uc3QgaWQgb2YgaWRzKSB7XG4gICAgICBjb25zdCBjb250cm9sU3RhdHVzQ2hhbmdlU3Vic2NyaXB0aW9uID0gdGhpcy5faWRUb0NvbnRyb2xTdGF0dXNDaGFuZ2VTdWJzY3JpcHRpb25baWRdO1xuICAgICAgY29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pZFRvQ29udHJvbFN0YXR1c0NoYW5nZVN1YnNjcmlwdGlvbiA9IHt9O1xuICB9XG5cbiAgLy8gV2hldGhlciB0aGVyZSBpcyBhbnkgaW52YWxpZCBmaWVsZCBvciBub3QuXG4gIHByaXZhdGUgc2hvdWxkQW55RmllbGRJbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlkcyA9IE9iamVjdC5rZXlzKHRoaXMuX2lkVG9JbnN0YW5jZSk7XG4gICAgaWYgKCFpZHMgfHwgIWlkcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsZXQgaGFzVmFsaWRhdGlvbkVycm9yID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IGlkIG9mIGlkcykge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmlkVG9JbnN0YW5jZVtpZF07XG4gICAgICBpZiAoIWluc3RhbmNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdGhpcy52YWxpZGF0aW9uU3VtbWFyaXplclNlcnZpY2UubG9hZENvbnRyb2xWYWxpZGF0aW9uRXJyb3JzKGluc3RhbmNlIGFzIGFueSk7XG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2lkVG9WYWxpZGF0aW9uRXJyb3JbaWRdID0gdmFsaWRhdGlvbkVycm9ycztcbiAgICAgIGNvbnN0IHNob3VsZFZhbGlkYXRpb25FcnJvclZpc2libGUgPSB0aGlzLnZpc2liaWxpdHlIYW5kbGVyID8gdGhpcy5fdmlzaWJpbGl0eUhhbmRsZXIoaW5zdGFuY2UpIDogZmFsc2U7XG4gICAgICBpZiAoIXNob3VsZFZhbGlkYXRpb25FcnJvclZpc2libGUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGhhc1ZhbGlkYXRpb25FcnJvciA9IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc1ZhbGlkYXRpb25FcnJvcjtcbiAgfVxuXG4gIC8vI2VuZHJlZ2lvblxufVxuIiwiPHVsICpuZ0lmPVwiaGFzSW52YWxpZEZpZWxkXCI+XG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW1Db250ZXh0IG9mIGl0ZW1Db250ZXh0c1wiPlxuICAgIDxjbXMtdmFsaWRhdGlvbi1zdW1tYXJpemVyICpuZ0lmPVwiaWRUb0luc3RhbmNlW2l0ZW1Db250ZXh0LmlkXSAmJiBzaG91bGRDb250cm9sSGFzVmFsaWRhdGlvbkVycm9yKGl0ZW1Db250ZXh0LmlkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2luc3RhbmNlXT1cImlkVG9JbnN0YW5jZVtpdGVtQ29udGV4dC5pZF1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJpZFRvTGFiZWxbaXRlbUNvbnRleHQuaWRdXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRhdGlvbi10ZW1wbGF0ZV09XCJpZFRvVGVtcGxhdGVbaXRlbUNvbnRleHQuaWRdIHx8IHZhbGlkYXRpb25TdW1tYXJpemVyVGVtcGxhdGVcIj5cbiAgICA8L2Ntcy12YWxpZGF0aW9uLXN1bW1hcml6ZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC91bD5cblxuXG48IS0tRGVmYXVsdCB2YWxpZGF0aW9uIHN1bW1hcnkgdGVtcGxhdGUtLT5cbjxuZy10ZW1wbGF0ZVxuICAjdmFsaWRhdGlvblN1bW1hcml6ZXJUZW1wbGF0ZVxuICBsZXQtbmdDb250cm9sPVwibmdDb250cm9sXCJcbiAgbGV0LWNvbnRyb2xMYWJlbD1cImNvbnRyb2xMYWJlbFwiXG4gIGxldC12YWxpZGF0aW9uTWVzc2FnZXM9XCJ2YWxpZGF0aW9uTWVzc2FnZXNcIlxuPlxuICA8bGkgKm5nRm9yPVwibGV0IHZhbGlkYXRpb25NZXNzYWdlIG9mIHZhbGlkYXRpb25NZXNzYWdlcztcIj5cbiAgICB7e2NvbnRyb2xMYWJlbH19IHt7dmFsaWRhdGlvbk1lc3NhZ2UgfCBqc29ufX1cbiAgPC9saT5cbjwvbmctdGVtcGxhdGU+XG4iXX0=