@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
54 lines • 18.9 kB
JavaScript
import { Component, Input } from '@angular/core';
import { BottomDrawerRef, PluginsService } from '@c8y/ngx-components';
import { defaultPackageTypes, EcosystemService } from '@c8y/ngx-components/ecosystem/shared';
import { BehaviorSubject, map, Observable } from 'rxjs';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
import * as i2 from "@c8y/ngx-components/ecosystem/shared";
import * as i3 from "@angular/common";
import * as i4 from "./plugin-list.component";
import * as i5 from "./only-latest-filter/only-latest-filter.component";
export class InstallPluginComponent {
constructor(bottomDrawerRef, ecosystemService, pluginsService) {
this.bottomDrawerRef = bottomDrawerRef;
this.ecosystemService = ecosystemService;
this.pluginsService = pluginsService;
this.filteredPlugins$ = new BehaviorSubject([]);
this.selectedPlugins = [];
this.packageTypes = defaultPackageTypes;
this.result = new Promise((resolve, reject) => {
this._install = resolve;
this._cancel = reject;
});
this.onlyLatestPluginVersion = true;
}
setFilterPipe(filterPipe) {
this.filteredPlugins$ = this.plugins$.pipe(map(plugins => plugins.map(plugin => {
plugin.filterProps = this.ecosystemService.getAppFilterProps(plugin.originApp);
return plugin;
})), src => filterPipe(src));
}
cancel() {
this.bottomDrawerRef.close();
this._cancel();
}
install() {
this._install(this.selectedPlugins);
this.bottomDrawerRef.close();
}
async showPluginOverview(plugin) {
this.selectedPlugin = plugin;
const baseUrl = `/apps/${plugin.id}/`;
this.pluginBaseUrl = baseUrl;
this.pluginMarkdown = await this.pluginsService.getReadmeFileContent(baseUrl);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InstallPluginComponent, deps: [{ token: i1.BottomDrawerRef }, { token: i2.EcosystemService }, { token: i1.PluginsService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: InstallPluginComponent, selector: "c8y-install-plugin", inputs: { plugins$: "plugins$" }, host: { classAttribute: "d-contents" }, ngImport: i0, template: " <div class=\"card-header gap-8 d-col p-l-24 p-r-24 separator-bottom flex-no-shrink\">\n <div\n class=\"card-title h4 text-center\"\n translate\n >\n Available plugins\n </div>\n <c8y-list-filters\n (filterPipeChange)=\"setFilterPipe($event)\"\n [packageTypes]=\"packageTypes\"\n >\n <c8y-archived-filter></c8y-archived-filter>\n <c8y-only-latest-filter></c8y-only-latest-filter>\n </c8y-list-filters>\n </div>\n <div class=\"d-grid grid__col--5-7--md min-height-0 flex-grow\">\n <c8y-plugin-list\n class=\"inner-scroll bg-level-1\"\n (selectedItems)=\"selectedPlugins = $event\"\n [emptyListText]=\"'No matching plugins' | translate\"\n [plugins$]=\"filteredPlugins$\"\n [selectable]=\"true\"\n [selectedPlugin]=\"selectedPlugin\"\n (showOverview)=\"showPluginOverview($event)\"\n ></c8y-plugin-list>\n <div class=\"inner-scroll bg-component\">\n <div class=\"card-header separator sticky-top bg-inherit\"\n *ngIf=\"pluginMarkdown\">\n <button\n class=\"m-l-auto btn-clean\"\n title=\"{{ 'Close' | translate }}\"\n type=\"button\"\n (click)=\"selectedPlugin = null; pluginMarkdown = null\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n <div class=\"card-block p-l-24 p-r-24\">\n <div\n class=\"markdown-content\"\n *ngIf=\"pluginMarkdown\"\n [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n ></div>\n <c8y-ui-empty-state\n [icon]=\"'user-manual'\"\n [title]=\"'No plugin selected' | translate\"\n [subtitle]=\"\n 'Select a plugin from the list to view its documentation.' | translate\"\n *ngIf=\"!pluginMarkdown\"\n [horizontal]=\"true\"\n >\n <p>\n <small >\n {{ 'Documentation availability varies by plugin.' | translate }}\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n </div>\n </div>\n <div class=\"text-center card-footer p-24 separator\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"install-plugin--cancel-button\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Install' | translate }}\"\n type=\"button\"\n (click)=\"install()\"\n [disabled]=\"selectedPlugins.length === 0\"\n data-cy=\"install-plugin--install-button\"\n >\n {{ 'Install' | translate }}\n <span\n class=\"badge\"\n *ngIf=\"selectedPlugins.length as length\"\n >\n {{ length }}\n </span>\n </button>\n </div>\n\n", dependencies: [{ kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ListFiltersComponent, selector: "c8y-list-filters", inputs: ["packageTypes", "packageAvailabilities", "packageContents"], outputs: ["filterPipeChange"] }, { kind: "component", type: i2.ArchivedFilterComponent, selector: "c8y-archived-filter" }, { kind: "component", type: i4.PluginListComponent, selector: "c8y-plugin-list", inputs: ["plugins$", "emptyListText", "selectable", "hideSource", "installable", "package", "selectedPlugin"], outputs: ["selectedItems", "showOverview"] }, { kind: "component", type: i5.OnlyLatestFilterComponent, selector: "c8y-only-latest-filter" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.MarkdownToHtmlPipe, name: "markdownToHtml" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: InstallPluginComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-install-plugin', host: { class: 'd-contents' }, template: " <div class=\"card-header gap-8 d-col p-l-24 p-r-24 separator-bottom flex-no-shrink\">\n <div\n class=\"card-title h4 text-center\"\n translate\n >\n Available plugins\n </div>\n <c8y-list-filters\n (filterPipeChange)=\"setFilterPipe($event)\"\n [packageTypes]=\"packageTypes\"\n >\n <c8y-archived-filter></c8y-archived-filter>\n <c8y-only-latest-filter></c8y-only-latest-filter>\n </c8y-list-filters>\n </div>\n <div class=\"d-grid grid__col--5-7--md min-height-0 flex-grow\">\n <c8y-plugin-list\n class=\"inner-scroll bg-level-1\"\n (selectedItems)=\"selectedPlugins = $event\"\n [emptyListText]=\"'No matching plugins' | translate\"\n [plugins$]=\"filteredPlugins$\"\n [selectable]=\"true\"\n [selectedPlugin]=\"selectedPlugin\"\n (showOverview)=\"showPluginOverview($event)\"\n ></c8y-plugin-list>\n <div class=\"inner-scroll bg-component\">\n <div class=\"card-header separator sticky-top bg-inherit\"\n *ngIf=\"pluginMarkdown\">\n <button\n class=\"m-l-auto btn-clean\"\n title=\"{{ 'Close' | translate }}\"\n type=\"button\"\n (click)=\"selectedPlugin = null; pluginMarkdown = null\"\n >\n <i c8yIcon=\"times\"></i>\n </button>\n </div>\n <div class=\"card-block p-l-24 p-r-24\">\n <div\n class=\"markdown-content\"\n *ngIf=\"pluginMarkdown\"\n [innerHTML]=\"pluginMarkdown | markdownToHtml: { baseUrl: pluginBaseUrl } | async\"\n ></div>\n <c8y-ui-empty-state\n [icon]=\"'user-manual'\"\n [title]=\"'No plugin selected' | translate\"\n [subtitle]=\"\n 'Select a plugin from the list to view its documentation.' | translate\"\n *ngIf=\"!pluginMarkdown\"\n [horizontal]=\"true\"\n >\n <p>\n <small >\n {{ 'Documentation availability varies by plugin.' | translate }}\n </small>\n </p>\n </c8y-ui-empty-state>\n </div>\n </div>\n </div>\n <div class=\"text-center card-footer p-24 separator\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n data-cy=\"install-plugin--cancel-button\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Install' | translate }}\"\n type=\"button\"\n (click)=\"install()\"\n [disabled]=\"selectedPlugins.length === 0\"\n data-cy=\"install-plugin--install-button\"\n >\n {{ 'Install' | translate }}\n <span\n class=\"badge\"\n *ngIf=\"selectedPlugins.length as length\"\n >\n {{ length }}\n </span>\n </button>\n </div>\n\n" }]
}], ctorParameters: () => [{ type: i1.BottomDrawerRef }, { type: i2.EcosystemService }, { type: i1.PluginsService }], propDecorators: { plugins$: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC1wbHVnaW4uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZWNvc3lzdGVtL2FwcGxpY2F0aW9uLXBsdWdpbnMvaW5zdGFsbC1wbHVnaW4uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vZWNvc3lzdGVtL2FwcGxpY2F0aW9uLXBsdWdpbnMvaW5zdGFsbC1wbHVnaW4uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFxQixlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDekYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixnQkFBZ0IsRUFHakIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZUFBZSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7QUFPeEQsTUFBTSxPQUFPLHNCQUFzQjtJQWlCakMsWUFDVSxlQUF3RCxFQUN4RCxnQkFBa0MsRUFDbEMsY0FBOEI7UUFGOUIsb0JBQWUsR0FBZixlQUFlLENBQXlDO1FBQ3hELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBbEJ4QyxxQkFBZ0IsR0FBd0MsSUFBSSxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEYsb0JBQWUsR0FBd0IsRUFBRSxDQUFDO1FBQzFDLGlCQUFZLEdBQUcsbUJBQW1CLENBQUM7UUFDbkMsV0FBTSxHQUFpQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUNyRSxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztZQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztRQUNILDRCQUF1QixHQUFHLElBQUksQ0FBQztJQVk1QixDQUFDO0lBRUosYUFBYSxDQUFDLFVBQXNCO1FBQ2xDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FDeEMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQ1osT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNuQixNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0UsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQ0gsRUFDRCxHQUFHLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FDdkIsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBeUI7UUFDaEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUM7UUFDN0IsTUFBTSxPQUFPLEdBQUcsU0FBUyxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUM7UUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEYsQ0FBQzsrR0FsRFUsc0JBQXNCO21HQUF0QixzQkFBc0Isb0lDZm5DLGl6RkF3RkE7OzRGRHpFYSxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0Usb0JBQW9CLFFBQ3hCLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRTtnSkFJcEIsUUFBUTtzQkFBaEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFwcGxpY2F0aW9uUGx1Z2luLCBCb3R0b21EcmF3ZXJSZWYsIFBsdWdpbnNTZXJ2aWNlIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5pbXBvcnQge1xuICBkZWZhdWx0UGFja2FnZVR5cGVzLFxuICBFY29zeXN0ZW1TZXJ2aWNlLFxuICBGaWx0ZXJhYmxlQXBwT3JQbHVnaW4sXG4gIEZpbHRlclBpcGVcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9lY29zeXN0ZW0vc2hhcmVkJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgbWFwLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1pbnN0YWxsLXBsdWdpbicsXG4gIGhvc3Q6IHsgY2xhc3M6ICdkLWNvbnRlbnRzJyB9LFxuICB0ZW1wbGF0ZVVybDogJy4vaW5zdGFsbC1wbHVnaW4uY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIEluc3RhbGxQbHVnaW5Db21wb25lbnQge1xuICBASW5wdXQoKSBwbHVnaW5zJDogT2JzZXJ2YWJsZTxGaWx0ZXJhYmxlQXBwT3JQbHVnaW5bXT47XG4gIGZpbHRlcmVkUGx1Z2lucyQ6IE9ic2VydmFibGU8RmlsdGVyYWJsZUFwcE9yUGx1Z2luW10+ID0gbmV3IEJlaGF2aW9yU3ViamVjdChbXSk7XG4gIHNlbGVjdGVkUGx1Z2luczogQXBwbGljYXRpb25QbHVnaW5bXSA9IFtdO1xuICBwYWNrYWdlVHlwZXMgPSBkZWZhdWx0UGFja2FnZVR5cGVzO1xuICByZXN1bHQ6IFByb21pc2U8QXBwbGljYXRpb25QbHVnaW5bXT4gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdGhpcy5faW5zdGFsbCA9IHJlc29sdmU7XG4gICAgdGhpcy5fY2FuY2VsID0gcmVqZWN0O1xuICB9KTtcbiAgb25seUxhdGVzdFBsdWdpblZlcnNpb24gPSB0cnVlO1xuICBzZWxlY3RlZFBsdWdpbjogQXBwbGljYXRpb25QbHVnaW47XG4gIHBsdWdpbkJhc2VVcmw6IHN0cmluZztcbiAgcGx1Z2luTWFya2Rvd246IHN0cmluZztcblxuICBwcml2YXRlIF9pbnN0YWxsO1xuICBwcml2YXRlIF9jYW5jZWw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBib3R0b21EcmF3ZXJSZWY6IEJvdHRvbURyYXdlclJlZjxJbnN0YWxsUGx1Z2luQ29tcG9uZW50PixcbiAgICBwcml2YXRlIGVjb3N5c3RlbVNlcnZpY2U6IEVjb3N5c3RlbVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwbHVnaW5zU2VydmljZTogUGx1Z2luc1NlcnZpY2VcbiAgKSB7fVxuXG4gIHNldEZpbHRlclBpcGUoZmlsdGVyUGlwZTogRmlsdGVyUGlwZSkge1xuICAgIHRoaXMuZmlsdGVyZWRQbHVnaW5zJCA9IHRoaXMucGx1Z2lucyQucGlwZShcbiAgICAgIG1hcChwbHVnaW5zID0+XG4gICAgICAgIHBsdWdpbnMubWFwKHBsdWdpbiA9PiB7XG4gICAgICAgICAgcGx1Z2luLmZpbHRlclByb3BzID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmdldEFwcEZpbHRlclByb3BzKHBsdWdpbi5vcmlnaW5BcHApO1xuICAgICAgICAgIHJldHVybiBwbHVnaW47XG4gICAgICAgIH0pXG4gICAgICApLFxuICAgICAgc3JjID0+IGZpbHRlclBpcGUoc3JjKVxuICAgICk7XG4gIH1cblxuICBjYW5jZWwoKSB7XG4gICAgdGhpcy5ib3R0b21EcmF3ZXJSZWYuY2xvc2UoKTtcbiAgICB0aGlzLl9jYW5jZWwoKTtcbiAgfVxuXG4gIGluc3RhbGwoKSB7XG4gICAgdGhpcy5faW5zdGFsbCh0aGlzLnNlbGVjdGVkUGx1Z2lucyk7XG4gICAgdGhpcy5ib3R0b21EcmF3ZXJSZWYuY2xvc2UoKTtcbiAgfVxuXG4gIGFzeW5jIHNob3dQbHVnaW5PdmVydmlldyhwbHVnaW46IEFwcGxpY2F0aW9uUGx1Z2luKSB7XG4gICAgdGhpcy5zZWxlY3RlZFBsdWdpbiA9IHBsdWdpbjtcbiAgICBjb25zdCBiYXNlVXJsID0gYC9hcHBzLyR7cGx1Z2luLmlkfS9gO1xuICAgIHRoaXMucGx1Z2luQmFzZVVybCA9IGJhc2VVcmw7XG4gICAgdGhpcy5wbHVnaW5NYXJrZG93biA9IGF3YWl0IHRoaXMucGx1Z2luc1NlcnZpY2UuZ2V0UmVhZG1lRmlsZUNvbnRlbnQoYmFzZVVybCk7XG4gIH1cbn1cbiIsIiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIGdhcC04IGQtY29sIHAtbC0yNCBwLXItMjQgc2VwYXJhdG9yLWJvdHRvbSBmbGV4LW5vLXNocmlua1wiPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiY2FyZC10aXRsZSBoNCB0ZXh0LWNlbnRlclwiXG4gICAgICB0cmFuc2xhdGVcbiAgICA+XG4gICAgICBBdmFpbGFibGUgcGx1Z2luc1xuICAgIDwvZGl2PlxuICAgIDxjOHktbGlzdC1maWx0ZXJzXG4gICAgICAoZmlsdGVyUGlwZUNoYW5nZSk9XCJzZXRGaWx0ZXJQaXBlKCRldmVudClcIlxuICAgICAgW3BhY2thZ2VUeXBlc109XCJwYWNrYWdlVHlwZXNcIlxuICAgID5cbiAgICAgIDxjOHktYXJjaGl2ZWQtZmlsdGVyPjwvYzh5LWFyY2hpdmVkLWZpbHRlcj5cbiAgICAgIDxjOHktb25seS1sYXRlc3QtZmlsdGVyPjwvYzh5LW9ubHktbGF0ZXN0LWZpbHRlcj5cbiAgICA8L2M4eS1saXN0LWZpbHRlcnM+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZC1ncmlkIGdyaWRfX2NvbC0tNS03LS1tZCBtaW4taGVpZ2h0LTAgZmxleC1ncm93XCI+XG4gICAgPGM4eS1wbHVnaW4tbGlzdFxuICAgICAgY2xhc3M9XCJpbm5lci1zY3JvbGwgYmctbGV2ZWwtMVwiXG4gICAgICAoc2VsZWN0ZWRJdGVtcyk9XCJzZWxlY3RlZFBsdWdpbnMgPSAkZXZlbnRcIlxuICAgICAgW2VtcHR5TGlzdFRleHRdPVwiJ05vIG1hdGNoaW5nIHBsdWdpbnMnIHwgdHJhbnNsYXRlXCJcbiAgICAgIFtwbHVnaW5zJF09XCJmaWx0ZXJlZFBsdWdpbnMkXCJcbiAgICAgIFtzZWxlY3RhYmxlXT1cInRydWVcIlxuICAgICAgW3NlbGVjdGVkUGx1Z2luXT1cInNlbGVjdGVkUGx1Z2luXCJcbiAgICAgIChzaG93T3ZlcnZpZXcpPVwic2hvd1BsdWdpbk92ZXJ2aWV3KCRldmVudClcIlxuICAgID48L2M4eS1wbHVnaW4tbGlzdD5cbiAgICA8ZGl2IGNsYXNzPVwiaW5uZXItc2Nyb2xsIGJnLWNvbXBvbmVudFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIHNlcGFyYXRvciBzdGlja3ktdG9wIGJnLWluaGVyaXRcIlxuICAgICAgICAqbmdJZj1cInBsdWdpbk1hcmtkb3duXCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBjbGFzcz1cIm0tbC1hdXRvIGJ0bi1jbGVhblwiXG4gICAgICAgICAgdGl0bGU9XCJ7eyAnQ2xvc2UnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0ZWRQbHVnaW4gPSBudWxsOyBwbHVnaW5NYXJrZG93biA9IG51bGxcIlxuICAgICAgICA+XG4gICAgICAgICAgPGkgYzh5SWNvbj1cInRpbWVzXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYmxvY2sgcC1sLTI0IHAtci0yNFwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJtYXJrZG93bi1jb250ZW50XCJcbiAgICAgICAgICAqbmdJZj1cInBsdWdpbk1hcmtkb3duXCJcbiAgICAgICAgICBbaW5uZXJIVE1MXT1cInBsdWdpbk1hcmtkb3duIHwgbWFya2Rvd25Ub0h0bWw6IHsgYmFzZVVybDogcGx1Z2luQmFzZVVybCB9IHwgYXN5bmNcIlxuICAgICAgICA+PC9kaXY+XG4gICAgICAgIDxjOHktdWktZW1wdHktc3RhdGVcbiAgICAgICAgICBbaWNvbl09XCIndXNlci1tYW51YWwnXCJcbiAgICAgICAgICBbdGl0bGVdPVwiJ05vIHBsdWdpbiBzZWxlY3RlZCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgIFtzdWJ0aXRsZV09XCJcbiAgICAgICAgICAgICdTZWxlY3QgYSBwbHVnaW4gZnJvbSB0aGUgbGlzdCB0byB2aWV3IGl0cyBkb2N1bWVudGF0aW9uLicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICpuZ0lmPVwiIXBsdWdpbk1hcmtkb3duXCJcbiAgICAgICAgICBbaG9yaXpvbnRhbF09XCJ0cnVlXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxwPlxuICAgICAgICAgICAgPHNtYWxsID5cbiAgICAgICAgICAgICAge3sgJ0RvY3VtZW50YXRpb24gYXZhaWxhYmlsaXR5IHZhcmllcyBieSBwbHVnaW4uJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgICA8L3A+XG4gICAgICAgPC9jOHktdWktZW1wdHktc3RhdGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciBjYXJkLWZvb3RlciBwLTI0IHNlcGFyYXRvclwiPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgIHRpdGxlPVwie3sgJ0NhbmNlbCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAoY2xpY2spPVwiY2FuY2VsKClcIlxuICAgICAgZGF0YS1jeT1cImluc3RhbGwtcGx1Z2luLS1jYW5jZWwtYnV0dG9uXCJcbiAgICA+XG4gICAgICB7eyAnQ2FuY2VsJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgIHRpdGxlPVwie3sgJ0luc3RhbGwnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgKGNsaWNrKT1cImluc3RhbGwoKVwiXG4gICAgICBbZGlzYWJsZWRdPVwic2VsZWN0ZWRQbHVnaW5zLmxlbmd0aCA9PT0gMFwiXG4gICAgICBkYXRhLWN5PVwiaW5zdGFsbC1wbHVnaW4tLWluc3RhbGwtYnV0dG9uXCJcbiAgICA+XG4gICAgICB7eyAnSW5zdGFsbCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDxzcGFuXG4gICAgICAgIGNsYXNzPVwiYmFkZ2VcIlxuICAgICAgICAqbmdJZj1cInNlbGVjdGVkUGx1Z2lucy5sZW5ndGggYXMgbGVuZ3RoXCJcbiAgICAgID5cbiAgICAgICAge3sgbGVuZ3RoIH19XG4gICAgICA8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4iXX0=