UNPKG

@nova-ui/bits

Version:

SolarWinds Nova Framework

226 lines (224 loc) 28.2 kB
// © 2022 SolarWinds Worldwide, LLC. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { Injectable } from "@angular/core"; import extend from "lodash/extend"; import isUndefined from "lodash/isUndefined"; import moment from "moment/moment"; import * as i0 from "@angular/core"; /** * __Name : __ * Timeframe service * * __Usage :__ * Used to get time frames via time patterns or presets */ /** * @ignore */ export class TimeframeService { static cloneTimeFrame(timeFrame) { return { ...timeFrame, startDatetime: timeFrame.startDatetime.clone(), endDatetime: timeFrame.endDatetime.clone(), }; } constructor() { this.defaultPresets = { lastHour: { name: $localize `Last hour`, startDatetimePattern: { hours: -1 }, endDatetimePattern: {}, }, last12Hours: { name: $localize `Last 12 hours`, startDatetimePattern: { hours: -12 }, endDatetimePattern: {}, }, last24Hours: { name: $localize `Last 24 hours`, startDatetimePattern: { hours: -24 }, endDatetimePattern: {}, }, last5Days: { name: $localize `Last 5 days`, startDatetimePattern: { days: -5 }, endDatetimePattern: {}, }, last7Days: { name: $localize `Last 7 days`, startDatetimePattern: { days: -7 }, endDatetimePattern: {}, }, last30Days: { name: $localize `Last 30 days`, startDatetimePattern: { days: -30 }, endDatetimePattern: {}, }, }; this.currentPresets = extend({}, this.defaultPresets); /** * __Description:__ Updates start and end time of timeframe according to preset if selected * * @param timeFrame timeframe to be updated * @param presets presets to look at. Defaults to service's currentPresets * @param baseDatetime date that should be used for relative time calculations. Defaults to now. * @returns updated clone of timeframe with startDatetime and endDatetime reconciled with selectedPresetId */ this.reconcileTimeframe = (timeFrame, presets, baseDatetime) => { if (!presets) { presets = this.currentPresets; } if (!baseDatetime) { baseDatetime = moment(); } const preset = timeFrame.selectedPresetId && presets[timeFrame.selectedPresetId]; return preset ? { ...timeFrame, startDatetime: baseDatetime .clone() .add(preset.startDatetimePattern), endDatetime: baseDatetime .clone() .add(preset.endDatetimePattern), } : TimeframeService.cloneTimeFrame(timeFrame); }; } /** * * __Description:__ Get timeframe from patterns of start and end points in time * @param startDatetimePattern * @param endDatetimePattern * @param baseDatetime */ getTimeframe(startDatetimePattern, endDatetimePattern, baseDatetime) { // check input parameters if (isUndefined(startDatetimePattern)) { throw new Error("Parameter 'startDatetimePattern' is undefined"); } if (isUndefined(endDatetimePattern)) { throw new Error("Parameter 'endDateTimePattern' is undefined"); } const startDatetime = moment(baseDatetime).add(startDatetimePattern); const endDatetime = moment(baseDatetime).add(endDatetimePattern); return { startDatetime: startDatetime, endDatetime: endDatetime, // @ts-ignore: preventing breaking default flow; selectedPresetId: null, }; } /** * __Description:__ Get timeframe by preset id, using the list of pre-defined presets */ getTimeframeByPresetId(id, baseDatetime) { // check input parameters if (isUndefined(id)) { throw new Error("Parameter 'id' is undefined"); } const startDatetime = moment(baseDatetime).add(this.currentPresets[id].startDatetimePattern); const endDatetime = moment(baseDatetime).add(this.currentPresets[id].endDatetimePattern); return { startDatetime: startDatetime, endDatetime: endDatetime, selectedPresetId: id, title: this.currentPresets[id].name, }; } /** * __Description:__ Get the list of all default presets */ getDefaultPresets() { return this.defaultPresets; } /** * __Description:__ Add custom presets to existing list of default presets * @param presets */ extendCurrentPresets(presets) { extend(this.currentPresets, presets); } /** * __Description:__ Compare two timeframes, return false if they are not equal */ isEqual(firstTimeFrame, secondTimeFrame, units = "minutes") { return (firstTimeFrame && secondTimeFrame && firstTimeFrame.endDatetime.isSame(secondTimeFrame.endDatetime, units) && firstTimeFrame.startDatetime.isSame(secondTimeFrame.startDatetime, units)); } /** * __Description:__ Compare two timeframe durations, return false if they are not equal */ isEqualDuration(firstTimeFrame, secondTimeFrame, units = "minutes") { return (firstTimeFrame && secondTimeFrame && firstTimeFrame.startDatetime.diff(firstTimeFrame.endDatetime, units) === secondTimeFrame.startDatetime.diff(secondTimeFrame.endDatetime, units)); } /** * __Description:__ * Adds the specified duration to startDatetime and endDatetime and returns a new timeframe. * Note: Input timeframe is not mutated. * * @param {ITimeframe} timeFrame The timeframe to shift * @param {Duration} duration The duration of the timeframe shift * @returns {ITimeframe} The shifted timeframe */ shiftTimeFrame(timeFrame, duration) { return { startDatetime: timeFrame.startDatetime.clone().add(duration), endDatetime: timeFrame.endDatetime.clone().add(duration), // @ts-ignore: preventing breaking default flow; selectedPresetId: null, }; } /** * __Description:__ * Returns the difference between timeFrame's startDatetime and endDatetime as moment.Duration * * @param {ITimeframe} timeFrame * @returns {Duration} */ getDuration(timeFrame) { return moment.duration(timeFrame.endDatetime.diff(timeFrame.startDatetime)); } /** * __Description:__ * Checks timeFrame "startDatetime" and "endDatetime" attributes for moment validity * * @param {ITimeframe} tf * @returns {Boolean} */ areTimeFrameDatesValid(tf) { const { startDatetime, endDatetime } = tf; const startValid = startDatetime && startDatetime.isValid(); const endValid = endDatetime && endDatetime.isValid(); return startValid && endValid; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TimeframeService, decorators: [{ type: Injectable }], ctorParameters: () => [] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWZyYW1lLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RpbWUtZnJhbWUtcGlja2VyL3NlcnZpY2VzL3RpbWVmcmFtZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUN6RCxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSw0REFBNEQ7QUFDNUQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsRUFBRTtBQUNGLDZFQUE2RTtBQUM3RSw0RUFBNEU7QUFDNUUsK0VBQStFO0FBQy9FLDBFQUEwRTtBQUMxRSxpRkFBaUY7QUFDakYsNkVBQTZFO0FBQzdFLGlCQUFpQjtBQUVqQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sTUFBTSxNQUFNLGVBQWUsQ0FBQztBQUNuQyxPQUFPLFdBQVcsTUFBTSxvQkFBb0IsQ0FBQztBQUM3QyxPQUFPLE1BQTRCLE1BQU0sZUFBZSxDQUFDOztBQUl6RDs7Ozs7O0dBTUc7QUFDSDs7R0FFRztBQUVILE1BQU0sT0FBTyxnQkFBZ0I7SUFDbEIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUFxQjtRQUM5QyxPQUFPO1lBQ0gsR0FBRyxTQUFTO1lBQ1osYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFO1lBQzlDLFdBQVcsRUFBRSxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRTtTQUM3QyxDQUFDO0lBQ04sQ0FBQztJQXdDRDtRQXRDTyxtQkFBYyxHQUErQjtZQUNoRCxRQUFRLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLFNBQVMsQ0FBQSxXQUFXO2dCQUMxQixvQkFBb0IsRUFBRSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRTtnQkFDbkMsa0JBQWtCLEVBQUUs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QUM7K0dBM1BRLGdCQUFnQjttSEFBaEIsZ0JBQWdCOzs0RkFBaEIsZ0JBQWdCO2tCQUQ1QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiLy8gwqkgMjAyMiBTb2xhcldpbmRzIFdvcmxkd2lkZSwgTExDLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vICBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0b1xuLy8gIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlXG4vLyAgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yXG4vLyAgc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vICBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4vLyAgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuLy8gIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vICBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuLy8gIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbi8vICBUSEUgU09GVFdBUkUuXG5cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IGV4dGVuZCBmcm9tIFwibG9kYXNoL2V4dGVuZFwiO1xuaW1wb3J0IGlzVW5kZWZpbmVkIGZyb20gXCJsb2Rhc2gvaXNVbmRlZmluZWRcIjtcbmltcG9ydCBtb21lbnQsIHsgRHVyYXRpb24sIE1vbWVudCB9IGZyb20gXCJtb21lbnQvbW9tZW50XCI7XG5cbmltcG9ydCB7IElUaW1lZnJhbWUsIElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5IH0gZnJvbSBcIi4uL3B1YmxpYy1hcGlcIjtcblxuLyoqXG4gKiBfX05hbWUgOiBfX1xuICogVGltZWZyYW1lIHNlcnZpY2VcbiAqXG4gKiBfX1VzYWdlIDpfX1xuICogVXNlZCB0byBnZXQgdGltZSBmcmFtZXMgdmlhIHRpbWUgcGF0dGVybnMgb3IgcHJlc2V0c1xuICovXG4vKipcbiAqIEBpZ25vcmVcbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFRpbWVmcmFtZVNlcnZpY2Uge1xuICAgIHB1YmxpYyBzdGF0aWMgY2xvbmVUaW1lRnJhbWUodGltZUZyYW1lOiBJVGltZWZyYW1lKTogSVRpbWVmcmFtZSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi50aW1lRnJhbWUsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lOiB0aW1lRnJhbWUuc3RhcnREYXRldGltZS5jbG9uZSgpLFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWU6IHRpbWVGcmFtZS5lbmREYXRldGltZS5jbG9uZSgpLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBkZWZhdWx0UHJlc2V0czogSVRpbWVGcmFtZVByZXNldERpY3Rpb25hcnkgPSB7XG4gICAgICAgIGxhc3RIb3VyOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCBob3VyYCxcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiB7IGhvdXJzOiAtMSB9LFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWVQYXR0ZXJuOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgbGFzdDEySG91cnM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDEyIGhvdXJzYCxcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiB7IGhvdXJzOiAtMTIgfSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjoge30sXG4gICAgICAgIH0sXG4gICAgICAgIGxhc3QyNEhvdXJzOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCAyNCBob3Vyc2AsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lUGF0dGVybjogeyBob3VyczogLTI0IH0sXG4gICAgICAgICAgICBlbmREYXRldGltZVBhdHRlcm46IHt9LFxuICAgICAgICB9LFxuICAgICAgICBsYXN0NURheXM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDUgZGF5c2AsXG4gICAgICAgICAgICBzdGFydERhdGV0aW1lUGF0dGVybjogeyBkYXlzOiAtNSB9LFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWVQYXR0ZXJuOiB7fSxcbiAgICAgICAgfSxcbiAgICAgICAgbGFzdDdEYXlzOiB7XG4gICAgICAgICAgICBuYW1lOiAkbG9jYWxpemVgTGFzdCA3IGRheXNgLFxuICAgICAgICAgICAgc3RhcnREYXRldGltZVBhdHRlcm46IHsgZGF5czogLTcgfSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjoge30sXG4gICAgICAgIH0sXG4gICAgICAgIGxhc3QzMERheXM6IHtcbiAgICAgICAgICAgIG5hbWU6ICRsb2NhbGl6ZWBMYXN0IDMwIGRheXNgLFxuICAgICAgICAgICAgc3RhcnREYXRldGltZVBhdHRlcm46IHsgZGF5czogLTMwIH0sXG4gICAgICAgICAgICBlbmREYXRldGltZVBhdHRlcm46IHt9LFxuICAgICAgICB9LFxuICAgIH07XG5cbiAgICBwdWJsaWMgY3VycmVudFByZXNldHM6IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5ID0gZXh0ZW5kKFxuICAgICAgICB7fSxcbiAgICAgICAgdGhpcy5kZWZhdWx0UHJlc2V0c1xuICAgICk7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIF9fRGVzY3JpcHRpb246X18gR2V0IHRpbWVmcmFtZSBmcm9tIHBhdHRlcm5zIG9mIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIGluIHRpbWVcbiAgICAgKiBAcGFyYW0gc3RhcnREYXRldGltZVBhdHRlcm5cbiAgICAgKiBAcGFyYW0gZW5kRGF0ZXRpbWVQYXR0ZXJuXG4gICAgICogQHBhcmFtIGJhc2VEYXRldGltZVxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRUaW1lZnJhbWUoXG4gICAgICAgIHN0YXJ0RGF0ZXRpbWVQYXR0ZXJuOiBhbnksXG4gICAgICAgIGVuZERhdGV0aW1lUGF0dGVybjogYW55LFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBzdHJpbmdcbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgLy8gY2hlY2sgaW5wdXQgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoaXNVbmRlZmluZWQoc3RhcnREYXRldGltZVBhdHRlcm4pKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXJhbWV0ZXIgJ3N0YXJ0RGF0ZXRpbWVQYXR0ZXJuJyBpcyB1bmRlZmluZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNVbmRlZmluZWQoZW5kRGF0ZXRpbWVQYXR0ZXJuKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFyYW1ldGVyICdlbmREYXRlVGltZVBhdHRlcm4nIGlzIHVuZGVmaW5lZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZXRpbWUgPSBtb21lbnQoYmFzZURhdGV0aW1lKS5hZGQoc3RhcnREYXRldGltZVBhdHRlcm4pO1xuICAgICAgICBjb25zdCBlbmREYXRldGltZSA9IG1vbWVudChiYXNlRGF0ZXRpbWUpLmFkZChlbmREYXRldGltZVBhdHRlcm4pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGFydERhdGV0aW1lOiBzdGFydERhdGV0aW1lLFxuICAgICAgICAgICAgZW5kRGF0ZXRpbWU6IGVuZERhdGV0aW1lLFxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogcHJldmVudGluZyBicmVha2luZyBkZWZhdWx0IGZsb3c7XG4gICAgICAgICAgICBzZWxlY3RlZFByZXNldElkOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIF9fRGVzY3JpcHRpb246X18gR2V0IHRpbWVmcmFtZSBieSBwcmVzZXQgaWQsIHVzaW5nIHRoZSBsaXN0IG9mIHByZS1kZWZpbmVkIHByZXNldHNcblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRUaW1lZnJhbWVCeVByZXNldElkKFxuICAgICAgICBpZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBzdHJpbmdcbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgLy8gY2hlY2sgaW5wdXQgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoaXNVbmRlZmluZWQoaWQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXJhbWV0ZXIgJ2lkJyBpcyB1bmRlZmluZWRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFydERhdGV0aW1lID0gbW9tZW50KGJhc2VEYXRldGltZSkuYWRkKFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50UHJlc2V0c1tpZF0uc3RhcnREYXRldGltZVBhdHRlcm5cbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZW5kRGF0ZXRpbWUgPSBtb21lbnQoYmFzZURhdGV0aW1lKS5hZGQoXG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRQcmVzZXRzW2lkXS5lbmREYXRldGltZVBhdHRlcm5cbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3RhcnREYXRldGltZTogc3RhcnREYXRldGltZSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lOiBlbmREYXRldGltZSxcbiAgICAgICAgICAgIHNlbGVjdGVkUHJlc2V0SWQ6IGlkLFxuICAgICAgICAgICAgdGl0bGU6IHRoaXMuY3VycmVudFByZXNldHNbaWRdLm5hbWUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBVcGRhdGVzIHN0YXJ0IGFuZCBlbmQgdGltZSBvZiB0aW1lZnJhbWUgYWNjb3JkaW5nIHRvIHByZXNldCBpZiBzZWxlY3RlZFxuICAgICAqXG4gICAgICogQHBhcmFtIHRpbWVGcmFtZSB0aW1lZnJhbWUgdG8gYmUgdXBkYXRlZFxuICAgICAqIEBwYXJhbSBwcmVzZXRzIHByZXNldHMgdG8gbG9vayBhdC4gRGVmYXVsdHMgdG8gc2VydmljZSdzIGN1cnJlbnRQcmVzZXRzXG4gICAgICogQHBhcmFtIGJhc2VEYXRldGltZSBkYXRlIHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHJlbGF0aXZlIHRpbWUgY2FsY3VsYXRpb25zLiBEZWZhdWx0cyB0byBub3cuXG4gICAgICogQHJldHVybnMgdXBkYXRlZCBjbG9uZSBvZiB0aW1lZnJhbWUgd2l0aCBzdGFydERhdGV0aW1lIGFuZCBlbmREYXRldGltZSByZWNvbmNpbGVkIHdpdGggc2VsZWN0ZWRQcmVzZXRJZFxuICAgICAqL1xuICAgIHB1YmxpYyByZWNvbmNpbGVUaW1lZnJhbWUgPSAoXG4gICAgICAgIHRpbWVGcmFtZTogSVRpbWVmcmFtZSxcbiAgICAgICAgcHJlc2V0cz86IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5LFxuICAgICAgICBiYXNlRGF0ZXRpbWU/OiBNb21lbnRcbiAgICApOiBJVGltZWZyYW1lID0+IHtcbiAgICAgICAgaWYgKCFwcmVzZXRzKSB7XG4gICAgICAgICAgICBwcmVzZXRzID0gdGhpcy5jdXJyZW50UHJlc2V0cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWJhc2VEYXRldGltZSkge1xuICAgICAgICAgICAgYmFzZURhdGV0aW1lID0gbW9tZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwcmVzZXQgPVxuICAgICAgICAgICAgdGltZUZyYW1lLnNlbGVjdGVkUHJlc2V0SWQgJiYgcHJlc2V0c1t0aW1lRnJhbWUuc2VsZWN0ZWRQcmVzZXRJZF07XG4gICAgICAgIHJldHVybiBwcmVzZXRcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgLi4udGltZUZyYW1lLFxuICAgICAgICAgICAgICAgICAgc3RhcnREYXRldGltZTogYmFzZURhdGV0aW1lXG4gICAgICAgICAgICAgICAgICAgICAgLmNsb25lKClcbiAgICAgICAgICAgICAgICAgICAgICAuYWRkKHByZXNldC5zdGFydERhdGV0aW1lUGF0dGVybiksXG4gICAgICAgICAgICAgICAgICBlbmREYXRldGltZTogYmFzZURhdGV0aW1lXG4gICAgICAgICAgICAgICAgICAgICAgLmNsb25lKClcbiAgICAgICAgICAgICAgICAgICAgICAuYWRkKHByZXNldC5lbmREYXRldGltZVBhdHRlcm4pLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IFRpbWVmcmFtZVNlcnZpY2UuY2xvbmVUaW1lRnJhbWUodGltZUZyYW1lKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBHZXQgdGhlIGxpc3Qgb2YgYWxsIGRlZmF1bHQgcHJlc2V0c1xuXG4gICAgICovXG4gICAgcHVibGljIGdldERlZmF1bHRQcmVzZXRzKCk6IElUaW1lRnJhbWVQcmVzZXREaWN0aW9uYXJ5IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdFByZXNldHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBBZGQgY3VzdG9tIHByZXNldHMgdG8gZXhpc3RpbmcgbGlzdCBvZiBkZWZhdWx0IHByZXNldHNcbiAgICAgKiBAcGFyYW0gcHJlc2V0c1xuICAgICAqL1xuICAgIHB1YmxpYyBleHRlbmRDdXJyZW50UHJlc2V0cyhwcmVzZXRzOiBJVGltZUZyYW1lUHJlc2V0RGljdGlvbmFyeSk6IHZvaWQge1xuICAgICAgICBleHRlbmQodGhpcy5jdXJyZW50UHJlc2V0cywgcHJlc2V0cyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBDb21wYXJlIHR3byB0aW1lZnJhbWVzLCByZXR1cm4gZmFsc2UgaWYgdGhleSBhcmUgbm90IGVxdWFsXG4gICAgICovXG4gICAgcHVibGljIGlzRXF1YWwoXG4gICAgICAgIGZpcnN0VGltZUZyYW1lOiBJVGltZWZyYW1lLFxuICAgICAgICBzZWNvbmRUaW1lRnJhbWU6IElUaW1lZnJhbWUsXG4gICAgICAgIHVuaXRzOiBtb21lbnQudW5pdE9mVGltZS5CYXNlID0gXCJtaW51dGVzXCJcbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lICYmXG4gICAgICAgICAgICBzZWNvbmRUaW1lRnJhbWUgJiZcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLmVuZERhdGV0aW1lLmlzU2FtZShcbiAgICAgICAgICAgICAgICBzZWNvbmRUaW1lRnJhbWUuZW5kRGF0ZXRpbWUsXG4gICAgICAgICAgICAgICAgdW5pdHNcbiAgICAgICAgICAgICkgJiZcbiAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLnN0YXJ0RGF0ZXRpbWUuaXNTYW1lKFxuICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5zdGFydERhdGV0aW1lLFxuICAgICAgICAgICAgICAgIHVuaXRzXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfXyBDb21wYXJlIHR3byB0aW1lZnJhbWUgZHVyYXRpb25zLCByZXR1cm4gZmFsc2UgaWYgdGhleSBhcmUgbm90IGVxdWFsXG4gICAgICovXG4gICAgcHVibGljIGlzRXF1YWxEdXJhdGlvbihcbiAgICAgICAgZmlyc3RUaW1lRnJhbWU6IElUaW1lZnJhbWUsXG4gICAgICAgIHNlY29uZFRpbWVGcmFtZTogSVRpbWVmcmFtZSxcbiAgICAgICAgdW5pdHM6IG1vbWVudC51bml0T2ZUaW1lLkJhc2UgPSBcIm1pbnV0ZXNcIlxuICAgICk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgZmlyc3RUaW1lRnJhbWUgJiZcbiAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZSAmJlxuICAgICAgICAgICAgZmlyc3RUaW1lRnJhbWUuc3RhcnREYXRldGltZS5kaWZmKFxuICAgICAgICAgICAgICAgIGZpcnN0VGltZUZyYW1lLmVuZERhdGV0aW1lLFxuICAgICAgICAgICAgICAgIHVuaXRzXG4gICAgICAgICAgICApID09PVxuICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5zdGFydERhdGV0aW1lLmRpZmYoXG4gICAgICAgICAgICAgICAgICAgIHNlY29uZFRpbWVGcmFtZS5lbmREYXRldGltZSxcbiAgICAgICAgICAgICAgICAgICAgdW5pdHNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfX1xuICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBkdXJhdGlvbiB0byBzdGFydERhdGV0aW1lIGFuZCBlbmREYXRldGltZSBhbmQgcmV0dXJucyBhIG5ldyB0aW1lZnJhbWUuXG4gICAgICogTm90ZTogSW5wdXQgdGltZWZyYW1lIGlzIG5vdCBtdXRhdGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtJVGltZWZyYW1lfSB0aW1lRnJhbWUgVGhlIHRpbWVmcmFtZSB0byBzaGlmdFxuICAgICAqIEBwYXJhbSB7RHVyYXRpb259IGR1cmF0aW9uIFRoZSBkdXJhdGlvbiBvZiB0aGUgdGltZWZyYW1lIHNoaWZ0XG4gICAgICogQHJldHVybnMge0lUaW1lZnJhbWV9IFRoZSBzaGlmdGVkIHRpbWVmcmFtZVxuICAgICAqL1xuICAgIHB1YmxpYyBzaGlmdFRpbWVGcmFtZShcbiAgICAgICAgdGltZUZyYW1lOiBJVGltZWZyYW1lLFxuICAgICAgICBkdXJhdGlvbjogRHVyYXRpb25cbiAgICApOiBJVGltZWZyYW1lIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0RGF0ZXRpbWU6IHRpbWVGcmFtZS5zdGFydERhdGV0aW1lLmNsb25lKCkuYWRkKGR1cmF0aW9uKSxcbiAgICAgICAgICAgIGVuZERhdGV0aW1lOiB0aW1lRnJhbWUuZW5kRGF0ZXRpbWUuY2xvbmUoKS5hZGQoZHVyYXRpb24pLFxuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZTogcHJldmVudGluZyBicmVha2luZyBkZWZhdWx0IGZsb3c7XG4gICAgICAgICAgICBzZWxlY3RlZFByZXNldElkOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIF9fRGVzY3JpcHRpb246X19cbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGltZUZyYW1lJ3Mgc3RhcnREYXRldGltZSBhbmQgZW5kRGF0ZXRpbWUgYXMgbW9tZW50LkR1cmF0aW9uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0lUaW1lZnJhbWV9IHRpbWVGcmFtZVxuICAgICAqIEByZXR1cm5zIHtEdXJhdGlvbn1cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RHVyYXRpb24odGltZUZyYW1lOiBJVGltZWZyYW1lKTogRHVyYXRpb24ge1xuICAgICAgICByZXR1cm4gbW9tZW50LmR1cmF0aW9uKFxuICAgICAgICAgICAgdGltZUZyYW1lLmVuZERhdGV0aW1lLmRpZmYodGltZUZyYW1lLnN0YXJ0RGF0ZXRpbWUpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogX19EZXNjcmlwdGlvbjpfX1xuICAgICAqIENoZWNrcyB0aW1lRnJhbWUgXCJzdGFydERhdGV0aW1lXCIgYW5kIFwiZW5kRGF0ZXRpbWVcIiBhdHRyaWJ1dGVzIGZvciBtb21lbnQgdmFsaWRpdHlcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7SVRpbWVmcmFtZX0gdGZcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cbiAgICBwdWJsaWMgYXJlVGltZUZyYW1lRGF0ZXNWYWxpZCh0ZjogSVRpbWVmcmFtZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB7IHN0YXJ0RGF0ZXRpbWUsIGVuZERhdGV0aW1lIH0gPSB0ZjtcbiAgICAgICAgY29uc3Qgc3RhcnRWYWxpZCA9IHN0YXJ0RGF0ZXRpbWUgJiYgc3RhcnREYXRldGltZS5pc1ZhbGlkKCk7XG4gICAgICAgIGNvbnN0IGVuZFZhbGlkID0gZW5kRGF0ZXRpbWUgJiYgZW5kRGF0ZXRpbWUuaXNWYWxpZCgpO1xuXG4gICAgICAgIHJldHVybiBzdGFydFZhbGlkICYmIGVuZFZhbGlkO1xuICAgIH1cbn1cbiJdfQ==