UNPKG

ngx-step

Version:

A simple library module to generate the different stages for activity to track multiple stages.

98 lines 57 kB
import { Component, Input } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "./stageformatter.pipe"; import * as i3 from "./customTimeConverter.pipe"; import * as i4 from "./customTimeCalculator.pipe"; export class NgxStepComponent { constructor() { this.updateProgressLogs = []; this.stages = [1, 2, 3, 4, 5]; this.jobOverallStatus = 'NOT_STARTED'; // Possible Values- NOT_STARTED , ACTIVE, COMPLETED, FAILED this.options = { type: 'BASIC', excludeFirstEntry: false, finalStageName: 'FINISH', isMultiWordStageName: false, textSeparator: '_' }; this.logsTableData = []; this.showLogs = false; this.logTableOptions = { tableTitle: 'Events & Logs', tableHeader: ['Date/Time', 'Events/Stages', 'Description', 'Status', 'Time Taken'], excludeFirstEntry: false, showTimeDiffColumn: false, manualCalculationForDuration: false, ascSortOrder: true, dateFormat: 'full' }; this.states = []; this.logs = []; } ngOnChanges(changes) { this.ngOnInit(); } ngOnInit() { this.generateStages(); if (this.showLogs) { this.logs = this.logsTableData; } } generateStages() { if (this.options.type === 'CUSTOM') { let result = this.groupBy(this.updateProgressLogs.updateInfo, (obj) => obj.stage); if (this.states.length > 0) { this.states = []; //reset previous states data } this.stages.forEach((item, index) => { var element = item.name ? item.name : item; if (element in result) { let stageStatus = result[element][result[element].length - 1].status; this.states.push({ 'name': element, 'status': stageStatus }); } else { // Then take the value from the updateInfo object if (index <= 0) { this.states.push({ 'name': element, 'status': 'NOT_STARTED' }); } else { // Check if previous stage of not found element is completed then make the not found stage at position 'index' status as IN_PROGRESS else 'NOT_STARTED'. var previousStateStatus = this.states[index - 1].status; var newStatusForNotFoundStage = (previousStateStatus === 'COMPLETED' || previousStateStatus === 'SKIPPED') ? 'IN_PROGRESS' : 'NOT_STARTED'; this.states.push({ 'name': element, 'status': newStatusForNotFoundStage }); } } }); } } groupBy(array, key) { const keyFn = key instanceof Function ? key : (obj) => obj[key]; return array.reduce((objectsByKeyValue, obj) => { const value = keyFn(obj); objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj); return objectsByKeyValue; }, {}); } } NgxStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxStepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); NgxStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NgxStepComponent, selector: "ngx-step", inputs: { updateProgressLogs: "updateProgressLogs", stages: "stages", jobOverallStatus: "jobOverallStatus", options: "options", logsTableData: "logsTableData", showLogs: "showLogs", logTableOptions: "logTableOptions" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"row mt-2\" style=\"overflow: hidden !important;\" *ngIf=\"options.type === 'BASIC'\">\r\n <div class=\"col-md-12 col-sm-12 job-progress-bar p-0 bg-white\">\r\n <div class=\"track\" *ngIf=\"stages.length >0\">\r\n <div class=\"step\" [ngClass]=\"state.status\" *ngFor=\"let state of stages; let i = index\">\r\n <span class=\"icon\"> <em class=\"fas\" [ngClass]=\"{\r\n 'fa-check': state.status === 'COMPLETED',\r\n 'fa-sync fa-spin': state.status === 'IN_PROGRESS',\r\n 'fa-times': state.status === 'FAILED',\r\n 'fa-circle': state.status === 'NOT_STARTED'\r\n }\"></em> </span>\r\n <span class=\"text\" *ngIf=\"options.isMultiWordStageName\">{{state.name | formatText :\r\n options.textSeparator}}</span>\r\n <span class=\"text\" *ngIf=\"!options.isMultiWordStageName\">{{state.name}}</span>\r\n\r\n </div>\r\n <div class=\"step\">\r\n <span class=\"icon\" [ngClass]=\"{\r\n 'job-success': (jobOverallStatus === 'COMPLETED' && states[this.states.length - 1].status === 'COMPLETED' ), \r\n 'text-white': (jobOverallStatus === 'ACTIVE'),\r\n 'job-failed': (jobOverallStatus === 'FAILED')\r\n }\">\r\n <em class=\"fa fa-clipboard-check\" *ngIf=\"jobOverallStatus === 'COMPLETED'\"></em>\r\n <em class=\"fa fa-times\" *ngIf=\"jobOverallStatus === 'FAILED'\"></em>\r\n <em class=\"fa fa-clipboard-check\"\r\n *ngIf=\"jobOverallStatus === 'ACTIVE' && states[this.states.length - 1].status != 'COMPLETED' \"></em>\r\n <em class=\"fa fa-cog fa-spin text-muted\"\r\n *ngIf=\"jobOverallStatus === 'ACTIVE' && states[this.states.length - 1].status === 'COMPLETED' \"></em>\r\n </span>\r\n <span class=\"text\">\r\n {{options.finalStageName}}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row mt-2\" style=\"overflow: hidden !important;\" *ngIf=\"options.type === 'CUSTOM'\">\r\n <div class=\"col-md-12 col-sm-12 job-progress-bar p-0 bg-white\">\r\n <div class=\"track\" *ngIf=\"states.length >0\">\r\n <div class=\"step\" [ngClass]=\"state.status\" *ngFor=\"let state of states; let i = index\">\r\n <span class=\"icon\"> <em class=\"fas\" [ngClass]=\"{\r\n 'fa-check': state.status === 'COMPLETED',\r\n 'fa-sync fa-spin': state.status === 'IN_PROGRESS',\r\n 'fa-times': state.status === 'FAILED',\r\n 'fa-circle': state.status === 'NOT_STARTED',\r\n 'fa-forward': state.status === 'SKIPPED'\r\n }\"></em> </span>\r\n <span class=\"text\" *ngIf=\"options.isMultiWordStageName\">{{state.name | formatText :\r\n options.textSeparator}}</span>\r\n <span class=\"text\" *ngIf=\"!options.isMultiWordStageName\">{{state.name}}</span>\r\n </div>\r\n <div class=\"step\">\r\n <span class=\"icon\" [ngClass]=\"{\r\n 'job-success': (jobOverallStatus === 'COMPLETED'), \r\n 'text-white': (jobOverallStatus === 'ACTIVE'),\r\n 'job-failed': (jobOverallStatus === 'FAILED')\r\n }\">\r\n <em class=\"fa fa-clipboard-check\" *ngIf=\"jobOverallStatus === 'COMPLETED'\"></em>\r\n <em class=\"fa fa-times\" *ngIf=\"jobOverallStatus === 'FAILED'\"></em>\r\n <em class=\"fa fa-cog fa-spin text-muted\" *ngIf=\"jobOverallStatus === 'ACTIVE'\"></em>\r\n </span>\r\n <span class=\"text\">\r\n {{options.finalStageName}}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<!-- If user wants Logs to display -->\r\n<div class=\"row mt-2\" *ngIf=\"showLogs\">\r\n <div class=\"col-md-12\">\r\n <div class=\"shadow-none\">\r\n <div class=\"card\">\r\n <div class=\"card-header ngxHeader\">\r\n <h3 class=\"card-title ngxHeaderTitle\">{{logTableOptions.tableTitle}}</h3>\r\n </div>\r\n\r\n <div class=\"card-body p-0 ngxTable\">\r\n <table class=\"table table-striped\" *ngIf=\"logs.length > 0\">\r\n <!-- <thead>\r\n <tr>\r\n <th *ngFor=\"let heads of tableHeader; let i = index\">{{heads.display_name}}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let element of jobDetailsData.updateInfo; let i = index\">\r\n <td *ngFor=\"let heads of tableHeader; let i = index\">\r\n {{element[heads.feild_name]}}\r\n </td>\r\n </tr>\r\n </tbody> -->\r\n <thead>\r\n <tr>\r\n <th>Date/Time</th>\r\n <th>Stages</th>\r\n <th>Description</th>\r\n <th>Status</th>\r\n <th *ngIf=\"logTableOptions.showTimeDiffColumn\">Time Taken (HH:MM:SS)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let element of logs; let i = index\">\r\n <td *ngIf=\"(logTableOptions?.dateFormat) && (logTableOptions?.dateFormat !='')\">{{(element.time_stamp | customTimeConverter)| date: logTableOptions.dateFormat }}</td>\r\n <td *ngIf=\"(!logTableOptions?.dateFormat) || (logTableOptions?.dateFormat ==='')\">{{(element.time_stamp | customTimeConverter)}}</td>\r\n <td>{{element.stage | formatText : options.textSeparator}}</td>\r\n <td>\r\n {{element.message}}\r\n <p *ngIf=\"element.status == 'FAILED'\">\r\n <strong>Reason : </strong>\r\n <span class=\"text-danger\">{{element.error_message}}</span>\r\n </p>\r\n </td>\r\n <td [ngClass]=\"{\r\n 'stage_failed': element.status == 'FAILED',\r\n 'stage_completed': element.status == 'COMPLETED',\r\n 'stage_progress': element.status == 'IN_PROGRESS',\r\n 'stage_not_started': element.status == 'NOT_STARTED'}\">\r\n <em class=\"fas mr-1\" [ngClass]=\"{\r\n 'fa-check': element.status === 'COMPLETED',\r\n 'fa-sync fa-spin': element.status === 'IN_PROGRESS',\r\n 'fa-times': element.status === 'FAILED',\r\n 'fa-circle': element.status === 'NOT_STARTED',\r\n 'fa-forward': element.status === 'SKIPPED'}\">\r\n </em>\r\n {{element.status | formatText : options.textSeparator}}\r\n </td>\r\n <td *ngIf=\"logTableOptions.showTimeDiffColumn\">\r\n <ng-container *ngIf=\"!logTableOptions.manualCalculationForDuration\">\r\n <span *ngIf=\"logs[i] && logs[i+1]\">\r\n {{(logs[i].time_stamp)|customTimeCalculator:logs[i+1].time_stamp}}\r\n </span>\r\n </ng-container>\r\n <ng-container *ngIf=\"logTableOptions.manualCalculationForDuration\">\r\n {{(logs[i]?.time_taken)}}\r\n </ng-container>\r\n \r\n </td>\r\n <!-- <td *ngIf=\"logTableOptions.showTimeDiffColumn && !logTableOptions.autoCalulateDuration\">\r\n {{(logs[i]?.time_taken)}}\r\n </td> -->\r\n </tr>\r\n </tbody>\r\n </table>\r\n <div class=\"row\" *ngIf=\"logs.length == 0\">\r\n <div class=\"error-page\" *ngIf=\"dataSource && dataSource.data.length === 0\">\r\n <div class=\"error-content\">\r\n <h3><em class=\"fas fa-exclamation-triangle\"></em> No Data Found.</h3>\r\n <p> Looks like there is no logs available.</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".wd-100px{width:100px}.wd-150px{width:150px}.label-name{font-weight:500}.mr-1{margin-right:.25rem!important}.stage_completed{color:inherit}.stage_progress{color:#eab417}.stage_failed{color:#f40c48}.text-primary{color:#015a92}.text-danger{color:#f40c48}:host ::ng-deep .last-edited-step-1 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-1 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(9):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(9):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(11):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(13):before{border-top-color:#7e8a8a!important}.track{position:relative;display:flex;margin-bottom:40px;margin-top:50px}.track .step{flex-grow:1;width:25%;margin-top:-13px;text-align:center;position:relative}.track .step.active:before{background:#FF5722}.track .step:before{height:5px;position:absolute;content:\"\";width:100%;top:13px}.track .step.active .icon{background:#ee5435;color:#fff}.track .icon{display:inline-block;width:30px;height:30px;line-height:30px;position:relative;border-radius:100%;background:#ddd}.track .step.active .text{font-weight:400;color:#000}.track .text{display:block;margin-top:7px;font-size:12px}.track .step.COMPLETED:before{background:#16b587}.track .step.COMPLETED .icon{background:#16b587;color:#fff}.track .step.COMPLETED .text{font-weight:400;color:#000}.track .step.FAILED:before{background:#f40c48}.track .step.FAILED .icon{background:#f40c48;color:#fff}.track .step.FAILED .text{font-weight:400;color:#f40c48}.track .step.IN_PROGRESS:before{background:#eab417}.track .step.IN_PROGRESS .icon{background:#eab417;color:#fff}.track .step.IN_PROGRESS .text{font-weight:500;color:#000}.track .step.NOT_STARTED:before{background:#dddddd}.track .step.NOT_STARTED .icon{color:#fff}.track .step.NOT_STARTED .text{font-weight:400;color:#6c757d}.track .step.SKIPPED:before{background:#7db0239c}.track .step.SKIPPED .icon{background:#7db0239c;color:#fff}.job-success{background:#16b587!important;color:#fff}.job-failed{background:#f40c48!important;color:#fff}.removed-node{opacity:.3}.job-create{background-color:#1eb980;text-transform:uppercase}.job-delete{background-color:#f8d7da;text-transform:uppercase}.job-upgrade{background-color:#eab417;text-transform:uppercase}.job-scaleup{background-color:#015a92;text-transform:uppercase;color:#fff}.job-scale-down{background-color:#ccc;text-transform:uppercase}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }, { kind: "pipe", type: i2.StageFormatterPipe, name: "formatText" }, { kind: "pipe", type: i3.CustomTimeConverterPipe, name: "customTimeConverter" }, { kind: "pipe", type: i4.CustomTimeCalculatorPipe, name: "customTimeCalculator" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NgxStepComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-step', template: "<div class=\"row mt-2\" style=\"overflow: hidden !important;\" *ngIf=\"options.type === 'BASIC'\">\r\n <div class=\"col-md-12 col-sm-12 job-progress-bar p-0 bg-white\">\r\n <div class=\"track\" *ngIf=\"stages.length >0\">\r\n <div class=\"step\" [ngClass]=\"state.status\" *ngFor=\"let state of stages; let i = index\">\r\n <span class=\"icon\"> <em class=\"fas\" [ngClass]=\"{\r\n 'fa-check': state.status === 'COMPLETED',\r\n 'fa-sync fa-spin': state.status === 'IN_PROGRESS',\r\n 'fa-times': state.status === 'FAILED',\r\n 'fa-circle': state.status === 'NOT_STARTED'\r\n }\"></em> </span>\r\n <span class=\"text\" *ngIf=\"options.isMultiWordStageName\">{{state.name | formatText :\r\n options.textSeparator}}</span>\r\n <span class=\"text\" *ngIf=\"!options.isMultiWordStageName\">{{state.name}}</span>\r\n\r\n </div>\r\n <div class=\"step\">\r\n <span class=\"icon\" [ngClass]=\"{\r\n 'job-success': (jobOverallStatus === 'COMPLETED' && states[this.states.length - 1].status === 'COMPLETED' ), \r\n 'text-white': (jobOverallStatus === 'ACTIVE'),\r\n 'job-failed': (jobOverallStatus === 'FAILED')\r\n }\">\r\n <em class=\"fa fa-clipboard-check\" *ngIf=\"jobOverallStatus === 'COMPLETED'\"></em>\r\n <em class=\"fa fa-times\" *ngIf=\"jobOverallStatus === 'FAILED'\"></em>\r\n <em class=\"fa fa-clipboard-check\"\r\n *ngIf=\"jobOverallStatus === 'ACTIVE' && states[this.states.length - 1].status != 'COMPLETED' \"></em>\r\n <em class=\"fa fa-cog fa-spin text-muted\"\r\n *ngIf=\"jobOverallStatus === 'ACTIVE' && states[this.states.length - 1].status === 'COMPLETED' \"></em>\r\n </span>\r\n <span class=\"text\">\r\n {{options.finalStageName}}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div class=\"row mt-2\" style=\"overflow: hidden !important;\" *ngIf=\"options.type === 'CUSTOM'\">\r\n <div class=\"col-md-12 col-sm-12 job-progress-bar p-0 bg-white\">\r\n <div class=\"track\" *ngIf=\"states.length >0\">\r\n <div class=\"step\" [ngClass]=\"state.status\" *ngFor=\"let state of states; let i = index\">\r\n <span class=\"icon\"> <em class=\"fas\" [ngClass]=\"{\r\n 'fa-check': state.status === 'COMPLETED',\r\n 'fa-sync fa-spin': state.status === 'IN_PROGRESS',\r\n 'fa-times': state.status === 'FAILED',\r\n 'fa-circle': state.status === 'NOT_STARTED',\r\n 'fa-forward': state.status === 'SKIPPED'\r\n }\"></em> </span>\r\n <span class=\"text\" *ngIf=\"options.isMultiWordStageName\">{{state.name | formatText :\r\n options.textSeparator}}</span>\r\n <span class=\"text\" *ngIf=\"!options.isMultiWordStageName\">{{state.name}}</span>\r\n </div>\r\n <div class=\"step\">\r\n <span class=\"icon\" [ngClass]=\"{\r\n 'job-success': (jobOverallStatus === 'COMPLETED'), \r\n 'text-white': (jobOverallStatus === 'ACTIVE'),\r\n 'job-failed': (jobOverallStatus === 'FAILED')\r\n }\">\r\n <em class=\"fa fa-clipboard-check\" *ngIf=\"jobOverallStatus === 'COMPLETED'\"></em>\r\n <em class=\"fa fa-times\" *ngIf=\"jobOverallStatus === 'FAILED'\"></em>\r\n <em class=\"fa fa-cog fa-spin text-muted\" *ngIf=\"jobOverallStatus === 'ACTIVE'\"></em>\r\n </span>\r\n <span class=\"text\">\r\n {{options.finalStageName}}\r\n </span>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<!-- If user wants Logs to display -->\r\n<div class=\"row mt-2\" *ngIf=\"showLogs\">\r\n <div class=\"col-md-12\">\r\n <div class=\"shadow-none\">\r\n <div class=\"card\">\r\n <div class=\"card-header ngxHeader\">\r\n <h3 class=\"card-title ngxHeaderTitle\">{{logTableOptions.tableTitle}}</h3>\r\n </div>\r\n\r\n <div class=\"card-body p-0 ngxTable\">\r\n <table class=\"table table-striped\" *ngIf=\"logs.length > 0\">\r\n <!-- <thead>\r\n <tr>\r\n <th *ngFor=\"let heads of tableHeader; let i = index\">{{heads.display_name}}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let element of jobDetailsData.updateInfo; let i = index\">\r\n <td *ngFor=\"let heads of tableHeader; let i = index\">\r\n {{element[heads.feild_name]}}\r\n </td>\r\n </tr>\r\n </tbody> -->\r\n <thead>\r\n <tr>\r\n <th>Date/Time</th>\r\n <th>Stages</th>\r\n <th>Description</th>\r\n <th>Status</th>\r\n <th *ngIf=\"logTableOptions.showTimeDiffColumn\">Time Taken (HH:MM:SS)</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let element of logs; let i = index\">\r\n <td *ngIf=\"(logTableOptions?.dateFormat) && (logTableOptions?.dateFormat !='')\">{{(element.time_stamp | customTimeConverter)| date: logTableOptions.dateFormat }}</td>\r\n <td *ngIf=\"(!logTableOptions?.dateFormat) || (logTableOptions?.dateFormat ==='')\">{{(element.time_stamp | customTimeConverter)}}</td>\r\n <td>{{element.stage | formatText : options.textSeparator}}</td>\r\n <td>\r\n {{element.message}}\r\n <p *ngIf=\"element.status == 'FAILED'\">\r\n <strong>Reason : </strong>\r\n <span class=\"text-danger\">{{element.error_message}}</span>\r\n </p>\r\n </td>\r\n <td [ngClass]=\"{\r\n 'stage_failed': element.status == 'FAILED',\r\n 'stage_completed': element.status == 'COMPLETED',\r\n 'stage_progress': element.status == 'IN_PROGRESS',\r\n 'stage_not_started': element.status == 'NOT_STARTED'}\">\r\n <em class=\"fas mr-1\" [ngClass]=\"{\r\n 'fa-check': element.status === 'COMPLETED',\r\n 'fa-sync fa-spin': element.status === 'IN_PROGRESS',\r\n 'fa-times': element.status === 'FAILED',\r\n 'fa-circle': element.status === 'NOT_STARTED',\r\n 'fa-forward': element.status === 'SKIPPED'}\">\r\n </em>\r\n {{element.status | formatText : options.textSeparator}}\r\n </td>\r\n <td *ngIf=\"logTableOptions.showTimeDiffColumn\">\r\n <ng-container *ngIf=\"!logTableOptions.manualCalculationForDuration\">\r\n <span *ngIf=\"logs[i] && logs[i+1]\">\r\n {{(logs[i].time_stamp)|customTimeCalculator:logs[i+1].time_stamp}}\r\n </span>\r\n </ng-container>\r\n <ng-container *ngIf=\"logTableOptions.manualCalculationForDuration\">\r\n {{(logs[i]?.time_taken)}}\r\n </ng-container>\r\n \r\n </td>\r\n <!-- <td *ngIf=\"logTableOptions.showTimeDiffColumn && !logTableOptions.autoCalulateDuration\">\r\n {{(logs[i]?.time_taken)}}\r\n </td> -->\r\n </tr>\r\n </tbody>\r\n </table>\r\n <div class=\"row\" *ngIf=\"logs.length == 0\">\r\n <div class=\"error-page\" *ngIf=\"dataSource && dataSource.data.length === 0\">\r\n <div class=\"error-content\">\r\n <h3><em class=\"fas fa-exclamation-triangle\"></em> No Data Found.</h3>\r\n <p> Looks like there is no logs available.</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".wd-100px{width:100px}.wd-150px{width:150px}.label-name{font-weight:500}.mr-1{margin-right:.25rem!important}.stage_completed{color:inherit}.stage_progress{color:#eab417}.stage_failed{color:#f40c48}.text-primary{color:#015a92}.text-danger{color:#f40c48}:host ::ng-deep .last-edited-step-1 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-1 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-2 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-3 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):after,:host ::ng-deep .last-edited-step-4 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(9):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(1):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(3):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(5):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(7):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(9):before,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(11):after,:host ::ng-deep .last-edited-step-5 .mat-horizontal-stepper-header-container .mat-step-header:nth-child(13):before{border-top-color:#7e8a8a!important}.track{position:relative;display:flex;margin-bottom:40px;margin-top:50px}.track .step{flex-grow:1;width:25%;margin-top:-13px;text-align:center;position:relative}.track .step.active:before{background:#FF5722}.track .step:before{height:5px;position:absolute;content:\"\";width:100%;top:13px}.track .step.active .icon{background:#ee5435;color:#fff}.track .icon{display:inline-block;width:30px;height:30px;line-height:30px;position:relative;border-radius:100%;background:#ddd}.track .step.active .text{font-weight:400;color:#000}.track .text{display:block;margin-top:7px;font-size:12px}.track .step.COMPLETED:before{background:#16b587}.track .step.COMPLETED .icon{background:#16b587;color:#fff}.track .step.COMPLETED .text{font-weight:400;color:#000}.track .step.FAILED:before{background:#f40c48}.track .step.FAILED .icon{background:#f40c48;color:#fff}.track .step.FAILED .text{font-weight:400;color:#f40c48}.track .step.IN_PROGRESS:before{background:#eab417}.track .step.IN_PROGRESS .icon{background:#eab417;color:#fff}.track .step.IN_PROGRESS .text{font-weight:500;color:#000}.track .step.NOT_STARTED:before{background:#dddddd}.track .step.NOT_STARTED .icon{color:#fff}.track .step.NOT_STARTED .text{font-weight:400;color:#6c757d}.track .step.SKIPPED:before{background:#7db0239c}.track .step.SKIPPED .icon{background:#7db0239c;color:#fff}.job-success{background:#16b587!important;color:#fff}.job-failed{background:#f40c48!important;color:#fff}.removed-node{opacity:.3}.job-create{background-color:#1eb980;text-transform:uppercase}.job-delete{background-color:#f8d7da;text-transform:uppercase}.job-upgrade{background-color:#eab417;text-transform:uppercase}.job-scaleup{background-color:#015a92;text-transform:uppercase;color:#fff}.job-scale-down{background-color:#ccc;text-transform:uppercase}\n"] }] }], ctorParameters: function () { return []; }, propDecorators: { updateProgressLogs: [{ type: Input }], stages: [{ type: Input }], jobOverallStatus: [{ type: Input }], options: [{ type: Input }], logsTableData: [{ type: Input }], showLogs: [{ type: Input }], logTableOptions: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXN0ZXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXN0ZXAvc3JjL2xpYi9uZ3gtc3RlcC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3RlcC9zcmMvbGliL25neC1zdGVwLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQXNDLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFRN0YsTUFBTSxPQUFPLGdCQUFnQjtJQTJCM0I7UUExQlMsdUJBQWtCLEdBQVEsRUFBRSxDQUFFO1FBQzlCLFdBQU0sR0FBUSxDQUFDLENBQUMsRUFBQyxDQUFDLEVBQUMsQ0FBQyxFQUFDLENBQUMsRUFBQyxDQUFDLENBQUMsQ0FBQztRQUMxQixxQkFBZ0IsR0FBUSxhQUFhLENBQUMsQ0FBQywyREFBMkQ7UUFDbEcsWUFBTyxHQUFPO1lBQ3JCLElBQUksRUFBRSxPQUFPO1lBQ2IsaUJBQWlCLEVBQUUsS0FBSztZQUN4QixjQUFjLEVBQUUsUUFBUTtZQUN4QixvQkFBb0IsRUFBRyxLQUFLO1lBQzVCLGFBQWEsRUFBRSxHQUFHO1NBQ25CLENBQUM7UUFDTyxrQkFBYSxHQUFRLEVBQUUsQ0FBQztRQUN4QixhQUFRLEdBQVksS0FBSyxDQUFDO1FBRTFCLG9CQUFlLEdBQU87WUFDN0IsVUFBVSxFQUFFLGVBQWU7WUFDM0IsV0FBVyxFQUFDLENBQUMsV0FBVyxFQUFDLGVBQWUsRUFBQyxhQUFhLEVBQUMsUUFBUSxFQUFDLFlBQVksQ0FBQztZQUM3RSxpQkFBaUIsRUFBRSxLQUFLO1lBQ3hCLGtCQUFrQixFQUFFLEtBQUs7WUFDekIsNEJBQTRCLEVBQUUsS0FBSztZQUNuQyxZQUFZLEVBQUMsSUFBSTtZQUNqQixVQUFVLEVBQUUsTUFBTTtTQUNuQixDQUFDO1FBR0YsV0FBTSxHQUFRLEVBQUUsQ0FBQztRQUNqQixTQUFJLEdBQVEs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LENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNULENBQUM7OzZHQXhFVSxnQkFBZ0I7aUdBQWhCLGdCQUFnQixpU0NSN0IsMmhUQTRKTTsyRkRwSk8sZ0JBQWdCO2tCQUw1QixTQUFTOytCQUNFLFVBQVU7MEVBS1gsa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQU9HLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxlQUFlO3NCQUF2QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBPbkNoYW5nZXMsVmlld0NoaWxkLCBTaW1wbGVDaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduZ3gtc3RlcCcsXHJcbiAgdGVtcGxhdGVVcmw6ICduZ3gtc3RlcC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnbmd4LXN0ZXAuY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIE5neFN0ZXBDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xyXG4gIEBJbnB1dCgpIHVwZGF0ZVByb2dyZXNzTG9nczogYW55ID0gW10gO1xyXG4gIEBJbnB1dCgpIHN0YWdlcyA6YW55ID0gWzEsMiwzLDQsNV07XHJcbiAgQElucHV0KCkgam9iT3ZlcmFsbFN0YXR1cyA6YW55ID0gJ05PVF9TVEFSVEVEJzsgLy8gUG9zc2libGUgVmFsdWVzLSBOT1RfU1RBUlRFRCAsIEFDVElWRSwgQ09NUExFVEVELCBGQUlMRURcclxuICBASW5wdXQoKSBvcHRpb25zOmFueSA9IHtcclxuICAgIHR5cGU6ICdCQVNJQycsLy9DVVNUT00gLSB5b3UgbmVlZCB0byBnZW5lcmF0ZSBzdGFnZXMgYW5kIGl0c1xyXG4gICAgZXhjbHVkZUZpcnN0RW50cnk6IGZhbHNlLFxyXG4gICAgZmluYWxTdGFnZU5hbWU6ICdGSU5JU0gnLFxyXG4gICAgaXNNdWx0aVdvcmRTdGFnZU5hbWUgOiBmYWxzZSxcclxuICAgIHRleHRTZXBhcmF0b3I6ICdfJ1xyXG4gIH07XHJcbiAgQElucHV0KCkgbG9nc1RhYmxlRGF0YTogYW55ID0gW107XHJcbiAgQElucHV0KCkgc2hvd0xvZ3M6IEJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgbG9nVGFibGVPcHRpb25zOmFueSA9IHtcclxuICAgIHRhYmxlVGl0bGU6ICdFdmVudHMgJiBMb2dzJyxcclxuICAgIHRhYmxlSGVhZGVyOlsnRGF0ZS9UaW1lJywnRXZlbnRzL1N0YWdlcycsJ0Rlc2NyaXB0aW9uJywnU3RhdHVzJywnVGltZSBUYWtlbiddLFxyXG4gICAgZXhjbHVkZUZpcnN0RW50cnk6IGZhbHNlLFxyXG4gICAgc2hvd1RpbWVEaWZmQ29sdW1uOiBmYWxzZSxcclxuICAgIG1hbnVhbENhbGN1bGF0aW9uRm9yRHVyYXRpb246IGZhbHNlLFxyXG4gICAgYXNjU29ydE9yZGVyOnRydWUsXHJcbiAgICBkYXRlRm9ybWF0OiAnZnVsbCdcclxuICB9O1xyXG5cclxuXHJcbiAgc3RhdGVzOiBhbnkgPSBbXTtcclxuICBsb2dzOiBhbnkgPSBbXTtcclxuICBjb25zdHJ1Y3RvcigpIHsgfVxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgIHRoaXMubmdPbkluaXQoKTtcclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5nZW5lcmF0ZVN0YWdlcygpO1xyXG4gICAgaWYodGhpcy5zaG93TG9ncyl7XHJcbiAgICAgICAgdGhpcy5sb2dzID0gdGhpcy5sb2dzVGFibGVEYXRhO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2VuZXJhdGVTdGFnZXMoKXtcclxuICAgIGlmKHRoaXMub3B0aW9ucy50eXBlID09PSAnQ1VTVE9NJyl7XHJcbiAgICAgIGxldCByZXN1bHQgPSB0aGlzLmdyb3VwQnkodGhpcy51cGRhdGVQcm9ncmVzc0xvZ3MudXBkYXRlSW5mbywgKG9iajphbnkpID0+IG9iai5zdGFnZSk7XHJcbiAgICAgIGlmKHRoaXMuc3RhdGVzLmxlbmd0aCA+IDApe1xyXG4gICAgICAgIHRoaXMuc3RhdGVzID0gW107IC8vcmVzZXQgcHJldmlvdXMgc3RhdGVzIGRhdGEgXHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5zdGFnZXMuZm9yRWFjaCgoaXRlbTphbnksIGluZGV4OmFueSkgPT4ge1xyXG4gICAgICAgIHZhciBlbGVtZW50ID0gaXRlbS5uYW1lID8gaXRlbS5uYW1lIDogaXRlbSA7XHJcbiAgICAgICAgaWYoZWxlbWVudCBpbiByZXN1bHQpe1xyXG4gICAgICAgICAgbGV0IHN0YWdlU3RhdHVzID0gIHJlc3VsdFtlbGVtZW50XVtyZXN1bHRbZWxlbWVudF0ubGVuZ3RoLTFdLnN0YXR1cztcclxuICAgICAgICAgIHRoaXMuc3RhdGVzLnB1c2goeyduYW1lJzplbGVtZW50LCdzdGF0dXMnOnN0YWdlU3RhdHVzfSk7XHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAvLyBUaGVuIHRha2UgdGhlIHZhbHVlIGZyb20gdGhlIHVwZGF0ZUluZm8gb2JqZWN0XHJcbiAgICAgICAgICBpZihpbmRleCA8PSAwKXtcclxuICAgICAgICAgICAgdGhpcy5zdGF0ZXMucHVzaCh7J25hbWUnOmVsZW1lbnQsJ3N0YXR1cyc6J05PVF9TVEFSVEVEJ30pO1xyXG4gICAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHByZXZpb3VzIHN0YWdlIG9mIG5vdCBmb3VuZCBlbGVtZW50IGlzIGNvbXBsZXRlZCB0aGVuIG1ha2UgdGhlIG5vdCBmb3VuZCBzdGFnZSBhdCBwb3NpdGlvbiAnaW5kZXgnIHN0YXR1cyBhcyBJTl9QUk9HUkVTUyBlbHNlICdOT1RfU1RBUlRFRCcuXHJcbiAgICAgICAgICAgICB2YXIgcHJldmlvdXNTdGF0ZVN0YXR1cyA9IHRoaXMuc3RhdGVzW2luZGV4LTFdLnN0YXR1cztcclxuICAgICAgICAgICAgIHZhciBuZXdTdGF0dXNGb3JOb3RGb3VuZFN0YWdlID0gKHByZXZpb3VzU3RhdGVTdGF0dXMgPT09ICdDT01QTEVURUQnICB8fCBwcmV2aW91c1N0YXRlU3RhdHVzID09PSAnU0tJUFBFRCcpID8gJ0lOX1BST0dSRVNTJyA6ICdOT1RfU1RBUlRFRCc7IFxyXG4gICAgICAgICAgICAgdGhpcy5zdGF0ZXMucHVzaCh7J25hbWUnOmVsZW1lbnQsJ3N0YXR1cyc6bmV3U3RhdHVzRm9yTm90Rm91bmRTdGFnZX0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdyb3VwQnkoYXJyYXk6YW55LCBrZXk6YW55KSB7XHJcbiAgICBjb25zdCBrZXlGbiA9IGtleSBpbnN0YW5jZW9mIEZ1bmN0aW9uID8ga2V5IDogKG9iajphbnkpID0+IG9ialtrZXldO1xyXG4gICAgcmV0dXJuIGFycmF5LnJlZHVjZSgob2JqZWN0c0J5S2V5VmFsdWU6YW55LCBvYmo6YW55KSA9PiB7XHJcbiAgICAgIGNvbnN0IHZhbHVlID0ga2V5Rm4ob2JqKTtcclxuICAgICAgb2JqZWN0c0J5S2V5VmFsdWVbdmFsdWVdID0gKG9iamVjdHNCeUtleVZhbHVlW3ZhbHVlXSB8fCBbXSkuY29uY2F0KG9iaik7XHJcbiAgICAgIHJldHVybiBvYmplY3RzQnlLZXlWYWx1ZTtcclxuICAgIH0sIHt9KTtcclxuICB9XHJcblxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJyb3cgbXQtMlwiIHN0eWxlPVwib3ZlcmZsb3c6IGhpZGRlbiAhaW1wb3J0YW50O1wiICpuZ0lmPVwib3B0aW9ucy50eXBlID09PSAnQkFTSUMnXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGNvbC1zbS0xMiBqb2ItcHJvZ3Jlc3MtYmFyIHAtMCBiZy13aGl0ZVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0cmFja1wiICpuZ0lmPVwic3RhZ2VzLmxlbmd0aCA+MFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RlcFwiIFtuZ0NsYXNzXT1cInN0YXRlLnN0YXR1c1wiICpuZ0Zvcj1cImxldCBzdGF0ZSBvZiBzdGFnZXM7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvblwiPiA8ZW0gY2xhc3M9XCJmYXNcIiBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgJ2ZhLWNoZWNrJzogc3RhdGUuc3RhdHVzID09PSAnQ09NUExFVEVEJyxcclxuICAgICAgICAgICAgICAgICAgICAnZmEtc3luYyBmYS1zcGluJzogc3RhdGUuc3RhdHVzID09PSAnSU5fUFJPR1JFU1MnLFxyXG4gICAgICAgICAgICAgICAgICAgICdmYS10aW1lcyc6IHN0YXRlLnN0YXR1cyA9PT0gJ0ZBSUxFRCcsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2ZhLWNpcmNsZSc6IHN0YXRlLnN0YXR1cyA9PT0gJ05PVF9TVEFSVEVEJ1xyXG4gICAgICAgICAgICAgICAgfVwiPjwvZW0+IDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dFwiICpuZ0lmPVwib3B0aW9ucy5pc011bHRpV29yZFN0YWdlTmFtZVwiPnt7c3RhdGUubmFtZSB8IGZvcm1hdFRleHQgOlxyXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudGV4dFNlcGFyYXRvcn19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0XCIgKm5nSWY9XCIhb3B0aW9ucy5pc011bHRpV29yZFN0YWdlTmFtZVwiPnt7c3RhdGUubmFtZX19PC9zcGFuPlxyXG5cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGVwXCI+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImljb25cIiBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdqb2Itc3VjY2Vzcyc6IChqb2JPdmVyYWxsU3RhdHVzID09PSAnQ09NUExFVEVEJyAmJiBzdGF0ZXNbdGhpcy5zdGF0ZXMubGVuZ3RoIC0gMV0uc3RhdHVzID09PSAnQ09NUExFVEVEJyApLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtd2hpdGUnOiAoam9iT3ZlcmFsbFN0YXR1cyA9PT0gJ0FDVElWRScpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnam9iLWZhaWxlZCc6IChqb2JPdmVyYWxsU3RhdHVzID09PSAnRkFJTEVEJylcclxuICAgICAgICAgICAgICAgICAgICB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGVtIGNsYXNzPVwiZmEgZmEtY2xpcGJvYXJkLWNoZWNrXCIgKm5nSWY9XCJqb2JPdmVyYWxsU3RhdHVzID09PSAnQ09NUExFVEVEJ1wiPjwvZW0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGVtIGNsYXNzPVwiZmEgZmEtdGltZXNcIiAqbmdJZj1cImpvYk92ZXJhbGxTdGF0dXMgPT09ICdGQUlMRUQnXCI+PC9lbT5cclxuICAgICAgICAgICAgICAgICAgICA8ZW0gY2xhc3M9XCJmYSBmYS1jbGlwYm9hcmQtY2hlY2tcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cImpvYk92ZXJhbGxTdGF0dXMgPT09ICdBQ1RJVkUnICYmIHN0YXRlc1t0aGlzLnN0YXRlcy5sZW5ndGggLSAxXS5zdGF0dXMgIT0gJ0NPTVBMRVRFRCcgIFwiPjwvZW0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGVtIGNsYXNzPVwiZmEgZmEtY29nIGZhLXNwaW4gdGV4dC1tdXRlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiam9iT3ZlcmFsbFN0YXR1cyA9PT0gJ0FDVElWRScgJiYgc3RhdGVzW3RoaXMuc3RhdGVzLmxlbmd0aCAtIDFdLnN0YXR1cyA9PT0gJ0NPTVBMRVRFRCcgXCI+PC9lbT5cclxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dFwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7b3B0aW9ucy5maW5hbFN0YWdlTmFtZX19XHJcbiAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuPGRpdiBjbGFzcz1cInJvdyBtdC0yXCIgc3R5bGU9XCJvdmVyZmxvdzogaGlkZGVuICFpbXBvcnRhbnQ7XCIgKm5nSWY9XCJvcHRpb25zLnR5cGUgPT09ICdDVVNUT00nXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTEyIGNvbC1zbS0xMiBqb2ItcHJvZ3Jlc3MtYmFyIHAtMCBiZy13aGl0ZVwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0cmFja1wiICpuZ0lmPVwic3RhdGVzLmxlbmd0aCA+MFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RlcFwiIFtuZ0NsYXNzXT1cInN0YXRlLnN0YXR1c1wiICpuZ0Zvcj1cImxldCBzdGF0ZSBvZiBzdGF0ZXM7IGxldCBpID0gaW5kZXhcIj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvblwiPiA8ZW0gY2xhc3M9XCJmYXNcIiBbbmdDbGFzc109XCJ7XHJcbiAgICAgICAgICAgICAgICAgICAgJ2ZhLWNoZWNrJzogc3RhdGUuc3RhdHVzID09PSAnQ09NUExFVEVEJyxcclxuICAgICAgICAgICAgICAgICAgICAnZmEtc3luYyBmYS1zcGluJzogc3RhdGUuc3RhdHVzID09PSAnSU5fUFJPR1JFU1MnLFxyXG4gICAgICAgICAgICAgICAgICAgICdmYS10aW1lcyc6IHN0YXRlLnN0YXR1cyA9PT0gJ0ZBSUxFRCcsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2ZhLWNpcmNsZSc6IHN0YXRlLnN0YXR1cyA9PT0gJ05PVF9TVEFSVEVEJyxcclxuICAgICAgICAgICAgICAgICAgICAnZmEtZm9yd2FyZCc6IHN0YXRlLnN0YXR1cyA9PT0gJ1NLSVBQRUQnXHJcbiAgICAgICAgICAgICAgICB9XCI+PC9lbT4gPC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0XCIgKm5nSWY9XCJvcHRpb25zLmlzTXVsdGlXb3JkU3RhZ2VOYW1lXCI+e3tzdGF0ZS5uYW1lIHwgZm9ybWF0VGV4dCA6XHJcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy50ZXh0U2VwYXJhdG9yfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHRcIiAqbmdJZj1cIiFvcHRpb25zLmlzTXVsdGlXb3JkU3RhZ2VOYW1lXCI+e3tzdGF0ZS5uYW1lfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RlcFwiPlxyXG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uXCIgW25nQ2xhc3NdPVwie1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnam9iLXN1Y2Nlc3MnOiAoam9iT3ZlcmFsbFN0YXR1cyA9PT0gJ0NPTVBMRVRFRCcpLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3RleHQtd2hpdGUnOiAoam9iT3ZlcmFsbFN0YXR1cyA9PT0gJ0FDVElWRScpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAnam9iLWZhaWxlZCc6IChqb2JPdmVyYWxsU3RhdHVzID09PSAnRkFJTEVEJylcclxuICAgICAgICAgICAgICAgICAgICB9XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGVtIGNsYXNzPVwiZmEgZmEtY2xpcGJvYXJkLWNoZWNrXCIgKm5nSWY9XCJqb2JPdmVyYWxsU3RhdHVzID09PSAnQ09NUExFVEVEJ1wiPjwvZW0+XHJcbiAgICAgICAgICAgICAgICAgICAgPGVtIGNsYXNzPVwiZmEgZmEtdGltZXNcIiAqbmdJZj1cImpvYk92ZXJhbGxTdGF0dXMgPT09ICdGQUlMRUQnXCI+PC9lbT5cclxuICAgICAgICAgICAgICAgICAgICA8ZW0gY2xhc3M9XCJmYSBmYS1jb2cgZmEtc3BpbiB0ZXh0LW11dGVkXCIgKm5nSWY9XCJqb2JPdmVyYWxsU3RhdHVzID09PSAnQUNUSVZFJ1wiPjwvZW0+XHJcbiAgICAgICAgICAgICAgICA8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHRcIj5cclxuICAgICAgICAgICAgICAgICAgICB7e29wdGlvbnMuZmluYWxTdGFnZU5hbWV9fVxyXG4gICAgICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG48L2Rpdj5cclxuPCEtLSBJZiB1c2VyIHdhbnRzIExvZ3MgdG8gZGlzcGxheSAtLT5cclxuPGRpdiBjbGFzcz1cInJvdyBtdC0yXCIgKm5nSWY9XCJzaG93TG9nc1wiPlxyXG4gICAgPGRpdiBjbGFzcz1cImNvbC1tZC0xMlwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzaGFkb3ctbm9uZVwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZFwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIG5neEhlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxoMyBjbGFzcz1cImNhcmQtdGl0bGUgbmd4SGVhZGVyVGl0bGVcIj57e2xvZ1RhYmxlT3B0aW9ucy50YWJsZVRpdGxlfX08L2gzPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJc