UNPKG

moh-common-lib

Version:

A library of Angular components, services, and styles for B.C. Government Ministry of Health (MoH).

220 lines 19 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, Input, Output, EventEmitter, Optional, Self } from '@angular/core'; import { NgControl } from '@angular/forms'; import { Subject, of } from 'rxjs'; import { GeocoderService } from '../../services/geocoder.service'; import { debounceTime, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators'; import { AbstractFormControl } from '../../models/abstract-form-control'; import { LabelReplacementTag } from '../../models/error-message.interface'; import { CANADA } from '../country/country.component'; import { BRITISH_COLUMBIA } from '../province/province.component'; export class StreetComponent extends AbstractFormControl { /** * @param {?} controlDir * @param {?} geocoderService */ constructor(controlDir, geocoderService) { super(); this.controlDir = controlDir; this.geocoderService = geocoderService; this.label = 'Full street address or rural route'; this.maxlength = '250'; this.labelforId = 'street_' + this.objectId; this.useGeoCoder = false; this.placeholder = 'Street name'; this.required = false; this.valueChange = new EventEmitter(); this.blur = new EventEmitter(); this.select = new EventEmitter(); this.street = ''; /** * The subject that triggers on user text input and gets typeaheadList$ to update. */ this.searchText$ = new Subject(); this._defaultErrMsg = { required: LabelReplacementTag + ' is required.', invalidChar: LabelReplacementTag + ' must contain letters, and numbers and may include special characters such as hyphen, ' + 'period, apostrophe, number sign, ampersand and blank characters.' }; if (controlDir) { controlDir.valueAccessor = this; } } /** * @param {?} val * @return {?} */ set value(val) { if (val) { this.street = val; } } /** * @return {?} */ get value() { return this.street; } /** * @return {?} */ ngOnInit() { super.ngOnInit(); // Set up for using GeoCoder this.typeaheadList$ = this.searchText$.pipe(debounceTime(500), distinctUntilChanged(), // Trigger the network request, get results switchMap((/** * @param {?} searchPhrase * @return {?} */ searchPhrase => { return this.geocoderService.lookup(searchPhrase); })), catchError((/** * @return {?} */ () => this.onError()))); } /** * @param {?} value * @return {?} */ onValueChange(value) { if (this.useGeoCoder) { // set the search string this.search = value; } this._onChange(value); this.valueChange.emit(value); } /** * @param {?} event * @return {?} */ onBlur(event) { this._onTouched(event); this.blur.emit(event); } /** * @param {?} value * @return {?} */ writeValue(value) { if (value !== undefined) { this.street = value; } } // @HostListener('keyup', ['$event']) /** * @param {?} event * @return {?} */ onKeyUp(event) { /** * Filter out 'enter' and other similar keyboard events that can trigger * when user is selecting a typeahead option instead of entering new text. * Without this filter, we do another HTTP request + force disiplay the UI * for now reason */ if (event.keyCode === 13 || event.keyCode === 9) { // enter & tab return; } this.searchText$.next(this.search); } /** * @return {?} */ onError() { // Empty array simulates no result response, nothing for typeahead to iterate over return of([]); } /** * @param {?} event * @return {?} */ onSelect(event) { /** @type {?} */ const data = event.item; this.street = data.street; // Set to defaults in response data.country = CANADA; data.province = BRITISH_COLUMBIA; this.select.emit(data); } } StreetComponent.decorators = [ { type: Component, args: [{ selector: 'common-street', template: "<label for=\"{{labelforId}}\">{{label}}</label>\r\n<div *ngIf=\"useGeoCoder; else NoGeoCoder;\">\r\n <input class=\"form-control\"\r\n spellcheck=\"false\"\r\n type=\"text\"\r\n id=\"{{labelforId}}\"\r\n [ngModel]=\"street\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (blur)=\"onBlur($event)\"\r\n [disabled]=\"disabled\"\r\n [attr.maxlength]=\"maxlength\"\r\n [required]=\"required\"\r\n (keyup)='onKeyUp($event)'\r\n [typeahead]='typeaheadList$'\r\n typeaheadOptionField='fullAddress'\r\n typeaheadMinLength='3'\r\n (typeaheadOnSelect)=\"onSelect($event)\"\r\n [placeholder]=\"placeholder\"\r\n autocomplete=\"off\"/>\r\n</div>\r\n\r\n<!-- Error messages for input -->\r\n<common-error-container\r\n[displayError]=\"controlDir && !disabled && (controlDir.touched || controlDir.dirty) && controlDir.errors\">\r\n <div *ngIf=\"controlDir.errors?.required\">\r\n {{_defaultErrMsg.required}}\r\n </div>\r\n <div *ngIf=\"controlDir.errors?.invalidChar\">\r\n {{_defaultErrMsg.invalidChar}}\r\n </div>\r\n\r\n</common-error-container>\r\n\r\n\r\n<ng-template #NoGeoCoder>\r\n <input class=\"form-control\"\r\n spellcheck=\"false\"\r\n type=\"text\"\r\n id=\"{{labelforId}}\"\r\n [value]=\"street\"\r\n (change)=\"onValueChange($event.target.value)\"\r\n (blur)=\"onBlur($event)\"\r\n [disabled]=\"disabled\"\r\n [required]=\"required\"\r\n [attr.maxlength]=\"maxlength\"\r\n [placeholder]=\"placeholder\"\r\n autocomplete=\"off\"/>\r\n</ng-template>\r\n" }] } ]; /** @nocollapse */ StreetComponent.ctorParameters = () => [ { type: NgControl, decorators: [{ type: Optional }, { type: Self }] }, { type: GeocoderService } ]; StreetComponent.propDecorators = { label: [{ type: Input }], maxlength: [{ type: Input }], labelforId: [{ type: Input }], useGeoCoder: [{ type: Input }], placeholder: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], valueChange: [{ type: Output }], blur: [{ type: Output }], select: [{ type: Output }] }; if (false) { /** @type {?} */ StreetComponent.prototype.label; /** @type {?} */ StreetComponent.prototype.maxlength; /** @type {?} */ StreetComponent.prototype.labelforId; /** @type {?} */ StreetComponent.prototype.useGeoCoder; /** @type {?} */ StreetComponent.prototype.placeholder; /** @type {?} */ StreetComponent.prototype.required; /** @type {?} */ StreetComponent.prototype.valueChange; /** @type {?} */ StreetComponent.prototype.blur; /** @type {?} */ StreetComponent.prototype.select; /** @type {?} */ StreetComponent.prototype.street; /** * The list of results, from API, that is passed to the typeahead list * Result from GeoCoderService address lookup * @type {?} */ StreetComponent.prototype.typeaheadList$; /** * Search string to store result from GeoCoder request * @type {?} * @private */ StreetComponent.prototype.search; /** * The subject that triggers on user text input and gets typeaheadList$ to update. * @type {?} * @private */ StreetComponent.prototype.searchText$; /** @type {?} */ StreetComponent.prototype._defaultErrMsg; /** @type {?} */ StreetComponent.prototype.controlDir; /** * @type {?} * @private */ StreetComponent.prototype.geocoderService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL21vaC1jb21tb24tbGliLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvc3RyZWV0L3N0cmVldC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFjLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFvQixlQUFlLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNwRixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzRixPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN6RSxPQUFPLEVBQWdCLG1CQUFtQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDekYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBTWxFLE1BQU0sT0FBTyxlQUFnQixTQUFRLG1CQUFtQjs7Ozs7SUEyQ3RELFlBQXdDLFVBQXFCLEVBQ3hDLGVBQWdDO1FBQ25ELEtBQUssRUFBRSxDQUFDO1FBRjhCLGVBQVUsR0FBVixVQUFVLENBQVc7UUFDeEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBMUM1QyxVQUFLLEdBQVcsb0NBQW9DLENBQUM7UUFDckQsY0FBUyxHQUFXLEtBQUssQ0FBQztRQUMxQixlQUFVLEdBQVcsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDL0MsZ0JBQVcsR0FBWSxLQUFLLENBQUM7UUFDN0IsZ0JBQVcsR0FBVyxhQUFhLENBQUM7UUFDcEMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQVl6QixnQkFBVyxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBQy9ELFNBQUksR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNsRCxXQUFNLEdBQW1DLElBQUksWUFBWSxFQUFvQixDQUFDO1FBRXhGLFdBQU0sR0FBVyxFQUFFLENBQUM7Ozs7UUFXWixnQkFBVyxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFFNUMsbUJBQWMsR0FBaUI7WUFDN0IsUUFBUSxFQUFHLG1CQUFtQixHQUFHLGVBQWU7WUFDaEQsV0FBVyxFQUFFLG1CQUFtQixHQUFHLHdGQUF3RjtnQkFDOUcsa0VBQWtFO1NBQ2hGLENBQUM7UUFNQSxJQUFLLFVBQVUsRUFBRztZQUNoQixVQUFVLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztTQUNqQztJQUNILENBQUM7Ozs7O0lBeENELElBQ0ksS0FBSyxDQUFFLEdBQVc7UUFDcEIsSUFBSyxHQUFHLEVBQUc7WUFDVCxJQUFJLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQztTQUNuQjtJQUNILENBQUM7Ozs7SUFDRCxJQUFJLEtBQUs7UUFDUCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDckIsQ0FBQzs7OztJQWtDRCxRQUFRO1FBQ04sS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRWpCLDRCQUE0QjtRQUM1QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUN6QyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQ2pCLG9CQUFvQixFQUFFO1FBQ3RCLDJDQUEyQztRQUMzQyxTQUFTOzs7O1FBQUMsWUFBWSxDQUFDLEVBQUU7WUFDdkIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuRCxDQUFDLEVBQUMsRUFDRixVQUFVOzs7UUFBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsQ0FDakMsQ0FBQztJQUNKLENBQUM7Ozs7O0lBRUQsYUFBYSxDQUFFLEtBQVU7UUFDdkIsSUFBSyxJQUFJLENBQUMsV0FBVyxFQUFHO1lBQ3RCLHdCQUF3QjtZQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztTQUNyQjtRQUNELElBQUksQ0FBQyxTQUFTLENBQUUsS0FBSyxDQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUUsS0FBSyxDQUFFLENBQUM7SUFDakMsQ0FBQzs7Ozs7SUFFRCxNQUFNLENBQUUsS0FBVTtRQUNoQixJQUFJLENBQUMsVUFBVSxDQUFFLEtBQUssQ0FBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFFLEtBQUssQ0FBRSxDQUFDO0lBQzFCLENBQUM7Ozs7O0lBRUQsVUFBVSxDQUFFLEtBQVU7UUFDcEIsSUFBSyxLQUFLLEtBQUssU0FBUyxFQUFHO1lBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1NBQ3ZCO0lBQ0gsQ0FBQzs7Ozs7O0lBR0QsT0FBTyxDQUFDLEtBQW9CO1FBQzFCOzs7OztXQUtHO1FBQ0gsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLEVBQUUsSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLENBQUMsRUFBRTtZQUMvQyxjQUFjO1lBQ2QsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Ozs7SUFFRCxPQUFPO1FBQ0wsa0ZBQWtGO1FBQ2xGLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hCLENBQUM7Ozs7O0lBRUQsUUFBUSxDQUFDLEtBQXFCOztjQUN0QixJQUFJLEdBQXFCLEtBQUssQ0FBQyxJQUFJO1FBQ3pDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUxQiw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQztRQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUUsQ0FBQztJQUMzQixDQUFDOzs7WUF2SEYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxlQUFlO2dCQUN6Qixrc0RBQXNDO2FBQ3ZDOzs7O1lBYlEsU0FBUyx1QkF5REYsUUFBUSxZQUFJLElBQUk7WUF2REwsZUFBZTs7O29CQWN2QyxLQUFLO3dCQUNMLEtBQUs7eUJBQ0wsS0FBSzswQkFDTCxLQUFLOzBCQUNMLEtBQUs7dUJBQ0wsS0FBSztvQkFFTCxLQUFLOzBCQVVMLE1BQU07bUJBQ04sTUFBTTtxQkFDTixNQUFNOzs7O0lBbkJQLGdDQUE4RDs7SUFDOUQsb0NBQW1DOztJQUNuQyxxQ0FBd0Q7O0lBQ3hELHNDQUFzQzs7SUFDdEMsc0NBQTZDOztJQUM3QyxtQ0FBbUM7O0lBWW5DLHNDQUF5RTs7SUFDekUsK0JBQTREOztJQUM1RCxpQ0FBd0Y7O0lBRXhGLGlDQUFvQjs7Ozs7O0lBTXBCLHlDQUErQzs7Ozs7O0lBRy9DLGlDQUF1Qjs7Ozs7O0lBRXZCLHNDQUE0Qzs7SUFFNUMseUNBSUU7O0lBR1cscUNBQWdEOzs7OztJQUNoRCwwQ0FBd0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT3B0aW9uYWwsIFNlbGYsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIG9mIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEdlb0FkZHJlc3NSZXN1bHQsIEdlb2NvZGVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2dlb2NvZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBzd2l0Y2hNYXAsIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IFR5cGVhaGVhZE1hdGNoIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC90eXBlYWhlYWQnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdEZvcm1Db250cm9sIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2Fic3RyYWN0LWZvcm0tY29udHJvbCc7XHJcbmltcG9ydCB7IEVycm9yTWVzc2FnZSwgTGFiZWxSZXBsYWNlbWVudFRhZyB9IGZyb20gJy4uLy4uL21vZGVscy9lcnJvci1tZXNzYWdlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IENBTkFEQSB9IGZyb20gJy4uL2NvdW50cnkvY291bnRyeS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBCUklUSVNIX0NPTFVNQklBIH0gZnJvbSAnLi4vcHJvdmluY2UvcHJvdmluY2UuY29tcG9uZW50JztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnY29tbW9uLXN0cmVldCcsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3N0cmVldC5jb21wb25lbnQuaHRtbCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBTdHJlZXRDb21wb25lbnQgZXh0ZW5kcyBBYnN0cmFjdEZvcm1Db250cm9sIGltcGxlbWVudHMgT25Jbml0ICB7XHJcblxyXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnRnVsbCBzdHJlZXQgYWRkcmVzcyBvciBydXJhbCByb3V0ZSc7XHJcbiAgQElucHV0KCkgbWF4bGVuZ3RoOiBzdHJpbmcgPSAnMjUwJztcclxuICBASW5wdXQoKSBsYWJlbGZvcklkOiBzdHJpbmcgPSAnc3RyZWV0XycgKyB0aGlzLm9iamVjdElkO1xyXG4gIEBJbnB1dCgpIHVzZUdlb0NvZGVyOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdTdHJlZXQgbmFtZSc7XHJcbiAgQElucHV0KCkgcmVxdWlyZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KClcclxuICBzZXQgdmFsdWUoIHZhbDogc3RyaW5nICkge1xyXG4gICAgaWYgKCB2YWwgKSB7XHJcbiAgICAgIHRoaXMuc3RyZWV0ID0gdmFsO1xyXG4gICAgfVxyXG4gIH1cclxuICBnZXQgdmFsdWUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdHJlZXQ7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcjxzdHJpbmc+KCk7XHJcbiAgQE91dHB1dCgpIGJsdXI6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIHNlbGVjdDogRXZlbnRFbWl0dGVyPEdlb0FkZHJlc3NSZXN1bHQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxHZW9BZGRyZXNzUmVzdWx0PigpO1xyXG5cclxuICBzdHJlZXQ6IHN0cmluZyA9ICcnO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbGlzdCBvZiByZXN1bHRzLCBmcm9tIEFQSSwgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIHR5cGVhaGVhZCBsaXN0XHJcbiAgICogUmVzdWx0IGZyb20gR2VvQ29kZXJTZXJ2aWNlIGFkZHJlc3MgbG9va3VwXHJcbiAgICovXHJcbiAgdHlwZWFoZWFkTGlzdCQ6IE9ic2VydmFibGU8R2VvQWRkcmVzc1Jlc3VsdFtdPjtcclxuXHJcbiAgLyoqIFNlYXJjaCBzdHJpbmcgdG8gc3RvcmUgcmVzdWx0IGZyb20gR2VvQ29kZXIgcmVxdWVzdCAqL1xyXG4gIHByaXZhdGUgc2VhcmNoOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBzdWJqZWN0IHRoYXQgdHJpZ2dlcnMgb24gdXNlciB0ZXh0IGlucHV0IGFuZCBnZXRzIHR5cGVhaGVhZExpc3QkIHRvIHVwZGF0ZS4gICovXHJcbiAgcHJpdmF0ZSBzZWFyY2hUZXh0JCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcclxuXHJcbiAgX2RlZmF1bHRFcnJNc2c6IEVycm9yTWVzc2FnZSA9IHtcclxuICAgIHJlcXVpcmVkOiAgTGFiZWxSZXBsYWNlbWVudFRhZyArICcgaXMgcmVxdWlyZWQuJyxcclxuICAgIGludmFsaWRDaGFyOiBMYWJlbFJlcGxhY2VtZW50VGFnICsgJyBtdXN0IGNvbnRhaW4gbGV0dGVycywgYW5kIG51bWJlcnMgYW5kIG1heSBpbmNsdWRlIHNwZWNpYWwgY2hhcmFjdGVycyBzdWNoIGFzIGh5cGhlbiwgJyArXHJcbiAgICAgICAgICAgICAgICAgJ3BlcmlvZCwgYXBvc3Ryb3BoZSwgbnVtYmVyIHNpZ24sIGFtcGVyc2FuZCBhbmQgYmxhbmsgY2hhcmFjdGVycy4nXHJcbiAgfTtcclxuXHJcblxyXG4gIGNvbnN0cnVjdG9yKCBAT3B0aW9uYWwoKSBAU2VsZigpIHB1YmxpYyBjb250cm9sRGlyOiBOZ0NvbnRyb2wsXHJcbiAgICAgICAgICAgICAgIHByaXZhdGUgZ2VvY29kZXJTZXJ2aWNlOiBHZW9jb2RlclNlcnZpY2UgKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgaWYgKCBjb250cm9sRGlyICkge1xyXG4gICAgICBjb250cm9sRGlyLnZhbHVlQWNjZXNzb3IgPSB0aGlzO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xyXG5cclxuICAgIC8vIFNldCB1cCBmb3IgdXNpbmcgR2VvQ29kZXJcclxuICAgIHRoaXMudHlwZWFoZWFkTGlzdCQgPSB0aGlzLnNlYXJjaFRleHQkLnBpcGUoXHJcbiAgICAgIGRlYm91bmNlVGltZSg1MDApLFxyXG4gICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICAvLyBUcmlnZ2VyIHRoZSBuZXR3b3JrIHJlcXVlc3QsIGdldCByZXN1bHRzXHJcbiAgICAgIHN3aXRjaE1hcChzZWFyY2hQaHJhc2UgPT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdlb2NvZGVyU2VydmljZS5sb29rdXAoc2VhcmNoUGhyYXNlKTtcclxuICAgICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IoKCkgPT4gdGhpcy5vbkVycm9yKCkpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgb25WYWx1ZUNoYW5nZSggdmFsdWU6IGFueSApIHtcclxuICAgIGlmICggdGhpcy51c2VHZW9Db2RlciApIHtcclxuICAgICAgLy8gc2V0IHRoZSBzZWFyY2ggc3RyaW5nXHJcbiAgICAgIHRoaXMuc2VhcmNoID0gdmFsdWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9vbkNoYW5nZSggdmFsdWUgKTtcclxuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCggdmFsdWUgKTtcclxuICB9XHJcblxyXG4gIG9uQmx1ciggZXZlbnQ6IGFueSApIHtcclxuICAgIHRoaXMuX29uVG91Y2hlZCggZXZlbnQgKTtcclxuICAgIHRoaXMuYmx1ci5lbWl0KCBldmVudCApO1xyXG4gIH1cclxuXHJcbiAgd3JpdGVWYWx1ZSggdmFsdWU6IGFueSApOiB2b2lkIHtcclxuICAgIGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcclxuICAgICAgICB0aGlzLnN0cmVldCA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gQEhvc3RMaXN0ZW5lcigna2V5dXAnLCBbJyRldmVudCddKVxyXG4gIG9uS2V5VXAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcclxuICAgIC8qKlxyXG4gICAgICogRmlsdGVyIG91dCAnZW50ZXInIGFuZCBvdGhlciBzaW1pbGFyIGtleWJvYXJkIGV2ZW50cyB0aGF0IGNhbiB0cmlnZ2VyXHJcbiAgICAgKiB3aGVuIHVzZXIgaXMgc2VsZWN0aW5nIGEgdHlwZWFoZWFkIG9wdGlvbiBpbnN0ZWFkIG9mIGVudGVyaW5nIG5ldyB0ZXh0LlxyXG4gICAgICogV2l0aG91dCB0aGlzIGZpbHRlciwgd2UgZG8gYW5vdGhlciBIVFRQIHJlcXVlc3QgKyBmb3JjZSBkaXNpcGxheSB0aGUgVUlcclxuICAgICAqIGZvciBub3cgcmVhc29uXHJcbiAgICAgKi9cclxuICAgIGlmIChldmVudC5rZXlDb2RlID09PSAxMyB8fCBldmVudC5rZXlDb2RlID09PSA5KSB7XHJcbiAgICAgIC8vIGVudGVyICYgdGFiXHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnNlYXJjaFRleHQkLm5leHQodGhpcy5zZWFyY2gpO1xyXG4gIH1cclxuXHJcbiAgb25FcnJvcigpOiBPYnNlcnZhYmxlPEdlb0FkZHJlc3NSZXN1bHRbXT4ge1xyXG4gICAgLy8gRW1wdHkgYXJyYXkgc2ltdWxhdGVzIG5vIHJlc3VsdCByZXNwb25zZSwgbm90aGluZyBmb3IgdHlwZWFoZWFkIHRvIGl0ZXJhdGUgb3ZlclxyXG4gICAgcmV0dXJuIG9mKFtdKTtcclxuICB9XHJcblxyXG4gIG9uU2VsZWN0KGV2ZW50OiBUeXBlYWhlYWRNYXRjaCk6IHZvaWQge1xyXG4gICAgY29uc3QgZGF0YTogR2VvQWRkcmVzc1Jlc3VsdCA9IGV2ZW50Lml0ZW07XHJcbiAgICB0aGlzLnN0cmVldCA9IGRhdGEuc3RyZWV0O1xyXG5cclxuICAgIC8vIFNldCB0byBkZWZhdWx0cyBpbiByZXNwb25zZVxyXG4gICAgZGF0YS5jb3VudHJ5ID0gQ0FOQURBO1xyXG4gICAgZGF0YS5wcm92aW5jZSA9IEJSSVRJU0hfQ09MVU1CSUE7XHJcbiAgICB0aGlzLnNlbGVjdC5lbWl0KCBkYXRhICk7XHJcbiAgfVxyXG5cclxufVxyXG4iXX0=