UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

133 lines 18.7 kB
import { Injectable } from '@angular/core'; import { AlarmStatus } from '@c8y/client'; import { Permissions } from '@c8y/ngx-components'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; export class AlarmDetailsService { constructor(permissions) { this.permissions = permissions; this.STATUS_ATTRIBUTE = 'status'; } /** * Retrieves the username of the user who acknowledged an alarm status. * * This method checks if the provided status is equal to the acknowledged * status. If it is not, or if the * audit log is empty or the first log item does not contain a user, the * method returns a default value ('--'). * * If the status is the acknowledged status and the audit log contains valid * records, the method iterates over the audit records in reverse order * (starting from the most recent). It finds the first record where the * status attribute (defined by this.STATUS_ATTRIBUTE) has been changed to * the acknowledged status. The method then returns the username of the user * who made this change. * * If no such change is found in the audit records, it returns the username * from the first record of the audit log. * * There can be multiple audit logs with ACKNOWLEDGED status. * * @param status - The current status of the alarm. * @param auditLog - An array of audit records to process. * @returns The username of the user who acknowledged the status * or '--' if the status is not acknowledged or audit log is invalid. */ getAcknowledgedBy(status, auditLog) { let acknowledgedBy = '--'; if (status !== AlarmStatus.ACKNOWLEDGED || !auditLog || !auditLog[0]?.user) { return acknowledgedBy; } acknowledgedBy = auditLog[0].user; return auditLog.reduceRight((acc, auditLogItem) => { const changes = Array.from(auditLogItem.changes || []); const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED); return (acknowledgedStatusChange && auditLogItem.user) || acc; }, acknowledgedBy); } /** * Calculates the acknowledge time from a list of audit records. * * This method iterates over the provided audit records in reverse order * (starting from the most recent) and finds the first record where a * specific status attribute (defined by this.STATUS_ATTRIBUTE) has been * acknowledged. It then returns the creation time of that record. * * If no such record is found, the method returns the creation time of the * first audit record. If the audit record list is empty, it returns null. * * There can be multiple audit logs with ACKNOWLEDGED status. * * @param auditLog - An array of audit records to process. * @returns The creation time of the acknowledged record, * the creation time of the first record if no acknowledged record is found, * or null if the audit log is empty. */ getAcknowledgeTime(auditLog) { const initialValue = auditLog.length ? auditLog[0].creationTime : null; return auditLog.reduceRight((acc, auditLogItem) => { const changes = Array.from(auditLogItem.changes || []); const acknowledgedStatusChange = changes.find((change) => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.ACKNOWLEDGED); return acknowledgedStatusChange ? auditLogItem.creationTime : acc; }, initialValue); } /** * Retrieves the end time of an event from an audit log. * * The method processes the provided audit log to find the first instance * (starting from the most recent record) where the status was changed to 'CLEARED'. * It iterates over the audit records and * checks the changes in each record to find this status change. * * If a record with the CLEARED status is found, the method returns the creation time * of that record. If the entire audit log is processed without finding a CLEARED status, * the creation time of the first audit log record is returned. * * If the audit log is empty or null, the method returns null. * * There can be only one audit log with CLEARED status. * * @param auditLog - An array of audit records to process. * @returns The creation time of the record with the CLEARED status, * the creation time of the first record if no CLEARED status is found, * or null if the audit log is empty or null. */ getEndTime(auditLog) { if (!auditLog || auditLog.length === 0) { return null; } let latestClearedAuditTime = null; for (const auditLogItem of auditLog) { const changes = Array.from(auditLogItem.changes || []); const clearedStatusChange = changes.find(change => change.attribute === this.STATUS_ATTRIBUTE && change.newValue === AlarmStatus.CLEARED); if (clearedStatusChange) { if (!latestClearedAuditTime || auditLogItem.creationTime > latestClearedAuditTime) { latestClearedAuditTime = auditLogItem.creationTime; } } } return latestClearedAuditTime || auditLog[0].creationTime; } checkIfHasAnyRoleAllowingToCreateSmartRule() { const ROLES_ALLOWING_SMART_RULE_CREATION = [ [ Permissions.ROLE_INVENTORY_ADMIN, Permissions.ROLE_INVENTORY_CREATE, Permissions.ROLE_MANAGED_OBJECT_ADMIN, Permissions.ROLE_MANAGED_OBJECT_CREATE ], [Permissions.ROLE_CEP_MANAGEMENT_ADMIN, Permissions.ROLE_SMARTRULE_ADMIN] ]; return (this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[0]) && this.permissions.hasAnyRole(ROLES_ALLOWING_SMART_RULE_CREATION[1])); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, deps: [{ token: i1.Permissions }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AlarmDetailsService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.Permissions }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxhcm0tZGV0YWlscy5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWxhcm1zL2FsYXJtLWRldGFpbHMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxXQUFXLEVBQTBDLE1BQU0sYUFBYSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBS2xELE1BQU0sT0FBTyxtQkFBbUI7SUFHOUIsWUFBb0IsV0FBd0I7UUFBeEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFGM0IscUJBQWdCLEdBQUcsUUFBUSxDQUFDO0lBRUUsQ0FBQztJQUVoRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bd0JHO0lBQ0gsaUJBQWlCLENBQUMsTUFBdUIsRUFBRSxRQUF3QjtRQUNqRSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFFMUIsSUFBSSxNQUFNLEtBQUssV0FBVyxDQUFDLFlBQVksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUMzRSxPQUFPLGNBQWMsQ0FBQztRQUN4QixDQUFDO1FBRUQsY0FBYyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFbEMsT0FBTyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxFQUFFLFlBQVksRUFBRSxFQUFFO1lBQ2hELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQzNDLENBQUMsTUFBZSxFQUFFLEVBQUUsQ0FDbEIsTUFBTSxDQUFDLFNBQVMsS0FBSyxJQUFJLENBQUMsZ0JBQWdC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NEZBRVAsbUJBQW1CO2tCQUgvQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFsYXJtU3RhdHVzLCBBbGFybVN0YXR1c1R5cGUsIElBdWRpdFJlY29yZCwgSUNoYW5nZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IFBlcm1pc3Npb25zIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEFsYXJtRGV0YWlsc1NlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IFNUQVRVU19BVFRSSUJVVEUgPSAnc3RhdHVzJztcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBlcm1pc3Npb25zOiBQZXJtaXNzaW9ucykge31cblxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSB1c2VybmFtZSBvZiB0aGUgdXNlciB3aG8gYWNrbm93bGVkZ2VkIGFuIGFsYXJtIHN0YXR1cy5cbiAgICpcbiAgICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBwcm92aWRlZCBzdGF0dXMgaXMgZXF1YWwgdG8gdGhlIGFja25vd2xlZGdlZFxuICAgKiBzdGF0dXMuIElmIGl0IGlzIG5vdCwgb3IgaWYgdGhlXG4gICAqIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciB0aGUgZmlyc3QgbG9nIGl0ZW0gZG9lcyBub3QgY29udGFpbiBhIHVzZXIsIHRoZVxuICAgKiBtZXRob2QgcmV0dXJucyBhIGRlZmF1bHQgdmFsdWUgKCctLScpLlxuICAgKlxuICAgKiBJZiB0aGUgc3RhdHVzIGlzIHRoZSBhY2tub3dsZWRnZWQgc3RhdHVzIGFuZCB0aGUgYXVkaXQgbG9nIGNvbnRhaW5zIHZhbGlkXG4gICAqIHJlY29yZHMsIHRoZSBtZXRob2QgaXRlcmF0ZXMgb3ZlciB0aGUgYXVkaXQgcmVjb3JkcyBpbiByZXZlcnNlIG9yZGVyXG4gICAqIChzdGFydGluZyBmcm9tIHRoZSBtb3N0IHJlY2VudCkuIEl0IGZpbmRzIHRoZSBmaXJzdCByZWNvcmQgd2hlcmUgdGhlXG4gICAqIHN0YXR1cyBhdHRyaWJ1dGUgKGRlZmluZWQgYnkgdGhpcy5TVEFUVVNfQVRUUklCVVRFKSBoYXMgYmVlbiBjaGFuZ2VkIHRvXG4gICAqIHRoZSBhY2tub3dsZWRnZWQgc3RhdHVzLiBUaGUgbWV0aG9kIHRoZW4gcmV0dXJucyB0aGUgdXNlcm5hbWUgb2YgdGhlIHVzZXJcbiAgICogd2hvIG1hZGUgdGhpcyBjaGFuZ2UuXG4gICAqXG4gICAqIElmIG5vIHN1Y2ggY2hhbmdlIGlzIGZvdW5kIGluIHRoZSBhdWRpdCByZWNvcmRzLCBpdCByZXR1cm5zIHRoZSB1c2VybmFtZVxuICAgKiBmcm9tIHRoZSBmaXJzdCByZWNvcmQgb2YgdGhlIGF1ZGl0IGxvZy5cbiAgICpcbiAgICogVGhlcmUgY2FuIGJlIG11bHRpcGxlIGF1ZGl0IGxvZ3Mgd2l0aCBBQ0tOT1dMRURHRUQgc3RhdHVzLlxuICAgKlxuICAgKiBAcGFyYW0gc3RhdHVzIC0gVGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBhbGFybS5cbiAgICogQHBhcmFtIGF1ZGl0TG9nIC0gQW4gYXJyYXkgb2YgYXVkaXQgcmVjb3JkcyB0byBwcm9jZXNzLlxuICAgKiBAcmV0dXJucyBUaGUgdXNlcm5hbWUgb2YgdGhlIHVzZXIgd2hvIGFja25vd2xlZGdlZCB0aGUgc3RhdHVzXG4gICAqICAgICAgICAgICBvciAnLS0nIGlmIHRoZSBzdGF0dXMgaXMgbm90IGFja25vd2xlZGdlZCBvciBhdWRpdCBsb2cgaXMgaW52YWxpZC5cbiAgICovXG4gIGdldEFja25vd2xlZGdlZEJ5KHN0YXR1czogQWxhcm1TdGF0dXNUeXBlLCBhdWRpdExvZzogSUF1ZGl0UmVjb3JkW10pOiBzdHJpbmcge1xuICAgIGxldCBhY2tub3dsZWRnZWRCeSA9ICctLSc7XG5cbiAgICBpZiAoc3RhdHVzICE9PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRUQgfHwgIWF1ZGl0TG9nIHx8ICFhdWRpdExvZ1swXT8udXNlcikge1xuICAgICAgcmV0dXJuIGFja25vd2xlZGdlZEJ5O1xuICAgIH1cblxuICAgIGFja25vd2xlZGdlZEJ5ID0gYXVkaXRMb2dbMF0udXNlcjtcblxuICAgIHJldHVybiBhdWRpdExvZy5yZWR1Y2VSaWdodCgoYWNjLCBhdWRpdExvZ0l0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSA9IGNoYW5nZXMuZmluZChcbiAgICAgICAgKGNoYW5nZTogSUNoYW5nZSkgPT5cbiAgICAgICAgICBjaGFuZ2UuYXR0cmlidXRlID09PSB0aGlzLlNUQVRVU19BVFRSSUJVVEUgJiYgY2hhbmdlLm5ld1ZhbHVlID09PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRURcbiAgICAgICk7XG4gICAgICByZXR1cm4gKGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSAmJiBhdWRpdExvZ0l0ZW0udXNlcikgfHwgYWNjO1xuICAgIH0sIGFja25vd2xlZGdlZEJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBhY2tub3dsZWRnZSB0aW1lIGZyb20gYSBsaXN0IG9mIGF1ZGl0IHJlY29yZHMuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGl0ZXJhdGVzIG92ZXIgdGhlIHByb3ZpZGVkIGF1ZGl0IHJlY29yZHMgaW4gcmV2ZXJzZSBvcmRlclxuICAgKiAoc3RhcnRpbmcgZnJvbSB0aGUgbW9zdCByZWNlbnQpIGFuZCBmaW5kcyB0aGUgZmlyc3QgcmVjb3JkIHdoZXJlIGFcbiAgICogc3BlY2lmaWMgc3RhdHVzIGF0dHJpYnV0ZSAoZGVmaW5lZCBieSB0aGlzLlNUQVRVU19BVFRSSUJVVEUpIGhhcyBiZWVuXG4gICAqIGFja25vd2xlZGdlZC4gSXQgdGhlbiByZXR1cm5zIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoYXQgcmVjb3JkLlxuICAgKlxuICAgKiBJZiBubyBzdWNoIHJlY29yZCBpcyBmb3VuZCwgdGhlIG1ldGhvZCByZXR1cm5zIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZVxuICAgKiBmaXJzdCBhdWRpdCByZWNvcmQuIElmIHRoZSBhdWRpdCByZWNvcmQgbGlzdCBpcyBlbXB0eSwgaXQgcmV0dXJucyBudWxsLlxuICAgKlxuICAgKiBUaGVyZSBjYW4gYmUgbXVsdGlwbGUgYXVkaXQgbG9ncyB3aXRoIEFDS05PV0xFREdFRCBzdGF0dXMuXG4gICAqXG4gICAqIEBwYXJhbSBhdWRpdExvZyAtIEFuIGFycmF5IG9mIGF1ZGl0IHJlY29yZHMgdG8gcHJvY2Vzcy5cbiAgICogQHJldHVybnMgVGhlIGNyZWF0aW9uIHRpbWUgb2YgdGhlIGFja25vd2xlZGdlZCByZWNvcmQsXG4gICAqICAgICAgICAgICB0aGUgY3JlYXRpb24gdGltZSBvZiB0aGUgZmlyc3QgcmVjb3JkIGlmIG5vIGFja25vd2xlZGdlZCByZWNvcmQgaXMgZm91bmQsXG4gICAqICAgICAgICAgICBvciBudWxsIGlmIHRoZSBhdWRpdCBsb2cgaXMgZW1wdHkuXG4gICAqL1xuICBnZXRBY2tub3dsZWRnZVRpbWUoYXVkaXRMb2c6IElBdWRpdFJlY29yZFtdKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3QgaW5pdGlhbFZhbHVlID0gYXVkaXRMb2cubGVuZ3RoID8gYXVkaXRMb2dbMF0uY3JlYXRpb25UaW1lIDogbnVsbDtcblxuICAgIHJldHVybiBhdWRpdExvZy5yZWR1Y2VSaWdodCgoYWNjLCBhdWRpdExvZ0l0ZW0pID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGFja25vd2xlZGdlZFN0YXR1c0NoYW5nZSA9IGNoYW5nZXMuZmluZChcbiAgICAgICAgKGNoYW5nZTogSUNoYW5nZSkgPT5cbiAgICAgICAgICBjaGFuZ2UuYXR0cmlidXRlID09PSB0aGlzLlNUQVRVU19BVFRSSUJVVEUgJiYgY2hhbmdlLm5ld1ZhbHVlID09PSBBbGFybVN0YXR1cy5BQ0tOT1dMRURHRURcbiAgICAgICk7XG4gICAgICByZXR1cm4gYWNrbm93bGVkZ2VkU3RhdHVzQ2hhbmdlID8gYXVkaXRMb2dJdGVtLmNyZWF0aW9uVGltZSA6IGFjYztcbiAgICB9LCBpbml0aWFsVmFsdWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgZW5kIHRpbWUgb2YgYW4gZXZlbnQgZnJvbSBhbiBhdWRpdCBsb2cuXG4gICAqXG4gICAqIFRoZSBtZXRob2QgcHJvY2Vzc2VzIHRoZSBwcm92aWRlZCBhdWRpdCBsb2cgdG8gZmluZCB0aGUgZmlyc3QgaW5zdGFuY2VcbiAgICogKHN0YXJ0aW5nIGZyb20gdGhlIG1vc3QgcmVjZW50IHJlY29yZCkgd2hlcmUgdGhlIHN0YXR1cyB3YXMgY2hhbmdlZCB0byAnQ0xFQVJFRCcuXG4gICAqIEl0IGl0ZXJhdGVzIG92ZXIgdGhlIGF1ZGl0IHJlY29yZHMgYW5kXG4gICAqIGNoZWNrcyB0aGUgY2hhbmdlcyBpbiBlYWNoIHJlY29yZCB0byBmaW5kIHRoaXMgc3RhdHVzIGNoYW5nZS5cbiAgICpcbiAgICogSWYgYSByZWNvcmQgd2l0aCB0aGUgQ0xFQVJFRCBzdGF0dXMgaXMgZm91bmQsIHRoZSBtZXRob2QgcmV0dXJucyB0aGUgY3JlYXRpb24gdGltZVxuICAgKiBvZiB0aGF0IHJlY29yZC4gSWYgdGhlIGVudGlyZSBhdWRpdCBsb2cgaXMgcHJvY2Vzc2VkIHdpdGhvdXQgZmluZGluZyBhIENMRUFSRUQgc3RhdHVzLFxuICAgKiB0aGUgY3JlYXRpb24gdGltZSBvZiB0aGUgZmlyc3QgYXVkaXQgbG9nIHJlY29yZCBpcyByZXR1cm5lZC5cbiAgICpcbiAgICogSWYgdGhlIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciBudWxsLCB0aGUgbWV0aG9kIHJldHVybnMgbnVsbC5cbiAgICpcbiAgICogVGhlcmUgY2FuIGJlIG9ubHkgb25lIGF1ZGl0IGxvZyB3aXRoIENMRUFSRUQgc3RhdHVzLlxuICAgKlxuICAgKiBAcGFyYW0gYXVkaXRMb2cgLSBBbiBhcnJheSBvZiBhdWRpdCByZWNvcmRzIHRvIHByb2Nlc3MuXG4gICAqIEByZXR1cm5zIFRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZSByZWNvcmQgd2l0aCB0aGUgQ0xFQVJFRCBzdGF0dXMsXG4gICAqICAgICAgICAgIHRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoZSBmaXJzdCByZWNvcmQgaWYgbm8gQ0xFQVJFRCBzdGF0dXMgaXMgZm91bmQsXG4gICAqICAgICAgICAgIG9yIG51bGwgaWYgdGhlIGF1ZGl0IGxvZyBpcyBlbXB0eSBvciBudWxsLlxuICAgKi9cbiAgZ2V0RW5kVGltZShhdWRpdExvZzogSUF1ZGl0UmVjb3JkW10pOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIWF1ZGl0TG9nIHx8IGF1ZGl0TG9nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgPSBudWxsO1xuXG4gICAgZm9yIChjb25zdCBhdWRpdExvZ0l0ZW0gb2YgYXVkaXRMb2cpIHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBBcnJheS5mcm9tKGF1ZGl0TG9nSXRlbS5jaGFuZ2VzIHx8IFtdKTtcbiAgICAgIGNvbnN0IGNsZWFyZWRTdGF0dXNDaGFuZ2UgPSBjaGFuZ2VzLmZpbmQoXG4gICAgICAgIGNoYW5nZSA9PlxuICAgICAgICAgIGNoYW5nZS5hdHRyaWJ1dGUgPT09IHRoaXMuU1RBVFVTX0FUVFJJQlVURSAmJiBjaGFuZ2UubmV3VmFsdWUgPT09IEFsYXJtU3RhdHVzLkNMRUFSRURcbiAgICAgICk7XG5cbiAgICAgIGlmIChjbGVhcmVkU3RhdHVzQ2hhbmdlKSB7XG4gICAgICAgIGlmICghbGF0ZXN0Q2xlYXJlZEF1ZGl0VGltZSB8fCBhdWRpdExvZ0l0ZW0uY3JlYXRpb25UaW1lID4gbGF0ZXN0Q2xlYXJlZEF1ZGl0VGltZSkge1xuICAgICAgICAgIGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgPSBhdWRpdExvZ0l0ZW0uY3JlYXRpb25UaW1lO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxhdGVzdENsZWFyZWRBdWRpdFRpbWUgfHwgYXVkaXRMb2dbMF0uY3JlYXRpb25UaW1lO1xuICB9XG5cbiAgY2hlY2tJZkhhc0FueVJvbGVBbGxvd2luZ1RvQ3JlYXRlU21hcnRSdWxlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IFJPTEVTX0FMTE9XSU5HX1NNQVJUX1JVTEVfQ1JFQVRJT04gPSBbXG4gICAgICBbXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfSU5WRU5UT1JZX0FETUlOLFxuICAgICAgICBQZXJtaXNzaW9ucy5ST0xFX0lOVkVOVE9SWV9DUkVBVEUsXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfTUFOQUdFRF9PQkpFQ1RfQURNSU4sXG4gICAgICAgIFBlcm1pc3Npb25zLlJPTEVfTUFOQUdFRF9PQkpFQ1RfQ1JFQVRFXG4gICAgICBdLFxuICAgICAgW1Blcm1pc3Npb25zLlJPTEVfQ0VQX01BTkFHRU1FTlRfQURNSU4sIFBlcm1pc3Npb25zLlJPTEVfU01BUlRSVUxFX0FETUlOXVxuICAgIF07XG5cbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5wZXJtaXNzaW9ucy5oYXNBbnlSb2xlKFJPTEVTX0FMTE9XSU5HX1NNQVJUX1JVTEVfQ1JFQVRJT05bMF0pICYmXG4gICAgICB0aGlzLnBlcm1pc3Npb25zLmhhc0FueVJvbGUoUk9MRVNfQUxMT1dJTkdfU01BUlRfUlVMRV9DUkVBVElPTlsxXSlcbiAgICApO1xuICB9XG59XG4iXX0=