@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
216 lines • 33.4 kB
JavaScript
import { Component, ContentChild, ContentChildren, ElementRef, EventEmitter, HostBinding, Input, Output, QueryList } from '@angular/core';
import { Subject } from 'rxjs';
import { delay, filter, takeUntil, tap } from 'rxjs/operators';
import { ListItemActionComponent } from './list-item-action.component';
import { ListItemCollapseComponent } from './list-item-collapse.component';
import { ListItemFooterComponent } from './list-item-footer.component';
import * as i0 from "@angular/core";
import * as i1 from "../common/icon.directive";
import * as i2 from "@angular/common";
import * as i3 from "../common/dropdown-direction.directive";
import * as i4 from "ngx-bootstrap/collapse";
import * as i5 from "ngx-bootstrap/dropdown";
import * as i6 from "@angular/cdk/a11y";
import * as i7 from "../i18n/c8y-translate.pipe";
/**
* A list item is a representation of an item inside a list and
* can be used to compose different styles in a list (mainly in a
* <c8y-group-list>-component but also in others like the
* <c8y-typeahead>-component):
* - a list with a footer
* - a list with one or multiple actions
* - an icon
* - a checkbox or radio input
*
* The item can be composed via content projection. The following
* example shows a radio list with an icon, two actions
* and a footer:
* ```html
* <c8y-list-group>
* <c8y-li
* *c8yFor="
* let device of devices;
* let i = index;
* "
* >
* <c8y-li-radio (onSelect)="updateSelected($event, device)"></c8y-li-radio>
* <c8y-li-icon [icon]="'rocket'"></c8y-li-icon>
* {{ i + 1 }}. {{ device.name || '-' }}
* <c8y-li-footer>
* Device id: <a [routerLink]="['/device', device.id]">{{ device.id }}</a>
* </c8y-li-footer>
* <c8y-li-action (click)="deleteDevice(device.id)" icon="times">
* Delete
* </c8y-li-action>
* <c8y-li-action (click)="(false)" icon="rocket">
* Launch to space
* </c8y-li-action>
* </c8y-li>
* </c8y-list-group>
* ```
*/
export class ListItemComponent {
/**
* @ignore
*/
constructor(element) {
this.element = element;
/**
* If set to true, the class "active" is added which
* indicates that the current row is active.
*/
this.active = false;
/**
* If set to true, the class "highlighted" is added which
* indicates that the current row is highlighted.
*/
this.highlighted = false;
/**
* If set to true, the class "c8y-list__item--empty-actions" is added which adds
* additional padding to compensate for the "actions" column in other list items.
*/
this.emptyActions = false;
/**
* If set to true, the item will be displayed in a dense style.
*/
this.dense = false;
/**
* Indicates if the current list item is collapsed. You can trigger the collapsing from
* any element event by toggling this value.
*
* ```html
* <c8y-li #li (click)="li.collapsed = !li.collapsed">
* Toggle
* <c8y-li-collapse>
* I can be toggled by clicking on the row.
* </c8y-li-collapse
* </c8y-li>
* ```
*/
this.collapsed = true;
/**
* Indicates if the current list item is selectable.
*/
this.selectable = true;
/**
* An event emitter which is triggered when the user collapses the content
* via the chevron on the right.
*/
this.collapsedChange = new EventEmitter();
/**
* @ignore
*/
this.showFooter = false;
/**
* @ignore
*/
this.showActions = false;
/**
* @ignore
*/
this.showCollapse = false;
this.pulse$ = new Subject();
this.destroy$ = new Subject();
this.ACTION_ITEM_HEIGHT = 40;
}
/**
* @ignore
*/
ngOnInit() {
this.pulse$
.pipe(filter(apply => !!apply), tap(() => this.element.nativeElement.classList.remove('c8y-list--pulse')), delay(100), tap(() => this.element.nativeElement.classList.add('c8y-list--pulse')), takeUntil(this.destroy$))
.subscribe();
}
/**
* @ignore
*/
ngAfterContentChecked() {
this.actions = this.itemActions.toArray();
this.showFooter = this.itemFooter != null;
this.showActions = this.itemActions.length > 0;
this.showCollapse = this.itemCollapse != null;
}
/**
* @ignore
*/
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* Toggles the collapse state and emits this state as
* collapsedChange output as boolean.
* @param $event Pass optional an event to stop propagation.
*/
toggleCollapsed($event) {
if ($event) {
$event.stopPropagation();
}
this.collapsed = !this.collapsed;
this.collapsedChange.emit(this.collapsed);
}
/**
* Toggles the collapse state in case the `collapseWay` is set to `row` and emits this state as
* collapsedChange output as boolean.
*/
rowToggleCollapsed() {
if (!this.itemCollapse || this.itemCollapse.collapseWay !== 'row') {
return;
}
this.toggleCollapsed();
}
/**
* Highlights the list-item. This method should be used to show the
* user that something within this item was changed.
*/
pulse() {
this.pulse$.next(true);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListItemComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: { active: "active", highlighted: "highlighted", emptyActions: "emptyActions", dense: "dense", collapsed: "collapsed", selectable: "selectable" }, outputs: { collapsedChange: "collapsedChange" }, host: { properties: { "class.active": "this.active", "class.highlighted": "this.highlighted", "class.c8y-list__item--empty-actions": "this.emptyActions", "class.c8y-list__item--dense": "this.dense", "class.selectable": "this.selectable" }, classAttribute: "c8y-list__item" }, queries: [{ propertyName: "itemFooter", first: true, predicate: ListItemFooterComponent, descendants: true }, { propertyName: "itemCollapse", first: true, predicate: ListItemCollapseComponent, descendants: true }, { propertyName: "itemActions", predicate: ListItemActionComponent }], ngImport: i0, template: "<div\n [ngClass]=\"{ expanded: !collapsed, interact: itemCollapse && itemCollapse.collapseWay === 'row' }\"\n>\n <div class=\"c8y-list__item__block\">\n <ng-content select=\"c8y-list-item-drag-handle, c8y-li-drag-handle\"></ng-content>\n <ng-content select=\"c8y-list-item-radio, c8y-li-radio\"></ng-content>\n <ng-content select=\"c8y-list-item-checkbox, c8y-li-checkbox\"></ng-content>\n\n <ng-content select=\"c8y-list-item-icon, c8y-li-icon\"></ng-content>\n\n <div\n class=\"c8y-list__item__body text-truncate-wrap\"\n (click)=\"rowToggleCollapsed()\"\n >\n <ng-content select=\"c8y-list-item-body, c8y-li-body\"></ng-content>\n <ng-content></ng-content>\n <div\n class=\"c8y-list__item__footer\"\n *ngIf=\"showFooter\"\n >\n <ng-content select=\"c8y-list-item-footer, c8y-li-footer\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"c8y-list__item__actions\"\n *ngIf=\"(showCollapse && itemCollapse && itemCollapse.collapseWay === 'button') || showActions\"\n >\n <button\n class=\"collapse-btn\"\n title=\"{{ 'Expand' | translate }}\"\n [attr.aria-expanded]=\"!collapsed\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n *ngIf=\"showCollapse && itemCollapse.collapseWay === 'button'\"\n data-cy=\"c8y-li--collapse-btn\"\n >\n <i [c8yIcon]=\"'chevron-down'\"></i>\n </button>\n <div\n class=\"dropdown\"\n #liDropdownActions=\"bs-dropdown\"\n [cdkTrapFocus]=\"liDropdownActions.isOpen\"\n dropdown\n c8yDropdownDirection\n #dropDirection=\"bs-dropdown\"\n [cdkTrapFocus]=\"dropDirection.isOpen\"\n *ngIf=\"showActions\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n type=\"button\"\n dropdownToggle\n data-cy=\"c8y-li--actions-btn\"\n >\n <i [c8yIcon]=\"'ellipsis-v'\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n data-cy=\"list-item--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"c8y-list-item-action, c8y-li-action\"></ng-content>\n <ng-container *ngFor=\"let action of actions\">\n <ng-container *ngTemplateOutlet=\"action.template\"></ng-container>\n </ng-container>\n </ul>\n </div>\n\n <ng-content\n select=\"c8y-list-item-action, c8y-li-action\"\n *ngIf=\"showActions\"\n ></ng-content>\n </div>\n </div>\n\n <div\n *ngIf=\"showCollapse\"\n [collapse]=\"collapsed\"\n [isAnimated]=\"true\"\n >\n <div class=\"c8y-list__item__collapse--container\">\n <ng-content select=\"c8y-list-item-collapse, c8y-li-collapse\"></ng-content>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.DropdownDirectionDirective, selector: "[dropdown][c8yBsDropdownDirection],[dropdown][c8yDropdownDirection]" }, { kind: "directive", type: i4.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "directive", type: i5.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i5.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i5.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: i6.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "pipe", type: i7.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ListItemComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-list-item, c8y-li', host: {
class: 'c8y-list__item'
}, template: "<div\n [ngClass]=\"{ expanded: !collapsed, interact: itemCollapse && itemCollapse.collapseWay === 'row' }\"\n>\n <div class=\"c8y-list__item__block\">\n <ng-content select=\"c8y-list-item-drag-handle, c8y-li-drag-handle\"></ng-content>\n <ng-content select=\"c8y-list-item-radio, c8y-li-radio\"></ng-content>\n <ng-content select=\"c8y-list-item-checkbox, c8y-li-checkbox\"></ng-content>\n\n <ng-content select=\"c8y-list-item-icon, c8y-li-icon\"></ng-content>\n\n <div\n class=\"c8y-list__item__body text-truncate-wrap\"\n (click)=\"rowToggleCollapsed()\"\n >\n <ng-content select=\"c8y-list-item-body, c8y-li-body\"></ng-content>\n <ng-content></ng-content>\n <div\n class=\"c8y-list__item__footer\"\n *ngIf=\"showFooter\"\n >\n <ng-content select=\"c8y-list-item-footer, c8y-li-footer\"></ng-content>\n </div>\n </div>\n\n <div\n class=\"c8y-list__item__actions\"\n *ngIf=\"(showCollapse && itemCollapse && itemCollapse.collapseWay === 'button') || showActions\"\n >\n <button\n class=\"collapse-btn\"\n title=\"{{ 'Expand' | translate }}\"\n [attr.aria-expanded]=\"!collapsed\"\n type=\"button\"\n (click)=\"toggleCollapsed($event)\"\n *ngIf=\"showCollapse && itemCollapse.collapseWay === 'button'\"\n data-cy=\"c8y-li--collapse-btn\"\n >\n <i [c8yIcon]=\"'chevron-down'\"></i>\n </button>\n <div\n class=\"dropdown\"\n #liDropdownActions=\"bs-dropdown\"\n [cdkTrapFocus]=\"liDropdownActions.isOpen\"\n dropdown\n c8yDropdownDirection\n #dropDirection=\"bs-dropdown\"\n [cdkTrapFocus]=\"dropDirection.isOpen\"\n *ngIf=\"showActions\"\n >\n <button\n class=\"dropdown-toggle c8y-dropdown\"\n title=\"{{ 'Actions' | translate }}\"\n type=\"button\"\n dropdownToggle\n data-cy=\"c8y-li--actions-btn\"\n >\n <i [c8yIcon]=\"'ellipsis-v'\"></i>\n </button>\n <ul\n class=\"dropdown-menu dropdown-menu-right\"\n data-cy=\"list-item--dropdown-menu\"\n *dropdownMenu\n >\n <ng-content select=\"c8y-list-item-action, c8y-li-action\"></ng-content>\n <ng-container *ngFor=\"let action of actions\">\n <ng-container *ngTemplateOutlet=\"action.template\"></ng-container>\n </ng-container>\n </ul>\n </div>\n\n <ng-content\n select=\"c8y-list-item-action, c8y-li-action\"\n *ngIf=\"showActions\"\n ></ng-content>\n </div>\n </div>\n\n <div\n *ngIf=\"showCollapse\"\n [collapse]=\"collapsed\"\n [isAnimated]=\"true\"\n >\n <div class=\"c8y-list__item__collapse--container\">\n <ng-content select=\"c8y-list-item-collapse, c8y-li-collapse\"></ng-content>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { active: [{
type: Input
}, {
type: HostBinding,
args: ['class.active']
}], highlighted: [{
type: Input
}, {
type: HostBinding,
args: ['class.highlighted']
}], emptyActions: [{
type: Input
}, {
type: HostBinding,
args: ['class.c8y-list__item--empty-actions']
}], dense: [{
type: Input
}, {
type: HostBinding,
args: ['class.c8y-list__item--dense']
}], collapsed: [{
type: Input
}], selectable: [{
type: Input
}, {
type: HostBinding,
args: ['class.selectable']
}], collapsedChange: [{
type: Output
}], itemFooter: [{
type: ContentChild,
args: [ListItemFooterComponent, { static: false }]
}], itemActions: [{
type: ContentChildren,
args: [ListItemActionComponent]
}], itemCollapse: [{
type: ContentChild,
args: [ListItemCollapseComponent, { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2NvcmUvbGlzdC1ncm91cC9saXN0LWl0ZW0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vY29yZS9saXN0LWdyb3VwL2xpc3QtaXRlbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixlQUFlLEVBQ2YsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsS0FBSyxFQUNMLE1BQU0sRUFDTixTQUFTLEVBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDL0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7Ozs7OztBQUV2RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0NHO0FBUUgsTUFBTSxPQUFPLGlCQUFpQjtJQWtJNUI7O09BRUc7SUFDSCxZQUFtQixPQUFtQjtRQUFuQixZQUFPLEdBQVAsT0FBTyxDQUFZO1FBcEl0Qzs7O1dBR0c7UUFHSCxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBRWY7OztXQUdHO1FBR0gsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFFcEI7OztXQUdHO1FBR0gsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckI7O1dBRUc7UUFHSCxVQUFLLEdBQUcsS0FBSyxDQUFDO1FBRWQ7Ozs7Ozs7Ozs7OztXQVlHO1FBRUgsY0FBUyxHQUFHLElBQUks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VixLQUFLOztzQkFDTCxXQUFXO3VCQUFDLG1CQUFtQjtnQkFTaEMsWUFBWTtzQkFGWCxLQUFLOztzQkFDTCxXQUFXO3VCQUFDLHFDQUFxQztnQkFRbEQsS0FBSztzQkFGSixLQUFLOztzQkFDTCxXQUFXO3VCQUFDLDZCQUE2QjtnQkFpQjFDLFNBQVM7c0JBRFIsS0FBSztnQkFRTixVQUFVO3NCQUZULEtBQUs7O3NCQUNMLFdBQVc7dUJBQUMsa0JBQWtCO2dCQVEvQixlQUFlO3NCQURkLE1BQU07Z0JBZVAsVUFBVTtzQkFEVCxZQUFZO3VCQUFDLHVCQUF1QixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFvQnhELFdBQVc7c0JBRFYsZUFBZTt1QkFBQyx1QkFBdUI7Z0JBZXhDLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyx5QkFBeUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3Rcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheSwgZmlsdGVyLCB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IExpc3RJdGVtQWN0aW9uQ29tcG9uZW50IH0gZnJvbSAnLi9saXN0LWl0ZW0tYWN0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBMaXN0SXRlbUNvbGxhcHNlQ29tcG9uZW50IH0gZnJvbSAnLi9saXN0LWl0ZW0tY29sbGFwc2UuY29tcG9uZW50JztcbmltcG9ydCB7IExpc3RJdGVtRm9vdGVyQ29tcG9uZW50IH0gZnJvbSAnLi9saXN0LWl0ZW0tZm9vdGVyLmNvbXBvbmVudCc7XG5cbi8qKlxuICogQSBsaXN0IGl0ZW0gaXMgYSByZXByZXNlbnRhdGlvbiBvZiBhbiBpdGVtIGluc2lkZSBhIGxpc3QgYW5kXG4gKiBjYW4gYmUgdXNlZCB0byBjb21wb3NlIGRpZmZlcmVudCBzdHlsZXMgaW4gYSBsaXN0IChtYWlubHkgaW4gYVxuICogPGM4eS1ncm91cC1saXN0Pi1jb21wb25lbnQgYnV0IGFsc28gaW4gb3RoZXJzIGxpa2UgdGhlXG4gKiA8Yzh5LXR5cGVhaGVhZD4tY29tcG9uZW50KTpcbiAqICAtIGEgbGlzdCB3aXRoIGEgZm9vdGVyXG4gKiAgLSBhIGxpc3Qgd2l0aCBvbmUgb3IgbXVsdGlwbGUgYWN0aW9uc1xuICogIC0gYW4gaWNvblxuICogIC0gYSBjaGVja2JveCBvciByYWRpbyBpbnB1dFxuICpcbiAqIFRoZSBpdGVtIGNhbiBiZSBjb21wb3NlZCB2aWEgY29udGVudCBwcm9qZWN0aW9uLiBUaGUgZm9sbG93aW5nXG4gKiBleGFtcGxlIHNob3dzIGEgcmFkaW8gbGlzdCB3aXRoIGFuIGljb24sIHR3byBhY3Rpb25zXG4gKiBhbmQgYSBmb290ZXI6XG4gKiBgYGBodG1sXG4gKiA8Yzh5LWxpc3QtZ3JvdXA+XG4gKiAgIDxjOHktbGlcbiAqICAgICAqYzh5Rm9yPVwiXG4gKiAgICAgICBsZXQgZGV2aWNlIG9mIGRldmljZXM7XG4gKiAgICAgICBsZXQgaSA9IGluZGV4O1xuICogICAgIFwiXG4gKiAgID5cbiAqICAgICA8Yzh5LWxpLXJhZGlvIChvblNlbGVjdCk9XCJ1cGRhdGVTZWxlY3RlZCgkZXZlbnQsIGRldmljZSlcIj48L2M4eS1saS1yYWRpbz5cbiAqICAgICA8Yzh5LWxpLWljb24gW2ljb25dPVwiJ3JvY2tldCdcIj48L2M4eS1saS1pY29uPlxuICogICAgIHt7IGkgKyAxIH19LiB7eyBkZXZpY2UubmFtZSB8fCAnLScgfX1cbiAqICAgICA8Yzh5LWxpLWZvb3Rlcj5cbiAqICAgICAgIERldmljZSBpZDogPGEgW3JvdXRlckxpbmtdPVwiWycvZGV2aWNlJywgZGV2aWNlLmlkXVwiPnt7IGRldmljZS5pZCB9fTwvYT5cbiAqICAgICA8L2M4eS1saS1mb290ZXI+XG4gKiAgICAgPGM4eS1saS1hY3Rpb24gKGNsaWNrKT1cImRlbGV0ZURldmljZShkZXZpY2UuaWQpXCIgaWNvbj1cInRpbWVzXCI+XG4gKiAgICAgICBEZWxldGVcbiAqICAgICA8L2M4eS1saS1hY3Rpb24+XG4gKiAgICAgPGM4eS1saS1hY3Rpb24gKGNsaWNrKT1cIihmYWxzZSlcIiBpY29uPVwicm9ja2V0XCI+XG4gKiAgICAgICBMYXVuY2ggdG8gc3BhY2VcbiAqICAgICA8L2M4eS1saS1hY3Rpb24+XG4gKiAgIDwvYzh5LWxpPlxuICogPC9jOHktbGlzdC1ncm91cD5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktbGlzdC1pdGVtLCBjOHktbGknLFxuICB0ZW1wbGF0ZVVybDogJy4vbGlzdC1pdGVtLmNvbXBvbmVudC5odG1sJyxcbiAgaG9zdDoge1xuICAgIGNsYXNzOiAnYzh5LWxpc3RfX2l0ZW0nXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTGlzdEl0ZW1Db21wb25lbnQge1xuICAvKipcbiAgICogSWYgc2V0IHRvIHRydWUsIHRoZSBjbGFzcyBcImFjdGl2ZVwiIGlzIGFkZGVkIHdoaWNoXG4gICAqIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IHJvdyBpcyBhY3RpdmUuXG4gICAqL1xuICBASW5wdXQoKVxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmFjdGl2ZScpXG4gIGFjdGl2ZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGNsYXNzIFwiaGlnaGxpZ2h0ZWRcIiBpcyBhZGRlZCB3aGljaFxuICAgKiBpbmRpY2F0ZXMgdGhhdCB0aGUgY3VycmVudCByb3cgaXMgaGlnaGxpZ2h0ZWQuXG4gICAqL1xuICBASW5wdXQoKVxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmhpZ2hsaWdodGVkJylcbiAgaGlnaGxpZ2h0ZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogSWYgc2V0IHRvIHRydWUsIHRoZSBjbGFzcyBcImM4eS1saXN0X19pdGVtLS1lbXB0eS1hY3Rpb25zXCIgaXMgYWRkZWQgd2hpY2ggYWRkc1xuICAgKiBhZGRpdGlvbmFsIHBhZGRpbmcgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIFwiYWN0aW9uc1wiIGNvbHVtbiBpbiBvdGhlciBsaXN0IGl0ZW1zLlxuICAgKi9cbiAgQElucHV0KClcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jOHktbGlzdF9faXRlbS0tZW1wdHktYWN0aW9ucycpXG4gIGVtcHR5QWN0aW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gdHJ1ZSwgdGhlIGl0ZW0gd2lsbCBiZSBkaXNwbGF5ZWQgaW4gYSBkZW5zZSBzdHlsZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIEBIb3N0QmluZGluZygnY2xhc3MuYzh5LWxpc3RfX2l0ZW0tLWRlbnNlJylcbiAgZGVuc2UgPSBmYWxzZTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIGlmIHRoZSBjdXJyZW50IGxpc3QgaXRlbSBpcyBjb2xsYXBzZWQuIFlvdSBjYW4gdHJpZ2dlciB0aGUgY29sbGFwc2luZyBmcm9tXG4gICAqIGFueSBlbGVtZW50IGV2ZW50IGJ5IHRvZ2dsaW5nIHRoaXMgdmFsdWUuXG4gICAqXG4gICAqIGBgYGh0bWxcbiAgICogPGM4eS1saSAjbGkgKGNsaWNrKT1cImxpLmNvbGxhcHNlZCA9ICFsaS5jb2xsYXBzZWRcIj5cbiAgICogIFRvZ2dsZVxuICAgKiAgPGM4eS1saS1jb2xsYXBzZT5cbiAgICogICAgSSBjYW4gYmUgdG9nZ2xlZCBieSBjbGlja2luZyBvbiB0aGUgcm93LlxuICAgKiAgPC9jOHktbGktY29sbGFwc2VcbiAgICogPC9jOHktbGk+XG4gICAqIGBgYFxuICAgKi9cbiAgQElucHV0KClcbiAgY29sbGFwc2VkID0gdHJ1ZTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIGlmIHRoZSBjdXJyZW50IGxpc3QgaXRlbSBpcyBzZWxlY3RhYmxlLlxuICAgKi9cbiAgQElucHV0KClcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5zZWxlY3RhYmxlJylcbiAgc2VsZWN0YWJsZSA9IHRydWU7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGVtaXR0ZXIgd2hpY2ggaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgY29sbGFwc2VzIHRoZSBjb250ZW50XG4gICAqIHZpYSB0aGUgY2hldnJvbiBvbiB0aGUgcmlnaHQuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgY29sbGFwc2VkQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gIC8qKlxuICAgKiBBIFtbTGlzdEl0ZW1Gb290ZXJDb21wb25lbnRdXSBlbGVtZW50IHdoaWNoIGNhbiBiZSB1c2VkIHRvIHNob3cgYSBmb290ZXIuXG4gICAqIGBgYGh0bWxcbiAgICogPGM4eS1saT5cbiAgICogIEkgYW0gdGhlIG1haW4gY29udGVudFxuICAgKiAgPGM4eS1saS1mb290ZXI+XG4gICAqICAgIEkgYW0gdGhlIGZvb3RlciBjb250ZW50XG4gICAqICA8L2M4eS1saS1mb290ZXI+XG4gICAqIDwvYzh5LWxpPlxuICAgKiBgYGBcbiAgICovXG4gIEBDb250ZW50Q2hpbGQoTGlzdEl0ZW1Gb290ZXJDb21wb25lbnQsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBpdGVtRm9vdGVyOiBMaXN0SXRlbUZvb3RlckNvbXBvbmVudDtcblxuICAvKipcbiAgICogW1tMaXN0SXRlbUFjdGlvbkNvbXBvbmVudF1dIGVsZW1lbnRzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHNob3cgYW4gYWN0aW9uLlxuICAgKiBBbiBhY3Rpb24gaXMgZGlzcGxheWVkIG9uIHRoZSByaWdodCBpbiB0aGUgZHJvcGRvd24gYW5kIHVzdWFsbHkgY29uc2lzdHMgb2YgYW5cbiAgICogaWNvbiBhbmQgYSBsYWJlbC5cbiAgICogYGBgaHRtbFxuICAgKiA8Yzh5LWxpPlxuICAgKiAgSSBhbSB0aGUgbWFpbiBjb250ZW50XG4gICAqICA8Yzh5LWxpLWFjdGlvbiAoY2xpY2spPVwibGF1bmNoVG9TcGFjZShkZXZpY2UuaWQpXCIgaWNvbj1cInJvY2tldFwiPlxuICAgKiAgICBMYXVuY2hcbiAgICogIDwvYzh5LWxpLWFjdGlvbj5cbiAgICogIDxjOHktbGktYWN0aW9uIChjbGljayk9XCJkZWxldGVEZXZpY2UoZGV2aWNlLmlkKVwiIGljb249XCJ0aW1lc1wiPlxuICAgKiAgICBEZWxldGVcbiAgICogIDwvYzh5LWxpLWFjdGlvbj5cbiAgICogPC9jOHktbGk+XG4gICAqIGBgYFxuICAgKi9cbiAgQENvbnRlbnRDaGlsZHJlbihMaXN0SXRlbUFjdGlvbkNvbXBvbmVudClcbiAgaXRlbUFjdGlvbnM6IFF1ZXJ5TGlzdDxMaXN0SXRlbUFjdGlvbkNvbXBvbmVudD47XG5cbiAgLyoqXG4gICAqIFtbTGlzdEl0ZW1Db2xsYXBzZUNvbXBvbmVudF1dIGVsZW1lbnRzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHNob3cgZGV0YWlsIHZpZXdzLlxuICAgKiBgYGBodG1sXG4gICAqIDxjOHktbGk+XG4gICAqICBJIGFtIHRoZSBtYWluIGNvbnRlbnRcbiAgICogIDxjOHktbGktY29sbGFwc2U+XG4gICAqICAgIEkgYW0gZGV0YWlsZWQgY29udGVudFxuICAgKiAgPC9jOHktbGktY29sbGFwc2U+XG4gICAqIDwvYzh5LWxpPlxuICAgKiBgYGBcbiAgICovXG4gIEBDb250ZW50Q2hpbGQoTGlzdEl0ZW1Db2xsYXBzZUNvbXBvbmVudCwgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIGl0ZW1Db2xsYXBzZTogTGlzdEl0ZW1Db2xsYXBzZUNvbXBvbmVudDtcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgc2hvd0Zvb3RlciA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgc2hvd0FjdGlvbnMgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHNob3dDb2xsYXBzZSA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgYWN0aW9uczogTGlzdEl0ZW1BY3Rpb25Db21wb25lbnRbXTtcblxuICBwcml2YXRlIHB1bHNlJDogU3ViamVjdDxib29sZWFuPiA9IG5ldyBTdWJqZWN0PGJvb2xlYW4+KCk7XG4gIHByaXZhdGUgZGVzdHJveSQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIHJlYWRvbmx5IEFDVElPTl9JVEVNX0hFSUdIVCA9IDQwO1xuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgZWxlbWVudDogRWxlbWVudFJlZikge31cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5wdWxzZSRcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoYXBwbHkgPT4gISFhcHBseSksXG4gICAgICAgIHRhcCgoKSA9PiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdjOHktbGlzdC0tcHVsc2UnKSksXG4gICAgICAgIGRlbGF5KDEwMCksXG4gICAgICAgIHRhcCgoKSA9PiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdjOHktbGlzdC0tcHVsc2UnKSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGlvbnMgPSB0aGlzLml0ZW1BY3Rpb25zLnRvQXJyYXkoKTtcbiAgICB0aGlzLnNob3dGb290ZXIgPSB0aGlzLml0ZW1Gb290ZXIgIT0gbnVsbDtcbiAgICB0aGlzLnNob3dBY3Rpb25zID0gdGhpcy5pdGVtQWN0aW9ucy5sZW5ndGggPiAwO1xuICAgIHRoaXMuc2hvd0NvbGxhcHNlID0gdGhpcy5pdGVtQ29sbGFwc2UgIT0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyB0aGUgY29sbGFwc2Ugc3RhdGUgYW5kIGVtaXRzIHRoaXMgc3RhdGUgYXNcbiAgICogY29sbGFwc2VkQ2hhbmdlIG91dHB1dCBhcyBib29sZWFuLlxuICAgKiBAcGFyYW0gJGV2ZW50IFBhc3Mgb3B0aW9uYWwgYW4gZXZlbnQgdG8gc3RvcCBwcm9wYWdhdGlvbi5cbiAgICovXG4gIHRvZ2dsZUNvbGxhcHNlZCgkZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmICgkZXZlbnQpIHtcbiAgICAgICRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gICAgdGhpcy5jb2xsYXBzZWQgPSAhdGhpcy5jb2xsYXBzZWQ7XG4gICAgdGhpcy5jb2xsYXBzZWRDaGFuZ2UuZW1pdCh0aGlzLmNvbGxhcHNlZCk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyB0aGUgY29sbGFwc2Ugc3RhdGUgaW4gY2FzZSB0aGUgYGNvbGxhcHNlV2F5YCBpcyBzZXQgdG8gYHJvd2AgYW5kIGVtaXRzIHRoaXMgc3RhdGUgYXNcbiAgICogY29sbGFwc2VkQ2hhbmdlIG91dHB1dCBhcyBib29sZWFuLlxuICAgKi9cbiAgcm93VG9nZ2xlQ29sbGFwc2VkKCkge1xuICAgIGlmICghdGhpcy5pdGVtQ29sbGFwc2UgfHwgdGhpcy5pdGVtQ29sbGFwc2UuY29sbGFwc2VXYXkgIT09ICdyb3cnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMudG9nZ2xlQ29sbGFwc2VkKCk7XG4gIH1cblxuICAvKipcbiAgICogSGlnaGxpZ2h0cyB0aGUgbGlzdC1pdGVtLiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgdXNlZCB0byBzaG93IHRoZVxuICAgKiB1c2VyIHRoYXQgc29tZXRoaW5nIHdpdGhpbiB0aGlzIGl0ZW0gd2FzIGNoYW5nZWQuXG4gICAqL1xuICBwdWxzZSgpIHtcbiAgICB0aGlzLnB1bHNlJC5uZXh0KHRydWUpO1xuICB9XG59XG4iLCI8ZGl2XG4gIFtuZ0NsYXNzXT1cInsgZXhwYW5kZWQ6ICFjb2xsYXBzZWQsIGludGVyYWN0OiBpdGVtQ29sbGFwc2UgJiYgaXRlbUNvbGxhcHNlLmNvbGxhcHNlV2F5ID09PSAncm93JyB9XCJcbj5cbiAgPGRpdiBjbGFzcz1cImM4eS1saXN0X19pdGVtX19ibG9ja1wiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImM4eS1saXN0LWl0ZW0tZHJhZy1oYW5kbGUsIGM4eS1saS1kcmFnLWhhbmRsZVwiPjwvbmctY29udGVudD5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJjOHktbGlzdC1pdGVtLXJhZGlvLCBjOHktbGktcmFkaW9cIj48L25nLWNvbnRlbnQ+XG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiYzh5LWxpc3QtaXRlbS1jaGVja2JveCwgYzh5LWxpLWNoZWNrYm94XCI+PC9uZy1jb250ZW50PlxuXG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiYzh5LWxpc3QtaXRlbS1pY29uLCBjOHktbGktaWNvblwiPjwvbmctY29udGVudD5cblxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW1fX2JvZHkgdGV4dC10cnVuY2F0ZS13cmFwXCJcbiAgICAgIChjbGljayk9XCJyb3dUb2dnbGVDb2xsYXBzZWQoKVwiXG4gICAgPlxuICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiYzh5LWxpc3QtaXRlbS1ib2R5LCBjOHktbGktYm9keVwiPjwvbmctY29udGVudD5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJjOHktbGlzdF9faXRlbV9fZm9vdGVyXCJcbiAgICAgICAgKm5nSWY9XCJzaG93Rm9vdGVyXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiYzh5LWxpc3QtaXRlbS1mb290ZXIsIGM4eS1saS1mb290ZXJcIj48L25nLWNvbnRlbnQ+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW1fX2FjdGlvbnNcIlxuICAgICAgKm5nSWY9XCIoc2hvd0NvbGxhcHNlICYmIGl0ZW1Db2xsYXBzZSAmJiBpdGVtQ29sbGFwc2UuY29sbGFwc2VXYXkgPT09ICdidXR0b24nKSB8fCBzaG93QWN0aW9uc1wiXG4gICAgPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImNvbGxhcHNlLWJ0blwiXG4gICAgICAgIHRpdGxlPVwie3sgJ0V4cGFuZCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cIiFjb2xsYXBzZWRcIlxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNvbGxhcHNlZCgkZXZlbnQpXCJcbiAgICAgICAgKm5nSWY9XCJzaG93Q29sbGFwc2UgJiYgaXRlbUNvbGxhcHNlLmNvbGxhcHNlV2F5ID09PSAnYnV0dG9uJ1wiXG4gICAgICAgIGRhdGEtY3k9XCJjOHktbGktLWNvbGxhcHNlLWJ0blwiXG4gICAgICA+XG4gICAgICAgIDxpIFtjOHlJY29uXT1cIidjaGV2cm9uLWRvd24nXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiZHJvcGRvd25cIlxuICAgICAgICAjbGlEcm9wZG93bkFjdGlvbnM9XCJicy1kcm9wZG93blwiXG4gICAgICAgIFtjZGtUcmFwRm9jdXNdPVwibGlEcm9wZG93bkFjdGlvbnMuaXNPcGVuXCJcbiAgICAgICAgZHJvcGRvd25cbiAgICAgICAgYzh5RHJvcGRvd25EaXJlY3Rpb25cbiAgICAgICAgI2Ryb3BEaXJlY3Rpb249XCJicy1kcm9wZG93blwiXG4gICAgICAgIFtjZGtUcmFwRm9jdXNdPVwiZHJvcERpcmVjdGlvbi5pc09wZW5cIlxuICAgICAgICAqbmdJZj1cInNob3dBY3Rpb25zXCJcbiAgICAgID5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGNsYXNzPVwiZHJvcGRvd24tdG9nZ2xlIGM4eS1kcm9wZG93blwiXG4gICAgICAgICAgdGl0bGU9XCJ7eyAnQWN0aW9ucycgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGRyb3Bkb3duVG9nZ2xlXG4gICAgICAgICAgZGF0YS1jeT1cImM4eS1saS0tYWN0aW9ucy1idG5cIlxuICAgICAgICA+XG4gICAgICAgICAgPGkgW2M4eUljb25dPVwiJ2VsbGlwc2lzLXYnXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPHVsXG4gICAgICAgICAgY2xhc3M9XCJkcm9wZG93bi1tZW51IGRyb3Bkb3duLW1lbnUtcmlnaHRcIlxuICAgICAgICAgIGRhdGEtY3k9XCJsaXN0LWl0ZW0tLWRyb3Bkb3duLW1lbnVcIlxuICAgICAgICAgICpkcm9wZG93bk1lbnVcbiAgICAgICAgPlxuICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImM4eS1saXN0LWl0ZW0tYWN0aW9uLCBjOHktbGktYWN0aW9uXCI+PC9uZy1jb250ZW50PlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGFjdGlvbiBvZiBhY3Rpb25zXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiYWN0aW9uLnRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvdWw+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPG5nLWNvbnRlbnRcbiAgICAgICAgc2VsZWN0PVwiYzh5LWxpc3QtaXRlbS1hY3Rpb24sIGM4eS1saS1hY3Rpb25cIlxuICAgICAgICAqbmdJZj1cInNob3dBY3Rpb25zXCJcbiAgICAgID48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXZcbiAgICAqbmdJZj1cInNob3dDb2xsYXBzZVwiXG4gICAgW2NvbGxhcHNlXT1cImNvbGxhcHNlZFwiXG4gICAgW2lzQW5pbWF0ZWRdPVwidHJ1ZVwiXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwiYzh5LWxpc3RfX2l0ZW1fX2NvbGxhcHNlLS1jb250YWluZXJcIj5cbiAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cImM4eS1saXN0LWl0ZW0tY29sbGFwc2UsIGM4eS1saS1jb2xsYXBzZVwiPjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==