UNPKG

carbon-components-angular

Version:
415 lines (407 loc) 35.1 kB
import { Component, Input, Output, EventEmitter, HostBinding, TemplateRef, ViewChild, ContentChild } from "@angular/core"; import { PasswordInput } from "./password.directive"; import { BaseIconButton } from "carbon-components-angular/button"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "carbon-components-angular/icon"; import * as i3 from "carbon-components-angular/tooltip"; /** * Get started with importing the module: * * ```typescript * import { InputModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-password-label> * Label * <input cdsPassword> * </cds-password-label> * ``` * * [See demo](../../?path=/story/components-input--basic) */ /** * Represents the Password Input Label Component. */ export class PasswordInputLabelComponent extends BaseIconButton { /** * Constructor for PasswordInputLabelComponent. * @param changeDetectorRef - Reference to ChangeDetectorRef. */ constructor(changeDetectorRef) { super(); this.changeDetectorRef = changeDetectorRef; /** * ID for the input item associated with the label. */ this.labelInputID = "cds-password-input-" + PasswordInputLabelComponent.labelCounter++; /** * Type for input field, either password or text. */ this.inputType = "password"; /** * Flag for checking if password is visible. */ this.passwordIsVisible = false; /** * Flag for disabled label. */ this.disabled = false; /** * Flag for loading (skeleton) label. */ this.skeleton = false; /** * Flag for an invalid label component. */ this.invalid = false; /** * Flag for showing a warning. */ this.warn = false; /** * Tooltip text for hiding password. */ this.hidePasswordLabel = "Hide password"; /** * Tooltip text for showing password. */ this.showPasswordLabel = "Show password"; /** * Experimental: enable fluid state */ this.fluid = false; /** * Set to `true` to hide the label visually, but keep accessible to * screen readers. */ this.hideLabel = false; /** * Set to `true` to render the label and field side-by-side instead of stacked. */ this.inline = false; /** * Emits whenever the show/hide password visibility toggle button is clicked. * Mirrors the `onTogglePasswordVisibility` prop of the React `PasswordInput` * component. */ this.togglePasswordVisibility = new EventEmitter(); /** * Binding for applying class to host element. */ this.labelClass = true; this.passwordInputWrapper = true; this.textInputWrapper = true; } get isReadonly() { return this.wrapper?.nativeElement.querySelector("input")?.readOnly ?? false; } get isInlineWrapper() { return this.inline; } get fluidClass() { return this.fluid && !this.skeleton; } get fluidSkeletonClass() { return this.fluid && this.skeleton; } /** * Lifecycle hook called after the view has been initialized to set the ID of the input element */ ngAfterViewInit() { if (this.wrapper) { const inputElement = this.wrapper.nativeElement.querySelector("input"); if (inputElement) { if (inputElement.id) { this.labelInputID = inputElement.id; this.changeDetectorRef.detectChanges(); } inputElement.setAttribute("id", this.labelInputID); return; } } } /** * Function to check if a value is a TemplateRef. * @param value - Value to check. * @returns Whether the value is a TemplateRef. */ isTemplate(value) { return value instanceof TemplateRef; } /** * Handler for toggling password visibility. */ handleTogglePasswordVisibility() { this.inputType = this.inputType === "password" ? "text" : "password"; this.textInput.type = this.inputType; this.passwordIsVisible = this.inputType === "text"; this.togglePasswordVisibility.emit(this.inputType); } } /** * Counter for generating unique labelInputID. */ PasswordInputLabelComponent.labelCounter = 0; PasswordInputLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PasswordInputLabelComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); PasswordInputLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PasswordInputLabelComponent, selector: "cds-password-label, ibm-password-label", inputs: { labelInputID: "labelInputID", disabled: "disabled", skeleton: "skeleton", labelTemplate: "labelTemplate", passwordInputTemplate: "passwordInputTemplate", helperText: "helperText", invalidText: "invalidText", invalid: "invalid", warn: "warn", warnText: "warnText", ariaLabel: "ariaLabel", hidePasswordLabel: "hidePasswordLabel", showPasswordLabel: "showPasswordLabel", fluid: "fluid", hideLabel: "hideLabel", inline: "inline" }, outputs: { togglePasswordVisibility: "togglePasswordVisibility" }, host: { properties: { "class.cds--form-item": "this.labelClass", "class.cds--password-input-wrapper": "this.passwordInputWrapper", "class.cds--text-input-wrapper": "this.textInputWrapper", "class.cds--text-input-wrapper--readonly": "this.isReadonly", "class.cds--text-input-wrapper--inline": "this.isInlineWrapper", "class.cds--text-input--fluid": "this.fluidClass", "class.cds--text-input--fluid__skeleton": "this.fluidSkeletonClass" } }, queries: [{ propertyName: "textInput", first: true, predicate: PasswordInput, descendants: true }], viewQueries: [{ propertyName: "wrapper", first: true, predicate: ["wrapper"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: ` <ng-container *ngIf="skeleton"> <span class="cds--label cds--skeleton"></span> <div class="cds--text-input cds--skeleton"></div> </ng-container> <label *ngIf="!skeleton" [for]="labelInputID" [attr.aria-label]="ariaLabel" class="cds--label" [ngClass]="{ 'cds--label--disabled': disabled, 'cds--visually-hidden': hideLabel, 'cds--label--inline': inline }"> <ng-template *ngIf="labelTemplate; else labelContent" [ngTemplateOutlet]="labelTemplate"></ng-template> <ng-template #labelContent> <ng-content></ng-content> </ng-template> </label> <div *ngIf="!skeleton" class="cds--text-input__field-outer-wrapper" [ngClass]="{'cds--text-input__field-outer-wrapper--inline': inline}"> <div class="cds--text-input__field-wrapper" [ngClass]="{ 'cds--text-input__field-wrapper--warning': warn }" [attr.data-invalid]="invalid ? true : null" #wrapper> <svg *ngIf="!warn && invalid" cdsIcon="warning--filled" size="16" class="cds--text-input__invalid-icon"> </svg> <svg *ngIf="!invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning"> </svg> <ng-content select="[cdsPassword], [ibmPassword]"></ng-content> <cds-tooltip *ngIf="!skeleton" [description]="passwordIsVisible ? hidePasswordLabel : showPasswordLabel" [disabled]="disabled" [caret]="caret" [dropShadow]="dropShadow" [highContrast]="highContrast" [isOpen]="isOpen" [align]="align" [autoAlign]="autoAlign" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" class="cds--toggle-password-tooltip"> <div class="cds--tooltip-trigger__wrapper"> <button class="cds--text-input--password__visibility__toggle cds--btn cds--tooltip__trigger cds--tooltip--a11y" [disabled]="disabled" type="button" (click)="handleTogglePasswordVisibility($event)"> <svg *ngIf="passwordIsVisible" cdsIcon="view--off" class="cds--icon-visibility-off" size="16"></svg> <svg *ngIf="!passwordIsVisible" cdsIcon="view" class="cds--icon-visibility-on" size="16"></svg> </button> </div> </cds-tooltip> <ng-container *ngIf="fluid"> <hr class="cds--text-input__divider" /> <div *ngIf="!warn && invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </ng-container> </div> <ng-container *ngIf="!fluid"> <div *ngIf="!skeleton && helperText && !invalid && !warn" class="cds--form__helper-text" [ngClass]="{ 'cds--form__helper-text--disabled': disabled }"> <ng-container *ngIf="!isTemplate(helperText)">{{ helperText }}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template> </div> <div *ngIf="!warn && invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </ng-container> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i3.Tooltip, selector: "cds-tooltip, ibm-tooltip", inputs: ["id", "enterDelayMs", "leaveDelayMs", "disabled", "description", "templateContext"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PasswordInputLabelComponent, decorators: [{ type: Component, args: [{ selector: "cds-password-label, ibm-password-label", template: ` <ng-container *ngIf="skeleton"> <span class="cds--label cds--skeleton"></span> <div class="cds--text-input cds--skeleton"></div> </ng-container> <label *ngIf="!skeleton" [for]="labelInputID" [attr.aria-label]="ariaLabel" class="cds--label" [ngClass]="{ 'cds--label--disabled': disabled, 'cds--visually-hidden': hideLabel, 'cds--label--inline': inline }"> <ng-template *ngIf="labelTemplate; else labelContent" [ngTemplateOutlet]="labelTemplate"></ng-template> <ng-template #labelContent> <ng-content></ng-content> </ng-template> </label> <div *ngIf="!skeleton" class="cds--text-input__field-outer-wrapper" [ngClass]="{'cds--text-input__field-outer-wrapper--inline': inline}"> <div class="cds--text-input__field-wrapper" [ngClass]="{ 'cds--text-input__field-wrapper--warning': warn }" [attr.data-invalid]="invalid ? true : null" #wrapper> <svg *ngIf="!warn && invalid" cdsIcon="warning--filled" size="16" class="cds--text-input__invalid-icon"> </svg> <svg *ngIf="!invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--text-input__invalid-icon cds--text-input__invalid-icon--warning"> </svg> <ng-content select="[cdsPassword], [ibmPassword]"></ng-content> <cds-tooltip *ngIf="!skeleton" [description]="passwordIsVisible ? hidePasswordLabel : showPasswordLabel" [disabled]="disabled" [caret]="caret" [dropShadow]="dropShadow" [highContrast]="highContrast" [isOpen]="isOpen" [align]="align" [autoAlign]="autoAlign" [enterDelayMs]="enterDelayMs" [leaveDelayMs]="leaveDelayMs" class="cds--toggle-password-tooltip"> <div class="cds--tooltip-trigger__wrapper"> <button class="cds--text-input--password__visibility__toggle cds--btn cds--tooltip__trigger cds--tooltip--a11y" [disabled]="disabled" type="button" (click)="handleTogglePasswordVisibility($event)"> <svg *ngIf="passwordIsVisible" cdsIcon="view--off" class="cds--icon-visibility-off" size="16"></svg> <svg *ngIf="!passwordIsVisible" cdsIcon="view" class="cds--icon-visibility-on" size="16"></svg> </button> </div> </cds-tooltip> <ng-container *ngIf="fluid"> <hr class="cds--text-input__divider" /> <div *ngIf="!warn && invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </ng-container> </div> <ng-container *ngIf="!fluid"> <div *ngIf="!skeleton && helperText && !invalid && !warn" class="cds--form__helper-text" [ngClass]="{ 'cds--form__helper-text--disabled': disabled }"> <ng-container *ngIf="!isTemplate(helperText)">{{ helperText }}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template> </div> <div *ngIf="!warn && invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{ invalidText }}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{ warnText }}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </ng-container> </div> ` }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { textInput: [{ type: ContentChild, args: [PasswordInput] }], labelInputID: [{ type: Input }], disabled: [{ type: Input }], skeleton: [{ type: Input }], labelTemplate: [{ type: Input }], passwordInputTemplate: [{ type: Input }], helperText: [{ type: Input }], invalidText: [{ type: Input }], invalid: [{ type: Input }], warn: [{ type: Input }], warnText: [{ type: Input }], ariaLabel: [{ type: Input }], hidePasswordLabel: [{ type: Input }], showPasswordLabel: [{ type: Input }], fluid: [{ type: Input }], hideLabel: [{ type: Input }], inline: [{ type: Input }], togglePasswordVisibility: [{ type: Output }], wrapper: [{ type: ViewChild, args: ["wrapper", { static: true }] }], labelClass: [{ type: HostBinding, args: ["class.cds--form-item"] }], passwordInputWrapper: [{ type: HostBinding, args: ["class.cds--password-input-wrapper"] }], textInputWrapper: [{ type: HostBinding, args: ["class.cds--text-input-wrapper"] }], isReadonly: [{ type: HostBinding, args: ["class.cds--text-input-wrapper--readonly"] }], isInlineWrapper: [{ type: HostBinding, args: ["class.cds--text-input-wrapper--inline"] }], fluidClass: [{ type: HostBinding, args: ["class.cds--text-input--fluid"] }], fluidSkeletonClass: [{ type: HostBinding, args: ["class.cds--text-input--fluid__skeleton"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFzc3dvcmQtaW5wdXQtbGFiZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2lucHV0L3Bhc3N3b3JkLWlucHV0LWxhYmVsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUdaLFdBQVcsRUFDWCxXQUFXLEVBQ1gsU0FBUyxFQUVULFlBQVksRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7OztBQUVsRTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUF3R0g7O0dBRUc7QUFDSCxNQUFNLE9BQU8sMkJBQTRCLFNBQVEsY0FBYztJQXFJOUQ7OztPQUdHO0lBQ0gsWUFBc0IsaUJBQW9DO1FBQ3pELEtBQUssRUFBRSxDQUFDO1FBRGEsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQWpJMUQ7O1dBRUc7UUFDTSxpQkFBWSxHQUFHLHFCQUFxQixHQUFHLDJCQUEyQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBRTNGOztXQUVHO1FBQ0gsY0FBUyxHQUF3QixVQUFVLENBQUM7UUFFNUM7O1VBRUU7UUFDRixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFFMUI7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRTFCOztXQUVHO1FBQ00sYUFBUSxHQUFHLEtBQUssQ0FBQztRQXNCMUI7O1dBRUc7UUFDTSxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBRXpCOztXQUVHO1FBQ00sU0FBSSxHQUFHLEtBQUssQ0FBQztRQVl0Qjs7V0FFRztRQUNNLHNCQUFpQixHQUFHLGVBQWUsQ0FBQztRQUU3Qzs7V0FFRztRQUNNLHNCQUFpQixHQUFHLGVBQWUsQ0FBQztRQUU3Qzs7V0FFRztR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Z0JBS0csUUFBUTtzQkFBaEIsS0FBSztnQkFLRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFLRyxVQUFVO3NCQUFsQixLQUFLO2dCQUtHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBS0csT0FBTztzQkFBZixLQUFLO2dCQUtHLElBQUk7c0JBQVosS0FBSztnQkFLRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBS0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUtHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFLRyxLQUFLO3NCQUFiLEtBQUs7Z0JBTUcsU0FBUztzQkFBakIsS0FBSztnQkFLRyxNQUFNO3NCQUFkLEtBQUs7Z0JBT0ksd0JBQXdCO3NCQUFqQyxNQUFNO2dCQUtpQyxPQUFPO3NCQUE5QyxTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBS0QsVUFBVTtzQkFBOUMsV0FBVzt1QkFBQyxzQkFBc0I7Z0JBQ2Usb0JBQW9CO3NCQUFyRSxXQUFXO3VCQUFDLG1DQUFtQztnQkFDRixnQkFBZ0I7c0JBQTdELFdBQVc7dUJBQUMsK0JBQStCO2dCQUNnQixVQUFVO3NCQUFyRSxXQUFXO3VCQUFDLHlDQUF5QztnQkFJSSxlQUFlO3NCQUF4RSxXQUFXO3VCQUFDLHVDQUF1QztnQkFJSCxVQUFVO3NCQUExRCxXQUFXO3VCQUFDLDhCQUE4QjtnQkFJZ0Isa0JBQWtCO3NCQUE1RSxXQUFXO3VCQUFDLHdDQUF3QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdE91dHB1dCxcblx0RXZlbnRFbWl0dGVyLFxuXHRBZnRlclZpZXdJbml0LFxuXHRFbGVtZW50UmVmLFxuXHRIb3N0QmluZGluZyxcblx0VGVtcGxhdGVSZWYsXG5cdFZpZXdDaGlsZCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbnRlbnRDaGlsZFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgUGFzc3dvcmRJbnB1dCB9IGZyb20gXCIuL3Bhc3N3b3JkLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgQmFzZUljb25CdXR0b24gfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci9idXR0b25cIjtcblxuLyoqXG4gKiBHZXQgc3RhcnRlZCB3aXRoIGltcG9ydGluZyB0aGUgbW9kdWxlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IElucHV0TW9kdWxlIH0gZnJvbSAnY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhcic7XG4gKiBgYGBcbiAqXG4gKiBgYGBodG1sXG4gKiA8Y2RzLXBhc3N3b3JkLWxhYmVsPlxuICogXHRMYWJlbFxuICpcdDxpbnB1dCBjZHNQYXNzd29yZD5cbiAqIDwvY2RzLXBhc3N3b3JkLWxhYmVsPlxuICogYGBgXG4gKlxuICogW1NlZSBkZW1vXSguLi8uLi8/cGF0aD0vc3RvcnkvY29tcG9uZW50cy1pbnB1dC0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtcGFzc3dvcmQtbGFiZWwsIGlibS1wYXNzd29yZC1sYWJlbFwiLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJza2VsZXRvblwiPlxuXHRcdFx0PHNwYW4gY2xhc3M9XCJjZHMtLWxhYmVsIGNkcy0tc2tlbGV0b25cIj48L3NwYW4+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0IGNkcy0tc2tlbGV0b25cIj48L2Rpdj5cblx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHQ8bGFiZWxcblx0XHRcdCpuZ0lmPVwiIXNrZWxldG9uXCJcblx0XHRcdFtmb3JdPVwibGFiZWxJbnB1dElEXCJcblx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdGNsYXNzPVwiY2RzLS1sYWJlbFwiXG5cdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdCdjZHMtLWxhYmVsLS1kaXNhYmxlZCc6IGRpc2FibGVkLFxuXHRcdFx0XHQnY2RzLS12aXN1YWxseS1oaWRkZW4nOiBoaWRlTGFiZWwsXG5cdFx0XHRcdCdjZHMtLWxhYmVsLS1pbmxpbmUnOiBpbmxpbmVcblx0XHRcdH1cIj5cblx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImxhYmVsVGVtcGxhdGU7IGVsc2UgbGFiZWxDb250ZW50XCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibGFiZWxUZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHQ8bmctdGVtcGxhdGUgI2xhYmVsQ29udGVudD5cblx0XHRcdFx0PG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuXHRcdFx0PC9uZy10ZW1wbGF0ZT5cblx0XHQ8L2xhYmVsPlxuXG5cdFx0PGRpdiAqbmdJZj1cIiFza2VsZXRvblwiIGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0X19maWVsZC1vdXRlci13cmFwcGVyXCIgW25nQ2xhc3NdPVwieydjZHMtLXRleHQtaW5wdXRfX2ZpZWxkLW91dGVyLXdyYXBwZXItLWlubGluZSc6IGlubGluZX1cIj5cblx0XHRcdDxkaXZcblx0XHRcdGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0X19maWVsZC13cmFwcGVyXCJcblx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0J2Nkcy0tdGV4dC1pbnB1dF9fZmllbGQtd3JhcHBlci0td2FybmluZyc6IHdhcm5cblx0XHRcdH1cIlxuXHRcdFx0W2F0dHIuZGF0YS1pbnZhbGlkXT1cImludmFsaWQgPyB0cnVlIDogbnVsbFwiXG5cdFx0XHQjd3JhcHBlcj5cblx0XHRcdFx0PHN2Z1xuXHRcdFx0XHRcdCpuZ0lmPVwiIXdhcm4gJiYgaW52YWxpZFwiXG5cdFx0XHRcdFx0Y2RzSWNvbj1cIndhcm5pbmctLWZpbGxlZFwiXG5cdFx0XHRcdFx0c2l6ZT1cIjE2XCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tdGV4dC1pbnB1dF9faW52YWxpZC1pY29uXCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Km5nSWY9XCIhaW52YWxpZCAmJiB3YXJuXCJcblx0XHRcdFx0XHRjZHNJY29uPVwid2FybmluZy0tYWx0LS1maWxsZWRcIlxuXHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRleHQtaW5wdXRfX2ludmFsaWQtaWNvbiBjZHMtLXRleHQtaW5wdXRfX2ludmFsaWQtaWNvbi0td2FybmluZ1wiPlxuXHRcdFx0XHQ8L3N2Zz5cblx0XHRcdFx0PG5nLWNvbnRlbnQgc2VsZWN0PVwiW2Nkc1Bhc3N3b3JkXSwgW2libVBhc3N3b3JkXVwiPjwvbmctY29udGVudD5cblx0XHRcdFx0PGNkcy10b29sdGlwXG5cdFx0XHRcdFx0Km5nSWY9XCIhc2tlbGV0b25cIlxuXHRcdFx0XHRcdFtkZXNjcmlwdGlvbl09XCJwYXNzd29yZElzVmlzaWJsZSA/IGhpZGVQYXNzd29yZExhYmVsIDogc2hvd1Bhc3N3b3JkTGFiZWxcIlxuXHRcdFx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRcdFx0W2NhcmV0XT1cImNhcmV0XCJcblx0XHRcdFx0XHRbZHJvcFNoYWRvd109XCJkcm9wU2hhZG93XCJcblx0XHRcdFx0XHRbaGlnaENvbnRyYXN0XT1cImhpZ2hDb250cmFzdFwiXG5cdFx0XHRcdFx0W2lzT3Blbl09XCJpc09wZW5cIlxuXHRcdFx0XHRcdFthbGlnbl09XCJhbGlnblwiXG5cdFx0XHRcdFx0W2F1dG9BbGlnbl09XCJhdXRvQWxpZ25cIlxuXHRcdFx0XHRcdFtlbnRlckRlbGF5TXNdPVwiZW50ZXJEZWxheU1zXCJcblx0XHRcdFx0XHRbbGVhdmVEZWxheU1zXT1cImxlYXZlRGVsYXlNc1wiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXRvZ2dsZS1wYXNzd29yZC10b29sdGlwXCI+XG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS10b29sdGlwLXRyaWdnZXJfX3dyYXBwZXJcIj5cblx0XHRcdFx0XHRcdFx0PGJ1dHRvblxuXHRcdFx0XHRcdFx0XHRcdGNsYXNzPVwiY2RzLS10ZXh0LWlucHV0LS1wYXNzd29yZF9fdmlzaWJpbGl0eV9fdG9nZ2xlIGNkcy0tYnRuIGNkcy0tdG9vbHRpcF9fdHJpZ2dlciBjZHMtLXRvb2x0aXAtLWExMXlcIlxuXHRcdFx0XHRcdFx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRcdFx0XHRcdFx0dHlwZT1cImJ1dHRvblwiXG5cdFx0XHRcdFx0XHRcdFx0KGNsaWNrKT1cImhhbmRsZVRvZ2dsZVBhc3N3b3JkVmlzaWJpbGl0eSgkZXZlbnQpXCI+XG5cdFx0XHRcdFx0XHRcdFx0PHN2ZyAqbmdJZj1cInBhc3N3b3JkSXNWaXNpYmxlXCIgY2RzSWNvbj1cInZpZXctLW9mZlwiIGNsYXNzPVwiY2RzLS1pY29uLXZpc2liaWxpdHktb2ZmXCIgc2l6ZT1cIjE2XCI+PC9zdmc+XG5cdFx0XHRcdFx0XHRcdFx0PHN2ZyAqbmdJZj1cIiFwYXNzd29yZElzVmlzaWJsZVwiIGNkc0ljb249XCJ2aWV3XCIgY2xhc3M9XCJjZHMtLWljb24tdmlzaWJpbGl0eS1vblwiIHNpemU9XCIxNlwiPjwvc3ZnPlxuXHRcdFx0XHRcdFx0XHQ8L2J1dHRvbj5cblx0XHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Nkcy10b29sdGlwPlxuXG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJmbHVpZFwiPlxuXHRcdFx0XHRcdDxociBjbGFzcz1cImNkcy0tdGV4dC1pbnB1dF9fZGl2aWRlclwiIC8+XG5cdFx0XHRcdFx0PGRpdiAqbmdJZj1cIiF3YXJuICYmIGludmFsaWRcIiBjbGFzcz1cImNkcy0tZm9ybS1yZXF1aXJlbWVudFwiPlxuXHRcdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiPnt7IGludmFsaWRUZXh0IH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImludmFsaWRUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0XHQ8ZGl2ICpuZ0lmPVwiIWludmFsaWQgJiYgd2FyblwiIGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUod2FyblRleHQpXCI+e3sgd2FyblRleHQgfX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUod2FyblRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwid2FyblRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmbHVpZFwiPlxuXHRcdFx0XHQ8ZGl2XG5cdFx0XHRcdFx0Km5nSWY9XCIhc2tlbGV0b24gJiYgaGVscGVyVGV4dCAmJiAhaW52YWxpZCAmJiAhd2FyblwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLWZvcm1fX2hlbHBlci10ZXh0XCJcblx0XHRcdFx0XHRbbmdDbGFzc109XCJ7ICdjZHMtLWZvcm1fX2hlbHBlci10ZXh0LS1kaXNhYmxlZCc6IGRpc2FibGVkIH1cIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaGVscGVyVGV4dClcIj57eyBoZWxwZXJUZXh0IH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZShoZWxwZXJUZXh0KVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImhlbHBlclRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2Rpdj5cblxuXHRcdFx0XHQ8ZGl2ICpuZ0lmPVwiIXdhcm4gJiYgaW52YWxpZFwiIGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGludmFsaWRUZXh0KVwiPnt7IGludmFsaWRUZXh0IH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZShpbnZhbGlkVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpbnZhbGlkVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDwvZGl2PlxuXG5cdFx0XHRcdDxkaXYgKm5nSWY9XCIhaW52YWxpZCAmJiB3YXJuXCIgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUod2FyblRleHQpXCI+e3sgd2FyblRleHQgfX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKHdhcm5UZXh0KVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIndhcm5UZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHQ8L2Rpdj5cbiAgICBgXG59KVxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBQYXNzd29yZCBJbnB1dCBMYWJlbCBDb21wb25lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXNzd29yZElucHV0TGFiZWxDb21wb25lbnQgZXh0ZW5kcyBCYXNlSWNvbkJ1dHRvbiBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuXHQvKipcblx0ICogQ291bnRlciBmb3IgZ2VuZXJhdGluZyB1bmlxdWUgbGFiZWxJbnB1dElELlxuXHQgKi9cblx0c3RhdGljIGxhYmVsQ291bnRlciA9IDA7XG5cblx0QENvbnRlbnRDaGlsZChQYXNzd29yZElucHV0KSB0ZXh0SW5wdXQ6IFBhc3N3b3JkSW5wdXQ7XG5cblx0LyoqXG5cdCAqIElEIGZvciB0aGUgaW5wdXQgaXRlbSBhc3NvY2lhdGVkIHdpdGggdGhlIGxhYmVsLlxuXHQgKi9cblx0QElucHV0KCkgbGFiZWxJbnB1dElEID0gXCJjZHMtcGFzc3dvcmQtaW5wdXQtXCIgKyBQYXNzd29yZElucHV0TGFiZWxDb21wb25lbnQubGFiZWxDb3VudGVyKys7XG5cblx0LyoqXG5cdCAqIFR5cGUgZm9yIGlucHV0IGZpZWxkLCBlaXRoZXIgcGFzc3dvcmQgb3IgdGV4dC5cblx0ICovXG5cdGlucHV0VHlwZTogXCJwYXNzd29yZFwiIHwgXCJ0ZXh0XCIgPSBcInBhc3N3b3JkXCI7XG5cblx0LyoqXG5cdCogRmxhZyBmb3IgY2hlY2tpbmcgaWYgcGFzc3dvcmQgaXMgdmlzaWJsZS5cblx0Ki9cblx0cGFzc3dvcmRJc1Zpc2libGUgPSBmYWxzZTtcblxuXHQvKipcblx0ICogRmxhZyBmb3IgZGlzYWJsZWQgbGFiZWwuXG5cdCAqL1xuXHRASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBGbGFnIGZvciBsb2FkaW5nIChza2VsZXRvbikgbGFiZWwuXG5cdCAqL1xuXHRASW5wdXQoKSBza2VsZXRvbiA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBUZW1wbGF0ZSBmb3IgbGFiZWwgY29udGVudC5cblx0ICovXG5cdEBJbnB1dCgpIGxhYmVsVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIFRlbXBsYXRlIGZvciBwYXNzd29yZCBpbnB1dC5cblx0ICovXG5cdEBJbnB1dCgpIHBhc3N3b3JkSW5wdXRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuXHQvKipcblx0ICogT3B0aW9uYWwgaGVscGVyIHRleHQgdW5kZXIgdGhlIGxhYmVsLlxuXHQgKi9cblx0QElucHV0KCkgaGVscGVyVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55PjtcblxuXHQvKipcblx0ICogU2V0cyB0aGUgaW52YWxpZCB0ZXh0LlxuXHQgKi9cblx0QElucHV0KCkgaW52YWxpZFRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIEZsYWcgZm9yIGFuIGludmFsaWQgbGFiZWwgY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgaW52YWxpZCA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBGbGFnIGZvciBzaG93aW5nIGEgd2FybmluZy5cblx0ICovXG5cdEBJbnB1dCgpIHdhcm4gPSBmYWxzZTtcblxuXHQvKipcblx0ICogV2FybmluZyB0ZXh0LlxuXHQgKi9cblx0QElucHV0KCkgd2FyblRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIEFyaWEgbGFiZWwgZm9yIGxhYmVsLlxuXHQgKi9cblx0QElucHV0KCkgYXJpYUxhYmVsOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIFRvb2x0aXAgdGV4dCBmb3IgaGlkaW5nIHBhc3N3b3JkLlxuXHQgKi9cblx0QElucHV0KCkgaGlkZVBhc3N3b3JkTGFiZWwgPSBcIkhpZGUgcGFzc3dvcmRcIjtcblxuXHQvKipcblx0ICogVG9vbHRpcCB0ZXh0IGZvciBzaG93aW5nIHBhc3N3b3JkLlxuXHQgKi9cblx0QElucHV0KCkgc2hvd1Bhc3N3b3JkTGFiZWwgPSBcIlNob3cgcGFzc3dvcmRcIjtcblxuXHQvKipcblx0ICogRXhwZXJpbWVudGFsOiBlbmFibGUgZmx1aWQgc3RhdGVcblx0ICovXG5cdEBJbnB1dCgpIGZsdWlkID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gaGlkZSB0aGUgbGFiZWwgdmlzdWFsbHksIGJ1dCBrZWVwIGFjY2Vzc2libGUgdG9cblx0ICogc2NyZWVuIHJlYWRlcnMuXG5cdCAqL1xuXHRASW5wdXQoKSBoaWRlTGFiZWwgPSBmYWxzZTtcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byByZW5kZXIgdGhlIGxhYmVsIGFuZCBmaWVsZCBzaWRlLWJ5LXNpZGUgaW5zdGVhZCBvZiBzdGFja2VkLlxuXHQgKi9cblx0QElucHV0KCkgaW5saW5lID0gZmFsc2U7XG5cblx0LyoqXG5cdCAqIEVtaXRzIHdoZW5ldmVyIHRoZSBzaG93L2hpZGUgcGFzc3dvcmQgdmlzaWJpbGl0eSB0b2dnbGUgYnV0dG9uIGlzIGNsaWNrZWQuXG5cdCAqIE1pcnJvcnMgdGhlIGBvblRvZ2dsZVBhc3N3b3JkVmlzaWJpbGl0eWAgcHJvcCBvZiB0aGUgUmVhY3QgYFBhc3N3b3JkSW5wdXRgXG5cdCAqIGNvbXBvbmVudC5cblx0ICovXG5cdEBPdXRwdXQoKSB0b2dnbGVQYXNzd29yZFZpc2liaWxpdHkgPSBuZXcgRXZlbnRFbWl0dGVyPFwicGFzc3dvcmRcIiB8IFwidGV4dFwiPigpO1xuXG5cdC8qKlxuXHQgKiBSZWZlcmVuY2UgdG8gdGhlIHdyYXBwZXIgZWxlbWVudC5cblx0ICovXG5cdEBWaWV3Q2hpbGQoXCJ3cmFwcGVyXCIsIHsgc3RhdGljOiB0cnVlIH0pIHdyYXBwZXI6IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG5cdC8qKlxuXHQgKiBCaW5kaW5nIGZvciBhcHBseWluZyBjbGFzcyB0byBob3N0IGVsZW1lbnQuXG5cdCAqL1xuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLWZvcm0taXRlbVwiKSBsYWJlbENsYXNzID0gdHJ1ZTtcblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS1wYXNzd29yZC1pbnB1dC13cmFwcGVyXCIpIHBhc3N3b3JkSW5wdXRXcmFwcGVyID0gdHJ1ZTtcblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS10ZXh0LWlucHV0LXdyYXBwZXJcIikgdGV4dElucHV0V3JhcHBlciA9IHRydWU7XG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tdGV4dC1pbnB1dC13cmFwcGVyLS1yZWFkb25seVwiKSBnZXQgaXNSZWFkb25seSgpIHtcblx0XHRyZXR1cm4gdGhpcy53cmFwcGVyPy5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dFwiKT8ucmVhZE9ubHkgPz8gZmFsc2U7XG5cdH1cblxuXHRASG9zdEJpbmRpbmcoXCJjbGFzcy5jZHMtLXRleHQtaW5wdXQtd3JhcHBlci0taW5saW5lXCIpIGdldCBpc0lubGluZVdyYXBwZXIoKSB7XG5cdFx0cmV0dXJuIHRoaXMuaW5saW5lO1xuXHR9XG5cblx0QEhvc3RCaW5kaW5nKFwiY2xhc3MuY2RzLS10ZXh0LWlucHV0LS1mbHVpZFwiKSBnZXQgZmx1aWRDbGFzcygpIHtcblx0XHRyZXR1cm4gdGhpcy5mbHVpZCAmJiAhdGhpcy5za2VsZXRvbjtcblx0fVxuXG5cdEBIb3N0QmluZGluZyhcImNsYXNzLmNkcy0tdGV4dC1pbnB1dC0tZmx1aWRfX3NrZWxldG9uXCIpIGdldCBmbHVpZFNrZWxldG9uQ2xhc3MoKSB7XG5cdFx0cmV0dXJuIHRoaXMuZmx1aWQgJiYgdGhpcy5za2VsZXRvbjtcblx0fVxuXG5cdC8qKlxuXHQgKiBDb25zdHJ1Y3RvciBmb3IgUGFzc3dvcmRJbnB1dExhYmVsQ29tcG9uZW50LlxuXHQgKiBAcGFyYW0gY2hhbmdlRGV0ZWN0b3JSZWYgLSBSZWZlcmVuY2UgdG8gQ2hhbmdlRGV0ZWN0b3JSZWYuXG5cdCAqL1xuXHRjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG5cdFx0c3VwZXIoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBMaWZlY3ljbGUgaG9vayBjYWxsZWQgYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgdG8gc2V0IHRoZSBJRCBvZiB0aGUgaW5wdXQgZWxlbWVudFxuXHQgKi9cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGlmICh0aGlzLndyYXBwZXIpIHtcblx0XHRcdGNvbnN0IGlucHV0RWxlbWVudCA9XG5cdFx0XHRcdHRoaXMud3JhcHBlci5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoXCJpbnB1dFwiKTtcblx0XHRcdGlmIChpbnB1dEVsZW1lbnQpIHtcblx0XHRcdFx0aWYgKGlucHV0RWxlbWVudC5pZCkge1xuXHRcdFx0XHRcdHRoaXMubGFiZWxJbnB1dElEID0gaW5wdXRFbGVtZW50LmlkO1xuXHRcdFx0XHRcdHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlucHV0RWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCB0aGlzLmxhYmVsSW5wdXRJRCk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogRnVuY3Rpb24gdG8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBhIFRlbXBsYXRlUmVmLlxuXHQgKiBAcGFyYW0gdmFsdWUgLSBWYWx1ZSB0byBjaGVjay5cblx0ICogQHJldHVybnMgV2hldGhlciB0aGUgdmFsdWUgaXMgYSBUZW1wbGF0ZVJlZi5cblx0ICovXG5cdHB1YmxpYyBpc1RlbXBsYXRlKHZhbHVlKSB7XG5cdFx0cmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlciBmb3IgdG9nZ2xpbmcgcGFzc3dvcmQgdmlzaWJpbGl0eS5cblx0ICovXG5cdHB1YmxpYyBoYW5kbGVUb2dnbGVQYXNzd29yZFZpc2liaWxpdHkoKSB7XG5cdFx0dGhpcy5pbnB1dFR5cGUgPSB0aGlzLmlucHV0VHlwZSA9PT0gXCJwYXNzd29yZFwiID8gXCJ0ZXh0XCIgOiBcInBhc3N3b3JkXCI7XG5cdFx0dGhpcy50ZXh0SW5wdXQudHlwZSA9IHRoaXMuaW5wdXRUeXBlO1xuXHRcdHRoaXMucGFzc3dvcmRJc1Zpc2libGUgPSB0aGlzLmlucHV0VHlwZSA9PT0gXCJ0ZXh0XCI7XG5cdFx0dGhpcy50b2dnbGVQYXNzd29yZFZpc2liaWxpdHkuZW1pdCh0aGlzLmlucHV0VHlwZSk7XG5cdH1cbn1cbiJdfQ==