angular-bootstrap-datetimepicker
Version:
Native Angular (8+) datetime picker component styled by Twitter Bootstrap 4.
245 lines • 30.7 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
**/
const moment = _moment;
/**
* Default implementation for the `day` view.
*/
export class DlDayModelProvider {
/**
* Receives input changes detected by Angular.
*
* @param changes
* the input changes detected by Angular.
*/
onChanges(
// @ts-ignore
changes) { }
/**
* Returns the `day` model for the specified moment in `local` time with the
* `active` day set to the first day of the month.
*
* The `day` model represents a month (42 days) as six rows with seven columns
* and each cell representing one-day increments.
*
* The `day` always starts at midnight.
*
* Each cell represents a one-day increment at midnight.
*
* @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.
*/
getModel(milliseconds, selectedMilliseconds) {
const startOfMonth = moment(milliseconds).startOf('month');
const endOfMonth = moment(milliseconds).endOf('month');
const startOfView = moment(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days');
const rowNumbers = [0, 1, 2, 3, 4, 5];
const columnNumbers = [0, 1, 2, 3, 4, 5, 6];
const previousMonth = moment(startOfMonth).subtract(1, 'month');
const nextMonth = moment(startOfMonth).add(1, 'month');
const activeValue = moment(milliseconds).startOf('day').valueOf();
const selectedValue = selectedMilliseconds === null || selectedMilliseconds === undefined
? selectedMilliseconds
: moment(selectedMilliseconds).startOf('day').valueOf();
return {
viewName: 'day',
viewLabel: startOfMonth.format('MMM YYYY'),
activeDate: activeValue,
leftButton: {
value: previousMonth.valueOf(),
ariaLabel: `Go to ${previousMonth.format('MMM YYYY')}`,
classes: {},
},
upButton: {
value: startOfMonth.valueOf(),
ariaLabel: `Go to month view`,
classes: {},
},
rightButton: {
value: nextMonth.valueOf(),
ariaLabel: `Go to ${nextMonth.format('MMM YYYY')}`,
classes: {},
},
rowLabels: columnNumbers.map((column) => moment().weekday(column).format('dd')),
rows: rowNumbers.map(rowOfDays)
};
function rowOfDays(rowNumber) {
const currentMoment = moment();
const cells = columnNumbers.map((columnNumber) => {
const dayMoment = moment(startOfView).add((rowNumber * columnNumbers.length) + columnNumber, 'days');
return {
display: dayMoment.format('D'),
ariaLabel: dayMoment.format('ll'),
value: dayMoment.valueOf(),
classes: {
'dl-abdtp-active': activeValue === dayMoment.valueOf(),
'dl-abdtp-future': dayMoment.isAfter(endOfMonth),
'dl-abdtp-past': dayMoment.isBefore(startOfMonth),
'dl-abdtp-selected': selectedValue === dayMoment.valueOf(),
'dl-abdtp-now': dayMoment.isSame(currentMoment, 'day'),
}
};
});
return { cells };
}
}
/**
* Move the active `day` one row `down` from the specified moment in time.
*
* Moving `down` can result in the `active` day being part of a different month than
* the specified `fromMilliseconds`, in this case the month represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the next `day` model `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one row `down` from the specified moment in time.
*/
goDown(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(7, 'days').valueOf(), selectedMilliseconds);
}
/**
* Move the active `day` one row `up` from the specified moment in time.
*
* Moving `up` can result in the `active` day being part of a different month than
* the specified `fromMilliseconds`, in this case the month represented by the model
* will change to show the correct hour.
*
* @param fromMilliseconds
* the moment in time from which the next `day` model `up` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one row `up` from the specified moment in time.
*/
goUp(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(7, 'days').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` day one cell `left` in the current `day` view.
*
* Moving `left` can result in the `active` day being part of a different month than
* the specified `fromMilliseconds`, in this case the month represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the `day` model to the `left` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one cell to the `left` of the specified moment in time.
*/
goLeft(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(1, 'day').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` day one cell `right` in the current `day` view.
*
* Moving `right` can result in the `active` day being part of a different month than
* the specified `fromMilliseconds`, in this case the month represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the `day` model to the `right` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one cell to the `right` of the specified moment in time.
*/
goRight(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(1, 'day').valueOf(), selectedMilliseconds);
}
/**
* Move the active `day` one month `down` from the specified moment in time.
*
* Paging `down` will result in the `active` day being part of a different month than
* the specified `fromMilliseconds`. As a result, the month represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the next `day` model page `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one month `down` from the specified moment in time.
*/
pageDown(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(1, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the active `day` one month `up` from the specified moment in time.
*
* Paging `up` will result in the `active` day being part of a different month than
* the specified `fromMilliseconds`. As a result, the month represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the next `day` model page `up` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `day` one month `up` from the specified moment in time.
*/
pageUp(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(1, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `day` to the last day of the month.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different day than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which the last day of the month 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 `day`.
*/
goEnd(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds)
.endOf('month').startOf('day').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `day` to the first day of the month.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different day than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which the first day of the month 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 `day`.
*/
goHome(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).startOf('month').valueOf(), selectedMilliseconds);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGwtbW9kZWwtcHJvdmlkZXItZGF5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1ib290c3RyYXAtZGF0ZXRpbWVwaWNrZXIvIiwic291cmNlcyI6WyJkbC1kYXRlLXRpbWUtcGlja2VyL2RsLW1vZGVsLXByb3ZpZGVyLWRheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBR0gsT0FBTyxLQUFLLE9BQU8sTUFBTSxRQUFRLENBQUM7QUFJbEM7Ozs7Ozs7Ozs7OztJQVlJO0FBQ0osTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDO0FBRXZCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGtCQUFrQjtJQUU3Qjs7Ozs7T0FLRztJQUNILFNBQVM7SUFDUCxhQUFhO0lBQ2IsT0FBc0IsSUFDZixDQUFDO0lBRVY7Ozs7Ozs7Ozs7Ozs7Ozs7O09BaUJHO0lBQ0gsUUFBUSxDQUFDLFlBQW9CLEVBQUUsb0JBQTRCO1FBRXpELE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2RCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFNUYsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFNUMsTUFB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LE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDakcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQzNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDdEcsQ0FBQztJQUdEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILEtBQUssQ0FBQyxnQkFBd0IsRUFBRSxvQkFBNEI7UUFDMUQsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQzthQUMxQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILE1BQU0sQ0FBQyxnQkFBd0IsRUFBRSxvQkFBNEI7UUFDM0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ2xHLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDEzLXByZXNlbnQgRGFsZSBMb3R0cyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogaHR0cDovL3d3dy5kYWxlbG90dHMuY29tXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL2RhbGVsb3R0cy9hbmd1bGFyLWJvb3RzdHJhcC1kYXRldGltZXBpY2tlci9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHtTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIF9tb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7RGxEYXRlVGltZVBpY2tlck1vZGVsfSBmcm9tICcuL2RsLWRhdGUtdGltZS1waWNrZXItbW9kZWwnO1xuaW1wb3J0IHtEbE1vZGVsUHJvdmlkZXJ9IGZyb20gJy4vZGwtbW9kZWwtcHJvdmlkZXInO1xuXG4vKipcbiAqIFdvcmsgYXJvdW5kIGZvciBtb21lbnQgbmFtZXNwYWNlIGNvbmZsaWN0IHdoZW4gdXNlZCB3aXRoIHdlYnBhY2sgYW5kIHJvbGx1cC5cbiAqIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZGhlcmdlcy9uZy1wYWNrYWdyL2lzc3Vlcy8xNjNcbiAqXG4gKiBEZXBlbmRpbmcgb24gd2hldGhlciByb2xsdXAgaXMgdXNlZCwgbW9tZW50IG5lZWRzIHRvIGJlIGltcG9ydGVkIGRpZmZlcmVudGx5LlxuICogU2luY2UgTW9tZW50LmpzIGRvZXNuJ3QgaGF2ZSBhIGRlZmF1bHQgZXhwb3J0LCB3ZSBub3JtYWxseSBuZWVkIHRvIGltcG9ydCB1c2luZ1xuICogdGhlIGAqIGFzYHN5bnRheC5cbiAqXG4gKiByb2xsdXAgY3JlYXRlcyBhIHN5bnRoZXRpYyBkZWZhdWx0IG1vZHVsZSBhbmQgd2UgdGh1cyBuZWVkIHRvIGltcG9ydCBpdCB1c2luZ1xuICogdGhlIGBkZWZhdWx0IGFzYCBzeW50YXguXG4gKlxuICogQGludGVybmFsXG4gKiovXG5jb25zdCBtb21lbnQgPSBfbW9tZW50O1xuXG4vKipcbiAqIERlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBgZGF5YCB2aWV3LlxuICovXG5leHBvcnQgY2xhc3MgRGxEYXlNb2RlbFByb3ZpZGVyIGltcGxlbWVudHMgRGxNb2RlbFByb3ZpZGVyIHtcblxuICAvKipcbiAgICogUmVjZWl2ZXMgaW5wdXQgY2hhbmdlcyBkZXRlY3RlZCBieSBBbmd1bGFyLlxuICAgKlxuICAgKiBAcGFyYW0gY2hhbmdlc1xuICAgKiAgdGhlIGlucHV0IGNoYW5nZXMgZGV0ZWN0ZWQgYnkgQW5ndWxhci5cbiAgICovXG4gIG9uQ2hhbmdlcyhcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY2hhbmdlczogU2ltcGxlQ2hhbmdlc1xuICApOiB2b2lkIHt9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGBkYXlgIG1vZGVsIGZvciB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiBgbG9jYWxgIHRpbWUgd2l0aCB0aGVcbiAgICogYGFjdGl2ZWAgZGF5IHNldCB0byB0aGUgZmlyc3QgZGF5IG9mIHRoZSBtb250aC5cbiAgICpcbiAgICogVGhlIGBkYXlgIG1vZGVsIHJlcHJlc2VudHMgYSBtb250aCAoNDIgZGF5cykgYXMgc2l4IHJvd3Mgd2l0aCBzZXZlbiBjb2x1bW5zXG4gICAqIGFuZCBlYWNoIGNlbGwgcmVwcmVzZW50aW5nIG9uZS1kYXkgaW5jcmVtZW50cy5cbiAgICpcbiAgICogVGhlIGBkYXlgIGFsd2F5cyBzdGFydHMgYXQgbWlkbmlnaHQuXG4gICAqXG4gICAqIEVhY2ggY2VsbCByZXByZXNlbnRzIGEgb25lLWRheSBpbmNyZW1lbnQgYXQgbWlkbmlnaHQuXG4gICAqXG4gICAqIEBwYXJhbSBtaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBtaW51dGUgbW9kZWwgd2lsbCBiZSBjcmVhdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgdGhlIG1vZGVsIHJlcHJlc2VudGluZyB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgZ2V0TW9kZWwobWlsbGlzZWNvbmRzOiBudW1iZXIsIHNlbGVjdGVkTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBEbERhdGVUaW1lUGlja2VyTW9kZWwge1xuXG4gICAgY29uc3Qgc3RhcnRPZk1vbnRoID0gbW9tZW50KG1pbGxpc2Vjb25kcykuc3RhcnRPZignbW9udGgnKTtcbiAgICBjb25zdCBlbmRPZk1vbnRoID0gbW9tZW50KG1pbGxpc2Vjb25kcykuZW5kT2YoJ21vbnRoJyk7XG4gICAgY29uc3Qgc3RhcnRPZlZpZXcgPSBtb21lbnQoc3RhcnRPZk1vbnRoKS5zdWJ0cmFjdChNYXRoLmFicyhzdGFydE9mTW9udGgud2Vla2RheSgpKSwgJ2RheXMnKTtcblxuICAgIGNvbnN0IHJvd051bWJlcnMgPSBbMCwgMSwgMiwgMywgNCwgNV07XG4gICAgY29uc3QgY29sdW1uTnVtYmVycyA9IFswLCAxLCAyLCAzLCA0LCA1LCA2XTtcblxuICAgIGNvbnN0IHByZXZpb3VzTW9udGggPSBtb21lbnQoc3RhcnRPZk1vbnRoKS5zdWJ0cmFjdCgxLCAnbW9udGgnKTtcbiAgICBjb25zdCBuZXh0TW9udGggPSBtb21lbnQoc3RhcnRPZk1vbnRoKS5hZGQoMSwgJ21vbnRoJyk7XG4gICAgY29uc3QgYWN0aXZlVmFsdWUgPSBtb21lbnQobWlsbGlzZWNvbmRzKS5zdGFydE9mKCdkYXknKS52YWx1ZU9mKCk7XG4gICAgY29uc3Qgc2VsZWN0ZWRWYWx1ZSA9IHNlbGVjdGVkTWlsbGlzZWNvbmRzID09PSBudWxsIHx8IHNlbGVjdGVkTWlsbGlzZWNvbmRzID09PSB1bmRlZmluZWRcbiAgICAgID8gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICAgIDogbW9tZW50KHNlbGVjdGVkTWlsbGlzZWNvbmRzKS5zdGFydE9mKCdkYXknKS52YWx1ZU9mKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmlld05hbWU6ICdkYXknLFxuICAgICAgdmlld0xhYmVsOiBzdGFydE9mTW9udGguZm9ybWF0KCdNTU0gWVlZWScpLFxuICAgICAgYWN0aXZlRGF0ZTogYWN0aXZlVmFsdWUsXG4gICAgICBsZWZ0QnV0dG9uOiB7XG4gICAgICAgIHZhbHVlOiBwcmV2aW91c01vbnRoLnZhbHVlT2YoKSxcbiAgICAgICAgYXJpYUxhYmVsOiBgR28gdG8gJHtwcmV2aW91c01vbnRoLmZvcm1hdCgnTU1NIFlZWVknKX1gLFxuICAgICAgICBjbGFzc2VzOiB7fSxcbiAgICAgIH0sXG4gICAgICB1cEJ1dHRvbjoge1xuICAgICAgICB2YWx1ZTogc3RhcnRPZk1vbnRoLnZhbHVlT2YoKSxcbiAgICAgICAgYXJpYUxhYmVsOiBgR28gdG8gbW9udGggdmlld2AsXG4gICAgICAgIGNsYXNzZXM6IHt9LFxuICAgICAgfSxcbiAgICAgIHJpZ2h0QnV0dG9uOiB7XG4gICAgICAgIHZhbHVlOiBuZXh0TW9udGgudmFsdWVPZigpLFxuICAgICAgICBhcmlhTGFiZWw6IGBHbyB0byAke25leHRNb250aC5mb3JtYXQoJ01NTSBZWVlZJyl9YCxcbiAgICAgICAgY2xhc3Nlczoge30sXG4gICAgICB9LFxuICAgICAgcm93TGFiZWxzOiBjb2x1bW5OdW1iZXJzLm1hcCgoY29sdW1uKSA9PiBtb21lbnQoKS53ZWVrZGF5KGNvbHVtbikuZm9ybWF0KCdkZCcpKSxcbiAgICAgIHJvd3M6IHJvd051bWJlcnMubWFwKHJvd09mRGF5cylcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcm93T2ZEYXlzKHJvd051bWJlcikge1xuICAgICAgY29uc3QgY3VycmVudE1vbWVudCA9IG1vbWVudCgpO1xuICAgICAgY29uc3QgY2VsbHMgPSBjb2x1bW5OdW1iZXJzLm1hcCgoY29sdW1uTnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGRheU1vbWVudCA9IG1vbWVudChzdGFydE9mVmlldykuYWRkKChyb3dOdW1iZXIgKiBjb2x1bW5OdW1iZXJzLmxlbmd0aCkgKyBjb2x1bW5OdW1iZXIsICdkYXlzJyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZGlzcGxheTogZGF5TW9tZW50LmZvcm1hdCgnRCcpLFxuICAgICAgICAgIGFyaWFMYWJlbDogZGF5TW9tZW50LmZvcm1hdCgnbGwnKSxcbiAgICAgICAgICB2YWx1ZTogZGF5TW9tZW50LnZhbHVlT2YoKSxcbiAgICAgICAgICBjbGFzc2VzOiB7XG4gICAgICAgICAgICAnZGwtYWJkdHAtYWN0aXZlJzogYWN0aXZlVmFsdWUgPT09IGRheU1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgICAgICAnZGwtYWJkdHAtZnV0dXJlJzogZGF5TW9tZW50LmlzQWZ0ZXIoZW5kT2ZNb250aCksXG4gICAgICAgICAgICAnZGwtYWJkdHAtcGFzdCc6IGRheU1vbWVudC5pc0JlZm9yZShzdGFydE9mTW9udGgpLFxuICAgICAgICAgICAgJ2RsLWFiZHRwLXNlbGVjdGVkJzogc2VsZWN0ZWRWYWx1ZSA9PT0gZGF5TW9tZW50LnZhbHVlT2YoKSxcbiAgICAgICAgICAgICdkbC1hYmR0cC1ub3cnOiBkYXlNb21lbnQuaXNTYW1lKGN1cnJlbnRNb21lbnQsICdkYXknKSxcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7Y2VsbHN9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBhY3RpdmUgYGRheWAgb25lIHJvdyBgZG93bmAgZnJvbSB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKlxuICAgKiBNb3ZpbmcgYGRvd25gIGNhbiByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIGRheSBiZWluZyBwYXJ0IG9mIGEgZGlmZmVyZW50IG1vbnRoIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgbW9udGggcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgaG91ci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBkYXlgIG1vZGVsIGBkb3duYCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgZGF5YCBvbmUgcm93IGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnb0Rvd24oZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKDcsICdkYXlzJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYWN0aXZlIGBkYXlgIG9uZSByb3cgYHVwYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIE1vdmluZyBgdXBgIGNhbiByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIGRheSBiZWluZyBwYXJ0IG9mIGEgZGlmZmVyZW50IG1vbnRoIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgbW9udGggcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgaG91ci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBkYXlgIG1vZGVsIGB1cGAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYGRheWAgb25lIHJvdyBgdXBgIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdvVXAoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3VidHJhY3QoNywgJ2RheXMnKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBgYWN0aXZlYCBkYXkgb25lIGNlbGwgYGxlZnRgIGluIHRoZSBjdXJyZW50IGBkYXlgIHZpZXcuXG4gICAqXG4gICAqIE1vdmluZyBgbGVmdGAgY2FuIHJlc3VsdCBpbiB0aGUgYGFjdGl2ZWAgZGF5IGJlaW5nIHBhcnQgb2YgYSBkaWZmZXJlbnQgbW9udGggdGhhblxuICAgKiB0aGUgc3BlY2lmaWVkIGBmcm9tTWlsbGlzZWNvbmRzYCwgaW4gdGhpcyBjYXNlIHRoZSBtb250aCByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCB5ZWFyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIGBkYXlgIG1vZGVsIHRvIHRoZSBgbGVmdGAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYGRheWAgb25lIGNlbGwgdG8gdGhlIGBsZWZ0YCBvZiB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgZ29MZWZ0KGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN1YnRyYWN0KDEsICdkYXknKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBgYWN0aXZlYCBkYXkgb25lIGNlbGwgYHJpZ2h0YCBpbiB0aGUgY3VycmVudCBgZGF5YCB2aWV3LlxuICAgKlxuICAgKiBNb3ZpbmcgYHJpZ2h0YCBjYW4gcmVzdWx0IGluIHRoZSBgYWN0aXZlYCBkYXkgYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCBtb250aCB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLCBpbiB0aGlzIGNhc2UgdGhlIG1vbnRoIHJlcHJlc2VudGVkIGJ5IHRoZSBtb2RlbFxuICAgKiB3aWxsIGNoYW5nZSB0byBzaG93IHRoZSBjb3JyZWN0IHllYXIuXG4gICAqXG4gICAqIEBwYXJhbSBmcm9tTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgbW9tZW50IGluIHRpbWUgZnJvbSB3aGljaCB0aGUgYGRheWAgbW9kZWwgdG8gdGhlIGByaWdodGAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYGRheWAgb25lIGNlbGwgdG8gdGhlIGByaWdodGAgb2YgdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdvUmlnaHQoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKDEsICdkYXknKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBhY3RpdmUgYGRheWAgb25lIG1vbnRoIGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIFBhZ2luZyBgZG93bmAgd2lsbCByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIGRheSBiZWluZyBwYXJ0IG9mIGEgZGlmZmVyZW50IG1vbnRoIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AuIEFzIGEgcmVzdWx0LCB0aGUgbW9udGggcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgeWVhci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBkYXlgIG1vZGVsIHBhZ2UgYGRvd25gIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBkYXlgIG9uZSBtb250aCBgZG93bmAgZnJvbSB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgcGFnZURvd24oZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKDEsICdtb250aCcpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGFjdGl2ZSBgZGF5YCBvbmUgbW9udGggYHVwYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIFBhZ2luZyBgdXBgIHdpbGwgcmVzdWx0IGluIHRoZSBgYWN0aXZlYCBkYXkgYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCBtb250aCB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLiBBcyBhIHJlc3VsdCwgdGhlIG1vbnRoIHJlcHJlc2VudGVkIGJ5IHRoZSBtb2RlbFxuICAgKiB3aWxsIGNoYW5nZSB0byBzaG93IHRoZSBjb3JyZWN0IHllYXIuXG4gICAqXG4gICAqIEBwYXJhbSBmcm9tTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgbW9tZW50IGluIHRpbWUgZnJvbSB3aGljaCB0aGUgbmV4dCBgZGF5YCBtb2RlbCBwYWdlIGB1cGAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYGRheWAgb25lIG1vbnRoIGB1cGAgZnJvbSB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgcGFnZVVwKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN1YnRyYWN0KDEsICdtb250aCcpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cblxuICAvKipcbiAgICogTW92ZSB0aGUgYGFjdGl2ZWAgYGRheWAgdG8gdGhlIGxhc3QgZGF5IG9mIHRoZSBtb250aC5cbiAgICpcbiAgICogVGhlIHZpZXcgb3IgdGltZSByYW5nZSB3aWxsIG5vdCBjaGFuZ2UgdW5sZXNzIHRoZSBgZnJvbU1pbGxpc2Vjb25kc2AgdmFsdWVcbiAgICogaXMgaW4gYSBkaWZmZXJlbnQgZGF5IHRoYW4gdGhlIGRpc3BsYXllZCBkZWNhZGUuXG4gICAqXG4gICAqIEBwYXJhbSBmcm9tTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgbW9tZW50IGluIHRpbWUgZnJvbSB3aGljaCB0aGUgbGFzdCBkYXkgb2YgdGhlIG1vbnRoIHdpbGwgYmUgY2FsY3VsYXRlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIGEgbW9kZWwgd2l0aCB0aGUgbGFzdCBjZWxsIGluIHRoZSB2aWV3IGFzIHRoZSBhY3RpdmUgYGRheWAuXG4gICAqL1xuICBnb0VuZChmcm9tTWlsbGlzZWNvbmRzOiBudW1iZXIsIHNlbGVjdGVkTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBEbERhdGVUaW1lUGlja2VyTW9kZWwge1xuICAgIHJldHVybiB0aGlzLmdldE1vZGVsKG1vbWVudChmcm9tTWlsbGlzZWNvbmRzKVxuICAgICAgLmVuZE9mKCdtb250aCcpLnN0YXJ0T2YoJ2RheScpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGBhY3RpdmVgIGBkYXlgIHRvIHRoZSBmaXJzdCBkYXkgb2YgdGhlIG1vbnRoLlxuICAgKlxuICAgKiBUaGUgdmlldyBvciB0aW1lIHJhbmdlIHdpbGwgbm90IGNoYW5nZSB1bmxlc3MgdGhlIGBmcm9tTWlsbGlzZWNvbmRzYCB2YWx1ZVxuICAgKiBpcyBpbiBhIGRpZmZlcmVudCBkYXkgdGhhbiB0aGUgZGlzcGxheWVkIGRlY2FkZS5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBmaXJzdCBkYXkgb2YgdGhlIG1vbnRoIHdpbGwgYmUgY2FsY3VsYXRlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIGEgbW9kZWwgd2l0aCB0aGUgZmlyc3QgY2VsbCBpbiB0aGUgdmlldyBhcyB0aGUgYWN0aXZlIGBkYXlgLlxuICAgKi9cbiAgZ29Ib21lKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN0YXJ0T2YoJ21vbnRoJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cbn1cbiJdfQ==