UNPKG

@iotize/ionic

Version:

Iotize specific building blocks on top of @ionic/angular.

161 lines 29.7 kB
import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; import { getAbstractVariableOrError, LibError } from '@iotize/ionic'; import { AbstractVariable, TapVariable } from '@iotize/tap/data'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "@angular/common"; import * as i3 from "@ionic/angular"; import * as i4 from "../monitoring-variable-value/monitoring-variable-value.component"; import * as i5 from "../tap-variable-range/tap-variable-range.component"; import * as i6 from "../tap-variable-buttons/tap-variable-buttons.component"; import * as i7 from "../tap-variable-toggle/tap-variable-toggle.component"; import * as i8 from "../tap-variable-select/tap-variable-select.component"; export class VariableCardComponent { router; waitForSubmit = false; cardType = 'text'; cardTypes = [ // 'chart', 'gauge', 'switch', 'text', 'buttons', 'range', 'select', ]; editMode = false; monitor = true; showStartStopMonitoring = false; unit = ''; bundleName = '...'; error; value = 'Unknown'; refreshValues = false; monitoringButtons = [0, 1, 2, 3, 4, 5].map((v) => { return { label: `${v}`, value: v, }; }); selectOptions = [0, 1, 2, 3, 4, 5].map((v) => { return { key: v, text: `Value ${v}`, }; }); _variable; _subscription; // private _switchButtonSubscription?: Subscription; set variable(variable) { // console.log('VariableCardComponent', 'SET VARIABLE', variable); this._variable = variable; if (this._subscription) { this._subscription.unsubscribe(); } this._subscription = variable.values.subscribe({ next: (value) => { if (this.refreshValues) { this.value = value; } }, error: (error) => { // console.warn(`Monitoring error: `, error); this.error = error; }, complete: () => { // console.warn('VariableCardComponent', 'values observable is complete') }, }); } get variable() { return getAbstractVariableOrError(this._variable); } constructor(router) { this.router = router; } get variableConfig() { if (this._variable instanceof TapVariable) { return this._variable.context.config; } return undefined; } // editConfig() { // this.router.navigate(['/device/monitoring/add']); // } async switchButtonToggleAction(checked) { if (!this._variable) { throw LibError.componentArgumentRequired('VariableCardComponent', 'variable'); } const value = checked ? 1 : 0; await this._variable.write(value); // .catch((error) => { // console.warn(`Cannot write ${this._variable.identifier()}: ${error}`) // this.error = error; // }) } // onEditEvent(event: MonitoringEditTextEvent) { // console.log('EDIT EVENT => ', event); // switch (event.type) { // case 'CLOSE': // this.editMode = false; // break; // case 'WRITE_SUCCESS': // this.editMode = false; // break; // } // } ngOnDestroy() { if (this._subscription) { this._subscription.unsubscribe(); } // if (this._switchButtonSubscription) { // this._switchButtonSubscription.unsubscribe(); // } } onCardTypeChange($event) { // console.log('onCardTypeChange', $event); // this.cardType = $event.detail.value; } toggleMonitoring() { // if (this.monitor) { // if (!this._variable) { // throw LibError.componentArgumentRequired('VariableCardComponent', 'variable'); // } this.refreshValues = !this.refreshValues; // if (this.refreshValues) { // // console.log('Start monitoring with period: ', this.monitoringPeriod); // this._variable.monitor().start({ // forceChange: false, // period: this.monitoringPeriod // }); // } else { // // console.log('Pause monitoring'); // this._variable.monitor().pause(); // } // } } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VariableCardComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: VariableCardComponent, selector: "app-variable-card", inputs: { cardType: "cardType", cardTypes: "cardTypes", editMode: "editMode", monitor: "monitor", showStartStopMonitoring: "showStartStopMonitoring", unit: "unit", bundleName: "bundleName", variable: "variable" }, ngImport: i0, template: "<ion-card *ngIf=\"_variable\">\n <ion-item lines=\"none\">\n <ion-label slot=\"start\">{{ bundleName }}</ion-label>\n <ion-label slot=\"end\">#{{ _variable.id }}</ion-label>\n </ion-item>\n <!-- <ion-item>\n <ion-icon *ngIf=\"icon\" name=\"{{icon}}\" slot=\"start\"></ion-icon>\n <ion-label>{{variable.identifier() || variableConfig.id }}</ion-label>\n </ion-item> -->\n <ion-card-content *ngIf=\"monitor\">\n <ng-container [ngSwitch]=\"cardType\">\n <ion-item *ngSwitchCase=\"'text'\" lines=\"none\" class=\"ion-no-padding\">\n <monitoring-variable-value\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [editable]=\"editMode\"\n ></monitoring-variable-value>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <ion-item *ngSwitchCase=\"'select'\" lines=\"none\" class=\"ion-no-padding\">\n <tap-variable-select\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [options]=\"selectOptions\"\n [editable]=\"editMode\"\n ></tap-variable-select>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <tap-variable-toggle\n *ngSwitchCase=\"'switch'\"\n [variable]=\"_variable\"\n ></tap-variable-toggle>\n <tap-variable-buttons\n *ngSwitchCase=\"'buttons'\"\n [variable]=\"variable\"\n [buttons]=\"monitoringButtons\"\n ></tap-variable-buttons>\n <tap-variable-range\n *ngSwitchCase=\"'range'\"\n [variable]=\"_variable\"\n [pin]=\"true\"\n [snaps]=\"true\"\n [ticks]=\"true\"\n [min]=\"0\"\n [max]=\"100\"\n ></tap-variable-range>\n <ion-text color=\"danger\" *ngSwitchDefault>\n <ion-icon name=\"alert\"></ion-icon> Unknown card type {{ cardType }}\n </ion-text>\n </ng-container>\n </ion-card-content>\n <ion-card-content *ngIf=\"error\">\n <ion-text color=\"danger\">{{ error }}</ion-text>\n </ion-card-content>\n <!--\n <ion-item>\n <ion-select\n [(ngModel)]=\"cardType\"\n okText=\"Select\"\n cancelText=\"Dismiss\"\n (ionChange)=\"onCardTypeChange($event)\"\n >\n <ion-select-option\n *ngFor=\"let cardType of cardTypes\"\n value=\"{{ cardType }}\"\n >{{ cardType }}</ion-select-option\n >\n </ion-select>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"toggleMonitoring()\" *ngIf=\"showStartStopMonitoring\">\n <ion-icon *ngIf=\"!playMonitoring\" name=\"play\"></ion-icon>\n <ion-icon *ngIf=\"playMonitoring\" name=\"pause\"></ion-icon>\n </ion-button>\n <ion-button (click)=\"editMode = !editMode\">\n <ion-icon *ngIf=\"!editMode\" name=\"create\"></ion-icon> <span *ngIf=\"!editMode\"></span>\n <ion-icon *ngIf=\"editMode\" name=\"close\"></ion-icon> \n </ion-button>\n <ion-button (click)=\"editConfig()\">\n \n <ion-icon name=\"cog\"></ion-icon> \n </ion-button>\n </ion-buttons>\n </ion-item>\n -->\n</ion-card>\n", styles: [".variable-value{font-size:1.4em;font-weight:700}ion-card-content{text-align:center}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "component", type: i3.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i3.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i3.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i3.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i3.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i3.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "component", type: i4.MonitoringVariableValueComponent, selector: "monitoring-variable-value", inputs: ["lines", "unitValue", "error", "variable", "config", "inputOptions", "editable", "modalEdition", "valueStyle", "digitsInfo", "refreshable", "valueFormatting"] }, { kind: "component", type: i5.TapVariableRangeComponent, selector: "tap-variable-range", inputs: ["variable", "editable", "writeValueForEveryChange", "min", "max", "step", "color", "pin", "snaps", "ticks", "debounce", "leftIcon", "leftIconColor", "rightIcon", "rightIconColor", "value"], outputs: ["valueChange"] }, { kind: "component", type: i6.TapVariableButtonsComponent, selector: "tap-variable-buttons", inputs: ["variable", "editable", "color", "segment", "buttons"] }, { kind: "component", type: i7.TapVariableToggleComponent, selector: "tap-variable-toggle", inputs: ["textOnLeft", "textOnRight", "lines", "toggleColor", "variable", "editable", "valueOn", "valueOff", "chip"] }, { kind: "component", type: i8.TapVariableSelectComponent, selector: "tap-variable-select", inputs: ["variable", "value", "editable", "refreshable", "multiple", "lines", "options"], outputs: ["valueChange"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: VariableCardComponent, decorators: [{ type: Component, args: [{ selector: 'app-variable-card', template: "<ion-card *ngIf=\"_variable\">\n <ion-item lines=\"none\">\n <ion-label slot=\"start\">{{ bundleName }}</ion-label>\n <ion-label slot=\"end\">#{{ _variable.id }}</ion-label>\n </ion-item>\n <!-- <ion-item>\n <ion-icon *ngIf=\"icon\" name=\"{{icon}}\" slot=\"start\"></ion-icon>\n <ion-label>{{variable.identifier() || variableConfig.id }}</ion-label>\n </ion-item> -->\n <ion-card-content *ngIf=\"monitor\">\n <ng-container [ngSwitch]=\"cardType\">\n <ion-item *ngSwitchCase=\"'text'\" lines=\"none\" class=\"ion-no-padding\">\n <monitoring-variable-value\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [editable]=\"editMode\"\n ></monitoring-variable-value>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <ion-item *ngSwitchCase=\"'select'\" lines=\"none\" class=\"ion-no-padding\">\n <tap-variable-select\n style=\"margin: auto\"\n [lines]=\"'none'\"\n [variable]=\"variable\"\n [options]=\"selectOptions\"\n [editable]=\"editMode\"\n ></tap-variable-select>\n <span slot=\"end\" *ngIf=\"unit\" class=\"unit\">{{ unit }}</span>\n </ion-item>\n <tap-variable-toggle\n *ngSwitchCase=\"'switch'\"\n [variable]=\"_variable\"\n ></tap-variable-toggle>\n <tap-variable-buttons\n *ngSwitchCase=\"'buttons'\"\n [variable]=\"variable\"\n [buttons]=\"monitoringButtons\"\n ></tap-variable-buttons>\n <tap-variable-range\n *ngSwitchCase=\"'range'\"\n [variable]=\"_variable\"\n [pin]=\"true\"\n [snaps]=\"true\"\n [ticks]=\"true\"\n [min]=\"0\"\n [max]=\"100\"\n ></tap-variable-range>\n <ion-text color=\"danger\" *ngSwitchDefault>\n <ion-icon name=\"alert\"></ion-icon> Unknown card type {{ cardType }}\n </ion-text>\n </ng-container>\n </ion-card-content>\n <ion-card-content *ngIf=\"error\">\n <ion-text color=\"danger\">{{ error }}</ion-text>\n </ion-card-content>\n <!--\n <ion-item>\n <ion-select\n [(ngModel)]=\"cardType\"\n okText=\"Select\"\n cancelText=\"Dismiss\"\n (ionChange)=\"onCardTypeChange($event)\"\n >\n <ion-select-option\n *ngFor=\"let cardType of cardTypes\"\n value=\"{{ cardType }}\"\n >{{ cardType }}</ion-select-option\n >\n </ion-select>\n <ion-buttons slot=\"end\">\n <ion-button (click)=\"toggleMonitoring()\" *ngIf=\"showStartStopMonitoring\">\n <ion-icon *ngIf=\"!playMonitoring\" name=\"play\"></ion-icon>\n <ion-icon *ngIf=\"playMonitoring\" name=\"pause\"></ion-icon>\n </ion-button>\n <ion-button (click)=\"editMode = !editMode\">\n <ion-icon *ngIf=\"!editMode\" name=\"create\"></ion-icon> <span *ngIf=\"!editMode\"></span>\n <ion-icon *ngIf=\"editMode\" name=\"close\"></ion-icon> \n </ion-button>\n <ion-button (click)=\"editConfig()\">\n \n <ion-icon name=\"cog\"></ion-icon> \n </ion-button>\n </ion-buttons>\n </ion-item>\n -->\n</ion-card>\n", styles: [".variable-value{font-size:1.4em;font-weight:700}ion-card-content{text-align:center}\n"] }] }], ctorParameters: () => [{ type: i1.Router }], propDecorators: { cardType: [{ type: Input }], cardTypes: [{ type: Input }], editMode: [{ type: Input }], monitor: [{ type: Input }], showStartStopMonitoring: [{ type: Input }], unit: [{ type: Input }], bundleName: [{ type: Input }], variable: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaWFibGUtY2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9pb3RpemUtaW9uaWMvbW9uaXRvcmluZy9zcmMvbGliL3VpLWNvbXBvbmVudHMvdmFyaWFibGUtY2FyZC92YXJpYWJsZS1jYXJkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2lvdGl6ZS1pb25pYy9tb25pdG9yaW5nL3NyYy9saWIvdWktY29tcG9uZW50cy92YXJpYWJsZS1jYXJkL3ZhcmlhYmxlLWNhcmQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDNUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLGtCQUFrQixDQUFDOzs7Ozs7Ozs7O0FBa0JqRSxNQUFNLE9BQU8scUJBQXFCO0lBeUViO0lBeEVuQixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBRWIsUUFBUSxHQUFhLE1BQU0sQ0FBQztJQUU1QixTQUFTLEdBQWU7UUFDL0IsV0FBVztRQUNYLE9BQU87UUFDUCxRQUFRO1FBQ1IsTUFBTTtRQUNOLFNBQVM7UUFDVCxPQUFPO1FBQ1AsUUFBUTtLQUNULENBQUM7SUFFTyxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBRWpCLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFFZix1QkFBdUIsR0FBRyxLQUFLLENBQUM7SUFFaEMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUVWLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFFNUIsS0FBSyxDQUFTO0lBQ2QsS0FBSyxHQUFRLFNBQVMs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VztRQUNULElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkMsQ0FBQztRQUNELHdDQUF3QztRQUN4QyxrREFBa0Q7UUFDbEQsSUFBSTtJQUNOLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxNQUF3QztRQUN2RCwyQ0FBMkM7UUFDM0MsdUNBQXVDO0lBQ3pDLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxzQkFBc0I7UUFDdEIseUJBQXlCO1FBQ3pCLG1GQUFtRjtRQUNuRixJQUFJO1FBQ0osSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7UUFDekMsNEJBQTRCO1FBQzVCLDZFQUE2RTtRQUM3RSxxQ0FBcUM7UUFDckMsMEJBQTBCO1FBQzFCLG9DQUFvQztRQUNwQyxRQUFRO1FBQ1IsV0FBVztRQUNYLHdDQUF3QztRQUN4QyxzQ0FBc0M7UUFDdEMsSUFBSTtRQUNKLElBQUk7SUFDTixDQUFDOzJIQWhKVSxxQkFBcUI7K0dBQXJCLHFCQUFxQiwrUUNyQmxDLG9uR0F1RkE7OzRGRGxFYSxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsbUJBQW1COzJFQU9wQixRQUFRO3NCQUFoQixLQUFLO2dCQUVHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBVUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUcsdUJBQXVCO3NCQUEvQixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQXdCTyxRQUFRO3NCQUFwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgZ2V0QWJzdHJhY3RWYXJpYWJsZU9yRXJyb3IsIExpYkVycm9yIH0gZnJvbSAnQGlvdGl6ZS9pb25pYyc7XG5pbXBvcnQgeyBBYnN0cmFjdFZhcmlhYmxlLCBUYXBWYXJpYWJsZSB9IGZyb20gJ0Bpb3RpemUvdGFwL2RhdGEnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBUYXBWYXJpYWJsZUJ1dHRvbiB9IGZyb20gJy4uL3RhcC12YXJpYWJsZS1idXR0b25zL3RhcC12YXJpYWJsZS1idXR0b25zLmNvbXBvbmVudCc7XG5cbnR5cGUgQ2FyZFR5cGUgPVxuICB8ICdnYXVnZSdcbiAgfCAndGV4dCdcbiAgfCAnY2hhcnQnXG4gIHwgJ3N3aXRjaCdcbiAgfCAnYnV0dG9ucydcbiAgfCAncmFuZ2UnXG4gIHwgJ3NlbGVjdCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC12YXJpYWJsZS1jYXJkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3ZhcmlhYmxlLWNhcmQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi92YXJpYWJsZS1jYXJkLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZhcmlhYmxlQ2FyZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHdhaXRGb3JTdWJtaXQgPSBmYWxzZTtcblxuICBASW5wdXQoKSBjYXJkVHlwZTogQ2FyZFR5cGUgPSAndGV4dCc7XG5cbiAgQElucHV0KCkgY2FyZFR5cGVzOiBDYXJkVHlwZVtdID0gW1xuICAgIC8vICdjaGFydCcsXG4gICAgJ2dhdWdlJyxcbiAgICAnc3dpdGNoJyxcbiAgICAndGV4dCcsXG4gICAgJ2J1dHRvbnMnLFxuICAgICdyYW5nZScsXG4gICAgJ3NlbGVjdCcsXG4gIF07XG5cbiAgQElucHV0KCkgZWRpdE1vZGUgPSBmYWxzZTtcblxuICBASW5wdXQoKSBtb25pdG9yID0gdHJ1ZTtcblxuICBASW5wdXQoKSBzaG93U3RhcnRTdG9wTW9uaXRvcmluZyA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIHVuaXQgPSAnJztcblxuICBASW5wdXQoKSBidW5kbGVOYW1lID0gJy4uLic7XG5cbiAgZXJyb3I/OiBFcnJvcjtcbiAgdmFsdWU6IGFueSA9ICdVbmtub3duJztcbiAgcmVmcmVzaFZhbHVlcyA9IGZhbHNlO1xuXG4gIG1vbml0b3JpbmdCdXR0b25zOiBUYXBWYXJpYWJsZUJ1dHRvbltdID0gWzAsIDEsIDIsIDMsIDQsIDVdLm1hcCgodikgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogYCR7dn1gLFxuICAgICAgdmFsdWU6IHYsXG4gICAgfTtcbiAgfSk7XG5cbiAgc2VsZWN0T3B0aW9ucyA9IFswLCAxLCAyLCAzLCA0LCA1XS5tYXAoKHYpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5OiB2LFxuICAgICAgdGV4dDogYFZhbHVlICR7dn1gLFxuICAgIH07XG4gIH0pO1xuXG4gIHB1YmxpYyBfdmFyaWFibGU/OiBBYnN0cmFjdFZhcmlhYmxlPGFueT47XG4gIHByaXZhdGUgX3N1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcbiAgLy8gcHJpdmF0ZSBfc3dpdGNoQnV0dG9uU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuXG4gIEBJbnB1dCgpIHNldCB2YXJpYWJsZSh2YXJpYWJsZTogQWJzdHJhY3RWYXJpYWJsZTxhbnk+KSB7XG4gICAgLy8gY29uc29sZS5sb2coJ1ZhcmlhYmxlQ2FyZENvbXBvbmVudCcsICdTRVQgVkFSSUFCTEUnLCB2YXJpYWJsZSk7XG4gICAgdGhpcy5fdmFyaWFibGUgPSB2YXJpYWJsZTtcbiAgICBpZiAodGhpcy5fc3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uID0gdmFyaWFibGUudmFsdWVzLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAodmFsdWUpID0+IHtcbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaFZhbHVlcykge1xuICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcbiAgICAgICAgLy8gY29uc29sZS53YXJuKGBNb25pdG9yaW5nIGVycm9yOiBgLCBlcnJvcik7XG4gICAgICAgIHRoaXMuZXJyb3IgPSBlcnJvcjtcbiAgICAgIH0sXG4gICAgICBjb21wbGV0ZTogKCkgPT4ge1xuICAgICAgICAvLyBjb25zb2xlLndhcm4oJ1ZhcmlhYmxlQ2FyZENvbXBvbmVudCcsICd2YWx1ZXMgb2JzZXJ2YWJsZSBpcyBjb21wbGV0ZScpXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHZhcmlhYmxlKCk6IEFic3RyYWN0VmFyaWFibGU8YW55PiB7XG4gICAgcmV0dXJuIGdldEFic3RyYWN0VmFyaWFibGVPckVycm9yKHRoaXMuX3ZhcmlhYmxlKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyByb3V0ZXI6IFJvdXRlcikge31cblxuICBnZXQgdmFyaWFibGVDb25maWcoKTogVGFwVmFyaWFibGUuQ29uZmlnIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5fdmFyaWFibGUgaW5zdGFuY2VvZiBUYXBWYXJpYWJsZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhcmlhYmxlLmNvbnRleHQuY29uZmlnO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gZWRpdENvbmZpZygpIHtcbiAgLy8gICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9kZXZpY2UvbW9uaXRvcmluZy9hZGQnXSk7XG4gIC8vIH1cblxuICBhc3luYyBzd2l0Y2hCdXR0b25Ub2dnbGVBY3Rpb24oY2hlY2tlZDogYm9vbGVhbikge1xuICAgIGlmICghdGhpcy5fdmFyaWFibGUpIHtcbiAgICAgIHRocm93IExpYkVycm9yLmNvbXBvbmVudEFyZ3VtZW50UmVxdWlyZWQoXG4gICAgICAgICdWYXJpYWJsZUNhcmRDb21wb25lbnQnLFxuICAgICAgICAndmFyaWFibGUnXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IGNoZWNrZWQgPyAxIDogMDtcbiAgICBhd2FpdCB0aGlzLl92YXJpYWJsZS53cml0ZSh2YWx1ZSk7XG4gICAgLy8gLmNhdGNoKChlcnJvcikgPT4ge1xuICAgIC8vICAgY29uc29sZS53YXJuKGBDYW5ub3Qgd3JpdGUgJHt0aGlzLl92YXJpYWJsZS5pZGVudGlmaWVyKCl9OiAke2Vycm9yfWApXG4gICAgLy8gICB0aGlzLmVycm9yID0gZXJyb3I7XG4gICAgLy8gfSlcbiAgfVxuXG4gIC8vIG9uRWRpdEV2ZW50KGV2ZW50OiBNb25pdG9yaW5nRWRpdFRleHRFdmVudCkge1xuICAvLyAgIGNvbnNvbGUubG9nKCdFRElUIEVWRU5UID0+ICcsIGV2ZW50KTtcbiAgLy8gICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgLy8gICAgIGNhc2UgJ0NMT1NFJzpcbiAgLy8gICAgICAgdGhpcy5lZGl0TW9kZSA9IGZhbHNlO1xuICAvLyAgICAgICBicmVhaztcbiAgLy8gICAgIGNhc2UgJ1dSSVRFX1NVQ0NFU1MnOlxuICAvLyAgICAgICB0aGlzLmVkaXRNb2RlID0gZmFsc2U7XG4gIC8vICAgICAgIGJyZWFrO1xuICAvLyAgIH1cbiAgLy8gfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9zdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX3N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICAvLyBpZiAodGhpcy5fc3dpdGNoQnV0dG9uU3Vic2NyaXB0aW9uKSB7XG4gICAgLy8gICB0aGlzLl9zd2l0Y2hCdXR0b25TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAvLyB9XG4gIH1cblxuICBvbkNhcmRUeXBlQ2hhbmdlKCRldmVudDogQ3VzdG9tRXZlbnQ8eyB2YWx1ZTogQ2FyZFR5cGUgfT4pIHtcbiAgICAvLyBjb25zb2xlLmxvZygnb25DYXJkVHlwZUNoYW5nZScsICRldmVudCk7XG4gICAgLy8gdGhpcy5jYXJkVHlwZSA9ICRldmVudC5kZXRhaWwudmFsdWU7XG4gIH1cblxuICB0b2dnbGVNb25pdG9yaW5nKCkge1xuICAgIC8vIGlmICh0aGlzLm1vbml0b3IpIHtcbiAgICAvLyBpZiAoIXRoaXMuX3ZhcmlhYmxlKSB7XG4gICAgLy8gICB0aHJvdyBMaWJFcnJvci5jb21wb25lbnRBcmd1bWVudFJlcXVpcmVkKCdWYXJpYWJsZUNhcmRDb21wb25lbnQnLCAndmFyaWFibGUnKTtcbiAgICAvLyB9XG4gICAgdGhpcy5yZWZyZXNoVmFsdWVzID0gIXRoaXMucmVmcmVzaFZhbHVlcztcbiAgICAvLyBpZiAodGhpcy5yZWZyZXNoVmFsdWVzKSB7XG4gICAgLy8gICAvLyBjb25zb2xlLmxvZygnU3RhcnQgbW9uaXRvcmluZyB3aXRoIHBlcmlvZDogJywgdGhpcy5tb25pdG9yaW5nUGVyaW9kKTtcbiAgICAvLyAgIHRoaXMuX3ZhcmlhYmxlLm1vbml0b3IoKS5zdGFydCh7XG4gICAgLy8gICAgIGZvcmNlQ2hhbmdlOiBmYWxzZSxcbiAgICAvLyAgICAgcGVyaW9kOiB0aGlzLm1vbml0b3JpbmdQZXJpb2RcbiAgICAvLyAgIH0pO1xuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICAvLyBjb25zb2xlLmxvZygnUGF1c2UgbW9uaXRvcmluZycpO1xuICAgIC8vICAgdGhpcy5fdmFyaWFibGUubW9uaXRvcigpLnBhdXNlKCk7XG4gICAgLy8gfVxuICAgIC8vIH1cbiAgfVxufVxuIiwiPGlvbi1jYXJkICpuZ0lmPVwiX3ZhcmlhYmxlXCI+XG4gIDxpb24taXRlbSBsaW5lcz1cIm5vbmVcIj5cbiAgICA8aW9uLWxhYmVsIHNsb3Q9XCJzdGFydFwiPnt7IGJ1bmRsZU5hbWUgfX08L2lvbi1sYWJlbD5cbiAgICA8aW9uLWxhYmVsIHNsb3Q9XCJlbmRcIj4je3sgX3ZhcmlhYmxlLmlkIH19PC9pb24tbGFiZWw+XG4gIDwvaW9uLWl0ZW0+XG4gIDwhLS0gPGlvbi1pdGVtPlxuICAgIDxpb24taWNvbiAqbmdJZj1cImljb25cIiBuYW1lPVwie3tpY29ufX1cIiBzbG90PVwic3RhcnRcIj48L2lvbi1pY29uPlxuICAgIDxpb24tbGFiZWw+e3t2YXJpYWJsZS5pZGVudGlmaWVyKCkgfHwgdmFyaWFibGVDb25maWcuaWQgfX08L2lvbi1sYWJlbD5cbiAgPC9pb24taXRlbT4gLS0+XG4gIDxpb24tY2FyZC1jb250ZW50ICpuZ0lmPVwibW9uaXRvclwiPlxuICAgIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cImNhcmRUeXBlXCI+XG4gICAgICA8aW9uLWl0ZW0gKm5nU3dpdGNoQ2FzZT1cIid0ZXh0J1wiIGxpbmVzPVwibm9uZVwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgPG1vbml0b3JpbmctdmFyaWFibGUtdmFsdWVcbiAgICAgICAgICBzdHlsZT1cIm1hcmdpbjogYXV0b1wiXG4gICAgICAgICAgW2xpbmVzXT1cIidub25lJ1wiXG4gICAgICAgICAgW3ZhcmlhYmxlXT1cInZhcmlhYmxlXCJcbiAgICAgICAgICBbZWRpdGFibGVdPVwiZWRpdE1vZGVcIlxuICAgICAgICA+PC9tb25pdG9yaW5nLXZhcmlhYmxlLXZhbHVlPlxuICAgICAgICA8c3BhbiBzbG90PVwiZW5kXCIgKm5nSWY9XCJ1bml0XCIgY2xhc3M9XCJ1bml0XCI+e3sgdW5pdCB9fTwvc3Bhbj5cbiAgICAgIDwvaW9uLWl0ZW0+XG4gICAgICA8aW9uLWl0ZW0gKm5nU3dpdGNoQ2FzZT1cIidzZWxlY3QnXCIgbGluZXM9XCJub25lXCIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICAgICAgICA8dGFwLXZhcmlhYmxlLXNlbGVjdFxuICAgICAgICAgIHN0eWxlPVwibWFyZ2luOiBhdXRvXCJcbiAgICAgICAgICBbbGluZXNdPVwiJ25vbmUnXCJcbiAgICAgICAgICBbdmFyaWFibGVdPVwidmFyaWFibGVcIlxuICAgICAgICAgIFtvcHRpb25zXT1cInNlbGVjdE9wdGlvbnNcIlxuICAgICAgICAgIFtlZGl0YWJsZV09XCJlZGl0TW9kZVwiXG4gICAgICAgID48L3RhcC12YXJpYWJsZS1zZWxlY3Q+XG4gICAgICAgIDxzcGFuIHNsb3Q9XCJlbmRcIiAqbmdJZj1cInVuaXRcIiBjbGFzcz1cInVuaXRcIj57eyB1bml0IH19PC9zcGFuPlxuICAgICAgPC9pb24taXRlbT5cbiAgICAgIDx0YXAtdmFyaWFibGUtdG9nZ2xlXG4gICAgICAgICpuZ1N3aXRjaENhc2U9XCInc3dpdGNoJ1wiXG4gICAgICAgIFt2YXJpYWJsZV09XCJfdmFyaWFibGVcIlxuICAgICAgPjwvdGFwLXZhcmlhYmxlLXRvZ2dsZT5cbiAgICAgIDx0YXAtdmFyaWFibGUtYnV0dG9uc1xuICAgICAgICAqbmdTd2l0Y2hDYXNlPVwiJ2J1dHRvbnMnXCJcbiAgICAgICAgW3ZhcmlhYmxlXT1cInZhcmlhYmxlXCJcbiAgICAgICAgW2J1dHRvbnNdPVwibW9uaXRvcmluZ0J1dHRvbnNcIlxuICAgICAgPjwvdGFwLXZhcmlhYmxlLWJ1dHRvbnM+XG4gICAgICA8dGFwLXZhcmlhYmxlLXJhbmdlXG4gICAgICAgICpuZ1N3aXRjaENhc2U9XCIncmFuZ2UnXCJcbiAgICAgICAgW3ZhcmlhYmxlXT1cIl92YXJpYWJsZVwiXG4gICAgICAgIFtwaW5dPVwidHJ1ZVwiXG4gICAgICAgIFtzbmFwc109XCJ0cnVlXCJcbiAgICAgICAgW3RpY2tzXT1cInRydWVcIlxuICAgICAgICBbbWluXT1cIjBcIlxuICAgICAgICBbbWF4XT1cIjEwMFwiXG4gICAgICA+PC90YXAtdmFyaWFibGUtcmFuZ2U+XG4gICAgICA8aW9uLXRleHQgY29sb3I9XCJkYW5nZXJcIiAqbmdTd2l0Y2hEZWZhdWx0PlxuICAgICAgICA8aW9uLWljb24gbmFtZT1cImFsZXJ0XCI+PC9pb24taWNvbj4gVW5rbm93biBjYXJkIHR5cGUge3sgY2FyZFR5cGUgfX1cbiAgICAgIDwvaW9uLXRleHQ+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvaW9uLWNhcmQtY29udGVudD5cbiAgPGlvbi1jYXJkLWNvbnRlbnQgKm5nSWY9XCJlcnJvclwiPlxuICAgIDxpb24tdGV4dCBjb2xvcj1cImRhbmdlclwiPnt7IGVycm9yIH19PC9pb24tdGV4dD5cbiAgPC9pb24tY2FyZC1jb250ZW50PlxuICA8IS0tXG4gIDxpb24taXRlbT5cbiAgICA8aW9uLXNlbGVjdFxuICAgICAgWyhuZ01vZGVsKV09XCJjYXJkVHlwZVwiXG4gICAgICBva1RleHQ9XCJTZWxlY3RcIlxuICAgICAgY2FuY2VsVGV4dD1cIkRpc21pc3NcIlxuICAgICAgKGlvbkNoYW5nZSk9XCJvbkNhcmRUeXBlQ2hhbmdlKCRldmVudClcIlxuICAgID5cbiAgICAgIDxpb24tc2VsZWN0LW9wdGlvblxuICAgICAgICAqbmdGb3I9XCJsZXQgY2FyZFR5cGUgb2YgY2FyZFR5cGVzXCJcbiAgICAgICAgdmFsdWU9XCJ7eyBjYXJkVHlwZSB9fVwiXG4gICAgICAgID57eyBjYXJkVHlwZSB9fTwvaW9uLXNlbGVjdC1vcHRpb25cbiAgICAgID5cbiAgICA8L2lvbi1zZWxlY3Q+XG4gICAgPGlvbi1idXR0b25zIHNsb3Q9XCJlbmRcIj5cbiAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJ0b2dnbGVNb25pdG9yaW5nKClcIiAqbmdJZj1cInNob3dTdGFydFN0b3BNb25pdG9yaW5nXCI+XG4gICAgICAgIDxpb24taWNvbiAqbmdJZj1cIiFwbGF5TW9uaXRvcmluZ1wiIG5hbWU9XCJwbGF5XCI+PC9pb24taWNvbj5cbiAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwicGxheU1vbml0b3JpbmdcIiBuYW1lPVwicGF1c2VcIj48L2lvbi1pY29uPlxuICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgPGlvbi1idXR0b24gKGNsaWNrKT1cImVkaXRNb2RlID0gIWVkaXRNb2RlXCI+XG4gICAgICAgIDxpb24taWNvbiAqbmdJZj1cIiFlZGl0TW9kZVwiIG5hbWU9XCJjcmVhdGVcIj48L2lvbi1pY29uPiA8c3BhbiAqbmdJZj1cIiFlZGl0TW9kZVwiPjwvc3Bhbj5cbiAgICAgICAgPGlvbi1pY29uICpuZ0lmPVwiZWRpdE1vZGVcIiBuYW1lPVwiY2xvc2VcIj48L2lvbi1pY29uPiBcbiAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgIDxpb24tYnV0dG9uIChjbGljayk9XCJlZGl0Q29uZmlnKClcIj5cbiAgICAgICAgXG4gICAgICAgIDxpb24taWNvbiBuYW1lPVwiY29nXCI+PC9pb24taWNvbj4gXG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgPC9pb24tYnV0dG9ucz5cbiAgPC9pb24taXRlbT5cbiAgLS0+XG48L2lvbi1jYXJkPlxuIl19