@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
251 lines • 30.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const token_1 = require("./token");
/**
* Represents a length of time.
*
* The amount can be specified either as a literal value (e.g: `10`) which
* cannot be negative, or as an unresolved number token.
*
* When the amount is passed as a token, unit conversion is not possible.
*/
class Duration {
constructor(amount, unit) {
if (!token_1.Token.isUnresolved(amount) && amount < 0) {
throw new Error(`Duration amounts cannot be negative. Received: ${amount}`);
}
this.amount = amount;
this.unit = unit;
}
/**
* Create a Duration representing an amount of milliseconds
*
* @param amount the amount of Milliseconds the `Duration` will represent.
* @returns a new `Duration` representing `amount` ms.
*/
static millis(amount) {
return new Duration(amount, TimeUnit.Milliseconds);
}
/**
* Create a Duration representing an amount of seconds
*
* @param amount the amount of Seconds the `Duration` will represent.
* @returns a new `Duration` representing `amount` Seconds.
*/
static seconds(amount) {
return new Duration(amount, TimeUnit.Seconds);
}
/**
* Create a Duration representing an amount of minutes
*
* @param amount the amount of Minutes the `Duration` will represent.
* @returns a new `Duration` representing `amount` Minutes.
*/
static minutes(amount) {
return new Duration(amount, TimeUnit.Minutes);
}
/**
* Create a Duration representing an amount of hours
*
* @param amount the amount of Hours the `Duration` will represent.
* @returns a new `Duration` representing `amount` Hours.
*/
static hours(amount) {
return new Duration(amount, TimeUnit.Hours);
}
/**
* Create a Duration representing an amount of days
*
* @param amount the amount of Days the `Duration` will represent.
* @returns a new `Duration` representing `amount` Days.
*/
static days(amount) {
return new Duration(amount, TimeUnit.Days);
}
/**
* Parse a period formatted according to the ISO 8601 standard
*
* @see https://www.iso.org/fr/standard/70907.html
* @param duration an ISO-formtted duration to be parsed.
* @returns the parsed `Duration`.
*/
static parse(duration) {
const matches = duration.match(/^PT(?:(\d+)D)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?$/);
if (!matches) {
throw new Error(`Not a valid ISO duration: ${duration}`);
}
const [, days, hours, minutes, seconds] = matches;
if (!days && !hours && !minutes && !seconds) {
throw new Error(`Not a valid ISO duration: ${duration}`);
}
return Duration.millis(_toInt(seconds) * TimeUnit.Seconds.inMillis
+ (_toInt(minutes) * TimeUnit.Minutes.inMillis)
+ (_toInt(hours) * TimeUnit.Hours.inMillis)
+ (_toInt(days) * TimeUnit.Days.inMillis));
function _toInt(str) {
if (!str) {
return 0;
}
return Number(str);
}
}
/**
* Return the total number of milliseconds in this Duration
*
* @returns the value of this `Duration` expressed in Milliseconds.
*/
toMilliseconds(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Milliseconds, opts);
}
/**
* Return the total number of seconds in this Duration
*
* @returns the value of this `Duration` expressed in Seconds.
*/
toSeconds(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Seconds, opts);
}
/**
* Return the total number of minutes in this Duration
*
* @returns the value of this `Duration` expressed in Minutes.
*/
toMinutes(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Minutes, opts);
}
/**
* Return the total number of hours in this Duration
*
* @returns the value of this `Duration` expressed in Hours.
*/
toHours(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Hours, opts);
}
/**
* Return the total number of days in this Duration
*
* @returns the value of this `Duration` expressed in Days.
*/
toDays(opts = {}) {
return convert(this.amount, this.unit, TimeUnit.Days, opts);
}
/**
* Return an ISO 8601 representation of this period
*
* @returns a string starting with 'PT' describing the period
* @see https://www.iso.org/fr/standard/70907.html
*/
toIsoString() {
if (this.amount === 0) {
return 'PT0S';
}
switch (this.unit) {
case TimeUnit.Seconds:
return `PT${this.fractionDuration('S', 60, Duration.minutes)}`;
case TimeUnit.Minutes:
return `PT${this.fractionDuration('M', 60, Duration.hours)}`;
case TimeUnit.Hours:
return `PT${this.fractionDuration('H', 24, Duration.days)}`;
case TimeUnit.Days:
return `PT${this.amount}D`;
default:
throw new Error(`Unexpected time unit: ${this.unit}`);
}
}
/**
* Return an ISO 8601 representation of this period
*
* @returns a string starting with 'PT' describing the period
* @see https://www.iso.org/fr/standard/70907.html
* @deprecated Use `toIsoString()` instead.
*/
toISOString() {
return this.toIsoString();
}
/**
* Turn this duration into a human-readable string
*/
toHumanString() {
if (this.amount === 0) {
return fmtUnit(0, this.unit);
}
if (token_1.Token.isUnresolved(this.amount)) {
return `<token> ${this.unit.label}`;
}
let millis = convert(this.amount, this.unit, TimeUnit.Milliseconds, { integral: false });
const parts = new Array();
for (const unit of [TimeUnit.Days, TimeUnit.Hours, TimeUnit.Hours, TimeUnit.Minutes, TimeUnit.Seconds]) {
const wholeCount = Math.floor(convert(millis, TimeUnit.Milliseconds, unit, { integral: false }));
if (wholeCount > 0) {
parts.push(fmtUnit(wholeCount, unit));
millis -= wholeCount * unit.inMillis;
}
}
// Remainder in millis
if (millis > 0) {
parts.push(fmtUnit(millis, TimeUnit.Milliseconds));
}
// 2 significant parts, that's totally enough for humans
return parts.slice(0, 2).join(' ');
function fmtUnit(amount, unit) {
if (amount === 1) {
// All of the labels end in 's'
return `${amount} ${unit.label.substring(0, unit.label.length - 1)}`;
}
return `${amount} ${unit.label}`;
}
}
/**
* Returns a string representation of this `Duration` that is also a Token that cannot be successfully resolved. This
* protects users against inadvertently stringifying a `Duration` object, when they should have called one of the
* `to*` methods instead.
*/
toString() {
return token_1.Token.asString(() => {
throw new Error(`Duration.toString() was used, but .toSeconds, .toMinutes or .toDays should have been called instead`);
}, { displayHint: `${this.amount} ${this.unit.label}` });
}
fractionDuration(symbol, modulus, next) {
if (this.amount < modulus) {
return `${this.amount}${symbol}`;
}
const remainder = this.amount % modulus;
const quotient = next((this.amount - remainder) / modulus).toISOString().slice(2);
return remainder > 0
? `${quotient}${remainder}${symbol}`
: quotient;
}
}
exports.Duration = Duration;
class TimeUnit {
constructor(label, inMillis) {
this.label = label;
this.inMillis = inMillis;
// MAX_SAFE_INTEGER is 2^53, so by representing our duration in millis (the lowest
// common unit) the highest duration we can represent is
// 2^53 / 86*10^6 ~= 104 * 10^6 days (about 100 million days).
}
toString() {
return this.label;
}
}
TimeUnit.Milliseconds = new TimeUnit('millis', 1);
TimeUnit.Seconds = new TimeUnit('seconds', 1000);
TimeUnit.Minutes = new TimeUnit('minutes', 60000);
TimeUnit.Hours = new TimeUnit('hours', 3600000);
TimeUnit.Days = new TimeUnit('days', 86400000);
function convert(amount, fromUnit, toUnit, { integral = true }) {
if (fromUnit.inMillis === toUnit.inMillis) {
return amount;
}
const multiplier = fromUnit.inMillis / toUnit.inMillis;
if (token_1.Token.isUnresolved(amount)) {
throw new Error(`Unable to perform time unit conversion on un-resolved token ${amount}.`);
}
const value = amount * multiplier;
if (!Number.isInteger(value) && integral) {
throw new Error(`'${amount} ${fromUnit}' cannot be converted into a whole number of ${toUnit}.`);
}
return value;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkdXJhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUFnQztBQUVoQzs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxRQUFRO0lBbUZuQixZQUFvQixNQUFjLEVBQUUsSUFBYztRQUNoRCxJQUFJLENBQUMsYUFBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQzdDLE1BQU0sSUFBSSxLQUFLLENBQUMsa0RBQWtELE1BQU0sRUFBRSxDQUFDLENBQUM7U0FDN0U7UUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztJQUNuQixDQUFDO0lBekZEOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFjO1FBQ2pDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQWM7UUFDbEMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBYztRQUNsQyxPQUFPLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFjO1FBQ2hDLE9BQU8sSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQWM7UUFDL0Is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QUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDekMsZ0JBQU8sR0FBRyxJQUFJLFFBQVEsQ0FBQyxTQUFTLEVBQUUsSUFBSyxDQUFDLENBQUM7QUFDekMsZ0JBQU8sR0FBRyxJQUFJLFFBQVEsQ0FBQyxTQUFTLEVBQUUsS0FBTSxDQUFDLENBQUM7QUFDMUMsY0FBSyxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRSxPQUFTLENBQUMsQ0FBQztBQUN6QyxhQUFJLEdBQUcsSUFBSSxRQUFRLENBQUMsTUFBTSxFQUFFLFFBQVUsQ0FBQyxDQUFDO0FBYWpFLFNBQVMsT0FBTyxDQUFDLE1BQWMsRUFBRSxRQUFrQixFQUFFLE1BQWdCLEVBQUUsRUFBRSxRQUFRLEdBQUcsSUFBSSxFQUF5QjtJQUMvRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLEtBQUssTUFBTSxDQUFDLFFBQVEsRUFBRTtRQUFFLE9BQU8sTUFBTSxDQUFDO0tBQUU7SUFDN0QsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBRXZELElBQUksYUFBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLCtEQUErRCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0tBQzNGO0lBQ0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxHQUFHLFVBQVUsQ0FBQztJQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxRQUFRLEVBQUU7UUFDeEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLE1BQU0sSUFBSSxRQUFRLGdEQUFnRCxNQUFNLEdBQUcsQ0FBQyxDQUFDO0tBQ2xHO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVG9rZW4gfSBmcm9tIFwiLi90b2tlblwiO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBsZW5ndGggb2YgdGltZS5cbiAqXG4gKiBUaGUgYW1vdW50IGNhbiBiZSBzcGVjaWZpZWQgZWl0aGVyIGFzIGEgbGl0ZXJhbCB2YWx1ZSAoZS5nOiBgMTBgKSB3aGljaFxuICogY2Fubm90IGJlIG5lZ2F0aXZlLCBvciBhcyBhbiB1bnJlc29sdmVkIG51bWJlciB0b2tlbi5cbiAqXG4gKiBXaGVuIHRoZSBhbW91bnQgaXMgcGFzc2VkIGFzIGEgdG9rZW4sIHVuaXQgY29udmVyc2lvbiBpcyBub3QgcG9zc2libGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBEdXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEdXJhdGlvbiByZXByZXNlbnRpbmcgYW4gYW1vdW50IG9mIG1pbGxpc2Vjb25kc1xuICAgKlxuICAgKiBAcGFyYW0gYW1vdW50IHRoZSBhbW91bnQgb2YgTWlsbGlzZWNvbmRzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBtcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgbWlsbGlzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIER1cmF0aW9uIHJlcHJlc2VudGluZyBhbiBhbW91bnQgb2Ygc2Vjb25kc1xuICAgKlxuICAgKiBAcGFyYW0gYW1vdW50IHRoZSBhbW91bnQgb2YgU2Vjb25kcyB0aGUgYER1cmF0aW9uYCB3aWxsIHJlcHJlc2VudC5cbiAgICogQHJldHVybnMgYSBuZXcgYER1cmF0aW9uYCByZXByZXNlbnRpbmcgYGFtb3VudGAgU2Vjb25kcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc2Vjb25kcyhhbW91bnQ6IG51bWJlcik6IER1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKGFtb3VudCwgVGltZVVuaXQuU2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gcmVwcmVzZW50aW5nIGFuIGFtb3VudCBvZiBtaW51dGVzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBNaW51dGVzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBNaW51dGVzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtaW51dGVzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5NaW51dGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEdXJhdGlvbiByZXByZXNlbnRpbmcgYW4gYW1vdW50IG9mIGhvdXJzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBIb3VycyB0aGUgYER1cmF0aW9uYCB3aWxsIHJlcHJlc2VudC5cbiAgICogQHJldHVybnMgYSBuZXcgYER1cmF0aW9uYCByZXByZXNlbnRpbmcgYGFtb3VudGAgSG91cnMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGhvdXJzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5Ib3Vycyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gcmVwcmVzZW50aW5nIGFuIGFtb3VudCBvZiBkYXlzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBEYXlzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBEYXlzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkYXlzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5EYXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBhIHBlcmlvZCBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBJU08gODYwMSBzdGFuZGFyZFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3Lmlzby5vcmcvZnIvc3RhbmRhcmQvNzA5MDcuaHRtbFxuICAgKiBAcGFyYW0gZHVyYXRpb24gYW4gSVNPLWZvcm10dGVkIGR1cmF0aW9uIHRvIGJlIHBhcnNlZC5cbiAgICogQHJldHVybnMgdGhlIHBhcnNlZCBgRHVyYXRpb25gLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwYXJzZShkdXJhdGlvbjogc3RyaW5nKTogRHVyYXRpb24ge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBkdXJhdGlvbi5tYXRjaCgvXlBUKD86KFxcZCspRCk/KD86KFxcZCspSCk/KD86KFxcZCspTSk/KD86KFxcZCspUyk/JC8pO1xuICAgIGlmICghbWF0Y2hlcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3QgYSB2YWxpZCBJU08gZHVyYXRpb246ICR7ZHVyYXRpb259YCk7XG4gICAgfVxuICAgIGNvbnN0IFssIGRheXMsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzXSA9IG1hdGNoZXM7XG4gICAgaWYgKCFkYXlzICYmICFob3VycyAmJiAhbWludXRlcyAmJiAhc2Vjb25kcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb3QgYSB2YWxpZCBJU08gZHVyYXRpb246ICR7ZHVyYXRpb259YCk7XG4gICAgfVxuICAgIHJldHVybiBEdXJhdGlvbi5taWxsaXMoXG4gICAgICBfdG9JbnQoc2Vjb25kcykgKiBUaW1lVW5pdC5TZWNvbmRzLmluTWlsbGlzXG4gICAgICArIChfdG9JbnQobWludXRlcykgKiBUaW1lVW5pdC5NaW51dGVzLmluTWlsbGlzKVxuICAgICAgKyAoX3RvSW50KGhvdXJzKSAqIFRpbWVVbml0LkhvdXJzLmluTWlsbGlzKVxuICAgICAgKyAoX3RvSW50KGRheXMpICogVGltZVVuaXQuRGF5cy5pbk1pbGxpcylcbiAgICApO1xuXG4gICAgZnVuY3Rpb24gX3RvSW50KHN0cjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgIGlmICghc3RyKSB7IHJldHVybiAwOyB9XG4gICAgICByZXR1cm4gTnVtYmVyKHN0cik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhbW91bnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSB1bml0OiBUaW1lVW5pdDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGFtb3VudDogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCkge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGFtb3VudCkgJiYgYW1vdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXJhdGlvbiBhbW91bnRzIGNhbm5vdCBiZSBuZWdhdGl2ZS4gUmVjZWl2ZWQ6ICR7YW1vdW50fWApO1xuICAgIH1cblxuICAgIHRoaXMuYW1vdW50ID0gYW1vdW50O1xuICAgIHRoaXMudW5pdCA9IHVuaXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSB0b3RhbCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGluIHRoaXMgRHVyYXRpb25cbiAgICpcbiAgICogQHJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYER1cmF0aW9uYCBleHByZXNzZWQgaW4gTWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIHRvTWlsbGlzZWNvbmRzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaWxsaXNlY29uZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgdG90YWwgbnVtYmVyIG9mIHNlY29uZHMgaW4gdGhpcyBEdXJhdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpcyBgRHVyYXRpb25gIGV4cHJlc3NlZCBpbiBTZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIHRvU2Vjb25kcyhvcHRzOiBUaW1lQ29udmVyc2lvbk9wdGlvbnMgPSB7fSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNvbnZlcnQodGhpcy5hbW91bnQsIHRoaXMudW5pdCwgVGltZVVuaXQuU2Vjb25kcywgb3B0cyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSB0b3RhbCBudW1iZXIgb2YgbWludXRlcyBpbiB0aGlzIER1cmF0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGBEdXJhdGlvbmAgZXhwcmVzc2VkIGluIE1pbnV0ZXMuXG4gICAqL1xuICBwdWJsaWMgdG9NaW51dGVzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaW51dGVzLCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBob3VycyBpbiB0aGlzIER1cmF0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGBEdXJhdGlvbmAgZXhwcmVzc2VkIGluIEhvdXJzLlxuICAgKi9cbiAgcHVibGljIHRvSG91cnMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0LkhvdXJzLCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBkYXlzIGluIHRoaXMgRHVyYXRpb25cbiAgICpcbiAgICogQHJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYER1cmF0aW9uYCBleHByZXNzZWQgaW4gRGF5cy5cbiAgICovXG4gIHB1YmxpYyB0b0RheXMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0LkRheXMsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBJU08gODYwMSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHBlcmlvZFxuICAgKlxuICAgKiBAcmV0dXJucyBhIHN0cmluZyBzdGFydGluZyB3aXRoICdQVCcgZGVzY3JpYmluZyB0aGUgcGVyaW9kXG4gICAqIEBzZWUgaHR0cHM6Ly93d3cuaXNvLm9yZy9mci9zdGFuZGFyZC83MDkwNy5odG1sXG4gICAqL1xuICBwdWJsaWMgdG9Jc29TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hbW91bnQgPT09IDApIHsgcmV0dXJuICdQVDBTJzsgfVxuICAgIHN3aXRjaCAodGhpcy51bml0KSB7XG4gICAgICBjYXNlIFRpbWVVbml0LlNlY29uZHM6XG4gICAgICAgIHJldHVybiBgUFQke3RoaXMuZnJhY3Rpb25EdXJhdGlvbignUycsIDYwLCBEdXJhdGlvbi5taW51dGVzKX1gO1xuICAgICAgY2FzZSBUaW1lVW5pdC5NaW51dGVzOlxuICAgICAgICByZXR1cm4gYFBUJHt0aGlzLmZyYWN0aW9uRHVyYXRpb24oJ00nLCA2MCwgRHVyYXRpb24uaG91cnMpfWA7XG4gICAgICBjYXNlIFRpbWVVbml0LkhvdXJzOlxuICAgICAgICByZXR1cm4gYFBUJHt0aGlzLmZyYWN0aW9uRHVyYXRpb24oJ0gnLCAyNCwgRHVyYXRpb24uZGF5cyl9YDtcbiAgICAgIGNhc2UgVGltZVVuaXQuRGF5czpcbiAgICAgICAgcmV0dXJuIGBQVCR7dGhpcy5hbW91bnR9RGA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgdGltZSB1bml0OiAke3RoaXMudW5pdH1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGFuIElTTyA4NjAxIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgcGVyaW9kXG4gICAqXG4gICAqIEByZXR1cm5zIGEgc3RyaW5nIHN0YXJ0aW5nIHdpdGggJ1BUJyBkZXNjcmliaW5nIHRoZSBwZXJpb2RcbiAgICogQHNlZSBodHRwczovL3d3dy5pc28ub3JnL2ZyL3N0YW5kYXJkLzcwOTA3Lmh0bWxcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGB0b0lzb1N0cmluZygpYCBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIHRvSVNPU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudG9Jc29TdHJpbmcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUdXJuIHRoaXMgZHVyYXRpb24gaW50byBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIHRvSHVtYW5TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hbW91bnQgPT09IDApIHsgcmV0dXJuIGZtdFVuaXQoMCwgdGhpcy51bml0KTsgfVxuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQodGhpcy5hbW91bnQpKSB7IHJldHVybiBgPHRva2VuPiAke3RoaXMudW5pdC5sYWJlbH1gOyB9XG5cbiAgICBsZXQgbWlsbGlzID0gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaWxsaXNlY29uZHMsIHsgaW50ZWdyYWw6IGZhbHNlIH0pO1xuICAgIGNvbnN0IHBhcnRzID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICAgIGZvciAoY29uc3QgdW5pdCBvZiBbVGltZVVuaXQuRGF5cywgVGltZVVuaXQuSG91cnMsIFRpbWVVbml0LkhvdXJzLCBUaW1lVW5pdC5NaW51dGVzLCBUaW1lVW5pdC5TZWNvbmRzXSkge1xuICAgICAgY29uc3Qgd2hvbGVDb3VudCA9IE1hdGguZmxvb3IoY29udmVydChtaWxsaXMsIFRpbWVVbml0Lk1pbGxpc2Vjb25kcywgdW5pdCwgeyBpbnRlZ3JhbDogZmFsc2UgfSkpO1xuICAgICAgaWYgKHdob2xlQ291bnQgPiAwKSB7XG4gICAgICAgIHBhcnRzLnB1c2goZm10VW5pdCh3aG9sZUNvdW50LCB1bml0KSk7XG4gICAgICAgIG1pbGxpcyAtPSB3aG9sZUNvdW50ICogdW5pdC5pbk1pbGxpcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1haW5kZXIgaW4gbWlsbGlzXG4gICAgaWYgKG1pbGxpcyA+IDApIHtcbiAgICAgIHBhcnRzLnB1c2goZm10VW5pdChtaWxsaXMsIFRpbWVVbml0Lk1pbGxpc2Vjb25kcykpO1xuICAgIH1cblxuICAgIC8vIDIgc2lnbmlmaWNhbnQgcGFydHMsIHRoYXQncyB0b3RhbGx5IGVub3VnaCBmb3IgaHVtYW5zXG4gICAgcmV0dXJuIHBhcnRzLnNsaWNlKDAsIDIpLmpvaW4oJyAnKTtcblxuICAgIGZ1bmN0aW9uIGZtdFVuaXQoYW1vdW50OiBudW1iZXIsIHVuaXQ6IFRpbWVVbml0KSB7XG4gICAgICBpZiAoYW1vdW50ID09PSAxKSB7XG4gICAgICAgIC8vIEFsbCBvZiB0aGUgbGFiZWxzIGVuZCBpbiAncydcbiAgICAgICAgcmV0dXJuIGAke2Ftb3VudH0gJHt1bml0LmxhYmVsLnN1YnN0cmluZygwLCB1bml0LmxhYmVsLmxlbmd0aCAtIDEpfWA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCR7YW1vdW50fSAke3VuaXQubGFiZWx9YDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGBEdXJhdGlvbmAgdGhhdCBpcyBhbHNvIGEgVG9rZW4gdGhhdCBjYW5ub3QgYmUgc3VjY2Vzc2Z1bGx5IHJlc29sdmVkLiBUaGlzXG4gICAqIHByb3RlY3RzIHVzZXJzIGFnYWluc3QgaW5hZHZlcnRlbnRseSBzdHJpbmdpZnlpbmcgYSBgRHVyYXRpb25gIG9iamVjdCwgd2hlbiB0aGV5IHNob3VsZCBoYXZlIGNhbGxlZCBvbmUgb2YgdGhlXG4gICAqIGB0bypgIG1ldGhvZHMgaW5zdGVhZC5cbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBUb2tlbi5hc1N0cmluZyhcbiAgICAgICgpID0+IHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXJhdGlvbi50b1N0cmluZygpIHdhcyB1c2VkLCBidXQgLnRvU2Vjb25kcywgLnRvTWludXRlcyBvciAudG9EYXlzIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGluc3RlYWRgKTtcbiAgICAgIH0sXG4gICAgICB7IGRpc3BsYXlIaW50OiBgJHt0aGlzLmFtb3VudH0gJHt0aGlzLnVuaXQubGFiZWx9YCB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZnJhY3Rpb25EdXJhdGlvbihzeW1ib2w6IHN0cmluZywgbW9kdWx1czogbnVtYmVyLCBuZXh0OiAoYW1vdW50OiBudW1iZXIpID0+IER1cmF0aW9uKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hbW91bnQgPCBtb2R1bHVzKSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy5hbW91bnR9JHtzeW1ib2x9YDtcbiAgICB9XG4gICAgY29uc3QgcmVtYWluZGVyID0gdGhpcy5hbW91bnQgJSBtb2R1bHVzO1xuICAgIGNvbnN0IHF1b3RpZW50ID0gbmV4dCgodGhpcy5hbW91bnQgLSByZW1haW5kZXIpIC8gbW9kdWx1cykudG9JU09TdHJpbmcoKS5zbGljZSgyKTtcbiAgICByZXR1cm4gcmVtYWluZGVyID4gMFxuICAgICAgPyBgJHtxdW90aWVudH0ke3JlbWFpbmRlcn0ke3N5bWJvbH1gXG4gICAgICA6IHF1b3RpZW50O1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgaG93IHRvIGNvbnZlcnQgdGltZSB0byBhIGRpZmZlcmVudCB1bml0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVDb252ZXJzaW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIGNvbnZlcnNpb25zIGludG8gYSBsYXJnZXIgdGltZSB1bml0IChlLmcuIGBTZWNvbmRzYCB0byBgTWludHVlc2ApIHdpbGwgZmFpbCBpZiB0aGUgcmVzdWx0IGlzIG5vdCBhblxuICAgKiBpbnRlZ2VyLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBpbnRlZ3JhbD86IGJvb2xlYW47XG59XG5cbmNsYXNzIFRpbWVVbml0IHtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBNaWxsaXNlY29uZHMgPSBuZXcgVGltZVVuaXQoJ21pbGxpcycsIDEpO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNlY29uZHMgPSBuZXcgVGltZVVuaXQoJ3NlY29uZHMnLCAxXzAwMCk7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTWludXRlcyA9IG5ldyBUaW1lVW5pdCgnbWludXRlcycsIDYwXzAwMCk7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSG91cnMgPSBuZXcgVGltZVVuaXQoJ2hvdXJzJywgM182MDBfMDAwKTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBEYXlzID0gbmV3IFRpbWVVbml0KCdkYXlzJywgODZfNDAwXzAwMCk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgbGFiZWw6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGluTWlsbGlzOiBudW1iZXIpIHtcbiAgICAvLyBNQVhfU0FGRV9JTlRFR0VSIGlzIDJeNTMsIHNvIGJ5IHJlcHJlc2VudGluZyBvdXIgZHVyYXRpb24gaW4gbWlsbGlzICh0aGUgbG93ZXN0XG4gICAgLy8gY29tbW9uIHVuaXQpIHRoZSBoaWdoZXN0IGR1cmF0aW9uIHdlIGNhbiByZXByZXNlbnQgaXNcbiAgICAvLyAyXjUzIC8gODYqMTBeNiB+PSAxMDQgKiAxMF42IGRheXMgKGFib3V0IDEwMCBtaWxsaW9uIGRheXMpLlxuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmxhYmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnQoYW1vdW50OiBudW1iZXIsIGZyb21Vbml0OiBUaW1lVW5pdCwgdG9Vbml0OiBUaW1lVW5pdCwgeyBpbnRlZ3JhbCA9IHRydWUgfTogVGltZUNvbnZlcnNpb25PcHRpb25zKSB7XG4gIGlmIChmcm9tVW5pdC5pbk1pbGxpcyA9PT0gdG9Vbml0LmluTWlsbGlzKSB7IHJldHVybiBhbW91bnQ7IH1cbiAgY29uc3QgbXVsdGlwbGllciA9IGZyb21Vbml0LmluTWlsbGlzIC8gdG9Vbml0LmluTWlsbGlzO1xuXG4gIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoYW1vdW50KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHBlcmZvcm0gdGltZSB1bml0IGNvbnZlcnNpb24gb24gdW4tcmVzb2x2ZWQgdG9rZW4gJHthbW91bnR9LmApO1xuICB9XG4gIGNvbnN0IHZhbHVlID0gYW1vdW50ICogbXVsdGlwbGllcjtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSAmJiBpbnRlZ3JhbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJyR7YW1vdW50fSAke2Zyb21Vbml0fScgY2Fubm90IGJlIGNvbnZlcnRlZCBpbnRvIGEgd2hvbGUgbnVtYmVyIG9mICR7dG9Vbml0fS5gKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG4iXX0=