UNPKG

@harbor/ui

Version:

Harbor shared UI components based on Clarity and Angular6

360 lines (359 loc) 38.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, Input, Output, EventEmitter, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from "@angular/core"; import { forkJoin } from "rxjs"; import { TranslateService } from "@ngx-translate/core"; import { ReplicationService } from "../service/replication.service"; import { ConfirmationDialogComponent } from "../confirmation-dialog/confirmation-dialog.component"; import { ConfirmationMessage } from "../confirmation-dialog/confirmation-message"; import { ErrorHandler } from "../error-handler/error-handler"; import { toPromise, CustomComparator } from "../utils"; import { operateChanges, OperateInfo, OperationState } from "../operation/operate"; import { OperationService } from "../operation/operation.service"; export class ListReplicationRuleComponent { /** * @param {?} replicationService * @param {?} translateService * @param {?} errorHandler * @param {?} operationService * @param {?} ref */ constructor(replicationService, translateService, errorHandler, operationService, ref) { this.replicationService = replicationService; this.translateService = translateService; this.errorHandler = errorHandler; this.operationService = operationService; this.ref = ref; this.nullTime = "0001-01-01T00:00:00Z"; this.loading = false; this.reload = new EventEmitter(); this.selectOne = new EventEmitter(); this.editOne = new EventEmitter(); this.toggleOne = new EventEmitter(); this.hideJobs = new EventEmitter(); this.redirect = new EventEmitter(); this.openNewRule = new EventEmitter(); this.replicateManual = new EventEmitter(); this.projectScope = false; this.startTimeComparator = new CustomComparator("start_time", "date"); this.enabledComparator = new CustomComparator("enabled", "number"); setInterval(() => ref.markForCheck(), 500); } /** * @param {?} desc * @return {?} */ trancatedDescription(desc) { if (desc.length > 35) { return desc.substr(0, 35); } else { return desc; } } /** * @return {?} */ ngOnInit() { // Global scope if (!this.projectScope) { this.retrieveRules(); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ let proIdChange = changes["projectId"]; if (proIdChange) { if (proIdChange.currentValue !== proIdChange.previousValue) { if (proIdChange.currentValue) { this.projectId = proIdChange.currentValue; this.projectScope = true; // Scope is project, not global list // Initially load the replication rule data this.retrieveRules(); } } } } /** * @param {?=} ruleName * @return {?} */ retrieveRules(ruleName = "") { this.loading = true; /*this.selectedRow = null;*/ toPromise(this.replicationService.getReplicationRules(this.projectId, ruleName)) .then(rules => { this.rules = rules || []; // job list hidden this.hideJobs.emit(); this.changedRules = this.rules; this.loading = false; }) .catch(error => { this.errorHandler.error(error); this.loading = false; }); } /** * @param {?} rule * @return {?} */ replicateRule(rule) { this.replicateManual.emit(rule); } /** * @param {?} rule * @return {?} */ hasDeletedLabel(rule) { if (rule.filters) { /** @type {?} */ let count = 0; rule.filters.forEach((data) => { if (data.kind === 'label' && data.value.deleted) { count++; } }); if (count === 0) { return 'enabled'; } else { return 'disabled'; } } return 'enabled'; } /** * @param {?} message * @return {?} */ deletionConfirm(message) { if (message && message.source === 4 /* POLICY */ && message.state === 1 /* CONFIRMED */) { this.deleteOpe(message.data); } } /** * @param {?} rule * @return {?} */ selectRule(rule) { this.selectedId = rule.id || ""; this.selectOne.emit(rule); } /** * @param {?} rule * @return {?} */ redirectTo(rule) { this.redirect.emit(rule); } /** * @return {?} */ openModal() { this.openNewRule.emit(); } /** * @param {?} rule * @return {?} */ editRule(rule) { this.editOne.emit(rule); } /** * @param {?} id * @return {?} */ jobList(id) { /** @type {?} */ let ruleData; this.canDeleteRule = true; /** @type {?} */ let count = 0; return toPromise(this.replicationService.getJobs(id)) .then(response => { ruleData = response.data; if (ruleData.length) { ruleData.forEach(job => { if (job.status === "pending" || job.status === "running" || job.status === "retrying") { count++; } }); } this.canDeleteRule = count > 0 ? false : true; }) .catch(error => this.errorHandler.error(error)); } /** * @param {?} rule * @return {?} */ deleteRule(rule) { if (rule) { /** @type {?} */ let deletionMessage = new ConfirmationMessage("REPLICATION.DELETION_TITLE", "REPLICATION.DELETION_SUMMARY", rule.name, rule, 4 /* POLICY */, 2 /* DELETE_CANCEL */); this.deletionConfirmDialog.open(deletionMessage); } } /** * @param {?} rule * @return {?} */ deleteOpe(rule) { if (rule) { /** @type {?} */ let promiseLists = []; Promise.all([this.jobList(rule.id)]).then(items => { promiseLists.push(this.delOperate(rule)); Promise.all(promiseLists).then(item => { this.selectedRow = null; this.reload.emit(true); /** @type {?} */ let hnd = setInterval(() => this.ref.markForCheck(), 200); setTimeout(() => clearInterval(hnd), 2000); }); }); } } /** * @param {?} rule * @return {?} */ delOperate(rule) { /** @type {?} */ let operMessage = new OperateInfo(); operMessage.name = 'OPERATION.DELETE_REPLICATION'; operMessage.data["id"] = +rule.id; operMessage.state = OperationState.progressing; operMessage.data["name"] = rule.name; this.operationService.publishInfo(operMessage); if (!this.canDeleteRule) { forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'), this.translateService.get('REPLICATION.DELETION_SUMMARY_FAILURE')).subscribe(res => { operateChanges(operMessage, OperationState.failure, res[1]); }); return null; } return toPromise(this.replicationService .deleteReplicationRule(+rule.id)) .then(() => { this.translateService.get('BATCH.DELETED_SUCCESS') .subscribe(res => operateChanges(operMessage, OperationState.success)); }) .catch(error => { if (error && error.status === 412) { forkJoin(this.translateService.get('BATCH.DELETED_FAILURE'), this.translateService.get('REPLICATION.FAILED_TO_DELETE_POLICY_ENABLED')).subscribe(res => { operateChanges(operMessage, OperationState.failure, res[1]); }); } else { this.translateService.get('BATCH.DELETED_FAILURE').subscribe(res => { operateChanges(operMessage, OperationState.failure, res); }); } }); } } ListReplicationRuleComponent.decorators = [ { type: Component, args: [{ selector: "hbr-list-replication-rule", template: "<div style=\"padding-bottom: 15px;\">\n<clr-datagrid [clrDgLoading]=\"loading\" [(clrDgSingleSelected)]=\"selectedRow\" [clDgRowSelection]=\"true\">\n <clr-dg-action-bar>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" *ngIf=\"isSystemAdmin\" (click)=\"openModal()\"><clr-icon shape=\"plus\" size=\"16\"></clr-icon>&nbsp;{{'REPLICATION.NEW_REPLICATION_RULE' | translate}}</button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" *ngIf=\"isSystemAdmin\" [disabled]=\"!selectedRow\" (click)=\"editRule(selectedRow)\"><clr-icon shape=\"pencil\" size=\"16\"></clr-icon>&nbsp;{{'REPLICATION.EDIT_POLICY' | translate}}</button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" *ngIf=\"isSystemAdmin\" [disabled]=\"!selectedRow\" (click)=\"deleteRule(selectedRow)\"><clr-icon shape=\"times\" size=\"16\"></clr-icon>&nbsp;{{'REPLICATION.DELETE_POLICY' | translate}}</button>\n <button type=\"button\" class=\"btn btn-sm btn-secondary\" *ngIf=\"isSystemAdmin\" [disabled]=\"!selectedRow\" (click)=\"replicateRule(selectedRow)\"><clr-icon shape=\"export\" size=\"16\"></clr-icon>&nbsp;{{'REPLICATION.REPLICATE' | translate}}</button>\n </clr-dg-action-bar>\n <clr-dg-column [clrDgField]=\"'name'\">{{'REPLICATION.NAME' | translate}}</clr-dg-column>\n <clr-dg-column [clrDgField]=\"'status'\">{{'REPLICATION.STATUS' | translate}}</clr-dg-column>\n <clr-dg-column *ngIf=\"!projectScope\">{{'REPLICATION.PROJECT' | translate}}</clr-dg-column>\n <clr-dg-column [clrDgField]=\"'description'\">{{'REPLICATION.DESCRIPTION' | translate}}</clr-dg-column>\n <clr-dg-column >{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>\n <clr-dg-column [clrDgField]=\"'trigger'\">{{'REPLICATION.TRIGGER_MODE' | translate}}</clr-dg-column>\n <clr-dg-placeholder>{{'REPLICATION.PLACEHOLDER' | translate }}</clr-dg-placeholder>\n <clr-dg-row *clrDgItems=\"let p of changedRules\" [clrDgItem]=\"p\" (click)=\"selectRule(p)\" [style.backgroundColor]=\"(projectScope && withReplicationJob && selectedId === p.id) ? '#eee' : ''\">\n <clr-dg-cell>{{p.name}}</clr-dg-cell>\n <clr-dg-cell>\n <div [ngSwitch]=\"hasDeletedLabel(p)\">\n <clr-tooltip *ngSwitchCase=\"'disabled'\" class=\"tooltip-lg\">\n <clr-icon clrTooltipTrigger shape=\"exclamation-triangle\" style=\"vertical-align: text-bottom;\" class=\"is-warning\" size=\"22\"></clr-icon>Disabled\n <clr-tooltip-content clrPosition=\"top-right\" clrSize=\"xs\" *clrIfOpen>\n <span>{{'REPLICATION.RULE_DISABLED' | translate}}</span>\n </clr-tooltip-content>\n </clr-tooltip>\n <div *ngSwitchCase=\"'enabled'\" ><clr-icon shape=\"success-standard\" style=\"vertical-align: text-bottom;\" class=\"is-success\" size=\"18\"></clr-icon> Enabled</div>\n </div>\n </clr-dg-cell>\n <clr-dg-cell *ngIf=\"!projectScope\">\n <a href=\"javascript:void(0)\" (click)=\"$event.stopPropagation(); redirectTo(p)\">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>\n </clr-dg-cell>\n <clr-dg-cell>\n {{p.description ? trancatedDescription(p.description) : '-'}}\n <clr-tooltip>\n <clr-icon *ngIf=\"p.description && p.description.length > 35\" clrTooltipTrigger shape=\"ellipsis-horizontal\" size=\"18\"></clr-icon>\n <clr-tooltip-content clrPosition=\"bottom-right\" clrSize=\"md\" *clrIfOpen>\n <span>{{p.description}}</span>\n </clr-tooltip-content>\n </clr-tooltip>\n </clr-dg-cell>\n <clr-dg-cell>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>\n <clr-dg-cell>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>\n </clr-dg-row>\n <clr-dg-footer>\n <span *ngIf=\"pagination.totalItems\">{{pagination.firstItem + 1}} - {{pagination.lastItem +1 }} {{'REPLICATION.OF' | translate}} </span>{{pagination.totalItems }} {{'REPLICATION.ITEMS' | translate}}\n <clr-dg-pagination #pagination [clrDgPageSize]=\"5\"></clr-dg-pagination>\n </clr-dg-footer>\n</clr-datagrid>\n<confirmation-dialog #deletionConfirmDialog (confirmAction)=\"deletionConfirm($event)\"></confirmation-dialog>\n</div>\n", changeDetection: ChangeDetectionStrategy.OnPush, styles: [""] }] } ]; /** @nocollapse */ ListReplicationRuleComponent.ctorParameters = () => [ { type: ReplicationService }, { type: TranslateService }, { type: ErrorHandler }, { type: OperationService }, { type: ChangeDetectorRef } ]; ListReplicationRuleComponent.propDecorators = { projectId: [{ type: Input }], isSystemAdmin: [{ type: Input }], selectedId: [{ type: Input }], withReplicationJob: [{ type: Input }], loading: [{ type: Input }], reload: [{ type: Output }], selectOne: [{ type: Output }], editOne: [{ type: Output }], toggleOne: [{ type: Output }], hideJobs: [{ type: Output }], redirect: [{ type: Output }], openNewRule: [{ type: Output }], replicateManual: [{ type: Output }], toggleConfirmDialog: [{ type: ViewChild, args: ["toggleConfirmDialog",] }], deletionConfirmDialog: [{ type: ViewChild, args: ["deletionConfirmDialog",] }] }; if (false) { /** @type {?} */ ListReplicationRuleComponent.prototype.nullTime; /** @type {?} */ ListReplicationRuleComponent.prototype.projectId; /** @type {?} */ ListReplicationRuleComponent.prototype.isSystemAdmin; /** @type {?} */ ListReplicationRuleComponent.prototype.selectedId; /** @type {?} */ ListReplicationRuleComponent.prototype.withReplicationJob; /** @type {?} */ ListReplicationRuleComponent.prototype.loading; /** @type {?} */ ListReplicationRuleComponent.prototype.reload; /** @type {?} */ ListReplicationRuleComponent.prototype.selectOne; /** @type {?} */ ListReplicationRuleComponent.prototype.editOne; /** @type {?} */ ListReplicationRuleComponent.prototype.toggleOne; /** @type {?} */ ListReplicationRuleComponent.prototype.hideJobs; /** @type {?} */ ListReplicationRuleComponent.prototype.redirect; /** @type {?} */ ListReplicationRuleComponent.prototype.openNewRule; /** @type {?} */ ListReplicationRuleComponent.prototype.replicateManual; /** @type {?} */ ListReplicationRuleComponent.prototype.projectScope; /** @type {?} */ ListReplicationRuleComponent.prototype.rules; /** @type {?} */ ListReplicationRuleComponent.prototype.changedRules; /** @type {?} */ ListReplicationRuleComponent.prototype.ruleName; /** @type {?} */ ListReplicationRuleComponent.prototype.canDeleteRule; /** @type {?} */ ListReplicationRuleComponent.prototype.selectedRow; /** @type {?} */ ListReplicationRuleComponent.prototype.toggleConfirmDialog; /** @type {?} */ ListReplicationRuleComponent.prototype.deletionConfirmDialog; /** @type {?} */ ListReplicationRuleComponent.prototype.startTimeComparator; /** @type {?} */ ListReplicationRuleComponent.prototype.enabledComparator; /** @type {?} */ ListReplicationRuleComponent.prototype.replicationService; /** @type {?} */ ListReplicationRuleComponent.prototype.translateService; /** @type {?} */ ListReplicationRuleComponent.prototype.errorHandler; /** @type {?} */ ListReplicationRuleComponent.prototype.operationService; /** @type {?} */ ListReplicationRuleComponent.prototype.ref; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1yZXBsaWNhdGlvbi1ydWxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BoYXJib3IvdWkvIiwic291cmNlcyI6WyJzcmMvbGlzdC1yZXBsaWNhdGlvbi1ydWxlL2xpc3QtcmVwbGljYXRpb24tcnVsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQWFBLE9BQU8sRUFDSCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFFTixZQUFZLEVBQ1osU0FBUyxFQUNULHVCQUF1QixFQUN2QixpQkFBaUIsRUFJcEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUUvQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RCxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQU1sRSxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxzREFBc0QsQ0FBQztBQUNqRyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSw2Q0FBNkMsQ0FBQztBQU9oRixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxFQUFDLFNBQVMsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNyRCxPQUFPLEVBQUMsY0FBYyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQVNoRSxNQUFNOzs7Ozs7OztJQXFDRixZQUFvQixrQkFBc0MsRUFDdEMsa0JBQ0EsY0FDQSxrQkFDQTtRQUpBLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMscUJBQWdCLEdBQWhCLGdCQUFnQjtRQUNoQixpQkFBWSxHQUFaLFlBQVk7UUFDWixxQkFBZ0IsR0FBaEIsZ0JBQWdCO1FBQ2hCLFFBQUcsR0FB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QUFDLE1BQU07O2FBQ2xEOzs7O1lBekJPLGtCQUFrQjtZQUZqQixnQkFBZ0I7WUFnQmpCLFlBQVk7WUFHWixnQkFBZ0I7WUExQnBCLGlCQUFpQjs7O3dCQXNDaEIsS0FBSzs0QkFDTCxLQUFLO3lCQUNMLEtBQUs7aUNBQ0wsS0FBSztzQkFFTCxLQUFLO3FCQUVMLE1BQU07d0JBQ04sTUFBTTtzQkFDTixNQUFNO3dCQUNOLE1BQU07dUJBQ04sTUFBTTt1QkFDTixNQUFNOzBCQUNOLE1BQU07OEJBQ04sTUFBTTtrQ0FXTixTQUFTLFNBQUMscUJBQXFCO29DQUcvQixTQUFTLFNBQUMsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSAyMDE3IFZNd2FyZSwgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuLy9cbi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4vLyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4vLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbi8vXG4vLyAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbi8vXG4vLyBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4vLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4vLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbi8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbi8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgSW5wdXQsXG4gICAgT3V0cHV0LFxuICAgIE9uSW5pdCxcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgVmlld0NoaWxkLFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIE9uQ2hhbmdlcyxcbiAgICBTaW1wbGVDaGFuZ2UsXG4gICAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgZm9ya0pvaW59IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgeyBDb21wYXJhdG9yIH0gZnJvbSBcIkBjbHIvYW5ndWxhclwiO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gXCJAbmd4LXRyYW5zbGF0ZS9jb3JlXCI7XG5cbmltcG9ydCB7UmVwbGljYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi4vc2VydmljZS9yZXBsaWNhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICAgIFJlcGxpY2F0aW9uSm9iLFxuICAgIFJlcGxpY2F0aW9uSm9iSXRlbSxcbiAgICBSZXBsaWNhdGlvblJ1bGVcbn0gZnJvbSBcIi4uL3NlcnZpY2UvaW50ZXJmYWNlXCI7XG5pbXBvcnQge0NvbmZpcm1hdGlvbkRpYWxvZ0NvbXBvbmVudH0gZnJvbSBcIi4uL2NvbmZpcm1hdGlvbi1kaWFsb2cvY29uZmlybWF0aW9uLWRpYWxvZy5jb21wb25lbnRcIjtcbmltcG9ydCB7Q29uZmlybWF0aW9uTWVzc2FnZX0gZnJvbSBcIi4uL2NvbmZpcm1hdGlvbi1kaWFsb2cvY29uZmlybWF0aW9uLW1lc3NhZ2VcIjtcbmltcG9ydCB7Q29uZmlybWF0aW9uQWNrbm93bGVkZ2VtZW50fSBmcm9tIFwiLi4vY29uZmlybWF0aW9uLWRpYWxvZy9jb25maXJtYXRpb24tc3RhdGUtbWVzc2FnZVwiO1xuaW1wb3J0IHtcbiAgICBDb25maXJtYXRpb25TdGF0ZSxcbiAgICBDb25maXJtYXRpb25UYXJnZXRzLFxuICAgIENvbmZpcm1hdGlvbkJ1dHRvbnNcbn0gZnJvbSBcIi4uL3NoYXJlZC9zaGFyZWQuY29uc3RcIjtcbmltcG9ydCB7RXJyb3JIYW5kbGVyfSBmcm9tIFwiLi4vZXJyb3ItaGFuZGxlci9lcnJvci1oYW5kbGVyXCI7XG5pbXBvcnQge3RvUHJvbWlzZSwgQ3VzdG9tQ29tcGFyYXRvcn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQge29wZXJhdGVDaGFuZ2VzLCBPcGVyYXRlSW5mbywgT3BlcmF0aW9uU3RhdGV9IGZyb20gXCIuLi9vcGVyYXRpb24vb3BlcmF0ZVwiO1xuaW1wb3J0IHtPcGVyYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi4vb3BlcmF0aW9uL29wZXJhdGlvbi5zZXJ2aWNlXCI7XG5cblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6IFwiaGJyLWxpc3QtcmVwbGljYXRpb24tcnVsZVwiLFxuICAgIHRlbXBsYXRlVXJsOiBcIi4vbGlzdC1yZXBsaWNhdGlvbi1ydWxlLmNvbXBvbmVudC5odG1sXCIsXG4gICAgc3R5bGVVcmxzOiBbXCIuL2xpc3QtcmVwbGljYXRpb24tcnVsZS5jb21wb25lbnQuc2Nzc1wiXSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBMaXN0UmVwbGljYXRpb25SdWxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICAgIG51bGxUaW1lID0gXCIwMDAxLTAxLTAxVDAwOjAwOjAwWlwiO1xuXG4gICAgQElucHV0KCkgcHJvamVjdElkOiBudW1iZXI7XG4gICAgQElucHV0KCkgaXNTeXN0ZW1BZG1pbjogYm9vbGVhbjtcbiAgICBASW5wdXQoKSBzZWxlY3RlZElkOiBudW1iZXIgfCBzdHJpbmc7XG4gICAgQElucHV0KCkgd2l0aFJlcGxpY2F0aW9uSm9iOiBib29sZWFuO1xuXG4gICAgQElucHV0KCkgbG9hZGluZyA9IGZhbHNlO1xuXG4gICAgQE91dHB1dCgpIHJlbG9hZCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgICBAT3V0cHV0KCkgc2VsZWN0T25lID0gbmV3IEV2ZW50RW1pdHRlcjxSZXBsaWNhdGlvblJ1bGU+KCk7XG4gICAgQE91dHB1dCgpIGVkaXRPbmUgPSBuZXcgRXZlbnRFbWl0dGVyPFJlcGxpY2F0aW9uUnVsZT4oKTtcbiAgICBAT3V0cHV0KCkgdG9nZ2xlT25lID0gbmV3IEV2ZW50RW1pdHRlcjxSZXBsaWNhdGlvblJ1bGU+KCk7XG4gICAgQE91dHB1dCgpIGhpZGVKb2JzID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICAgQE91dHB1dCgpIHJlZGlyZWN0ID0gbmV3IEV2ZW50RW1pdHRlcjxSZXBsaWNhdGlvblJ1bGU+KCk7XG4gICAgQE91dHB1dCgpIG9wZW5OZXdSdWxlID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICAgQE91dHB1dCgpIHJlcGxpY2F0ZU1hbnVhbCA9IG5ldyBFdmVudEVtaXR0ZXI8UmVwbGljYXRpb25SdWxlPigpO1xuXG4gICAgcHJvamVjdFNjb3BlID0gZmFsc2U7XG5cbiAgICBydWxlczogUmVwbGljYXRpb25SdWxlW107XG4gICAgY2hhbmdlZFJ1bGVzOiBSZXBsaWNhdGlvblJ1bGVbXTtcbiAgICBydWxlTmFtZTogc3RyaW5nO1xuICAgIGNhbkRlbGV0ZVJ1bGU6IGJvb2xlYW47XG5cbiAgICBzZWxlY3RlZFJvdzogUmVwbGljYXRpb25SdWxlO1xuXG4gICAgQFZpZXdDaGlsZChcInRvZ2dsZUNvbmZpcm1EaWFsb2dcIilcbiAgICB0b2dnbGVDb25maXJtRGlhbG9nOiBDb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQ7XG5cbiAgICBAVmlld0NoaWxkKFwiZGVsZXRpb25Db25maXJtRGlhbG9nXCIpXG4gICAgZGVsZXRpb25Db25maXJtRGlhbG9nOiBDb25maXJtYXRpb25EaWFsb2dDb21wb25lbnQ7XG5cbiAgICBzdGFydFRpbWVDb21wYXJhdG9yOiBDb21wYXJhdG9yPFJlcGxpY2F0aW9uUnVsZT4gPSBuZXcgQ3VzdG9tQ29tcGFyYXRvcjxSZXBsaWNhdGlvblJ1bGU+KFwic3RhcnRfdGltZVwiLCBcImRhdGVcIik7XG4gICAgZW5hYmxlZENvbXBhcmF0b3I6IENvbXBhcmF0b3I8UmVwbGljYXRpb25SdWxlPiA9IG5ldyBDdXN0b21Db21wYXJhdG9yPFJlcGxpY2F0aW9uUnVsZT4oXCJlbmFibGVkXCIsIFwibnVtYmVyXCIpO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZXBsaWNhdGlvblNlcnZpY2U6IFJlcGxpY2F0aW9uU2VydmljZSxcbiAgICAgICAgICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBlcnJvckhhbmRsZXI6IEVycm9ySGFuZGxlcixcbiAgICAgICAgICAgICAgICBwcml2YXRlIG9wZXJhdGlvblNlcnZpY2U6IE9wZXJhdGlvblNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSByZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gICAgICAgIHNldEludGVydmFsKCgpID0+IHJlZi5tYXJrRm9yQ2hlY2soKSwgNTAwKTtcbiAgICB9XG5cbiAgICB0cmFuY2F0ZWREZXNjcmlwdGlvbihkZXNjOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBpZiAoZGVzYy5sZW5ndGggPiAzNSkge1xuICAgICAgICAgICAgcmV0dXJuIGRlc2Muc3Vic3RyKDAsIDM1KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBkZXNjO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIC8vIEdsb2JhbCBzY29wZVxuICAgICAgICBpZiAoIXRoaXMucHJvamVjdFNjb3BlKSB7XG4gICAgICAgICAgICB0aGlzLnJldHJpZXZlUnVsZXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgbGV0IHByb0lkQ2hhbmdlOiBTaW1wbGVDaGFuZ2UgPSBjaGFuZ2VzW1wicHJvamVjdElkXCJdO1xuICAgICAgICBpZiAocHJvSWRDaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmIChwcm9JZENoYW5nZS5jdXJyZW50VmFsdWUgIT09IHByb0lkQ2hhbmdlLnByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvSWRDaGFuZ2UuY3VycmVudFZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvamVjdElkID0gcHJvSWRDaGFuZ2UuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2plY3RTY29wZSA9IHRydWU7IC8vIFNjb3BlIGlzIHByb2plY3QsIG5vdCBnbG9iYWwgbGlzdFxuICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsbHkgbG9hZCB0aGUgcmVwbGljYXRpb24gcnVsZSBkYXRhXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmV0cmlldmVSdWxlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHJpZXZlUnVsZXMocnVsZU5hbWUgPSBcIlwiKTogdm9pZCB7XG4gICAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICAgIC8qdGhpcy5zZWxlY3RlZFJvdyA9IG51bGw7Ki9cbiAgICAgICAgdG9Qcm9taXNlPFJlcGxpY2F0aW9uUnVsZVtdPihcbiAgICAgICAgICAgIHRoaXMucmVwbGljYXRpb25TZXJ2aWNlLmdldFJlcGxpY2F0aW9uUnVsZXModGhpcy5wcm9qZWN0SWQsIHJ1bGVOYW1lKVxuICAgICAgICApXG4gICAgICAgICAgICAudGhlbihydWxlcyA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydWxlcyA9IHJ1bGVzIHx8IFtdO1xuICAgICAgICAgICAgICAgIC8vIGpvYiBsaXN0IGhpZGRlblxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZUpvYnMuZW1pdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZFJ1bGVzID0gdGhpcy5ydWxlcztcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJlcGxpY2F0ZVJ1bGUocnVsZTogUmVwbGljYXRpb25SdWxlKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVwbGljYXRlTWFudWFsLmVtaXQocnVsZSk7XG4gICAgfVxuXG4gICAgaGFzRGVsZXRlZExhYmVsKHJ1bGU6IGFueSkge1xuICAgICAgICBpZiAocnVsZS5maWx0ZXJzKSB7XG4gICAgICAgICAgICBsZXQgY291bnQgPSAwO1xuICAgICAgICAgICAgcnVsZS5maWx0ZXJzLmZvckVhY2goKGRhdGE6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhLmtpbmQgPT09ICdsYWJlbCcgJiYgZGF0YS52YWx1ZS5kZWxldGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICdlbmFibGVkJztcbiAgICAgICAgICAgIH0gZWxzZSB7IHJldHVybiAnZGlzYWJsZWQnOyB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICdlbmFibGVkJztcbiAgICB9XG5cbiAgICBkZWxldGlvbkNvbmZpcm0obWVzc2FnZTogQ29uZmlybWF0aW9uQWNrbm93bGVkZ2VtZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIG1lc3NhZ2UgJiZcbiAgICAgICAgICAgIG1lc3NhZ2Uuc291cmNlID09PSBDb25maXJtYXRpb25UYXJnZXRzLlBPTElDWSAmJlxuICAgICAgICAgICAgbWVzc2FnZS5zdGF0ZSA9PT0gQ29uZmlybWF0aW9uU3RhdGUuQ09ORklSTUVEXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5kZWxldGVPcGUobWVzc2FnZS5kYXRhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNlbGVjdFJ1bGUocnVsZTogUmVwbGljYXRpb25SdWxlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJZCA9IHJ1bGUuaWQgfHwgXCJcIjtcbiAgICAgICAgdGhpcy5zZWxlY3RPbmUuZW1pdChydWxlKTtcbiAgICB9XG5cbiAgICByZWRpcmVjdFRvKHJ1bGU6IFJlcGxpY2F0aW9uUnVsZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnJlZGlyZWN0LmVtaXQocnVsZSk7XG4gICAgfVxuXG4gICAgb3Blbk1vZGFsKCk6IHZvaWQge1xuICAgICAgICB0aGlzLm9wZW5OZXdSdWxlLmVtaXQoKTtcbiAgICB9XG5cbiAgICBlZGl0UnVsZShydWxlOiBSZXBsaWNhdGlvblJ1bGUpIHtcbiAgICAgICAgdGhpcy5lZGl0T25lLmVtaXQocnVsZSk7XG4gICAgfVxuXG4gICAgam9iTGlzdChpZDogc3RyaW5nIHwgbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBydWxlRGF0YTogUmVwbGljYXRpb25Kb2JJdGVtW107XG4gICAgICAgIHRoaXMuY2FuRGVsZXRlUnVsZSA9IHRydWU7XG4gICAgICAgIGxldCBjb3VudCA9IDA7XG4gICAgICAgIHJldHVybiB0b1Byb21pc2U8UmVwbGljYXRpb25Kb2I+KHRoaXMucmVwbGljYXRpb25TZXJ2aWNlLmdldEpvYnMoaWQpKVxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgIHJ1bGVEYXRhID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgICAgICAgICAgICBpZiAocnVsZURhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bGVEYXRhLmZvckVhY2goam9iID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBqb2Iuc3RhdHVzID09PSBcInBlbmRpbmdcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpvYi5zdGF0dXMgPT09IFwicnVubmluZ1wiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgam9iLnN0YXR1cyA9PT0gXCJyZXRyeWluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5jYW5EZWxldGVSdWxlID0gY291bnQgPiAwID8gZmFsc2UgOiB0cnVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB0aGlzLmVycm9ySGFuZGxlci5lcnJvcihlcnJvcikpO1xuICAgIH1cblxuICAgIGRlbGV0ZVJ1bGUocnVsZTogUmVwbGljYXRpb25SdWxlKSB7XG4gICAgICAgIGlmIChydWxlKSB7XG4gICAgICAgICAgICBsZXQgZGVsZXRpb25NZXNzYWdlID0gbmV3IENvbmZpcm1hdGlvbk1lc3NhZ2UoXG4gICAgICAgICAgICAgICAgXCJSRVBMSUNBVElPTi5ERUxFVElPTl9USVRMRVwiLFxuICAgICAgICAgICAgICAgIFwiUkVQTElDQVRJT04uREVMRVRJT05fU1VNTUFSWVwiLFxuICAgICAgICAgICAgICAgIHJ1bGUubmFtZSxcbiAgICAgICAgICAgICAgICBydWxlLFxuICAgICAgICAgICAgICAgIENvbmZpcm1hdGlvblRhcmdldHMuUE9MSUNZLFxuICAgICAgICAgICAgICAgIENvbmZpcm1hdGlvbkJ1dHRvbnMuREVMRVRFX0NBTkNFTFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRpb25Db25maXJtRGlhbG9nLm9wZW4oZGVsZXRpb25NZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGRlbGV0ZU9wZShydWxlOiBSZXBsaWNhdGlvblJ1bGUpIHtcbiAgICAgICAgaWYgKHJ1bGUpIHtcbiAgICAgICAgICAgIGxldCBwcm9taXNlTGlzdHM6IGFueVtdID0gW107XG4gICAgICAgICAgICBQcm9taXNlLmFsbChbdGhpcy5qb2JMaXN0KHJ1bGUuaWQpXSkudGhlbihpdGVtcyA9PiB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZUxpc3RzLnB1c2godGhpcy5kZWxPcGVyYXRlKHJ1bGUpKTtcblxuICAgICAgICAgICAgICAgIFByb21pc2UuYWxsKHByb21pc2VMaXN0cykudGhlbihpdGVtID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJvdyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkLmVtaXQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBobmQgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKSwgMjAwKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBjbGVhckludGVydmFsKGhuZCksIDIwMDApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZWxPcGVyYXRlKHJ1bGU6IFJlcGxpY2F0aW9uUnVsZSkge1xuICAgICAgICAvLyBpbml0IG9wZXJhdGlvbiBpbmZvXG4gICAgICAgIGxldCBvcGVyTWVzc2FnZSA9IG5ldyBPcGVyYXRlSW5mbygpO1xuICAgICAgICBvcGVyTWVzc2FnZS5uYW1lID0gJ09QRVJBVElPTi5ERUxFVEVfUkVQTElDQVRJT04nO1xuICAgICAgICBvcGVyTWVzc2FnZS5kYXRhLmlkID0gK3J1bGUuaWQ7XG4gICAgICAgIG9wZXJNZXNzYWdlLnN0YXRlID0gT3BlcmF0aW9uU3RhdGUucHJvZ3Jlc3Npbmc7XG4gICAgICAgIG9wZXJNZXNzYWdlLmRhdGEubmFtZSA9IHJ1bGUubmFtZTtcbiAgICAgICAgdGhpcy5vcGVyYXRpb25TZXJ2aWNlLnB1Ymxpc2hJbmZvKG9wZXJNZXNzYWdlKTtcblxuICAgICAgICBpZiAoIXRoaXMuY2FuRGVsZXRlUnVsZSkge1xuICAgICAgICAgICAgZm9ya0pvaW4odGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9GQUlMVVJFJyksXG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnUkVQTElDQVRJT04uREVMRVRJT05fU1VNTUFSWV9GQUlMVVJFJykpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgICAgIG9wZXJhdGVDaGFuZ2VzKG9wZXJNZXNzYWdlLCBPcGVyYXRpb25TdGF0ZS5mYWlsdXJlLCByZXNbMV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0b1Byb21pc2U8YW55Pih0aGlzLnJlcGxpY2F0aW9uU2VydmljZVxuICAgICAgICAgICAgLmRlbGV0ZVJlcGxpY2F0aW9uUnVsZSgrcnVsZS5pZCkpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9TVUNDRVNTJylcbiAgICAgICAgICAgICAgICAgICAgLnN1YnNjcmliZShyZXMgPT4gb3BlcmF0ZUNoYW5nZXMob3Blck1lc3NhZ2UsIE9wZXJhdGlvblN0YXRlLnN1Y2Nlc3MpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5zdGF0dXMgPT09IDQxMikge1xuICAgICAgICAgICAgICAgICAgICBmb3JrSm9pbih0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KCdCQVRDSC5ERUxFVEVEX0ZBSUxVUkUnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5nZXQoJ1JFUExJQ0FUSU9OLkZBSUxFRF9UT19ERUxFVEVfUE9MSUNZX0VOQUJMRUQnKSkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRlQ2hhbmdlcyhvcGVyTWVzc2FnZSwgT3BlcmF0aW9uU3RhdGUuZmFpbHVyZSwgcmVzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmdldCgnQkFUQ0guREVMRVRFRF9GQUlMVVJFJykuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRlQ2hhbmdlcyhvcGVyTWVzc2FnZSwgT3BlcmF0aW9uU3RhdGUuZmFpbHVyZSwgcmVzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxufVxuIl19