@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
76 lines • 28.4 kB
JavaScript
import { Component, Output, Input, EventEmitter } from '@angular/core';
import { ControlContainer, NgForm } from '@angular/forms';
import { BsModalService } from 'ngx-bootstrap/modal';
import { InventoryRolesModalComponent } from './inventory-roles-modal.component';
import { take, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "ngx-bootstrap/modal";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@angular/common";
import * as i5 from "ngx-bootstrap/tooltip";
import * as i6 from "./child-predicates.component";
export class InventoryRolesMappingComponent {
constructor(controlContainer, bsModal) {
this.controlContainer = controlContainer;
this.bsModal = bsModal;
this.inventoryRoles = [];
this.selectedInventoryRoles = [];
this.onRemoveInventoryMapping = new EventEmitter();
}
ngOnChanges() {
this.setSelectedInventoryRoles();
}
onRemoveAllChildPredicates() {
this.onRemoveInventoryMapping.emit(this.inventoryMapping);
}
getIds(selectedItems) {
return selectedItems.map(item => item.id);
}
removeInventoryRole(inventoryRole) {
this.inventoryMapping.thenInventoryRoles = this.inventoryMapping.thenInventoryRoles.filter(value => value.managedObject !== inventoryRole.managedObject);
delete this.selectedInventoryRoles[inventoryRole.managedObject];
}
addInventoryRoles() {
const currentlySelectedGroups = this.inventoryMapping.thenInventoryRoles.map(inventoryRole => ({ id: inventoryRole.managedObject }));
const modal = this.bsModal.show(InventoryRolesModalComponent, {
ignoreBackdropClick: true,
class: 'modal-sm',
ariaDescribedby: 'modal-body',
ariaLabelledBy: 'modal-title',
initialState: {
selectedGroups: currentlySelectedGroups
}
});
modal.content.resultEmitter
.pipe(take(1), tap(() => this.controlContainer.control.markAsDirty()))
.subscribe(selectedGroups => {
const newSelectedGroups = selectedGroups.filter(group => !currentlySelectedGroups.some(({ id }) => id === group.id));
const newInventoryRoles = newSelectedGroups.map(group => ({ managedObject: group.id, roleIds: [] }));
this.inventoryMapping.thenInventoryRoles =
this.inventoryMapping.thenInventoryRoles.concat(newInventoryRoles);
});
}
setSelectedInventoryRoles() {
if (this.inventoryMapping && this.inventoryMapping.thenInventoryRoles && this.inventoryRoles) {
this.inventoryMapping.thenInventoryRoles.forEach(inventoryRole => {
this.selectedInventoryRoles[inventoryRole.managedObject] = this.inventoryRoles.filter(item => inventoryRole.roleIds.includes(+item.id));
});
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InventoryRolesMappingComponent, deps: [{ token: i1.ControlContainer }, { token: i2.BsModalService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InventoryRolesMappingComponent, selector: "c8y-sso-inventory-roles-mapping", inputs: { inventoryMapping: "inventoryMapping", inventoryMappingIndex: "inventoryMappingIndex", inventoryRoles: "inventoryRoles" }, outputs: { onRemoveInventoryMapping: "onRemoveInventoryMapping" }, usesOnChanges: true, ngImport: i0, template: "<fieldset class=\"c8y-fieldset p-t-8 p-b-8 p-l-16 p-r-16\">\n <div *ngIf=\"inventoryMapping.when.childPredicates.length !== 0\">\n <c8y-sso-child-predicates\n [childPredicates]=\"inventoryMapping.when.childPredicates\"\n [accessMappingIndex]=\"'irm' + inventoryMappingIndex\"\n (onRemoveAllChildPredicates)=\"onRemoveAllChildPredicates()\"\n ></c8y-sso-child-predicates>\n <fieldset class=\"c8y-fieldset p-16\">\n <legend>\n {{ 'Provide inventory roles' | translate }}\n </legend>\n <div\n class=\"p-l-8 p-r-8\"\n *ngIf=\"inventoryMapping.thenInventoryRoles.length !== 0\"\n >\n <div class=\"tight-grid p-b-8 separator-bottom hidden-sm hidden-xs\">\n <div class=\"col-md-5\">\n <label translate>Groups</label>\n </div>\n <div class=\"col-md-6\">\n <label translate>Inventory roles</label>\n </div>\n </div>\n <div\n class=\"tight-grid d-flex-md a-i-center p-t-8 p-b-8 separator-bottom\"\n *ngFor=\"let inventoryRole of inventoryMapping.thenInventoryRoles; index as idx\"\n >\n <div class=\"col-md-5\">\n <div class=\"d-flex a-i-center\">\n <!-- TODO:\n We need to retrive the icon here, for groups there are 3 possible icons:\n \u2022 Regular group\n \u2022 Remote group\n \u2022 Smartgroup\n Besides groups, there's also Assets from DTM, in which each asset has a different icon\n -->\n <i\n class=\"m-r-8 text-16\"\n c8yIcon=\"c8y-group\"\n ></i>\n <span\n class=\"text-truncate\"\n title=\"{{ inventoryRole.managedObject | moName | async }}\"\n >\n {{ inventoryRole.managedObject | moName | async }}\n </span>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div\n class=\"form-group m-b-0\"\n title=\"{{ 'Inventory roles' | translate }}\"\n >\n <c8y-select-legacy\n [id]=\"'ir' + idx + accessMappingIndex\"\n [items]=\"inventoryRoles\"\n [selected]=\"selectedInventoryRoles[inventoryRole.managedObject]\"\n [disableApplyOnNoSelection]=\"true\"\n (onChange)=\"\n controlContainer.control.markAsDirty();\n selectedInventoryRoles[inventoryRole.managedObject] = $event;\n inventoryRole.roleIds = getIds($event)\n \"\n ></c8y-select-legacy>\n </div>\n </div>\n <div class=\"col-md-1\">\n <button\n class=\"btn btn-dot btn-dot--danger hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"{{ 'Remove' | translate }}\"\n name=\"removeButton\"\n type=\"button\"\n (click)=\"controlContainer.control.markAsDirty(); removeInventoryRole(inventoryRole)\"\n [delay]=\"300\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n <button\n class=\"btn btn-danger btn-block btn-sm visible-xs visible-sm\"\n title=\"{{ 'Remove' | translate }}\"\n name=\"removeButton\"\n type=\"button\"\n (click)=\"controlContainer.control.markAsDirty(); removeInventoryRole(inventoryRole)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n <span translate>Remove</span>\n </button>\n </div>\n </div>\n </div>\n\n <button\n class=\"btn btn-default m-t-16\"\n title=\"{{ 'Add inventory roles' | translate }}\"\n id=\"add-inventory-roles-button\"\n type=\"button\"\n (click)=\"addInventoryRoles()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n {{ 'Add inventory roles' | translate }}\n </button>\n </fieldset>\n </div>\n</fieldset>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.SelectLegacyComponent, selector: "c8y-select-legacy", inputs: ["placeholder", "selectedLabel", "applyLabel", "items", "selected", "updateItems", "disableApplyOnNoSelection", "addDropdownContainerToBody"], outputs: ["onChange"] }, { kind: "directive", type: i5.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i6.ChildPredicatesComponent, selector: "c8y-sso-child-predicates", inputs: ["childPredicates", "accessMappingIndex"], outputs: ["onRemoveAllChildPredicates"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.MoNamePipe, name: "moName" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InventoryRolesMappingComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-sso-inventory-roles-mapping', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], template: "<fieldset class=\"c8y-fieldset p-t-8 p-b-8 p-l-16 p-r-16\">\n <div *ngIf=\"inventoryMapping.when.childPredicates.length !== 0\">\n <c8y-sso-child-predicates\n [childPredicates]=\"inventoryMapping.when.childPredicates\"\n [accessMappingIndex]=\"'irm' + inventoryMappingIndex\"\n (onRemoveAllChildPredicates)=\"onRemoveAllChildPredicates()\"\n ></c8y-sso-child-predicates>\n <fieldset class=\"c8y-fieldset p-16\">\n <legend>\n {{ 'Provide inventory roles' | translate }}\n </legend>\n <div\n class=\"p-l-8 p-r-8\"\n *ngIf=\"inventoryMapping.thenInventoryRoles.length !== 0\"\n >\n <div class=\"tight-grid p-b-8 separator-bottom hidden-sm hidden-xs\">\n <div class=\"col-md-5\">\n <label translate>Groups</label>\n </div>\n <div class=\"col-md-6\">\n <label translate>Inventory roles</label>\n </div>\n </div>\n <div\n class=\"tight-grid d-flex-md a-i-center p-t-8 p-b-8 separator-bottom\"\n *ngFor=\"let inventoryRole of inventoryMapping.thenInventoryRoles; index as idx\"\n >\n <div class=\"col-md-5\">\n <div class=\"d-flex a-i-center\">\n <!-- TODO:\n We need to retrive the icon here, for groups there are 3 possible icons:\n \u2022 Regular group\n \u2022 Remote group\n \u2022 Smartgroup\n Besides groups, there's also Assets from DTM, in which each asset has a different icon\n -->\n <i\n class=\"m-r-8 text-16\"\n c8yIcon=\"c8y-group\"\n ></i>\n <span\n class=\"text-truncate\"\n title=\"{{ inventoryRole.managedObject | moName | async }}\"\n >\n {{ inventoryRole.managedObject | moName | async }}\n </span>\n </div>\n </div>\n <div class=\"col-md-6\">\n <div\n class=\"form-group m-b-0\"\n title=\"{{ 'Inventory roles' | translate }}\"\n >\n <c8y-select-legacy\n [id]=\"'ir' + idx + accessMappingIndex\"\n [items]=\"inventoryRoles\"\n [selected]=\"selectedInventoryRoles[inventoryRole.managedObject]\"\n [disableApplyOnNoSelection]=\"true\"\n (onChange)=\"\n controlContainer.control.markAsDirty();\n selectedInventoryRoles[inventoryRole.managedObject] = $event;\n inventoryRole.roleIds = getIds($event)\n \"\n ></c8y-select-legacy>\n </div>\n </div>\n <div class=\"col-md-1\">\n <button\n class=\"btn btn-dot btn-dot--danger hidden-xs hidden-sm\"\n [attr.aria-label]=\"'Remove' | translate\"\n tooltip=\"{{ 'Remove' | translate }}\"\n name=\"removeButton\"\n type=\"button\"\n (click)=\"controlContainer.control.markAsDirty(); removeInventoryRole(inventoryRole)\"\n [delay]=\"300\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n </button>\n <button\n class=\"btn btn-danger btn-block btn-sm visible-xs visible-sm\"\n title=\"{{ 'Remove' | translate }}\"\n name=\"removeButton\"\n type=\"button\"\n (click)=\"controlContainer.control.markAsDirty(); removeInventoryRole(inventoryRole)\"\n >\n <i c8yIcon=\"minus-circle\"></i>\n <span translate>Remove</span>\n </button>\n </div>\n </div>\n </div>\n\n <button\n class=\"btn btn-default m-t-16\"\n title=\"{{ 'Add inventory roles' | translate }}\"\n id=\"add-inventory-roles-button\"\n type=\"button\"\n (click)=\"addInventoryRoles()\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"plus-circle\"\n ></i>\n {{ 'Add inventory roles' | translate }}\n </button>\n </fieldset>\n </div>\n</fieldset>\n" }]
}], ctorParameters: () => [{ type: i1.ControlContainer }, { type: i2.BsModalService }], propDecorators: { inventoryMapping: [{
type: Input
}], inventoryMappingIndex: [{
type: Input
}], inventoryRoles: [{
type: Input
}], onRemoveInventoryMapping: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52ZW50b3J5LXJvbGVzLW1hcHBpbmcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vYXV0aC1jb25maWd1cmF0aW9uL3Nzby1jb25maWd1cmF0aW9uL3RlbXBsYXRlLXBhcnRzL2FjY2Vzcy1tYXBwaW5nL2ludmVudG9yeS1yb2xlcy1tYXBwaW5nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2F1dGgtY29uZmlndXJhdGlvbi9zc28tY29uZmlndXJhdGlvbi90ZW1wbGF0ZS1wYXJ0cy9hY2Nlc3MtbWFwcGluZy9pbnZlbnRvcnktcm9sZXMtbWFwcGluZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUxRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDakYsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7QUFRM0MsTUFBTSxPQUFPLDhCQUE4QjtJQVN6QyxZQUFtQixnQkFBa0MsRUFBVSxPQUF1QjtRQUFuRSxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQVUsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFMN0UsbUJBQWMsR0FBa0IsRUFBRSxDQUFDO1FBQzVDLDJCQUFzQixHQUFrQixFQUFFLENBQUM7UUFFakMsNkJBQXdCLEdBQW1DLElBQUksWUFBWSxFQUFFLENBQUM7SUFFQyxDQUFDO0lBRTFGLFdBQVc7UUFDVCxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQztJQUNuQyxD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Q0gsQ0FBQzsrR0FwRVUsOEJBQThCO21HQUE5Qiw4QkFBOEIsbVNDYjNDLHduSUE0R0EsNGtERGpHaUIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLENBQUM7OzRGQUV4RCw4QkFBOEI7a0JBTDFDLFNBQVM7K0JBQ0UsaUNBQWlDLGlCQUU1QixDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQztrSEFHMUQsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFFRyxjQUFjO3NCQUF0QixLQUFLO2dCQUdJLHdCQUF3QjtzQkFBakMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT3V0cHV0LCBJbnB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sQ29udGFpbmVyLCBOZ0Zvcm0gfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBJbnZlbnRvcnlNYXBwaW5nLCBJbnZlbnRvcnlSb2xlIH0gZnJvbSAnLi4vLi4vc3NvLWNvbmZpZ3VyYXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgQnNNb2RhbFNlcnZpY2UgfSBmcm9tICduZ3gtYm9vdHN0cmFwL21vZGFsJztcbmltcG9ydCB7IEludmVudG9yeVJvbGVzTW9kYWxDb21wb25lbnQgfSBmcm9tICcuL2ludmVudG9yeS1yb2xlcy1tb2RhbC5jb21wb25lbnQnO1xuaW1wb3J0IHsgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgSUlkZW50aWZpZWQgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1zc28taW52ZW50b3J5LXJvbGVzLW1hcHBpbmcnLFxuICB0ZW1wbGF0ZVVybDogJy4vaW52ZW50b3J5LXJvbGVzLW1hcHBpbmcuY29tcG9uZW50Lmh0bWwnLFxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogTmdGb3JtIH1dXG59KVxuZXhwb3J0IGNsYXNzIEludmVudG9yeVJvbGVzTWFwcGluZ0NvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGludmVudG9yeU1hcHBpbmc6IEludmVudG9yeU1hcHBpbmc7XG4gIEBJbnB1dCgpIGludmVudG9yeU1hcHBpbmdJbmRleDogbnVtYmVyO1xuXG4gIEBJbnB1dCgpIGludmVudG9yeVJvbGVzOiBJSWRlbnRpZmllZFtdID0gW107XG4gIHNlbGVjdGVkSW52ZW50b3J5Um9sZXM6IElJZGVudGlmaWVkW10gPSBbXTtcblxuICBAT3V0cHV0KCkgb25SZW1vdmVJbnZlbnRvcnlNYXBwaW5nOiBFdmVudEVtaXR0ZXI8SW52ZW50b3J5TWFwcGluZz4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgY29uc3RydWN0b3IocHVibGljIGNvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXIsIHByaXZhdGUgYnNNb2RhbDogQnNNb2RhbFNlcnZpY2UpIHt9XG5cbiAgbmdPbkNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5zZXRTZWxlY3RlZEludmVudG9yeVJvbGVzKCk7XG4gIH1cblxuICBvblJlbW92ZUFsbENoaWxkUHJlZGljYXRlcygpIHtcbiAgICB0aGlzLm9uUmVtb3ZlSW52ZW50b3J5TWFwcGluZy5lbWl0KHRoaXMuaW52ZW50b3J5TWFwcGluZyk7XG4gIH1cblxuICBnZXRJZHMoc2VsZWN0ZWRJdGVtczogSUlkZW50aWZpZWRbXSkge1xuICAgIHJldHVybiBzZWxlY3RlZEl0ZW1zLm1hcChpdGVtID0+IGl0ZW0uaWQpO1xuICB9XG5cbiAgcmVtb3ZlSW52ZW50b3J5Um9sZShpbnZlbnRvcnlSb2xlOiBJbnZlbnRvcnlSb2xlKSB7XG4gICAgdGhpcy5pbnZlbnRvcnlNYXBwaW5nLnRoZW5JbnZlbnRvcnlSb2xlcyA9IHRoaXMuaW52ZW50b3J5TWFwcGluZy50aGVuSW52ZW50b3J5Um9sZXMuZmlsdGVyKFxuICAgICAgdmFsdWUgPT4gdmFsdWUubWFuYWdlZE9iamVjdCAhPT0gaW52ZW50b3J5Um9sZS5tYW5hZ2VkT2JqZWN0XG4gICAgKTtcbiAgICBkZWxldGUgdGhpcy5zZWxlY3RlZEludmVudG9yeVJvbGVzW2ludmVudG9yeVJvbGUubWFuYWdlZE9iamVjdF07XG4gIH1cblxuICBhZGRJbnZlbnRvcnlSb2xlcygpIHtcbiAgICBjb25zdCBjdXJyZW50bHlTZWxlY3RlZEdyb3VwczogSUlkZW50aWZpZWRbXSA9IHRoaXMuaW52ZW50b3J5TWFwcGluZy50aGVuSW52ZW50b3J5Um9sZXMubWFwKFxuICAgICAgaW52ZW50b3J5Um9sZSA9PiAoeyBpZDogaW52ZW50b3J5Um9sZS5tYW5hZ2VkT2JqZWN0IH0pXG4gICAgKTtcbiAgICBjb25zdCBtb2RhbCA9IHRoaXMuYnNNb2RhbC5zaG93KEludmVudG9yeVJvbGVzTW9kYWxDb21wb25lbnQsIHtcbiAgICAgIGlnbm9yZUJhY2tkcm9wQ2xpY2s6IHRydWUsXG4gICAgICBjbGFzczogJ21vZGFsLXNtJyxcbiAgICAgIGFyaWFEZXNjcmliZWRieTogJ21vZGFsLWJvZHknLFxuICAgICAgYXJpYUxhYmVsbGVkQnk6ICdtb2RhbC10aXRsZScsXG4gICAgICBpbml0aWFsU3RhdGU6IHtcbiAgICAgICAgc2VsZWN0ZWRHcm91cHM6IGN1cnJlbnRseVNlbGVjdGVkR3JvdXBzXG4gICAgICB9XG4gICAgfSk7XG4gICAgbW9kYWwuY29udGVudC5yZXN1bHRFbWl0dGVyXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgdGFwKCgpID0+IHRoaXMuY29udHJvbENvbnRhaW5lci5jb250cm9sLm1hcmtBc0RpcnR5KCkpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHNlbGVjdGVkR3JvdXBzID0+IHtcbiAgICAgICAgY29uc3QgbmV3U2VsZWN0ZWRHcm91cHMgPSBzZWxlY3RlZEdyb3Vwcy5maWx0ZXIoXG4gICAgICAgICAgZ3JvdXAgPT4gIWN1cnJlbnRseVNlbGVjdGVkR3JvdXBzLnNvbWUoKHsgaWQgfSkgPT4gaWQgPT09IGdyb3VwLmlkKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBuZXdJbnZlbnRvcnlSb2xlczogSW52ZW50b3J5Um9sZVtdID0gbmV3U2VsZWN0ZWRHcm91cHMubWFwKFxuICAgICAgICAgIGdyb3VwID0+ICh7IG1hbmFnZWRPYmplY3Q6IGdyb3VwLmlkLCByb2xlSWRzOiBbXSB9IGFzIEludmVudG9yeVJvbGUpXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuaW52ZW50b3J5TWFwcGluZy50aGVuSW52ZW50b3J5Um9sZXMgPVxuICAgICAgICAgIHRoaXMuaW52ZW50b3J5TWFwcGluZy50aGVuSW52ZW50b3J5Um9sZXMuY29uY2F0KG5ld0ludmVudG9yeVJvbGVzKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTZWxlY3RlZEludmVudG9yeVJvbGVzKCkge1xuICAgIGlmICh0aGlzLmludmVudG9yeU1hcHBpbmcgJiYgdGhpcy5pbnZlbnRvcnlNYXBwaW5nLnRoZW5JbnZlbnRvcnlSb2xlcyAmJiB0aGlzLmludmVudG9yeVJvbGVzKSB7XG4gICAgICB0aGlzLmludmVudG9yeU1hcHBpbmcudGhlbkludmVudG9yeVJvbGVzLmZvckVhY2goaW52ZW50b3J5Um9sZSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJbnZlbnRvcnlSb2xlc1tpbnZlbnRvcnlSb2xlLm1hbmFnZWRPYmplY3RdID0gdGhpcy5pbnZlbnRvcnlSb2xlcy5maWx0ZXIoXG4gICAgICAgICAgaXRlbSA9PiBpbnZlbnRvcnlSb2xlLnJvbGVJZHMuaW5jbHVkZXMoK2l0ZW0uaWQpXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiIsIjxmaWVsZHNldCBjbGFzcz1cImM4eS1maWVsZHNldCBwLXQtOCBwLWItOCBwLWwtMTYgcC1yLTE2XCI+XG4gIDxkaXYgKm5nSWY9XCJpbnZlbnRvcnlNYXBwaW5nLndoZW4uY2hpbGRQcmVkaWNhdGVzLmxlbmd0aCAhPT0gMFwiPlxuICAgIDxjOHktc3NvLWNoaWxkLXByZWRpY2F0ZXNcbiAgICAgIFtjaGlsZFByZWRpY2F0ZXNdPVwiaW52ZW50b3J5TWFwcGluZy53aGVuLmNoaWxkUHJlZGljYXRlc1wiXG4gICAgICBbYWNjZXNzTWFwcGluZ0luZGV4XT1cIidpcm0nICsgaW52ZW50b3J5TWFwcGluZ0luZGV4XCJcbiAgICAgIChvblJlbW92ZUFsbENoaWxkUHJlZGljYXRlcyk9XCJvblJlbW92ZUFsbENoaWxkUHJlZGljYXRlcygpXCJcbiAgICA+PC9jOHktc3NvLWNoaWxkLXByZWRpY2F0ZXM+XG4gICAgPGZpZWxkc2V0IGNsYXNzPVwiYzh5LWZpZWxkc2V0IHAtMTZcIj5cbiAgICAgIDxsZWdlbmQ+XG4gICAgICAgIHt7ICdQcm92aWRlIGludmVudG9yeSByb2xlcycgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvbGVnZW5kPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInAtbC04IHAtci04XCJcbiAgICAgICAgKm5nSWY9XCJpbnZlbnRvcnlNYXBwaW5nLnRoZW5JbnZlbnRvcnlSb2xlcy5sZW5ndGggIT09IDBcIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGlnaHQtZ3JpZCBwLWItOCBzZXBhcmF0b3ItYm90dG9tIGhpZGRlbi1zbSBoaWRkZW4teHNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTVcIj5cbiAgICAgICAgICAgIDxsYWJlbCB0cmFuc2xhdGU+R3JvdXBzPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgICAgIDxsYWJlbCB0cmFuc2xhdGU+SW52ZW50b3J5IHJvbGVzPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cInRpZ2h0LWdyaWQgZC1mbGV4LW1kIGEtaS1jZW50ZXIgcC10LTggcC1iLTggc2VwYXJhdG9yLWJvdHRvbVwiXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGludmVudG9yeVJvbGUgb2YgaW52ZW50b3J5TWFwcGluZy50aGVuSW52ZW50b3J5Um9sZXM7IGluZGV4IGFzIGlkeFwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTVcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlclwiPlxuICAgICAgICAgICAgICA8IS0tIFRPRE86XG4gICAgICAgICAgICAgICAgV2UgbmVlZCB0byByZXRyaXZlIHRoZSBpY29uIGhlcmUsIGZvciBncm91cHMgdGhlcmUgYXJlIDMgcG9zc2libGUgaWNvbnM6XG4gICAgICAgICAgICAgICAg4oCiIFJlZ3VsYXIgZ3JvdXBcbiAgICAgICAgICAgICAgICDigKIgUmVtb3RlIGdyb3VwXG4gICAgICAgICAgICAgICAg4oCiIFNtYXJ0Z3JvdXBcbiAgICAgICAgICAgICAgICBCZXNpZGVzIGdyb3VwcywgdGhlcmUncyBhbHNvIEFzc2V0cyBmcm9tIERUTSwgaW4gd2hpY2ggZWFjaCBhc3NldCBoYXMgYSBkaWZmZXJlbnQgaWNvblxuICAgICAgICAgICAgICAtLT5cbiAgICAgICAgICAgICAgPGlcbiAgICAgICAgICAgICAgICBjbGFzcz1cIm0tci04IHRleHQtMTZcIlxuICAgICAgICAgICAgICAgIGM4eUljb249XCJjOHktZ3JvdXBcIlxuICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJ7eyBpbnZlbnRvcnlSb2xlLm1hbmFnZWRPYmplY3QgfCBtb05hbWUgfCBhc3luYyB9fVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyBpbnZlbnRvcnlSb2xlLm1hbmFnZWRPYmplY3QgfCBtb05hbWUgfCBhc3luYyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTZcIj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWdyb3VwIG0tYi0wXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJ7eyAnSW52ZW50b3J5IHJvbGVzJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxjOHktc2VsZWN0LWxlZ2FjeVxuICAgICAgICAgICAgICAgIFtpZF09XCInaXInICsgaWR4ICsgYWNjZXNzTWFwcGluZ0luZGV4XCJcbiAgICAgICAgICAgICAgICBbaXRlbXNdPVwiaW52ZW50b3J5Um9sZXNcIlxuICAgICAgICAgICAgICAgIFtzZWxlY3RlZF09XCJzZWxlY3RlZEludmVudG9yeVJvbGVzW2ludmVudG9yeVJvbGUubWFuYWdlZE9iamVjdF1cIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlQXBwbHlPbk5vU2VsZWN0aW9uXT1cInRydWVcIlxuICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJcbiAgICAgICAgICAgICAgICAgIGNvbnRyb2xDb250YWluZXIuY29udHJvbC5tYXJrQXNEaXJ0eSgpO1xuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJbnZlbnRvcnlSb2xlc1tpbnZlbnRvcnlSb2xlLm1hbmFnZWRPYmplY3RdID0gJGV2ZW50O1xuICAgICAgICAgICAgICAgICAgaW52ZW50b3J5Um9sZS5yb2xlSWRzID0gZ2V0SWRzKCRldmVudClcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+PC9jOHktc2VsZWN0LWxlZ2FjeT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtMVwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBjbGFzcz1cImJ0biBidG4tZG90IGJ0bi1kb3QtLWRhbmdlciBoaWRkZW4teHMgaGlkZGVuLXNtXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInUmVtb3ZlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIHRvb2x0aXA9XCJ7eyAnUmVtb3ZlJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAgIG5hbWU9XCJyZW1vdmVCdXR0b25cIlxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbnRyb2xDb250YWluZXIuY29udHJvbC5tYXJrQXNEaXJ0eSgpOyByZW1vdmVJbnZlbnRvcnlSb2xlKGludmVudG9yeVJvbGUpXCJcbiAgICAgICAgICAgICAgW2RlbGF5XT1cIjMwMFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGM4eUljb249XCJtaW51cy1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRhbmdlciBidG4tYmxvY2sgYnRuLXNtIHZpc2libGUteHMgdmlzaWJsZS1zbVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwie3sgJ1JlbW92ZScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICBuYW1lPVwicmVtb3ZlQnV0dG9uXCJcbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjb250cm9sQ29udGFpbmVyLmNvbnRyb2wubWFya0FzRGlydHkoKTsgcmVtb3ZlSW52ZW50b3J5Um9sZShpbnZlbnRvcnlSb2xlKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGM4eUljb249XCJtaW51cy1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5SZW1vdmU8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBtLXQtMTZcIlxuICAgICAgICB0aXRsZT1cInt7ICdBZGQgaW52ZW50b3J5IHJvbGVzJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIGlkPVwiYWRkLWludmVudG9yeS1yb2xlcy1idXR0b25cIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgKGNsaWNrKT1cImFkZEludmVudG9yeVJvbGVzKClcIlxuICAgICAgPlxuICAgICAgICA8aVxuICAgICAgICAgIGNsYXNzPVwibS1yLTRcIlxuICAgICAgICAgIGM4eUljb249XCJwbHVzLWNpcmNsZVwiXG4gICAgICAgID48L2k+XG4gICAgICAgIHt7ICdBZGQgaW52ZW50b3J5IHJvbGVzJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgPC9maWVsZHNldD5cbiAgPC9kaXY+XG48L2ZpZWxkc2V0PlxuIl19