angular-bootstrap-datetimepicker
Version:
Native Angular (8+) datetime picker component styled by Twitter Bootstrap 4.
271 lines • 35.4 kB
JavaScript
/**
* @license
* Copyright 2013-present Dale Lotts All Rights Reserved.
* http://www.dalelotts.com
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/dalelotts/angular-bootstrap-datetimepicker/blob/master/LICENSE
*/
import * as _moment from 'moment';
/**
* Work around for moment namespace conflict when used with webpack and rollup.
* See https://github.com/dherges/ng-packagr/issues/163
*
* Depending on whether rollup is used, moment needs to be imported differently.
* Since Moment.js doesn't have a default export, we normally need to import using
* the `* as`syntax.
*
* rollup creates a synthetic default module and we thus need to import it using
* the `default as` syntax.
*
* @internal
**/
var moment = _moment;
/**
* Default implementation for the `minute` view.
*/
var DlMinuteModelProvider = /** @class */ (function () {
function DlMinuteModelProvider() {
this.step = 5;
}
/**
* Receives `minuteStep` configuration changes detected by Angular.
*
* Changes where the value has not changed are ignored.
*
* Setting `minuteStep` to `null` or `undefined` will result in a
* minuteStep of `5`.
*
* @param changes
* the input changes detected by Angular.
*/
DlMinuteModelProvider.prototype.onChanges = function (changes) {
var minuteStepChange = changes['minuteStep'];
if (minuteStepChange
&& (minuteStepChange.previousValue !== minuteStepChange.currentValue)) {
this.step = minuteStepChange.currentValue;
if (this.step === null || this.step === undefined) {
this.step = 5;
}
}
};
/**
* Returns the `minute` model for the specified moment in `local` time with the
* `active` minute set to the beginning of the hour.
*
* The `minute` model represents an hour (60 minutes) as three rows with four columns
* and each cell representing 5-minute increments.
*
* The hour always starts at midnight.
*
* Each cell represents a 5-minute increment starting at midnight.
*
* The `active` minute will be the 5-minute increments less than or equal to the specified milliseconds.
*
* @param milliseconds
* the moment in time from which the minute model will be created.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* the model representing the specified moment in time.
*/
DlMinuteModelProvider.prototype.getModel = function (milliseconds, selectedMilliseconds) {
var _this = this;
var startDate = moment(milliseconds).startOf('hour');
var currentMilliseconds = moment().valueOf();
var minuteSteps = new Array(Math.ceil(60 / this.step)).fill(0).map(function (zero, index) { return zero + index * _this.step; });
var minuteValues = minuteSteps.map(function (minutesToAdd) { return moment(startDate).add(minutesToAdd, 'minutes').valueOf(); });
var activeValue = moment(minuteValues.filter(function (value) { return value <= milliseconds; }).pop()).valueOf();
var nowValue = currentMilliseconds >= startDate.valueOf() && currentMilliseconds <= moment(startDate).endOf('hour').valueOf()
? moment(minuteValues.filter(function (value) { return value <= currentMilliseconds; }).pop()).valueOf()
: null;
var previousHour = moment(startDate).subtract(1, 'hour');
var nextHour = moment(startDate).add(1, 'hour');
var selectedValue = selectedMilliseconds === null || selectedMilliseconds === undefined
? selectedMilliseconds
: moment(minuteValues.filter(function (value) { return value <= selectedMilliseconds; }).pop()).valueOf();
var rows = new Array(Math.ceil(minuteSteps.length / 4))
.fill(0)
.map(function (zero, index) { return zero + index; })
.map(function (value) {
return { cells: minuteSteps.slice((value * 4), (value * 4) + 4).map(rowOfMinutes) };
});
return {
viewName: 'minute',
viewLabel: startDate.format('lll'),
activeDate: activeValue,
leftButton: {
value: previousHour.valueOf(),
ariaLabel: "Go to " + previousHour.format('lll'),
classes: {},
},
upButton: {
value: startDate.valueOf(),
ariaLabel: "Go to " + startDate.format('ll'),
classes: {},
},
rightButton: {
value: nextHour.valueOf(),
ariaLabel: "Go to " + nextHour.format('lll'),
classes: {},
},
rows: rows
};
function rowOfMinutes(stepMinutes) {
var minuteMoment = moment(startDate).add(stepMinutes, 'minutes');
return {
display: minuteMoment.format('LT'),
ariaLabel: minuteMoment.format('LLL'),
value: minuteMoment.valueOf(),
classes: {
'dl-abdtp-active': activeValue === minuteMoment.valueOf(),
'dl-abdtp-selected': selectedValue === minuteMoment.valueOf(),
'dl-abdtp-now': nowValue === minuteMoment.valueOf(),
}
};
}
};
/**
* Move the active `minute` one row `down` from the specified moment in time.
*
* Moving `down` can result in the `active` minute being part of a different hour than
* the specified `fromMilliseconds`, in this case the hour represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the next `minute` model `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `minute` one row `down` from the specified moment in time.
*/
DlMinuteModelProvider.prototype.goDown = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(this.step * 4, 'minutes').valueOf(), selectedMilliseconds);
};
/**
* Move the active `minute` one row `down` from the specified moment in time.
*
* Moving `down` can result in the `active` minute being part of a different hour than
* the specified `fromMilliseconds`, in this case the hour represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the next `minute` model `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `minute` one row `down` from the specified moment in time.
*/
DlMinuteModelProvider.prototype.goUp = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(this.step * 4, 'minutes').valueOf(), selectedMilliseconds);
};
/**
* Move the `active` date one cell to `left` in the current `minute` view.
*
* Moving `left` can result in the `active` hour being part of a different hour than
* the specified `fromMilliseconds`, in this case the hour represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the `minute` model to the `left` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `minute` one cell to the `left` of the specified moment in time.
*/
DlMinuteModelProvider.prototype.goLeft = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(this.step, 'minutes').valueOf(), selectedMilliseconds);
};
/**
* Move `active` minute one cell to `right` in the current `minute` view.
*
* Moving `right` can result in the `active` hour being part of a different hour than
* the specified `fromMilliseconds`, in this case the hour represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the `minute` model to the `right` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `minute` one cell to the `right` of the specified moment in time.
*/
DlMinuteModelProvider.prototype.goRight = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(this.step, 'minutes').valueOf(), selectedMilliseconds);
};
/**
* Move the active `minute` one hour `down` from the specified moment in time.
*
* The `active` minute will be `one (1) hour after` the specified milliseconds.
* This moves the `active` date one `page` `down` from the current `minute` view.
*
* The next cell `page-down` will be in a different hour than the currently
* displayed view and the model time range will include the new active cell.
*
* @param fromMilliseconds
* the moment in time from which the next `month` model page `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one year `down` from the specified moment in time.
*/
DlMinuteModelProvider.prototype.pageDown = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(1, 'hour').valueOf(), selectedMilliseconds);
};
/**
* Move the active `minute` one hour `up` from the specified moment in time.
*
* The `active` minute will be `one (1) hour before` the specified milliseconds.
* This moves the `active` date one `page` `down` from the current `minute` view.
*
* The next cell `page-up` will be in a different hour than the currently
* displayed view and the model time range will include the new active cell.
*
* @param fromMilliseconds
* the moment in time from which the next `month` model page `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one year `down` from the specified moment in time.
*/
DlMinuteModelProvider.prototype.pageUp = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(1, 'hour').valueOf(), selectedMilliseconds);
};
/**
* Move the `active` `minute` to the last cell of the current hour.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different hour than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which the last cell will be calculated.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* a model with the last cell in the view as the active `minute`.
*/
DlMinuteModelProvider.prototype.goEnd = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds)
.endOf('hour')
.valueOf(), selectedMilliseconds);
};
/**
* Move the `active` `minute` to the first cell of the current hour.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different hour than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which the first cell will be calculated.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* a model with the first cell in the view as the active `minute`.
*/
DlMinuteModelProvider.prototype.goHome = function (fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).startOf('hour').valueOf(), selectedMilliseconds);
};
return DlMinuteModelProvider;
}());
export { DlMinuteModelProvider };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGwtbW9kZWwtcHJvdmlkZXItbWludXRlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1ib290c3RyYXAtZGF0ZXRpbWVwaWNrZXIvIiwic291cmNlcyI6WyJkbC1kYXRlLXRpbWUtcGlja2VyL2RsLW1vZGVsLXByb3ZpZGVyLW1pbnV0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBR0gsT0FBTyxLQUFLLE9BQU8sTUFBTSxRQUFRLENBQUM7QUFJbEM7Ozs7Ozs7Ozs7OztJQVlJO0FBQ0osSUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBRXZCOztHQUVHO0FBQ0g7SUFBQTtRQUVVLFNBQUksR0FBRyxDQUFDLENBQUM7SUF3UW5CLENBQUM7SUF0UUM7Ozs7Ozs7Ozs7T0FVRztJQUVILHlDQUFTLEdBQVQsVUFBVSxPQUFzQjtRQUU5QixJQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUUvQyxJQUFJLGdCQUFnQjtlQUNmLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxLQUFLLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxFQUNyRTtZQUNBLElBQUksQ0FBQyxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsWUFBWSxDQUFDO1lBQzFDLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUU7Z0JBQ2pELElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO2FBQ2Y7U0FDRjtJQUNILENBQUM7SUFHRDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQW1CRztJQUNILHdDQUFRLEdBQVIsVUFBUyxZQUFvQixFQUFFLG9CQUE0QjtRQUEzRCxpQkFrRUM7UUFqRUMsSUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2RCxJQUFNLG1CQUFtQixHQUFHLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxD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Ozs7Ozs7Ozs7OztPQWVHO0lBQ0gsc0NBQU0sR0FBTixVQUFPLGdCQUF3QixFQUFFLG9CQUE0QjtRQUMzRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3JHLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSCxxQ0FBSyxHQUFMLFVBQU0sZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQzFELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7YUFDMUMsS0FBSyxDQUFDLE1BQU0sQ0FBQzthQUNiLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILHNDQUFNLEdBQU4sVUFBTyxnQkFBd0IsRUFBRSxvQkFBNEI7UUFDM0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ2pHLENBQUM7SUFDSCw0QkFBQztBQUFELENBQUMsQUExUUQsSUEwUUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxMy1wcmVzZW50IERhbGUgTG90dHMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIGh0dHA6Ly93d3cuZGFsZWxvdHRzLmNvbVxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9kYWxlbG90dHMvYW5ndWxhci1ib290c3RyYXAtZGF0ZXRpbWVwaWNrZXIvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7U2ltcGxlQ2hhbmdlc30gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgKiBhcyBfbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQge0RsRGF0ZVRpbWVQaWNrZXJNb2RlbH0gZnJvbSAnLi9kbC1kYXRlLXRpbWUtcGlja2VyLW1vZGVsJztcbmltcG9ydCB7RGxNb2RlbFByb3ZpZGVyfSBmcm9tICcuL2RsLW1vZGVsLXByb3ZpZGVyJztcblxuLyoqXG4gKiBXb3JrIGFyb3VuZCBmb3IgbW9tZW50IG5hbWVzcGFjZSBjb25mbGljdCB3aGVuIHVzZWQgd2l0aCB3ZWJwYWNrIGFuZCByb2xsdXAuXG4gKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2RoZXJnZXMvbmctcGFja2Fnci9pc3N1ZXMvMTYzXG4gKlxuICogRGVwZW5kaW5nIG9uIHdoZXRoZXIgcm9sbHVwIGlzIHVzZWQsIG1vbWVudCBuZWVkcyB0byBiZSBpbXBvcnRlZCBkaWZmZXJlbnRseS5cbiAqIFNpbmNlIE1vbWVudC5qcyBkb2Vzbid0IGhhdmUgYSBkZWZhdWx0IGV4cG9ydCwgd2Ugbm9ybWFsbHkgbmVlZCB0byBpbXBvcnQgdXNpbmdcbiAqIHRoZSBgKiBhc2BzeW50YXguXG4gKlxuICogcm9sbHVwIGNyZWF0ZXMgYSBzeW50aGV0aWMgZGVmYXVsdCBtb2R1bGUgYW5kIHdlIHRodXMgbmVlZCB0byBpbXBvcnQgaXQgdXNpbmdcbiAqIHRoZSBgZGVmYXVsdCBhc2Agc3ludGF4LlxuICpcbiAqIEBpbnRlcm5hbFxuICoqL1xuY29uc3QgbW9tZW50ID0gX21vbWVudDtcblxuLyoqXG4gKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGZvciB0aGUgYG1pbnV0ZWAgdmlldy5cbiAqL1xuZXhwb3J0IGNsYXNzIERsTWludXRlTW9kZWxQcm92aWRlciBpbXBsZW1lbnRzIERsTW9kZWxQcm92aWRlciB7XG5cbiAgcHJpdmF0ZSBzdGVwID0gNTtcblxuICAvKipcbiAgICogUmVjZWl2ZXMgYG1pbnV0ZVN0ZXBgIGNvbmZpZ3VyYXRpb24gY2hhbmdlcyBkZXRlY3RlZCBieSBBbmd1bGFyLlxuICAgKlxuICAgKiBDaGFuZ2VzIHdoZXJlIHRoZSB2YWx1ZSBoYXMgbm90IGNoYW5nZWQgYXJlIGlnbm9yZWQuXG4gICAqXG4gICAqIFNldHRpbmcgYG1pbnV0ZVN0ZXBgIHRvIGBudWxsYCBvciBgdW5kZWZpbmVkYCB3aWxsIHJlc3VsdCBpbiBhXG4gICAqIG1pbnV0ZVN0ZXAgb2YgYDVgLlxuICAgKlxuICAgKiBAcGFyYW0gY2hhbmdlc1xuICAgKiAgdGhlIGlucHV0IGNoYW5nZXMgZGV0ZWN0ZWQgYnkgQW5ndWxhci5cbiAgICovXG5cbiAgb25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcblxuICAgIGNvbnN0IG1pbnV0ZVN0ZXBDaGFuZ2UgPSBjaGFuZ2VzWydtaW51dGVTdGVwJ107XG5cbiAgICBpZiAobWludXRlU3RlcENoYW5nZVxuICAgICAgJiYgKG1pbnV0ZVN0ZXBDaGFuZ2UucHJldmlvdXNWYWx1ZSAhPT0gbWludXRlU3RlcENoYW5nZS5jdXJyZW50VmFsdWUpXG4gICAgKSB7XG4gICAgICB0aGlzLnN0ZXAgPSBtaW51dGVTdGVwQ2hhbmdlLmN1cnJlbnRWYWx1ZTtcbiAgICAgIGlmICh0aGlzLnN0ZXAgPT09IG51bGwgfHwgdGhpcy5zdGVwID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5zdGVwID0gNTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBgbWludXRlYCBtb2RlbCBmb3IgdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gYGxvY2FsYCB0aW1lIHdpdGggdGhlXG4gICAqIGBhY3RpdmVgIG1pbnV0ZSBzZXQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgaG91ci5cbiAgICpcbiAgICogVGhlIGBtaW51dGVgIG1vZGVsIHJlcHJlc2VudHMgYW4gaG91ciAoNjAgbWludXRlcykgYXMgdGhyZWUgcm93cyB3aXRoIGZvdXIgY29sdW1uc1xuICAgKiBhbmQgZWFjaCBjZWxsIHJlcHJlc2VudGluZyA1LW1pbnV0ZSBpbmNyZW1lbnRzLlxuICAgKlxuICAgKiBUaGUgaG91ciBhbHdheXMgc3RhcnRzIGF0IG1pZG5pZ2h0LlxuICAgKlxuICAgKiBFYWNoIGNlbGwgcmVwcmVzZW50cyBhIDUtbWludXRlIGluY3JlbWVudCBzdGFydGluZyBhdCBtaWRuaWdodC5cbiAgICpcbiAgICogVGhlIGBhY3RpdmVgIG1pbnV0ZSB3aWxsIGJlIHRoZSA1LW1pbnV0ZSBpbmNyZW1lbnRzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcy5cbiAgICpcbiAgICogQHBhcmFtIG1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIG1pbnV0ZSBtb2RlbCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICB0aGUgbW9kZWwgcmVwcmVzZW50aW5nIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnZXRNb2RlbChtaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgY29uc3Qgc3RhcnREYXRlID0gbW9tZW50KG1pbGxpc2Vjb25kcykuc3RhcnRPZignaG91cicpO1xuICAgIGNvbnN0IGN1cnJlbnRNaWxsaXNlY29uZHMgPSBtb21lbnQoKS52YWx1ZU9mKCk7XG5cbiAgICBjb25zdCBtaW51dGVTdGVwcyA9IG5ldyBBcnJheShNYXRoLmNlaWwoNjAgLyB0aGlzLnN0ZXApKS5maWxsKDApLm1hcCgoemVybywgaW5kZXgpID0+IHplcm8gKyBpbmRleCAqIHRoaXMuc3RlcCk7XG4gICAgY29uc3QgbWludXRlVmFsdWVzID0gbWludXRlU3RlcHMubWFwKChtaW51dGVzVG9BZGQpID0+IG1vbWVudChzdGFydERhdGUpLmFkZChtaW51dGVzVG9BZGQsICdtaW51dGVzJykudmFsdWVPZigpKTtcbiAgICBjb25zdCBhY3RpdmVWYWx1ZSA9IG1vbWVudChtaW51dGVWYWx1ZXMuZmlsdGVyKCh2YWx1ZSkgPT4gdmFsdWUgPD0gbWlsbGlzZWNvbmRzKS5wb3AoKSkudmFsdWVPZigpO1xuXG4gICAgY29uc3Qgbm93VmFsdWUgPSBjdXJyZW50TWlsbGlzZWNvbmRzID49IHN0YXJ0RGF0ZS52YWx1ZU9mKCkgJiYgY3VycmVudE1pbGxpc2Vjb25kcyA8PSBtb21lbnQoc3RhcnREYXRlKS5lbmRPZignaG91cicpLnZhbHVlT2YoKVxuICAgICAgPyBtb21lbnQobWludXRlVmFsdWVzLmZpbHRlcigodmFsdWUpID0+IHZhbHVlIDw9IGN1cnJlbnRNaWxsaXNlY29uZHMpLnBvcCgpKS52YWx1ZU9mKClcbiAgICAgIDogbnVsbDtcblxuXG4gICAgY29uc3QgcHJldmlvdXNIb3VyID0gbW9tZW50KHN0YXJ0RGF0ZSkuc3VidHJhY3QoMSwgJ2hvdXInKTtcbiAgICBjb25zdCBuZXh0SG91ciA9IG1vbWVudChzdGFydERhdGUpLmFkZCgxLCAnaG91cicpO1xuICAgIGNvbnN0IHNlbGVjdGVkVmFsdWUgPSBzZWxlY3RlZE1pbGxpc2Vjb25kcyA9PT0gbnVsbCB8fCBzZWxlY3RlZE1pbGxpc2Vjb25kcyA9PT0gdW5kZWZpbmVkXG4gICAgICA/IHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAgICA6IG1vbWVudChtaW51dGVWYWx1ZXMuZmlsdGVyKCh2YWx1ZSkgPT4gdmFsdWUgPD0gc2VsZWN0ZWRNaWxsaXNlY29uZHMpLnBvcCgpKS52YWx1ZU9mKCk7XG5cbiAgICBjb25zdCByb3dzID0gbmV3IEFycmF5KE1hdGguY2VpbChtaW51dGVTdGVwcy5sZW5ndGggLyA0KSlcbiAgICAgIC5maWxsKDApXG4gICAgICAubWFwKCh6ZXJvLCBpbmRleCkgPT4gemVybyArIGluZGV4KVxuICAgICAgLm1hcCgodmFsdWUpID0+IHtcbiAgICAgICAgcmV0dXJuIHtjZWxsczogbWludXRlU3RlcHMuc2xpY2UoKHZhbHVlICogNCksICh2YWx1ZSAqIDQpICsgNCkubWFwKHJvd09mTWludXRlcyl9O1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmlld05hbWU6ICdtaW51dGUnLFxuICAgICAgdmlld0xhYmVsOiBzdGFydERhdGUuZm9ybWF0KCdsbGwnKSxcbiAgICAgIGFjdGl2ZURhdGU6IGFjdGl2ZVZhbHVlLFxuICAgICAgbGVmdEJ1dHRvbjoge1xuICAgICAgICB2YWx1ZTogcHJldmlvdXNIb3VyLnZhbHVlT2YoKSxcbiAgICAgICAgYXJpYUxhYmVsOiBgR28gdG8gJHtwcmV2aW91c0hvdXIuZm9ybWF0KCdsbGwnKX1gLFxuICAgICAgICBjbGFzc2VzOiB7fSxcbiAgICAgIH0sXG4gICAgICB1cEJ1dHRvbjoge1xuICAgICAgICB2YWx1ZTogc3RhcnREYXRlLnZhbHVlT2YoKSxcbiAgICAgICAgYXJpYUxhYmVsOiBgR28gdG8gJHtzdGFydERhdGUuZm9ybWF0KCdsbCcpfWAsXG4gICAgICAgIGNsYXNzZXM6IHt9LFxuICAgICAgfSxcbiAgICAgIHJpZ2h0QnV0dG9uOiB7XG4gICAgICAgIHZhbHVlOiBuZXh0SG91ci52YWx1ZU9mKCksXG4gICAgICAgIGFyaWFMYWJlbDogYEdvIHRvICR7bmV4dEhvdXIuZm9ybWF0KCdsbGwnKX1gLFxuICAgICAgICBjbGFzc2VzOiB7fSxcbiAgICAgIH0sXG4gICAgICByb3dzXG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHJvd09mTWludXRlcyhzdGVwTWludXRlcyk6IHtcbiAgICAgIGRpc3BsYXk6IHN0cmluZztcbiAgICAgIGFyaWFMYWJlbDogc3RyaW5nO1xuICAgICAgdmFsdWU6IG51bWJlcjtcbiAgICAgIGNsYXNzZXM6IHt9O1xuICAgIH0ge1xuICAgICAgY29uc3QgbWludXRlTW9tZW50ID0gbW9tZW50KHN0YXJ0RGF0ZSkuYWRkKHN0ZXBNaW51dGVzLCAnbWludXRlcycpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGlzcGxheTogbWludXRlTW9tZW50LmZvcm1hdCgnTFQnKSxcbiAgICAgICAgYXJpYUxhYmVsOiBtaW51dGVNb21lbnQuZm9ybWF0KCdMTEwnKSxcbiAgICAgICAgdmFsdWU6IG1pbnV0ZU1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgIGNsYXNzZXM6IHtcbiAgICAgICAgICAnZGwtYWJkdHAtYWN0aXZlJzogYWN0aXZlVmFsdWUgPT09IG1pbnV0ZU1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgICAgJ2RsLWFiZHRwLXNlbGVjdGVkJzogc2VsZWN0ZWRWYWx1ZSA9PT0gbWludXRlTW9tZW50LnZhbHVlT2YoKSxcbiAgICAgICAgICAnZGwtYWJkdHAtbm93Jzogbm93VmFsdWUgPT09IG1pbnV0ZU1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGFjdGl2ZSBgbWludXRlYCBvbmUgcm93IGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIE1vdmluZyBgZG93bmAgY2FuIHJlc3VsdCBpbiB0aGUgYGFjdGl2ZWAgbWludXRlIGJlaW5nIHBhcnQgb2YgYSBkaWZmZXJlbnQgaG91ciB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLCBpbiB0aGlzIGNhc2UgdGhlIGhvdXIgcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgaG91ci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBtaW51dGVgIG1vZGVsIGBkb3duYCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgbWludXRlYCBvbmUgcm93IGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnb0Rvd24oZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKHRoaXMuc3RlcCAqIDQsICdtaW51dGVzJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYWN0aXZlIGBtaW51dGVgIG9uZSByb3cgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICpcbiAgICogTW92aW5nIGBkb3duYCBjYW4gcmVzdWx0IGluIHRoZSBgYWN0aXZlYCBtaW51dGUgYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCBob3VyIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgaG91ciByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCBob3VyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIG5leHQgYG1pbnV0ZWAgbW9kZWwgYGRvd25gIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBtaW51dGVgIG9uZSByb3cgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdvVXAoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3VidHJhY3QodGhpcy5zdGVwICogNCwgJ21pbnV0ZXMnKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBgYWN0aXZlYCBkYXRlIG9uZSBjZWxsIHRvIGBsZWZ0YCBpbiB0aGUgY3VycmVudCBgbWludXRlYCB2aWV3LlxuICAgKlxuICAgKiBNb3ZpbmcgYGxlZnRgIGNhbiByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIGhvdXIgYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCBob3VyIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgaG91ciByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCBob3VyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIGBtaW51dGVgIG1vZGVsIHRvIHRoZSBgbGVmdGAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYG1pbnV0ZWAgb25lIGNlbGwgdG8gdGhlIGBsZWZ0YCBvZiB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgZ29MZWZ0KGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN1YnRyYWN0KHRoaXMuc3RlcCwgJ21pbnV0ZXMnKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIGBhY3RpdmVgIG1pbnV0ZSBvbmUgY2VsbCB0byBgcmlnaHRgIGluIHRoZSBjdXJyZW50IGBtaW51dGVgIHZpZXcuXG4gICAqXG4gICAqIE1vdmluZyBgcmlnaHRgIGNhbiByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIGhvdXIgYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCBob3VyIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgaG91ciByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCBob3VyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIGBtaW51dGVgIG1vZGVsIHRvIHRoZSBgcmlnaHRgIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBtaW51dGVgIG9uZSBjZWxsIHRvIHRoZSBgcmlnaHRgIG9mIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnb1JpZ2h0KGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLmFkZCh0aGlzLnN0ZXAsICdtaW51dGVzJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYWN0aXZlIGBtaW51dGVgIG9uZSBob3VyIGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIFRoZSBgYWN0aXZlYCBtaW51dGUgd2lsbCBiZSBgb25lICgxKSBob3VyIGFmdGVyYCB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcy5cbiAgICogVGhpcyBtb3ZlcyB0aGUgYGFjdGl2ZWAgZGF0ZSBvbmUgYHBhZ2VgIGBkb3duYCBmcm9tIHRoZSBjdXJyZW50IGBtaW51dGVgIHZpZXcuXG4gICAqXG4gICAqIFRoZSBuZXh0IGNlbGwgYHBhZ2UtZG93bmAgd2lsbCBiZSBpbiBhIGRpZmZlcmVudCBob3VyIHRoYW4gdGhlIGN1cnJlbnRseVxuICAgKiBkaXNwbGF5ZWQgdmlldyBhbmQgdGhlIG1vZGVsIHRpbWUgcmFuZ2Ugd2lsbCBpbmNsdWRlIHRoZSBuZXcgYWN0aXZlIGNlbGwuXG4gICAqXG4gICAqIEBwYXJhbSBmcm9tTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgbW9tZW50IGluIHRpbWUgZnJvbSB3aGljaCB0aGUgbmV4dCBgbW9udGhgIG1vZGVsIHBhZ2UgYGRvd25gIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBtb250aGAgb25lIHllYXIgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIHBhZ2VEb3duKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLmFkZCgxLCAnaG91cicpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGFjdGl2ZSBgbWludXRlYCBvbmUgaG91ciBgdXBgIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICpcbiAgICogVGhlIGBhY3RpdmVgIG1pbnV0ZSB3aWxsIGJlIGBvbmUgKDEpIGhvdXIgYmVmb3JlYCB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcy5cbiAgICogVGhpcyBtb3ZlcyB0aGUgYGFjdGl2ZWAgZGF0ZSBvbmUgYHBhZ2VgIGBkb3duYCBmcm9tIHRoZSBjdXJyZW50IGBtaW51dGVgIHZpZXcuXG4gICAqXG4gICAqIFRoZSBuZXh0IGNlbGwgYHBhZ2UtdXBgIHdpbGwgYmUgaW4gYSBkaWZmZXJlbnQgaG91ciB0aGFuIHRoZSBjdXJyZW50bHlcbiAgICogZGlzcGxheWVkIHZpZXcgYW5kIHRoZSBtb2RlbCB0aW1lIHJhbmdlIHdpbGwgaW5jbHVkZSB0aGUgbmV3IGFjdGl2ZSBjZWxsLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIG5leHQgYG1vbnRoYCBtb2RlbCBwYWdlIGBkb3duYCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgbW9udGhgIG9uZSB5ZWFyIGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBwYWdlVXAoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3VidHJhY3QoMSwgJ2hvdXInKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBgYWN0aXZlYCBgbWludXRlYCB0byB0aGUgbGFzdCBjZWxsIG9mIHRoZSBjdXJyZW50IGhvdXIuXG4gICAqXG4gICAqIFRoZSB2aWV3IG9yIHRpbWUgcmFuZ2Ugd2lsbCBub3QgY2hhbmdlIHVubGVzcyB0aGUgYGZyb21NaWxsaXNlY29uZHNgIHZhbHVlXG4gICAqIGlzIGluIGEgZGlmZmVyZW50IGhvdXIgdGhhbiB0aGUgZGlzcGxheWVkIGRlY2FkZS5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBsYXN0IGNlbGwgd2lsbCBiZSBjYWxjdWxhdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgYSBtb2RlbCB3aXRoIHRoZSBsYXN0IGNlbGwgaW4gdGhlIHZpZXcgYXMgdGhlIGFjdGl2ZSBgbWludXRlYC5cbiAgICovXG4gIGdvRW5kKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpXG4gICAgICAuZW5kT2YoJ2hvdXInKVxuICAgICAgLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGBhY3RpdmVgIGBtaW51dGVgIHRvIHRoZSBmaXJzdCBjZWxsIG9mIHRoZSBjdXJyZW50IGhvdXIuXG4gICAqXG4gICAqIFRoZSB2aWV3IG9yIHRpbWUgcmFuZ2Ugd2lsbCBub3QgY2hhbmdlIHVubGVzcyB0aGUgYGZyb21NaWxsaXNlY29uZHNgIHZhbHVlXG4gICAqIGlzIGluIGEgZGlmZmVyZW50IGhvdXIgdGhhbiB0aGUgZGlzcGxheWVkIGRlY2FkZS5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBmaXJzdCBjZWxsIHdpbGwgYmUgY2FsY3VsYXRlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIGEgbW9kZWwgd2l0aCB0aGUgZmlyc3QgY2VsbCBpbiB0aGUgdmlldyBhcyB0aGUgYWN0aXZlIGBtaW51dGVgLlxuICAgKi9cbiAgZ29Ib21lKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN0YXJ0T2YoJ2hvdXInKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxufVxuIl19