UNPKG

ng-voice-inputs

Version:

This library provides Voice Recognition service to fill the form input fields (text, datepicker, textarea, button-click) for Angular application.

390 lines 38.5 kB
/** * @fileoverview added by tsickle * Generated from: lib/ng-voice-inputs.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, EventEmitter, Output, Input, ViewEncapsulation } from '@angular/core'; import { VuiVoiceRecognitionService } from './ng-voice-inputs.service'; import * as moment_ from 'moment/moment'; /** @type {?} */ const moment = moment_; import VuiResponse from './vui-response'; /** @type {?} */ const DEFAULT_STYLE = { containerClass: 'centered', iconStart: 'icon icon-mic', iconParse: 'icon icon-mic', iconStop: 'icon icon-mic', animationParse: 'parsing', animationListen: 'listening' }; /** @type {?} */ const DEFAULT_SCROLL_OFFSET = 200; /** @type {?} */ const DEFAULT_SCROLL_DURATION = 300; /** @type {?} */ const DEFAULT_SCROLL_DIRECTION = 'vertical'; export class NgVoiceInputsComponent { /** * @param {?} vuiService * @param {?} ref */ constructor(vuiService, ref) { this.vuiService = vuiService; this.ref = ref; this.onValueChange = new EventEmitter(); /** * Decides direction of scroll movement ( Up or Down ) or ( Left or Right) * +ve value indicates Down/Right and -ve value idicates Up/Left */ this.activeDirection = +1; /** * Decides direction of Scroll ( Vertical or Horizontal ) */ this.scrollDirection = DEFAULT_SCROLL_DIRECTION; this.scrollToTop = (/** * @param {?} duration * @return {?} */ (duration) => { /** @type {?} */ let interval = setInterval((/** * @return {?} */ () => { /** @type {?} */ var pos = Math.abs(Math.round((window.pageYOffset / (duration / 100)))); if (pos > 0) { window.scrollTo(0, pos - 20); // how far to scroll on each step } else { clearInterval(interval); } }), 100); }); this.scrollBy = (/** * @param {?} offset * @param {?} duration * @param {?=} direction * @return {?} */ (offset, duration, direction) => { this.activeDirection = (offset / offset); this.scrollDirection = direction || DEFAULT_SCROLL_DIRECTION; if (offset == 1) { offset = window.outerHeight; } /** @type {?} */ let val = Math.abs(Math.round((offset / (duration / 100)))); /** @type {?} */ let totalOffset = 0; /** @type {?} */ let interval = setInterval((/** * @return {?} */ () => { if (totalOffset >= Math.abs(offset)) { clearInterval(interval); } else { /** @type {?} */ let opt = { top: offset < 0 ? -1 * val : val, left: 0 }; if (direction == 'horizontal') { opt = { top: 0, left: offset < 0 ? -1 * val : val }; } window.scrollBy(Object.assign({}, opt, { behavior: 'smooth' })); totalOffset = totalOffset + val; } }), 100); }); this.scroll = { SCROLLDOWN: (/** * @return {?} */ () => { this.scrollBy(this.scrollOffset, this.scrollDuration); }), SCROLLUP: (/** * @return {?} */ () => { this.scrollBy(-1 * this.scrollOffset, this.scrollDuration); }), SCROLLRIGHT: (/** * @return {?} */ () => { this.scrollBy(this.scrollOffset, this.scrollDuration, 'horizontal'); }), SCROLLLEFT: (/** * @return {?} */ () => { this.scrollBy(-1 * this.scrollOffset, this.scrollDuration, 'horizontal'); }), SCROLLBOTTOM: (/** * @return {?} */ () => { this.scrollBy(1, this.scrollDuration); }), SCROLLTOP: (/** * @return {?} */ () => { this.scrollToTop(this.scrollDuration); }), SCROLLCONTINUE: (/** * @return {?} */ () => { /** @type {?} */ const factor = Math.ceil(window.outerHeight / this.scrollDuration); console.log(factor * this.scrollDuration, factor); this.scrollBy(window.outerHeight, factor * 1000); }) }; } /** * @return {?} */ ngOnInit() { this.style = Object.assign({}, DEFAULT_STYLE, this.style); this.scrollOffset = this.scrollOffset || DEFAULT_SCROLL_OFFSET; this.scrollDuration = this.scrollDuration || DEFAULT_SCROLL_DURATION; try { this.initVoiceRecognition(); } catch (e) { console.error('Failed to initialize or parse'); this.stopRecognition(); } this.vuiService.response.subscribe(this.vuiResponseSubscription.bind(this)); } /** * @param {?} data * @return {?} */ vuiResponseSubscription(data) { this.transcript = ''; /** @type {?} */ let currentRef = this.vuiService.currentRef; if (data.type == 'COMMAND_NEXT') { currentRef = ++this.vuiService.currentRef; } else if (data.type == 'COMMAND_PREVIOUS') { currentRef = --this.vuiService.currentRef; } else if (data.type == 'COMMAND_FIRST') { currentRef = 0; } else if (data.type == 'COMMAND_LAST') { currentRef = this.vuiService.inputRefs.length - 1; } else if (data.type == 'COMMAND_CLEAR') { this.vuiService.inputRefs[currentRef].nativeElement.value = ''; } else if (data.type == 'COMMAND_CLICK') { this.vuiService.inputRefs[currentRef].nativeElement.click(); } else if (data.type.includes('COMMAND_SCROLL')) { this.scroll[data.type.replace('COMMAND_', '')].call(); } else if (data.type == 'COMMAND_STOP') { this.stopRecognition(); } else { /** @type {?} */ const currentInputObj = this.vuiService.inputRefs[currentRef]; /** @type {?} */ const currentEl = currentInputObj.nativeElement; /** @type {?} */ const opts = currentInputObj['options']; if (data.value && data.value[0] instanceof Date) { if (currentEl.type == 'date' || currentEl.type == 'datetime') { currentEl.value = this.formatDate(data.value[0], 'YYYY-MM-DD'); } else { currentEl.value = this.formatDate(data.value[0], opts && opts.format); } } else { currentEl.value = data.value; } currentEl.dispatchEvent(new Event('input')); this.onValueChange.emit(data); } this.vuiService.inputRefs[currentRef].nativeElement.focus(); this.setProcess('listening'); } /** * @param {?} processType * @return {?} */ setProcess(processType) { this.process = processType; this.ref.detectChanges(); } /** * @param {?} date * @param {?=} format * @return {?} */ formatDate(date, format) { return moment(date).format(format || 'DD/MM/YYYY'); } /** * @return {?} */ initVoiceRecognition() { this.recognition = new window['webkitSpeechRecognition'](); this.recognition.continuous = true; this.recognition.interimResults = true; this.recognition.onstart = (/** * @param {?} event * @return {?} */ (event) => { this.setProcess('listening'); }); this.recognition.onresult = (/** * @param {?} event * @return {?} */ (event) => { /** @type {?} */ const currentInputObj = this.vuiService.inputRefs[this.vuiService.currentRef]; /** @type {?} */ const opts = currentInputObj['options']; this.setProcess('parsing'); for (var i = event.resultIndex; i < event.results.length; ++i) { if (event.results[i].isFinal) { this.transcript += event.results[i][0].transcript; /** @type {?} */ let data = this.vuiService.interpretSpeech(this.transcript, opts && opts.type); /** @type {?} */ let resp = new VuiResponse('invalid', data); if (data) { resp = new VuiResponse('date-range', data); if (typeof data == 'string') { resp = new VuiResponse(data, data.includes('_') ? '' : data); } } this.vuiService.response.next(resp); } } }); this.recognition.onerror = (/** * @return {?} */ () => { this.setProcess(null); }); this.recognition.onend = (/** * @return {?} */ () => { this.setProcess(null); }); } /** * @return {?} */ startRecognition() { this.transcript = ''; this.recognition.start(); } /** * @return {?} */ stopRecognition() { this.transcript = ''; this.recognition.stop(); this.setProcess(null); } } NgVoiceInputsComponent.decorators = [ { type: Component, args: [{ selector: 'ng-voice-input', template: ` <div [class]="style.containerClass"> <i [class]="style.iconStart" mat-raised-button (click)="startRecognition()" *ngIf="!process"></i> <i [ngClass]="process == 'parsing' ? style.iconParse + ' ' + style.animationParse : style.iconStop + ' ' + style.animationListen" (click)="stopRecognition()" *ngIf="process"></i> </div> `, encapsulation: ViewEncapsulation.None, styles: [".centered{margin:auto;text-align:center}.listening{color:red}.parsing{color:green}.icon{position:relative;width:45px;height:45px;display:inline-block;background-size:26px 26px;background-position:7px 7px;background-repeat:no-repeat;cursor:pointer}.icon.parsing::after{opacity:0;position:absolute;top:-5px;left:-5px;right:0;bottom:0;content:'';border:3px solid #42c0fb;border-radius:100%;-webkit-animation-name:ripple;animation-name:ripple;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-delay:0s;animation-delay:0s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.65,0,.34,1);animation-timing-function:cubic-bezier(.65,0,.34,1);z-index:-1}.icon.parsing::before{opacity:0;position:absolute;top:-5px;left:-5px;right:0;bottom:0;content:'';border:3px solid #42c0fb;border-radius:100%;-webkit-animation-name:ripple;animation-name:ripple;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-delay:.3s;animation-delay:.3s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.65,0,.34,1);animation-timing-function:cubic-bezier(.65,0,.34,1);z-index:-1}.icon.listening::after{opacity:0;position:absolute;top:-5px;left:-5px;right:0;bottom:0;content:'';border:3px solid #42c0fb44;border-radius:100%;-webkit-animation-name:ripple;animation-name:ripple;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-delay:0s;animation-delay:0s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:cubic-bezier(.65,0,.34,1);animation-timing-function:cubic-bezier(.65,0,.34,1);z-index:-1}.icon-small{width:25px;height:25px;background-size:15px 15px;background-position:5px 10px}.icon-mic{background-image:url(\"data:image/svg+xml;utf8,<svg version='1.0' xmlns='http://www.w3.org/2000/svg' width='853.000000pt' height='1280.000000pt' viewBox='0 0 853.000000 1280.000000' preserveAspectRatio='xMidYMid meet'> <metadata> Created by potrace 1.15, written by Peter Selinger 2001-2017 </metadata> <g transform='translate(0.000000,1280.000000) scale(0.100000,-0.100000)' fill='rgb(66,192,251)' > <path d='M4060 12789 c-194 -22 -402 -81 -577 -164 -472 -224 -789 -626 -894 -1135 l-24 -115 0 -2575 c0 -2452 1 -2579 18 -2665 145 -710 755 -1260 1492 -1345 327 -37 671 21 975 166 473 226 789 629 892 1137 l23 112 0 2575 c0 2448 -1 2579 -18 2665 -116 576 -556 1066 -1134 1264 -227 78 -508 108 -753 80z'/><path d='M301 8004 c-158 -42 -262 -156 -292 -319 -7 -38 -9 -312 -6 -839 3 -648 7 -805 21 -921 64 -538 177 -928 391 -1350 184 -361 380 -630 670 -920 529 -528 1216 -906 2020 -1110 116 -29 231 -56 258 -60 l47 -7 0 -854 0 -854 -657 0 c-717 0 -743 -2 -851 -57 -69 -35 -155 -127 -176 -189 -53 -155 36 -357 203 -463 103 -66 -69 -61 2341 -61 2377 0 2235 -3 2349 54 64 33 144 122 173 194 19 49 23 75 23 182 0 120 -1 128 -32 192 -36 76 -100 146 -165 179 -95 48 -100 49 -820 49 l-678 0 0 854 c0 805 1 855 18 860 9 2 33 7 52 11 406 77 934 271 1313 484 1088 609 1778 1567 1971 2736 48 288 51 352 51 1150 l0 760 -23 58 c-63 155 -190 243 -367 254 -147 10 -260 -32 -350 -129 -32 -34 -63 -80 -76 -115 l-24 -58 -6 -785 c-6 -737 -11 -850 -39 -1050 -100 -705 -417 -1330 -913 -1794 -538 -505 -1229 -810 -2052 -908 -146 -17 -674 -17 -820 0 -663 79 -1253 297 -1735 642 -683 489 -1111 1202 -1230 2050 -28 194 -33 327 -39 1060 l-6 785 -24 58 c-44 111 -161 208 -282 236 -62 15 -175 12 -238 -5z'/></g> </svg>\")}.icon-mic-blue{background-image:url(../../assets/icons/mic-blue-solid.png)}.icon-mic-red{background-image:url(../../assets/icons/mic-red-solid.png)}.icon-mic-green{background-image:url(../../assets/icons/mic-green-solid.png)}@-webkit-keyframes ripple{from{opacity:1;transform:scale3d(.75,.75,1)}to{opacity:0;transform:scale3d(1.5,1.5,1)}}@keyframes ripple{from{opacity:1;transform:scale3d(.75,.75,1)}to{opacity:0;transform:scale3d(1.5,1.5,1)}}"] }] } ]; /** @nocollapse */ NgVoiceInputsComponent.ctorParameters = () => [ { type: VuiVoiceRecognitionService }, { type: ChangeDetectorRef } ]; NgVoiceInputsComponent.propDecorators = { style: [{ type: Input }], scrollOffset: [{ type: Input }], scrollDuration: [{ type: Input }], onValueChange: [{ type: Output }] }; if (false) { /** @type {?} */ NgVoiceInputsComponent.prototype.recognition; /** @type {?} */ NgVoiceInputsComponent.prototype.transcript; /** @type {?} */ NgVoiceInputsComponent.prototype.selectedDate; /** @type {?} */ NgVoiceInputsComponent.prototype.process; /** @type {?} */ NgVoiceInputsComponent.prototype.style; /** @type {?} */ NgVoiceInputsComponent.prototype.scrollOffset; /** @type {?} */ NgVoiceInputsComponent.prototype.scrollDuration; /** @type {?} */ NgVoiceInputsComponent.prototype.onValueChange; /** * Decides direction of scroll movement ( Up or Down ) or ( Left or Right) * +ve value indicates Down/Right and -ve value idicates Up/Left * @type {?} */ NgVoiceInputsComponent.prototype.activeDirection; /** * Decides direction of Scroll ( Vertical or Horizontal ) * @type {?} */ NgVoiceInputsComponent.prototype.scrollDirection; /** @type {?} */ NgVoiceInputsComponent.prototype.scrollToTop; /** @type {?} */ NgVoiceInputsComponent.prototype.scrollBy; /** @type {?} */ NgVoiceInputsComponent.prototype.scroll; /** * @type {?} * @private */ NgVoiceInputsComponent.prototype.vuiService; /** * @type {?} * @private */ NgVoiceInputsComponent.prototype.ref; } Date.prototype['isValid'] = (/** * @return {?} */ function () { // If the date object is invalid it // will return 'NaN' on getTime() // and NaN is never equal to itself. return this.getTime() === this.getTime(); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdm9pY2UtaW5wdXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXZvaWNlLWlucHV0cy8iLCJzb3VyY2VzIjpbImxpYi9uZy12b2ljZS1pbnB1dHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQVUsTUFBTSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNySCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN2RSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQzs7TUFDbkMsTUFBTSxHQUFHLE9BQU87QUFDdEIsT0FBTyxXQUFXLE1BQU0sZ0JBQWdCLENBQUM7O01BRW5DLGFBQWEsR0FBRztJQUNwQixjQUFjLEVBQUUsVUFBVTtJQUMxQixTQUFTLEVBQUUsZUFBZTtJQUMxQixTQUFTLEVBQUUsZUFBZTtJQUMxQixRQUFRLEVBQUUsZUFBZTtJQUN6QixjQUFjLEVBQUUsU0FBUztJQUN6QixlQUFlLEVBQUUsV0FBVztDQUM3Qjs7TUFFSyxxQkFBcUIsR0FBRyxHQUFHOztNQUMzQix1QkFBdUIsR0FBRyxHQUFHOztNQUM3Qix3QkFBd0IsR0FBRyxVQUFVO0FBYzNDLE1BQU0sT0FBTyxzQkFBc0I7Ozs7O0lBOEJqQyxZQUFvQixVQUFzQyxFQUFVLEdBQXNCO1FBQXRFLGVBQVUsR0FBVixVQUFVLENBQTRCO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFiMUYsa0JBQWEsR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQzs7Ozs7UUFNdEQsb0JBQWUsR0FBVyxDQUFDLENBQUMsQ0FBQzs7OztRQUs3QixvQkFBZSxHQUFXLHdCQUF3QixDQUFDO1FBc0JuRCxnQkFBVzs7OztRQUFHLENBQUMsUUFBUSxFQUFFLEVBQUU7O2dCQUNyQixRQUFRLEdBQUcsV0FBVzs7O1lBQUMs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LElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0IsQ0FBQzs7OztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsQ0FBQzs7O1lBM09GLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO2dCQUMxQixRQUFRLEVBQUU7Ozs7O2FBS0M7Z0JBQ1gsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7O2FBRXRDOzs7O1lBN0JRLDBCQUEwQjtZQUQxQixpQkFBaUI7OztvQkFzQ3ZCLEtBQUs7MkJBR0wsS0FBSzs2QkFHTCxLQUFLOzRCQUdMLE1BQU07Ozs7SUFkUCw2Q0FBaUI7O0lBQ2pCLDRDQUFtQjs7SUFDbkIsOENBQW1COztJQUNuQix5Q0FBYTs7SUFFYix1Q0FDTTs7SUFFTiw4Q0FDYTs7SUFFYixnREFDZTs7SUFFZiwrQ0FDc0Q7Ozs7OztJQU10RCxpREFBNkI7Ozs7O0lBSzdCLGlEQUFtRDs7SUFzQm5ELDZDQVNDOztJQUVELDBDQStCQzs7SUFFRCx3Q0F5QkM7Ozs7O0lBekZXLDRDQUE4Qzs7Ozs7SUFBRSxxQ0FBOEI7O0FBc001RixJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQzs7O0FBQUc7SUFFMUIsb0NBQW9DO0lBQ3BDLG9DQUFvQztJQUNwQyx1Q0FBdUM7SUFDdkMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQzNDLENBQUMsQ0FBQSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIE91dHB1dCwgSW5wdXQsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBWdWlWb2ljZVJlY29nbml0aW9uU2VydmljZSB9IGZyb20gJy4vbmctdm9pY2UtaW5wdXRzLnNlcnZpY2UnO1xuaW1wb3J0ICogYXMgbW9tZW50XyBmcm9tICdtb21lbnQvbW9tZW50JztcbmNvbnN0IG1vbWVudCA9IG1vbWVudF87XG5pbXBvcnQgVnVpUmVzcG9uc2UgZnJvbSAnLi92dWktcmVzcG9uc2UnO1xuXG5jb25zdCBERUZBVUxUX1NUWUxFID0ge1xuICBjb250YWluZXJDbGFzczogJ2NlbnRlcmVkJyxcbiAgaWNvblN0YXJ0OiAnaWNvbiBpY29uLW1pYycsXG4gIGljb25QYXJzZTogJ2ljb24gaWNvbi1taWMnLFxuICBpY29uU3RvcDogJ2ljb24gaWNvbi1taWMnLFxuICBhbmltYXRpb25QYXJzZTogJ3BhcnNpbmcnLFxuICBhbmltYXRpb25MaXN0ZW46ICdsaXN0ZW5pbmcnXG59XG5cbmNvbnN0IERFRkFVTFRfU0NST0xMX09GRlNFVCA9IDIwMDtcbmNvbnN0IERFRkFVTFRfU0NST0xMX0RVUkFUSU9OID0gMzAwO1xuY29uc3QgREVGQVVMVF9TQ1JPTExfRElSRUNUSU9OID0gJ3ZlcnRpY2FsJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy12b2ljZS1pbnB1dCcsXG4gIHRlbXBsYXRlOiBgXG4gICAgICAgICAgICAgIDxkaXYgW2NsYXNzXT1cInN0eWxlLmNvbnRhaW5lckNsYXNzXCI+XG4gICAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cInN0eWxlLmljb25TdGFydFwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJzdGFydFJlY29nbml0aW9uKClcIiAqbmdJZj1cIiFwcm9jZXNzXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxpIFtuZ0NsYXNzXT1cInByb2Nlc3MgPT0gJ3BhcnNpbmcnID8gc3R5bGUuaWNvblBhcnNlICsgJyAnICsgc3R5bGUuYW5pbWF0aW9uUGFyc2UgOiBzdHlsZS5pY29uU3RvcCArICcgJyArIHN0eWxlLmFuaW1hdGlvbkxpc3RlblwiIChjbGljayk9XCJzdG9wUmVjb2duaXRpb24oKVwiICpuZ0lmPVwicHJvY2Vzc1wiPjwvaT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzdHlsZVVybHM6IFsnLi9uZy12b2ljZS1pbnB1dHMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOZ1ZvaWNlSW5wdXRzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICByZWNvZ25pdGlvbjogYW55O1xuICB0cmFuc2NyaXB0OiBzdHJpbmc7XG4gIHNlbGVjdGVkRGF0ZTogRGF0ZTtcbiAgcHJvY2VzczogYW55O1xuXG4gIEBJbnB1dCgpXG4gIHN0eWxlO1xuXG4gIEBJbnB1dCgpXG4gIHNjcm9sbE9mZnNldDtcblxuICBASW5wdXQoKVxuICBzY3JvbGxEdXJhdGlvbjtcblxuICBAT3V0cHV0KClcbiAgb25WYWx1ZUNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLyoqXG4gICAqIERlY2lkZXMgZGlyZWN0aW9uIG9mIHNjcm9sbCBtb3ZlbWVudCAoIFVwIG9yIERvd24gKSBvciAoIExlZnQgb3IgUmlnaHQpIFxuICAgKiArdmUgdmFsdWUgaW5kaWNhdGVzIERvd24vUmlnaHQgYW5kIC12ZSB2YWx1ZSBpZGljYXRlcyBVcC9MZWZ0XG4gICAqL1xuICBhY3RpdmVEaXJlY3Rpb246IG51bWJlciA9ICsxO1xuXG4gIC8qKlxuICAgKiBEZWNpZGVzIGRpcmVjdGlvbiBvZiBTY3JvbGwgKCBWZXJ0aWNhbCBvciBIb3Jpem9udGFsIClcbiAgICovXG4gIHNjcm9sbERpcmVjdGlvbjogc3RyaW5nID0gREVGQVVMVF9TQ1JPTExfRElSRUNUSU9OO1xuICBcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB2dWlTZXJ2aWNlOiBWdWlWb2ljZVJlY29nbml0aW9uU2VydmljZSwgcHJpdmF0ZSByZWY6IENoYW5nZURldGVjdG9yUmVmKSB7IH1cblxuICBuZ09uSW5pdCgpIHtcblxuICAgIHRoaXMuc3R5bGUgPSB7IC4uLkRFRkFVTFRfU1RZTEUsIC4uLnRoaXMuc3R5bGUgfTtcbiAgICB0aGlzLnNjcm9sbE9mZnNldCA9IHRoaXMuc2Nyb2xsT2Zmc2V0IHx8IERFRkFVTFRfU0NST0xMX09GRlNFVDtcbiAgICB0aGlzLnNjcm9sbER1cmF0aW9uID0gdGhpcy5zY3JvbGxEdXJhdGlvbiB8fCBERUZBVUxUX1NDUk9MTF9EVVJBVElPTjtcblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmluaXRWb2ljZVJlY29nbml0aW9uKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGluaXRpYWxpemUgb3IgcGFyc2UnKTtcbiAgICAgIHRoaXMuc3RvcFJlY29nbml0aW9uKCk7XG4gICAgfVxuXG4gICAgdGhpcy52dWlTZXJ2aWNlLnJlc3BvbnNlLnN1YnNjcmliZSh0aGlzLnZ1aVJlc3BvbnNlU3Vic2NyaXB0aW9uLmJpbmQodGhpcykpO1xuICB9XG5cbiAgXG5cbiAgc2Nyb2xsVG9Ub3AgPSAoZHVyYXRpb24pID0+IHtcbiAgICBsZXQgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgIHZhciBwb3MgPSBNYXRoLmFicyhNYXRoLnJvdW5kKCh3aW5kb3cucGFnZVlPZmZzZXQgLyAoZHVyYXRpb24gLyAxMDApKSkpO1xuICAgICAgICBpZiAoIHBvcyA+IDAgKSB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oIDAsIHBvcyAtIDIwICk7IC8vIGhvdyBmYXIgdG8gc2Nyb2xsIG9uIGVhY2ggc3RlcFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICB9LCAxMDApO1xuICB9IFxuICBcbiAgc2Nyb2xsQnkgPSAob2Zmc2V0LCBkdXJhdGlvbiwgZGlyZWN0aW9uPykgPT4ge1xuICAgIHRoaXMuYWN0aXZlRGlyZWN0aW9uID0gKG9mZnNldCAvIG9mZnNldCk7XG4gICAgdGhpcy5zY3JvbGxEaXJlY3Rpb24gPSBkaXJlY3Rpb24gfHwgREVGQVVMVF9TQ1JPTExfRElSRUNUSU9OO1xuICAgIGlmIChvZmZzZXQgPT0gMSkge1xuICAgICAgb2Zmc2V0ID0gd2luZG93Lm91dGVySGVpZ2h0O1xuICAgIH1cbiAgICBsZXQgdmFsID0gTWF0aC5hYnMoTWF0aC5yb3VuZCgob2Zmc2V0IC8gKGR1cmF0aW9uIC8gMTAwKSkpKTsgXG4gICAgbGV0IHRvdGFsT2Zmc2V0ID0gMDtcblxuICAgIGxldCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICh0b3RhbE9mZnNldCA+PSBNYXRoLmFicyhvZmZzZXQpKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IG9wdCA9IHsgXG4gICAgICAgICAgdG9wOiBvZmZzZXQgPCAwID8gLTEgKiB2YWwgOiB2YWwsIFxuICAgICAgICAgIGxlZnQ6IDAgXG4gICAgICAgIH07XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgb3B0ID0geyBcbiAgICAgICAgICAgIHRvcDogMCwgXG4gICAgICAgICAgICBsZWZ0OiBvZmZzZXQgPCAwID8gLTEgKiB2YWwgOiB2YWxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHdpbmRvdy5zY3JvbGxCeSh7XG4gICAgICAgICAgLi4ub3B0LCBcbiAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCdcbiAgICAgICAgfSk7XG4gICAgICAgIHRvdGFsT2Zmc2V0ID0gdG90YWxPZmZzZXQgKyB2YWw7XG4gICAgICB9XG4gICAgICBcbiAgICB9LCAxMDApO1xuICB9XG5cbiAgc2Nyb2xsID0ge1xuICAgIFNDUk9MTERPV046ICgpID0+IHtcbiAgICAgIHRoaXMuc2Nyb2xsQnkodGhpcy5zY3JvbGxPZmZzZXQsIHRoaXMuc2Nyb2xsRHVyYXRpb24pO1xuICAgIH0sXG4gICAgU0NST0xMVVA6ICgpID0+IHtcbiAgICAgIHRoaXMuc2Nyb2xsQnkoLTEgKiB0aGlzLnNjcm9sbE9mZnNldCwgdGhpcy5zY3JvbGxEdXJhdGlvbik7XG4gICAgfSxcbiAgICBTQ1JPTExSSUdIVDogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxCeSh0aGlzLnNjcm9sbE9mZnNldCwgdGhpcy5zY3JvbGxEdXJhdGlvbiwgJ2hvcml6b250YWwnKTtcbiAgICB9LFxuICAgIFNDUk9MTExFRlQ6ICgpID0+IHtcbiAgICAgIHRoaXMuc2Nyb2xsQnkoLTEgKiB0aGlzLnNjcm9sbE9mZnNldCwgdGhpcy5zY3JvbGxEdXJhdGlvbiwgJ2hvcml6b250YWwnKTtcbiAgICB9LFxuICAgIFNDUk9MTEJPVFRPTTogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxCeSgxLCB0aGlzLnNjcm9sbER1cmF0aW9uKTtcbiAgICB9LFxuICAgIFNDUk9MTFRPUDogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxUb1RvcCh0aGlzLnNjcm9sbER1cmF0aW9uKTtcbiAgICB9LFxuICAgIFNDUk9MTENPTlRJTlVFOiAoKSA9PiB7XG4gICAgICBjb25zdCBmYWN0b3IgPSBNYXRoLmNlaWwod2luZG93Lm91dGVySGVpZ2h0IC8gdGhpcy5zY3JvbGxEdXJhdGlvbik7XG5cbiAgICAgIGNvbnNvbGUubG9nKGZhY3RvciAqIHRoaXMuc2Nyb2xsRHVyYXRpb24sIGZhY3RvcilcbiAgICAgIHRoaXMuc2Nyb2xsQnkod2luZG93Lm91dGVySGVpZ2h0LCBmYWN0b3IgKiAxMDAwKTtcbiAgICB9XG4gIH1cblxuICB2dWlSZXNwb25zZVN1YnNjcmlwdGlvbihkYXRhKSB7XG4gICAgXG4gICAgdGhpcy50cmFuc2NyaXB0ID0gJyc7XG5cbiAgICBsZXQgY3VycmVudFJlZiA9IHRoaXMudnVpU2VydmljZS5jdXJyZW50UmVmO1xuICAgIGlmIChkYXRhLnR5cGUgPT0gJ0NPTU1BTkRfTkVYVCcpIHtcbiAgICAgIGN1cnJlbnRSZWYgPSArK3RoaXMudnVpU2VydmljZS5jdXJyZW50UmVmO1xuICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09ICdDT01NQU5EX1BSRVZJT1VTJykge1xuICAgICAgY3VycmVudFJlZiA9IC0tdGhpcy52dWlTZXJ2aWNlLmN1cnJlbnRSZWY7XG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUgPT0gJ0NPTU1BTkRfRklSU1QnKSB7XG4gICAgICBjdXJyZW50UmVmID0gMDtcbiAgICB9IGVsc2UgaWYgKGRhdGEudHlwZSA9PSAnQ09NTUFORF9MQVNUJykge1xuICAgICAgY3VycmVudFJlZiA9IHRoaXMudnVpU2VydmljZS5pbnB1dFJlZnMubGVuZ3RoIC0gMTtcbiAgICB9IGVsc2UgaWYgKGRhdGEudHlwZSA9PSAnQ09NTUFORF9DTEVBUicpIHtcbiAgICAgIHRoaXMudnVpU2VydmljZS5pbnB1dFJlZnNbY3VycmVudFJlZl0ubmF0aXZlRWxlbWVudC52YWx1ZSA9ICcnO1xuICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09ICdDT01NQU5EX0NMSUNLJykge1xuICAgICAgdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmc1tjdXJyZW50UmVmXS5uYXRpdmVFbGVtZW50LmNsaWNrKCk7XG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUuaW5jbHVkZXMoJ0NPTU1BTkRfU0NST0xMJykpIHtcbiAgICAgIHRoaXMuc2Nyb2xsW2RhdGEudHlwZS5yZXBsYWNlKCdDT01NQU5EXycsJycpXS5jYWxsKCk7XG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUgPT0gJ0NPTU1BTkRfU1RPUCcpIHtcbiAgICAgIHRoaXMuc3RvcFJlY29nbml0aW9uKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGN1cnJlbnRJbnB1dE9iaiA9IHRoaXMudnVpU2VydmljZS5pbnB1dFJlZnNbY3VycmVudFJlZl07XG4gICAgICBjb25zdCBjdXJyZW50RWwgPSBjdXJyZW50SW5wdXRPYmoubmF0aXZlRWxlbWVudDtcbiAgICAgIGNvbnN0IG9wdHMgPSBjdXJyZW50SW5wdXRPYmpbJ29wdGlvbnMnXTtcblxuICAgICAgaWYgKGRhdGEudmFsdWUgJiYgZGF0YS52YWx1ZVswXSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgaWYgKGN1cnJlbnRFbC50eXBlID09ICdkYXRlJyB8fCBjdXJyZW50RWwudHlwZSA9PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgY3VycmVudEVsLnZhbHVlID0gdGhpcy5mb3JtYXREYXRlKGRhdGEudmFsdWVbMF0sICdZWVlZLU1NLUREJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY3VycmVudEVsLnZhbHVlID0gdGhpcy5mb3JtYXREYXRlKGRhdGEudmFsdWVbMF0sIG9wdHMgJiYgb3B0cy5mb3JtYXQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW50RWwudmFsdWUgPSBkYXRhLnZhbHVlO1xuICAgICAgfVxuICAgICAgXG4gICAgICBjdXJyZW50RWwuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2lucHV0JykpO1xuICAgICAgdGhpcy5vblZhbHVlQ2hhbmdlLmVtaXQoZGF0YSk7XG4gICAgfVxuXG4gICAgdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmc1tjdXJyZW50UmVmXS5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cbiAgICB0aGlzLnNldFByb2Nlc3MoJ2xpc3RlbmluZycpO1xuICB9XG5cbiAgc2V0UHJvY2Vzcyhwcm9jZXNzVHlwZSkge1xuICAgIHRoaXMucHJvY2VzcyA9IHByb2Nlc3NUeXBlO1xuICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIGZvcm1hdERhdGUoZGF0ZTogRGF0ZSwgZm9ybWF0Pzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG1vbWVudChkYXRlKS5mb3JtYXQoZm9ybWF0IHx8ICdERC9NTS9ZWVlZJyk7XG4gIH1cblxuICBpbml0Vm9pY2VSZWNvZ25pdGlvbigpIHtcblxuICAgICAgdGhpcy5yZWNvZ25pdGlvbiA9IG5ldyB3aW5kb3dbJ3dlYmtpdFNwZWVjaFJlY29nbml0aW9uJ10oKTtcbiAgICAgIHRoaXMucmVjb2duaXRpb24uY29udGludW91cyA9IHRydWU7XG4gICAgICB0aGlzLnJlY29nbml0aW9uLmludGVyaW1SZXN1bHRzID0gdHJ1ZTtcblxuICAgICAgdGhpcy5yZWNvZ25pdGlvbi5vbnN0YXJ0ID0gKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuc2V0UHJvY2VzcygnbGlzdGVuaW5nJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlY29nbml0aW9uLm9ucmVzdWx0ID0gKGV2ZW50KSA9PiB7XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRJbnB1dE9iaiA9IHRoaXMudnVpU2VydmljZS5pbnB1dFJlZnNbdGhpcy52dWlTZXJ2aWNlLmN1cnJlbnRSZWZdO1xuICAgICAgY29uc3Qgb3B0cyA9IGN1cnJlbnRJbnB1dE9ialsnb3B0aW9ucyddO1xuXG4gICAgICAgIHRoaXMuc2V0UHJvY2VzcygncGFyc2luZycpO1xuXG4gICAgICAgIGZvciAodmFyIGkgPSBldmVudC5yZXN1bHRJbmRleDsgaSA8IGV2ZW50LnJlc3VsdHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICBpZiAoZXZlbnQucmVzdWx0c1tpXS5pc0ZpbmFsKSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zY3JpcHQgKz0gZXZlbnQucmVzdWx0c1tpXVswXS50cmFuc2NyaXB0O1xuICAgICAgICAgICAgbGV0IGRhdGE6IGFueSA9IHRoaXMudnVpU2VydmljZS5pbnRlcnByZXRTcGVlY2godGhpcy50cmFuc2NyaXB0LCBvcHRzICYmIG9wdHMudHlwZSk7XG4gICAgICAgICAgICBsZXQgcmVzcCA9IG5ldyBWdWlSZXNwb25zZSgnaW52YWxpZCcsIGRhdGEpO1xuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgcmVzcCA9IG5ldyBWdWlSZXNwb25zZSgnZGF0ZS1yYW5nZScsIGRhdGEpO1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICByZXNwID0gbmV3IFZ1aVJlc3BvbnNlKGRhdGEsIGRhdGEuaW5jbHVkZXMoJ18nKSA/ICcnIDogZGF0YSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnZ1aVNlcnZpY2UucmVzcG9uc2UubmV4dChyZXNwKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMucmVjb2duaXRpb24ub25lcnJvciA9ICgpID0+IHsgXG4gICAgICAgIHRoaXMuc2V0UHJvY2VzcyhudWxsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVjb2duaXRpb24ub25lbmQgPSAoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0UHJvY2VzcyhudWxsKTtcbiAgICAgIH1cbiAgfVxuXG4gIHN0YXJ0UmVjb2duaXRpb24oKSB7XG4gICAgdGhpcy50cmFuc2NyaXB0ID0gJyc7XG4gICAgdGhpcy5yZWNvZ25pdGlvbi5zdGFydCgpO1xuICB9XG5cbiAgc3RvcFJlY29nbml0aW9uKCkge1xuICAgIHRoaXMudHJhbnNjcmlwdCA9ICcnO1xuICAgIHRoaXMucmVjb2duaXRpb24uc3RvcCgpO1xuICAgIHRoaXMuc2V0UHJvY2VzcyhudWxsKTtcbiAgfVxufVxuXG5cbkRhdGUucHJvdG90eXBlWydpc1ZhbGlkJ10gPSBmdW5jdGlvbiAoKSB7IFxuICAgICAgICAgICAgICAgXG4gIC8vIElmIHRoZSBkYXRlIG9iamVjdCBpcyBpbnZhbGlkIGl0IFxuICAvLyB3aWxsIHJldHVybiAnTmFOJyBvbiBnZXRUaW1lKCkgICBcbiAgLy8gYW5kIE5hTiBpcyBuZXZlciBlcXVhbCB0byBpdHNlbGYuICAgXG4gIHJldHVybiB0aGlzLmdldFRpbWUoKSA9PT0gdGhpcy5nZXRUaW1lKCk7IFxufTsgIl19