@clr/angular
Version:
Angular components for Clarity
162 lines • 26.4 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { animate, state, style, transition, trigger } from '@angular/animations';
import { Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
import { IfExpandService } from '../../utils/conditional/if-expanded.service';
import { VerticalNavGroupService } from './providers/vertical-nav-group.service';
import * as i0 from "@angular/core";
import * as i1 from "../../utils/conditional/if-expanded.service";
import * as i2 from "./providers/vertical-nav-group-registration.service";
import * as i3 from "./providers/vertical-nav-group.service";
import * as i4 from "./providers/vertical-nav.service";
import * as i5 from "../../utils/i18n/common-strings.service";
import * as i6 from "../../icon/icon";
const EXPANDED_STATE = 'expanded';
const COLLAPSED_STATE = 'collapsed';
export class ClrVerticalNavGroup {
constructor(_itemExpand, _navGroupRegistrationService, _navGroupService, _navService, commonStrings) {
this._itemExpand = _itemExpand;
this._navGroupRegistrationService = _navGroupRegistrationService;
this._navGroupService = _navGroupService;
this._navService = _navService;
this.commonStrings = commonStrings;
this.expandedChange = new EventEmitter(true);
this.wasExpanded = false;
this._subscriptions = [];
this._expandAnimationState = COLLAPSED_STATE;
this._navGroupRegistrationService.registerNavGroup();
// FIXME: This subscription handles a corner case
// Vertical Nav collapse requires the animation to run first and then
// remove the nodes from the DOM. If the user directly sets the input
// on the clrIfExpanded directive, we have no chance to run the animation
// and wait for it to complete. This subscription makes sure that the
// animation states are correct for that edge case.
this._subscriptions.push(this._itemExpand.expandChange.subscribe(value => {
if (value && this.expandAnimationState === COLLAPSED_STATE) {
if (this._navService.collapsed) {
this._navService.collapsed = false;
}
this.expandAnimationState = EXPANDED_STATE;
}
else if (!value && this.expandAnimationState === EXPANDED_STATE) {
this.expandAnimationState = COLLAPSED_STATE;
}
}));
// 1. If the nav is collapsing, close the open nav group + save its state
// 2. If the nav is expanding, expand the nav group if the previous state was expanded
this._subscriptions.push(this._navService.animateOnCollapsed.subscribe((goingToCollapse) => {
if (goingToCollapse && this.expanded) {
this.wasExpanded = true;
this.expandAnimationState = COLLAPSED_STATE;
}
else if (!goingToCollapse && this.wasExpanded) {
this.expandGroup();
this.wasExpanded = false;
}
}));
// If a link is clicked, expand the nav group
this._subscriptions.push(this._navGroupService.expandChange.subscribe((expand) => {
if (expand && !this.expanded) {
this.expandGroup();
}
}));
}
get expanded() {
return this._itemExpand.expanded;
}
set expanded(value) {
if (this._itemExpand.expanded !== value) {
this._itemExpand.expanded = value;
this.expandedChange.emit(value);
}
}
set userExpandedInput(value) {
value = !!value;
if (this.expanded !== value) {
// We have to call toggleExpand because some cases require animations to occur first
// Directly setting the Expand service value skips the animation and can result in
// nodes in the DOM but the nav group still being collapsed
this.toggleExpand();
}
}
get expandAnimationState() {
return this._expandAnimationState;
}
set expandAnimationState(value) {
if (value !== this._expandAnimationState) {
this._expandAnimationState = value;
}
}
ngAfterContentInit() {
// This makes sure that if someone marks a nav group expanded in a collapsed nav
// the expanded property is switched back to collapsed state.
if (this._navService.collapsed && this.expanded) {
this.wasExpanded = true;
this.expandAnimationState = COLLAPSED_STATE;
}
}
ngOnDestroy() {
this._subscriptions.forEach((sub) => sub.unsubscribe());
this._navGroupRegistrationService.unregisterNavGroup();
}
expandGroup() {
this.expanded = true;
// Expanded animation occurs after Expand.expand is set to true
this.expandAnimationState = EXPANDED_STATE;
}
collapseGroup() {
// If a Vertical Nav Group toggle button is clicked while the Vertical Nav is in Collapsed state,
// the Vertical Nav should be expanded first.
this.expandAnimationState = COLLAPSED_STATE;
}
// closes a group after the collapse animation
expandAnimationDone($event) {
if ($event.toState === COLLAPSED_STATE) {
this.expanded = false;
}
}
toggleExpand() {
if (this.expanded) {
this.collapseGroup();
}
else {
// If nav is collasped, first open the nav
if (this._navService.collapsed) {
this._navService.collapsed = false;
}
// then expand the nav group
this.expandGroup();
}
}
}
ClrVerticalNavGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrVerticalNavGroup, deps: [{ token: i1.IfExpandService }, { token: i2.VerticalNavGroupRegistrationService }, { token: i3.VerticalNavGroupService }, { token: i4.VerticalNavService }, { token: i5.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component });
ClrVerticalNavGroup.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrVerticalNavGroup, selector: "clr-vertical-nav-group", inputs: { userExpandedInput: ["clrVerticalNavGroupExpanded", "userExpandedInput"] }, outputs: { expandedChange: "clrVerticalNavGroupExpandedChange" }, host: { properties: { "class.is-expanded": "this.expanded" }, classAttribute: "nav-group" }, providers: [IfExpandService, VerticalNavGroupService], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"nav-group-content\">\n <ng-content select=\"[clrVerticalNavLink]\"></ng-content>\n <button class=\"nav-group-trigger\" type=\"button\" [attr.aria-expanded]=\"expanded\" (click)=\"toggleExpand()\">\n <ng-content select=\"[clrVerticalNavIcon]\"></ng-content>\n <div class=\"nav-group-text\">\n <ng-content></ng-content>\n </div>\n <cds-icon shape=\"angle\" class=\"nav-group-trigger-icon\" [attr.direction]=\"expanded ? 'down' : 'right'\"></cds-icon>\n </button>\n</div>\n<!--TODO: This animation needs to be added to the clr-vertical-nav-group-children component-->\n<div class=\"nav-group-children\" [@clrExpand]=\"expandAnimationState\" (@clrExpand.done)=\"expandAnimationDone($event)\">\n <ng-content select=\"[clrIfExpanded], clr-vertical-nav-group-children\"></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i6.CdsIconCustomTag, selector: "cds-icon" }], animations: [
trigger('clrExpand', [
state(EXPANDED_STATE, style({ height: '*' })),
state(COLLAPSED_STATE, style({ height: 0, visibility: 'hidden' })),
transition(`${EXPANDED_STATE} <=> ${COLLAPSED_STATE}`, animate('0.2s ease-in-out')),
]),
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrVerticalNavGroup, decorators: [{
type: Component,
args: [{ selector: 'clr-vertical-nav-group', providers: [IfExpandService, VerticalNavGroupService], animations: [
trigger('clrExpand', [
state(EXPANDED_STATE, style({ height: '*' })),
state(COLLAPSED_STATE, style({ height: 0, visibility: 'hidden' })),
transition(`${EXPANDED_STATE} <=> ${COLLAPSED_STATE}`, animate('0.2s ease-in-out')),
]),
], host: { class: 'nav-group' }, template: "<!--\n ~ Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n<div class=\"nav-group-content\">\n <ng-content select=\"[clrVerticalNavLink]\"></ng-content>\n <button class=\"nav-group-trigger\" type=\"button\" [attr.aria-expanded]=\"expanded\" (click)=\"toggleExpand()\">\n <ng-content select=\"[clrVerticalNavIcon]\"></ng-content>\n <div class=\"nav-group-text\">\n <ng-content></ng-content>\n </div>\n <cds-icon shape=\"angle\" class=\"nav-group-trigger-icon\" [attr.direction]=\"expanded ? 'down' : 'right'\"></cds-icon>\n </button>\n</div>\n<!--TODO: This animation needs to be added to the clr-vertical-nav-group-children component-->\n<div class=\"nav-group-children\" [@clrExpand]=\"expandAnimationState\" (@clrExpand.done)=\"expandAnimationDone($event)\">\n <ng-content select=\"[clrIfExpanded], clr-vertical-nav-group-children\"></ng-content>\n</div>\n" }]
}], ctorParameters: function () { return [{ type: i1.IfExpandService }, { type: i2.VerticalNavGroupRegistrationService }, { type: i3.VerticalNavGroupService }, { type: i4.VerticalNavService }, { type: i5.ClrCommonStringsService }]; }, propDecorators: { expandedChange: [{
type: Output,
args: ['clrVerticalNavGroupExpandedChange']
}], expanded: [{
type: HostBinding,
args: ['class.is-expanded']
}], userExpandedInput: [{
type: Input,
args: ['clrVerticalNavGroupExpanded']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVydGljYWwtbmF2LWdyb3VwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvbGF5b3V0L3ZlcnRpY2FsLW5hdi92ZXJ0aWNhbC1uYXYtZ3JvdXAudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyL3NyYy9sYXlvdXQvdmVydGljYWwtbmF2L3ZlcnRpY2FsLW5hdi1ncm91cC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFrQixLQUFLLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRyxPQUFPLEVBQW9CLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHakgsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBRzlFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDOzs7Ozs7OztBQUdqRixNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUM7QUFDbEMsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDO0FBZXBDLE1BQU0sT0FBTyxtQkFBbUI7SUFPOUIsWUFDVSxXQUE0QixFQUM1Qiw0QkFBaUUsRUFDakUsZ0JBQXlDLEVBQ3pDLFdBQStCLEVBQ2hDLGFBQXNDO1FBSnJDLGdCQUFXLEdBQVgsV0FBVyxDQUFpQjtRQUM1QixpQ0FBNEIsR0FBNUIsNEJBQTRCLENBQXFDO1FBQ2pFLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBeUI7UUFDekMsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO1FBQ2hDLGtCQUFhLEdBQWIsYUFBYSxDQUF5QjtRQVhGLG1CQUFjLEdBQUcsSUFBSSxZQUFZLENBQVUsSUFBSSxDQUFDLENBQUM7UUFFdEYsZ0JBQVcsR0FBRyxLQUFLLENB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O3NCQURwQixLQUFLO3VCQUFDLDZCQUE2QiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYtMjAyMyBWTXdhcmUsIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgYW5pbWF0ZSwgQW5pbWF0aW9uRXZlbnQsIHN0YXRlLCBzdHlsZSwgdHJhbnNpdGlvbiwgdHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL2FuaW1hdGlvbnMnO1xuaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIEhvc3RCaW5kaW5nLCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBJZkV4cGFuZFNlcnZpY2UgfSBmcm9tICcuLi8uLi91dGlscy9jb25kaXRpb25hbC9pZi1leHBhbmRlZC5zZXJ2aWNlJztcbmltcG9ydCB7IENsckNvbW1vblN0cmluZ3NTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vdXRpbHMvaTE4bi9jb21tb24tc3RyaW5ncy5zZXJ2aWNlJztcbmltcG9ydCB7IFZlcnRpY2FsTmF2R3JvdXBSZWdpc3RyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi9wcm92aWRlcnMvdmVydGljYWwtbmF2LWdyb3VwLXJlZ2lzdHJhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IFZlcnRpY2FsTmF2R3JvdXBTZXJ2aWNlIH0gZnJvbSAnLi9wcm92aWRlcnMvdmVydGljYWwtbmF2LWdyb3VwLnNlcnZpY2UnO1xuaW1wb3J0IHsgVmVydGljYWxOYXZTZXJ2aWNlIH0gZnJvbSAnLi9wcm92aWRlcnMvdmVydGljYWwtbmF2LnNlcnZpY2UnO1xuXG5jb25zdCBFWFBBTkRFRF9TVEFURSA9ICdleHBhbmRlZCc7XG5jb25zdCBDT0xMQVBTRURfU1RBVEUgPSAnY29sbGFwc2VkJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2xyLXZlcnRpY2FsLW5hdi1ncm91cCcsXG4gIHRlbXBsYXRlVXJsOiAnLi92ZXJ0aWNhbC1uYXYtZ3JvdXAuaHRtbCcsXG4gIHByb3ZpZGVyczogW0lmRXhwYW5kU2VydmljZSwgVmVydGljYWxOYXZHcm91cFNlcnZpY2VdLFxuICBhbmltYXRpb25zOiBbXG4gICAgdHJpZ2dlcignY2xyRXhwYW5kJywgW1xuICAgICAgc3RhdGUoRVhQQU5ERURfU1RBVEUsIHN0eWxlKHsgaGVpZ2h0OiAnKicgfSkpLFxuICAgICAgc3RhdGUoQ09MTEFQU0VEX1NUQVRFLCBzdHlsZSh7IGhlaWdodDogMCwgdmlzaWJpbGl0eTogJ2hpZGRlbicgfSkpLFxuICAgICAgdHJhbnNpdGlvbihgJHtFWFBBTkRFRF9TVEFURX0gPD0+ICR7Q09MTEFQU0VEX1NUQVRFfWAsIGFuaW1hdGUoJzAuMnMgZWFzZS1pbi1vdXQnKSksXG4gICAgXSksXG4gIF0sXG4gIGhvc3Q6IHsgY2xhc3M6ICduYXYtZ3JvdXAnIH0sXG59KVxuZXhwb3J0IGNsYXNzIENsclZlcnRpY2FsTmF2R3JvdXAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICBAT3V0cHV0KCdjbHJWZXJ0aWNhbE5hdkdyb3VwRXhwYW5kZWRDaGFuZ2UnKSBleHBhbmRlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4odHJ1ZSk7XG5cbiAgcHJpdmF0ZSB3YXNFeHBhbmRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuICBwcml2YXRlIF9leHBhbmRBbmltYXRpb25TdGF0ZTogc3RyaW5nID0gQ09MTEFQU0VEX1NUQVRFO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2l0ZW1FeHBhbmQ6IElmRXhwYW5kU2VydmljZSxcbiAgICBwcml2YXRlIF9uYXZHcm91cFJlZ2lzdHJhdGlvblNlcnZpY2U6IFZlcnRpY2FsTmF2R3JvdXBSZWdpc3RyYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgX25hdkdyb3VwU2VydmljZTogVmVydGljYWxOYXZHcm91cFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBfbmF2U2VydmljZTogVmVydGljYWxOYXZTZXJ2aWNlLFxuICAgIHB1YmxpYyBjb21tb25TdHJpbmdzOiBDbHJDb21tb25TdHJpbmdzU2VydmljZVxuICApIHtcbiAgICB0aGlzLl9uYXZHcm91cFJlZ2lzdHJhdGlvblNlcnZpY2UucmVnaXN0ZXJOYXZHcm91cCgpO1xuXG4gICAgLy8gRklYTUU6IFRoaXMgc3Vic2NyaXB0aW9uIGhhbmRsZXMgYSBjb3JuZXIgY2FzZVxuICAgIC8vIFZlcnRpY2FsIE5hdiBjb2xsYXBzZSByZXF1aXJlcyB0aGUgYW5pbWF0aW9uIHRvIHJ1biBmaXJzdCBhbmQgdGhlblxuICAgIC8vIHJlbW92ZSB0aGUgbm9kZXMgZnJvbSB0aGUgRE9NLiBJZiB0aGUgdXNlciBkaXJlY3RseSBzZXRzIHRoZSBpbnB1dFxuICAgIC8vIG9uIHRoZSBjbHJJZkV4cGFuZGVkIGRpcmVjdGl2ZSwgd2UgaGF2ZSBubyBjaGFuY2UgdG8gcnVuIHRoZSBhbmltYXRpb25cbiAgICAvLyBhbmQgd2FpdCBmb3IgaXQgdG8gY29tcGxldGUuIFRoaXMgc3Vic2NyaXB0aW9uIG1ha2VzIHN1cmUgdGhhdCB0aGVcbiAgICAvLyBhbmltYXRpb24gc3RhdGVzIGFyZSBjb3JyZWN0IGZvciB0aGF0IGVkZ2UgY2FzZS5cbiAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLl9pdGVtRXhwYW5kLmV4cGFuZENoYW5nZS5zdWJzY3JpYmUodmFsdWUgPT4ge1xuICAgICAgICBpZiAodmFsdWUgJiYgdGhpcy5leHBhbmRBbmltYXRpb25TdGF0ZSA9PT0gQ09MTEFQU0VEX1NUQVRFKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX25hdlNlcnZpY2UuY29sbGFwc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXZTZXJ2aWNlLmNvbGxhcHNlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmV4cGFuZEFuaW1hdGlvblN0YXRlID0gRVhQQU5ERURfU1RBVEU7XG4gICAgICAgIH0gZWxzZSBpZiAoIXZhbHVlICYmIHRoaXMuZXhwYW5kQW5pbWF0aW9uU3RhdGUgPT09IEVYUEFOREVEX1NUQVRFKSB7XG4gICAgICAgICAgdGhpcy5leHBhbmRBbmltYXRpb25TdGF0ZSA9IENPTExBUFNFRF9TVEFURTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gMS4gSWYgdGhlIG5hdiBpcyBjb2xsYXBzaW5nLCBjbG9zZSB0aGUgb3BlbiBuYXYgZ3JvdXAgKyBzYXZlIGl0cyBzdGF0ZVxuICAgIC8vIDIuIElmIHRoZSBuYXYgaXMgZXhwYW5kaW5nLCBleHBhbmQgdGhlIG5hdiBncm91cCBpZiB0aGUgcHJldmlvdXMgc3RhdGUgd2FzIGV4cGFuZGVkXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5fbmF2U2VydmljZS5hbmltYXRlT25Db2xsYXBzZWQuc3Vic2NyaWJlKChnb2luZ1RvQ29sbGFwc2U6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKGdvaW5nVG9Db2xsYXBzZSAmJiB0aGlzLmV4cGFuZGVkKSB7XG4gICAgICAgICAgdGhpcy53YXNFeHBhbmRlZCA9IHRydWU7XG4gICAgICAgICAgdGhpcy5leHBhbmRBbmltYXRpb25TdGF0ZSA9IENPTExBUFNFRF9TVEFURTtcbiAgICAgICAgfSBlbHNlIGlmICghZ29pbmdUb0NvbGxhcHNlICYmIHRoaXMud2FzRXhwYW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmV4cGFuZEdyb3VwKCk7XG4gICAgICAgICAgdGhpcy53YXNFeHBhbmRlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBJZiBhIGxpbmsgaXMgY2xpY2tlZCwgZXhwYW5kIHRoZSBuYXYgZ3JvdXBcbiAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLl9uYXZHcm91cFNlcnZpY2UuZXhwYW5kQ2hhbmdlLnN1YnNjcmliZSgoZXhwYW5kOiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChleHBhbmQgJiYgIXRoaXMuZXhwYW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmV4cGFuZEdyb3VwKCk7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIEBIb3N0QmluZGluZygnY2xhc3MuaXMtZXhwYW5kZWQnKVxuICBnZXQgZXhwYW5kZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2l0ZW1FeHBhbmQuZXhwYW5kZWQ7XG4gIH1cbiAgc2V0IGV4cGFuZGVkKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuX2l0ZW1FeHBhbmQuZXhwYW5kZWQgIT09IHZhbHVlKSB7XG4gICAgICB0aGlzLl9pdGVtRXhwYW5kLmV4cGFuZGVkID0gdmFsdWU7XG4gICAgICB0aGlzLmV4cGFuZGVkQ2hhbmdlLmVtaXQodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIEBJbnB1dCgnY2xyVmVydGljYWxOYXZHcm91cEV4cGFuZGVkJylcbiAgc2V0IHVzZXJFeHBhbmRlZElucHV0KHZhbHVlOiBib29sZWFuIHwgc3RyaW5nKSB7XG4gICAgdmFsdWUgPSAhIXZhbHVlO1xuICAgIGlmICh0aGlzLmV4cGFuZGVkICE9PSB2YWx1ZSkge1xuICAgICAgLy8gV2UgaGF2ZSB0byBjYWxsIHRvZ2dsZUV4cGFuZCBiZWNhdXNlIHNvbWUgY2FzZXMgcmVxdWlyZSBhbmltYXRpb25zIHRvIG9jY3VyIGZpcnN0XG4gICAgICAvLyBEaXJlY3RseSBzZXR0aW5nIHRoZSBFeHBhbmQgc2VydmljZSB2YWx1ZSBza2lwcyB0aGUgYW5pbWF0aW9uIGFuZCBjYW4gcmVzdWx0IGluXG4gICAgICAvLyBub2RlcyBpbiB0aGUgRE9NIGJ1dCB0aGUgbmF2IGdyb3VwIHN0aWxsIGJlaW5nIGNvbGxhcHNlZFxuICAgICAgdGhpcy50b2dnbGVFeHBhbmQoKTtcbiAgICB9XG4gIH1cblxuICBnZXQgZXhwYW5kQW5pbWF0aW9uU3RhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fZXhwYW5kQW5pbWF0aW9uU3RhdGU7XG4gIH1cbiAgc2V0IGV4cGFuZEFuaW1hdGlvblN0YXRlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAodmFsdWUgIT09IHRoaXMuX2V4cGFuZEFuaW1hdGlvblN0YXRlKSB7XG4gICAgICB0aGlzLl9leHBhbmRBbmltYXRpb25TdGF0ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICAvLyBUaGlzIG1ha2VzIHN1cmUgdGhhdCBpZiBzb21lb25lIG1hcmtzIGEgbmF2IGdyb3VwIGV4cGFuZGVkIGluIGEgY29sbGFwc2VkIG5hdlxuICAgIC8vIHRoZSBleHBhbmRlZCBwcm9wZXJ0eSBpcyBzd2l0Y2hlZCBiYWNrIHRvIGNvbGxhcHNlZCBzdGF0ZS5cbiAgICBpZiAodGhpcy5fbmF2U2VydmljZS5jb2xsYXBzZWQgJiYgdGhpcy5leHBhbmRlZCkge1xuICAgICAgdGhpcy53YXNFeHBhbmRlZCA9IHRydWU7XG4gICAgICB0aGlzLmV4cGFuZEFuaW1hdGlvblN0YXRlID0gQ09MTEFQU0VEX1NUQVRFO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbnMuZm9yRWFjaCgoc3ViOiBTdWJzY3JpcHRpb24pID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgICB0aGlzLl9uYXZHcm91cFJlZ2lzdHJhdGlvblNlcnZpY2UudW5yZWdpc3Rlck5hdkdyb3VwKCk7XG4gIH1cblxuICBleHBhbmRHcm91cCgpOiB2b2lkIHtcbiAgICB0aGlzLmV4cGFuZGVkID0gdHJ1ZTtcbiAgICAvLyBFeHBhbmRlZCBhbmltYXRpb24gb2NjdXJzIGFmdGVyIEV4cGFuZC5leHBhbmQgaXMgc2V0IHRvIHRydWVcbiAgICB0aGlzLmV4cGFuZEFuaW1hdGlvblN0YXRlID0gRVhQQU5ERURfU1RBVEU7XG4gIH1cblxuICBjb2xsYXBzZUdyb3VwKCk6IHZvaWQge1xuICAgIC8vIElmIGEgVmVydGljYWwgTmF2IEdyb3VwIHRvZ2dsZSBidXR0b24gaXMgY2xpY2tlZCB3aGlsZSB0aGUgVmVydGljYWwgTmF2IGlzIGluIENvbGxhcHNlZCBzdGF0ZSxcbiAgICAvLyB0aGUgVmVydGljYWwgTmF2IHNob3VsZCBiZSBleHBhbmRlZCBmaXJzdC5cbiAgICB0aGlzLmV4cGFuZEFuaW1hdGlvblN0YXRlID0gQ09MTEFQU0VEX1NUQVRFO1xuICB9XG5cbiAgLy8gY2xvc2VzIGEgZ3JvdXAgYWZ0ZXIgdGhlIGNvbGxhcHNlIGFuaW1hdGlvblxuICBleHBhbmRBbmltYXRpb25Eb25lKCRldmVudDogQW5pbWF0aW9uRXZlbnQpIHtcbiAgICBpZiAoJGV2ZW50LnRvU3RhdGUgPT09IENPTExBUFNFRF9TVEFURSkge1xuICAgICAgdGhpcy5leHBhbmRlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZUV4cGFuZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5leHBhbmRlZCkge1xuICAgICAgdGhpcy5jb2xsYXBzZUdyb3VwKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIG5hdiBpcyBjb2xsYXNwZWQsIGZpcnN0IG9wZW4gdGhlIG5hdlxuICAgICAgaWYgKHRoaXMuX25hdlNlcnZpY2UuY29sbGFwc2VkKSB7XG4gICAgICAgIHRoaXMuX25hdlNlcnZpY2UuY29sbGFwc2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyB0aGVuIGV4cGFuZCB0aGUgbmF2IGdyb3VwXG4gICAgICB0aGlzLmV4cGFuZEdyb3VwKCk7XG4gICAgfVxuICB9XG59XG4iLCI8IS0tXG4gIH4gQ29weXJpZ2h0IChjKSAyMDE2LTIwMjMgVk13YXJlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gIH4gVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBNSVQgbGljZW5zZS5cbiAgfiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gIC0tPlxuXG48ZGl2IGNsYXNzPVwibmF2LWdyb3VwLWNvbnRlbnRcIj5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2NsclZlcnRpY2FsTmF2TGlua11cIj48L25nLWNvbnRlbnQ+XG4gIDxidXR0b24gY2xhc3M9XCJuYXYtZ3JvdXAtdHJpZ2dlclwiIHR5cGU9XCJidXR0b25cIiBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImV4cGFuZGVkXCIgKGNsaWNrKT1cInRvZ2dsZUV4cGFuZCgpXCI+XG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2NsclZlcnRpY2FsTmF2SWNvbl1cIj48L25nLWNvbnRlbnQ+XG4gICAgPGRpdiBjbGFzcz1cIm5hdi1ncm91cC10ZXh0XCI+XG4gICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gICAgPGNkcy1pY29uIHNoYXBlPVwiYW5nbGVcIiBjbGFzcz1cIm5hdi1ncm91cC10cmlnZ2VyLWljb25cIiBbYXR0ci5kaXJlY3Rpb25dPVwiZXhwYW5kZWQgPyAnZG93bicgOiAncmlnaHQnXCI+PC9jZHMtaWNvbj5cbiAgPC9idXR0b24+XG48L2Rpdj5cbjwhLS1UT0RPOiBUaGlzIGFuaW1hdGlvbiBuZWVkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xyLXZlcnRpY2FsLW5hdi1ncm91cC1jaGlsZHJlbiBjb21wb25lbnQtLT5cbjxkaXYgY2xhc3M9XCJuYXYtZ3JvdXAtY2hpbGRyZW5cIiBbQGNsckV4cGFuZF09XCJleHBhbmRBbmltYXRpb25TdGF0ZVwiIChAY2xyRXhwYW5kLmRvbmUpPVwiZXhwYW5kQW5pbWF0aW9uRG9uZSgkZXZlbnQpXCI+XG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIltjbHJJZkV4cGFuZGVkXSwgY2xyLXZlcnRpY2FsLW5hdi1ncm91cC1jaGlsZHJlblwiPjwvbmctY29udGVudD5cbjwvZGl2PlxuIl19