UNPKG

ngx-material-timepicker-decon

Version:
473 lines 44.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, EventEmitter, HostListener, Input, Output, TemplateRef, ViewChild } from '@angular/core'; import { merge } from 'rxjs'; import { NgxMaterialTimepickerService } from './services/ngx-material-timepicker.service'; import { TimeUnit } from './models/time-unit.enum'; import { animate, style, transition, trigger } from '@angular/animations'; import { NgxMaterialTimepickerEventService } from './services/ngx-material-timepicker-event.service'; import { filter } from 'rxjs/operators'; /** @enum {string} */ var AnimationState = { ENTER: 'enter', LEAVE: 'leave', }; export { AnimationState }; /** @enum {number} */ var KeyboardTypes = { 'NUMPAD': 0, 'CLOCK': 1, }; export { KeyboardTypes }; KeyboardTypes[KeyboardTypes['NUMPAD']] = 'NUMPAD'; KeyboardTypes[KeyboardTypes['CLOCK']] = 'CLOCK'; /** @type {?} */ var ESCAPE = 27; var NgxMaterialTimepickerComponent = /** @class */ (function () { function NgxMaterialTimepickerComponent(timepickerService, eventService) { var _this = this; this.timepickerService = timepickerService; this.eventService = eventService; this.timeUnit = TimeUnit; this.activeTimeUnit = TimeUnit.HOUR; this.isOpened = false; this.keyboardTypes = KeyboardTypes; this.isEsc = true; this.keyboardType = KeyboardTypes.NUMPAD; this.keyboardTypeChanged = new EventEmitter(); this.timeSet = new EventEmitter(); this.opened = new EventEmitter(); this.closed = new EventEmitter(); this.hourSelected = new EventEmitter(); this.subscriptions = []; this.subscriptions.push(merge(this.eventService.backdropClick, this.eventService.keydownEvent.pipe(filter(function (e) { return e.keyCode === ESCAPE && _this.isEsc; }))) .subscribe(function () { return _this.close(); })); } Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "minutesGap", { get: /** * @return {?} */ function () { return this._minutesGap; }, set: /** * @param {?} gap * @return {?} */ function (gap) { if (gap == null) { return; } gap = Math.floor(gap); this._minutesGap = gap <= 59 ? gap : 1; }, enumerable: true, configurable: true }); Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "defaultTime", { set: /** * @param {?} time * @return {?} */ function (time) { this.setDefaultTime(time); }, enumerable: true, configurable: true }); /** * @return {?} */ NgxMaterialTimepickerComponent.blurAll = /** * @return {?} */ function () { // const tmp = document.createElement('input'); // document.body.appendChild(tmp); // tmp.focus(); // document.body.removeChild(tmp); /** @type {?} */ var btn = document.querySelector('.hidden-button'); if (btn) { btn.focus(); } }; Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "minTime", { get: /** * @return {?} */ function () { return this.timepickerInput && this.timepickerInput.min; }, enumerable: true, configurable: true }); Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "maxTime", { get: /** * @return {?} */ function () { return this.timepickerInput && this.timepickerInput.max; }, enumerable: true, configurable: true }); Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "disabled", { get: /** * @return {?} */ function () { return this.timepickerInput && this.timepickerInput.disabled; }, enumerable: true, configurable: true }); Object.defineProperty(NgxMaterialTimepickerComponent.prototype, "format", { get: /** * @return {?} */ function () { return this.timepickerInput && this.timepickerInput.format; }, enumerable: true, configurable: true }); /** * @return {?} */ NgxMaterialTimepickerComponent.prototype.ngOnInit = /** * @return {?} */ function () { var _this = this; this.subscriptions.push(this.timepickerService.selectedHour .subscribe(function (hour) { return _this.selectedHour = hour; })); this.subscriptions.push(this.timepickerService.selectedMinute .subscribe(function (minute) { return _this.selectedMinute = minute; })); this.subscriptions.push(this.timepickerService.selectedPeriod .subscribe(function (period) { return _this.selectedPeriod = period; })); }; /** * @param {?} type * @return {?} */ NgxMaterialTimepickerComponent.prototype.changeKeyboardType = /** * @param {?} type * @return {?} */ function (type) { this.keyboardType = type; this.keyboardTypeChanged.emit(type); }; /*** * Register an input with this timepicker. * input - The timepicker input to register with this timepicker */ /** * * Register an input with this timepicker. * input - The timepicker input to register with this timepicker * @param {?} input * @return {?} */ NgxMaterialTimepickerComponent.prototype.registerInput = /** * * Register an input with this timepicker. * input - The timepicker input to register with this timepicker * @param {?} input * @return {?} */ function (input) { if (this.timepickerInput) { throw Error('A Timepicker can only be associated with a single input.'); } this.timepickerInput = input; }; /** * @param {?} hour * @return {?} */ NgxMaterialTimepickerComponent.prototype.onHourChange = /** * @param {?} hour * @return {?} */ function (hour) { this.timepickerService.hour = hour; }; /** * @param {?} hour * @return {?} */ NgxMaterialTimepickerComponent.prototype.onHourSelected = /** * @param {?} hour * @return {?} */ function (hour) { this.changeTimeUnit(TimeUnit.MINUTE); this.hourSelected.next(hour); }; /** * @param {?} minute * @return {?} */ NgxMaterialTimepickerComponent.prototype.onMinuteChange = /** * @param {?} minute * @return {?} */ function (minute) { this.timepickerService.minute = minute; }; /** * @param {?} period * @return {?} */ NgxMaterialTimepickerComponent.prototype.changePeriod = /** * @param {?} period * @return {?} */ function (period) { this.timepickerService.period = period; }; /** * @param {?} unit * @return {?} */ NgxMaterialTimepickerComponent.prototype.changeTimeUnit = /** * @param {?} unit * @return {?} */ function (unit) { this.activeTimeUnit = unit; }; /** * @return {?} */ NgxMaterialTimepickerComponent.prototype.setTime = /** * @return {?} */ function () { this.timeSet.next(this.timepickerService.getFullTime(this.format)); this.close(); }; /** * @param {?} time * @return {?} */ NgxMaterialTimepickerComponent.prototype.setDefaultTime = /** * @param {?} time * @return {?} */ function (time) { this.timepickerService.setDefaultTimeIfAvailable(time, (/** @type {?} */ (this.minTime)), (/** @type {?} */ (this.maxTime)), this.format, this.minutesGap); }; /** * @return {?} */ NgxMaterialTimepickerComponent.prototype.open = /** * @return {?} */ function () { this.isOpened = true; if (!this.disableAnimation) { this.animationState = AnimationState.ENTER; } this.opened.next(); }; /** * @return {?} */ NgxMaterialTimepickerComponent.prototype.close = /** * @return {?} */ function () { if (this.disableAnimation) { this.closeTimepicker(); return; } this.animationState = AnimationState.LEAVE; }; /** * @param {?} event * @return {?} */ NgxMaterialTimepickerComponent.prototype.animationDone = /** * @param {?} event * @return {?} */ function (event) { if (event.phaseName === 'done' && event.toState === AnimationState.LEAVE) { this.closeTimepicker(); } }; /** * @param {?} e * @return {?} */ NgxMaterialTimepickerComponent.prototype.onKeydown = /** * @param {?} e * @return {?} */ function (e) { this.eventService.dispatchEvent(e); e.stopPropagation(); }; /** * @return {?} */ NgxMaterialTimepickerComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.subscriptions.forEach(function (subscription) { return subscription.unsubscribe(); }); }; /** * @private * @return {?} */ NgxMaterialTimepickerComponent.prototype.closeTimepicker = /** * @private * @return {?} */ function () { this.isOpened = false; this.activeTimeUnit = TimeUnit.HOUR; this.closed.next(); }; /** * @param {?} k * @return {?} */ NgxMaterialTimepickerComponent.prototype.numPadPressed = /** * @param {?} k * @return {?} */ function (k) { NgxMaterialTimepickerComponent.blurAll(); this.timepickerService.keyboardClick.emit(new KeyboardEvent('keypress', (/** @type {?} */ ({ ctrlKey: true, key: k, charCode: k === 'Backspace' ? 46 : k.charCodeAt(0), keyCode: k === 'Backspace' ? 46 : k.charCodeAt(0) })))); }; NgxMaterialTimepickerComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-material-timepicker', template: "<div class=\"timepicker-backdrop-overlay\" *ngIf=\"isOpened\" [overlay]=\"preventOverlayClick\"></div>\n<div class=\"timepicker-overlay\" *ngIf=\"isOpened\">\n <div class=\"timepicker\" [@timepicker]=\"animationState\" (@timepicker.done)=\"animationDone($event)\">\n <header class=\"timepicker__header\">\n <button class=\"hidden-button\"></button>\n <button class=\"change-type-button\" *ngIf=\"keyboardType === keyboardTypes.NUMPAD\" (click)=\"changeKeyboardType(keyboardTypes.CLOCK)\">\n <i class=\"decontimepicker-clock\"></i>\n </button>\n <button class=\"change-type-button\" *ngIf=\"keyboardType === keyboardTypes.CLOCK\" (click)=\"changeKeyboardType(keyboardTypes.NUMPAD)\">\n <i class=\"decontimepicker-keypad\"></i>\n </button>\n <ngx-material-timepicker-dial [format]=\"format\" [hour]=\"selectedHour?.time\"\n [minute]=\"selectedMinute?.time\"\n [period]=\"selectedPeriod\" [activeTimeUnit]=\"activeTimeUnit\"\n [minTime]=\"minTime\" [maxTime]=\"maxTime\"\n [isEditable]=\"enableKeyboardInput\"\n [editableHintTmpl]=\"editableHintTmpl\"\n [minutesGap]=\"minutesGap\"\n (periodChanged)=\"changePeriod($event)\"\n (timeUnitChanged)=\"changeTimeUnit($event)\"\n (hourChanged)=\"onHourChange($event)\"\n (minuteChanged)=\"onMinuteChange($event)\"\n ></ngx-material-timepicker-dial>\n </header>\n <div class=\"timepicker__main-content\">\n <div *ngIf=\"keyboardType === keyboardTypes.CLOCK\">\n <div class=\"timepicker__body\" [ngSwitch]=\"activeTimeUnit\">\n <div *ngSwitchCase=\"timeUnit.HOUR\">\n <ngx-material-timepicker-24-hours-face *ngIf=\"format === 24;else ampmHours\"\n (hourChange)=\"onHourChange($event)\"\n [selectedHour]=\"selectedHour\"\n [minTime]=\"minTime\"\n [maxTime]=\"maxTime\"\n [format]=\"format\"\n (hourSelected)=\"onHourSelected($event)\"></ngx-material-timepicker-24-hours-face>\n <ng-template #ampmHours>\n <ngx-material-timepicker-12-hours-face\n (hourChange)=\"onHourChange($event)\"\n [selectedHour]=\"selectedHour\"\n [period]=\"selectedPeriod\"\n [minTime]=\"minTime\"\n [maxTime]=\"maxTime\"\n (hourSelected)=\"onHourSelected($event)\"></ngx-material-timepicker-12-hours-face>\n </ng-template>\n </div>\n <ngx-material-timepicker-minutes-face *ngSwitchCase=\"timeUnit.MINUTE\"\n [selectedMinute]=\"selectedMinute\"\n [selectedHour]=\"selectedHour?.time\"\n [minTime]=\"minTime\"\n [maxTime]=\"maxTime\"\n [format]=\"format\"\n [period]=\"selectedPeriod\"\n [minutesGap]=\"minutesGap\"\n (minuteChange)=\"onMinuteChange($event)\"></ngx-material-timepicker-minutes-face>\n </div>\n </div>\n <div *ngIf=\"keyboardType === keyboardTypes.NUMPAD\">\n <timepicker-numpad (keyPressed)=\"numPadPressed($event)\"></timepicker-numpad>\n </div>\n <div class=\"timepicker__actions\">\n <div (click)=\"close()\">\n <!--suppress HtmlUnknownAttribute -->\n <ng-container *ngTemplateOutlet=\"cancelBtnTmpl ? cancelBtnTmpl : cancelBtnDefault\"></ng-container>\n </div>\n <div (click)=\"setTime()\">\n <!--suppress HtmlUnknownAttribute -->\n <ng-container\n *ngTemplateOutlet=\"confirmBtnTmpl ? confirmBtnTmpl : confirmBtnDefault\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n</div>\n<ng-template #cancelBtnDefault>\n <ngx-material-timepicker-button>Cancel</ngx-material-timepicker-button>\n</ng-template>\n<ng-template #confirmBtnDefault>\n <ngx-material-timepicker-button>Ok</ngx-material-timepicker-button>\n</ng-template>\n", animations: [ trigger('timepicker', [ transition("* => " + AnimationState.ENTER, [ style({ transform: 'translateY(-30%)' }), animate('0.2s ease-out', style({ transform: 'translateY(0)' })) ]), transition(AnimationState.ENTER + " => " + AnimationState.LEAVE, [ style({ transform: 'translateY(0)', opacity: 1 }), animate('0.2s ease-out', style({ transform: 'translateY(-30%)', opacity: 0 })) ]) ]) ], providers: [NgxMaterialTimepickerService], styles: [":host{--body-background-color:#fff;--primary-font-family:'Roboto',sans-serif;--button-color:deepskyblue;--dial-active-color:#fff;--dial-inactive-color:rgba(255, 255, 255, .5);--dial-background-color:deepskyblue;--clock-face-time-active-color:#fff;--clock-face-time-inactive-color:#6c6c6c;--clock-face-inner-time-inactive-color:#929292;--clock-face-time-disabled-color:#c5c5c5;--clock-face-background-color:#f0f0f0;--clock-hand-color:deepskyblue}@font-face{font-family:decontimepicker;src:url(../assets/icons/decontimepicker.eot);src:url(../assets/icons/decontimepicker.eot?#iefix) format(\"embedded-opentype\"),url(../assets/icons/decontimepicker.woff) format(\"woff\"),url(../assets/icons/decontimepicker.ttf) format(\"truetype\"),url(../assets/icons/decontimepicker.svg#decontimepicker) format(\"svg\");font-weight:400;font-style:normal}[class*=decontimepicker-]:before{display:inline-block;font-family:decontimepicker;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.decontimepicker-backspace:before{content:'\\0041'}.decontimepicker-clock:before{content:'\\0042'}.decontimepicker-keypad:before{content:'\\0043'}.timepicker-overlay::ng-deep [class*=decontimepicker-]:before{display:inline-block;font-family:decontimepicker;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.timepicker-overlay::ng-deep .decontimepicker-backspace:before{content:'\\0041'}.timepicker-overlay::ng-deep .decontimepicker-clock:before{content:'\\0042'}.timepicker-overlay::ng-deep .decontimepicker-keypad:before{content:'\\0043'}.simple-keyboard{font-family:HelveticaNeue-Light,Helvetica Neue Light,Helvetica Neue,Helvetica,Arial,Lucida Grande,sans-serif;width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;overflow:hidden;touch-action:manipulation}.simple-keyboard .hg-row{display:flex}.simple-keyboard .hg-row:not(:last-child){margin-bottom:5px}.simple-keyboard .hg-row .hg-button-container,.simple-keyboard .hg-row .hg-button:not(:last-child){margin-right:5px}.simple-keyboard .hg-row>div:last-child{margin-right:0}.simple-keyboard .hg-row .hg-button-container{display:flex}.simple-keyboard .hg-button{display:inline-block;flex-grow:1;cursor:pointer}.simple-keyboard .hg-button span{pointer-events:none}.simple-keyboard.hg-theme-default{background-color:rgba(0,0,0,.1);padding:5px;border-radius:5px}.simple-keyboard.hg-theme-default .hg-button{box-shadow:0 0 3px -1px rgba(0,0,0,.3);height:40px;border-radius:5px;box-sizing:border-box;padding:5px;background:#fff;border-bottom:1px solid #b5b5b5;cursor:pointer;display:flex;align-items:center;justify-content:center}.simple-keyboard button.hg-button{border-width:0;outline:0;font-size:inherit}.simple-keyboard.hg-theme-default:not(.hg-touch-events) .hg-button:active{background:#e4e4e4}.simple-keyboard.hg-theme-default.hg-layout-numeric .hg-button{width:33.3%;height:60px;align-items:center;display:flex;justify-content:center}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadadd,.simple-keyboard.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.simple-keyboard.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.simple-keyboard.hg-theme-default .hg-button.hg-button-com{max-width:85px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.simple-keyboard.hg-theme-default .hg-button.hg-selectedButton{background:rgba(5,25,70,.53);color:#fff}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=\".com\"]{max-width:82px}.simple-keyboard.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=\"@\"]{max-width:60px}.hidden-button{display:block;visibility:hidden;height:1px;width:1px;overflow:hidden;border:0;position:fixed;top:-1px;left:-1px}.timepicker-backdrop-overlay{position:fixed;top:0;bottom:0;right:0;left:0;background-color:rgba(0,0,0,.3);z-index:999;pointer-events:auto}.timepicker-overlay{position:fixed;top:0;left:0;width:100%;height:100%;display:flex;justify-content:center;align-items:center;z-index:999;pointer-events:none}.timepicker{width:300px;border-radius:2px;box-shadow:rgba(0,0,0,.25) 0 14px 45px,rgba(0,0,0,.22) 0 10px 18px;outline:0;position:static;z-index:999;pointer-events:auto}.timepicker__header{color:#fff;padding:15px 30px;background-color:#00bfff}@supports (background-color:var(--dial-background-color)){.timepicker__header{background-color:var(--dial-background-color)}}.timepicker__body{padding:15px 5px;display:flex;justify-content:center;align-items:center;background-color:#fff}@supports (background-color:var(--body-background-color)){.timepicker__body{background-color:var(--body-background-color)}}.timepicker__actions{display:flex;justify-content:flex-end;padding:15px;background-color:#fff}@supports (background-color:var(--body-background-color)){.timepicker__actions{background-color:var(--body-background-color)}}@media (max-device-width:1023px) and (orientation:landscape){.timepicker{display:flex;width:515px}.timepicker__header{display:flex;align-items:center}.timepicker__main-content{display:flex;flex-direction:column;width:100%}.timepicker__actions{padding:5px;margin-top:-1px}}"] }] } ]; /** @nocollapse */ NgxMaterialTimepickerComponent.ctorParameters = function () { return [ { type: NgxMaterialTimepickerService }, { type: NgxMaterialTimepickerEventService } ]; }; NgxMaterialTimepickerComponent.propDecorators = { cancelBtnTmpl: [{ type: Input }], editableHintTmpl: [{ type: Input }], confirmBtnTmpl: [{ type: Input }], isEsc: [{ type: Input, args: ['ESC',] }], enableKeyboardInput: [{ type: Input }], preventOverlayClick: [{ type: Input }], disableAnimation: [{ type: Input }], keyboardType: [{ type: Input }], keyboardTypeChanged: [{ type: Output }], minutesGap: [{ type: Input }], defaultTime: [{ type: Input }], timeSet: [{ type: Output }], opened: [{ type: Output }], closed: [{ type: Output }], hourSelected: [{ type: Output }], timepickerComponent: [{ type: ViewChild, args: ['timepickerww',] }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }] }; return NgxMaterialTimepickerComponent; }()); export { NgxMaterialTimepickerComponent }; if (false) { /** @type {?} */ NgxMaterialTimepickerComponent.prototype.selectedHour; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.selectedMinute; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.selectedPeriod; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.timeUnit; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.activeTimeUnit; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.isOpened; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.animationState; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.keyboardTypes; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.cancelBtnTmpl; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.editableHintTmpl; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.confirmBtnTmpl; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.isEsc; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.enableKeyboardInput; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.preventOverlayClick; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.disableAnimation; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.keyboardType; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.keyboardTypeChanged; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.timeSet; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.opened; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.closed; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.hourSelected; /** @type {?} */ NgxMaterialTimepickerComponent.prototype.timepickerComponent; /** * @type {?} * @private */ NgxMaterialTimepickerComponent.prototype._minutesGap; /** * @type {?} * @private */ NgxMaterialTimepickerComponent.prototype.timepickerInput; /** * @type {?} * @private */ NgxMaterialTimepickerComponent.prototype.subscriptions; /** * @type {?} * @private */ NgxMaterialTimepickerComponent.prototype.timepickerService; /** * @type {?} * @private */ NgxMaterialTimepickerComponent.prototype.eventService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LW1hdGVyaWFsLXRpbWVwaWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXItZGVjb24vIiwic291cmNlcyI6WyJzcmMvYXBwL21hdGVyaWFsLXRpbWVwaWNrZXIvbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHNUksT0FBTyxFQUFFLEtBQUssRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDMUYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxPQUFPLEVBQWtCLEtBQUssRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDMUYsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0sa0RBQWtELENBQUM7QUFDckcsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7SUFLcEMsT0FBUSxPQUFPO0lBQ2YsT0FBUSxPQUFPOzs7OztJQUdmLFdBQVE7SUFDUixVQUFPOzs7NEJBRFAsUUFBUSxLQUFSLFFBQVE7NEJBQ1IsT0FBTyxLQUFQLE9BQU87O0lBR0wsTUFBTSxHQUFHLEVBQUU7QUFFakI7SUF1RUksd0NBQW9CLGlCQUErQyxFQUMvQyxZQUErQztRQURuRSxpQkFPQztRQVBtQixzQkFBaUIsR0FBakIsaUJBQWlCLENBQThCO1FBQy9DLGlCQUFZLEdBQVosWUFBWSxDQUFtQztRQWhEbkUsYUFBUSxHQUFHLFFBQVEsQ0FBQztRQUNwQixtQkFBYyxHQUFHLFFBQVEs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LFNBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDOztJQXlCdkMscUNBQUM7Q0FBQSxBQXBORCxJQW9OQztTQWxNWSw4QkFBOEI7OztJQUV2QyxzREFBNEI7O0lBQzVCLHdEQUE4Qjs7SUFDOUIsd0RBQTJCOztJQUUzQixrREFBb0I7O0lBQ3BCLHdEQUErQjs7SUFFL0Isa0RBQWlCOztJQUNqQix3REFBK0I7O0lBRS9CLHVEQUE4Qjs7SUFFOUIsdURBQTBDOztJQUMxQywwREFBNkM7O0lBQzdDLHdEQUEyQzs7SUFDM0MsK0NBQTJCOztJQUMzQiw2REFBc0M7O0lBQ3RDLDZEQUFzQzs7SUFDdEMsMERBQW1DOztJQUNuQyxzREFBNEQ7O0lBQzVELDZEQUFnRjs7SUFvQmhGLGlEQUErQzs7SUFDL0MsZ0RBQTRDOztJQUM1QyxnREFBNEM7O0lBQzVDLHNEQUFvRDs7SUFFcEQsNkRBQTJEOzs7OztJQUUzRCxxREFBNEI7Ozs7O0lBQzVCLHlEQUE2Qzs7Ozs7SUFDN0MsdURBQTJDOzs7OztJQUUvQiwyREFBdUQ7Ozs7O0lBQ3ZELHNEQUF1RCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDbG9ja0ZhY2VUaW1lIH0gZnJvbSAnLi9tb2RlbHMvY2xvY2stZmFjZS10aW1lLmludGVyZmFjZSc7XG5pbXBvcnQgeyBUaW1lUGVyaW9kIH0gZnJvbSAnLi9tb2RlbHMvdGltZS1wZXJpb2QuZW51bSc7XG5pbXBvcnQgeyBtZXJnZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9uZ3gtbWF0ZXJpYWwtdGltZXBpY2tlci5zZXJ2aWNlJztcbmltcG9ydCB7IFRpbWVVbml0IH0gZnJvbSAnLi9tb2RlbHMvdGltZS11bml0LmVudW0nO1xuaW1wb3J0IHsgYW5pbWF0ZSwgQW5pbWF0aW9uRXZlbnQsIHN0eWxlLCB0cmFuc2l0aW9uLCB0cmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJFdmVudFNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL25neC1tYXRlcmlhbC10aW1lcGlja2VyLWV2ZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGltZXBpY2tlckRpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9uZ3gtdGltZXBpY2tlci5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICdsdXhvbic7XG5cbmV4cG9ydCBlbnVtIEFuaW1hdGlvblN0YXRlIHtcbiAgICBFTlRFUiA9ICdlbnRlcicsXG4gICAgTEVBVkUgPSAnbGVhdmUnXG59XG5leHBvcnQgZW51bSBLZXlib2FyZFR5cGVzIHtcbiAgICAnTlVNUEFEJyxcbiAgICAnQ0xPQ0snXG59XG5cbmNvbnN0IEVTQ0FQRSA9IDI3O1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25neC1tYXRlcmlhbC10aW1lcGlja2VyJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL25neC1tYXRlcmlhbC10aW1lcGlja2VyLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgYW5pbWF0aW9uczogW1xuICAgICAgICB0cmlnZ2VyKCd0aW1lcGlja2VyJywgW1xuICAgICAgICAgICAgdHJhbnNpdGlvbihgKiA9PiAke0FuaW1hdGlvblN0YXRlLkVOVEVSfWAsIFtcbiAgICAgICAgICAgICAgICBzdHlsZSh7dHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMzAlKSd9KSxcbiAgICAgICAgICAgICAgICBhbmltYXRlKCcwLjJzIGVhc2Utb3V0Jywgc3R5bGUoe3RyYW5zZm9ybTogJ3RyYW5zbGF0ZVkoMCknfSkpXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgICAgIHRyYW5zaXRpb24oYCR7QW5pbWF0aW9uU3RhdGUuRU5URVJ9ID0+ICR7QW5pbWF0aW9uU3RhdGUuTEVBVkV9YCwgW1xuICAgICAgICAgICAgICAgIHN0eWxlKHt0cmFuc2Zvcm06ICd0cmFuc2xhdGVZKDApJywgb3BhY2l0eTogMX0pLFxuICAgICAgICAgICAgICAgIGFuaW1hdGUoJzAuMnMgZWFzZS1vdXQnLCBzdHlsZSh7dHJhbnNmb3JtOiAndHJhbnNsYXRlWSgtMzAlKScsIG9wYWNpdHk6IDB9KSlcbiAgICAgICAgICAgIF0pXG4gICAgICAgIF0pXG4gICAgXSxcbiAgICBwcm92aWRlcnM6IFtOZ3hNYXRlcmlhbFRpbWVwaWNrZXJTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgICBzZWxlY3RlZEhvdXI6IENsb2NrRmFjZVRpbWU7XG4gICAgc2VsZWN0ZWRNaW51dGU6IENsb2NrRmFjZVRpbWU7XG4gICAgc2VsZWN0ZWRQZXJpb2Q6IFRpbWVQZXJpb2Q7XG5cbiAgICB0aW1lVW5pdCA9IFRpbWVVbml0O1xuICAgIGFjdGl2ZVRpbWVVbml0ID0gVGltZVVuaXQuSE9VUjtcblxuICAgIGlzT3BlbmVkID0gZmFsc2U7XG4gICAgYW5pbWF0aW9uU3RhdGU6IEFuaW1hdGlvblN0YXRlO1xuXG4gICAga2V5Ym9hcmRUeXBlcyA9IEtleWJvYXJkVHlwZXM7XG5cbiAgICBASW5wdXQoKSBjYW5jZWxCdG5UbXBsOiBUZW1wbGF0ZVJlZjxOb2RlPjtcbiAgICBASW5wdXQoKSBlZGl0YWJsZUhpbnRUbXBsOiBUZW1wbGF0ZVJlZjxOb2RlPjtcbiAgICBASW5wdXQoKSBjb25maXJtQnRuVG1wbDogVGVtcGxhdGVSZWY8Tm9kZT47XG4gICAgQElucHV0KCdFU0MnKSBpc0VzYyA9IHRydWU7XG4gICAgQElucHV0KCkgZW5hYmxlS2V5Ym9hcmRJbnB1dDogYm9vbGVhbjtcbiAgICBASW5wdXQoKSBwcmV2ZW50T3ZlcmxheUNsaWNrOiBib29sZWFuO1xuICAgIEBJbnB1dCgpIGRpc2FibGVBbmltYXRpb246IGJvb2xlYW47XG4gICAgQElucHV0KCkga2V5Ym9hcmRUeXBlOiBLZXlib2FyZFR5cGVzID0gS2V5Ym9hcmRUeXBlcy5OVU1QQUQ7XG4gICAgQE91dHB1dCgpIGtleWJvYXJkVHlwZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxLZXlib2FyZFR5cGVzPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIEBJbnB1dCgpXG4gICAgc2V0IG1pbnV0ZXNHYXAoZ2FwOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGdhcCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZ2FwID0gTWF0aC5mbG9vcihnYXApO1xuICAgICAgICB0aGlzLl9taW51dGVzR2FwID0gZ2FwIDw9IDU5ID8gZ2FwIDogMTtcbiAgICB9XG5cbiAgICBnZXQgbWludXRlc0dhcCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWludXRlc0dhcDtcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBkZWZhdWx0VGltZSh0aW1lOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZXREZWZhdWx0VGltZSh0aW1lKTtcbiAgICB9XG5cbiAgICBAT3V0cHV0KCkgdGltZVNldCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICAgIEBPdXRwdXQoKSBvcGVuZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bGw+KCk7XG4gICAgQE91dHB1dCgpIGNsb3NlZCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVsbD4oKTtcbiAgICBAT3V0cHV0KCkgaG91clNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cbiAgICBAVmlld0NoaWxkKCd0aW1lcGlja2Vyd3cnKSB0aW1lcGlja2VyQ29tcG9uZW50OiBFbGVtZW50UmVmO1xuXG4gICAgcHJpdmF0ZSBfbWludXRlc0dhcDogbnVtYmVyO1xuICAgIHByaXZhdGUgdGltZXBpY2tlcklucHV0OiBUaW1lcGlja2VyRGlyZWN0aXZlO1xuICAgIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgdGltZXBpY2tlclNlcnZpY2U6IE5neE1hdGVyaWFsVGltZXBpY2tlclNlcnZpY2UsXG4gICAgICAgICAgICAgICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IE5neE1hdGVyaWFsVGltZXBpY2tlckV2ZW50U2VydmljZSkge1xuXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKG1lcmdlKHRoaXMuZXZlbnRTZXJ2aWNlLmJhY2tkcm9wQ2xpY2ssXG4gICAgICAgICAgICB0aGlzLmV2ZW50U2VydmljZS5rZXlkb3duRXZlbnQucGlwZShmaWx0ZXIoZSA9PiBlLmtleUNvZGUgPT09IEVTQ0FQRSAmJiB0aGlzLmlzRXNjKSkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuY2xvc2UoKSkpO1xuXG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBibHVyQWxsKCkge1xuICAgICAgICAvLyBjb25zdCB0bXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICAvLyBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRtcCk7XG4gICAgICAgIC8vIHRtcC5mb2N1cygpO1xuICAgICAgICAvLyBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRtcCk7XG4gICAgICAgIGNvbnN0IGJ0bjogSFRNTEJ1dHRvbkVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuaGlkZGVuLWJ1dHRvbicpO1xuICAgICAgICBpZiAoYnRuKSB7XG4gICAgICAgICAgICBidG4uZm9jdXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBtaW5UaW1lKCk6IHN0cmluZyB8IERhdGVUaW1lIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGltZXBpY2tlcklucHV0ICYmIHRoaXMudGltZXBpY2tlcklucHV0Lm1pbjtcbiAgICB9XG5cbiAgICBnZXQgbWF4VGltZSgpOiBzdHJpbmcgfCBEYXRlVGltZSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRpbWVwaWNrZXJJbnB1dCAmJiB0aGlzLnRpbWVwaWNrZXJJbnB1dC5tYXg7XG4gICAgfVxuXG4gICAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy50aW1lcGlja2VySW5wdXQgJiYgdGhpcy50aW1lcGlja2VySW5wdXQuZGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy50aW1lcGlja2VySW5wdXQgJiYgdGhpcy50aW1lcGlja2VySW5wdXQuZm9ybWF0O1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLnNlbGVjdGVkSG91clxuICAgICAgICAgICAgLnN1YnNjcmliZShob3VyID0+IHRoaXMuc2VsZWN0ZWRIb3VyID0gaG91cikpO1xuXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKHRoaXMudGltZXBpY2tlclNlcnZpY2Uuc2VsZWN0ZWRNaW51dGVcbiAgICAgICAgICAgIC5zdWJzY3JpYmUobWludXRlID0+IHRoaXMuc2VsZWN0ZWRNaW51dGUgPSBtaW51dGUpKTtcblxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaCh0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLnNlbGVjdGVkUGVyaW9kXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHBlcmlvZCA9PiB0aGlzLnNlbGVjdGVkUGVyaW9kID0gcGVyaW9kKSk7XG4gICAgfVxuXG4gICAgY2hhbmdlS2V5Ym9hcmRUeXBlKHR5cGU6IEtleWJvYXJkVHlwZXMpIHtcbiAgICAgICAgdGhpcy5rZXlib2FyZFR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmtleWJvYXJkVHlwZUNoYW5nZWQuZW1pdCh0eXBlKTtcbiAgICB9XG5cbiAgICAvKioqXG4gICAgICogUmVnaXN0ZXIgYW4gaW5wdXQgd2l0aCB0aGlzIHRpbWVwaWNrZXIuXG4gICAgICogaW5wdXQgLSBUaGUgdGltZXBpY2tlciBpbnB1dCB0byByZWdpc3RlciB3aXRoIHRoaXMgdGltZXBpY2tlclxuICAgICAqL1xuICAgIHJlZ2lzdGVySW5wdXQoaW5wdXQ6IFRpbWVwaWNrZXJEaXJlY3RpdmUpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudGltZXBpY2tlcklucHV0KSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignQSBUaW1lcGlja2VyIGNhbiBvbmx5IGJlIGFzc29jaWF0ZWQgd2l0aCBhIHNpbmdsZSBpbnB1dC4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRpbWVwaWNrZXJJbnB1dCA9IGlucHV0O1xuICAgIH1cblxuICAgIG9uSG91ckNoYW5nZShob3VyOiBDbG9ja0ZhY2VUaW1lKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGltZXBpY2tlclNlcnZpY2UuaG91ciA9IGhvdXI7XG4gICAgfVxuXG4gICAgb25Ib3VyU2VsZWN0ZWQoaG91cjogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hhbmdlVGltZVVuaXQoVGltZVVuaXQuTUlOVVRFKTtcbiAgICAgICAgdGhpcy5ob3VyU2VsZWN0ZWQubmV4dChob3VyKTtcbiAgICB9XG5cbiAgICBvbk1pbnV0ZUNoYW5nZShtaW51dGU6IENsb2NrRmFjZVRpbWUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50aW1lcGlja2VyU2VydmljZS5taW51dGUgPSBtaW51dGU7XG4gICAgfVxuXG4gICAgY2hhbmdlUGVyaW9kKHBlcmlvZDogVGltZVBlcmlvZCk6IHZvaWQge1xuICAgICAgICB0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLnBlcmlvZCA9IHBlcmlvZDtcbiAgICB9XG5cbiAgICBjaGFuZ2VUaW1lVW5pdCh1bml0OiBUaW1lVW5pdCk6IHZvaWQge1xuICAgICAgICB0aGlzLmFjdGl2ZVRpbWVVbml0ID0gdW5pdDtcbiAgICB9XG5cbiAgICBzZXRUaW1lKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnRpbWVTZXQubmV4dCh0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLmdldEZ1bGxUaW1lKHRoaXMuZm9ybWF0KSk7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICB9XG5cbiAgICBzZXREZWZhdWx0VGltZSh0aW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50aW1lcGlja2VyU2VydmljZS5zZXREZWZhdWx0VGltZUlmQXZhaWxhYmxlKFxuICAgICAgICAgICAgdGltZSwgdGhpcy5taW5UaW1lIGFzIERhdGVUaW1lLCB0aGlzLm1heFRpbWUgYXMgRGF0ZVRpbWUsIHRoaXMuZm9ybWF0LCB0aGlzLm1pbnV0ZXNHYXApO1xuICAgIH1cblxuICAgIG9wZW4oKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNPcGVuZWQgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZUFuaW1hdGlvbikge1xuICAgICAgICAgICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9IEFuaW1hdGlvblN0YXRlLkVOVEVSO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbmVkLm5leHQoKTtcbiAgICB9XG5cbiAgICBjbG9zZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzYWJsZUFuaW1hdGlvbikge1xuICAgICAgICAgICAgdGhpcy5jbG9zZVRpbWVwaWNrZXIoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gQW5pbWF0aW9uU3RhdGUuTEVBVkU7XG4gICAgfVxuXG4gICAgYW5pbWF0aW9uRG9uZShldmVudDogQW5pbWF0aW9uRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LnBoYXNlTmFtZSA9PT0gJ2RvbmUnICYmIGV2ZW50LnRvU3RhdGUgPT09IEFuaW1hdGlvblN0YXRlLkxFQVZFKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlVGltZXBpY2tlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pXG4gICAgb25LZXlkb3duKGU6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgdGhpcy5ldmVudFNlcnZpY2UuZGlzcGF0Y2hFdmVudChlKTtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goc3Vic2NyaXB0aW9uID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNsb3NlVGltZXBpY2tlcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pc09wZW5lZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmFjdGl2ZVRpbWVVbml0ID0gVGltZVVuaXQuSE9VUjtcbiAgICAgICAgdGhpcy5jbG9zZWQubmV4dCgpO1xuICAgIH1cblxuICAgIG51bVBhZFByZXNzZWQoazogc3RyaW5nKSB7XG4gICAgICAgIE5neE1hdGVyaWFsVGltZXBpY2tlckNvbXBvbmVudC5ibHVyQWxsKCk7XG4gICAgICAgIHRoaXMudGltZXBpY2tlclNlcnZpY2Uua2V5Ym9hcmRDbGljay5lbWl0KG5ldyBLZXlib2FyZEV2ZW50KCdrZXlwcmVzcycsIDxhbnk+e1xuICAgICAgICAgICAgY3RybEtleTogdHJ1ZSxcbiAgICAgICAgICAgIGtleTogayxcbiAgICAgICAgICAgIGNoYXJDb2RlOiBrID09PSAnQmFja3NwYWNlJyA/IDQ2IDogay5jaGFyQ29kZUF0KDApLFxuICAgICAgICAgICAga2V5Q29kZTogayA9PT0gJ0JhY2tzcGFjZScgPyA0NiA6IGsuY2hhckNvZGVBdCgwKVxuICAgICAgICB9KSk7XG4gICAgfVxufVxuIl19