@asadi/angular-date-components
Version:
`Angular Date Components` is a comprehensive angular library of date-related components designed to meet the needs of applications that require localization based on various calendar systems. While the package currently includes two powerful components (S
136 lines • 16.7 kB
JavaScript
/**
* A utility class for handling and parsing date and time strings.
* Provides methods to extract date parts, time parts, hours, and minutes from formatted date strings.
* This class is designed to work with ISO 8601-like datetime formats.
*/
export class ADCDateTimeTools {
constructor() {
/**
* Allowed date splitters for parsing date strings.
*/
this.dateSplitters = ['-', '/'];
}
/**
* Constructs a dynamic regex pattern for date splitters.
*
* @returns A string pattern containing allowed splitters.
*/
getDateSplitterPattern() {
// Escape special characters for regex and join them into a character class.
return `[${this.dateSplitters.map(char => `\\${char}`).join('')}]`;
}
/**
* Extracts the date portion (YYYY-MM-DD or YYYY/MM/DD) from a datetime string.
*
* @param source - A datetime string in the format `yyyy-MM-ddThh:mm:ss` or `yyyy-MM-dd`.
* @returns The extracted date in the format `yyyy-MM-dd` or `yyyy/MM/dd`.
* @throws If the source string is not a valid date string.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.dateOnly('2024-11-12T15:30:00')); // Output: '2024-11-12'
*/
dateOnly(source) {
const splitterPattern = this.getDateSplitterPattern();
const regex = new RegExp(`^\\d{4}${splitterPattern}(0[1-9]|1[0-2])${splitterPattern}(0[1-9]|[12]\\d|3[01])`);
if (!regex.test(source)) {
throw new Error(`Invalid date string format: ${source}. Expected formats: yyyy-MM-dd or yyyy/MM/dd`);
}
return source.split('T')[0];
}
/**
* Extracts the time portion (hh:mm:ss) from a datetime string.
*
* @param source - A datetime string in the format `yyyy-MM-ddThh:mm:ss` or `yyyy-MM-ddThh:mm`.
* @returns The extracted time in the format `hh:mm:ss` or `hh:mm`.
* @throws If the source string is not a valid datetime string.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.timeOnly('2024-11-12T15:30:00')); // Output: '15:30:00'
*/
timeOnly(source) {
const regex = /.*T(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
if (!regex.test(source)) {
throw new Error(`Invalid datetime string format: ${source}. Expected format: *Thh:mm:ss or *Thh:mm`);
}
return source.split('T')[1];
}
/**
* Extracts the hour from a time string.
*
* @param source - A time string in the format `hh:mm:ss` or `hh:mm`.
* @returns The hour as a string.
* @throws If the source string is not a valid time string.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.hour('15:45')); // Output: '15'
*/
hour(source) {
const regex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
if (!regex.test(source)) {
throw new Error(`Invalid time string format: ${source}. Expected format: hh:mm:ss or hh:mm`);
}
return source.split(':')[0];
}
/**
* Extracts the hour from a time string or returns a default value if the source is null or undefined.
*
* @param source - A time string in the format `hh:mm:ss` or `hh:mm`, or `null`/`undefined`.
* @param defaultHour - The default hour to return if the source is null or invalid.
* @returns The hour as a string or the default value.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.hourOrDefault(null, '08')); // Output: '08'
*/
hourOrDefault(source, defaultHour) {
if (source == null)
return defaultHour;
const regex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
if (!regex.test(source)) {
throw new Error(`Invalid time string format: ${source}. Expected format: hh:mm:ss or hh:mm`);
}
return source.split(':')[0];
}
/**
* Extracts the minutes from a time string.
*
* @param source - A time string in the format `hh:mm:ss` or `hh:mm`.
* @returns The minutes as a string.
* @throws If the source string is not a valid time string.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.minutes('15:45')); // Output: '45'
*/
minutes(source) {
const regex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
if (!regex.test(source)) {
throw new Error(`Invalid time string format: ${source}. Expected format: hh:mm:ss or hh:mm`);
}
return source.split(':')[1];
}
/**
* Extracts the minutes from a time string or returns a default value if the source is null or undefined.
*
* @param source - A time string in the format `hh:mm:ss` or `hh:mm`, or `null`/`undefined`.
* @param defaultMinute - The default minute to return if the source is null or invalid.
* @returns The minutes as a string or the default value.
*
* @example
* const tools = new ADCDateTimeTools();
* console.log(tools.minutesOrDefault(null, '30')); // Output: '30'
*/
minutesOrDefault(source, defaultMinute) {
if (source == null)
return defaultMinute;
const regex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$/;
if (!regex.test(source)) {
throw new Error(`Invalid time string format: ${source}. Expected format: hh:mm:ss or hh:mm`);
}
return source.split(':')[1];
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS10aW1lLnRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNhZGkvYW5ndWxhci1kYXRlLWNvbXBvbmVudHMvY29yZS9zcmMvdXRpbHMvZGF0ZS10aW1lLnRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sZ0JBQWdCO0lBQTdCO1FBRUk7O1dBRUc7UUFDYyxrQkFBYSxHQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBOEl4RCxDQUFDO0lBNUlDOzs7O09BSUc7SUFDSyxzQkFBc0I7UUFDNUIsNEVBQTRFO1FBQzVFLE9BQU8sSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILFFBQVEsQ0FBQyxNQUFjO1FBQ3JCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ3RELE1BQU0sS0FBSyxHQUFHLElBQUksTUFBTSxDQUFDLFVBQVUsZUFBZSxrQkFBa0IsZUFBZSx3QkFBd0IsQ0FBQyxDQUFDO1FBRTdHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLE1BQU0sOENBQThDLENBQUMsQ0FBQztTQUN0RztRQUVELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILFFBQVEsQ0FBQyxNQUFjO1FBQ3JCLE1BQU0sS0FBSyxHQUFHLHFEQUFxRCxDQUFDO1FBRXBFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLE1BQU0sMENBQTBDLENBQUMsQ0FBQztTQUN0RztRQUVELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILElBQUksQ0FBQyxNQUFjO1FBQ2pCLE1BQU0sS0FBSyxHQUFHLG1EQUFtRCxDQUFDO1FBRWxFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLE1BQU0sc0NBQXNDLENBQUMsQ0FBQztTQUM5RjtRQUVELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNILGFBQWEsQ0FBQyxNQUFpQyxFQUFFLFdBQW1CO1FBQ2xFLElBQUksTUFBTSxJQUFJLElBQUk7WUFBRSxPQUFPLFdBQVcsQ0FBQztRQUV2QyxNQUFNLEtBQUssR0FBRyxtREFBbUQsQ0FBQztRQUVsRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixNQUFNLHNDQUFzQyxDQUFDLENBQUM7U0FDOUY7UUFFRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxPQUFPLENBQUMsTUFBYztRQUNwQixNQUFNLEtBQUssR0FBRyxtREFBbUQsQ0FBQztRQUVsRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixNQUFNLHNDQUFzQyxDQUFDLENBQUM7U0FDOUY7UUFFRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVEOzs7Ozs7Ozs7O0dBVUQ7SUFDSCxnQkFBZ0IsQ0FBQyxNQUFpQyxFQUFFLGFBQXFCO1FBQ3JFLElBQUksTUFBTSxJQUFJLElBQUk7WUFBRSxPQUFPLGFBQWEsQ0FBQztRQUV6QyxNQUFNLEtBQUssR0FBRyxtREFBbUQsQ0FBQztRQUVsRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixNQUFNLHNDQUFzQyxDQUFDLENBQUM7U0FDaEc7UUFFRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsQ0FBQztDQUNFIiwic291cmNlc0NvbnRlbnQiOlsiXHJcbi8qKlxyXG4gKiBBIHV0aWxpdHkgY2xhc3MgZm9yIGhhbmRsaW5nIGFuZCBwYXJzaW5nIGRhdGUgYW5kIHRpbWUgc3RyaW5ncy5cclxuICogUHJvdmlkZXMgbWV0aG9kcyB0byBleHRyYWN0IGRhdGUgcGFydHMsIHRpbWUgcGFydHMsIGhvdXJzLCBhbmQgbWludXRlcyBmcm9tIGZvcm1hdHRlZCBkYXRlIHN0cmluZ3MuXHJcbiAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gd29yayB3aXRoIElTTyA4NjAxLWxpa2UgZGF0ZXRpbWUgZm9ybWF0cy5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBBRENEYXRlVGltZVRvb2xzIHtcclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBBbGxvd2VkIGRhdGUgc3BsaXR0ZXJzIGZvciBwYXJzaW5nIGRhdGUgc3RyaW5ncy5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSByZWFkb25seSBkYXRlU3BsaXR0ZXJzOiBzdHJpbmdbXSA9IFsnLScsICcvJ107XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBkeW5hbWljIHJlZ2V4IHBhdHRlcm4gZm9yIGRhdGUgc3BsaXR0ZXJzLlxyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyBBIHN0cmluZyBwYXR0ZXJuIGNvbnRhaW5pbmcgYWxsb3dlZCBzcGxpdHRlcnMuXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0RGF0ZVNwbGl0dGVyUGF0dGVybigpOiBzdHJpbmcge1xyXG4gICAgICAvLyBFc2NhcGUgc3BlY2lhbCBjaGFyYWN0ZXJzIGZvciByZWdleCBhbmQgam9pbiB0aGVtIGludG8gYSBjaGFyYWN0ZXIgY2xhc3MuXHJcbiAgICAgIHJldHVybiBgWyR7dGhpcy5kYXRlU3BsaXR0ZXJzLm1hcChjaGFyID0+IGBcXFxcJHtjaGFyfWApLmpvaW4oJycpfV1gO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBFeHRyYWN0cyB0aGUgZGF0ZSBwb3J0aW9uIChZWVlZLU1NLUREIG9yIFlZWVkvTU0vREQpIGZyb20gYSBkYXRldGltZSBzdHJpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBzb3VyY2UgLSBBIGRhdGV0aW1lIHN0cmluZyBpbiB0aGUgZm9ybWF0IGB5eXl5LU1NLWRkVGhoOm1tOnNzYCBvciBgeXl5eS1NTS1kZGAuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgZXh0cmFjdGVkIGRhdGUgaW4gdGhlIGZvcm1hdCBgeXl5eS1NTS1kZGAgb3IgYHl5eXkvTU0vZGRgLlxyXG4gICAgICogQHRocm93cyBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBub3QgYSB2YWxpZCBkYXRlIHN0cmluZy5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIGNvbnN0IHRvb2xzID0gbmV3IEFEQ0RhdGVUaW1lVG9vbHMoKTtcclxuICAgICAqIGNvbnNvbGUubG9nKHRvb2xzLmRhdGVPbmx5KCcyMDI0LTExLTEyVDE1OjMwOjAwJykpOyAvLyBPdXRwdXQ6ICcyMDI0LTExLTEyJ1xyXG4gICAgICovXHJcbiAgICBkYXRlT25seShzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgIGNvbnN0IHNwbGl0dGVyUGF0dGVybiA9IHRoaXMuZ2V0RGF0ZVNwbGl0dGVyUGF0dGVybigpO1xyXG4gICAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoYF5cXFxcZHs0fSR7c3BsaXR0ZXJQYXR0ZXJufSgwWzEtOV18MVswLTJdKSR7c3BsaXR0ZXJQYXR0ZXJufSgwWzEtOV18WzEyXVxcXFxkfDNbMDFdKWApO1xyXG4gIFxyXG4gICAgICBpZiAoIXJlZ2V4LnRlc3Qoc291cmNlKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBkYXRlIHN0cmluZyBmb3JtYXQ6ICR7c291cmNlfS4gRXhwZWN0ZWQgZm9ybWF0czogeXl5eS1NTS1kZCBvciB5eXl5L01NL2RkYCk7XHJcbiAgICAgIH1cclxuICBcclxuICAgICAgcmV0dXJuIHNvdXJjZS5zcGxpdCgnVCcpWzBdO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBFeHRyYWN0cyB0aGUgdGltZSBwb3J0aW9uIChoaDptbTpzcykgZnJvbSBhIGRhdGV0aW1lIHN0cmluZy5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHNvdXJjZSAtIEEgZGF0ZXRpbWUgc3RyaW5nIGluIHRoZSBmb3JtYXQgYHl5eXktTU0tZGRUaGg6bW06c3NgIG9yIGB5eXl5LU1NLWRkVGhoOm1tYC5cclxuICAgICAqIEByZXR1cm5zIFRoZSBleHRyYWN0ZWQgdGltZSBpbiB0aGUgZm9ybWF0IGBoaDptbTpzc2Agb3IgYGhoOm1tYC5cclxuICAgICAqIEB0aHJvd3MgSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgbm90IGEgdmFsaWQgZGF0ZXRpbWUgc3RyaW5nLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogY29uc3QgdG9vbHMgPSBuZXcgQURDRGF0ZVRpbWVUb29scygpO1xyXG4gICAgICogY29uc29sZS5sb2codG9vbHMudGltZU9ubHkoJzIwMjQtMTEtMTJUMTU6MzA6MDAnKSk7IC8vIE91dHB1dDogJzE1OjMwOjAwJ1xyXG4gICAgICovXHJcbiAgICB0aW1lT25seShzb3VyY2U6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICAgIGNvbnN0IHJlZ2V4ID0gLy4qVCgwWzAtOV18MVswLTldfDJbMC0zXSk6WzAtNV1bMC05XSg6WzAtNV1bMC05XSk/JC87XHJcbiAgXHJcbiAgICAgIGlmICghcmVnZXgudGVzdChzb3VyY2UpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRhdGV0aW1lIHN0cmluZyBmb3JtYXQ6ICR7c291cmNlfS4gRXhwZWN0ZWQgZm9ybWF0OiAqVGhoOm1tOnNzIG9yICpUaGg6bW1gKTtcclxuICAgICAgfVxyXG4gIFxyXG4gICAgICByZXR1cm4gc291cmNlLnNwbGl0KCdUJylbMV07XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIEV4dHJhY3RzIHRoZSBob3VyIGZyb20gYSB0aW1lIHN0cmluZy5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHNvdXJjZSAtIEEgdGltZSBzdHJpbmcgaW4gdGhlIGZvcm1hdCBgaGg6bW06c3NgIG9yIGBoaDptbWAuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgaG91ciBhcyBhIHN0cmluZy5cclxuICAgICAqIEB0aHJvd3MgSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgbm90IGEgdmFsaWQgdGltZSBzdHJpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiBjb25zdCB0b29scyA9IG5ldyBBRENEYXRlVGltZVRvb2xzKCk7XHJcbiAgICAgKiBjb25zb2xlLmxvZyh0b29scy5ob3VyKCcxNTo0NScpKTsgLy8gT3V0cHV0OiAnMTUnXHJcbiAgICAgKi9cclxuICAgIGhvdXIoc291cmNlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICBjb25zdCByZWdleCA9IC9eKDBbMC05XXwxWzAtOV18MlswLTNdKTpbMC01XVswLTldKDpbMC01XVswLTldKT8kLztcclxuICBcclxuICAgICAgaWYgKCFyZWdleC50ZXN0KHNvdXJjZSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgdGltZSBzdHJpbmcgZm9ybWF0OiAke3NvdXJjZX0uIEV4cGVjdGVkIGZvcm1hdDogaGg6bW06c3Mgb3IgaGg6bW1gKTtcclxuICAgICAgfVxyXG4gIFxyXG4gICAgICByZXR1cm4gc291cmNlLnNwbGl0KCc6JylbMF07XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIEV4dHJhY3RzIHRoZSBob3VyIGZyb20gYSB0aW1lIHN0cmluZyBvciByZXR1cm5zIGEgZGVmYXVsdCB2YWx1ZSBpZiB0aGUgc291cmNlIGlzIG51bGwgb3IgdW5kZWZpbmVkLlxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gc291cmNlIC0gQSB0aW1lIHN0cmluZyBpbiB0aGUgZm9ybWF0IGBoaDptbTpzc2Agb3IgYGhoOm1tYCwgb3IgYG51bGxgL2B1bmRlZmluZWRgLlxyXG4gICAgICogQHBhcmFtIGRlZmF1bHRIb3VyIC0gVGhlIGRlZmF1bHQgaG91ciB0byByZXR1cm4gaWYgdGhlIHNvdXJjZSBpcyBudWxsIG9yIGludmFsaWQuXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgaG91ciBhcyBhIHN0cmluZyBvciB0aGUgZGVmYXVsdCB2YWx1ZS5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIGNvbnN0IHRvb2xzID0gbmV3IEFEQ0RhdGVUaW1lVG9vbHMoKTtcclxuICAgICAqIGNvbnNvbGUubG9nKHRvb2xzLmhvdXJPckRlZmF1bHQobnVsbCwgJzA4JykpOyAvLyBPdXRwdXQ6ICcwOCdcclxuICAgICAqL1xyXG4gICAgaG91ck9yRGVmYXVsdChzb3VyY2U6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIGRlZmF1bHRIb3VyOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICBpZiAoc291cmNlID09IG51bGwpIHJldHVybiBkZWZhdWx0SG91cjtcclxuICBcclxuICAgICAgY29uc3QgcmVnZXggPSAvXigwWzAtOV18MVswLTldfDJbMC0zXSk6WzAtNV1bMC05XSg6WzAtNV1bMC05XSk/JC87XHJcbiAgXHJcbiAgICAgIGlmICghcmVnZXgudGVzdChzb3VyY2UpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRpbWUgc3RyaW5nIGZvcm1hdDogJHtzb3VyY2V9LiBFeHBlY3RlZCBmb3JtYXQ6IGhoOm1tOnNzIG9yIGhoOm1tYCk7XHJcbiAgICAgIH1cclxuICBcclxuICAgICAgcmV0dXJuIHNvdXJjZS5zcGxpdCgnOicpWzBdO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBFeHRyYWN0cyB0aGUgbWludXRlcyBmcm9tIGEgdGltZSBzdHJpbmcuXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSBzb3VyY2UgLSBBIHRpbWUgc3RyaW5nIGluIHRoZSBmb3JtYXQgYGhoOm1tOnNzYCBvciBgaGg6bW1gLlxyXG4gICAgICogQHJldHVybnMgVGhlIG1pbnV0ZXMgYXMgYSBzdHJpbmcuXHJcbiAgICAgKiBAdGhyb3dzIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIG5vdCBhIHZhbGlkIHRpbWUgc3RyaW5nLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogY29uc3QgdG9vbHMgPSBuZXcgQURDRGF0ZVRpbWVUb29scygpO1xyXG4gICAgICogY29uc29sZS5sb2codG9vbHMubWludXRlcygnMTU6NDUnKSk7IC8vIE91dHB1dDogJzQ1J1xyXG4gICAgICovXHJcbiAgICBtaW51dGVzKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgY29uc3QgcmVnZXggPSAvXigwWzAtOV18MVswLTldfDJbMC0zXSk6WzAtNV1bMC05XSg6WzAtNV1bMC05XSk/JC87XHJcbiAgXHJcbiAgICAgIGlmICghcmVnZXgudGVzdChzb3VyY2UpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRpbWUgc3RyaW5nIGZvcm1hdDogJHtzb3VyY2V9LiBFeHBlY3RlZCBmb3JtYXQ6IGhoOm1tOnNzIG9yIGhoOm1tYCk7XHJcbiAgICAgIH1cclxuICBcclxuICAgICAgcmV0dXJuIHNvdXJjZS5zcGxpdCgnOicpWzFdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gKiBFeHRyYWN0cyB0aGUgbWludXRlcyBmcm9tIGEgdGltZSBzdHJpbmcgb3IgcmV0dXJucyBhIGRlZmF1bHQgdmFsdWUgaWYgdGhlIHNvdXJjZSBpcyBudWxsIG9yIHVuZGVmaW5lZC5cclxuICogXHJcbiAqIEBwYXJhbSBzb3VyY2UgLSBBIHRpbWUgc3RyaW5nIGluIHRoZSBmb3JtYXQgYGhoOm1tOnNzYCBvciBgaGg6bW1gLCBvciBgbnVsbGAvYHVuZGVmaW5lZGAuXHJcbiAqIEBwYXJhbSBkZWZhdWx0TWludXRlIC0gVGhlIGRlZmF1bHQgbWludXRlIHRvIHJldHVybiBpZiB0aGUgc291cmNlIGlzIG51bGwgb3IgaW52YWxpZC5cclxuICogQHJldHVybnMgVGhlIG1pbnV0ZXMgYXMgYSBzdHJpbmcgb3IgdGhlIGRlZmF1bHQgdmFsdWUuXHJcbiAqIFxyXG4gKiBAZXhhbXBsZVxyXG4gKiBjb25zdCB0b29scyA9IG5ldyBBRENEYXRlVGltZVRvb2xzKCk7XHJcbiAqIGNvbnNvbGUubG9nKHRvb2xzLm1pbnV0ZXNPckRlZmF1bHQobnVsbCwgJzMwJykpOyAvLyBPdXRwdXQ6ICczMCdcclxuICovXHJcbm1pbnV0ZXNPckRlZmF1bHQoc291cmNlOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLCBkZWZhdWx0TWludXRlOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKHNvdXJjZSA9PSBudWxsKSByZXR1cm4gZGVmYXVsdE1pbnV0ZTtcclxuXHJcbiAgICBjb25zdCByZWdleCA9IC9eKDBbMC05XXwxWzAtOV18MlswLTNdKTpbMC01XVswLTldKDpbMC01XVswLTldKT8kLztcclxuXHJcbiAgICBpZiAoIXJlZ2V4LnRlc3Qoc291cmNlKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0aW1lIHN0cmluZyBmb3JtYXQ6ICR7c291cmNlfS4gRXhwZWN0ZWQgZm9ybWF0OiBoaDptbTpzcyBvciBoaDptbWApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzb3VyY2Uuc3BsaXQoJzonKVsxXTtcclxufVxyXG4gIH0iXX0=