1 | ;
|
2 | var _a;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.Duration = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const token_1 = require("./token");
|
8 | /**
|
9 | * Represents a length of time.
|
10 | *
|
11 | * The amount can be specified either as a literal value (e.g: `10`) which
|
12 | * cannot be negative, or as an unresolved number token.
|
13 | *
|
14 | * When the amount is passed as a token, unit conversion is not possible.
|
15 | */
|
16 | class Duration {
|
17 | constructor(amount, unit) {
|
18 | if (!token_1.Token.isUnresolved(amount) && amount < 0) {
|
19 | throw new Error(`Duration amounts cannot be negative. Received: ${amount}`);
|
20 | }
|
21 | this.amount = amount;
|
22 | this.unit = unit;
|
23 | }
|
24 | /**
|
25 | * Create a Duration representing an amount of milliseconds
|
26 | *
|
27 | * @param amount the amount of Milliseconds the `Duration` will represent.
|
28 | * @returns a new `Duration` representing `amount` ms.
|
29 | */
|
30 | static millis(amount) {
|
31 | return new Duration(amount, TimeUnit.Milliseconds);
|
32 | }
|
33 | /**
|
34 | * Create a Duration representing an amount of seconds
|
35 | *
|
36 | * @param amount the amount of Seconds the `Duration` will represent.
|
37 | * @returns a new `Duration` representing `amount` Seconds.
|
38 | */
|
39 | static seconds(amount) {
|
40 | return new Duration(amount, TimeUnit.Seconds);
|
41 | }
|
42 | /**
|
43 | * Create a Duration representing an amount of minutes
|
44 | *
|
45 | * @param amount the amount of Minutes the `Duration` will represent.
|
46 | * @returns a new `Duration` representing `amount` Minutes.
|
47 | */
|
48 | static minutes(amount) {
|
49 | return new Duration(amount, TimeUnit.Minutes);
|
50 | }
|
51 | /**
|
52 | * Create a Duration representing an amount of hours
|
53 | *
|
54 | * @param amount the amount of Hours the `Duration` will represent.
|
55 | * @returns a new `Duration` representing `amount` Hours.
|
56 | */
|
57 | static hours(amount) {
|
58 | return new Duration(amount, TimeUnit.Hours);
|
59 | }
|
60 | /**
|
61 | * Create a Duration representing an amount of days
|
62 | *
|
63 | * @param amount the amount of Days the `Duration` will represent.
|
64 | * @returns a new `Duration` representing `amount` Days.
|
65 | */
|
66 | static days(amount) {
|
67 | return new Duration(amount, TimeUnit.Days);
|
68 | }
|
69 | /**
|
70 | * Parse a period formatted according to the ISO 8601 standard
|
71 | *
|
72 | * @see https://www.iso.org/fr/standard/70907.html
|
73 | * @param duration an ISO-formtted duration to be parsed.
|
74 | * @returns the parsed `Duration`.
|
75 | */
|
76 | static parse(duration) {
|
77 | const matches = duration.match(/^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/);
|
78 | if (!matches) {
|
79 | throw new Error(`Not a valid ISO duration: ${duration}`);
|
80 | }
|
81 | const [, days, hours, minutes, seconds] = matches;
|
82 | if (!days && !hours && !minutes && !seconds) {
|
83 | throw new Error(`Not a valid ISO duration: ${duration}`);
|
84 | }
|
85 | return Duration.millis(_toInt(seconds) * TimeUnit.Seconds.inMillis
|
86 | + (_toInt(minutes) * TimeUnit.Minutes.inMillis)
|
87 | + (_toInt(hours) * TimeUnit.Hours.inMillis)
|
88 | + (_toInt(days) * TimeUnit.Days.inMillis));
|
89 | function _toInt(str) {
|
90 | if (!str) {
|
91 | return 0;
|
92 | }
|
93 | return Number(str);
|
94 | }
|
95 | }
|
96 | /**
|
97 | * Add two Durations together
|
98 | */
|
99 | plus(rhs) {
|
100 | try {
|
101 | jsiiDeprecationWarnings._aws_cdk_core_Duration(rhs);
|
102 | }
|
103 | catch (error) {
|
104 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
105 | Error.captureStackTrace(error, this.plus);
|
106 | }
|
107 | throw error;
|
108 | }
|
109 | const targetUnit = finestUnit(this.unit, rhs.unit);
|
110 | const res = convert(this.amount, this.unit, targetUnit, {}) + convert(rhs.amount, rhs.unit, targetUnit, {});
|
111 | return new Duration(res, targetUnit);
|
112 | }
|
113 | /**
|
114 | * Substract two Durations together
|
115 | */
|
116 | minus(rhs) {
|
117 | try {
|
118 | jsiiDeprecationWarnings._aws_cdk_core_Duration(rhs);
|
119 | }
|
120 | catch (error) {
|
121 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
122 | Error.captureStackTrace(error, this.minus);
|
123 | }
|
124 | throw error;
|
125 | }
|
126 | const targetUnit = finestUnit(this.unit, rhs.unit);
|
127 | const res = convert(this.amount, this.unit, targetUnit, {}) - convert(rhs.amount, rhs.unit, targetUnit, {});
|
128 | return new Duration(res, targetUnit);
|
129 | }
|
130 | /**
|
131 | * Return the total number of milliseconds in this Duration
|
132 | *
|
133 | * @returns the value of this `Duration` expressed in Milliseconds.
|
134 | */
|
135 | toMilliseconds(opts = {}) {
|
136 | try {
|
137 | jsiiDeprecationWarnings._aws_cdk_core_TimeConversionOptions(opts);
|
138 | }
|
139 | catch (error) {
|
140 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
141 | Error.captureStackTrace(error, this.toMilliseconds);
|
142 | }
|
143 | throw error;
|
144 | }
|
145 | return convert(this.amount, this.unit, TimeUnit.Milliseconds, opts);
|
146 | }
|
147 | /**
|
148 | * Return the total number of seconds in this Duration
|
149 | *
|
150 | * @returns the value of this `Duration` expressed in Seconds.
|
151 | */
|
152 | toSeconds(opts = {}) {
|
153 | try {
|
154 | jsiiDeprecationWarnings._aws_cdk_core_TimeConversionOptions(opts);
|
155 | }
|
156 | catch (error) {
|
157 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
158 | Error.captureStackTrace(error, this.toSeconds);
|
159 | }
|
160 | throw error;
|
161 | }
|
162 | return convert(this.amount, this.unit, TimeUnit.Seconds, opts);
|
163 | }
|
164 | /**
|
165 | * Return the total number of minutes in this Duration
|
166 | *
|
167 | * @returns the value of this `Duration` expressed in Minutes.
|
168 | */
|
169 | toMinutes(opts = {}) {
|
170 | try {
|
171 | jsiiDeprecationWarnings._aws_cdk_core_TimeConversionOptions(opts);
|
172 | }
|
173 | catch (error) {
|
174 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
175 | Error.captureStackTrace(error, this.toMinutes);
|
176 | }
|
177 | throw error;
|
178 | }
|
179 | return convert(this.amount, this.unit, TimeUnit.Minutes, opts);
|
180 | }
|
181 | /**
|
182 | * Return the total number of hours in this Duration
|
183 | *
|
184 | * @returns the value of this `Duration` expressed in Hours.
|
185 | */
|
186 | toHours(opts = {}) {
|
187 | try {
|
188 | jsiiDeprecationWarnings._aws_cdk_core_TimeConversionOptions(opts);
|
189 | }
|
190 | catch (error) {
|
191 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
192 | Error.captureStackTrace(error, this.toHours);
|
193 | }
|
194 | throw error;
|
195 | }
|
196 | return convert(this.amount, this.unit, TimeUnit.Hours, opts);
|
197 | }
|
198 | /**
|
199 | * Return the total number of days in this Duration
|
200 | *
|
201 | * @returns the value of this `Duration` expressed in Days.
|
202 | */
|
203 | toDays(opts = {}) {
|
204 | try {
|
205 | jsiiDeprecationWarnings._aws_cdk_core_TimeConversionOptions(opts);
|
206 | }
|
207 | catch (error) {
|
208 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
209 | Error.captureStackTrace(error, this.toDays);
|
210 | }
|
211 | throw error;
|
212 | }
|
213 | return convert(this.amount, this.unit, TimeUnit.Days, opts);
|
214 | }
|
215 | /**
|
216 | * Return an ISO 8601 representation of this period
|
217 | *
|
218 | * @returns a string starting with 'P' describing the period
|
219 | * @see https://www.iso.org/fr/standard/70907.html
|
220 | */
|
221 | toIsoString() {
|
222 | if (this.amount === 0) {
|
223 | return 'PT0S';
|
224 | }
|
225 | const ret = ['P'];
|
226 | let tee = false;
|
227 | for (const [amount, unit] of this.components(true)) {
|
228 | if ([TimeUnit.Seconds, TimeUnit.Minutes, TimeUnit.Hours].includes(unit) && !tee) {
|
229 | ret.push('T');
|
230 | tee = true;
|
231 | }
|
232 | ret.push(`${amount}${unit.isoLabel}`);
|
233 | }
|
234 | return ret.join('');
|
235 | }
|
236 | /**
|
237 | * Return an ISO 8601 representation of this period
|
238 | *
|
239 | * @returns a string starting with 'P' describing the period
|
240 | * @see https://www.iso.org/fr/standard/70907.html
|
241 | * @deprecated Use `toIsoString()` instead.
|
242 | */
|
243 | toISOString() {
|
244 | try {
|
245 | jsiiDeprecationWarnings.print("@aws-cdk/core.Duration#toISOString", "Use `toIsoString()` instead.");
|
246 | }
|
247 | catch (error) {
|
248 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
249 | Error.captureStackTrace(error, this.toISOString);
|
250 | }
|
251 | throw error;
|
252 | }
|
253 | return this.toIsoString();
|
254 | }
|
255 | /**
|
256 | * Turn this duration into a human-readable string
|
257 | */
|
258 | toHumanString() {
|
259 | if (this.amount === 0) {
|
260 | return fmtUnit(0, this.unit);
|
261 | }
|
262 | if (token_1.Token.isUnresolved(this.amount)) {
|
263 | return `<token> ${this.unit.label}`;
|
264 | }
|
265 | return this.components(false)
|
266 | // 2 significant parts, that's totally enough for humans
|
267 | .slice(0, 2)
|
268 | .map(([amount, unit]) => fmtUnit(amount, unit))
|
269 | .join(' ');
|
270 | function fmtUnit(amount, unit) {
|
271 | if (amount === 1) {
|
272 | // All of the labels end in 's'
|
273 | return `${amount} ${unit.label.substring(0, unit.label.length - 1)}`;
|
274 | }
|
275 | return `${amount} ${unit.label}`;
|
276 | }
|
277 | }
|
278 | /**
|
279 | * Returns a string representation of this `Duration`
|
280 | *
|
281 | * This is is never the right function to use when you want to use the `Duration`
|
282 | * object in a template. Use `toSeconds()`, `toMinutes()`, `toDays()`, etc. instead.
|
283 | */
|
284 | toString() {
|
285 | return `Duration.${this.unit.label}(${this.amount})`;
|
286 | }
|
287 | /**
|
288 | * Return the duration in a set of whole numbered time components, ordered from largest to smallest
|
289 | *
|
290 | * Only components != 0 will be returned.
|
291 | *
|
292 | * Can combine millis and seconds together for the benefit of toIsoString,
|
293 | * makes the logic in there simpler.
|
294 | */
|
295 | components(combineMillisWithSeconds) {
|
296 | const ret = new Array();
|
297 | let millis = convert(this.amount, this.unit, TimeUnit.Milliseconds, { integral: false });
|
298 | for (const unit of [TimeUnit.Days, TimeUnit.Hours, TimeUnit.Minutes, TimeUnit.Seconds]) {
|
299 | const count = convert(millis, TimeUnit.Milliseconds, unit, { integral: false });
|
300 | // Round down to a whole number UNLESS we're combining millis and seconds and we got to the seconds
|
301 | const wholeCount = unit === TimeUnit.Seconds && combineMillisWithSeconds ? count : Math.floor(count);
|
302 | if (wholeCount > 0) {
|
303 | ret.push([wholeCount, unit]);
|
304 | millis -= wholeCount * unit.inMillis;
|
305 | }
|
306 | }
|
307 | // Remainder in millis
|
308 | if (millis > 0) {
|
309 | ret.push([millis, TimeUnit.Milliseconds]);
|
310 | }
|
311 | return ret;
|
312 | }
|
313 | /**
|
314 | * Checks if duration is a token or a resolvable object
|
315 | */
|
316 | isUnresolved() {
|
317 | return token_1.Token.isUnresolved(this.amount);
|
318 | }
|
319 | /**
|
320 | * Returns unit of the duration
|
321 | */
|
322 | unitLabel() {
|
323 | return this.unit.label;
|
324 | }
|
325 | /**
|
326 | * Returns stringified number of duration
|
327 | */
|
328 | formatTokenToNumber() {
|
329 | const number = token_1.Tokenization.stringifyNumber(this.amount);
|
330 | return `${number} ${this.unit.label}`;
|
331 | }
|
332 | }
|
333 | exports.Duration = Duration;
|
334 | _a = JSII_RTTI_SYMBOL_1;
|
335 | Duration[_a] = { fqn: "@aws-cdk/core.Duration", version: "1.204.0" };
|
336 | class TimeUnit {
|
337 | constructor(label, isoLabel, inMillis) {
|
338 | this.label = label;
|
339 | this.isoLabel = isoLabel;
|
340 | this.inMillis = inMillis;
|
341 | }
|
342 | toString() {
|
343 | return this.label;
|
344 | }
|
345 | }
|
346 | TimeUnit.Milliseconds = new TimeUnit('millis', '', 1);
|
347 | TimeUnit.Seconds = new TimeUnit('seconds', 'S', 1000);
|
348 | TimeUnit.Minutes = new TimeUnit('minutes', 'M', 60000);
|
349 | TimeUnit.Hours = new TimeUnit('hours', 'H', 3600000);
|
350 | TimeUnit.Days = new TimeUnit('days', 'D', 86400000);
|
351 | function convert(amount, fromUnit, toUnit, { integral = true }) {
|
352 | if (fromUnit.inMillis === toUnit.inMillis) {
|
353 | return amount;
|
354 | }
|
355 | if (token_1.Token.isUnresolved(amount)) {
|
356 | throw new Error(`Duration must be specified as 'Duration.${toUnit}()' here since its value comes from a token and cannot be converted (got Duration.${fromUnit})`);
|
357 | }
|
358 | const value = (amount * fromUnit.inMillis) / toUnit.inMillis;
|
359 | if (!Number.isInteger(value) && integral) {
|
360 | throw new Error(`'${amount} ${fromUnit}' cannot be converted into a whole number of ${toUnit}.`);
|
361 | }
|
362 | return value;
|
363 | }
|
364 | /**
|
365 | * Return the time unit with highest granularity
|
366 | */
|
367 | function finestUnit(a, b) {
|
368 | return a.inMillis < b.inMillis ? a : b;
|
369 | }
|
370 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHVyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkdXJhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxtQ0FBOEM7QUFFOUM7Ozs7Ozs7R0FPRztBQUNILE1BQWEsUUFBUTtJQW1GbkIsWUFBb0IsTUFBYyxFQUFFLElBQWM7UUFDaEQsSUFBSSxDQUFDLGFBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM3QyxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxNQUFNLEVBQUUsQ0FBQyxDQUFDO1NBQzdFO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7S0FDbEI7SUF6RkQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQWM7UUFDakMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO0tBQ3BEO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQWM7UUFDbEMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQy9DO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQWM7UUFDbEMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQy9DO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQWM7UUFDaEMsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQzdDO0lBRUQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQWM7UUFDL0IsT0FBTyxJQUFJLFFBQVEsQ0FBQyxN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QUFHLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsUUFBVSxDQUFDLENBQUM7QUFhdEUsU0FBUyxPQUFPLENBQUMsTUFBYyxFQUFFLFFBQWtCLEVBQUUsTUFBZ0IsRUFBRSxFQUFFLFFBQVEsR0FBRyxJQUFJLEVBQXlCO0lBQy9HLElBQUksUUFBUSxDQUFDLFFBQVEsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFO1FBQUUsT0FBTyxNQUFNLENBQUM7S0FBRTtJQUU3RCxJQUFJLGFBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsTUFBTSxxRkFBcUYsUUFBUSxHQUFHLENBQUMsQ0FBQztLQUNwSztJQUNELE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO0lBQzdELElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsRUFBRTtRQUN4QyxNQUFNLElBQUksS0FBSyxDQUFDLElBQUksTUFBTSxJQUFJLFFBQVEsZ0RBQWdELE1BQU0sR0FBRyxDQUFDLENBQUM7S0FDbEc7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsVUFBVSxDQUFDLENBQVcsRUFBRSxDQUFXO0lBQzFDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVG9rZW4sIFRva2VuaXphdGlvbiB9IGZyb20gJy4vdG9rZW4nO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBsZW5ndGggb2YgdGltZS5cbiAqXG4gKiBUaGUgYW1vdW50IGNhbiBiZSBzcGVjaWZpZWQgZWl0aGVyIGFzIGEgbGl0ZXJhbCB2YWx1ZSAoZS5nOiBgMTBgKSB3aGljaFxuICogY2Fubm90IGJlIG5lZ2F0aXZlLCBvciBhcyBhbiB1bnJlc29sdmVkIG51bWJlciB0b2tlbi5cbiAqXG4gKiBXaGVuIHRoZSBhbW91bnQgaXMgcGFzc2VkIGFzIGEgdG9rZW4sIHVuaXQgY29udmVyc2lvbiBpcyBub3QgcG9zc2libGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBEdXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEdXJhdGlvbiByZXByZXNlbnRpbmcgYW4gYW1vdW50IG9mIG1pbGxpc2Vjb25kc1xuICAgKlxuICAgKiBAcGFyYW0gYW1vdW50IHRoZSBhbW91bnQgb2YgTWlsbGlzZWNvbmRzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBtcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgbWlsbGlzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5NaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIER1cmF0aW9uIHJlcHJlc2VudGluZyBhbiBhbW91bnQgb2Ygc2Vjb25kc1xuICAgKlxuICAgKiBAcGFyYW0gYW1vdW50IHRoZSBhbW91bnQgb2YgU2Vjb25kcyB0aGUgYER1cmF0aW9uYCB3aWxsIHJlcHJlc2VudC5cbiAgICogQHJldHVybnMgYSBuZXcgYER1cmF0aW9uYCByZXByZXNlbnRpbmcgYGFtb3VudGAgU2Vjb25kcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc2Vjb25kcyhhbW91bnQ6IG51bWJlcik6IER1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKGFtb3VudCwgVGltZVVuaXQuU2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gcmVwcmVzZW50aW5nIGFuIGFtb3VudCBvZiBtaW51dGVzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBNaW51dGVzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBNaW51dGVzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtaW51dGVzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5NaW51dGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBEdXJhdGlvbiByZXByZXNlbnRpbmcgYW4gYW1vdW50IG9mIGhvdXJzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBIb3VycyB0aGUgYER1cmF0aW9uYCB3aWxsIHJlcHJlc2VudC5cbiAgICogQHJldHVybnMgYSBuZXcgYER1cmF0aW9uYCByZXByZXNlbnRpbmcgYGFtb3VudGAgSG91cnMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGhvdXJzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5Ib3Vycyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgRHVyYXRpb24gcmVwcmVzZW50aW5nIGFuIGFtb3VudCBvZiBkYXlzXG4gICAqXG4gICAqIEBwYXJhbSBhbW91bnQgdGhlIGFtb3VudCBvZiBEYXlzIHRoZSBgRHVyYXRpb25gIHdpbGwgcmVwcmVzZW50LlxuICAgKiBAcmV0dXJucyBhIG5ldyBgRHVyYXRpb25gIHJlcHJlc2VudGluZyBgYW1vdW50YCBEYXlzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkYXlzKGFtb3VudDogbnVtYmVyKTogRHVyYXRpb24ge1xuICAgIHJldHVybiBuZXcgRHVyYXRpb24oYW1vdW50LCBUaW1lVW5pdC5EYXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBhIHBlcmlvZCBmb3JtYXR0ZWQgYWNjb3JkaW5nIHRvIHRoZSBJU08gODYwMSBzdGFuZGFyZFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vd3d3Lmlzby5vcmcvZnIvc3RhbmRhcmQvNzA5MDcuaHRtbFxuICAgKiBAcGFyYW0gZHVyYXRpb24gYW4gSVNPLWZvcm10dGVkIGR1cmF0aW9uIHRvIGJlIHBhcnNlZC5cbiAgICogQHJldHVybnMgdGhlIHBhcnNlZCBgRHVyYXRpb25gLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwYXJzZShkdXJhdGlvbjogc3RyaW5nKTogRHVyYXRpb24ge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBkdXJhdGlvbi5tYXRjaCgvXlAoPzooXFxkKylEKT8oPzpUKD86KFxcZCspSCk/KD86KFxcZCspTSk/KD86KFxcZCspUyk/KT8kLyk7XG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIHZhbGlkIElTTyBkdXJhdGlvbjogJHtkdXJhdGlvbn1gKTtcbiAgICB9XG4gICAgY29uc3QgWywgZGF5cywgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHNdID0gbWF0Y2hlcztcbiAgICBpZiAoIWRheXMgJiYgIWhvdXJzICYmICFtaW51dGVzICYmICFzZWNvbmRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIHZhbGlkIElTTyBkdXJhdGlvbjogJHtkdXJhdGlvbn1gKTtcbiAgICB9XG4gICAgcmV0dXJuIER1cmF0aW9uLm1pbGxpcyhcbiAgICAgIF90b0ludChzZWNvbmRzKSAqIFRpbWVVbml0LlNlY29uZHMuaW5NaWxsaXNcbiAgICAgICsgKF90b0ludChtaW51dGVzKSAqIFRpbWVVbml0Lk1pbnV0ZXMuaW5NaWxsaXMpXG4gICAgICArIChfdG9JbnQoaG91cnMpICogVGltZVVuaXQuSG91cnMuaW5NaWxsaXMpXG4gICAgICArIChfdG9JbnQoZGF5cykgKiBUaW1lVW5pdC5EYXlzLmluTWlsbGlzKSxcbiAgICApO1xuXG4gICAgZnVuY3Rpb24gX3RvSW50KHN0cjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAgIGlmICghc3RyKSB7IHJldHVybiAwOyB9XG4gICAgICByZXR1cm4gTnVtYmVyKHN0cik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhbW91bnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSB1bml0OiBUaW1lVW5pdDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKGFtb3VudDogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCkge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKGFtb3VudCkgJiYgYW1vdW50IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBEdXJhdGlvbiBhbW91bnRzIGNhbm5vdCBiZSBuZWdhdGl2ZS4gUmVjZWl2ZWQ6ICR7YW1vdW50fWApO1xuICAgIH1cblxuICAgIHRoaXMuYW1vdW50ID0gYW1vdW50O1xuICAgIHRoaXMudW5pdCA9IHVuaXQ7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHR3byBEdXJhdGlvbnMgdG9nZXRoZXJcbiAgICovXG4gIHB1YmxpYyBwbHVzKHJoczogRHVyYXRpb24pOiBEdXJhdGlvbiB7XG4gICAgY29uc3QgdGFyZ2V0VW5pdCA9IGZpbmVzdFVuaXQodGhpcy51bml0LCByaHMudW5pdCk7XG4gICAgY29uc3QgcmVzID0gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCB0YXJnZXRVbml0LCB7fSkgKyBjb252ZXJ0KHJocy5hbW91bnQsIHJocy51bml0LCB0YXJnZXRVbml0LCB7fSk7XG4gICAgcmV0dXJuIG5ldyBEdXJhdGlvbihyZXMsIHRhcmdldFVuaXQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnN0cmFjdCB0d28gRHVyYXRpb25zIHRvZ2V0aGVyXG4gICAqL1xuICBwdWJsaWMgbWludXMocmhzOiBEdXJhdGlvbik6IER1cmF0aW9uIHtcbiAgICBjb25zdCB0YXJnZXRVbml0ID0gZmluZXN0VW5pdCh0aGlzLnVuaXQsIHJocy51bml0KTtcbiAgICBjb25zdCByZXMgPSBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIHRhcmdldFVuaXQsIHt9KSAtIGNvbnZlcnQocmhzLmFtb3VudCwgcmhzLnVuaXQsIHRhcmdldFVuaXQsIHt9KTtcbiAgICByZXR1cm4gbmV3IER1cmF0aW9uKHJlcywgdGFyZ2V0VW5pdCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSB0b3RhbCBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIGluIHRoaXMgRHVyYXRpb25cbiAgICpcbiAgICogQHJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYER1cmF0aW9uYCBleHByZXNzZWQgaW4gTWlsbGlzZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIHRvTWlsbGlzZWNvbmRzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaWxsaXNlY29uZHMsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgdG90YWwgbnVtYmVyIG9mIHNlY29uZHMgaW4gdGhpcyBEdXJhdGlvblxuICAgKlxuICAgKiBAcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhpcyBgRHVyYXRpb25gIGV4cHJlc3NlZCBpbiBTZWNvbmRzLlxuICAgKi9cbiAgcHVibGljIHRvU2Vjb25kcyhvcHRzOiBUaW1lQ29udmVyc2lvbk9wdGlvbnMgPSB7fSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGNvbnZlcnQodGhpcy5hbW91bnQsIHRoaXMudW5pdCwgVGltZVVuaXQuU2Vjb25kcywgb3B0cyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSB0b3RhbCBudW1iZXIgb2YgbWludXRlcyBpbiB0aGlzIER1cmF0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGBEdXJhdGlvbmAgZXhwcmVzc2VkIGluIE1pbnV0ZXMuXG4gICAqL1xuICBwdWJsaWMgdG9NaW51dGVzKG9wdHM6IFRpbWVDb252ZXJzaW9uT3B0aW9ucyA9IHt9KTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29udmVydCh0aGlzLmFtb3VudCwgdGhpcy51bml0LCBUaW1lVW5pdC5NaW51dGVzLCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBob3VycyBpbiB0aGlzIER1cmF0aW9uXG4gICAqXG4gICAqIEByZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGlzIGBEdXJhdGlvbmAgZXhwcmVzc2VkIGluIEhvdXJzLlxuICAgKi9cbiAgcHVibGljIHRvSG91cnMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0LkhvdXJzLCBvcHRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBkYXlzIGluIHRoaXMgRHVyYXRpb25cbiAgICpcbiAgICogQHJldHVybnMgdGhlIHZhbHVlIG9mIHRoaXMgYER1cmF0aW9uYCBleHByZXNzZWQgaW4gRGF5cy5cbiAgICovXG4gIHB1YmxpYyB0b0RheXMob3B0czogVGltZUNvbnZlcnNpb25PcHRpb25zID0ge30pOiBudW1iZXIge1xuICAgIHJldHVybiBjb252ZXJ0KHRoaXMuYW1vdW50LCB0aGlzLnVuaXQsIFRpbWVVbml0LkRheXMsIG9wdHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBJU08gODYwMSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHBlcmlvZFxuICAgKlxuICAgKiBAcmV0dXJucyBhIHN0cmluZyBzdGFydGluZyB3aXRoICdQJyBkZXNjcmliaW5nIHRoZSBwZXJpb2RcbiAgICogQHNlZSBodHRwczovL3d3dy5pc28ub3JnL2ZyL3N0YW5kYXJkLzcwOTA3Lmh0bWxcbiAgICovXG4gIHB1YmxpYyB0b0lzb1N0cmluZygpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmFtb3VudCA9PT0gMCkgeyByZXR1cm4gJ1BUMFMnOyB9XG5cbiAgICBjb25zdCByZXQgPSBbJ1AnXTtcbiAgICBsZXQgdGVlID0gZmFsc2U7XG5cbiAgICBmb3IgKGNvbnN0IFthbW91bnQsIHVuaXRdIG9mIHRoaXMuY29tcG9uZW50cyh0cnVlKSkge1xuICAgICAgaWYgKFtUaW1lVW5pdC5TZWNvbmRzLCBUaW1lVW5pdC5NaW51dGVzLCBUaW1lVW5pdC5Ib3Vyc10uaW5jbHVkZXModW5pdCkgJiYgIXRlZSkge1xuICAgICAgICByZXQucHVzaCgnVCcpO1xuICAgICAgICB0ZWUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0LnB1c2goYCR7YW1vdW50fSR7dW5pdC5pc29MYWJlbH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmV0LmpvaW4oJycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbiBJU08gODYwMSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHBlcmlvZFxuICAgKlxuICAgKiBAcmV0dXJucyBhIHN0cmluZyBzdGFydGluZyB3aXRoICdQJyBkZXNjcmliaW5nIHRoZSBwZXJpb2RcbiAgICogQHNlZSBodHRwczovL3d3dy5pc28ub3JnL2ZyL3N0YW5kYXJkLzcwOTA3Lmh0bWxcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGB0b0lzb1N0cmluZygpYCBpbnN0ZWFkLlxuICAgKi9cbiAgcHVibGljIHRvSVNPU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudG9Jc29TdHJpbmcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUdXJuIHRoaXMgZHVyYXRpb24gaW50byBhIGh1bWFuLXJlYWRhYmxlIHN0cmluZ1xuICAgKi9cbiAgcHVibGljIHRvSHVtYW5TdHJpbmcoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5hbW91bnQgPT09IDApIHsgcmV0dXJuIGZtdFVuaXQoMCwgdGhpcy51bml0KTsgfVxuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQodGhpcy5hbW91bnQpKSB7IHJldHVybiBgPHRva2VuPiAke3RoaXMudW5pdC5sYWJlbH1gOyB9XG5cbiAgICByZXR1cm4gdGhpcy5jb21wb25lbnRzKGZhbHNlKVxuICAgICAgLy8gMiBzaWduaWZpY2FudCBwYXJ0cywgdGhhdCdzIHRvdGFsbHkgZW5vdWdoIGZvciBodW1hbnNcbiAgICAgIC5zbGljZSgwLCAyKVxuICAgICAgLm1hcCgoW2Ftb3VudCwgdW5pdF0pID0+IGZtdFVuaXQoYW1vdW50LCB1bml0KSlcbiAgICAgIC5qb2luKCcgJyk7XG5cbiAgICBmdW5jdGlvbiBmbXRVbml0KGFtb3VudDogbnVtYmVyLCB1bml0OiBUaW1lVW5pdCkge1xuICAgICAgaWYgKGFtb3VudCA9PT0gMSkge1xuICAgICAgICAvLyBBbGwgb2YgdGhlIGxhYmVscyBlbmQgaW4gJ3MnXG4gICAgICAgIHJldHVybiBgJHthbW91bnR9ICR7dW5pdC5sYWJlbC5zdWJzdHJpbmcoMCwgdW5pdC5sYWJlbC5sZW5ndGggLSAxKX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGAke2Ftb3VudH0gJHt1bml0LmxhYmVsfWA7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBgRHVyYXRpb25gXG4gICAqXG4gICAqIFRoaXMgaXMgaXMgbmV2ZXIgdGhlIHJpZ2h0IGZ1bmN0aW9uIHRvIHVzZSB3aGVuIHlvdSB3YW50IHRvIHVzZSB0aGUgYER1cmF0aW9uYFxuICAgKiBvYmplY3QgaW4gYSB0ZW1wbGF0ZS4gVXNlIGB0b1NlY29uZHMoKWAsIGB0b01pbnV0ZXMoKWAsIGB0b0RheXMoKWAsIGV0Yy4gaW5zdGVhZC5cbiAgICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgRHVyYXRpb24uJHt0aGlzLnVuaXQubGFiZWx9KCR7dGhpcy5hbW91bnR9KWA7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBkdXJhdGlvbiBpbiBhIHNldCBvZiB3aG9sZSBudW1iZXJlZCB0aW1lIGNvbXBvbmVudHMsIG9yZGVyZWQgZnJvbSBsYXJnZXN0IHRvIHNtYWxsZXN0XG4gICAqXG4gICAqIE9ubHkgY29tcG9uZW50cyAhPSAwIHdpbGwgYmUgcmV0dXJuZWQuXG4gICAqXG4gICAqIENhbiBjb21iaW5lIG1pbGxpcyBhbmQgc2Vjb25kcyB0b2dldGhlciBmb3IgdGhlIGJlbmVmaXQgb2YgdG9Jc29TdHJpbmcsXG4gICAqIG1ha2VzIHRoZSBsb2dpYyBpbiB0aGVyZSBzaW1wbGVyLlxuICAgKi9cbiAgcHJpdmF0ZSBjb21wb25lbnRzKGNvbWJpbmVNaWxsaXNXaXRoU2Vjb25kczogYm9vbGVhbik6IEFycmF5PFtudW1iZXIsIFRpbWVVbml0XT4ge1xuICAgIGNvbnN0IHJldCA9IG5ldyBBcnJheTxbbnVtYmVyLCBUaW1lVW5pdF0+KCk7XG4gICAgbGV0IG1pbGxpcyA9IGNvbnZlcnQodGhpcy5hbW91bnQsIHRoaXMudW5pdCwgVGltZVVuaXQuTWlsbGlzZWNvbmRzLCB7IGludGVncmFsOiBmYWxzZSB9KTtcblxuICAgIGZvciAoY29uc3QgdW5pdCBvZiBbVGltZVVuaXQuRGF5cywgVGltZVVuaXQuSG91cnMsIFRpbWVVbml0Lk1pbnV0ZXMsIFRpbWVVbml0LlNlY29uZHNdKSB7XG4gICAgICBjb25zdCBjb3VudCA9IGNvbnZlcnQobWlsbGlzLCBUaW1lVW5pdC5NaWxsaXNlY29uZHMsIHVuaXQsIHsgaW50ZWdyYWw6IGZhbHNlIH0pO1xuICAgICAgLy8gUm91bmQgZG93biB0byBhIHdob2xlIG51bWJlciBVTkxFU1Mgd2UncmUgY29tYmluaW5nIG1pbGxpcyBhbmQgc2Vjb25kcyBhbmQgd2UgZ290IHRvIHRoZSBzZWNvbmRzXG4gICAgICBjb25zdCB3aG9sZUNvdW50ID0gdW5pdCA9PT0gVGltZVVuaXQuU2Vjb25kcyAmJiBjb21iaW5lTWlsbGlzV2l0aFNlY29uZHMgPyBjb3VudCA6IE1hdGguZmxvb3IoY291bnQpO1xuICAgICAgaWYgKHdob2xlQ291bnQgPiAwKSB7XG4gICAgICAgIHJldC5wdXNoKFt3aG9sZUNvdW50LCB1bml0XSk7XG4gICAgICAgIG1pbGxpcyAtPSB3aG9sZUNvdW50ICogdW5pdC5pbk1pbGxpcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1haW5kZXIgaW4gbWlsbGlzXG4gICAgaWYgKG1pbGxpcyA+IDApIHtcbiAgICAgIHJldC5wdXNoKFttaWxsaXMsIFRpbWVVbml0Lk1pbGxpc2Vjb25kc10pO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBkdXJhdGlvbiBpcyBhIHRva2VuIG9yIGEgcmVzb2x2YWJsZSBvYmplY3RcbiAgICovXG4gIHB1YmxpYyBpc1VucmVzb2x2ZWQoKSB7XG4gICAgcmV0dXJuIFRva2VuLmlzVW5yZXNvbHZlZCh0aGlzLmFtb3VudCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB1bml0IG9mIHRoZSBkdXJhdGlvblxuICAgKi9cbiAgcHVibGljIHVuaXRMYWJlbCgpIHtcbiAgICByZXR1cm4gdGhpcy51bml0LmxhYmVsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgc3RyaW5naWZpZWQgbnVtYmVyIG9mIGR1cmF0aW9uXG4gICAqL1xuICBwdWJsaWMgZm9ybWF0VG9rZW5Ub051bWJlcigpOiBzdHJpbmcge1xuICAgIGNvbnN0IG51bWJlciA9IFRva2VuaXphdGlvbi5zdHJpbmdpZnlOdW1iZXIodGhpcy5hbW91bnQpO1xuICAgIHJldHVybiBgJHtudW1iZXJ9ICR7dGhpcy51bml0LmxhYmVsfWA7XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBob3cgdG8gY29udmVydCB0aW1lIHRvIGEgZGlmZmVyZW50IHVuaXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGltZUNvbnZlcnNpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIGB0cnVlYCwgY29udmVyc2lvbnMgaW50byBhIGxhcmdlciB0aW1lIHVuaXQgKGUuZy4gYFNlY29uZHNgIHRvIGBNaW51dGVzYCkgd2lsbCBmYWlsIGlmIHRoZSByZXN1bHQgaXMgbm90IGFuXG4gICAqIGludGVnZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGludGVncmFsPzogYm9vbGVhbjtcbn1cblxuY2xhc3MgVGltZVVuaXQge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IE1pbGxpc2Vjb25kcyA9IG5ldyBUaW1lVW5pdCgnbWlsbGlzJywgJycsIDEpO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNlY29uZHMgPSBuZXcgVGltZVVuaXQoJ3NlY29uZHMnLCAnUycsIDFfMDAwKTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBNaW51dGVzID0gbmV3IFRpbWVVbml0KCdtaW51dGVzJywgJ00nLCA2MF8wMDApO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEhvdXJzID0gbmV3IFRpbWVVbml0KCdob3VycycsICdIJywgM182MDBfMDAwKTtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBEYXlzID0gbmV3IFRpbWVVbml0KCdkYXlzJywgJ0QnLCA4Nl80MDBfMDAwKTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSBsYWJlbDogc3RyaW5nLCBwdWJsaWMgcmVhZG9ubHkgaXNvTGFiZWw6IHN0cmluZywgcHVibGljIHJlYWRvbmx5IGluTWlsbGlzOiBudW1iZXIpIHtcbiAgICAvLyBNQVhfU0FGRV9JTlRFR0VSIGlzIDJeNTMsIHNvIGJ5IHJlcHJlc2VudGluZyBvdXIgZHVyYXRpb24gaW4gbWlsbGlzICh0aGUgbG93ZXN0XG4gICAgLy8gY29tbW9uIHVuaXQpIHRoZSBoaWdoZXN0IGR1cmF0aW9uIHdlIGNhbiByZXByZXNlbnQgaXNcbiAgICAvLyAyXjUzIC8gODYqMTBeNiB+PSAxMDQgKiAxMF42IGRheXMgKGFib3V0IDEwMCBtaWxsaW9uIGRheXMpLlxuICB9XG5cbiAgcHVibGljIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmxhYmVsO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnQoYW1vdW50OiBudW1iZXIsIGZyb21Vbml0OiBUaW1lVW5pdCwgdG9Vbml0OiBUaW1lVW5pdCwgeyBpbnRlZ3JhbCA9IHRydWUgfTogVGltZUNvbnZlcnNpb25PcHRpb25zKSB7XG4gIGlmIChmcm9tVW5pdC5pbk1pbGxpcyA9PT0gdG9Vbml0LmluTWlsbGlzKSB7IHJldHVybiBhbW91bnQ7IH1cblxuICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKGFtb3VudCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYER1cmF0aW9uIG11c3QgYmUgc3BlY2lmaWVkIGFzICdEdXJhdGlvbi4ke3RvVW5pdH0oKScgaGVyZSBzaW5jZSBpdHMgdmFsdWUgY29tZXMgZnJvbSBhIHRva2VuIGFuZCBjYW5ub3QgYmUgY29udmVydGVkIChnb3QgRHVyYXRpb24uJHtmcm9tVW5pdH0pYCk7XG4gIH1cbiAgY29uc3QgdmFsdWUgPSAoYW1vdW50ICogZnJvbVVuaXQuaW5NaWxsaXMpIC8gdG9Vbml0LmluTWlsbGlzO1xuICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsdWUpICYmIGludGVncmFsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAnJHthbW91bnR9ICR7ZnJvbVVuaXR9JyBjYW5ub3QgYmUgY29udmVydGVkIGludG8gYSB3aG9sZSBudW1iZXIgb2YgJHt0b1VuaXR9LmApO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHRpbWUgdW5pdCB3aXRoIGhpZ2hlc3QgZ3JhbnVsYXJpdHlcbiAqL1xuZnVuY3Rpb24gZmluZXN0VW5pdChhOiBUaW1lVW5pdCwgYjogVGltZVVuaXQpIHtcbiAgcmV0dXJuIGEuaW5NaWxsaXMgPCBiLmluTWlsbGlzID8gYSA6IGI7XG59XG4iXX0= |
\ | No newline at end of file |