ng-voice-inputs
Version:
This library provides Voice Recognition service to fill the form input fields (text, datepicker, textarea, button-click) for Angular application.
411 lines • 39.4 kB
JavaScript
/**
* @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 * as tslib_1 from "tslib";
import { ChangeDetectorRef, Component, EventEmitter, Output, Input, ViewEncapsulation } from '@angular/core';
import { VuiVoiceRecognitionService } from './ng-voice-inputs.service';
import * as moment_ from 'moment/moment';
/** @type {?} */
var moment = moment_;
import VuiResponse from './vui-response';
/** @type {?} */
var DEFAULT_STYLE = {
containerClass: 'centered',
iconStart: 'icon icon-mic',
iconParse: 'icon icon-mic',
iconStop: 'icon icon-mic',
animationParse: 'parsing',
animationListen: 'listening'
};
/** @type {?} */
var DEFAULT_SCROLL_OFFSET = 200;
/** @type {?} */
var DEFAULT_SCROLL_DURATION = 300;
/** @type {?} */
var DEFAULT_SCROLL_DIRECTION = 'vertical';
var NgVoiceInputsComponent = /** @class */ (function () {
function NgVoiceInputsComponent(vuiService, ref) {
var _this = this;
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 {?}
*/
function (duration) {
/** @type {?} */
var interval = setInterval((/**
* @return {?}
*/
function () {
/** @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 {?}
*/
function (offset, duration, direction) {
_this.activeDirection = (offset / offset);
_this.scrollDirection = direction || DEFAULT_SCROLL_DIRECTION;
if (offset == 1) {
offset = window.outerHeight;
}
/** @type {?} */
var val = Math.abs(Math.round((offset / (duration / 100))));
/** @type {?} */
var totalOffset = 0;
/** @type {?} */
var interval = setInterval((/**
* @return {?}
*/
function () {
if (totalOffset >= Math.abs(offset)) {
clearInterval(interval);
}
else {
/** @type {?} */
var opt = {
top: offset < 0 ? -1 * val : val,
left: 0
};
if (direction == 'horizontal') {
opt = {
top: 0,
left: offset < 0 ? -1 * val : val
};
}
window.scrollBy(tslib_1.__assign({}, opt, { behavior: 'smooth' }));
totalOffset = totalOffset + val;
}
}), 100);
});
this.scroll = {
SCROLLDOWN: (/**
* @return {?}
*/
function () {
_this.scrollBy(_this.scrollOffset, _this.scrollDuration);
}),
SCROLLUP: (/**
* @return {?}
*/
function () {
_this.scrollBy(-1 * _this.scrollOffset, _this.scrollDuration);
}),
SCROLLRIGHT: (/**
* @return {?}
*/
function () {
_this.scrollBy(_this.scrollOffset, _this.scrollDuration, 'horizontal');
}),
SCROLLLEFT: (/**
* @return {?}
*/
function () {
_this.scrollBy(-1 * _this.scrollOffset, _this.scrollDuration, 'horizontal');
}),
SCROLLBOTTOM: (/**
* @return {?}
*/
function () {
_this.scrollBy(1, _this.scrollDuration);
}),
SCROLLTOP: (/**
* @return {?}
*/
function () {
_this.scrollToTop(_this.scrollDuration);
}),
SCROLLCONTINUE: (/**
* @return {?}
*/
function () {
/** @type {?} */
var factor = Math.ceil(window.outerHeight / _this.scrollDuration);
console.log(factor * _this.scrollDuration, factor);
_this.scrollBy(window.outerHeight, factor * 1000);
})
};
}
/**
* @return {?}
*/
NgVoiceInputsComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.style = tslib_1.__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 {?}
*/
NgVoiceInputsComponent.prototype.vuiResponseSubscription = /**
* @param {?} data
* @return {?}
*/
function (data) {
this.transcript = '';
/** @type {?} */
var 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 {?} */
var currentInputObj = this.vuiService.inputRefs[currentRef];
/** @type {?} */
var currentEl = currentInputObj.nativeElement;
/** @type {?} */
var 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 {?}
*/
NgVoiceInputsComponent.prototype.setProcess = /**
* @param {?} processType
* @return {?}
*/
function (processType) {
this.process = processType;
this.ref.detectChanges();
};
/**
* @param {?} date
* @param {?=} format
* @return {?}
*/
NgVoiceInputsComponent.prototype.formatDate = /**
* @param {?} date
* @param {?=} format
* @return {?}
*/
function (date, format) {
return moment(date).format(format || 'DD/MM/YYYY');
};
/**
* @return {?}
*/
NgVoiceInputsComponent.prototype.initVoiceRecognition = /**
* @return {?}
*/
function () {
var _this = this;
this.recognition = new window['webkitSpeechRecognition']();
this.recognition.continuous = true;
this.recognition.interimResults = true;
this.recognition.onstart = (/**
* @param {?} event
* @return {?}
*/
function (event) {
_this.setProcess('listening');
});
this.recognition.onresult = (/**
* @param {?} event
* @return {?}
*/
function (event) {
/** @type {?} */
var currentInputObj = _this.vuiService.inputRefs[_this.vuiService.currentRef];
/** @type {?} */
var 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 {?} */
var data = _this.vuiService.interpretSpeech(_this.transcript, opts && opts.type);
/** @type {?} */
var 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 {?}
*/
function () {
_this.setProcess(null);
});
this.recognition.onend = (/**
* @return {?}
*/
function () {
_this.setProcess(null);
});
};
/**
* @return {?}
*/
NgVoiceInputsComponent.prototype.startRecognition = /**
* @return {?}
*/
function () {
this.transcript = '';
this.recognition.start();
};
/**
* @return {?}
*/
NgVoiceInputsComponent.prototype.stopRecognition = /**
* @return {?}
*/
function () {
this.transcript = '';
this.recognition.stop();
this.setProcess(null);
};
NgVoiceInputsComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-voice-input',
template: "\n <div [class]=\"style.containerClass\">\n <i [class]=\"style.iconStart\" mat-raised-button (click)=\"startRecognition()\" *ngIf=\"!process\"></i>\n <i [ngClass]=\"process == 'parsing' ? style.iconParse + ' ' + style.animationParse : style.iconStop + ' ' + style.animationListen\" (click)=\"stopRecognition()\" *ngIf=\"process\"></i>\n </div>\n ",
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 = function () { return [
{ type: VuiVoiceRecognitionService },
{ type: ChangeDetectorRef }
]; };
NgVoiceInputsComponent.propDecorators = {
style: [{ type: Input }],
scrollOffset: [{ type: Input }],
scrollDuration: [{ type: Input }],
onValueChange: [{ type: Output }]
};
return NgVoiceInputsComponent;
}());
export { NgVoiceInputsComponent };
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdm9pY2UtaW5wdXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXZvaWNlLWlucHV0cy8iLCJzb3VyY2VzIjpbImxpYi9uZy12b2ljZS1pbnB1dHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFVLE1BQU0sRUFBRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckgsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdkUsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7O0lBQ25DLE1BQU0sR0FBRyxPQUFPO0FBQ3RCLE9BQU8sV0FBVyxNQUFNLGdCQUFnQixDQUFDOztJQUVuQyxhQUFhLEdBQUc7SUFDcEIsY0FBYyxFQUFFLFVBQVU7SUFDMUIsU0FBUyxFQUFFLGVBQWU7SUFDMUIsU0FBUyxFQUFFLGVBQWU7SUFDMUIsUUFBUSxFQUFFLGVBQWU7SUFDekIsY0FBYyxFQUFFLFNBQVM7SUFDekIsZUFBZSxFQUFFLFdBQVc7Q0FDN0I7O0lBRUsscUJBQXFCLEdBQUcsR0FBRzs7SUFDM0IsdUJBQXVCLEdBQUcsR0FBRzs7SUFDN0Isd0JBQXdCLEdBQUcsVUFBVTtBQUczQztJQXlDRSxnQ0FBb0IsVUFBc0MsRUFBVSxHQUFzQjtRQUExRixpQkFBK0Y7UUFBM0UsZUFBVSxHQUFWLFVBQVUsQ0FBNEI7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQWIxRixrQkFBYSxHQUFzQixJQUFJLFlBQVksRUFBRSxDQUFDOzs7OztRQU10RCxvQkFBZSxHQUFXLENBQUMsQ0FBQyxDQUFDOzs7O1FBSzdCLG9CQUFlLEdBQVcsd0JBQXdCLENBQUM7UUFzQm5ELGdCQUFXOzs7O1FBQUcsVUFBQyxRQUFROztnQkFDakIsUUFBUSxHQUFHLFdBQVc7OztZQUFDOztvQkFDbkIsR0FBRyxHQUFH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QUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hCLENBQUM7O2dCQTNPRixTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLGdCQUFnQjtvQkFDMUIsUUFBUSxFQUFFLCtaQUtDO29CQUNYLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJOztpQkFFdEM7Ozs7Z0JBN0JRLDBCQUEwQjtnQkFEMUIsaUJBQWlCOzs7d0JBc0N2QixLQUFLOytCQUdMLEtBQUs7aUNBR0wsS0FBSztnQ0FHTCxNQUFNOztJQWlOVCw2QkFBQztDQUFBLEFBNU9ELElBNE9DO1NBak9ZLHNCQUFzQjs7O0lBRWpDLDZDQUFpQjs7SUFDakIsNENBQW1COztJQUNuQiw4Q0FBbUI7O0lBQ25CLHlDQUFhOztJQUViLHVDQUNNOztJQUVOLDhDQUNhOztJQUViLGdEQUNlOztJQUVmLCtDQUNzRDs7Ozs7O0lBTXRELGlEQUE2Qjs7Ozs7SUFLN0IsaURBQW1EOztJQXNCbkQsNkNBU0M7O0lBRUQsMENBK0JDOztJQUVELHdDQXlCQzs7Ozs7SUF6RlcsNENBQThDOzs7OztJQUFFLHFDQUE4Qjs7QUFzTTVGLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDOzs7QUFBRztJQUUxQixvQ0FBb0M7SUFDcEMsb0NBQW9DO0lBQ3BDLHVDQUF1QztJQUN2QyxPQUFPLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7QUFDM0MsQ0FBQyxDQUFBLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIE9uSW5pdCwgT3V0cHV0LCBJbnB1dCwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZ1aVZvaWNlUmVjb2duaXRpb25TZXJ2aWNlIH0gZnJvbSAnLi9uZy12b2ljZS1pbnB1dHMuc2VydmljZSc7XG5pbXBvcnQgKiBhcyBtb21lbnRfIGZyb20gJ21vbWVudC9tb21lbnQnO1xuY29uc3QgbW9tZW50ID0gbW9tZW50XztcbmltcG9ydCBWdWlSZXNwb25zZSBmcm9tICcuL3Z1aS1yZXNwb25zZSc7XG5cbmNvbnN0IERFRkFVTFRfU1RZTEUgPSB7XG4gIGNvbnRhaW5lckNsYXNzOiAnY2VudGVyZWQnLFxuICBpY29uU3RhcnQ6ICdpY29uIGljb24tbWljJyxcbiAgaWNvblBhcnNlOiAnaWNvbiBpY29uLW1pYycsXG4gIGljb25TdG9wOiAnaWNvbiBpY29uLW1pYycsXG4gIGFuaW1hdGlvblBhcnNlOiAncGFyc2luZycsXG4gIGFuaW1hdGlvbkxpc3RlbjogJ2xpc3RlbmluZydcbn1cblxuY29uc3QgREVGQVVMVF9TQ1JPTExfT0ZGU0VUID0gMjAwO1xuY29uc3QgREVGQVVMVF9TQ1JPTExfRFVSQVRJT04gPSAzMDA7XG5jb25zdCBERUZBVUxUX1NDUk9MTF9ESVJFQ1RJT04gPSAndmVydGljYWwnO1xuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25nLXZvaWNlLWlucHV0JyxcbiAgdGVtcGxhdGU6IGBcbiAgICAgICAgICAgICAgPGRpdiBbY2xhc3NdPVwic3R5bGUuY29udGFpbmVyQ2xhc3NcIj5cbiAgICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwic3R5bGUuaWNvblN0YXJ0XCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cInN0YXJ0UmVjb2duaXRpb24oKVwiICpuZ0lmPVwiIXByb2Nlc3NcIj48L2k+XG4gICAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwicHJvY2VzcyA9PSAncGFyc2luZycgPyBzdHlsZS5pY29uUGFyc2UgKyAnICcgKyBzdHlsZS5hbmltYXRpb25QYXJzZSA6IHN0eWxlLmljb25TdG9wICsgJyAnICsgc3R5bGUuYW5pbWF0aW9uTGlzdGVuXCIgKGNsaWNrKT1cInN0b3BSZWNvZ25pdGlvbigpXCIgKm5nSWY9XCJwcm9jZXNzXCI+PC9pPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGAsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHN0eWxlVXJsczogWycuL25nLXZvaWNlLWlucHV0cy5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIE5nVm9pY2VJbnB1dHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIHJlY29nbml0aW9uOiBhbnk7XG4gIHRyYW5zY3JpcHQ6IHN0cmluZztcbiAgc2VsZWN0ZWREYXRlOiBEYXRlO1xuICBwcm9jZXNzOiBhbnk7XG5cbiAgQElucHV0KClcbiAgc3R5bGU7XG5cbiAgQElucHV0KClcbiAgc2Nyb2xsT2Zmc2V0O1xuXG4gIEBJbnB1dCgpXG4gIHNjcm9sbER1cmF0aW9uO1xuXG4gIEBPdXRwdXQoKVxuICBvblZhbHVlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAvKipcbiAgICogRGVjaWRlcyBkaXJlY3Rpb24gb2Ygc2Nyb2xsIG1vdmVtZW50ICggVXAgb3IgRG93biApIG9yICggTGVmdCBvciBSaWdodCkgXG4gICAqICt2ZSB2YWx1ZSBpbmRpY2F0ZXMgRG93bi9SaWdodCBhbmQgLXZlIHZhbHVlIGlkaWNhdGVzIFVwL0xlZnRcbiAgICovXG4gIGFjdGl2ZURpcmVjdGlvbjogbnVtYmVyID0gKzE7XG5cbiAgLyoqXG4gICAqIERlY2lkZXMgZGlyZWN0aW9uIG9mIFNjcm9sbCAoIFZlcnRpY2FsIG9yIEhvcml6b250YWwgKVxuICAgKi9cbiAgc2Nyb2xsRGlyZWN0aW9uOiBzdHJpbmcgPSBERUZBVUxUX1NDUk9MTF9ESVJFQ1RJT047XG4gIFxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHZ1aVNlcnZpY2U6IFZ1aVZvaWNlUmVjb2duaXRpb25TZXJ2aWNlLCBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuXG4gICAgdGhpcy5zdHlsZSA9IHsgLi4uREVGQVVMVF9TVFlMRSwgLi4udGhpcy5zdHlsZSB9O1xuICAgIHRoaXMuc2Nyb2xsT2Zmc2V0ID0gdGhpcy5zY3JvbGxPZmZzZXQgfHwgREVGQVVMVF9TQ1JPTExfT0ZGU0VUO1xuICAgIHRoaXMuc2Nyb2xsRHVyYXRpb24gPSB0aGlzLnNjcm9sbER1cmF0aW9uIHx8IERFRkFVTFRfU0NST0xMX0RVUkFUSU9OO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuaW5pdFZvaWNlUmVjb2duaXRpb24oKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gaW5pdGlhbGl6ZSBvciBwYXJzZScpO1xuICAgICAgdGhpcy5zdG9wUmVjb2duaXRpb24oKTtcbiAgICB9XG5cbiAgICB0aGlzLnZ1aVNlcnZpY2UucmVzcG9uc2Uuc3Vic2NyaWJlKHRoaXMudnVpUmVzcG9uc2VTdWJzY3JpcHRpb24uYmluZCh0aGlzKSk7XG4gIH1cblxuICBcblxuICBzY3JvbGxUb1RvcCA9IChkdXJhdGlvbikgPT4ge1xuICAgIGxldCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgdmFyIHBvcyA9IE1hdGguYWJzKE1hdGgucm91bmQoKHdpbmRvdy5wYWdlWU9mZnNldCAvIChkdXJhdGlvbiAvIDEwMCkpKSk7XG4gICAgICAgIGlmICggcG9zID4gMCApIHtcbiAgICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyggMCwgcG9zIC0gMjAgKTsgLy8gaG93IGZhciB0byBzY3JvbGwgb24gZWFjaCBzdGVwXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgICAgICAgfVxuICAgIH0sIDEwMCk7XG4gIH0gXG4gIFxuICBzY3JvbGxCeSA9IChvZmZzZXQsIGR1cmF0aW9uLCBkaXJlY3Rpb24/KSA9PiB7XG4gICAgdGhpcy5hY3RpdmVEaXJlY3Rpb24gPSAob2Zmc2V0IC8gb2Zmc2V0KTtcbiAgICB0aGlzLnNjcm9sbERpcmVjdGlvbiA9IGRpcmVjdGlvbiB8fCBERUZBVUxUX1NDUk9MTF9ESVJFQ1RJT047XG4gICAgaWYgKG9mZnNldCA9PSAxKSB7XG4gICAgICBvZmZzZXQgPSB3aW5kb3cub3V0ZXJIZWlnaHQ7XG4gICAgfVxuICAgIGxldCB2YWwgPSBNYXRoLmFicyhNYXRoLnJvdW5kKChvZmZzZXQgLyAoZHVyYXRpb24gLyAxMDApKSkpOyBcbiAgICBsZXQgdG90YWxPZmZzZXQgPSAwO1xuXG4gICAgbGV0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgaWYgKHRvdGFsT2Zmc2V0ID49IE1hdGguYWJzKG9mZnNldCkpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgb3B0ID0geyBcbiAgICAgICAgICB0b3A6IG9mZnNldCA8IDAgPyAtMSAqIHZhbCA6IHZhbCwgXG4gICAgICAgICAgbGVmdDogMCBcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgICAgICBvcHQgPSB7IFxuICAgICAgICAgICAgdG9wOiAwLCBcbiAgICAgICAgICAgIGxlZnQ6IG9mZnNldCA8IDAgPyAtMSAqIHZhbCA6IHZhbFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgd2luZG93LnNjcm9sbEJ5KHtcbiAgICAgICAgICAuLi5vcHQsIFxuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJ1xuICAgICAgICB9KTtcbiAgICAgICAgdG90YWxPZmZzZXQgPSB0b3RhbE9mZnNldCArIHZhbDtcbiAgICAgIH1cbiAgICAgIFxuICAgIH0sIDEwMCk7XG4gIH1cblxuICBzY3JvbGwgPSB7XG4gICAgU0NST0xMRE9XTjogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxCeSh0aGlzLnNjcm9sbE9mZnNldCwgdGhpcy5zY3JvbGxEdXJhdGlvbik7XG4gICAgfSxcbiAgICBTQ1JPTExVUDogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxCeSgtMSAqIHRoaXMuc2Nyb2xsT2Zmc2V0LCB0aGlzLnNjcm9sbER1cmF0aW9uKTtcbiAgICB9LFxuICAgIFNDUk9MTFJJR0hUOiAoKSA9PiB7XG4gICAgICB0aGlzLnNjcm9sbEJ5KHRoaXMuc2Nyb2xsT2Zmc2V0LCB0aGlzLnNjcm9sbER1cmF0aW9uLCAnaG9yaXpvbnRhbCcpO1xuICAgIH0sXG4gICAgU0NST0xMTEVGVDogKCkgPT4ge1xuICAgICAgdGhpcy5zY3JvbGxCeSgtMSAqIHRoaXMuc2Nyb2xsT2Zmc2V0LCB0aGlzLnNjcm9sbER1cmF0aW9uLCAnaG9yaXpvbnRhbCcpO1xuICAgIH0sXG4gICAgU0NST0xMQk9UVE9NOiAoKSA9PiB7XG4gICAgICB0aGlzLnNjcm9sbEJ5KDEsIHRoaXMuc2Nyb2xsRHVyYXRpb24pO1xuICAgIH0sXG4gICAgU0NST0xMVE9QOiAoKSA9PiB7XG4gICAgICB0aGlzLnNjcm9sbFRvVG9wKHRoaXMuc2Nyb2xsRHVyYXRpb24pO1xuICAgIH0sXG4gICAgU0NST0xMQ09OVElOVUU6ICgpID0+IHtcbiAgICAgIGNvbnN0IGZhY3RvciA9IE1hdGguY2VpbCh3aW5kb3cub3V0ZXJIZWlnaHQgLyB0aGlzLnNjcm9sbER1cmF0aW9uKTtcblxuICAgICAgY29uc29sZS5sb2coZmFjdG9yICogdGhpcy5zY3JvbGxEdXJhdGlvbiwgZmFjdG9yKVxuICAgICAgdGhpcy5zY3JvbGxCeSh3aW5kb3cub3V0ZXJIZWlnaHQsIGZhY3RvciAqIDEwMDApO1xuICAgIH1cbiAgfVxuXG4gIHZ1aVJlc3BvbnNlU3Vic2NyaXB0aW9uKGRhdGEpIHtcbiAgICBcbiAgICB0aGlzLnRyYW5zY3JpcHQgPSAnJztcblxuICAgIGxldCBjdXJyZW50UmVmID0gdGhpcy52dWlTZXJ2aWNlLmN1cnJlbnRSZWY7XG4gICAgaWYgKGRhdGEudHlwZSA9PSAnQ09NTUFORF9ORVhUJykge1xuICAgICAgY3VycmVudFJlZiA9ICsrdGhpcy52dWlTZXJ2aWNlLmN1cnJlbnRSZWY7XG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUgPT0gJ0NPTU1BTkRfUFJFVklPVVMnKSB7XG4gICAgICBjdXJyZW50UmVmID0gLS10aGlzLnZ1aVNlcnZpY2UuY3VycmVudFJlZjtcbiAgICB9IGVsc2UgaWYgKGRhdGEudHlwZSA9PSAnQ09NTUFORF9GSVJTVCcpIHtcbiAgICAgIGN1cnJlbnRSZWYgPSAwO1xuICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09ICdDT01NQU5EX0xBU1QnKSB7XG4gICAgICBjdXJyZW50UmVmID0gdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmcy5sZW5ndGggLSAxO1xuICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09ICdDT01NQU5EX0NMRUFSJykge1xuICAgICAgdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmc1tjdXJyZW50UmVmXS5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgfSBlbHNlIGlmIChkYXRhLnR5cGUgPT0gJ0NPTU1BTkRfQ0xJQ0snKSB7XG4gICAgICB0aGlzLnZ1aVNlcnZpY2UuaW5wdXRSZWZzW2N1cnJlbnRSZWZdLm5hdGl2ZUVsZW1lbnQuY2xpY2soKTtcbiAgICB9IGVsc2UgaWYgKGRhdGEudHlwZS5pbmNsdWRlcygnQ09NTUFORF9TQ1JPTEwnKSkge1xuICAgICAgdGhpcy5zY3JvbGxbZGF0YS50eXBlLnJlcGxhY2UoJ0NPTU1BTkRfJywnJyldLmNhbGwoKTtcbiAgICB9IGVsc2UgaWYgKGRhdGEudHlwZSA9PSAnQ09NTUFORF9TVE9QJykge1xuICAgICAgdGhpcy5zdG9wUmVjb2duaXRpb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY3VycmVudElucHV0T2JqID0gdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmc1tjdXJyZW50UmVmXTtcbiAgICAgIGNvbnN0IGN1cnJlbnRFbCA9IGN1cnJlbnRJbnB1dE9iai5uYXRpdmVFbGVtZW50O1xuICAgICAgY29uc3Qgb3B0cyA9IGN1cnJlbnRJbnB1dE9ialsnb3B0aW9ucyddO1xuXG4gICAgICBpZiAoZGF0YS52YWx1ZSAmJiBkYXRhLnZhbHVlWzBdIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICBpZiAoY3VycmVudEVsLnR5cGUgPT0gJ2RhdGUnIHx8IGN1cnJlbnRFbC50eXBlID09ICdkYXRldGltZScpIHtcbiAgICAgICAgICBjdXJyZW50RWwudmFsdWUgPSB0aGlzLmZvcm1hdERhdGUoZGF0YS52YWx1ZVswXSwgJ1lZWVktTU0tREQnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjdXJyZW50RWwudmFsdWUgPSB0aGlzLmZvcm1hdERhdGUoZGF0YS52YWx1ZVswXSwgb3B0cyAmJiBvcHRzLmZvcm1hdCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnRFbC52YWx1ZSA9IGRhdGEudmFsdWU7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGN1cnJlbnRFbC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgnaW5wdXQnKSk7XG4gICAgICB0aGlzLm9uVmFsdWVDaGFuZ2UuZW1pdChkYXRhKTtcbiAgICB9XG5cbiAgICB0aGlzLnZ1aVNlcnZpY2UuaW5wdXRSZWZzW2N1cnJlbnRSZWZdLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcblxuICAgIHRoaXMuc2V0UHJvY2VzcygnbGlzdGVuaW5nJyk7XG4gIH1cblxuICBzZXRQcm9jZXNzKHByb2Nlc3NUeXBlKSB7XG4gICAgdGhpcy5wcm9jZXNzID0gcHJvY2Vzc1R5cGU7XG4gICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgZm9ybWF0RGF0ZShkYXRlOiBEYXRlLCBmb3JtYXQ/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbW9tZW50KGRhdGUpLmZvcm1hdChmb3JtYXQgfHwgJ0REL01NL1lZWVknKTtcbiAgfVxuXG4gIGluaXRWb2ljZVJlY29nbml0aW9uKCkge1xuXG4gICAgICB0aGlzLnJlY29nbml0aW9uID0gbmV3IHdpbmRvd1snd2Via2l0U3BlZWNoUmVjb2duaXRpb24nXSgpO1xuICAgICAgdGhpcy5yZWNvZ25pdGlvbi5jb250aW51b3VzID0gdHJ1ZTtcbiAgICAgIHRoaXMucmVjb2duaXRpb24uaW50ZXJpbVJlc3VsdHMgPSB0cnVlO1xuXG4gICAgICB0aGlzLnJlY29nbml0aW9uLm9uc3RhcnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5zZXRQcm9jZXNzKCdsaXN0ZW5pbmcnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVjb2duaXRpb24ub25yZXN1bHQgPSAoZXZlbnQpID0+IHtcblxuICAgICAgY29uc3QgY3VycmVudElucHV0T2JqID0gdGhpcy52dWlTZXJ2aWNlLmlucHV0UmVmc1t0aGlzLnZ1aVNlcnZpY2UuY3VycmVudFJlZl07XG4gICAgICBjb25zdCBvcHRzID0gY3VycmVudElucHV0T2JqWydvcHRpb25zJ107XG5cbiAgICAgICAgdGhpcy5zZXRQcm9jZXNzKCdwYXJzaW5nJyk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IGV2ZW50LnJlc3VsdEluZGV4OyBpIDwgZXZlbnQucmVzdWx0cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmIChldmVudC5yZXN1bHRzW2ldLmlzRmluYWwpIHtcbiAgICAgICAgICAgIHRoaXMudHJhbnNjcmlwdCArPSBldmVudC5yZXN1bHRzW2ldWzBdLnRyYW5zY3JpcHQ7XG4gICAgICAgICAgICBsZXQgZGF0YTogYW55ID0gdGhpcy52dWlTZXJ2aWNlLmludGVycHJldFNwZWVjaCh0aGlzLnRyYW5zY3JpcHQsIG9wdHMgJiYgb3B0cy50eXBlKTtcbiAgICAgICAgICAgIGxldCByZXNwID0gbmV3IFZ1aVJlc3BvbnNlKCdpbnZhbGlkJywgZGF0YSk7XG4gICAgICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgICAgICByZXNwID0gbmV3IFZ1aVJlc3BvbnNlKCdkYXRlLXJhbmdlJywgZGF0YSk7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHJlc3AgPSBuZXcgVnVpUmVzcG9uc2UoZGF0YSwgZGF0YS5pbmNsdWRlcygnXycpID8gJycgOiBkYXRhKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMudnVpU2VydmljZS5yZXNwb25zZS5uZXh0KHJlc3ApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZWNvZ25pdGlvbi5vbmVycm9yID0gKCkgPT4geyBcbiAgICAgICAgdGhpcy5zZXRQcm9jZXNzKG51bGwpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZWNvZ25pdGlvbi5vbmVuZCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5zZXRQcm9jZXNzKG51bGwpO1xuICAgICAgfVxuICB9XG5cbiAgc3RhcnRSZWNvZ25pdGlvbigpIHtcbiAgICB0aGlzLnRyYW5zY3JpcHQgPSAnJztcbiAgICB0aGlzLnJlY29nbml0aW9uLnN0YXJ0KCk7XG4gIH1cblxuICBzdG9wUmVjb2duaXRpb24oKSB7XG4gICAgdGhpcy50cmFuc2NyaXB0ID0gJyc7XG4gICAgdGhpcy5yZWNvZ25pdGlvbi5zdG9wKCk7XG4gICAgdGhpcy5zZXRQcm9jZXNzKG51bGwpO1xuICB9XG59XG5cblxuRGF0ZS5wcm90b3R5cGVbJ2lzVmFsaWQnXSA9IGZ1bmN0aW9uICgpIHsgXG4gICAgICAgICAgICAgICBcbiAgLy8gSWYgdGhlIGRhdGUgb2JqZWN0IGlzIGludmFsaWQgaXQgXG4gIC8vIHdpbGwgcmV0dXJuICdOYU4nIG9uIGdldFRpbWUoKSAgIFxuICAvLyBhbmQgTmFOIGlzIG5ldmVyIGVxdWFsIHRvIGl0c2VsZi4gICBcbiAgcmV0dXJuIHRoaXMuZ2V0VGltZSgpID09PSB0aGlzLmdldFRpbWUoKTsgXG59OyAiXX0=