UNPKG

@sam17896/ngx-speech-recognition

Version:

Angular 5+ speech recognition service (based on browser implementation such as Chrome).

504 lines 48.4 kB
/** * @fileoverview added by tsickle * Generated from: lib/service/speech-recognition.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable, ApplicationRef, Inject, Optional, } from '@angular/core'; import { SpeechRecognitionGrammars, SpeechRecognitionLang, SpeechRecognitionContinuous, SpeechRecognitionInterimResults, SpeechRecognitionMaxAlternatives, SpeechRecognitionServiceUri, SpeechRecognitionAudiostartHandler, SpeechRecognitionSoundstartHandler, SpeechRecognitionSpeechstartHandler, SpeechRecognitionSpeechendHandler, SpeechRecognitionSoundendHandler, SpeechRecognitionAudioendHandler, SpeechRecognitionResultHandler, SpeechRecognitionNomatchHandler, SpeechRecognitionErrorHandler, SpeechRecognitionStartHandler, SpeechRecognitionEndHandler, } from './speech-recognition.token'; import { SpeechRecognitionCommon, } from './speech-recognition.common'; // @dynamic /** * * @see https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition * @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API */ export class SpeechRecognitionService extends SpeechRecognitionCommon { /** * @param {?} ref * @param {?} grammars * @param {?} lang * @param {?} continuous * @param {?} interimResults * @param {?} maxAlternatives * @param {?} serviceURI * @param {?} audiostartHandler * @param {?} soundstartHandler * @param {?} speechstartHandler * @param {?} speechendHandler * @param {?} soundendHandler * @param {?} audioendHandler * @param {?} resultHandler * @param {?} nomatchHandler * @param {?} errorHandler * @param {?} startHandler * @param {?} endHandler */ constructor(ref, grammars, lang, continuous, interimResults, maxAlternatives, serviceURI, audiostartHandler, soundstartHandler, speechstartHandler, speechendHandler, soundendHandler, audioendHandler, resultHandler, nomatchHandler, errorHandler, startHandler, endHandler) { super(grammars, lang, continuous, interimResults, maxAlternatives, serviceURI); this.ref = ref; this.audiostartHandler = audiostartHandler; this.soundstartHandler = soundstartHandler; this.speechstartHandler = speechstartHandler; this.speechendHandler = speechendHandler; this.soundendHandler = soundendHandler; this.audioendHandler = audioendHandler; this.resultHandler = resultHandler; this.nomatchHandler = nomatchHandler; this.errorHandler = errorHandler; this.startHandler = startHandler; this.endHandler = endHandler; this.initHandlers(); this.initInternal(); } /** * @private * @return {?} */ initHandlers() { /** @type {?} */ const _ = (/** * @return {?} */ () => { }); if (!this.audiostartHandler) { this.audiostartHandler = _; } if (!this.soundstartHandler) { this.soundstartHandler = _; } if (!this.speechstartHandler) { this.speechstartHandler = _; } if (!this.speechendHandler) { this.speechendHandler = _; } if (!this.soundendHandler) { this.soundendHandler = _; } if (!this.audioendHandler) { this.audioendHandler = _; } if (!this.resultHandler) { this.resultHandler = _; } if (!this.nomatchHandler) { this.nomatchHandler = _; } if (!this.errorHandler) { this.errorHandler = _; } if (!this.startHandler) { this.startHandler = _; } if (!this.endHandler) { this.endHandler = _; } } /** * @private * @return {?} */ initInternal() { // see setter methods this.grammars = this._grammars; this.lang = this._lang; this.continuous = this._continuous; this.interimResults = this._interimResults; this.maxAlternatives = this._maxAlternatives; this.serviceURI = this._serviceURI; this.internal.onaudiostart = (/** * @param {?} e * @return {?} */ (e) => { this.audiostartHandler(e); this.ref.tick(); }); this.internal.onsoundstart = (/** * @param {?} e * @return {?} */ (e) => { this.soundstartHandler(e); this.ref.tick(); }); this.internal.onspeechstart = (/** * @param {?} e * @return {?} */ (e) => { this.speechstartHandler(e); this.ref.tick(); }); this.internal.onspeechend = (/** * @param {?} e * @return {?} */ (e) => { this.speechendHandler(e); this.ref.tick(); }); this.internal.onsoundend = (/** * @param {?} e * @return {?} */ (e) => { this.soundendHandler(e); this.ref.tick(); }); this.internal.onaudioend = (/** * @param {?} e * @return {?} */ (e) => { this.audioendHandler(e); this.ref.tick(); }); this.internal.onresult = (/** * @param {?} e * @return {?} */ (e) => { this.resultHandler(e); this.ref.tick(); }); this.internal.onnomatch = (/** * @param {?} e * @return {?} */ (e) => { this.nomatchHandler(e); this.ref.tick(); }); this.internal.onerror = (/** * @param {?} e * @return {?} */ (e) => { this.errorHandler(e); this.ref.tick(); }); this.internal.onstart = (/** * @param {?} e * @return {?} */ (e) => { this.startHandler(e); this.ref.tick(); }); this.internal.onend = (/** * @param {?} e * @return {?} */ (e) => { this.endHandler(e); this.ref.tick(); }); } // The onaudiostart property of the SpeechRecognition interface // represents an event handler that will run // when the user agent has started to capture audio // (when the audiostart event fires.) // // SpeechRecognitionインターフェイスのonaudiostartプロパティは、 // ユーザーエージェントがオーディオのキャプチャを開始したとき // (audiostartイベントが発生したとき)に実行されるイベントハンドラを // 表します。 /** * @param {?} handler * @return {?} */ set onaudiostart(handler) { this.audiostartHandler = handler; } // The onsoundstart property of the SpeechRecognition interface represents // an event handler that will run when any sound // — recognisable speech or not // — has been detected (when the soundstart event fires.) // // SpeechRecognitionインターフェイスのonsoundstartプロパティは、 // サウンド認識可能な音声が検出されたときに実行されるイベントハンドラを表します // (サウンドスタートイベントが発生したとき)。 /** * @param {?} handler * @return {?} */ set onsoundstart(handler) { this.soundstartHandler = handler; } // The onspeechstart property of the SpeechRecognition interface represents // an event handler that will run when sound recognised // by the speech recognition service as speech has been detected // (when the speechstart event fires.) // // SpeechRecognitionインターフェイスのonspeechstartプロパティは、 // スピーチが検出されたとき(スピーチ開始イベントが発生したとき)に // 音声認識サービスによって認識されたサウンドが実行されるイベントハンドラを表します。 /** * @param {?} handler * @return {?} */ set onspeechstart(handler) { this.speechstartHandler = handler; } // The onspeechend property of the SpeechRecognition interface represents // an event handler that will run when speech recognised // by the speech recognition service has stopped being detected // (when the speechend event fires.) // // SpeechRecognitionインターフェイスのonspeechendプロパティは、 // 音声認識サービスによって認識された音声が検出されなくなったとき // (Speechendイベントが発生したとき)に実行されるイベントハンドラを表します。 /** * @param {?} handler * @return {?} */ set onspeechend(handler) { this.speechendHandler = handler; } // The onsoundend property of the SpeechRecognition interface represents // an event handler that will run when any sound // — recognisable speech or not — has stopped being detected // (when the soundend event fires.) // // SpeechRecognitionインターフェイスのonsoundendプロパティは、 // サウンド認識可能な音声が検出されなくなったときに実行されるイベントハンドラを表します // (サウンドエンドイベントが発生したとき)。 /** * @param {?} handler * @return {?} */ set onsoundend(handler) { this.soundendHandler = handler; } // The onaudioend property of the SpeechRecognition interface represents // an event handler that will run // when the user agent has finished capturing audio // (when the audioend event fires.) // // SpeechRecognitionインターフェイスのonaudioendプロパティは、 // ユーザーエージェントがオーディオのキャプチャを終了したとき // (オーディオエンドイベントが発生したとき)に実行されるイベントハンドラを表します。 /** * @param {?} handler * @return {?} */ set onaudioend(handler) { this.audioendHandler = handler; } // The onresult property of the SpeechRecognition interface represents // an event handler that will run // when the speech recognition service returns a result // — a word or phrase has been positively recognized // and this has been communicated back to the app // (when the result event fires.) // // SpeechRecognitionインターフェイスのonresultプロパティは、 // 音声認識サービスが結果を返すときに実行されるイベントハンドラを表します。 // 単語やフレーズが確実に認識され、結果イベントが発生したときにアプリに返されます。 /** * @param {?} handler * @return {?} */ set onresult(handler) { this.resultHandler = handler; } // The onnomatch property of the SpeechRecognition interface represents // an event handler that will run // when the speech recognition service returns // a final result with no significant recognition // (when the nomatch event fires.) // // This may involve some degree of recognition // which doesn't meet or exceed the confidence threshold. // // // SpeechRecognitionインターフェイスのonnomatchプロパティは、 // 音声認識サービスが重要な認識なしに(nomatchイベントが発生したとき) // 最終結果を返すときに実行されるイベントハンドラを表します。 // // これには、ある程度の認識が必要であり、これは信頼限界を満たさないか、 // 超えている。 /** * @param {?} handler * @return {?} */ set onnomatch(handler) { this.nomatchHandler = handler; } // The onerror property of the SpeechRecognition interface represents // an event handler that will run // when a speech recognition error occurs // (when the error event fires.) // // SpeechRecognitionインターフェイスのonerrorプロパティは、 // 音声認識エラーが発生したとき(エラーイベントが発生したとき)に // 実行されるイベントハンドラを表します。 /** * @param {?} handler * @return {?} */ set onerror(handler) { this.errorHandler = handler; } // The onstart property of the SpeechRecognition interface represents // an event handler that will run when the speech // recognition service has begun listening // to incoming audio with intent to recognize grammars // associated with the current SpeechRecognition // (when the start event fires.) // // // SpeechRecognitionインターフェイスのonstartプロパティは、 // 音声認識サービスが現在のSpeechRecognitionに関連付けられている文法を // 認識することを目的として着信オーディオを聴き始めたときに実行される // イベントハンドラを表します(開始イベントが発生したとき)。 /** * @param {?} handler * @return {?} */ set onstart(handler) { this.startHandler = handler; } // The onend property of the SpeechRecognition interface represents // an event handler that will run when the speech recognition // service has disconnected (when the end event fires.) // // SpeechRecognitionインターフェイスのonendプロパティは、 // 音声認識サービスが切断されたとき(終了イベントが発生したとき)に // 実行されるイベントハンドラを表します。 /** * @param {?} handler * @return {?} */ set onend(handler) { this.endHandler = handler; } // The start() method of the Web Speech API starts the speech recognition service // listening to incoming audio with intent to recognize grammars // associated with the current SpeechRecognition. // // Web Speech APIのstart()メソッドは、現在のSpeechRecognitionに // 関連付けられた文法を認識することを目的として、 // 着信音声を聴取する音声認識サービスを開始します。 /** * @return {?} */ start() { this.internal.start(); this.ref.tick(); } // The stop() method of the Web Speech API stops the speech recognition service // from listening to incoming audio, and attempts to return a SpeechRecognitionResult // using the audio captured so far. // // Web Speech APIのstop()メソッドは、音声認識サービスが着信音声を聴取するのを停止し、 // これまでに取得した音声を使用してSpeechRecognitionResultを返そうとします。 /** * @return {?} */ stop() { this.internal.stop(); this.ref.tick(); } // The abort() method of the Web Speech API stops the speech recognition service // from listening to incoming audio, and doesn't attempt to return // a SpeechRecognitionResult. // // Web Speech APIのabort()メソッドは、音声認識サービスが着信オーディオを聴くのをやめ、 // SpeechRecognitionResultを返そうとしません。 /** * @return {?} */ abort() { this.internal.abort(); this.ref.tick(); } } SpeechRecognitionService.decorators = [ { type: Injectable } ]; /** @nocollapse */ SpeechRecognitionService.ctorParameters = () => [ { type: ApplicationRef }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionGrammars,] }] }, { type: String, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionLang,] }] }, { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionContinuous,] }] }, { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionInterimResults,] }] }, { type: Number, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionMaxAlternatives,] }] }, { type: String, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionServiceUri,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionAudiostartHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionSoundstartHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionSpeechstartHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionSpeechendHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionSoundendHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionAudioendHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionResultHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionNomatchHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionErrorHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionStartHandler,] }] }, { type: Function, decorators: [{ type: Optional }, { type: Inject, args: [SpeechRecognitionEndHandler,] }] } ]; if (false) { /** * @type {?} * @private */ SpeechRecognitionService.prototype.ref; /** * @type {?} * @private */ SpeechRecognitionService.prototype.audiostartHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.soundstartHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.speechstartHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.speechendHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.soundendHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.audioendHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.resultHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.nomatchHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.errorHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.startHandler; /** * @type {?} * @private */ SpeechRecognitionService.prototype.endHandler; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BlZWNoLXJlY29nbml0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac2FtMTc4OTYvbmd4LXNwZWVjaC1yZWNvZ25pdGlvbi8iLCJzb3VyY2VzIjpbImxpYi9zZXJ2aWNlL3NwZWVjaC1yZWNvZ25pdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNMLFVBQVUsRUFDVixjQUFjLEVBQ2QsTUFBTSxFQUNOLFFBQVEsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQiwyQkFBMkIsRUFDM0IsK0JBQStCLEVBQy9CLGdDQUFnQyxFQUNoQywyQkFBMkIsRUFDM0Isa0NBQWtDLEVBQ2xDLGtDQUFrQyxFQUNsQyxtQ0FBbUMsRUFDbkMsaUNBQWlDLEVBQ2pDLGdDQUFnQyxFQUNoQyxnQ0FBZ0MsRUFDaEMsOEJBQThCLEVBQzlCLCtCQUErQixFQUMvQiw2QkFBNkIsRUFDN0IsNkJBQTZCLEVBQzdCLDJCQUEyQixHQUM1QixNQUFNLDRCQUE0QixDQUFDO0FBTXBDLE9BQU8sRUFDTCx1QkFBdUIsR0FDeEIsTUFBTSw2QkFBNkIsQ0FBQzs7QUFJckM7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyx3QkFBeUIsU0FBUSx1QkFBdUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXlFbkUsWUFDVSxHQUFtQixFQUczQixRQUErQixFQUcvQixJQUFZLEVBR1osVUFBbUIsRUFHbkIsY0FBdUIsRUFHdkIsZUFBdUIsRUFHdkIsVUFBa0IsRUFHVixpQkFBcUMsRUFHckMsaUJBQXFDLEVBR3JDLGtCQUFzQyxFQUd0QyxnQkFBb0MsRUFHcEMsZUFBbUMsRUFHbkMsZUFBbUMsRUFHbkMsYUFBa0QsRUFHbEQsY0FBbUQsRUFHbkQsWUFBaUQsRUFHakQsWUFBZ0MsRUFHaEMsVUFBOEI7UUFFdEMsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFyRHZFLFFBQUcsR0FBSCxHQUFHLENBQWdCO1FBcUJuQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW9CO1FBR3JDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBb0I7UUFHckMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUd0QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQW9CO1FBR3BDLG9CQUFlLEdBQWYsZUFBZSxDQUFvQjtRQUduQyxvQkFBZSxHQUFmLGVBQWUsQ0FBb0I7UUFHbkMsa0JBQWEsR0FBYixhQUFhLENBQXFDO1FBR2xELG1CQUFjLEdBQWQsY0FBYyxDQUFxQztRQUduRCxpQkFBWSxHQUFaLFlBQVksQ0FBcUM7UUFHakQsaUJBQVksR0FBWixZQUFZLENBQW9CO1FBR2hDLGVBQVUsR0FBVixVQUFVLENBQW9CO1FBSXRDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUVwQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdEIsQ0FBQzs7Ozs7SUFsSU8sWUFBWTs7Y0FDWixDQUFDOzs7UUFBRyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtZQUFFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUM7U0FBRTtRQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQUUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztTQUFFO1FBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFBRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsQ0FBQyxDQUFDO1NBQUU7UUFDOUQsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUFFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7U0FBRTtRQUMxRCxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUFFLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxDQUFDO1NBQUU7UUFDeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFBRSxJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztTQUFFO1FBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7U0FBRTtRQUNwRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUFFLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO1NBQUU7UUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFBRSxJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztTQUFFO1FBQ2xELElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQUUsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7U0FBRTtRQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUFFLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1NBQUU7SUFDaEQsQ0FBQzs7Ozs7SUFFTyxZQUFZO1FBQ2xCLHFCQUFxQjtRQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDL0IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUNuQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDM0MsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDN0MsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRW5DLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWTs7OztRQUFHLENBQUMsQ0FBUSxFQUFFLEVBQUU7WUFDeEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFBLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVk7Ozs7UUFBRyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ3hDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQSxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhOzs7O1FBQUcsQ0FBQyxDQUFRLEVBQUUsRUFBRTtZQUN6QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUEsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVzs7OztRQUFHLENBQUMsQ0FBUSxFQUFFLEVBQUU7WUFDdkMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFBLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVU7Ozs7UUFBRyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUEsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTs7OztRQUFHLENBQUMsQ0FBUSxFQUFFLEVBQUU7WUFDdEMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQSxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFROzs7O1FBQUcsQ0FBQyxDQUF5QixFQUFFLEVBQUU7WUFDckQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQSxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTOzs7O1FBQUcsQ0FBQyxDQUF5QixFQUFFLEVBQUU7WUFDdEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQSxDQUFDO1FBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPOzs7O1FBQUcsQ0FBQyxDQUFNLEVBQUUsRUFBRTtZQUNqQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbEIsQ0FBQyxDQUFBLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU87Ozs7UUFBRyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixDQUFDLENBQUEsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSzs7OztRQUFHLENBQUMsQ0FBUSxFQUFFLEVBQUU7WUFDakMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLENBQUMsQ0FBQSxDQUFDO0lBQ0osQ0FBQzs7Ozs7Ozs7Ozs7Ozs7SUEwRUQsSUFBSSxZQUFZLENBQUMsT0FBMkI7UUFDMUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztJQUNuQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsSUFBSSxZQUFZLENBQUMsT0FBMkI7UUFDMUMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQztJQUNuQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsSUFBSSxhQUFhLENBQUMsT0FBMkI7UUFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztJQUNwQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsSUFBSSxXQUFXLENBQUMsT0FBMkI7UUFDekMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQztJQUNsQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsSUFBSSxVQUFVLENBQUMsT0FBMkI7UUFDeEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7SUFDakMsQ0FBQzs7Ozs7Ozs7Ozs7OztJQVVELElBQUksVUFBVSxDQUFDLE9BQTJCO1FBQ3hDLElBQUksQ0FBQyxlQUFlLEdBQUcsT0FBTyxDQUFDO0lBQ2pDLENBQUM7Ozs7Ozs7Ozs7Ozs7OztJQVlELElBQUksUUFBUSxDQUFDLE9BQTRDO1FBQ3ZELElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO0lBQy9CLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWtCRCxJQUFJLFNBQVMsQ0FBQyxPQUE0QztRQUN4RCxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQztJQUNoQyxDQUFDOzs7Ozs7Ozs7Ozs7O0lBVUQsSUFBSSxPQUFPLENBQUMsT0FBNEM7UUFDdEQsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUM7SUFDOUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFjRCxJQUFJLE9BQU8sQ0FBQyxPQUEyQjtRQUNyQyxJQUFJLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQztJQUM5QixDQUFDOzs7Ozs7Ozs7Ozs7SUFTRCxJQUFJLEtBQUssQ0FBQyxPQUEyQjtRQUNuQyxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQztJQUM1QixDQUFDOzs7Ozs7Ozs7OztJQVNNLEtBQUs7UUFDVixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbEIsQ0FBQzs7Ozs7Ozs7OztJQVFNLElBQUk7UUFDVCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbEIsQ0FBQzs7Ozs7Ozs7OztJQVFNLEtBQUs7UUFDVixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbEIsQ0FBQzs7O1lBL1RGLFVBQVU7Ozs7WUFsQ1QsY0FBYzs0Q0FvSFgsUUFBUSxZQUFJLE1BQU0sU0FBQyx5QkFBeUI7eUNBRzVDLFFBQVEsWUFBSSxNQUFNLFNBQUMscUJBQXFCOzBDQUd4QyxRQUFRLFlBQUksTUFBTSxTQUFDLDJCQUEyQjswQ0FHOUMsUUFBUSxZQUFJLE1BQU0sU0FBQywrQkFBK0I7eUNBR2xELFFBQVEsWUFBSSxNQUFNLFNBQUMsZ0NBQWdDO3lDQUduRCxRQUFRLFlBQUksTUFBTSxTQUFDLDJCQUEyQjsyQ0FHOUMsUUFBUSxZQUFJLE1BQU0sU0FBQyxrQ0FBa0M7MkNBR3JELFFBQVEsWUFBSSxNQUFNLFNBQUMsa0NBQWtDOzJDQUdyRCxRQUFRLFlBQUksTUFBTSxTQUFDLG1DQUFtQzsyQ0FHdEQsUUFBUSxZQUFJLE1BQU0sU0FBQyxpQ0FBaUM7MkNBR3BELFFBQVEsWUFBSSxNQUFNLFNBQUMsZ0NBQWdDOzJDQUduRCxRQUFRLFlBQUksTUFBTSxTQUFDLGdDQUFnQzsyQ0FHbkQsUUFBUSxZQUFJLE1BQU0sU0FBQyw4QkFBOEI7MkNBR2pELFFBQVEsWUFBSSxNQUFNLFNBQUMsK0JBQStCOzJDQUdsRCxRQUFRLFlBQUksTUFBTSxTQUFDLDZCQUE2QjsyQ0FHaEQsUUFBUSxZQUFJLE1BQU0sU0FBQyw2QkFBNkI7MkNBR2hELFFBQVEsWUFBSSxNQUFNLFNBQUMsMkJBQTJCOzs7Ozs7O0lBbEQvQyx1Q0FBMkI7Ozs7O0lBb0IzQixxREFDNkM7Ozs7O0lBRTdDLHFEQUM2Qzs7Ozs7SUFFN0Msc0RBQzhDOzs7OztJQUU5QyxvREFDNEM7Ozs7O0lBRTVDLG1EQUMyQzs7Ozs7SUFFM0MsbURBQzJDOzs7OztJQUUzQyxpREFDMEQ7Ozs7O0lBRTFELGtEQUMyRDs7Ozs7SUFFM0QsZ0RBQ3lEOzs7OztJQUV6RCxnREFDd0M7Ozs7O0lBRXhDLDhDQUNzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgSW5qZWN0YWJsZSxcclxuICBBcHBsaWNhdGlvblJlZixcclxuICBJbmplY3QsXHJcbiAgT3B0aW9uYWwsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQge1xyXG4gIFNwZWVjaFJlY29nbml0aW9uR3JhbW1hcnMsXHJcbiAgU3BlZWNoUmVjb2duaXRpb25MYW5nLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uQ29udGludW91cyxcclxuICBTcGVlY2hSZWNvZ25pdGlvbkludGVyaW1SZXN1bHRzLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uTWF4QWx0ZXJuYXRpdmVzLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uU2VydmljZVVyaSxcclxuICBTcGVlY2hSZWNvZ25pdGlvbkF1ZGlvc3RhcnRIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uU291bmRzdGFydEhhbmRsZXIsXHJcbiAgU3BlZWNoUmVjb2duaXRpb25TcGVlY2hzdGFydEhhbmRsZXIsXHJcbiAgU3BlZWNoUmVjb2duaXRpb25TcGVlY2hlbmRIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uU291bmRlbmRIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uQXVkaW9lbmRIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uUmVzdWx0SGFuZGxlcixcclxuICBTcGVlY2hSZWNvZ25pdGlvbk5vbWF0Y2hIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uRXJyb3JIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uU3RhcnRIYW5kbGVyLFxyXG4gIFNwZWVjaFJlY29nbml0aW9uRW5kSGFuZGxlcixcclxufSBmcm9tICcuL3NwZWVjaC1yZWNvZ25pdGlvbi50b2tlbic7XHJcblxyXG5pbXBvcnQge1xyXG4gIFNwZWVjaEdyYW1tYXJMaXN0VHlwZSxcclxufSBmcm9tICcuLi9hZGFwdGVyJztcclxuXHJcbmltcG9ydCB7XHJcbiAgU3BlZWNoUmVjb2duaXRpb25Db21tb24sXHJcbn0gZnJvbSAnLi9zcGVlY2gtcmVjb2duaXRpb24uY29tbW9uJztcclxuXHJcbi8vIEBkeW5hbWljXHJcbkBJbmplY3RhYmxlKClcclxuLyoqXHJcbiAqXHJcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1NwZWVjaFJlY29nbml0aW9uXHJcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dlYl9TcGVlY2hfQVBJXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgU3BlZWNoUmVjb2duaXRpb25TZXJ2aWNlIGV4dGVuZHMgU3BlZWNoUmVjb2duaXRpb25Db21tb24ge1xyXG5cclxuICBwcml2YXRlIGluaXRIYW5kbGVycygpIHtcclxuICAgIGNvbnN0IF8gPSAoKSA9PiB7IH07XHJcbiAgICBpZiAoIXRoaXMuYXVkaW9zdGFydEhhbmRsZXIpIHsgdGhpcy5hdWRpb3N0YXJ0SGFuZGxlciA9IF87IH1cclxuICAgIGlmICghdGhpcy5zb3VuZHN0YXJ0SGFuZGxlcikgeyB0aGlzLnNvdW5kc3RhcnRIYW5kbGVyID0gXzsgfVxyXG4gICAgaWYgKCF0aGlzLnNwZWVjaHN0YXJ0SGFuZGxlcikgeyB0aGlzLnNwZWVjaHN0YXJ0SGFuZGxlciA9IF87IH1cclxuICAgIGlmICghdGhpcy5zcGVlY2hlbmRIYW5kbGVyKSB7IHRoaXMuc3BlZWNoZW5kSGFuZGxlciA9IF87IH1cclxuICAgIGlmICghdGhpcy5zb3VuZGVuZEhhbmRsZXIpIHsgdGhpcy5zb3VuZGVuZEhhbmRsZXIgPSBfOyB9XHJcbiAgICBpZiAoIXRoaXMuYXVkaW9lbmRIYW5kbGVyKSB7IHRoaXMuYXVkaW9lbmRIYW5kbGVyID0gXzsgfVxyXG4gICAgaWYgKCF0aGlzLnJlc3VsdEhhbmRsZXIpIHsgdGhpcy5yZXN1bHRIYW5kbGVyID0gXzsgfVxyXG4gICAgaWYgKCF0aGlzLm5vbWF0Y2hIYW5kbGVyKSB7IHRoaXMubm9tYXRjaEhhbmRsZXIgPSBfOyB9XHJcbiAgICBpZiAoIXRoaXMuZXJyb3JIYW5kbGVyKSB7IHRoaXMuZXJyb3JIYW5kbGVyID0gXzsgfVxyXG4gICAgaWYgKCF0aGlzLnN0YXJ0SGFuZGxlcikgeyB0aGlzLnN0YXJ0SGFuZGxlciA9IF87IH1cclxuICAgIGlmICghdGhpcy5lbmRIYW5kbGVyKSB7IHRoaXMuZW5kSGFuZGxlciA9IF87IH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdEludGVybmFsKCkge1xyXG4gICAgLy8gc2VlIHNldHRlciBtZXRob2RzXHJcbiAgICB0aGlzLmdyYW1tYXJzID0gdGhpcy5fZ3JhbW1hcnM7XHJcbiAgICB0aGlzLmxhbmcgPSB0aGlzLl9sYW5nO1xyXG4gICAgdGhpcy5jb250aW51b3VzID0gdGhpcy5fY29udGludW91cztcclxuICAgIHRoaXMuaW50ZXJpbVJlc3VsdHMgPSB0aGlzLl9pbnRlcmltUmVzdWx0cztcclxuICAgIHRoaXMubWF4QWx0ZXJuYXRpdmVzID0gdGhpcy5fbWF4QWx0ZXJuYXRpdmVzO1xyXG4gICAgdGhpcy5zZXJ2aWNlVVJJID0gdGhpcy5fc2VydmljZVVSSTtcclxuXHJcbiAgICB0aGlzLmludGVybmFsLm9uYXVkaW9zdGFydCA9IChlOiBFdmVudCkgPT4ge1xyXG4gICAgICB0aGlzLmF1ZGlvc3RhcnRIYW5kbGVyKGUpO1xyXG4gICAgICB0aGlzLnJlZi50aWNrKCk7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5pbnRlcm5hbC5vbnNvdW5kc3RhcnQgPSAoZTogRXZlbnQpID0+IHtcclxuICAgICAgdGhpcy5zb3VuZHN0YXJ0SGFuZGxlcihlKTtcclxuICAgICAgdGhpcy5yZWYudGljaygpO1xyXG4gICAgfTtcclxuICAgIHRoaXMuaW50ZXJuYWwub25zcGVlY2hzdGFydCA9IChlOiBFdmVudCkgPT4ge1xyXG4gICAgICB0aGlzLnNwZWVjaHN0YXJ0SGFuZGxlcihlKTtcclxuICAgICAgdGhpcy5yZWYudGljaygpO1xyXG4gICAgfTtcclxuICAgIHRoaXMuaW50ZXJuYWwub25zcGVlY2hlbmQgPSAoZTogRXZlbnQpID0+IHtcclxuICAgICAgdGhpcy5zcGVlY2hlbmRIYW5kbGVyKGUpO1xyXG4gICAgICB0aGlzLnJlZi50aWNrKCk7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5pbnRlcm5hbC5vbnNvdW5kZW5kID0gKGU6IEV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMuc291bmRlbmRIYW5kbGVyKGUpO1xyXG4gICAgICB0aGlzLnJlZi50aWNrKCk7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5pbnRlcm5hbC5vbmF1ZGlvZW5kID0gKGU6IEV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMuYXVkaW9lbmRIYW5kbGVyKGUpO1xyXG4gICAgICB0aGlzLnJlZi50aWNrKCk7XHJcbiAgICB9O1xyXG4gICAgdGhpcy5pbnRlcm5hbC5vbnJlc3VsdCA9IChlOiBTcGVlY2hSZWNvZ25pdGlvbkV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMucmVzdWx0SGFuZGxlcihlKTtcclxuICAgICAgdGhpcy5yZWYudGljaygpO1xyXG4gICAgfTtcclxuICAgIHRoaXMuaW50ZXJuYWwub25ub21hdGNoID0gKGU6IFNwZWVjaFJlY29nbml0aW9uRXZlbnQpID0+IHtcclxuICAgICAgdGhpcy5ub21hdGNoSGFuZGxlcihlKTtcclxuICAgICAgdGhpcy5yZWYudGljaygpO1xyXG4gICAgfTtcclxuICAgIHRoaXMuaW50ZXJuYWwub25lcnJvciA9IChlOiBhbnkpID0+IHtcclxuICAgICAgdGhpcy5lcnJvckhhbmRsZXIoZSk7XHJcbiAgICAgIHRoaXMucmVmLnRpY2soKTtcclxuICAgIH07XHJcbiAgICB0aGlzLmludGVybmFsLm9uc3RhcnQgPSAoZTogRXZlbnQpID0+IHtcclxuICAgICAgdGhpcy5zdGFydEhhbmRsZXIoZSk7XHJcbiAgICAgIHRoaXMucmVmLnRpY2soKTtcclxuICAgIH07XHJcbiAgICB0aGlzLmludGVybmFsLm9uZW5kID0gKGU6IEV2ZW50KSA9PiB7XHJcbiAgICAgIHRoaXMuZW5kSGFuZGxlcihlKTtcclxuICAgICAgdGhpcy5yZWYudGljaygpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgcmVmOiBBcHBsaWNhdGlvblJlZixcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uR3JhbW1hcnMpXHJcbiAgICBncmFtbWFyczogU3BlZWNoR3JhbW1hckxpc3RUeXBlLFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25MYW5nKVxyXG4gICAgbGFuZzogc3RyaW5nLFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25Db250aW51b3VzKVxyXG4gICAgY29udGludW91czogYm9vbGVhbixcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uSW50ZXJpbVJlc3VsdHMpXHJcbiAgICBpbnRlcmltUmVzdWx0czogYm9vbGVhbixcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uTWF4QWx0ZXJuYXRpdmVzKVxyXG4gICAgbWF4QWx0ZXJuYXRpdmVzOiBudW1iZXIsXHJcblxyXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChTcGVlY2hSZWNvZ25pdGlvblNlcnZpY2VVcmkpXHJcbiAgICBzZXJ2aWNlVVJJOiBzdHJpbmcsXHJcblxyXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChTcGVlY2hSZWNvZ25pdGlvbkF1ZGlvc3RhcnRIYW5kbGVyKVxyXG4gICAgcHJpdmF0ZSBhdWRpb3N0YXJ0SGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25Tb3VuZHN0YXJ0SGFuZGxlcilcclxuICAgIHByaXZhdGUgc291bmRzdGFydEhhbmRsZXI6IChldjogRXZlbnQpID0+IGFueSxcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uU3BlZWNoc3RhcnRIYW5kbGVyKVxyXG4gICAgcHJpdmF0ZSBzcGVlY2hzdGFydEhhbmRsZXI6IChldjogRXZlbnQpID0+IGFueSxcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uU3BlZWNoZW5kSGFuZGxlcilcclxuICAgIHByaXZhdGUgc3BlZWNoZW5kSGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25Tb3VuZGVuZEhhbmRsZXIpXHJcbiAgICBwcml2YXRlIHNvdW5kZW5kSGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25BdWRpb2VuZEhhbmRsZXIpXHJcbiAgICBwcml2YXRlIGF1ZGlvZW5kSGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25SZXN1bHRIYW5kbGVyKVxyXG4gICAgcHJpdmF0ZSByZXN1bHRIYW5kbGVyOiAoZXY6IFNwZWVjaFJlY29nbml0aW9uRXZlbnQpID0+IGFueSxcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uTm9tYXRjaEhhbmRsZXIpXHJcbiAgICBwcml2YXRlIG5vbWF0Y2hIYW5kbGVyOiAoZXY6IFNwZWVjaFJlY29nbml0aW9uRXZlbnQpID0+IGFueSxcclxuXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNwZWVjaFJlY29nbml0aW9uRXJyb3JIYW5kbGVyKVxyXG4gICAgcHJpdmF0ZSBlcnJvckhhbmRsZXI6IChldjogU3BlZWNoUmVjb2duaXRpb25FdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25TdGFydEhhbmRsZXIpXHJcbiAgICBwcml2YXRlIHN0YXJ0SGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55LFxyXG5cclxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU3BlZWNoUmVjb2duaXRpb25FbmRIYW5kbGVyKVxyXG4gICAgcHJpdmF0ZSBlbmRIYW5kbGVyOiAoZXY6IEV2ZW50KSA9PiBhbnlcclxuICApIHtcclxuICAgIHN1cGVyKGdyYW1tYXJzLCBsYW5nLCBjb250aW51b3VzLCBpbnRlcmltUmVzdWx0cywgbWF4QWx0ZXJuYXRpdmVzLCBzZXJ2aWNlVVJJKTtcclxuXHJcbiAgICB0aGlzLmluaXRIYW5kbGVycygpO1xyXG5cclxuICAgIHRoaXMuaW5pdEludGVybmFsKCk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gVGhlIG9uYXVkaW9zdGFydCBwcm9wZXJ0eSBvZiB0aGUgU3BlZWNoUmVjb2duaXRpb24gaW50ZXJmYWNlXHJcbiAgLy8gcmVwcmVzZW50cyBhbiBldmVudCBoYW5kbGVyIHRoYXQgd2lsbCBydW5cclxuICAvLyB3aGVuIHRoZSB1c2VyIGFnZW50IGhhcyBzdGFydGVkIHRvIGNhcHR1cmUgYXVkaW9cclxuICAvLyAod2hlbiB0aGUgYXVkaW9zdGFydCBldmVudCBmaXJlcy4pXHJcbiAgLy9cclxuICAvLyBTcGVlY2hSZWNvZ25pdGlvbuOCpOODs+OCv+ODvOODleOCp+OCpOOCueOBrm9uYXVkaW9zdGFydOODl+ODreODkeODhuOCo+OBr+OAgVxyXG4gIC8vIOODpuODvOOCtuODvOOCqOODvOOCuOOCp+ODs+ODiOOBjOOCquODvOODh+OCo+OCquOBruOCreODo+ODl+ODgeODo+OCkumWi+Wni+OBl+OBn+OBqOOBjVxyXG4gIC8vIO+8iGF1ZGlvc3RhcnTjgqTjg5njg7Pjg4jjgYznmbrnlJ/jgZfjgZ/jgajjgY3vvInjgavlrp/ooYzjgZXjgozjgovjgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgpJcclxuICAvLyDooajjgZfjgb7jgZnjgIJcclxuICBzZXQgb25hdWRpb3N0YXJ0KGhhbmRsZXI6IChldjogRXZlbnQpID0+IGFueSkge1xyXG4gICAgdGhpcy5hdWRpb3N0YXJ0SGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgb25zb3VuZHN0YXJ0IHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1biB3aGVuIGFueSBzb3VuZFxyXG4gIC8vIOKAlCByZWNvZ25pc2FibGUgc3BlZWNoIG9yIG5vdFxyXG4gIC8vIOKAlCBoYXMgYmVlbiBkZXRlY3RlZCAod2hlbiB0aGUgc291bmRzdGFydCBldmVudCBmaXJlcy4pXHJcbiAgLy9cclxuICAvLyBTcGVlY2hSZWNvZ25pdGlvbuOCpOODs+OCv+ODvOODleOCp+OCpOOCueOBrm9uc291bmRzdGFydOODl+ODreODkeODhuOCo+OBr+OAgVxyXG4gIC8vIOOCteOCpuODs+ODieiqjeitmOWPr+iDveOBqumfs+WjsOOBjOaknOWHuuOBleOCjOOBn+OBqOOBjeOBq+Wun+ihjOOBleOCjOOCi+OCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuihqOOBl+OBvuOBmVxyXG4gIC8vIO+8iOOCteOCpuODs+ODieOCueOCv+ODvOODiOOCpOODmeODs+ODiOOBjOeZuueUn+OBl+OBn+OBqOOBje+8ieOAglxyXG4gIHNldCBvbnNvdW5kc3RhcnQoaGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55KSB7XHJcbiAgICB0aGlzLnNvdW5kc3RhcnRIYW5kbGVyID0gaGFuZGxlcjtcclxuICB9XHJcblxyXG4gIC8vIFRoZSBvbnNwZWVjaHN0YXJ0IHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1biB3aGVuIHNvdW5kIHJlY29nbmlzZWRcclxuICAvLyBieSB0aGUgc3BlZWNoIHJlY29nbml0aW9uIHNlcnZpY2UgYXMgc3BlZWNoIGhhcyBiZWVuIGRldGVjdGVkXHJcbiAgLy8gKHdoZW4gdGhlIHNwZWVjaHN0YXJ0IGV2ZW50IGZpcmVzLilcclxuICAvL1xyXG4gIC8vIFNwZWVjaFJlY29nbml0aW9u44Kk44Oz44K/44O844OV44Kn44Kk44K544Gub25zcGVlY2hzdGFydOODl+ODreODkeODhuOCo+OBr+OAgVxyXG4gIC8vIOOCueODlOODvOODgeOBjOaknOWHuuOBleOCjOOBn+OBqOOBje+8iOOCueODlOODvOODgemWi+Wni+OCpOODmeODs+ODiOOBjOeZuueUn+OBl+OBn+OBqOOBje+8ieOBq1xyXG4gIC8vIOmfs+WjsOiqjeitmOOCteODvOODk+OCueOBq+OCiOOBo+OBpuiqjeitmOOBleOCjOOBn+OCteOCpuODs+ODieOBjOWun+ihjOOBleOCjOOCi+OCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuihqOOBl+OBvuOBmeOAglxyXG4gIHNldCBvbnNwZWVjaHN0YXJ0KGhhbmRsZXI6IChldjogRXZlbnQpID0+IGFueSkge1xyXG4gICAgdGhpcy5zcGVlY2hzdGFydEhhbmRsZXIgPSBoYW5kbGVyO1xyXG4gIH1cclxuXHJcbiAgLy8gVGhlIG9uc3BlZWNoZW5kIHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1biB3aGVuIHNwZWVjaCByZWNvZ25pc2VkXHJcbiAgLy8gYnkgdGhlIHNwZWVjaCByZWNvZ25pdGlvbiBzZXJ2aWNlIGhhcyBzdG9wcGVkIGJlaW5nIGRldGVjdGVkXHJcbiAgLy8gKHdoZW4gdGhlIHNwZWVjaGVuZCBldmVudCBmaXJlcy4pXHJcbiAgLy9cclxuICAvLyBTcGVlY2hSZWNvZ25pdGlvbuOCpOODs+OCv+ODvOODleOCp+OCpOOCueOBrm9uc3BlZWNoZW5k44OX44Ot44OR44OG44Kj44Gv44CBXHJcbiAgLy8g6Z+z5aOw6KqN6K2Y44K144O844OT44K544Gr44KI44Gj44Gm6KqN6K2Y44GV44KM44Gf6Z+z5aOw44GM5qSc5Ye644GV44KM44Gq44GP44Gq44Gj44Gf44Go44GNXHJcbiAgLy8g77yIU3BlZWNoZW5k44Kk44OZ44Oz44OI44GM55m655Sf44GX44Gf44Go44GN77yJ44Gr5a6f6KGM44GV44KM44KL44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44KS6KGo44GX44G+44GZ44CCXHJcbiAgc2V0IG9uc3BlZWNoZW5kKGhhbmRsZXI6IChldjogRXZlbnQpID0+IGFueSkge1xyXG4gICAgdGhpcy5zcGVlY2hlbmRIYW5kbGVyID0gaGFuZGxlcjtcclxuICB9XHJcblxyXG4gIC8vIFRoZSBvbnNvdW5kZW5kIHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1biB3aGVuIGFueSBzb3VuZFxyXG4gIC8vIOKAlCByZWNvZ25pc2FibGUgc3BlZWNoIG9yIG5vdCDigJQgaGFzIHN0b3BwZWQgYmVpbmcgZGV0ZWN0ZWRcclxuICAvLyAod2hlbiB0aGUgc291bmRlbmQgZXZlbnQgZmlyZXMuKVxyXG4gIC8vXHJcbiAgLy8gU3BlZWNoUmVjb2duaXRpb27jgqTjg7Pjgr/jg7zjg5XjgqfjgqTjgrnjga5vbnNvdW5kZW5k44OX44Ot44OR44OG44Kj44Gv44CBXHJcbiAgLy8g44K144Km44Oz44OJ6KqN6K2Y5Y+v6IO944Gq6Z+z5aOw44GM5qSc5Ye644GV44KM44Gq44GP44Gq44Gj44Gf44Go44GN44Gr5a6f6KGM44GV44KM44KL44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44KS6KGo44GX44G+44GZXHJcbiAgLy8g77yI44K144Km44Oz44OJ44Ko44Oz44OJ44Kk44OZ44Oz44OI44GM55m655Sf44GX44Gf44Go44GN77yJ44CCXHJcbiAgc2V0IG9uc291bmRlbmQoaGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55KSB7XHJcbiAgICB0aGlzLnNvdW5kZW5kSGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgb25hdWRpb2VuZCBwcm9wZXJ0eSBvZiB0aGUgU3BlZWNoUmVjb2duaXRpb24gaW50ZXJmYWNlIHJlcHJlc2VudHNcclxuICAvLyBhbiBldmVudCBoYW5kbGVyIHRoYXQgd2lsbCBydW5cclxuICAvLyB3aGVuIHRoZSB1c2VyIGFnZW50IGhhcyBmaW5pc2hlZCBjYXB0dXJpbmcgYXVkaW9cclxuICAvLyAod2hlbiB0aGUgYXVkaW9lbmQgZXZlbnQgZmlyZXMuKVxyXG4gIC8vXHJcbiAgLy8gU3BlZWNoUmVjb2duaXRpb27jgqTjg7Pjgr/jg7zjg5XjgqfjgqTjgrnjga5vbmF1ZGlvZW5k44OX44Ot44OR44OG44Kj44Gv44CBXHJcbiAgLy8g44Om44O844K244O844Ko44O844K444Kn44Oz44OI44GM44Kq44O844OH44Kj44Kq44Gu44Kt44Oj44OX44OB44Oj44KS57WC5LqG44GX44Gf44Go44GNXHJcbiAgLy8g77yI44Kq44O844OH44Kj44Kq44Ko44Oz44OJ44Kk44OZ44Oz44OI44GM55m655Sf44GX44Gf44Go44GN77yJ44Gr5a6f6KGM44GV44KM44KL44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44KS6KGo44GX44G+44GZ44CCXHJcbiAgc2V0IG9uYXVkaW9lbmQoaGFuZGxlcjogKGV2OiBFdmVudCkgPT4gYW55KSB7XHJcbiAgICB0aGlzLmF1ZGlvZW5kSGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgb25yZXN1bHQgcHJvcGVydHkgb2YgdGhlIFNwZWVjaFJlY29nbml0aW9uIGludGVyZmFjZSByZXByZXNlbnRzXHJcbiAgLy8gYW4gZXZlbnQgaGFuZGxlciB0aGF0IHdpbGwgcnVuXHJcbiAgLy8gd2hlbiB0aGUgc3BlZWNoIHJlY29nbml0aW9uIHNlcnZpY2UgcmV0dXJucyBhIHJlc3VsdFxyXG4gIC8vIOKAlCBhIHdvcmQgb3IgcGhyYXNlIGhhcyBiZWVuIHBvc2l0aXZlbHkgcmVjb2duaXplZFxyXG4gIC8vIGFuZCB0aGlzIGhhcyBiZWVuIGNvbW11bmljYXRlZCBiYWNrIHRvIHRoZSBhcHBcclxuICAvLyAod2hlbiB0aGUgcmVzdWx0IGV2ZW50IGZpcmVzLilcclxuICAvL1xyXG4gIC8vIFNwZWVjaFJlY29nbml0aW9u44Kk44Oz44K/44O844OV44Kn44Kk44K544Gub25yZXN1bHTjg5fjg63jg5Hjg4bjgqPjga/jgIFcclxuICAvLyDpn7Plo7Doqo3orZjjgrXjg7zjg5PjgrnjgYzntZDmnpzjgpLov5TjgZnjgajjgY3jgavlrp/ooYzjgZXjgozjgovjgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgpLooajjgZfjgb7jgZnjgIJcclxuICAvLyDljZjoqp7jgoTjg5Xjg6zjg7zjgrrjgYznorrlrp/jgavoqo3orZjjgZXjgozjgIHntZDmnpzjgqTjg5njg7Pjg4jjgYznmbrnlJ/jgZfjgZ/jgajjgY3jgavjgqLjg5fjg6rjgavov5TjgZXjgozjgb7jgZnjgIJcclxuICBzZXQgb25yZXN1bHQoaGFuZGxlcjogKGV2OiBTcGVlY2hSZWNvZ25pdGlvbkV2ZW50KSA9PiBhbnkpIHtcclxuICAgIHRoaXMucmVzdWx0SGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgb25ub21hdGNoIHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1blxyXG4gIC8vIHdoZW4gdGhlIHNwZWVjaCByZWNvZ25pdGlvbiBzZXJ2aWNlIHJldHVybnNcclxuICAvLyBhIGZpbmFsIHJlc3VsdCB3aXRoIG5vIHNpZ25pZmljYW50IHJlY29nbml0aW9uXHJcbiAgLy8gKHdoZW4gdGhlIG5vbWF0Y2ggZXZlbnQgZmlyZXMuKVxyXG4gIC8vXHJcbiAgLy8gVGhpcyBtYXkgaW52b2x2ZSBzb21lIGRlZ3JlZSBvZiByZWNvZ25pdGlvblxyXG4gIC8vICB3aGljaCBkb2Vzbid0IG1lZXQgb3IgZXhjZWVkIHRoZSBjb25maWRlbmNlIHRocmVzaG9sZC5cclxuICAvL1xyXG4gIC8vXHJcbiAgLy8gU3BlZWNoUmVjb2duaXRpb27jgqTjg7Pjgr/jg7zjg5XjgqfjgqTjgrnjga5vbm5vbWF0Y2jjg5fjg63jg5Hjg4bjgqPjga/jgIFcclxuICAvLyDpn7Plo7Doqo3orZjjgrXjg7zjg5PjgrnjgYzph43opoHjgaroqo3orZjjgarjgZfjgavvvIhub21hdGNo44Kk44OZ44Oz44OI44GM55m655Sf44GX44Gf44Go44GN77yJXHJcbiAgLy8g5pyA57WC57WQ5p6c44KS6L+U44GZ44Go44GN44Gr5a6f6KGM44GV44KM44KL44Kk44OZ44Oz44OI44OP44Oz44OJ44Op44KS6KGo44GX44G+44GZ44CCXHJcbiAgLy9cclxuICAvLyDjgZPjgozjgavjga/jgIHjgYLjgovnqIvluqbjga7oqo3orZjjgYzlv4XopoHjgafjgYLjgorjgIHjgZPjgozjga/kv6HpoLzpmZDnlYzjgpLmuoDjgZ/jgZXjgarjgYTjgYvjgIFcclxuICAvLyDotoXjgYjjgabjgYTjgovjgIJcclxuICBzZXQgb25ub21hdGNoKGhhbmRsZXI6IChldjogU3BlZWNoUmVjb2duaXRpb25FdmVudCkgPT4gYW55KSB7XHJcbiAgICB0aGlzLm5vbWF0Y2hIYW5kbGVyID0gaGFuZGxlcjtcclxuICB9XHJcblxyXG4gIC8vIFRoZSBvbmVycm9yIHByb3BlcnR5IG9mIHRoZSBTcGVlY2hSZWNvZ25pdGlvbiBpbnRlcmZhY2UgcmVwcmVzZW50c1xyXG4gIC8vIGFuIGV2ZW50IGhhbmRsZXIgdGhhdCB3aWxsIHJ1blxyXG4gIC8vIHdoZW4gYSBzcGVlY2ggcmVjb2duaXRpb24gZXJyb3Igb2NjdXJzXHJcbiAgLy8gKHdoZW4gdGhlIGVycm9yIGV2ZW50IGZpcmVzLilcclxuICAvL1xyXG4gIC8vIFNwZWVjaFJlY29nbml0aW9u44Kk44Oz44K/44O844OV44Kn44Kk44K544Gub25lcnJvcuODl+ODreODkeODhuOCo+OBr+OAgVxyXG4gIC8vIOmfs+WjsOiqjeitmOOCqOODqeODvOOBjOeZuueUn+OBl+OBn+OBqOOBje+8iOOCqOODqeODvOOCpOODmeODs+ODiOOBjOeZuueUn+OBl+OBn+OBqOOBje+8ieOBq1xyXG4gIC8vIOWun+ihjOOBleOCjOOCi+OCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuihqOOBl+OBvuOBmeOAglxyXG4gIHNldCBvbmVycm9yKGhhbmRsZXI6IChldjogU3BlZWNoUmVjb2duaXRpb25FdmVudCkgPT4gYW55KSB7XHJcbiAgICB0aGlzLmVycm9ySGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgb25zdGFydCBwcm9wZXJ0eSBvZiB0aGUgU3BlZWNoUmVjb2duaXRpb24gaW50ZXJmYWNlIHJlcHJlc2VudHNcclxuICAvLyBhbiBldmVudCBoYW5kbGVyIHRoYXQgd2lsbCBydW4gd2hlbiB0aGUgc3BlZWNoXHJcbiAgLy8gcmVjb2duaXRpb24gc2VydmljZSBoYXMgYmVndW4gbGlzdGVuaW5nXHJcbiAgLy8gdG8gaW5jb21pbmcgYXVkaW8gd2l0aCBpbnRlbnQgdG8gcmVjb2duaXplIGdyYW1tYXJzXHJcbiAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IFNwZWVjaFJlY29nbml0aW9uXHJcbiAgLy8gKHdoZW4gdGhlIHN0YXJ0IGV2ZW50IGZpcmVzLilcclxuICAvL1xyXG4gIC8vXHJcbiAgLy8gU3BlZWNoUmVjb2duaXRpb27jgqTjg7Pjgr/jg7zjg5XjgqfjgqTjgrnjga5vbnN0YXJ044OX44Ot44OR44OG44Kj44Gv44CBXHJcbiAgLy8g6Z+z5aOw6KqN6K2Y44K144O844OT44K544GM54++5Zyo44GuU3BlZWNoUmVjb2duaXRpb27jgavplqLpgKPku5jjgZHjgonjgozjgabjgYTjgovmlofms5XjgpJcclxuICAvLyDoqo3orZjjgZnjgovjgZPjgajjgpLnm67nmoTjgajjgZfjgabnnYDkv6Hjgqrjg7zjg4fjgqPjgqrjgpLogbTjgY3lp4vjgoHjgZ/jgajjgY3jgavlrp/ooYzjgZXjgozjgotcclxuICAvLyDjgqTjg5njg7Pjg4jjg4/jg7Pjg4njg6njgpLooajjgZfjgb7jgZnvvIjplovlp4vjgqTjg5njg7Pjg4jjgYznmbrnlJ/jgZfjgZ/jgajjgY3vvInjgIJcclxuICBzZXQgb25zdGFydChoYW5kbGVyOiAoZXY6IEV2ZW50KSA9PiBhbnkpIHtcclxuICAgIHRoaXMuc3RhcnRIYW5kbGVyID0gaGFuZGxlcjtcclxuICB9XHJcblxyXG4gIC8vIFRoZSBvbmVuZCBwcm9wZXJ0eSBvZiB0aGUgU3BlZWNoUmVjb2duaXRpb24gaW50ZXJmYWNlIHJlcHJlc2VudHNcclxuICAvLyBhbiBldmVudCBoYW5kbGVyIHRoYXQgd2lsbCBydW4gd2hlbiB0aGUgc3BlZWNoIHJlY29nbml0aW9uXHJcbiAgLy8gc2VydmljZSBoYXMgZGlzY29ubmVjdGVkICh3aGVuIHRoZSBlbmQgZXZlbnQgZmlyZXMuKVxyXG4gIC8vXHJcbiAgLy8gU3BlZWNoUmVjb2duaXRpb27jgqTjg7Pjgr/jg7zjg5XjgqfjgqTjgrnjga5vbmVuZOODl+ODreODkeODhuOCo+OBr+OAgVxyXG4gIC8vIOmfs+WjsOiqjeitmOOCteODvOODk+OCueOBjOWIh+aWreOBleOCjOOBn+OBqOOBje+8iOe1guS6huOCpOODmeODs+ODiOOBjOeZuueUn+OBl+OBn+OBqOOBje+8ieOBq1xyXG4gIC8vIOWun+ihjOOBleOCjOOCi+OCpOODmeODs+ODiOODj+ODs+ODieODqeOCkuihqOOBl+OBvuOBmeOAglxyXG4gIHNldCBvbmVuZChoYW5kbGVyOiAoZXY6IEV2ZW50KSA9PiBhbnkpIHtcclxuICAgIHRoaXMuZW5kSGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgfVxyXG5cclxuICAvLyBUaGUgc3RhcnQoKSBtZXRob2Qgb2YgdGhlIFdlYiBTcGVlY2ggQVBJIHN0YXJ0cyB0aGUgc3BlZWNoIHJlY29nbml0aW9uIHNlcnZpY2VcclxuICAvLyBsaXN0ZW5pbmcgdG8gaW5jb21pbmcgYXVkaW8gd2l0aCBpbnRlbnQgdG8gcmVjb2duaXplIGdyYW1tYXJzXHJcbiAgLy8gYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IFNwZWVjaFJlY29nbml0aW9uLlxyXG4gIC8vXHJcbiAgLy8gV2ViIFNwZWVjaCBBUEnjga5zdGFydO+8iO+8ieODoeOCveODg+ODieOBr+OAgeePvuWcqOOBrlNwZWVjaFJlY29nbml0aW9u44GrXHJcbiAgLy8g6Zai6YCj5LuY44GR44KJ44KM44Gf5paH5rOV44KS6KqN6K2Y44GZ44KL44GT44Go44KS55uu55qE44Go44GX44Gm44CBXHJcbiAgLy8g552A5L+h6Z+z5aOw44KS6IG05Y+W44GZ44KL6Z+z5aOw6KqN6K2Y44K144O844OT44K544KS6ZaL5aeL44GX44G+44GZ44CCXHJcbiAgcHVibGljIHN0YXJ0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbnRlcm5hbC5zdGFydCgpO1xyXG4gICAgdGhpcy5yZWYudGljaygpO1xyXG4gIH1cclxuXHJcbiAgLy8gVGhlIHN0b3AoKSBtZXRob2Qgb2YgdGhlIFdlYiBTcGVlY2ggQVBJIHN0b3BzIHRoZSBzcGVlY2ggcmVjb2duaXRpb24gc2VydmljZVxyXG4gIC8vIGZyb20gbGlzdGVuaW5nIHRvIGluY29taW5nIGF1ZGlvLCBhbmQgYXR0ZW1wdHMgdG8gcmV0dXJuIGEgU3BlZWNoUmVjb2duaXRpb25SZXN1bHRcclxuICAvLyB1c2luZyB0aGUgYXVkaW8gY2FwdHVyZWQgc28gZmFyLlxyXG4gIC8vXHJcbiAgLy8gV2ViIFNwZWVjaCBBUEnjga5zdG9w77yI77yJ44Oh44K944OD44OJ44Gv44CB6Z+z5aOw6KqN6K2Y44K144O844OT44K544GM552A5L+h6Z+z5aOw44KS6IG05Y+W44GZ44KL44Gu44KS5YGc5q2i44GX44CBXHJcbiAgLy8g44GT44KM44G+44Gn44Gr5Y+W5b6X44GX44Gf6Z+z5aOw44KS5L2/55So44GX44GmU3BlZWNoUmVjb2duaXRpb25SZXN1bHTjgpLov5TjgZ3jgYbjgajjgZfjgb7jgZnjgIJcclxuICBwdWJsaWMgc3RvcCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW50ZXJuYWwuc3RvcCgpO1xyXG4gICAgdGhpcy5yZWYudGljaygpO1xyXG4gIH1cclxuXHJcbiAgLy8gVGhlIGFib3J0KCkgbWV0aG9kIG9mIHRoZSBXZWIgU3BlZWNoIEFQSSBzdG9wcyB0aGUgc3BlZWNoIHJlY29nbml0aW9uIHNlcnZpY2VcclxuICAvLyBmcm9tIGxpc3RlbmluZyB0byBpbmNvbWluZyBhdWRpbywgYW5kIGRvZXNuJ3QgYXR0ZW1wdCB0byByZXR1cm5cclxuICAvLyBhIFNwZWVjaFJlY29nbml0aW9uUmVzdWx0LlxyXG4gIC8vXHJcbiAgLy8gV2ViIFNwZWVjaCBBUEnjga5hYm9ydO+8iO+8ieODoeOCveODg+ODieOBr+OAgemfs+WjsOiqjeitmOOCteODvOODk+OCueOBjOedgOS/oeOCquODvOODh+OCo+OCquOCkuiBtOOBj+OBruOCkuOChOOCgeOAgVxyXG4gIC8vIFNwZWVjaFJlY29nbml0aW9uUmVzdWx044KS6L+U44Gd44GG44Go44GX44G+44Gb44KT44CCXHJcbiAgcHVibGljIGFib3J0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbnRlcm5hbC5hYm9ydCgpO1xyXG4gICAgdGhpcy5yZWYudGljaygpO1xyXG4gIH1cclxuXHJcblxyXG59XHJcbiJdfQ==