book-picker
Version:
<p align="center"> <img width="409" height="331" src="https://raw.githubusercontent.com/ymxk/book-picker/master/book-picker.gif"> </p>
458 lines • 32.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, Output, EventEmitter } from '@angular/core';
import moment from 'moment';
import { HoursOfDay } from './hours-of-day';
import { TimeClass } from './time-class.enum';
import jspath from "jspath";
var TimePickerComponent = /** @class */ (function () {
function TimePickerComponent() {
this.timeCells = [];
this.nowTime = moment();
this.bookeds = new Array();
this.hours = new Array();
this.selected = new EventEmitter();
this.onerror = new EventEmitter();
}
/**
* @return {?}
*/
TimePickerComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.initBooksOrHours();
this.getHoursForDays();
};
/**
* @return {?}
*/
TimePickerComponent.prototype.initBooksOrHours = /**
* @return {?}
*/
function () {
if (!this.bookeds) {
this.bookeds = new Array();
}
if (!this.hours) {
this.hours = new Array();
}
};
/**
* @return {?}
*/
TimePickerComponent.prototype.onClear = /**
* @return {?}
*/
function () {
this.start = null;
this.end = null;
};
/**
* @return {?}
*/
TimePickerComponent.prototype.emitSelected = /**
* @return {?}
*/
function () {
this.selected.emit({ start: this.start, end: this.addHalfHour(this.end) });
};
/**
* @param {?} v
* @return {?}
*/
TimePickerComponent.prototype.addHalfHour = /**
* @param {?} v
* @return {?}
*/
function (v) {
return v ? v.clone().add(30, 'm') : null;
};
/**
* @return {?}
*/
TimePickerComponent.prototype.emitError = /**
* @return {?}
*/
function () {
this.onerror.emit();
};
/**
* @param {?} value
* @return {?}
*/
TimePickerComponent.prototype.onSelected = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (this.start && this.end && this.start.isSame(value, 'm') && this.end.isSame(value, 'm')) {
this.onClear();
this.emitSelected();
return false;
}
if (this.start && this.end && this.start.isSame(value, 'm')) {
this.start = this.end;
this.emitSelected();
return false;
}
if (this.start && this.end && this.end.isSame(value, 'm')) {
this.end = this.start;
this.emitSelected();
return false;
}
if (!this.start && !this.end) {
/** @type {?} */
var x = this.includesDisable(value.clone(), value.clone());
if (x) {
this.emitError();
return false;
}
this.start = value;
this.end = value;
this.emitSelected();
return false;
}
if (value.isBefore(this.start)) {
/** @type {?} */
var x = this.includesDisable(value.clone(), this.start.clone());
if (x) {
this.emitError();
return false;
}
this.end = this.start;
this.start = value;
}
if (value.isAfter(this.start)) {
/** @type {?} */
var x = this.includesDisable(this.start.clone(), value.clone());
if (x) {
this.emitError();
return false;
}
this.end = value;
}
this.emitSelected();
};
/**
* @param {?} start
* @param {?} end
* @return {?}
*/
TimePickerComponent.prototype.includesDisable = /**
* @param {?} start
* @param {?} end
* @return {?}
*/
function (start, end) {
var _this = this;
/** @type {?} */
var range = [];
for (var item = start; item.isBefore(end) || item.isSame(end); item.add(30, 'm')) {
range.push(item.clone());
}
return range.filter((/**
* @param {?} e
* @return {?}
*/
function (e) { return _this.includesBooked(e) || _this.includesCloses(e); })).length > 0;
};
/**
* @param {?} v
* @return {?}
*/
TimePickerComponent.prototype.includesBooked = /**
* @param {?} v
* @return {?}
*/
function (v) {
var _this = this;
return this.bookeds.filter((/**
* @param {?} e
* @return {?}
*/
function (e) { return _this.isBetweenDate(v, e.start, e.end); })).length > 0;
};
/**
* @param {?} v
* @return {?}
*/
TimePickerComponent.prototype.includesCloses = /**
* @param {?} v
* @return {?}
*/
function (v) {
var _this = this;
/** @type {?} */
var ph = this.getOpenHoursOnDated();
if (ph && ph.length == 0) {
return true;
}
return ph.filter((/**
* @param {?} e
* @return {?}
*/
function (e) { return _this.isBetweenNotEnd(v, e.opens, e.closes); })).length == 0;
};
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
TimePickerComponent.prototype.isBetweenNotEnd = /**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
function (v, s, e) {
/** @type {?} */
var vs = this.setHourMinuteIgnorDate(v);
/** @type {?} */
var ss = this.setHourMinuteIgnorDate(s);
/** @type {?} */
var es = this.setHourMinuteIgnorDate(e);
return (vs.isBetween(ss, es, 'm') || vs.isSame(ss, 'm')) ? true : false;
};
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
TimePickerComponent.prototype.isBetweenDate = /**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
function (v, s, e) {
return v.isBetween(s, e) || v.isSame(s) || v.isSame(e);
};
/**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
TimePickerComponent.prototype.isBetweenM = /**
* @param {?} v
* @param {?} s
* @param {?} e
* @return {?}
*/
function (v, s, e) {
return v.isBetween(s, e, 'm') || v.isSame(s, 'm') || v.isSame(e, 'm');
};
/**
* @param {?} value
* @return {?}
*/
TimePickerComponent.prototype.getClassBy = /**
* @param {?} value
* @return {?}
*/
function (value) {
if (this.includesBooked(value)) {
return TimeClass.BOOKED;
}
if (this.includesCloses(value)) {
return TimeClass.DISABLE;
}
if (this.isBetweenM(value, this.start, this.end)) {
return TimeClass.SELECTED;
}
return TimeClass.NORMAL;
};
/**
* @param {?} v
* @return {?}
*/
TimePickerComponent.prototype.isSameDay = /**
* @param {?} v
* @return {?}
*/
function (v) {
return moment().isSame(v, 'month') && moment().isSame(v, 'day');
};
/**
* @return {?}
*/
TimePickerComponent.prototype.getDefaultOpenHours = /**
* @return {?}
*/
function () {
return new HoursOfDay(this.nowTime.clone().startOf('day'), this.nowTime.clone().endOf('day'));
};
/**
* @return {?}
*/
TimePickerComponent.prototype.nextHalfHourInNow = /**
* @return {?}
*/
function () {
/** @type {?} */
var y = parseFloat(this.nowTime.clone().format('mm')) % 30;
return this.addHalfHour(this.nowTime.clone().subtract(y, 'm'));
};
/**
* @param {?} oh
* @return {?}
*/
TimePickerComponent.prototype.replaceStartByNow = /**
* @param {?} oh
* @return {?}
*/
function (oh) {
/** @type {?} */
var start = this.setHourMinuteIgnorDate(oh.start);
if (this.isSameDay(start)) {
return new HoursOfDay(this.nextHalfHourInNow(), oh.end);
}
return oh;
};
/**
* @return {?}
*/
TimePickerComponent.prototype.getHoursForDays = /**
* @return {?}
*/
function () {
/** @type {?} */
var oh = this.getOpenHoursOnDated();
if (oh && oh.length > 0) {
this.createHours(this.toHoursOfDayFrom(oh));
}
else {
this.createHours(this.getDefaultOpenHours());
}
};
/**
* @param {?} v
* @return {?}
*/
TimePickerComponent.prototype.setHourMinuteIgnorDate = /**
* @param {?} v
* @return {?}
*/
function (v) {
return this.nowTime.clone().hour(v.hour()).minute(v.minute());
};
/**
* @param {?} oh
* @return {?}
*/
TimePickerComponent.prototype.createHours = /**
* @param {?} oh
* @return {?}
*/
function (oh) {
/** @type {?} */
var t = this.replaceStartByNow(oh);
/** @type {?} */
var start = t.start.clone();
/** @type {?} */
var end = t.end.clone();
this.timeCells = [];
for (var item = start; item.isBefore(end); item.add(30, 'm')) {
this.timeCells.push(item.clone());
}
};
/**
* @return {?}
*/
TimePickerComponent.prototype.getOpenHoursOnDated = /**
* @return {?}
*/
function () {
var _this = this;
return this.hours.filter((/**
* @param {?} e
* @return {?}
*/
function (e) {
return e.weeks.includes(_this.nowTime.day());
}));
};
;
/**
* @param {?} ts
* @return {?}
*/
TimePickerComponent.prototype.toHoursOfDayFrom = /**
* @param {?} ts
* @return {?}
*/
function (ts) {
/** @type {?} */
var opens = jspath.apply(".opens", ts);
/** @type {?} */
var closes = jspath.apply(".closes", ts);
return new HoursOfDay(this.setHourMinuteIgnorDate(moment.min(opens)), this.setHourMinuteIgnorDate(moment.max(closes)));
};
/**
* @param {?} changes
* @return {?}
*/
TimePickerComponent.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
/** @type {?} */
var log = [];
for (var propName in changes) {
/** @type {?} */
var changedProp = changes[propName];
if (changedProp.isFirstChange()) {
this.nowTime = moment();
}
else {
this.onClear();
this.nowTime = changedProp.currentValue;
this.getHoursForDays();
}
}
};
TimePickerComponent.decorators = [
{ type: Component, args: [{
selector: 'app-time-picker',
template: "<section class=\"card\">\n\n\t<div *ngFor=\"let c of timeCells\" [ngClass]=\"getClassBy(c)\">\n\t\t<div (click)=\"onSelected(c)\">{{c | amDateFormat: 'HH:mm'}}</div>\n\t</div>\n</section>",
styles: ["@charset \"UTF-8\";.card{display:-webkit-flex;display:flex;min-width:100%;min-height:54px;overflow-x:auto;border-top:1px solid #e9e9e9;border-bottom:1px solid #e9e9e9}.card>div{min-width:55px;height:54px;background-color:#fff;text-align:center;border-left:1px solid #e9e9e9}.card>div>div:first-child{font-size:13px;font-family:PingFangSC-Regular;font-weight:400;color:#242424;line-height:54px}.card>div:last-child{border-right:1px solid #e9e9e9}.card::-webkit-scrollbar{display:none}.time-disable div{background:#fbfbfb;color:#c4c4c4!important;line-height:14px!important;padding:20px 0 0 2px}.time-disable ::after{content:\"\\a\u672A\u8425\u4E1A\";white-space:pre-wrap;font-size:10px;color:#c4c4c4}.time-selected div{background:#e5f2ff!important;color:#007aff!important;border-left:0!important}.time-booked div{background:#fbfbfb;color:#c4c4c4!important;line-height:14px!important;padding:20px 0 0 2px}.time-booked ::after{content:\"\\a\u5DF2\u9884\u8BA2\";white-space:pre-wrap;font-size:10px;color:#c4c4c4}"]
}] }
];
/** @nocollapse */
TimePickerComponent.ctorParameters = function () { return []; };
TimePickerComponent.propDecorators = {
nowTime: [{ type: Input }],
bookeds: [{ type: Input }],
hours: [{ type: Input }],
selected: [{ type: Output }],
onerror: [{ type: Output }]
};
return TimePickerComponent;
}());
export { TimePickerComponent };
if (false) {
/** @type {?} */
TimePickerComponent.prototype.timeCells;
/** @type {?} */
TimePickerComponent.prototype.nowTime;
/** @type {?} */
TimePickerComponent.prototype.bookeds;
/** @type {?} */
TimePickerComponent.prototype.hours;
/** @type {?} */
TimePickerComponent.prototype.selected;
/** @type {?} */
TimePickerComponent.prototype.onerror;
/** @type {?} */
TimePickerComponent.prototype.start;
/** @type {?} */
TimePickerComponent.prototype.end;
/* Skipping unhandled member: ;*/
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYm9vay1waWNrZXIvIiwic291cmNlcyI6WyJ0aW1lLXBpY2tlci90aW1lLXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBMkIsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hHLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUk1QixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QjtJQWVFO1FBVEEsY0FBUyxHQUFvQixFQUFFLENBQUM7UUFDdkIsWUFBTyxHQUFrQixNQUFNLEVBQUUsQ0FBQztRQUNsQyxZQUFPLEdBQWEsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUNoQyxVQUFLLEdBQVksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUM1QixhQUFRLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztRQUN6QyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztJQUlsQyxDQUFDOzs7O0lBRWpCLHNDQUFROzs7SUFBUjtRQUNFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN6QixDQUFDOzs7O0lBRUQsOENBQWdCOzs7SUFBaEI7UUFDRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7U0FDNUI7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNmLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztTQUMxQjtJQUNILENB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Q2xELG9DQUFxQjs7SUFDckIsa0NBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPdXRwdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlLCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IFRpbWVSYW5nZSB9IGZyb20gJy4uL3RpbWUtcmFuZ2UnO1xuaW1wb3J0IHsgQm9va2VkIH0gZnJvbSAnLi4vYm9va2VkJztcbmltcG9ydCB7IEhvdXJzIH0gZnJvbSAnLi4vaG91cnMnO1xuaW1wb3J0IHsgSG91cnNPZkRheSB9IGZyb20gJy4vaG91cnMtb2YtZGF5JztcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gJy4vdGltZS1jbGFzcy5lbnVtJztcbmltcG9ydCBqc3BhdGggZnJvbSBcImpzcGF0aFwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtdGltZS1waWNrZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vdGltZS1waWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90aW1lLXBpY2tlci5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIFRpbWVQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICB0aW1lQ2VsbHM6IG1vbWVudC5Nb21lbnRbXSA9IFtdO1xuICBASW5wdXQoKSBub3dUaW1lOiBtb21lbnQuTW9tZW50ID0gbW9tZW50KCk7XG4gIEBJbnB1dCgpIGJvb2tlZHM6IEJvb2tlZFtdID0gbmV3IEFycmF5KCk7XG4gIEBJbnB1dCgpIGhvdXJzOiBIb3Vyc1tdID0gbmV3IEFycmF5KCk7XG4gIEBPdXRwdXQoKSBzZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VGltZVJhbmdlPigpO1xuICBAT3V0cHV0KCkgb25lcnJvciA9IG5ldyBFdmVudEVtaXR0ZXI8VGltZVJhbmdlPigpO1xuICBzdGFydDogbW9tZW50Lk1vbWVudDtcbiAgZW5kOiBtb21lbnQuTW9tZW50O1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5pbml0Qm9va3NPckhvdXJzKCk7XG4gICAgdGhpcy5nZXRIb3Vyc0ZvckRheXMoKTtcbiAgfVxuXG4gIGluaXRCb29rc09ySG91cnMoKSB7XG4gICAgaWYgKCF0aGlzLmJvb2tlZHMpIHtcbiAgICAgIHRoaXMuYm9va2VkcyA9IG5ldyBBcnJheSgpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaG91cnMpIHtcbiAgICAgIHRoaXMuaG91cnMgPSBuZXcgQXJyYXkoKTtcbiAgICB9XG4gIH1cblxuICBvbkNsZWFyKCkge1xuICAgIHRoaXMuc3RhcnQgPSBudWxsO1xuICAgIHRoaXMuZW5kID0gbnVsbDtcbiAgfVxuXG4gIGVtaXRTZWxlY3RlZCgpIHtcbiAgICB0aGlzLnNlbGVjdGVkLmVtaXQoeyBzdGFydDogdGhpcy5zdGFydCwgZW5kOiB0aGlzLmFkZEhhbGZIb3VyKHRoaXMuZW5kKSB9KTtcbiAgfVxuXG4gIGFkZEhhbGZIb3VyKHY6IG1vbWVudC5Nb21lbnQpIHtcbiAgICByZXR1cm4gdiA/IHYuY2xvbmUoKS5hZGQoMzAsICdtJykgOiBudWxsO1xuICB9XG5cbiAgZW1pdEVycm9yKCkge1xuICAgIHRoaXMub25lcnJvci5lbWl0KCk7XG4gIH1cblxuICBvblNlbGVjdGVkKHZhbHVlOiBtb21lbnQuTW9tZW50KSB7XG4gICAgaWYgKHRoaXMuc3RhcnQgJiYgdGhpcy5lbmQgJiYgdGhpcy5zdGFydC5pc1NhbWUodmFsdWUsICdtJykgJiYgdGhpcy5lbmQuaXNTYW1lKHZhbHVlLCAnbScpKSB7XG4gICAgICB0aGlzLm9uQ2xlYXIoKTtcbiAgICAgIHRoaXMuZW1pdFNlbGVjdGVkKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnN0YXJ0ICYmIHRoaXMuZW5kICYmIHRoaXMuc3RhcnQuaXNTYW1lKHZhbHVlLCAnbScpKSB7XG4gICAgICB0aGlzLnN0YXJ0ID0gdGhpcy5lbmQ7XG4gICAgICB0aGlzLmVtaXRTZWxlY3RlZCgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGFydCAmJiB0aGlzLmVuZCAmJiB0aGlzLmVuZC5pc1NhbWUodmFsdWUsICdtJykpIHtcbiAgICAgIHRoaXMuZW5kID0gdGhpcy5zdGFydDtcbiAgICAgIHRoaXMuZW1pdFNlbGVjdGVkKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICghdGhpcy5zdGFydCAmJiAhdGhpcy5lbmQpIHtcbiAgICAgIGxldCB4ID0gdGhpcy5pbmNsdWRlc0Rpc2FibGUodmFsdWUuY2xvbmUoKSwgdmFsdWUuY2xvbmUoKSk7XG4gICAgICBpZiAoeCkge1xuICAgICAgICB0aGlzLmVtaXRFcnJvcigpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLnN0YXJ0ID0gdmFsdWU7XG4gICAgICB0aGlzLmVuZCA9IHZhbHVlO1xuICAgICAgdGhpcy5lbWl0U2VsZWN0ZWQoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHZhbHVlLmlzQmVmb3JlKHRoaXMuc3RhcnQpKSB7XG4gICAgICBsZXQgeCA9IHRoaXMuaW5jbHVkZXNEaXNhYmxlKHZhbHVlLmNsb25lKCksIHRoaXMuc3RhcnQuY2xvbmUoKSk7XG4gICAgICBpZiAoeCkge1xuICAgICAgICB0aGlzLmVtaXRFcnJvcigpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmVuZCA9IHRoaXMuc3RhcnQ7XG4gICAgICB0aGlzLnN0YXJ0ID0gdmFsdWU7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5pc0FmdGVyKHRoaXMuc3RhcnQpKSB7XG4gICAgICBsZXQgeCA9IHRoaXMuaW5jbHVkZXNEaXNhYmxlKHRoaXMuc3RhcnQuY2xvbmUoKSwgdmFsdWUuY2xvbmUoKSk7XG4gICAgICBpZiAoeCkge1xuICAgICAgICB0aGlzLmVtaXRFcnJvcigpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmVuZCA9IHZhbHVlO1xuICAgIH1cbiAgICB0aGlzLmVtaXRTZWxlY3RlZCgpO1xuICB9XG5cbiAgaW5jbHVkZXNEaXNhYmxlKHN0YXJ0OiBtb21lbnQuTW9tZW50LCBlbmQ6IG1vbWVudC5Nb21lbnQpIHtcbiAgICBsZXQgcmFuZ2UgPSBbXTtcbiAgICBmb3IgKGxldCBpdGVtID0gc3RhcnQ7IGl0ZW0uaXNCZWZvcmUoZW5kKSB8fCBpdGVtLmlzU2FtZShlbmQpOyBpdGVtLmFkZCgzMCwgJ20nKSkge1xuICAgICAgcmFuZ2UucHVzaChpdGVtLmNsb25lKCkpO1xuICAgIH1cbiAgICByZXR1cm4gcmFuZ2UuZmlsdGVyKGUgPT4geyByZXR1cm4gdGhpcy5pbmNsdWRlc0Jvb2tlZChlKSB8fCB0aGlzLmluY2x1ZGVzQ2xvc2VzKGUpOyB9KS5sZW5ndGggPiAwO1xuICB9XG5cbiAgaW5jbHVkZXNCb29rZWQodjogbW9tZW50Lk1vbWVudCkge1xuICAgIHJldHVybiB0aGlzLmJvb2tlZHMuZmlsdGVyKGUgPT4geyByZXR1cm4gdGhpcy5pc0JldHdlZW5EYXRlKHYsIGUuc3RhcnQsIGUuZW5kKSB9KS5sZW5ndGggPiAwO1xuICB9XG5cbiAgaW5jbHVkZXNDbG9zZXModjogbW9tZW50Lk1vbWVudCkge1xuICAgIGxldCBwaCA9IHRoaXMuZ2V0T3BlbkhvdXJzT25EYXRlZCgpO1xuICAgIGlmIChwaCAmJiBwaC5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBwaC5maWx0ZXIoZSA9PiB7IHJldHVybiB0aGlzLmlzQmV0d2Vlbk5vdEVuZCh2LCBlLm9wZW5zLCBlLmNsb3Nlcyk7IH0pLmxlbmd0aCA9PSAwO1xuICB9XG5cbiAgaXNCZXR3ZWVuTm90RW5kKHY6IG1vbWVudC5Nb21lbnQsIHM6IG1vbWVudC5Nb21lbnQsIGU6IG1vbWVudC5Nb21lbnQpIHtcbiAgICBsZXQgdnMgPSB0aGlzLnNldEhvdXJNaW51dGVJZ25vckRhdGUodik7XG4gICAgbGV0IHNzID0gdGhpcy5zZXRIb3VyTWludXRlSWdub3JEYXRlKHMpO1xuICAgIGxldCBlcyA9IHRoaXMuc2V0SG91ck1pbnV0ZUlnbm9yRGF0ZShlKTtcbiAgICByZXR1cm4gKHZzLmlzQmV0d2VlbihzcywgZXMsICdtJykgfHwgdnMuaXNTYW1lKHNzLCAnbScpKSA/IHRydWUgOiBmYWxzZTtcbiAgfVxuXG4gIGlzQmV0d2VlbkRhdGUodjogbW9tZW50Lk1vbWVudCwgczogbW9tZW50Lk1vbWVudCwgZTogbW9tZW50Lk1vbWVudCkge1xuICAgIHJldHVybiB2LmlzQmV0d2VlbihzLCBlKSB8fCB2LmlzU2FtZShzKSB8fCB2LmlzU2FtZShlKTtcbiAgfVxuXG4gIGlzQmV0d2Vlbk0odjogbW9tZW50Lk1vbWVudCwgczogbW9tZW50Lk1vbWVudCwgZTogbW9tZW50Lk1vbWVudCkge1xuICAgIHJldHVybiB2LmlzQmV0d2VlbihzLCBlLCAnbScpIHx8IHYuaXNTYW1lKHMsICdtJykgfHwgdi5pc1NhbWUoZSwgJ20nKTtcbiAgfVxuXG4gIGdldENsYXNzQnkodmFsdWU6IG1vbWVudC5Nb21lbnQpIHtcbiAgICBpZiAodGhpcy5pbmNsdWRlc0Jvb2tlZCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBUaW1lQ2xhc3MuQk9PS0VEO1xuICAgIH1cbiAgICBpZiAodGhpcy5pbmNsdWRlc0Nsb3Nlcyh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBUaW1lQ2xhc3MuRElTQUJMRTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNCZXR3ZWVuTSh2YWx1ZSwgdGhpcy5zdGFydCwgdGhpcy5lbmQpKSB7XG4gICAgICByZXR1cm4gVGltZUNsYXNzLlNFTEVDVEVEO1xuICAgIH1cbiAgICByZXR1cm4gVGltZUNsYXNzLk5PUk1BTDtcbiAgfVxuXG4gIGlzU2FtZURheSh2OiBtb21lbnQuTW9tZW50KSB7XG4gICAgcmV0dXJuIG1vbWVudCgpLmlzU2FtZSh2LCAnbW9udGgnKSAmJiBtb21lbnQoKS5pc1NhbWUodiwgJ2RheScpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdE9wZW5Ib3VycygpIHtcbiAgICByZXR1cm4gbmV3IEhvdXJzT2ZEYXkodGhpcy5ub3dUaW1lLmNsb25lKCkuc3RhcnRPZignZGF5JyksIHRoaXMubm93VGltZS5jbG9uZSgpLmVuZE9mKCdkYXknKSk7XG4gIH1cblxuICBuZXh0SGFsZkhvdXJJbk5vdygpIHtcbiAgICBjb25zdCB5ID0gcGFyc2VGbG9hdCh0aGlzLm5vd1RpbWUuY2xvbmUoKS5mb3JtYXQoJ21tJykpICUgMzA7XG4gICAgcmV0dXJuIHRoaXMuYWRkSGFsZkhvdXIodGhpcy5ub3dUaW1lLmNsb25lKCkuc3VidHJhY3QoeSwgJ20nKSk7XG4gIH1cblxuICByZXBsYWNlU3RhcnRCeU5vdyhvaDogSG91cnNPZkRheSkge1xuICAgIGxldCBzdGFydCA9IHRoaXMuc2V0SG91ck1pbnV0ZUlnbm9yRGF0ZShvaC5zdGFydCk7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF5KHN0YXJ0KSkge1xuXG4gICAgICByZXR1cm4gbmV3IEhvdXJzT2ZEYXkodGhpcy5uZXh0SGFsZkhvdXJJbk5vdygpLCBvaC5lbmQpO1xuICAgIH1cbiAgICByZXR1cm4gb2g7XG4gIH1cblxuICBnZXRIb3Vyc0ZvckRheXMoKSB7XG4gICAgbGV0IG9oID0gdGhpcy5nZXRPcGVuSG91cnNPbkRhdGVkKCk7XG4gICAgaWYgKG9oICYmIG9oLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuY3JlYXRlSG91cnModGhpcy50b0hvdXJzT2ZEYXlGcm9tKG9oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JlYXRlSG91cnModGhpcy5nZXREZWZhdWx0T3BlbkhvdXJzKCkpO1xuICAgIH1cbiAgfVxuXG4gIHNldEhvdXJNaW51dGVJZ25vckRhdGUodjogbW9tZW50Lk1vbWVudCkge1xuICAgIHJldHVybiB0aGlzLm5vd1RpbWUuY2xvbmUoKS5ob3VyKHYuaG91cigpKS5taW51dGUodi5taW51dGUoKSk7XG4gIH1cblxuICBjcmVhdGVIb3VycyhvaDogSG91cnNPZkRheSkge1xuICAgIGxldCB0ID0gdGhpcy5yZXBsYWNlU3RhcnRCeU5vdyhvaCk7XG4gICAgbGV0IHN0YXJ0ID0gdC5zdGFydC5jbG9uZSgpO1xuICAgIGxldCBlbmQgPSB0LmVuZC5jbG9uZSgpO1xuICAgIHRoaXMudGltZUNlbGxzID0gW107XG4gICAgZm9yIChsZXQgaXRlbSA9IHN0YXJ0OyBpdGVtLmlzQmVmb3JlKGVuZCk7IGl0ZW0uYWRkKDMwLCAnbScpKSB7XG4gICAgICB0aGlzLnRpbWVDZWxscy5wdXNoKGl0ZW0uY2xvbmUoKSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0T3BlbkhvdXJzT25EYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5ob3Vycy5maWx0ZXIoKGU6IEhvdXJzKSA9PiB7XG4gICAgICByZXR1cm4gZS53ZWVrcy5pbmNsdWRlcyh0aGlzLm5vd1RpbWUuZGF5KCkpOyBcbiAgICB9KVxuICB9O1xuXG4gIHRvSG91cnNPZkRheUZyb20odHM6IEhvdXJzW10pIHtcbiAgICBjb25zdCBvcGVucyA9IGpzcGF0aC5hcHBseShgLm9wZW5zYCwgdHMpO1xuICAgIGNvbnN0IGNsb3NlcyA9IGpzcGF0aC5hcHBseShgLmNsb3Nlc2AsIHRzKTtcbiAgICByZXR1cm4gbmV3IEhvdXJzT2ZEYXkodGhpcy5zZXRIb3VyTWludXRlSWdub3JEYXRlKG1vbWVudC5taW4ob3BlbnMpKSwgdGhpcy5zZXRIb3VyTWludXRlSWdub3JEYXRlKG1vbWVudC5tYXgoY2xvc2VzKSkpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogeyBbcHJvcEtleTogc3RyaW5nXTogU2ltcGxlQ2hhbmdlIH0pIHtcbiAgICBsZXQgbG9nOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAobGV0IHByb3BOYW1lIGluIGNoYW5nZXMpIHtcbiAgICAgIGxldCBjaGFuZ2VkUHJvcCA9IGNoYW5nZXNbcHJvcE5hbWVdO1xuICAgICAgaWYgKGNoYW5nZWRQcm9wLmlzRmlyc3RDaGFuZ2UoKSkge1xuICAgICAgICB0aGlzLm5vd1RpbWUgPSBtb21lbnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25DbGVhcigpO1xuICAgICAgICB0aGlzLm5vd1RpbWUgPSBjaGFuZ2VkUHJvcC5jdXJyZW50VmFsdWU7XG4gICAgICAgIHRoaXMuZ2V0SG91cnNGb3JEYXlzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59Il19