UNPKG

carbon-components-angular

Version:
359 lines 30.1 kB
import { Component, Input, Output, EventEmitter, TemplateRef } from "@angular/core"; import * as i0 from "@angular/core"; import * as i1 from "./treeview.service"; import * as i2 from "@angular/common"; import * as i3 from "carbon-components-angular/icon"; export class TreeNodeComponent { constructor(treeViewService) { this.treeViewService = treeViewService; this.id = `tree-node-${TreeNodeComponent.treeNodeCount++}`; this.active = false; this.disabled = false; this.expanded = false; this.selected = false; this.children = []; /** * Determines the depth of the node * Calculated by default when passing `Node` array to `TreeViewComponent`, manual entry required otherwise */ this.depth = 0; this.nodeFocus = new EventEmitter(); this.nodeBlur = new EventEmitter(); this.nodeSelect = new EventEmitter(); this.nodetoggle = new EventEmitter(); } /** * Simple way to set all attributes of Node component via node object * Would simplify setting component attributes when dynamically rendering node. */ set node(node) { this._node = node; this.id = node.id ?? this.id; this.active = node.active ?? this.active; this.disabled = node.disabled ?? this.disabled; this.expanded = node.expanded ?? this.expanded; this.label = node.label ?? this.label; this.value = node.value ?? this.value; this.icon = node.icon ?? this.icon; this.selected = node.selected ?? this.selected; this.depth = node.depth ?? this.depth; this.children = node.children ?? this.children; } get node() { return this._node; } /** * Caclulate offset for margin/padding */ ngAfterContentChecked() { this.offset = this.calculateOffset(); } /** * Highlight the node */ ngOnInit() { // Highlight the node this.subscription = this.treeViewService.selectionObservable.subscribe((value) => { this.selected = value.has(this.id); this.active = this.selected; }); } /** * Unsubscribe from subscriptions */ ngOnDestroy() { this.subscription?.unsubscribe(); } /** * Selects the node and emits the event from the tree view component * @param event */ nodeClick(event) { if (!this.disabled) { this.selected = true; this.active = true; event.target.parentElement.focus(); // Passes event to all nodes to update highlighting & parent to emit this.treeViewService.selectNode({ id: this.id, label: this.label, value: this.value }); } } /** * Calculate the node offset * @returns Number */ calculateOffset() { // Parent node with icon if (this.children.length && this.icon) { return this.depth + 1 + this.depth * 0.5; } // parent node without icon if (this.children.length) { return this.depth + 1; } // leaf node with icon if (this.icon) { return this.depth + 2 + this.depth * 0.5; } return this.depth + 2.5; } emitFocusEvent(event) { this.nodeFocus.emit({ node: { id: this.id, label: this.label, value: this.value }, event }); } emitBlurEvent(event) { this.nodeBlur.emit({ node: { id: this.id, label: this.label, value: this.value }, event }); } /** * Expand children if not disabled * @param event: Event */ toggleExpanded(event) { if (!this.disabled) { this.nodetoggle.emit({ node: { id: this.id, label: this.label, value: this.value }, event }); this.expanded = !this.expanded; // Prevent selection of the node event.stopPropagation(); } } /** * Manages the keyboard accessibility for children expansion & selection */ navigateTree(event) { if (event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Enter") { event.stopPropagation(); } // Unexpand if (event.key === "ArrowLeft") { if (this.expanded && this.children) { this.toggleExpanded(event); } } if (event.key === "ArrowRight") { if (!this.expanded && this.children) { this.toggleExpanded(event); } } if (event.key === "Enter") { event.preventDefault(); this.nodeClick(event); } } isTemplate(value) { return value instanceof TemplateRef; } isProjected() { return this.treeViewService.contentProjected; } } TreeNodeComponent.treeNodeCount = 0; TreeNodeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TreeNodeComponent, deps: [{ token: i1.TreeViewService }], target: i0.ɵɵFactoryTarget.Component }); TreeNodeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: TreeNodeComponent, selector: "cds-tree-node", inputs: { id: "id", active: "active", disabled: "disabled", expanded: "expanded", label: "label", selected: "selected", value: "value", icon: "icon", children: "children", depth: "depth", node: "node" }, outputs: { nodeFocus: "nodeFocus", nodeBlur: "nodeBlur", nodeSelect: "nodeSelect", nodetoggle: "nodetoggle" }, ngImport: i0, template: ` <div [id]="id" class="cds--tree-node" [ngClass]="{ 'cds--tree-node--active': active, 'cds--tree-node--disabled': disabled, 'cds--tree-node--selected': selected, 'cds--tree-leaf-node': !children.length, 'cds--tree-parent-node': children.length, 'cds--tree-node--with-icon': icon }" [attr.aria-expanded]="expanded || null" [attr.aria-current]="active || null" [attr.aria-selected]="disabled ? null : selected" [attr.aria-disabled]="disabled" role="treeitem" [attr.tabindex]="selected ? 0 : -1" (focus)="emitFocusEvent($event)" (blur)="emitBlurEvent($event)" (keydown)="navigateTree($event)"> <div *ngIf="!children.length" class="cds--tree-node__label" [style.padding-inline-start.rem]="offset" [style.margin-inline-start.rem]="-offset" (click)="nodeClick($event)"> <!-- Icon --> <ng-container *ngIf="icon && !isTemplate(icon)"> <svg class="cds--tree-node__icon" [cdsIcon]="icon" size="16"> </svg> </ng-container> <ng-template *ngIf="isTemplate(icon)" [ngTemplateOutlet]="icon"></ng-template> {{label}} </div> <div *ngIf="children.length" class="cds--tree-node__label" [style.padding-inline-start.rem]="offset" [style.margin-inline-start.rem]="-offset" role="group" (click)="nodeClick($event)"> <span class="cds--tree-parent-node__toggle" [attr.disabled]="disabled || null" (click)="toggleExpanded($event)"> <svg class="cds--tree-parent-node__toggle-icon" [ngClass]="{'cds--tree-parent-node__toggle-icon--expanded' : expanded}" ibmIcon="caret--down" size="16"> </svg> </span> <span class="cds--tree-node__label__details"> <!-- Icon --> <ng-container *ngIf="icon && !isTemplate(icon)"> <svg class="cds--tree-node__icon" [cdsIcon]="icon" size="16"> </svg> </ng-container> <ng-template *ngIf="isTemplate(icon)" [ngTemplateOutlet]="icon"></ng-template> {{label}} </span> </div> <div *ngIf="expanded" role="group" class="cds--tree-node__children"> <ng-container *ngIf="isProjected(); else notProjected"> <ng-content></ng-content> </ng-container> <ng-template #notProjected> <cds-tree-node *ngFor="let childNode of children" [node]="childNode" [depth]="depth + 1" [disabled]="disabled"> </cds-tree-node> </ng-template> </div> </div> `, isInline: true, dependencies: [{ 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.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: TreeNodeComponent, selector: "cds-tree-node", inputs: ["id", "active", "disabled", "expanded", "label", "selected", "value", "icon", "children", "depth", "node"], outputs: ["nodeFocus", "nodeBlur", "nodeSelect", "nodetoggle"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TreeNodeComponent, decorators: [{ type: Component, args: [{ selector: "cds-tree-node", template: ` <div [id]="id" class="cds--tree-node" [ngClass]="{ 'cds--tree-node--active': active, 'cds--tree-node--disabled': disabled, 'cds--tree-node--selected': selected, 'cds--tree-leaf-node': !children.length, 'cds--tree-parent-node': children.length, 'cds--tree-node--with-icon': icon }" [attr.aria-expanded]="expanded || null" [attr.aria-current]="active || null" [attr.aria-selected]="disabled ? null : selected" [attr.aria-disabled]="disabled" role="treeitem" [attr.tabindex]="selected ? 0 : -1" (focus)="emitFocusEvent($event)" (blur)="emitBlurEvent($event)" (keydown)="navigateTree($event)"> <div *ngIf="!children.length" class="cds--tree-node__label" [style.padding-inline-start.rem]="offset" [style.margin-inline-start.rem]="-offset" (click)="nodeClick($event)"> <!-- Icon --> <ng-container *ngIf="icon && !isTemplate(icon)"> <svg class="cds--tree-node__icon" [cdsIcon]="icon" size="16"> </svg> </ng-container> <ng-template *ngIf="isTemplate(icon)" [ngTemplateOutlet]="icon"></ng-template> {{label}} </div> <div *ngIf="children.length" class="cds--tree-node__label" [style.padding-inline-start.rem]="offset" [style.margin-inline-start.rem]="-offset" role="group" (click)="nodeClick($event)"> <span class="cds--tree-parent-node__toggle" [attr.disabled]="disabled || null" (click)="toggleExpanded($event)"> <svg class="cds--tree-parent-node__toggle-icon" [ngClass]="{'cds--tree-parent-node__toggle-icon--expanded' : expanded}" ibmIcon="caret--down" size="16"> </svg> </span> <span class="cds--tree-node__label__details"> <!-- Icon --> <ng-container *ngIf="icon && !isTemplate(icon)"> <svg class="cds--tree-node__icon" [cdsIcon]="icon" size="16"> </svg> </ng-container> <ng-template *ngIf="isTemplate(icon)" [ngTemplateOutlet]="icon"></ng-template> {{label}} </span> </div> <div *ngIf="expanded" role="group" class="cds--tree-node__children"> <ng-container *ngIf="isProjected(); else notProjected"> <ng-content></ng-content> </ng-container> <ng-template #notProjected> <cds-tree-node *ngFor="let childNode of children" [node]="childNode" [depth]="depth + 1" [disabled]="disabled"> </cds-tree-node> </ng-template> </div> </div> ` }] }], ctorParameters: function () { return [{ type: i1.TreeViewService }]; }, propDecorators: { id: [{ type: Input }], active: [{ type: Input }], disabled: [{ type: Input }], expanded: [{ type: Input }], label: [{ type: Input }], selected: [{ type: Input }], value: [{ type: Input }], icon: [{ type: Input }], children: [{ type: Input }], depth: [{ type: Input }], node: [{ type: Input }], nodeFocus: [{ type: Output }], nodeBlur: [{ type: Output }], nodeSelect: [{ type: Output }], nodetoggle: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1ub2RlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90cmVldmlldy90cmVlLW5vZGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTixTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBSVosV0FBVyxFQUVYLE1BQU0sZUFBZSxDQUFDOzs7OztBQStGdkIsTUFBTSxPQUFPLGlCQUFpQjtJQWtEN0IsWUFBb0IsZUFBZ0M7UUFBaEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBaEQzQyxPQUFFLEdBQUcsYUFBYSxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1FBQ3RELFdBQU0sR0FBRyxLQUFLLENBQUM7UUFDZixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFakIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUdqQixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBRS9COzs7V0FHRztRQUNNLFVBQUssR0FBRyxDQUFDLENBQUM7UUF5QlQsY0FBUyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDL0IsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDOUIsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDaEMsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7SUFNYSxDQUFDO0lBaEN4RDs7O09BR0c7SUFDSCxJQUFhLElBQUksQ0FBQyxJQUFVO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBRWxCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxRQUFR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Ozs7Ozs7Ozs7RUFzRlQ7aUJBQ0Q7c0dBR1MsRUFBRTtzQkFBVixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQU1HLEtBQUs7c0JBQWIsS0FBSztnQkFNTyxJQUFJO3NCQUFoQixLQUFLO2dCQW1CSSxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLFFBQVE7c0JBQWpCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRJbnB1dCxcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXIsXG5cdE9uSW5pdCxcblx0T25EZXN0cm95LFxuXHRBZnRlckNvbnRlbnRJbml0LFxuXHRUZW1wbGF0ZVJlZixcblx0QWZ0ZXJDb250ZW50Q2hlY2tlZFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IFRyZWVWaWV3U2VydmljZSB9IGZyb20gXCIuL3RyZWV2aWV3LnNlcnZpY2VcIjtcbmltcG9ydCB7IE5vZGUgfSBmcm9tIFwiLi90cmVlLW5vZGUudHlwZXNcIjtcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiBcImNkcy10cmVlLW5vZGVcIixcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2XG5cdFx0XHRbaWRdPVwiaWRcIlxuXHRcdFx0Y2xhc3M9XCJjZHMtLXRyZWUtbm9kZVwiXG5cdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdCdjZHMtLXRyZWUtbm9kZS0tYWN0aXZlJzogYWN0aXZlLFxuXHRcdFx0XHQnY2RzLS10cmVlLW5vZGUtLWRpc2FibGVkJzogZGlzYWJsZWQsXG5cdFx0XHRcdCdjZHMtLXRyZWUtbm9kZS0tc2VsZWN0ZWQnOiBzZWxlY3RlZCxcblx0XHRcdFx0J2Nkcy0tdHJlZS1sZWFmLW5vZGUnOiAhY2hpbGRyZW4ubGVuZ3RoLFxuXHRcdFx0XHQnY2RzLS10cmVlLXBhcmVudC1ub2RlJzogY2hpbGRyZW4ubGVuZ3RoLFxuXHRcdFx0XHQnY2RzLS10cmVlLW5vZGUtLXdpdGgtaWNvbic6IGljb25cblx0XHRcdH1cIlxuXHRcdFx0W2F0dHIuYXJpYS1leHBhbmRlZF09XCJleHBhbmRlZCB8fCBudWxsXCJcblx0XHRcdFthdHRyLmFyaWEtY3VycmVudF09XCJhY3RpdmUgfHwgbnVsbFwiXG5cdFx0XHRbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImRpc2FibGVkID8gbnVsbCA6IHNlbGVjdGVkXCJcblx0XHRcdFthdHRyLmFyaWEtZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuXHRcdFx0cm9sZT1cInRyZWVpdGVtXCJcblx0XHRcdFthdHRyLnRhYmluZGV4XT1cInNlbGVjdGVkID8gMCA6IC0xXCJcblx0XHRcdChmb2N1cyk9XCJlbWl0Rm9jdXNFdmVudCgkZXZlbnQpXCJcblx0XHRcdChibHVyKT1cImVtaXRCbHVyRXZlbnQoJGV2ZW50KVwiXG5cdFx0XHQoa2V5ZG93bik9XCJuYXZpZ2F0ZVRyZWUoJGV2ZW50KVwiPlxuXHRcdFx0PGRpdlxuXHRcdFx0XHQqbmdJZj1cIiFjaGlsZHJlbi5sZW5ndGhcIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tdHJlZS1ub2RlX19sYWJlbFwiXG5cdFx0XHRcdFtzdHlsZS5wYWRkaW5nLWlubGluZS1zdGFydC5yZW1dPVwib2Zmc2V0XCJcblx0XHRcdFx0W3N0eWxlLm1hcmdpbi1pbmxpbmUtc3RhcnQucmVtXT1cIi1vZmZzZXRcIlxuXHRcdFx0XHQoY2xpY2spPVwibm9kZUNsaWNrKCRldmVudClcIj5cblx0XHRcdFx0PCEtLSBJY29uIC0tPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiaWNvbiAmJiAhaXNUZW1wbGF0ZShpY29uKVwiPlxuXHRcdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRcdGNsYXNzPVwiY2RzLS10cmVlLW5vZGVfX2ljb25cIlxuXHRcdFx0XHRcdFx0W2Nkc0ljb25dPVwiaWNvblwiXG5cdFx0XHRcdFx0XHRzaXplPVwiMTZcIj5cblx0XHRcdFx0XHQ8L3N2Zz5cblx0XHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaWNvbilcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpY29uXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0e3tsYWJlbH19XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxkaXZcblx0XHRcdFx0Km5nSWY9XCJjaGlsZHJlbi5sZW5ndGhcIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tdHJlZS1ub2RlX19sYWJlbFwiXG5cdFx0XHRcdFtzdHlsZS5wYWRkaW5nLWlubGluZS1zdGFydC5yZW1dPVwib2Zmc2V0XCJcblx0XHRcdFx0W3N0eWxlLm1hcmdpbi1pbmxpbmUtc3RhcnQucmVtXT1cIi1vZmZzZXRcIlxuXHRcdFx0XHRyb2xlPVwiZ3JvdXBcIlxuXHRcdFx0XHQoY2xpY2spPVwibm9kZUNsaWNrKCRldmVudClcIj5cblx0XHRcdFx0PHNwYW5cblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdHJlZS1wYXJlbnQtbm9kZV9fdG9nZ2xlXCJcblx0XHRcdFx0XHRbYXR0ci5kaXNhYmxlZF09XCJkaXNhYmxlZCB8fCBudWxsXCJcblx0XHRcdFx0XHQoY2xpY2spPVwidG9nZ2xlRXhwYW5kZWQoJGV2ZW50KVwiPlxuXHRcdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRcdGNsYXNzPVwiY2RzLS10cmVlLXBhcmVudC1ub2RlX190b2dnbGUtaWNvblwiXG5cdFx0XHRcdFx0XHRbbmdDbGFzc109XCJ7J2Nkcy0tdHJlZS1wYXJlbnQtbm9kZV9fdG9nZ2xlLWljb24tLWV4cGFuZGVkJyA6IGV4cGFuZGVkfVwiXG5cdFx0XHRcdFx0XHRpYm1JY29uPVwiY2FyZXQtLWRvd25cIlxuXHRcdFx0XHRcdFx0c2l6ZT1cIjE2XCI+XG5cdFx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdDwvc3Bhbj5cblx0XHRcdFx0PHNwYW4gY2xhc3M9XCJjZHMtLXRyZWUtbm9kZV9fbGFiZWxfX2RldGFpbHNcIj5cblx0XHRcdFx0XHQ8IS0tIEljb24gLS0+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cImljb24gJiYgIWlzVGVtcGxhdGUoaWNvbilcIj5cblx0XHRcdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRyZWUtbm9kZV9faWNvblwiXG5cdFx0XHRcdFx0XHRcdFtjZHNJY29uXT1cImljb25cIlxuXHRcdFx0XHRcdFx0XHRzaXplPVwiMTZcIj5cblx0XHRcdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaWNvbilcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpY29uXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0XHR7e2xhYmVsfX1cblx0XHRcdFx0PC9zcGFuPlxuXHRcdFx0PC9kaXY+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdCpuZ0lmPVwiZXhwYW5kZWRcIlxuXHRcdFx0XHRyb2xlPVwiZ3JvdXBcIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tdHJlZS1ub2RlX19jaGlsZHJlblwiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiaXNQcm9qZWN0ZWQoKTsgZWxzZSBub3RQcm9qZWN0ZWRcIj5cblx0XHRcdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctdGVtcGxhdGUgI25vdFByb2plY3RlZD5cblx0XHRcdFx0XHQ8Y2RzLXRyZWUtbm9kZVxuXHRcdFx0XHRcdFx0Km5nRm9yPVwibGV0IGNoaWxkTm9kZSBvZiBjaGlsZHJlblwiXG5cdFx0XHRcdFx0XHRbbm9kZV09XCJjaGlsZE5vZGVcIlxuXHRcdFx0XHRcdFx0W2RlcHRoXT1cImRlcHRoICsgMVwiXG5cdFx0XHRcdFx0XHRbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIj5cblx0XHRcdFx0XHQ8L2Nkcy10cmVlLW5vZGU+XG5cdFx0XHRcdDwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L2Rpdj5cblx0YFxufSlcbmV4cG9ydCBjbGFzcyBUcmVlTm9kZUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQsIE9uSW5pdCwgT25EZXN0cm95IHtcblx0c3RhdGljIHRyZWVOb2RlQ291bnQgPSAwO1xuXHRASW5wdXQoKSBpZCA9IGB0cmVlLW5vZGUtJHtUcmVlTm9kZUNvbXBvbmVudC50cmVlTm9kZUNvdW50Kyt9YDtcblx0QElucHV0KCkgYWN0aXZlID0gZmFsc2U7XG5cdEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cdEBJbnB1dCgpIGV4cGFuZGVkID0gZmFsc2U7XG5cdEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHRASW5wdXQoKSBzZWxlY3RlZCA9IGZhbHNlO1xuXHRASW5wdXQoKSB2YWx1ZTtcblx0QElucHV0KCkgaWNvbjogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0QElucHV0KCkgY2hpbGRyZW46IE5vZGVbXSA9IFtdO1xuXG5cdC8qKlxuXHQgKiBEZXRlcm1pbmVzIHRoZSBkZXB0aCBvZiB0aGUgbm9kZVxuXHQgKiBDYWxjdWxhdGVkIGJ5IGRlZmF1bHQgd2hlbiBwYXNzaW5nIGBOb2RlYCBhcnJheSB0byBgVHJlZVZpZXdDb21wb25lbnRgLCBtYW51YWwgZW50cnkgcmVxdWlyZWQgb3RoZXJ3aXNlXG5cdCAqL1xuXHRASW5wdXQoKSBkZXB0aCA9IDA7XG5cblx0LyoqXG5cdCAqIFNpbXBsZSB3YXkgdG8gc2V0IGFsbCBhdHRyaWJ1dGVzIG9mIE5vZGUgY29tcG9uZW50IHZpYSBub2RlIG9iamVjdFxuXHQgKiBXb3VsZCBzaW1wbGlmeSBzZXR0aW5nIGNvbXBvbmVudCBhdHRyaWJ1dGVzIHdoZW4gZHluYW1pY2FsbHkgcmVuZGVyaW5nIG5vZGUuXG5cdCAqL1xuXHRASW5wdXQoKSBzZXQgbm9kZShub2RlOiBOb2RlKSB7XG5cdFx0dGhpcy5fbm9kZSA9IG5vZGU7XG5cblx0XHR0aGlzLmlkID0gbm9kZS5pZCA/PyB0aGlzLmlkO1xuXHRcdHRoaXMuYWN0aXZlID0gbm9kZS5hY3RpdmUgPz8gdGhpcy5hY3RpdmU7XG5cdFx0dGhpcy5kaXNhYmxlZCA9IG5vZGUuZGlzYWJsZWQgPz8gdGhpcy5kaXNhYmxlZDtcblx0XHR0aGlzLmV4cGFuZGVkID0gbm9kZS5leHBhbmRlZCA/PyB0aGlzLmV4cGFuZGVkO1xuXHRcdHRoaXMubGFiZWwgPSBub2RlLmxhYmVsID8/IHRoaXMubGFiZWw7XG5cdFx0dGhpcy52YWx1ZSA9IG5vZGUudmFsdWUgPz8gdGhpcy52YWx1ZTtcblx0XHR0aGlzLmljb24gPSBub2RlLmljb24gPz8gdGhpcy5pY29uO1xuXHRcdHRoaXMuc2VsZWN0ZWQgPSBub2RlLnNlbGVjdGVkID8/IHRoaXMuc2VsZWN0ZWQ7XG5cdFx0dGhpcy5kZXB0aCA9IG5vZGUuZGVwdGggPz8gdGhpcy5kZXB0aDtcblx0XHR0aGlzLmNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbiA/PyB0aGlzLmNoaWxkcmVuO1xuXHR9XG5cblx0Z2V0IG5vZGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX25vZGU7XG5cdH1cblxuXHRAT3V0cHV0KCkgbm9kZUZvY3VzID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRAT3V0cHV0KCkgbm9kZUJsdXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cdEBPdXRwdXQoKSBub2RlU2VsZWN0ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRAT3V0cHV0KCkgbm9kZXRvZ2dsZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHRvZmZzZXQ7XG5cdHByaXZhdGUgX25vZGU7XG5cdHByaXZhdGUgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSB0cmVlVmlld1NlcnZpY2U6IFRyZWVWaWV3U2VydmljZSkge31cblxuXHQvKipcblx0ICogQ2FjbHVsYXRlIG9mZnNldCBmb3IgbWFyZ2luL3BhZGRpbmdcblx0ICovXG5cdG5nQWZ0ZXJDb250ZW50Q2hlY2tlZCgpOiB2b2lkIHtcblx0XHR0aGlzLm9mZnNldCA9IHRoaXMuY2FsY3VsYXRlT2Zmc2V0KCk7XG5cdH1cblxuXHQvKipcblx0ICogSGlnaGxpZ2h0IHRoZSBub2RlXG5cdCAqL1xuXHRuZ09uSW5pdCgpOiB2b2lkIHtcblx0XHQvLyBIaWdobGlnaHQgdGhlIG5vZGVcblx0XHR0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMudHJlZVZpZXdTZXJ2aWNlLnNlbGVjdGlvbk9ic2VydmFibGUuc3Vic2NyaWJlKCh2YWx1ZTogTWFwPHN0cmluZywgTm9kZT4pID0+IHtcblx0XHRcdHRoaXMuc2VsZWN0ZWQgPSB2YWx1ZS5oYXModGhpcy5pZCk7XG5cdFx0XHR0aGlzLmFjdGl2ZSA9IHRoaXMuc2VsZWN0ZWQ7XG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVW5zdWJzY3JpYmUgZnJvbSBzdWJzY3JpcHRpb25zXG5cdCAqL1xuXHRuZ09uRGVzdHJveSgpOiB2b2lkIHtcblx0XHR0aGlzLnN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWxlY3RzIHRoZSBub2RlIGFuZCBlbWl0cyB0aGUgZXZlbnQgZnJvbSB0aGUgdHJlZSB2aWV3IGNvbXBvbmVudFxuXHQgKiBAcGFyYW0gZXZlbnRcblx0ICovXG5cdG5vZGVDbGljayhldmVudCkge1xuXHRcdGlmICghdGhpcy5kaXNhYmxlZCkge1xuXHRcdFx0dGhpcy5zZWxlY3RlZCA9IHRydWU7XG5cdFx0XHR0aGlzLmFjdGl2ZSA9IHRydWU7XG5cdFx0XHRldmVudC50YXJnZXQucGFyZW50RWxlbWVudC5mb2N1cygpO1xuXHRcdFx0Ly8gUGFzc2VzIGV2ZW50IHRvIGFsbCBub2RlcyB0byB1cGRhdGUgaGlnaGxpZ2h0aW5nICYgcGFyZW50IHRvIGVtaXRcblx0XHRcdHRoaXMudHJlZVZpZXdTZXJ2aWNlLnNlbGVjdE5vZGUoeyBpZDogdGhpcy5pZCwgbGFiZWw6IHRoaXMubGFiZWwsIHZhbHVlOiB0aGlzLnZhbHVlIH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBDYWxjdWxhdGUgdGhlIG5vZGUgb2Zmc2V0XG5cdCAqIEByZXR1cm5zIE51bWJlclxuXHQgKi9cblx0Y2FsY3VsYXRlT2Zmc2V0KCkge1xuXHRcdC8vIFBhcmVudCBub2RlIHdpdGggaWNvblxuXHRcdGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCAmJiB0aGlzLmljb24pIHtcblx0XHRcdHJldHVybiB0aGlzLmRlcHRoICsgMSArIHRoaXMuZGVwdGggKiAwLjU7XG5cdFx0fVxuXG5cdFx0Ly8gcGFyZW50IG5vZGUgd2l0aG91dCBpY29uXG5cdFx0aWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5kZXB0aCArIDE7XG5cdFx0fVxuXG5cdFx0Ly8gbGVhZiBub2RlIHdpdGggaWNvblxuXHRcdGlmICh0aGlzLmljb24pIHtcblx0XHRcdHJldHVybiB0aGlzLmRlcHRoICsgMiArIHRoaXMuZGVwdGggKiAwLjU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZGVwdGggKyAyLjU7XG5cdH1cblxuXHRlbWl0Rm9jdXNFdmVudChldmVudCkge1xuXHRcdHRoaXMubm9kZUZvY3VzLmVtaXQoeyBub2RlOiB7IGlkOiB0aGlzLmlkLCBsYWJlbDogdGhpcy5sYWJlbCwgdmFsdWU6IHRoaXMudmFsdWUgfSwgZXZlbnQgfSk7XG5cdH1cblxuXHRlbWl0Qmx1ckV2ZW50KGV2ZW50KSB7XG5cdFx0dGhpcy5ub2RlQmx1ci5lbWl0KHsgbm9kZTogeyBpZDogdGhpcy5pZCwgbGFiZWw6IHRoaXMubGFiZWwsIHZhbHVlOiB0aGlzLnZhbHVlIH0sIGV2ZW50IH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEV4cGFuZCBjaGlsZHJlbiBpZiBub3QgZGlzYWJsZWRcblx0ICogQHBhcmFtIGV2ZW50OiBFdmVudFxuXHQgKi9cblx0dG9nZ2xlRXhwYW5kZWQoZXZlbnQpIHtcblx0XHRpZiAoIXRoaXMuZGlzYWJsZWQpIHtcblx0XHRcdHRoaXMubm9kZXRvZ2dsZS5lbWl0KHsgbm9kZTogeyBpZDogdGhpcy5pZCwgbGFiZWw6IHRoaXMubGFiZWwsIHZhbHVlOiB0aGlzLnZhbHVlIH0sIGV2ZW50IH0pO1xuXHRcdFx0dGhpcy5leHBhbmRlZCA9ICF0aGlzLmV4cGFuZGVkO1xuXHRcdFx0Ly8gUHJldmVudCBzZWxlY3Rpb24gb2YgdGhlIG5vZGVcblx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBNYW5hZ2VzIHRoZSBrZXlib2FyZCBhY2Nlc3NpYmlsaXR5IGZvciBjaGlsZHJlbiBleHBhbnNpb24gJiBzZWxlY3Rpb25cblx0ICovXG5cdG5hdmlnYXRlVHJlZShldmVudDogS2V5Ym9hcmRFdmVudCkge1xuXHRcdGlmIChldmVudC5rZXkgPT09IFwiQXJyb3dMZWZ0XCIgfHwgZXZlbnQua2V5ID09PSBcIkFycm93UmlnaHRcIiB8fCBldmVudC5rZXkgPT09IFwiRW50ZXJcIikge1xuXHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHRcdC8vIFVuZXhwYW5kXG5cdFx0aWYgKGV2ZW50LmtleSA9PT0gXCJBcnJvd0xlZnRcIikge1xuXHRcdFx0aWYgKHRoaXMuZXhwYW5kZWQgJiYgdGhpcy5jaGlsZHJlbikge1xuXHRcdFx0XHR0aGlzLnRvZ2dsZUV4cGFuZGVkKGV2ZW50KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoZXZlbnQua2V5ID09PSBcIkFycm93UmlnaHRcIikge1xuXHRcdFx0aWYgKCF0aGlzLmV4cGFuZGVkICYmIHRoaXMuY2hpbGRyZW4pIHtcblx0XHRcdFx0dGhpcy50b2dnbGVFeHBhbmRlZChldmVudCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGV2ZW50LmtleSA9PT0gXCJFbnRlclwiKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0dGhpcy5ub2RlQ2xpY2soZXZlbnQpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBpc1RlbXBsYXRlKHZhbHVlKSB7XG5cdFx0cmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7XG5cdH1cblxuXHRwdWJsaWMgaXNQcm9qZWN0ZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMudHJlZVZpZXdTZXJ2aWNlLmNvbnRlbnRQcm9qZWN0ZWQ7XG5cdH1cbn1cbiJdfQ==