UNPKG

@hpe/angular-toolkit

Version:

Hewlett-Packard Enterprise : Angular toolkit for rapid project development

680 lines (668 loc) 70.7 kB
import { EventEmitter, Injectable, NgModule } from '@angular/core'; import { AppEvent } from '@hpe/angular-toolkit/model'; import { HttpClient } from '@angular/common/http'; import { DomSanitizer } from '@angular/platform-browser'; import { throwError } from 'rxjs'; import { catchError, map, finalize } from 'rxjs/operators'; import { MessageService } from 'primeng/components/common/messageservice'; import { CommonModule } from '@angular/common'; import { MessageService as MessageService$1 } from 'primeng/api'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= //=== //=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP. //=== //=== Use of this source code is governed by an MIT-style license that can be //=== found in the LICENSE file //============================================================================= class AbstractSubscriber { /** * @param {?} eventBusService */ constructor(eventBusService) { this.eventBusService = eventBusService; this.subscriptions = []; } /** * @return {?} */ ngOnDestroy() { this.subscriptions.forEach((s) => s.unsubscribe()); } /** * @param {?} eventCode * @param {?} handler * @return {?} */ subscribeToApp(eventCode, handler) { let /** @type {?} */ s = this.eventBusService.subscribeToApp(eventCode, handler); this.subscriptions.push(s); return s; } /** * @param {?} event * @return {?} */ emitToApp(event) { this.eventBusService.emitToApp(event); } /** * @param {?} handler * @return {?} */ subscribeToError(handler) { let /** @type {?} */ s = this.eventBusService.subscribeToError(handler); this.subscriptions.push(s); return s; } /** * @param {?} event * @return {?} */ emitToError(event) { this.eventBusService.emitToError(event); } } //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class EventBusService { constructor() { this.eventEmitterMap = new Map(); this.errorEvents = new EventEmitter(); } /** * @param {?} eventCode * @param {?} handler * @return {?} */ subscribeToApp(eventCode, handler) { let /** @type {?} */ emitter = this.eventEmitterMap.get(eventCode); if (emitter == null) { emitter = new EventEmitter(); this.eventEmitterMap.set(eventCode, emitter); } return emitter.subscribe(handler, null, null); } /** * @param {?} event * @return {?} */ emitToApp(event) { let /** @type {?} */ emitter = this.eventEmitterMap.get(event.code); if (emitter != null) { console.log("Emitting event : " + JSON.stringify(event)); emitter.emit(event); } else { console.log("WARNING : Emitting an event without any handler : " + JSON.stringify(event)); } //--- Emitting to global handlers emitter = this.eventEmitterMap.get(AppEvent.ANY); if (emitter != null) { emitter.emit(event); } } /** * @param {?} handler * @return {?} */ subscribeToError(handler) { return this.errorEvents.subscribe(handler, null, null); } /** * @param {?} event * @return {?} */ emitToError(event) { console.log("Emitting error event : " + JSON.stringify(event)); this.errorEvents.emit(event); } } EventBusService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ EventBusService.ctorParameters = () => []; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** @enum {number} */ const Status = { LOGIN: 0, LOADING: 1, READY: 2, }; Status[Status.LOGIN] = "LOGIN"; Status[Status.LOADING] = "LOADING"; Status[Status.READY] = "READY"; class ApplicationService extends AbstractSubscriber { /** * @param {?} eventBusService */ constructor(eventBusService) { super(eventBusService); this.status = Status.LOGIN; super.subscribeToApp(AppEvent.LOGIN_SUCCESS, (event) => this.onLoginSuccess(event)); super.subscribeToApp(AppEvent.LOGIN_FAILED, (event) => this.onLoginFailed(event)); super.subscribeToApp(AppEvent.LOGOUT_SUCCESS, (event) => this.onLogoutSuccess(event)); super.subscribeToApp(AppEvent.LOGOUT_FAILED, (event) => this.onLogoutFailed(event)); super.subscribeToApp(AppEvent.INVALID_TOKEN, (event) => this.onInvalidToken(event)); super.subscribeToApp(AppEvent.APPLICATION_READY, (event) => this.onApplicationReady(event)); } /** * @return {?} */ isStatusLogin() { return this.status == Status.LOGIN; } /** * @return {?} */ isStatusLoading() { return this.status == Status.LOADING; } /** * @return {?} */ isStatusReady() { return this.status == Status.READY; } /** * @param {?} event * @return {?} */ onLoginSuccess(event) { this.status = Status.LOADING; } /** * @param {?} event * @return {?} */ onLoginFailed(event) { this.status = Status.LOGIN; } /** * @param {?} event * @return {?} */ onLogoutSuccess(event) { this.status = Status.LOGIN; } /** * @param {?} event * @return {?} */ onLogoutFailed(event) { this.status = Status.LOGIN; } /** * @param {?} event * @return {?} */ onInvalidToken(event) { this.status = Status.LOGIN; } /** * @param {?} event * @return {?} */ onApplicationReady(event) { this.status = Status.READY; } } ApplicationService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ ApplicationService.ctorParameters = () => [ { type: EventBusService, }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class HttpService { /** * @param {?} httpClient * @param {?} eventBusService * @param {?} domSanitizer */ constructor(httpClient, eventBusService, domSanitizer) { this.httpClient = httpClient; this.eventBusService = eventBusService; this.domSanitizer = domSanitizer; this.openRequests = 0; } /** * @return {?} */ get loading() { return (this.openRequests > 0); } /** * @param {?} url * @param {?=} options * @return {?} */ getObject(url, options) { this.showLoader(); //--- "Pragma": "no-cache" for IE 11 let /** @type {?} */ header = { "Pragma": "no-cache", "Cache-Control": "no-cache", "Expires": "0" }; return this.httpClient.get(url, { params: options, headers: header }).pipe(catchError((error) => this.handleError(error)), finalize(() => this.hideLoader())); } /** * @param {?} url * @param {?=} options * @return {?} */ getBlob(url, options) { this.showLoader(); //--- Add timestamp to change static url to dynamic for IE 11 if (options != null) { options.ts = Date.now(); } return this.httpClient.get(url, { params: options, responseType: 'blob' }).pipe(map(e => this.getSanitizedUrl(URL.createObjectURL(e))), catchError((error) => this.handleError(error)), finalize(() => this.hideLoader())); } /** * @param {?} url * @param {?} object * @param {?=} options * @return {?} */ postObject(url, object, options) { this.showLoader(); return this.httpClient.post(url, object, options).pipe(catchError((error) => this.handleError(error)), finalize(() => this.hideLoader())); } /** * @param {?} url * @return {?} */ getSanitizedUrl(url) { return this.domSanitizer.bypassSecurityTrustResourceUrl(url); } /** * @param {?} response * @return {?} */ handleError(response) { console.log("Got the following HTTP error : " + JSON.stringify(response)); let /** @type {?} */ error; if (response.status == 422) { //--- Unprocessable entity error = response.error; } else { error = { code: response.status.toString(), error: response.error.toString() }; } this.eventBusService.emitToError(error); return throwError(error); } /** * @return {?} */ showLoader() { if (++this.openRequests == 1) { this.eventBusService.emitToApp(new AppEvent(AppEvent.SUBMIT_START)); } } /** * @return {?} */ hideLoader() { if (--this.openRequests == 0) { this.eventBusService.emitToApp(new AppEvent(AppEvent.SUBMIT_END)); } } } HttpService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ HttpService.ctorParameters = () => [ { type: HttpClient, }, { type: EventBusService, }, { type: DomSanitizer, }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class LabelService { /** * @param {?} httpService */ constructor(httpService) { this.httpService = httpService; this.languages = ["en", "it"]; this.labelSet = new Map(); this.language = "en"; //--- Load language files this.languages.forEach((language) => { this.initLanguage(language); }); } /** * @param {?} language * @return {?} */ setLanguage(language) { this.language = language; } /** * @param {?} entity * @param {?} code * @return {?} */ getLabel(entity, code) { if (code == null) { return null; } let /** @type {?} */ entitySet = this.getMapping(entity); if (entitySet == null) { return "?" + entity + "?"; } let /** @type {?} */ label = entitySet[code]; if (label == null) { return entity + ".?" + code + "?"; } return label; } /** * @param {?} entity * @return {?} */ getMapping(entity) { let /** @type {?} */ labels = this.labelSet.get(this.language); if (labels != null) { return labels.get(entity); } //--- Probably, we are still loading data return null; } /** * @param {?} language * @return {?} */ initLanguage(language) { this.loadLanguageFile(language, LabelService.TOOLKIT_FILE); this.loadLanguageFile(language, LabelService.APPLICATION_FILE); } /** * @param {?} language * @param {?} name * @return {?} */ loadLanguageFile(language, name) { let /** @type {?} */ file = name + "-" + language + ".json"; this.httpService.getObject("asset/lang/" + file) .subscribe(result => this.processFile(language, file, result), error => console.log("Cannot load labels file : " + file)); } /** * @param {?} language * @param {?} file * @param {?} data * @return {?} */ processFile(language, file, data) { console.log("Loaded labels file : " + file); let /** @type {?} */ labels = this.labelSet.get(language); if (labels == null) { labels = new Map(); this.labelSet.set(language, labels); } for (let /** @type {?} */ key in data) { labels.set(key, data[key]); } } } LabelService.TOOLKIT_FILE = "toolkit"; LabelService.APPLICATION_FILE = "application"; LabelService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ LabelService.ctorParameters = () => [ { type: HttpService, }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class NotificationService { /** * @param {?} messageService */ constructor(messageService) { this.messageService = messageService; } /** * @param {?} title * @param {?} message * @return {?} */ showSuccess(title, message) { this.show('success', title, message); } /** * @param {?} title * @param {?} message * @return {?} */ showInfo(title, message) { this.show('info', title, message); } /** * @param {?} title * @param {?} message * @return {?} */ showWarn(title, message) { this.show('warn', title, message); } /** * @param {?} title * @param {?} message * @return {?} */ showError(title, message) { this.show('error', title, message); } /** * @param {?} severity * @param {?} title * @param {?} message * @return {?} */ show(severity, title, message) { this.messageService.add({ severity: severity, summary: title, detail: message }); } } NotificationService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ NotificationService.ctorParameters = () => [ { type: MessageService, }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class SessionService extends AbstractSubscriber { /** * @param {?} eventBusService * @param {?} httpService */ constructor(eventBusService, httpService) { super(eventBusService); this.httpService = httpService; this.clearSession(); super.subscribeToApp(AppEvent.INVALID_TOKEN, event => this.onInvalidToken(event)); } /** * @param {?} cred * @return {?} */ login(cred) { console.log("SessionService.login : Logging in user='" + cred.username + "'"); //--- Loads user profile from server this.httpService.postObject("/api/session/login", cred) .subscribe(result => this.loginSuccess(result), error => this.loginError(error)); } /** * @return {?} */ logout() { console.log("SessionService.logout : Logging out user='" + (this.user || "???") + "'"); this.httpService.postObject("/api/session/logout", { token: this.token }) .subscribe(result => this.logoutSuccess(), error => this.logoutError(error)); } /** * @return {?} */ clearSession() { console.log("SessionService.clearSession: Resetting session..."); this.session = null; this.token = null; this.user = null; this.profile = null; this.permissions = new Map(); } /** * @return {?} */ get homePage() { return (this.profile) ? this.profile.homePage : null; } /** * @param {?} name * @return {?} */ hasPermission(name) { return (this.permissions.get(name)); } /** * @param {?} session * @return {?} */ loginSuccess(session) { this.session = session; this.token = session.token; this.user = session.user; this.profile = session.profile; this.permissions = this.setupPermissionMap(this.profile.permissions); super.emitToApp(new AppEvent(AppEvent.LOGIN_SUCCESS, session)); console.log("Login successful for user=" + this.user.username); } /** * @param {?} response * @return {?} */ loginError(response) { super.emitToApp(new AppEvent(AppEvent.LOGIN_FAILED, response)); } /** * @return {?} */ logoutSuccess() { let /** @type {?} */ username = this.user.username; this.clearSession(); super.emitToApp(new AppEvent(AppEvent.LOGOUT_SUCCESS, username)); console.log("Logout successful for user=" + username); } /** * @param {?} response * @return {?} */ logoutError(response) { this.clearSession(); super.emitToApp(new AppEvent(AppEvent.LOGOUT_FAILED)); } /** * @param {?} permissions * @return {?} */ setupPermissionMap(permissions) { let /** @type {?} */ map$$1 = new Map(); permissions.forEach((p) => map$$1.set(p, true)); return map$$1; } /** * @param {?} event * @return {?} */ onInvalidToken(event) { this.clearSession(); } } SessionService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ SessionService.ctorParameters = () => [ { type: EventBusService, }, { type: HttpService, }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= class HpeServiceModule { } HpeServiceModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], declarations: [], exports: [], providers: [ ApplicationService, EventBusService, HttpService, LabelService, NotificationService, SessionService, MessageService$1 ], },] }, ]; //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ //============================================================================= /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ export { HpeServiceModule, AbstractSubscriber, ApplicationService, EventBusService, HttpService, LabelService, NotificationService, SessionService }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHBlLWFuZ3VsYXItdG9vbGtpdC1zZXJ2aWNlLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL2Fic3RyYWN0LXN1YnNjcmliZXIudHMiLCJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L3NlcnZpY2UvZXZlbnRidXMtc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9hcHBsaWNhdGlvbi1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL2h0dHAtc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9sYWJlbC1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL25vdGlmaWNhdGlvbi1zZXJ2aWNlLnRzIiwibmc6Ly9AaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlL3Nlc3Npb24tc2VydmljZS50cyIsIm5nOi8vQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZS9tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge09uRGVzdHJveX0gICAgZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge0V2ZW50SGFuZGxlciwgRXJyb3JIYW5kbGVyLCBBcHBFdmVudCwgRXJyb3JFdmVudH0gZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7RXZlbnRCdXNTZXJ2aWNlfSBmcm9tIFwiLi9ldmVudGJ1cy1zZXJ2aWNlXCI7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGNsYXNzIEFic3RyYWN0U3Vic2NyaWJlciBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIENvbnN0cnVjdG9yXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgZXZlbnRCdXNTZXJ2aWNlIDogRXZlbnRCdXNTZXJ2aWNlKSB7fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBMaWZlY3ljbGUgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goIChzIDogU3Vic2NyaXB0aW9uKSA9PiBzLnVuc3Vic2NyaWJlKCkpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEFQSSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByb3RlY3RlZCBzdWJzY3JpYmVUb0FwcChldmVudENvZGUgOiBzdHJpbmcsIGhhbmRsZXIgOiBFdmVudEhhbmRsZXIpIDogU3Vic2NyaXB0aW9uIHtcblxuXHRcdGxldCBzIDogU3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudEJ1c1NlcnZpY2Uuc3Vic2NyaWJlVG9BcHAoZXZlbnRDb2RlLCBoYW5kbGVyKTtcblx0XHR0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzKTtcblxuXHRcdHJldHVybiBzO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJvdGVjdGVkIGVtaXRUb0FwcChldmVudCA6IEFwcEV2ZW50KSA6IHZvaWQge1xuXHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0FwcChldmVudCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcm90ZWN0ZWQgc3Vic2NyaWJlVG9FcnJvcihoYW5kbGVyIDogRXJyb3JIYW5kbGVyKSA6IFN1YnNjcmlwdGlvbiB7XG5cblx0XHRsZXQgcyA6IFN1YnNjcmlwdGlvbiA9IHRoaXMuZXZlbnRCdXNTZXJ2aWNlLnN1YnNjcmliZVRvRXJyb3IoaGFuZGxlcik7XG5cdFx0dGhpcy5zdWJzY3JpcHRpb25zLnB1c2gocyk7XG5cblx0XHRyZXR1cm4gcztcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByb3RlY3RlZCBlbWl0VG9FcnJvcihldmVudCA6IEVycm9yRXZlbnQpIDogdm9pZCB7XG5cdFx0dGhpcy5ldmVudEJ1c1NlcnZpY2UuZW1pdFRvRXJyb3IoZXZlbnQpO1xuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtFdmVudEVtaXR0ZXIsIEluamVjdGFibGV9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tIFwicnhqc1wiO1xuXG5pbXBvcnQge0FwcEV2ZW50LCBFcnJvckV2ZW50LCBFcnJvckhhbmRsZXIsIEV2ZW50SGFuZGxlcn0gZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEV2ZW50QnVzU2VydmljZSB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGV2ZW50RW1pdHRlck1hcCA6IE1hcDxzdHJpbmcsIEV2ZW50RW1pdHRlcjxBcHBFdmVudD4+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIGVycm9yRXZlbnRzICAgICA6IEV2ZW50RW1pdHRlcjxFcnJvckV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHN1YnNjcmliZVRvQXBwKGV2ZW50Q29kZSA6IHN0cmluZywgaGFuZGxlciA6IEV2ZW50SGFuZGxlcikgOiBTdWJzY3JpcHRpb24ge1xuXG5cdFx0bGV0IGVtaXR0ZXIgOiBFdmVudEVtaXR0ZXI8QXBwRXZlbnQ+ID0gdGhpcy5ldmVudEVtaXR0ZXJNYXAuZ2V0KGV2ZW50Q29kZSk7XG5cblx0XHRpZiAoZW1pdHRlciA9PSBudWxsKSB7XG5cdFx0XHRlbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRcdFx0dGhpcy5ldmVudEVtaXR0ZXJNYXAuc2V0KGV2ZW50Q29kZSwgZW1pdHRlcik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVtaXR0ZXIuc3Vic2NyaWJlKGhhbmRsZXIsIG51bGwsIG51bGwpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIGVtaXRUb0FwcChldmVudCA6IEFwcEV2ZW50KSA6IHZvaWQge1xuXG5cdFx0bGV0IGVtaXR0ZXIgPSB0aGlzLmV2ZW50RW1pdHRlck1hcC5nZXQoZXZlbnQuY29kZSk7XG5cblx0XHRpZiAoZW1pdHRlciAhPSBudWxsKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkVtaXR0aW5nIGV2ZW50IDogXCIrIEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cdFx0XHRlbWl0dGVyLmVtaXQoZXZlbnQpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGNvbnNvbGUubG9nKFwiV0FSTklORyA6IEVtaXR0aW5nIGFuIGV2ZW50IHdpdGhvdXQgYW55IGhhbmRsZXIgOiBcIisgSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblx0XHR9XG5cblx0XHQvLy0tLSBFbWl0dGluZyB0byBnbG9iYWwgaGFuZGxlcnNcblxuXHRcdGVtaXR0ZXIgPSB0aGlzLmV2ZW50RW1pdHRlck1hcC5nZXQoQXBwRXZlbnQuQU5ZKTtcblxuXHRcdGlmIChlbWl0dGVyICE9IG51bGwpIHtcblx0XHRcdGVtaXR0ZXIuZW1pdChldmVudCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHN1YnNjcmliZVRvRXJyb3IoaGFuZGxlciA6IEVycm9ySGFuZGxlcikgOiBTdWJzY3JpcHRpb24ge1xuXHRcdHJldHVybiB0aGlzLmVycm9yRXZlbnRzLnN1YnNjcmliZShoYW5kbGVyLCBudWxsLCBudWxsKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBlbWl0VG9FcnJvcihldmVudCA6IEVycm9yRXZlbnQpIDogdm9pZCB7XG5cdFx0Y29uc29sZS5sb2coXCJFbWl0dGluZyBlcnJvciBldmVudCA6IFwiKyBKU09OLnN0cmluZ2lmeShldmVudCkpO1xuXHRcdHRoaXMuZXJyb3JFdmVudHMuZW1pdChldmVudCk7XG5cdH1cbn1cblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge0luamVjdGFibGV9ICAgICAgICAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0FwcEV2ZW50fSAgICAgICAgICAgZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7QWJzdHJhY3RTdWJzY3JpYmVyfSBmcm9tIFwiLi9hYnN0cmFjdC1zdWJzY3JpYmVyXCI7XG5pbXBvcnQge0V2ZW50QnVzU2VydmljZX0gICAgZnJvbSBcIi4vZXZlbnRidXMtc2VydmljZVwiO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbmVudW0gU3RhdHVzIHtcblx0TE9HSU4sXG5cdExPQURJTkcsXG5cdFJFQURZXG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uU2VydmljZSBleHRlbmRzIEFic3RyYWN0U3Vic2NyaWJlciB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIHN0YXR1cyA6IFN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IoZXZlbnRCdXNTZXJ2aWNlOiBFdmVudEJ1c1NlcnZpY2UpIHtcblxuXHRcdHN1cGVyKGV2ZW50QnVzU2VydmljZSk7XG5cblx0XHRzdXBlci5zdWJzY3JpYmVUb0FwcChBcHBFdmVudC5MT0dJTl9TVUNDRVNTLCAgICAgKGV2ZW50IDogQXBwRXZlbnQpID0+IHRoaXMub25Mb2dpblN1Y2Nlc3MgICAgKGV2ZW50KSk7XG5cdFx0c3VwZXIuc3Vic2NyaWJlVG9BcHAoQXBwRXZlbnQuTE9HSU5fRkFJTEVELCAgICAgIChldmVudCA6IEFwcEV2ZW50KSA9PiB0aGlzLm9uTG9naW5GYWlsZWQgICAgIChldmVudCkpO1xuXHRcdHN1cGVyLnN1YnNjcmliZVRvQXBwKEFwcEV2ZW50LkxPR09VVF9TVUNDRVNTLCAgICAoZXZlbnQgOiBBcHBFdmVudCkgPT4gdGhpcy5vbkxvZ291dFN1Y2Nlc3MgICAoZXZlbnQpKTtcblx0XHRzdXBlci5zdWJzY3JpYmVUb0FwcChBcHBFdmVudC5MT0dPVVRfRkFJTEVELCAgICAgKGV2ZW50IDogQXBwRXZlbnQpID0+IHRoaXMub25Mb2dvdXRGYWlsZWQgICAgKGV2ZW50KSk7XG5cdFx0c3VwZXIuc3Vic2NyaWJlVG9BcHAoQXBwRXZlbnQuSU5WQUxJRF9UT0tFTiwgICAgIChldmVudCA6IEFwcEV2ZW50KSA9PiB0aGlzLm9uSW52YWxpZFRva2VuICAgIChldmVudCkpO1xuXHRcdHN1cGVyLnN1YnNjcmliZVRvQXBwKEFwcEV2ZW50LkFQUExJQ0FUSU9OX1JFQURZLCAoZXZlbnQgOiBBcHBFdmVudCkgPT4gdGhpcy5vbkFwcGxpY2F0aW9uUmVhZHkoZXZlbnQpKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBBUEkgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgaXNTdGF0dXNMb2dpbigpIDogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuc3RhdHVzID09IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBpc1N0YXR1c0xvYWRpbmcoKSA6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLnN0YXR1cyA9PSBTdGF0dXMuTE9BRElORztcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBpc1N0YXR1c1JlYWR5KCkgOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5zdGF0dXMgPT0gU3RhdHVzLlJFQURZO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEV2ZW50c1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIG9uTG9naW5TdWNjZXNzKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0FESU5HO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBvbkxvZ2luRmFpbGVkKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb25Mb2dvdXRTdWNjZXNzKGV2ZW50IDogQXBwRXZlbnQpIHtcblx0XHR0aGlzLnN0YXR1cyA9IFN0YXR1cy5MT0dJTjtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb25Mb2dvdXRGYWlsZWQoZXZlbnQgOiBBcHBFdmVudCkge1xuXHRcdHRoaXMuc3RhdHVzID0gU3RhdHVzLkxPR0lOO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBvbkludmFsaWRUb2tlbihldmVudCA6IEFwcEV2ZW50KSB7XG5cdFx0dGhpcy5zdGF0dXMgPSBTdGF0dXMuTE9HSU47XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIG9uQXBwbGljYXRpb25SZWFkeShldmVudCA6IEFwcEV2ZW50KSB7XG5cdFx0dGhpcy5zdGF0dXMgPSBTdGF0dXMuUkVBRFk7XG5cdH1cbn1cblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5pbXBvcnQge0luamVjdGFibGV9ICAgZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7SHR0cENsaWVudH0gICBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7RG9tU2FuaXRpemVyfSBmcm9tIFwiQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3NlclwiO1xuaW1wb3J0IHtTYWZlVXJsfSAgICAgIGZyb20gXCJAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyL3NyYy9zZWN1cml0eS9kb21fc2FuaXRpemF0aW9uX3NlcnZpY2VcIjtcblxuaW1wb3J0IHtPYnNlcnZhYmxlLCB0aHJvd0Vycm9yfSAgICBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHtjYXRjaEVycm9yLCBtYXAsIGZpbmFsaXplfSBmcm9tIFwicnhqcy9vcGVyYXRvcnNcIjtcbmltcG9ydCB7QXBwRXZlbnQsIEVycm9yRXZlbnQgfSAgICAgZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L21vZGVsXCI7XG5cbmltcG9ydCB7RXZlbnRCdXNTZXJ2aWNlfSAgICAgICAgICAgZnJvbSBcIi4vZXZlbnRidXMtc2VydmljZVwiXG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEh0dHBTZXJ2aWNlIHtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gVmFyaWFibGVzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgb3BlblJlcXVlc3RzIDogbnVtYmVyID0gMDtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSBodHRwQ2xpZW50ICAgICAgOiBIdHRwQ2xpZW50LFxuXHRcdFx0XHRwcml2YXRlIGV2ZW50QnVzU2VydmljZSA6IEV2ZW50QnVzU2VydmljZSxcblx0XHRcdFx0cHJpdmF0ZSBkb21TYW5pdGl6ZXIgICAgOiBEb21TYW5pdGl6ZXIgKSB7fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBBUEkgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0IGxvYWRpbmcoKSA6IGJvb2xlYW4ge1xuXHRcdHJldHVybiAodGhpcy5vcGVuUmVxdWVzdHMgPiAwKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBnZXRPYmplY3QodXJsIDogc3RyaW5nLCBvcHRpb25zPyA6IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG5cblx0XHR0aGlzLnNob3dMb2FkZXIoKTtcblxuXHRcdC8vLS0tIFwiUHJhZ21hXCI6IFwibm8tY2FjaGVcIiBmb3IgSUUgMTFcblxuXHRcdGxldCBoZWFkZXIgPSB7XG5cdFx0XHRcIlByYWdtYVwiICAgICAgICA6IFwibm8tY2FjaGVcIixcblx0XHRcdFwiQ2FjaGUtQ29udHJvbFwiIDogXCJuby1jYWNoZVwiLFxuXHRcdFx0XCJFeHBpcmVzXCIgICAgICAgOiBcIjBcIlxuXHRcdH07XG5cblx0XHRyZXR1cm4gdGhpcy5odHRwQ2xpZW50LmdldCh1cmwsIHsgcGFyYW1zOiBvcHRpb25zLCBoZWFkZXJzIDogaGVhZGVyIH0pLnBpcGUoXG5cdFx0XHRjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnJvcikpLFxuXHRcdFx0ZmluYWxpemUgICgoKSAgICAgID0+IHRoaXMuaGlkZUxvYWRlcigpKVxuXHRcdCk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0QmxvYih1cmwgOiBzdHJpbmcsIG9wdGlvbnM/IDogYW55KTogT2JzZXJ2YWJsZTxhbnk+IHtcblxuXHRcdHRoaXMuc2hvd0xvYWRlcigpO1xuXG5cdFx0Ly8tLS0gQWRkIHRpbWVzdGFtcCB0byBjaGFuZ2Ugc3RhdGljIHVybCB0byBkeW5hbWljIGZvciBJRSAxMVxuXG5cdFx0aWYgKG9wdGlvbnMgIT0gbnVsbCkge1xuXHRcdFx0b3B0aW9ucy50cyA9IERhdGUubm93KCk7XG5cdFx0fVxuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQuZ2V0KHVybCwgeyBwYXJhbXM6IG9wdGlvbnMsIHJlc3BvbnNlVHlwZSA6ICdibG9iJ30pLnBpcGUoXG5cdFx0XHRtYXAoZSA9PiB0aGlzLmdldFNhbml0aXplZFVybChVUkwuY3JlYXRlT2JqZWN0VVJMKGUpKSksXG5cdFx0XHRjYXRjaEVycm9yKChlcnJvcikgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnJvcikpLFxuXHRcdFx0ZmluYWxpemUoKCkgPT4gdGhpcy5oaWRlTG9hZGVyKCkpXG5cdFx0KTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBwb3N0T2JqZWN0KHVybDogc3RyaW5nLCBvYmplY3Q6IGFueSwgb3B0aW9ucz86IGFueSk6IE9ic2VydmFibGU8YW55PiB7XG5cbiAgICAgICAgdGhpcy5zaG93TG9hZGVyKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5wb3N0ICh1cmwsIG9iamVjdCwgb3B0aW9ucykucGlwZShcblx0XHRcdGNhdGNoRXJyb3IoKGVycm9yKSA9PiB0aGlzLmhhbmRsZUVycm9yKGVycm9yKSksXG5cdFx0XHRmaW5hbGl6ZSAgKCgpICAgICAgPT4gdGhpcy5oaWRlTG9hZGVyKCkpXG5cdFx0KTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBnZXRTYW5pdGl6ZWRVcmwodXJsIDogc3RyaW5nKTogU2FmZVVybCB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybCh1cmwpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFByaXZhdGUgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGhhbmRsZUVycm9yKHJlc3BvbnNlIDogYW55KSA6IE9ic2VydmFibGU8YW55PiB7XG5cblx0XHRjb25zb2xlLmxvZyhcIkdvdCB0aGUgZm9sbG93aW5nIEhUVFAgZXJyb3IgOiBcIiArIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG5cblx0XHRsZXQgZXJyb3IgOiBFcnJvckV2ZW50O1xuXG5cdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PSA0MjIpIHtcblx0XHRcdC8vLS0tIFVucHJvY2Vzc2FibGUgZW50aXR5XG5cdFx0XHRlcnJvciA9IHJlc3BvbnNlLmVycm9yO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGVycm9yID0ge1xuXHRcdFx0XHRjb2RlIDogcmVzcG9uc2Uuc3RhdHVzLnRvU3RyaW5nKCksXG5cdFx0XHRcdGVycm9yOiByZXNwb25zZS5lcnJvci50b1N0cmluZygpXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0Vycm9yKGVycm9yKTtcblxuXHRcdHJldHVybiB0aHJvd0Vycm9yKGVycm9yKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgc2hvd0xvYWRlcigpOiB2b2lkIHtcblxuXHRcdGlmICgrK3RoaXMub3BlblJlcXVlc3RzID09IDEpIHtcblx0XHRcdHRoaXMuZXZlbnRCdXNTZXJ2aWNlLmVtaXRUb0FwcChuZXcgQXBwRXZlbnQoQXBwRXZlbnQuU1VCTUlUX1NUQVJUKSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBoaWRlTG9hZGVyKCk6IHZvaWQge1xuXG5cdFx0aWYgKC0tdGhpcy5vcGVuUmVxdWVzdHMgPT0gMCkge1xuXHRcdFx0dGhpcy5ldmVudEJ1c1NlcnZpY2UuZW1pdFRvQXBwKG5ldyBBcHBFdmVudChBcHBFdmVudC5TVUJNSVRfRU5EKSk7XG5cdFx0fVxuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtJbmplY3RhYmxlfSAgZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7SHR0cFNlcnZpY2V9IGZyb20gXCIuL2h0dHAtc2VydmljZVwiO1xuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBMYWJlbFNlcnZpY2Uge1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBWYXJpYWJsZXNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHJpdmF0ZSBzdGF0aWMgVE9PTEtJVF9GSUxFICAgICA6IHN0cmluZyA9IFwidG9vbGtpdFwiO1xuXHRwcml2YXRlIHN0YXRpYyBBUFBMSUNBVElPTl9GSUxFIDogc3RyaW5nID0gXCJhcHBsaWNhdGlvblwiO1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgbGFiZWxTZXQgOiBNYXA8U3RyaW5nLCBNYXA8c3RyaW5nLCBhbnk+Pjtcblx0cHJpdmF0ZSBsYW5ndWFnZSA6IHN0cmluZztcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGxhbmd1YWdlcyA6IHN0cmluZ1tdID0gWyBcImVuXCIsIFwiaXRcIiBdO1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBDb25zdHJ1Y3RvclxuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHBTZXJ2aWNlIDogSHR0cFNlcnZpY2UpIHtcblxuXHRcdHRoaXMubGFiZWxTZXQgPSBuZXcgTWFwKCk7XG5cdFx0dGhpcy5sYW5ndWFnZSA9IFwiZW5cIjtcblxuXHRcdC8vLS0tIExvYWQgbGFuZ3VhZ2UgZmlsZXNcblxuXHRcdHRoaXMubGFuZ3VhZ2VzLmZvckVhY2goIChsYW5ndWFnZSA6IHN0cmluZykgPT4ge1xuXHRcdFx0dGhpcy5pbml0TGFuZ3VhZ2UobGFuZ3VhZ2UpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEFQSSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBzZXRMYW5ndWFnZShsYW5ndWFnZSA6IHN0cmluZykgOiB2b2lkIHtcblx0XHR0aGlzLmxhbmd1YWdlID0gbGFuZ3VhZ2U7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0TGFiZWwoZW50aXR5IDogc3RyaW5nLCBjb2RlIDogc3RyaW5nKSA6IGFueSB7XG5cblx0XHRpZiAoY29kZSA9PSBudWxsKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cblx0XHRsZXQgZW50aXR5U2V0ID0gdGhpcy5nZXRNYXBwaW5nKGVudGl0eSk7XG5cblx0XHRpZiAoZW50aXR5U2V0ID09IG51bGwpIHtcblx0XHRcdHJldHVybiBcIj9cIitlbnRpdHkrXCI/XCI7XG5cdFx0fVxuXG5cdFx0bGV0IGxhYmVsID0gZW50aXR5U2V0W2NvZGVdO1xuXG5cdFx0aWYgKGxhYmVsID09IG51bGwpIHtcblx0XHRcdHJldHVybiBlbnRpdHkrXCIuP1wiKyBjb2RlICtcIj9cIjtcblx0XHR9XG5cblx0XHRyZXR1cm4gbGFiZWw7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgZ2V0TWFwcGluZyhlbnRpdHkgOiBzdHJpbmcpIDogT2JqZWN0IHtcblxuXHRcdGxldCBsYWJlbHMgPSB0aGlzLmxhYmVsU2V0LmdldCh0aGlzLmxhbmd1YWdlKTtcblxuXHRcdGlmIChsYWJlbHMgIT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIGxhYmVscy5nZXQoZW50aXR5KTtcblx0XHR9XG5cblx0XHQvLy0tLSBQcm9iYWJseSwgd2UgYXJlIHN0aWxsIGxvYWRpbmcgZGF0YVxuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFByaXZhdGUgbWV0aG9kc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGluaXRMYW5ndWFnZShsYW5ndWFnZSA6IHN0cmluZykgOiB2b2lkIHtcblxuXHRcdHRoaXMubG9hZExhbmd1YWdlRmlsZShsYW5ndWFnZSwgTGFiZWxTZXJ2aWNlLlRPT0xLSVRfRklMRSk7XG5cdFx0dGhpcy5sb2FkTGFuZ3VhZ2VGaWxlKGxhbmd1YWdlLCBMYWJlbFNlcnZpY2UuQVBQTElDQVRJT05fRklMRSk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGxvYWRMYW5ndWFnZUZpbGUobGFuZ3VhZ2UgOiBzdHJpbmcsIG5hbWUgOiBzdHJpbmcpIHtcblxuXHRcdGxldCBmaWxlIDogc3RyaW5nID0gbmFtZSArXCItXCIrIGxhbmd1YWdlICtcIi5qc29uXCI7XG5cblx0XHR0aGlzLmh0dHBTZXJ2aWNlLmdldE9iamVjdChcImFzc2V0L2xhbmcvXCIrIGZpbGUpXG5cdFx0XHRcdFx0XHQuc3Vic2NyaWJlKFx0cmVzdWx0ID0+IHRoaXMucHJvY2Vzc0ZpbGUobGFuZ3VhZ2UsIGZpbGUsIHJlc3VsdCksXG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvciA9PiBjb25zb2xlLmxvZyhcIkNhbm5vdCBsb2FkIGxhYmVscyBmaWxlIDogXCIrIGZpbGUpKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgcHJvY2Vzc0ZpbGUobGFuZ3VhZ2UgOiBzdHJpbmcsIGZpbGU6c3RyaW5nLCBkYXRhIDogT2JqZWN0KSA6IHZvaWQge1xuXG5cdFx0Y29uc29sZS5sb2coXCJMb2FkZWQgbGFiZWxzIGZpbGUgOiBcIisgZmlsZSk7XG5cblx0XHRsZXQgbGFiZWxzID0gdGhpcy5sYWJlbFNldC5nZXQobGFuZ3VhZ2UpO1xuXG5cdFx0aWYgKGxhYmVscyA9PSBudWxsKSB7XG5cdFx0XHRsYWJlbHMgPSBuZXcgTWFwKCk7XG5cdFx0XHR0aGlzLmxhYmVsU2V0LnNldChsYW5ndWFnZSwgbGFiZWxzKTtcblx0XHR9XG5cblx0XHRmb3IgKGxldCBrZXkgaW4gZGF0YSkge1xuXHRcdFx0bGFiZWxzLnNldChrZXksIGRhdGFba2V5XSk7XG5cdFx0fVxuXHR9XG59XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIsIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtNZXNzYWdlU2VydmljZX0gZnJvbSAncHJpbWVuZy9jb21wb25lbnRzL2NvbW1vbi9tZXNzYWdlc2VydmljZSc7XG5cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvblNlcnZpY2Uge1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLy0tLVxuXHQvLy0tLSBDb25zdHJ1Y3RvclxuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIG1lc3NhZ2VTZXJ2aWNlOk1lc3NhZ2VTZXJ2aWNlKSB7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQVBJIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHNob3dTdWNjZXNzKHRpdGxlIDogc3RyaW5nLCBtZXNzYWdlIDogc3RyaW5nKSA6IHZvaWQge1xuXHRcdHRoaXMuc2hvdygnc3VjY2VzcycsIHRpdGxlLCBtZXNzYWdlKTtcblx0fVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBzaG93SW5mbyh0aXRsZSA6IHN0cmluZywgbWVzc2FnZSA6IHN0cmluZykgOiB2b2lkIHtcblx0XHR0aGlzLnNob3coJ2luZm8nLCB0aXRsZSwgbWVzc2FnZSk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgc2hvd1dhcm4odGl0bGUgOiBzdHJpbmcsIG1lc3NhZ2UgOiBzdHJpbmcpIDogdm9pZCB7XG5cdFx0dGhpcy5zaG93KCd3YXJuJywgdGl0bGUsIG1lc3NhZ2UpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHNob3dFcnJvcih0aXRsZSA6IHN0cmluZywgbWVzc2FnZSA6IHN0cmluZykgOiB2b2lkIHtcblx0XHR0aGlzLnNob3coJ2Vycm9yJywgdGl0bGUsIG1lc3NhZ2UpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIHNob3coc2V2ZXJpdHkgOiBzdHJpbmcsIHRpdGxlIDogc3RyaW5nLCBtZXNzYWdlIDogc3RyaW5nKSA6IHZvaWQge1xuXG5cdFx0dGhpcy5tZXNzYWdlU2VydmljZS5hZGQoIHtcblx0XHRcdHNldmVyaXR5OiBzZXZlcml0eSxcblx0XHRcdHN1bW1hcnkgOiB0aXRsZSxcblx0XHRcdGRldGFpbCAgOiBtZXNzYWdlXG5cdFx0fSk7XG5cdH1cbn1cblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwiLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy89PT1cbi8vPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbi8vPT09XG4vLz09PSBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuLy89PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuLy89PT1cbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtBcHBFdmVudH0gICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtDcmVkZW50aWFsc30gICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtQcm9maWxlfSAgICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtTZXNzaW9ufSAgICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtTZXNzaW9uVXNlcn0gICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuXG5pbXBvcnQge0Fic3RyYWN0U3Vic2NyaWJlcn0gZnJvbSBcIi4vYWJzdHJhY3Qtc3Vic2NyaWJlclwiO1xuaW1wb3J0IHtFdmVudEJ1c1NlcnZpY2V9ICAgIGZyb20gXCIuL2V2ZW50YnVzLXNlcnZpY2VcIjtcbmltcG9ydCB7SHR0cFNlcnZpY2V9ICAgICAgICBmcm9tIFwiLi9odHRwLXNlcnZpY2VcIjtcblxuXG4vLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBTZXNzaW9uU2VydmljZSBleHRlbmRzIEFic3RyYWN0U3Vic2NyaWJlciB7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIFZhcmlhYmxlc1xuXHQvLy0tLVxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwdWJsaWMgc2Vzc2lvbiAgICAgOiBTZXNzaW9uO1xuXHRwdWJsaWMgdG9rZW4gICAgICAgOiBzdHJpbmc7XG5cdHB1YmxpYyB1c2VyICAgICAgICA6IFNlc3Npb25Vc2VyO1xuXHRwdWJsaWMgcHJvZmlsZSAgICAgOiBQcm9maWxlO1xuXHRwdWJsaWMgcGVybWlzc2lvbnMgOiBNYXA8c3RyaW5nLCBib29sZWFuPjtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gQ29uc3RydWN0b3Jcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Y29uc3RydWN0b3IoZXZlbnRCdXNTZXJ2aWNlOiBFdmVudEJ1c1NlcnZpY2UsIHByaXZhdGUgaHR0cFNlcnZpY2UgOiBIdHRwU2VydmljZSkge1xuXG5cdFx0c3VwZXIoZXZlbnRCdXNTZXJ2aWNlKTtcblx0XHR0aGlzLmNsZWFyU2Vzc2lvbigpO1xuXG5cdFx0c3VwZXIuc3Vic2NyaWJlVG9BcHAoQXBwRXZlbnQuSU5WQUxJRF9UT0tFTiwgZXZlbnQgPT4gdGhpcy5vbkludmFsaWRUb2tlbihldmVudCkpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIEFQSSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBsb2dpbihjcmVkIDogQ3JlZGVudGlhbHMpIDogdm9pZCB7XG5cblx0XHRjb25zb2xlLmxvZyhcIlNlc3Npb25TZXJ2aWNlLmxvZ2luIDogTG9nZ2luZyBpbiB1c2VyPSdcIiArIGNyZWQudXNlcm5hbWUgKyBcIidcIik7XG5cblx0XHQvLy0t