@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
107 lines • 35.8 kB
JavaScript
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { set, unset, toInteger } from 'lodash';
import { gettext } from '@c8y/ngx-components';
import { ControlContainer, NgModelGroup } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
import * as i2 from "@angular/common";
import * as i3 from "@angular/forms";
import * as i4 from "ngx-bootstrap/collapse";
export class OpcuaDeviceProtocolDataReportingComponent {
constructor() {
this.onSubscriptionChange = new EventEmitter();
this.subscription = {
type: 'None'
};
this.subscriptionParameters = {
samplingRate: undefined,
deadbandType: 'None',
deadbandValue: undefined,
ranges: '',
queueSize: undefined,
dataChangeTrigger: 'Status',
discardOldest: true
};
this.cyclicReadParameters = {
rate: undefined
};
this.types = [
{ value: 'None', label: gettext('None') },
{ value: 'CyclicRead', label: gettext('Cyclic read') },
{ value: 'Subscription', label: gettext('Subscription') }
];
this.filters = [
{ value: 'None', label: gettext('None') },
{ value: 'Absolute', label: gettext('Absolute') },
{ value: 'Percent', label: gettext('Percent') }
];
this.triggers = [
{ value: 'Status', label: gettext('Status') },
{ value: 'StatusValue', label: gettext('Status/Value') },
{ value: 'StatusValueTimestamp', label: gettext('Status/Value/Timestamp') }
];
this.discard = [
{ value: true, label: gettext('oldest`data`') },
{ value: false, label: gettext('newest`data`') }
];
this.requireCyclic = false;
this.requireSubscription = false;
this.subscriptionTypeName = 'subscriptionType';
this.parseReadingInterval = $event => toInteger($event.target.value);
}
set model(_model) {
if (_model.subscriptionType) {
this.subscription = _model.subscriptionType;
if (this.subscription.type === 'CyclicRead') {
this.cyclicReadParameters = _model.subscriptionType.cyclicReadParameters;
this.requireCyclic = true;
this.requireSubscription = false;
}
if (this.subscription.type === 'Subscription') {
this.subscriptionParameters = _model.subscriptionType.subscriptionParameters;
this.requireCyclic = false;
this.requireSubscription = true;
}
if (this.subscription.type === 'None') {
this.requireCyclic = false;
this.requireSubscription = false;
}
}
this._model = _model;
this.subscriptionTypeName = 'subscriptionType' + _model.id;
}
updateModel() {
setTimeout(() => {
unset(this.subscription, 'subscriptionParameters');
unset(this.subscription, 'cyclicReadParameters');
if (this.subscription.type === 'CyclicRead') {
this.requireCyclic = true;
this.requireSubscription = false;
set(this.subscription, 'cyclicReadParameters', this.cyclicReadParameters);
}
else if (this.subscription.type === 'Subscription') {
this.requireCyclic = false;
this.requireSubscription = true;
set(this.subscription, 'subscriptionParameters', this.subscriptionParameters);
}
else if (this.subscription.type === 'None') {
this.requireCyclic = false;
this.requireSubscription = false;
}
this.onSubscriptionChange.emit(this.subscription);
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OpcuaDeviceProtocolDataReportingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: OpcuaDeviceProtocolDataReportingComponent, selector: "opcua-device-protocol-data-reporting", inputs: { model: "model", groupName: "groupName" }, outputs: { onSubscriptionChange: "onSubscriptionChange" }, ngImport: i0, template: "<c8y-form-group>\n <label translate>Mechanism</label>\n <label\n title=\"{{ mechanism.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n *ngFor=\"let mechanism of types\"\n >\n <input\n type=\"radio\"\n name=\"{{subscriptionTypeName}}\"\n [value]=\"mechanism.value\"\n [(ngModel)]=\"subscription.type\"\n (change)=\"updateModel()\"\n required\n [attr.data-cy]=\"mechanism.value\"\n />\n <span></span>\n <span>{{ mechanism.label | translate }}</span>\n </label>\n</c8y-form-group>\n\n<div class=\"row collapse\" [collapse]=\"subscription.type != 'CyclicRead'\" [isAnimated]=\"true\">\n <div class=\"col-sm-6 col-md-4 col-lg-3\">\n <c8y-form-group>\n <label translate>Reading interval</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"rate\"\n [(ngModel)]=\"cyclicReadParameters.rate\"\n placeholder=\"{{ 'e.g.' | translate }} 50\"\n [required]=\"requireCyclic\"\n min=\"50\"\n [attr.data-cy]=\"'cyclicReadRate'\"\n />\n <span class=\"input-group-addon units\" title=\"{{ 'Milliseconds' | translate }}\">\n {{ 'msec' | translate }}\n </span>\n </div>\n </c8y-form-group>\n </div>\n</div>\n\n<div class=\"row collapse\" [collapse]=\"subscription.type != 'Subscription'\" [isAnimated]=\"true\">\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Sampling interval</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"samplingRate\"\n [(ngModel)]=\"subscriptionParameters.samplingRate\"\n placeholder=\"{{ 'e.g.' | translate }} 500\"\n [required]=\"requireSubscription\"\n min=\"0\"\n [attr.data-cy]=\"'subscriptionSamplingRate'\"\n />\n <span class=\"input-group-addon units\" title=\"{{ 'Milliseconds' | translate }}\" translate>\n msec\n </span>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Queue size</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"queueSize\"\n [(ngModel)]=\"subscriptionParameters.queueSize\"\n placeholder=\"{{ 'e.g.' | translate }} 10\"\n min=\"1\"\n [attr.data-cy]=\"'subscriptionQueueSize'\"\n />\n <span class=\"input-group-addon\">\n <strong translate>Discard</strong> \n <label\n *ngFor=\"let discardOption of discard\"\n title=\"{{ discardOption.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"discard{{ _model.id }}\"\n [value]=\"discardOption.value\"\n [(ngModel)]=\"subscriptionParameters.discardOldest\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"discardOption.label\"\n [attr.data-name]=\"'discard' + _model.id\"\n />\n <span></span>\n <span>{{ discardOption.label | translate }}</span>\n </label>\n </span>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"clearfix\"></div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Data change trigger</label>\n <label\n *ngFor=\"let trigger of triggers\"\n title=\"{{ trigger.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"dataChangeTrigger{{ _model.id }}\"\n [value]=\"trigger.value\"\n [(ngModel)]=\"subscriptionParameters.dataChangeTrigger\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"trigger.label\"\n [attr.data-name]=\"'dataChangeTrigger' + _model.id\"\n />\n <span></span>\n <span>{{ trigger.label | translate }}</span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Deadband filter</label>\n <label\n *ngFor=\"let deadbandFilter of filters\"\n title=\"{{ deadbandFilter.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"deadbandType{{ _model.id }}\"\n [value]=\"deadbandFilter.value\"\n [(ngModel)]=\"subscriptionParameters.deadbandType\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"deadbandFilter.label\"\n [attr.data-name]=\"'deadbandType' + _model.id\"\n />\n <span></span>\n <span>{{ deadbandFilter.label | translate }}</span>\n </label>\n </c8y-form-group>\n <div [collapse]=\"subscriptionParameters.deadbandType == 'None'\" [isAnimated]=\"true\">\n <c8y-form-group>\n <label translate>Deadband value</label>\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"deadbandValue\"\n [(ngModel)]=\"subscriptionParameters.deadbandValue\"\n placeholder=\"{{ 'e.g.' | translate }} 10\"\n [required]=\"subscriptionParameters.deadbandType != 'None'\"\n min=\"0\"\n [attr.data-cy]=\"'deadbandValue'\"\n />\n </c8y-form-group>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.MinValidationDirective, selector: "[min]", inputs: ["min"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i4.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgModelGroup }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: OpcuaDeviceProtocolDataReportingComponent, decorators: [{
type: Component,
args: [{ selector: 'opcua-device-protocol-data-reporting', viewProviders: [{ provide: ControlContainer, useExisting: NgModelGroup }], template: "<c8y-form-group>\n <label translate>Mechanism</label>\n <label\n title=\"{{ mechanism.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n *ngFor=\"let mechanism of types\"\n >\n <input\n type=\"radio\"\n name=\"{{subscriptionTypeName}}\"\n [value]=\"mechanism.value\"\n [(ngModel)]=\"subscription.type\"\n (change)=\"updateModel()\"\n required\n [attr.data-cy]=\"mechanism.value\"\n />\n <span></span>\n <span>{{ mechanism.label | translate }}</span>\n </label>\n</c8y-form-group>\n\n<div class=\"row collapse\" [collapse]=\"subscription.type != 'CyclicRead'\" [isAnimated]=\"true\">\n <div class=\"col-sm-6 col-md-4 col-lg-3\">\n <c8y-form-group>\n <label translate>Reading interval</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"rate\"\n [(ngModel)]=\"cyclicReadParameters.rate\"\n placeholder=\"{{ 'e.g.' | translate }} 50\"\n [required]=\"requireCyclic\"\n min=\"50\"\n [attr.data-cy]=\"'cyclicReadRate'\"\n />\n <span class=\"input-group-addon units\" title=\"{{ 'Milliseconds' | translate }}\">\n {{ 'msec' | translate }}\n </span>\n </div>\n </c8y-form-group>\n </div>\n</div>\n\n<div class=\"row collapse\" [collapse]=\"subscription.type != 'Subscription'\" [isAnimated]=\"true\">\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Sampling interval</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"samplingRate\"\n [(ngModel)]=\"subscriptionParameters.samplingRate\"\n placeholder=\"{{ 'e.g.' | translate }} 500\"\n [required]=\"requireSubscription\"\n min=\"0\"\n [attr.data-cy]=\"'subscriptionSamplingRate'\"\n />\n <span class=\"input-group-addon units\" title=\"{{ 'Milliseconds' | translate }}\" translate>\n msec\n </span>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Queue size</label>\n <div class=\"input-group\">\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"queueSize\"\n [(ngModel)]=\"subscriptionParameters.queueSize\"\n placeholder=\"{{ 'e.g.' | translate }} 10\"\n min=\"1\"\n [attr.data-cy]=\"'subscriptionQueueSize'\"\n />\n <span class=\"input-group-addon\">\n <strong translate>Discard</strong> \n <label\n *ngFor=\"let discardOption of discard\"\n title=\"{{ discardOption.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"discard{{ _model.id }}\"\n [value]=\"discardOption.value\"\n [(ngModel)]=\"subscriptionParameters.discardOldest\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"discardOption.label\"\n [attr.data-name]=\"'discard' + _model.id\"\n />\n <span></span>\n <span>{{ discardOption.label | translate }}</span>\n </label>\n </span>\n </div>\n </c8y-form-group>\n </div>\n <div class=\"clearfix\"></div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Data change trigger</label>\n <label\n *ngFor=\"let trigger of triggers\"\n title=\"{{ trigger.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"dataChangeTrigger{{ _model.id }}\"\n [value]=\"trigger.value\"\n [(ngModel)]=\"subscriptionParameters.dataChangeTrigger\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"trigger.label\"\n [attr.data-name]=\"'dataChangeTrigger' + _model.id\"\n />\n <span></span>\n <span>{{ trigger.label | translate }}</span>\n </label>\n </c8y-form-group>\n </div>\n <div class=\"col-sm-6 col-lg-4\">\n <c8y-form-group>\n <label translate>Deadband filter</label>\n <label\n *ngFor=\"let deadbandFilter of filters\"\n title=\"{{ deadbandFilter.label | translate }}\"\n class=\"c8y-radio radio-inline\"\n >\n <input\n type=\"radio\"\n name=\"deadbandType{{ _model.id }}\"\n [value]=\"deadbandFilter.value\"\n [(ngModel)]=\"subscriptionParameters.deadbandType\"\n [required]=\"requireSubscription\"\n [attr.data-cy]=\"deadbandFilter.label\"\n [attr.data-name]=\"'deadbandType' + _model.id\"\n />\n <span></span>\n <span>{{ deadbandFilter.label | translate }}</span>\n </label>\n </c8y-form-group>\n <div [collapse]=\"subscriptionParameters.deadbandType == 'None'\" [isAnimated]=\"true\">\n <c8y-form-group>\n <label translate>Deadband value</label>\n <input\n class=\"form-control\"\n type=\"number\"\n name=\"deadbandValue\"\n [(ngModel)]=\"subscriptionParameters.deadbandValue\"\n placeholder=\"{{ 'e.g.' | translate }} 10\"\n [required]=\"subscriptionParameters.deadbandType != 'None'\"\n min=\"0\"\n [attr.data-cy]=\"'deadbandValue'\"\n />\n </c8y-form-group>\n </div>\n </div>\n</div>\n" }]
}], propDecorators: { model: [{
type: Input
}], groupName: [{
type: Input
}], onSubscriptionChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BjdWEtZGV2aWNlLXByb3RvY29sLWRhdGEtcmVwb3J0aW5nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb3RvY29sLW9wY3VhL29wY3VhLWRldmljZS1wcm90b2NvbC1kYXRhLXJlcG9ydGluZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9wcm90b2NvbC1vcGN1YS9vcGN1YS1kZXZpY2UtcHJvdG9jb2wtZGF0YS1yZXBvcnRpbmcuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUMvQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7QUFPaEUsTUFBTSxPQUFPLHlDQUF5QztJQUx0RDtRQWdDWSx5QkFBb0IsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUU1RSxpQkFBWSxHQUFHO1lBQ2IsSUFBSSxFQUFFLE1BQU07U0FDYixDQUFDO1FBQ0YsMkJBQXNCLEdBQUc7WUFDdkIsWUFBWSxFQUFFLFNBQVM7WUFDdkIsWUFBWSxFQUFFLE1BQU07WUFDcEIsYUFBYSxFQUFFLFNBQVM7WUFDeEIsTUFBTSxFQUFFLEVBQUU7WUFDVixTQUFTLEVBQUUsU0FBUztZQUNwQixpQkFBaUIsRUFBRSxRQUFRO1lBQzNCLGFBQWEsRUFBRSxJQUFJO1NBQ3BCLENBQUM7UUFFRix5QkFBb0IsR0FBRztZQUNyQixJQUFJLEVBQUUsU0FBUztTQUNoQixDQUFDO1FBRUYsVUFBSyxHQUFVO1lBQ2IsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFP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QUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxDQUFDOzhCQUc1RCxLQUFLO3NCQUFqQixLQUFLO2dCQXVCRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdJLG9CQUFvQjtzQkFBN0IsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBzZXQsIHVuc2V0LCB0b0ludGVnZXIgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQ29udHJvbENvbnRhaW5lciwgTmdNb2RlbEdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvcGN1YS1kZXZpY2UtcHJvdG9jb2wtZGF0YS1yZXBvcnRpbmcnLFxuICB0ZW1wbGF0ZVVybDogJy4vb3BjdWEtZGV2aWNlLXByb3RvY29sLWRhdGEtcmVwb3J0aW5nLmh0bWwnLFxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogTmdNb2RlbEdyb3VwIH1dXG59KVxuZXhwb3J0IGNsYXNzIE9wY3VhRGV2aWNlUHJvdG9jb2xEYXRhUmVwb3J0aW5nQ29tcG9uZW50IHtcbiAgQElucHV0KCkgc2V0IG1vZGVsKF9tb2RlbCkge1xuICAgIGlmIChfbW9kZWwuc3Vic2NyaXB0aW9uVHlwZSkge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb24gPSBfbW9kZWwuc3Vic2NyaXB0aW9uVHlwZTtcbiAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbi50eXBlID09PSAnQ3ljbGljUmVhZCcpIHtcbiAgICAgICAgdGhpcy5jeWNsaWNSZWFkUGFyYW1ldGVycyA9IF9tb2RlbC5zdWJzY3JpcHRpb25UeXBlLmN5Y2xpY1JlYWRQYXJhbWV0ZXJzO1xuICAgICAgICB0aGlzLnJlcXVpcmVDeWNsaWMgPSB0cnVlO1xuICAgICAgICB0aGlzLnJlcXVpcmVTdWJzY3JpcHRpb24gPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3Vic2NyaXB0aW9uLnR5cGUgPT09ICdTdWJzY3JpcHRpb24nKSB7XG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uUGFyYW1ldGVycyA9IF9tb2RlbC5zdWJzY3JpcHRpb25UeXBlLnN1YnNjcmlwdGlvblBhcmFtZXRlcnM7XG4gICAgICAgIHRoaXMucmVxdWlyZUN5Y2xpYyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlcXVpcmVTdWJzY3JpcHRpb24gPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb24udHlwZSA9PT0gJ05vbmUnKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZUN5Y2xpYyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlcXVpcmVTdWJzY3JpcHRpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fbW9kZWwgPSBfbW9kZWw7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25UeXBlTmFtZSA9ICdzdWJzY3JpcHRpb25UeXBlJyArIF9tb2RlbC5pZDtcbiAgfVxuICBASW5wdXQoKSBncm91cE5hbWU7XG5cbiAgX21vZGVsOiBvYmplY3Q7XG4gIEBPdXRwdXQoKSBvblN1YnNjcmlwdGlvbkNoYW5nZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBzdWJzY3JpcHRpb24gPSB7XG4gICAgdHlwZTogJ05vbmUnXG4gIH07XG4gIHN1YnNjcmlwdGlvblBhcmFtZXRlcnMgPSB7XG4gICAgc2FtcGxpbmdSYXRlOiB1bmRlZmluZWQsXG4gICAgZGVhZGJhbmRUeXBlOiAnTm9uZScsXG4gICAgZGVhZGJhbmRWYWx1ZTogdW5kZWZpbmVkLFxuICAgIHJhbmdlczogJycsXG4gICAgcXVldWVTaXplOiB1bmRlZmluZWQsXG4gICAgZGF0YUNoYW5nZVRyaWdnZXI6ICdTdGF0dXMnLFxuICAgIGRpc2NhcmRPbGRlc3Q6IHRydWVcbiAgfTtcblxuICBjeWNsaWNSZWFkUGFyYW1ldGVycyA9IHtcbiAgICByYXRlOiB1bmRlZmluZWRcbiAgfTtcblxuICB0eXBlczogYW55W10gPSBbXG4gICAgeyB2YWx1ZTogJ05vbmUnLCBsYWJlbDogZ2V0dGV4dCgnTm9uZScpIH0sXG4gICAgeyB2YWx1ZTogJ0N5Y2xpY1JlYWQnLCBsYWJlbDogZ2V0dGV4dCgnQ3ljbGljIHJlYWQnKSB9LFxuICAgIHsgdmFsdWU6ICdTdWJzY3JpcHRpb24nLCBsYWJlbDogZ2V0dGV4dCgnU3Vic2NyaXB0aW9uJykgfVxuICBdO1xuXG4gIGZpbHRlcnM6IGFueVtdID0gW1xuICAgIHsgdmFsdWU6ICdOb25lJywgbGFiZWw6IGdldHRleHQoJ05vbmUnKSB9LFxuICAgIHsgdmFsdWU6ICdBYnNvbHV0ZScsIGxhYmVsOiBnZXR0ZXh0KCdBYnNvbHV0ZScpIH0sXG4gICAgeyB2YWx1ZTogJ1BlcmNlbnQnLCBsYWJlbDogZ2V0dGV4dCgnUGVyY2VudCcpIH1cbiAgXTtcblxuICB0cmlnZ2VyczogYW55W10gPSBbXG4gICAgeyB2YWx1ZTogJ1N0YXR1cycsIGxhYmVsOiBnZXR0ZXh0KCdTdGF0dXMnKSB9LFxuICAgIHsgdmFsdWU6ICdTdGF0dXNWYWx1ZScsIGxhYmVsOiBnZXR0ZXh0KCdTdGF0dXMvVmFsdWUnKSB9LFxuICAgIHsgdmFsdWU6ICdTdGF0dXNWYWx1ZVRpbWVzdGFtcCcsIGxhYmVsOiBnZXR0ZXh0KCdTdGF0dXMvVmFsdWUvVGltZXN0YW1wJykgfVxuICBdO1xuXG4gIGRpc2NhcmQ6IGFueVtdID0gW1xuICAgIHsgdmFsdWU6IHRydWUsIGxhYmVsOiBnZXR0ZXh0KCdvbGRlc3RgZGF0YWAnKSB9LFxuICAgIHsgdmFsdWU6IGZhbHNlLCBsYWJlbDogZ2V0dGV4dCgnbmV3ZXN0YGRhdGFgJykgfVxuICBdO1xuXG4gIHJlcXVpcmVDeWNsaWMgPSBmYWxzZTtcbiAgcmVxdWlyZVN1YnNjcmlwdGlvbiA9IGZhbHNlO1xuICBzdWJzY3JpcHRpb25UeXBlTmFtZSA9ICdzdWJzY3JpcHRpb25UeXBlJztcblxuICBwYXJzZVJlYWRpbmdJbnRlcnZhbCA9ICRldmVudCA9PiB0b0ludGVnZXIoJGV2ZW50LnRhcmdldC52YWx1ZSk7XG5cbiAgdXBkYXRlTW9kZWwoKSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB1bnNldCh0aGlzLnN1YnNjcmlwdGlvbiwgJ3N1YnNjcmlwdGlvblBhcmFtZXRlcnMnKTtcbiAgICAgIHVuc2V0KHRoaXMuc3Vic2NyaXB0aW9uLCAnY3ljbGljUmVhZFBhcmFtZXRlcnMnKTtcbiAgICAgIGlmICh0aGlzLnN1YnNjcmlwdGlvbi50eXBlID09PSAnQ3ljbGljUmVhZCcpIHtcbiAgICAgICAgdGhpcy5yZXF1aXJlQ3ljbGljID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5yZXF1aXJlU3Vic2NyaXB0aW9uID0gZmFsc2U7XG4gICAgICAgIHNldCh0aGlzLnN1YnNjcmlwdGlvbiwgJ2N5Y2xpY1JlYWRQYXJhbWV0ZXJzJywgdGhpcy5jeWNsaWNSZWFkUGFyYW1ldGVycyk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuc3Vic2NyaXB0aW9uLnR5cGUgPT09ICdTdWJzY3JpcHRpb24nKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZUN5Y2xpYyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlcXVpcmVTdWJzY3JpcHRpb24gPSB0cnVlO1xuICAgICAgICBzZXQodGhpcy5zdWJzY3JpcHRpb24sICdzdWJzY3JpcHRpb25QYXJhbWV0ZXJzJywgdGhpcy5zdWJzY3JpcHRpb25QYXJhbWV0ZXJzKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdWJzY3JpcHRpb24udHlwZSA9PT0gJ05vbmUnKSB7XG4gICAgICAgIHRoaXMucmVxdWlyZUN5Y2xpYyA9IGZhbHNlO1xuICAgICAgICB0aGlzLnJlcXVpcmVTdWJzY3JpcHRpb24gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMub25TdWJzY3JpcHRpb25DaGFuZ2UuZW1pdCh0aGlzLnN1YnNjcmlwdGlvbik7XG4gICAgfSk7XG4gIH1cbn1cbiIsIjxjOHktZm9ybS1ncm91cD5cbiAgPGxhYmVsIHRyYW5zbGF0ZT5NZWNoYW5pc208L2xhYmVsPlxuICA8bGFiZWxcbiAgICB0aXRsZT1cInt7IG1lY2hhbmlzbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgY2xhc3M9XCJjOHktcmFkaW8gcmFkaW8taW5saW5lXCJcbiAgICAqbmdGb3I9XCJsZXQgbWVjaGFuaXNtIG9mIHR5cGVzXCJcbiAgPlxuICAgIDxpbnB1dFxuICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgIG5hbWU9XCJ7e3N1YnNjcmlwdGlvblR5cGVOYW1lfX1cIlxuICAgICAgW3ZhbHVlXT1cIm1lY2hhbmlzbS52YWx1ZVwiXG4gICAgICBbKG5nTW9kZWwpXT1cInN1YnNjcmlwdGlvbi50eXBlXCJcbiAgICAgIChjaGFuZ2UpPVwidXBkYXRlTW9kZWwoKVwiXG4gICAgICByZXF1aXJlZFxuICAgICAgW2F0dHIuZGF0YS1jeV09XCJtZWNoYW5pc20udmFsdWVcIlxuICAgIC8+XG4gICAgPHNwYW4+PC9zcGFuPlxuICAgIDxzcGFuPnt7IG1lY2hhbmlzbS5sYWJlbCB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgPC9sYWJlbD5cbjwvYzh5LWZvcm0tZ3JvdXA+XG5cbjxkaXYgY2xhc3M9XCJyb3cgY29sbGFwc2VcIiBbY29sbGFwc2VdPVwic3Vic2NyaXB0aW9uLnR5cGUgIT0gJ0N5Y2xpY1JlYWQnXCIgW2lzQW5pbWF0ZWRdPVwidHJ1ZVwiPlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTYgY29sLW1kLTQgY29sLWxnLTNcIj5cbiAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8bGFiZWwgdHJhbnNsYXRlPlJlYWRpbmcgaW50ZXJ2YWw8L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICBuYW1lPVwicmF0ZVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJjeWNsaWNSZWFkUGFyYW1ldGVycy5yYXRlXCJcbiAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7ICdlLmcuJyB8IHRyYW5zbGF0ZSB9fSA1MFwiXG4gICAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVDeWNsaWNcIlxuICAgICAgICAgIG1pbj1cIjUwXCJcbiAgICAgICAgICBbYXR0ci5kYXRhLWN5XT1cIidjeWNsaWNSZWFkUmF0ZSdcIlxuICAgICAgICAvPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLWFkZG9uIHVuaXRzXCIgdGl0bGU9XCJ7eyAnTWlsbGlzZWNvbmRzJyB8IHRyYW5zbGF0ZSB9fVwiPlxuICAgICAgICAgIHt7ICdtc2VjJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwicm93IGNvbGxhcHNlXCIgW2NvbGxhcHNlXT1cInN1YnNjcmlwdGlvbi50eXBlICE9ICdTdWJzY3JpcHRpb24nXCIgW2lzQW5pbWF0ZWRdPVwidHJ1ZVwiPlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTYgY29sLWxnLTRcIj5cbiAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8bGFiZWwgdHJhbnNsYXRlPlNhbXBsaW5nIGludGVydmFsPC9sYWJlbD5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgdHlwZT1cIm51bWJlclwiXG4gICAgICAgICAgbmFtZT1cInNhbXBsaW5nUmF0ZVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzdWJzY3JpcHRpb25QYXJhbWV0ZXJzLnNhbXBsaW5nUmF0ZVwiXG4gICAgICAgICAgcGxhY2Vob2xkZXI9XCJ7eyAnZS5nLicgfCB0cmFuc2xhdGUgfX0gNTAwXCJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZVN1YnNjcmlwdGlvblwiXG4gICAgICAgICAgbWluPVwiMFwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1jeV09XCInc3Vic2NyaXB0aW9uU2FtcGxpbmdSYXRlJ1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtYWRkb24gdW5pdHNcIiB0aXRsZT1cInt7ICdNaWxsaXNlY29uZHMnIHwgdHJhbnNsYXRlIH19XCIgdHJhbnNsYXRlPlxuICAgICAgICAgIG1zZWNcbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9jOHktZm9ybS1ncm91cD5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbGctNFwiPlxuICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgIDxsYWJlbCB0cmFuc2xhdGU+UXVldWUgc2l6ZTwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgIG5hbWU9XCJxdWV1ZVNpemVcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwic3Vic2NyaXB0aW9uUGFyYW1ldGVycy5xdWV1ZVNpemVcIlxuICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ2UuZy4nIHwgdHJhbnNsYXRlIH19IDEwXCJcbiAgICAgICAgICBtaW49XCIxXCJcbiAgICAgICAgICBbYXR0ci5kYXRhLWN5XT1cIidzdWJzY3JpcHRpb25RdWV1ZVNpemUnXCJcbiAgICAgICAgLz5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC1hZGRvblwiPlxuICAgICAgICAgIDxzdHJvbmcgdHJhbnNsYXRlPkRpc2NhcmQ8L3N0cm9uZz4mbmJzcDtcbiAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBkaXNjYXJkT3B0aW9uIG9mIGRpc2NhcmRcIlxuICAgICAgICAgICAgdGl0bGU9XCJ7eyBkaXNjYXJkT3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgIGNsYXNzPVwiYzh5LXJhZGlvIHJhZGlvLWlubGluZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIHR5cGU9XCJyYWRpb1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJkaXNjYXJke3sgX21vZGVsLmlkIH19XCJcbiAgICAgICAgICAgICAgW3ZhbHVlXT1cImRpc2NhcmRPcHRpb24udmFsdWVcIlxuICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInN1YnNjcmlwdGlvblBhcmFtZXRlcnMuZGlzY2FyZE9sZGVzdFwiXG4gICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJyZXF1aXJlU3Vic2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1jeV09XCJkaXNjYXJkT3B0aW9uLmxhYmVsXCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1uYW1lXT1cIidkaXNjYXJkJyArIF9tb2RlbC5pZFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPHNwYW4+PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4+e3sgZGlzY2FyZE9wdGlvbi5sYWJlbCB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImNsZWFyZml4XCI+PC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjb2wtc20tNiBjb2wtbGctNFwiPlxuICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgIDxsYWJlbCB0cmFuc2xhdGU+RGF0YSBjaGFuZ2UgdHJpZ2dlcjwvbGFiZWw+XG4gICAgICA8bGFiZWxcbiAgICAgICAgKm5nRm9yPVwibGV0IHRyaWdnZXIgb2YgdHJpZ2dlcnNcIlxuICAgICAgICB0aXRsZT1cInt7IHRyaWdnZXIubGFiZWwgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICBjbGFzcz1cImM4eS1yYWRpbyByYWRpby1pbmxpbmVcIlxuICAgICAgPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICB0eXBlPVwicmFkaW9cIlxuICAgICAgICAgIG5hbWU9XCJkYXRhQ2hhbmdlVHJpZ2dlcnt7IF9tb2RlbC5pZCB9fVwiXG4gICAgICAgICAgW3ZhbHVlXT1cInRyaWdnZXIudmFsdWVcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwic3Vic2NyaXB0aW9uUGFyYW1ldGVycy5kYXRhQ2hhbmdlVHJpZ2dlclwiXG4gICAgICAgICAgW3JlcXVpcmVkXT1cInJlcXVpcmVTdWJzY3JpcHRpb25cIlxuICAgICAgICAgIFthdHRyLmRhdGEtY3ldPVwidHJpZ2dlci5sYWJlbFwiXG4gICAgICAgICAgW2F0dHIuZGF0YS1uYW1lXT1cIidkYXRhQ2hhbmdlVHJpZ2dlcicgKyBfbW9kZWwuaWRcIlxuICAgICAgICAvPlxuICAgICAgICA8c3Bhbj48L3NwYW4+XG4gICAgICAgIDxzcGFuPnt7IHRyaWdnZXIubGFiZWwgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICA8L2xhYmVsPlxuICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTYgY29sLWxnLTRcIj5cbiAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8bGFiZWwgdHJhbnNsYXRlPkRlYWRiYW5kIGZpbHRlcjwvbGFiZWw+XG4gICAgICA8bGFiZWxcbiAgICAgICAgKm5nRm9yPVwibGV0IGRlYWRiYW5kRmlsdGVyIG9mIGZpbHRlcnNcIlxuICAgICAgICB0aXRsZT1cInt7IGRlYWRiYW5kRmlsdGVyLmxhYmVsIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgY2xhc3M9XCJjOHktcmFkaW8gcmFkaW8taW5saW5lXCJcbiAgICAgID5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICBuYW1lPVwiZGVhZGJhbmRUeXBle3sgX21vZGVsLmlkIH19XCJcbiAgICAgICAgICBbdmFsdWVdPVwiZGVhZGJhbmRGaWx0ZXIudmFsdWVcIlxuICAgICAgICAgIFsobmdNb2RlbCldPVwic3Vic2NyaXB0aW9uUGFyYW1ldGVycy5kZWFkYmFuZFR5cGVcIlxuICAgICAgICAgIFtyZXF1aXJlZF09XCJyZXF1aXJlU3Vic2NyaXB0aW9uXCJcbiAgICAgICAgICBbYXR0ci5kYXRhLWN5XT1cImRlYWRiYW5kRmlsdGVyLmxhYmVsXCJcbiAgICAgICAgICBbYXR0ci5kYXRhLW5hbWVdPVwiJ2RlYWRiYW5kVHlwZScgKyBfbW9kZWwuaWRcIlxuICAgICAgICAvPlxuICAgICAgICA8c3Bhbj48L3NwYW4+XG4gICAgICAgIDxzcGFuPnt7IGRlYWRiYW5kRmlsdGVyLmxhYmVsIHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgPC9sYWJlbD5cbiAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgIDxkaXYgW2NvbGxhcHNlXT1cInN1YnNjcmlwdGlvblBhcmFtZXRlcnMuZGVhZGJhbmRUeXBlID09ICdOb25lJ1wiIFtpc0FuaW1hdGVkXT1cInRydWVcIj5cbiAgICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgICAgPGxhYmVsIHRyYW5zbGF0ZT5EZWFkYmFuZCB2YWx1ZTwvbGFiZWw+XG4gICAgICAgIDxpbnB1dFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICBuYW1lPVwiZGVhZGJhbmRWYWx1ZVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJzdWJzY3JpcHRpb25QYXJhbWV0ZXJzLmRlYWRiYW5kVmFsdWVcIlxuICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ2UuZy4nIHwgdHJhbnNsYXRlIH19IDEwXCJcbiAgICAgICAgICBbcmVxdWlyZWRdPVwic3Vic2NyaXB0aW9uUGFyYW1ldGVycy5kZWFkYmFuZFR5cGUgIT0gJ05vbmUnXCJcbiAgICAgICAgICBtaW49XCIwXCJcbiAgICAgICAgICBbYXR0ci5kYXRhLWN5XT1cIidkZWFkYmFuZFZhbHVlJ1wiXG4gICAgICAgIC8+XG4gICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19