UNPKG

carbon-components-angular

Version:
501 lines (499 loc) 38.3 kB
import { Component, Input, Output, HostListener, EventEmitter, TemplateRef, ViewChild } from "@angular/core"; import { NG_VALUE_ACCESSOR } from "@angular/forms"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "carbon-components-angular/icon"; /** * `cds-select` provides a styled `select` component. Get started with importing the module: * * ```typescript * import { SelectModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-select [(ngModel)]="model"> * <option value="default" disabled selected hidden>Choose an option</option> * <option value="option1">Option 1</option> * <option value="option2">Option 2</option> * <option value="option3">Option 3</option> * </cds-select> * ``` * * [See demo](../../?path=/story/components-select--basic) */ export class Select { constructor() { /** * `inline` or `default` select displays */ this.display = "default"; /** * Set to `true` to show a warning (contents set by warningText) */ this.warn = false; /** * Sets the unique ID. Defaults to `select-${total count of selects instantiated}` */ this.id = `select-${Select.selectCount++}`; /** * Number input field render size */ this.size = "md"; /** * Set to true to disable component. */ this.disabled = false; /** * Set to true for a loading select. */ this.skeleton = false; /** * Set to `true` for an invalid select component. */ this.invalid = false; /** * Set to `true` for readonly state. */ this.readonly = false; /** * @deprecated since v5 - Use `cdsLayer` directive instead * `light` or `dark` select theme */ this.theme = "dark"; /** * Specify whether the visible label should be hidden but still available * to assistive technology. */ this.hideLabel = false; /** * Experimental: enable fluid state */ this.fluid = false; this.valueChange = new EventEmitter(); this.focused = false; /** * placeholder declarations. Replaced by the functions provided to `registerOnChange` and `registerOnTouched` */ this.onChangeHandler = (_) => { }; this.onTouchedHandler = () => { }; } set value(v) { this._value = v; if (this.select) { this.select.nativeElement.value = this._value; } } get value() { return this._value; } ngAfterViewInit() { if (this.value !== undefined && this.value !== null && this.select && this.select.nativeElement.value !== this.value) { this.select.nativeElement.value = this.value; } } /** * Receives a value from the model. */ writeValue(obj) { this.value = obj; } /** * Registers a listener that notifies the model when the control updates */ registerOnChange(fn) { this.onChangeHandler = fn; } /** * Registers a listener that notifies the model when the control is blurred */ registerOnTouched(fn) { this.onTouchedHandler = fn; } /** * Sets the disabled state through the model */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * Handles the change event from the `select`. * Sends events to the change handler and emits a `selected` event. */ onChange(event) { this.value = event.target.value; this.onChangeHandler(event.target.value); this.valueChange.emit(event.target.value); } /** * Listens for the host blurring, and notifies the model */ focusOut() { this.onTouchedHandler(); } isTemplate(value) { return value instanceof TemplateRef; } onMouseDown(event) { /** * This prevents the select from opening with mouse */ if (this.readonly) { event.preventDefault(); event.target.focus(); } } onKeyDown(event) { const selectAccessKeys = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight", " "]; /** * This prevents the select from opening for the above keys */ if (this.readonly && selectAccessKeys.includes(event.key)) { event.preventDefault(); } } handleFocus(event) { this.focused = event.type === "focus"; } } /** * Tracks the total number of selects instantiated. Used to generate unique IDs */ Select.selectCount = 0; Select.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component }); Select.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Select, selector: "cds-select, ibm-select", inputs: { value: "value", display: "display", label: "label", helperText: "helperText", invalidText: "invalidText", warn: "warn", warnText: "warnText", id: "id", size: "size", disabled: "disabled", skeleton: "skeleton", invalid: "invalid", readonly: "readonly", theme: "theme", ariaLabel: "ariaLabel", hideLabel: "hideLabel", fluid: "fluid", decorator: "decorator" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "focusout": "focusOut()" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true } ], viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true }], ngImport: i0, template: ` <div [ngClass]="{ 'cds--form-item': !skeleton, 'cds--select--fluid': fluid && !skeleton }"> <ng-container *ngIf="skeleton && !fluid"> <div *ngIf="label" class="cds--label cds--skeleton"></div> <div class="cds--select cds--skeleton"></div> </ng-container> <ng-container *ngIf="skeleton && fluid"> <div class="cds--list-box__wrapper--fluid"> <div class="cds--list-box cds--skeleton"> <div class="cds--list-box__label"></div> <div class="cds--list-box__field"></div> </div> </div> </ng-container> <div *ngIf="!skeleton" class="cds--select" [ngClass]="{ 'cds--select--inline': display === 'inline', 'cds--select--light': theme === 'light', 'cds--select--invalid': invalid, 'cds--select--warning': warn, 'cds--select--disabled': disabled, 'cds--select--readonly': readonly, 'cds--select--fluid--invalid': fluid && invalid, 'cds--select--fluid--focus': fluid && focused, 'cds--select--decorator': !!decorator }"> <label *ngIf="label" [for]="id" class="cds--label" [ngClass]="{ 'cds--label--disabled': disabled, 'cds--visually-hidden': hideLabel }"> <ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container> <ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template> </label> <div *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper"> <ng-container *ngTemplateOutlet="noInline"></ng-container> </div> <div *ngIf="helperText && !invalid && !warn && !skeleton && !fluid" 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> </div> <!-- select element: dynamically projected based on 'display' variant --> <ng-template #noInline> <div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)"> <select #select [attr.id]="id" [attr.aria-label]="ariaLabel" [disabled]="disabled" (change)="onChange($event)" [attr.aria-invalid]="invalid ? 'true' : null" [attr.aria-readonly]="readonly ? 'true' : null" class="cds--select-input" [ngClass]="{ 'cds--select-input--sm': size === 'sm', 'cds--select-input--md': size === 'md', 'cds--select-input--lg': size === 'lg' }" (mousedown)="onMouseDown($event)" (keydown)="onKeyDown($event)" (focus)="fluid ? handleFocus($event) : null" (blur)="fluid ? handleFocus($event) : null"> <ng-content></ng-content> </select> <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" class="cds--select__arrow" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path> </svg> <svg *ngIf="invalid" cdsIcon="warning--filled" size="16" class="cds--select__invalid-icon"> </svg> <svg *ngIf="!invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--select__invalid-icon cds--select__invalid-icon--warning"> </svg> <ng-container *ngIf="decorator"> <div class="cds--select__inner-wrapper--decorator"> <ng-template [ngTemplateOutlet]="decorator"></ng-template> </div> </ng-container> <ng-container *ngIf="fluid"> <hr class="cds--select__divider" /> <div *ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite"> <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="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite"> <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> </ng-template> `, 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"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, decorators: [{ type: Component, args: [{ selector: "cds-select, ibm-select", template: ` <div [ngClass]="{ 'cds--form-item': !skeleton, 'cds--select--fluid': fluid && !skeleton }"> <ng-container *ngIf="skeleton && !fluid"> <div *ngIf="label" class="cds--label cds--skeleton"></div> <div class="cds--select cds--skeleton"></div> </ng-container> <ng-container *ngIf="skeleton && fluid"> <div class="cds--list-box__wrapper--fluid"> <div class="cds--list-box cds--skeleton"> <div class="cds--list-box__label"></div> <div class="cds--list-box__field"></div> </div> </div> </ng-container> <div *ngIf="!skeleton" class="cds--select" [ngClass]="{ 'cds--select--inline': display === 'inline', 'cds--select--light': theme === 'light', 'cds--select--invalid': invalid, 'cds--select--warning': warn, 'cds--select--disabled': disabled, 'cds--select--readonly': readonly, 'cds--select--fluid--invalid': fluid && invalid, 'cds--select--fluid--focus': fluid && focused, 'cds--select--decorator': !!decorator }"> <label *ngIf="label" [for]="id" class="cds--label" [ngClass]="{ 'cds--label--disabled': disabled, 'cds--visually-hidden': hideLabel }"> <ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container> <ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template> </label> <div *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper"> <ng-container *ngTemplateOutlet="noInline"></ng-container> </div> <div *ngIf="helperText && !invalid && !warn && !skeleton && !fluid" 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> </div> <!-- select element: dynamically projected based on 'display' variant --> <ng-template #noInline> <div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)"> <select #select [attr.id]="id" [attr.aria-label]="ariaLabel" [disabled]="disabled" (change)="onChange($event)" [attr.aria-invalid]="invalid ? 'true' : null" [attr.aria-readonly]="readonly ? 'true' : null" class="cds--select-input" [ngClass]="{ 'cds--select-input--sm': size === 'sm', 'cds--select-input--md': size === 'md', 'cds--select-input--lg': size === 'lg' }" (mousedown)="onMouseDown($event)" (keydown)="onKeyDown($event)" (focus)="fluid ? handleFocus($event) : null" (blur)="fluid ? handleFocus($event) : null"> <ng-content></ng-content> </select> <svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" class="cds--select__arrow" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"> <path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path> </svg> <svg *ngIf="invalid" cdsIcon="warning--filled" size="16" class="cds--select__invalid-icon"> </svg> <svg *ngIf="!invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--select__invalid-icon cds--select__invalid-icon--warning"> </svg> <ng-container *ngIf="decorator"> <div class="cds--select__inner-wrapper--decorator"> <ng-template [ngTemplateOutlet]="decorator"></ng-template> </div> </ng-container> <ng-container *ngIf="fluid"> <hr class="cds--select__divider" /> <div *ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite"> <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="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite"> <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> </ng-template> `, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Select, multi: true } ] }] }], propDecorators: { value: [{ type: Input }], display: [{ type: Input }], label: [{ type: Input }], helperText: [{ type: Input }], invalidText: [{ type: Input }], warn: [{ type: Input }], warnText: [{ type: Input }], id: [{ type: Input }], size: [{ type: Input }], disabled: [{ type: Input }], skeleton: [{ type: Input }], invalid: [{ type: Input }], readonly: [{ type: Input }], theme: [{ type: Input }], ariaLabel: [{ type: Input }], hideLabel: [{ type: Input }], fluid: [{ type: Input }], decorator: [{ type: Input }], valueChange: [{ type: Output }], select: [{ type: ViewChild, args: ["select"] }], focusOut: [{ type: HostListener, args: ["focusout"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZWxlY3Qvc2VsZWN0LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRU4sU0FBUyxFQUVULEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNaLFlBQVksRUFDWixXQUFXLEVBQ1gsU0FBUyxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUV6RTs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFtSkgsTUFBTSxPQUFPLE1BQU07SUFsSm5CO1FBbUtDOztXQUVHO1FBQ00sWUFBTyxHQUF5QixTQUFTLENBQUM7UUFhbkQ7O1lBRUk7UUFDSyxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBS3RCOztXQUVHO1FBQ00sT0FBRSxHQUFHLFVBQVUsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7UUFDL0M7O1dBRUc7UUFDTSxTQUFJLEdBQXVCLElBQUksQ0FBQztRQUN6Qzs7V0FFRztRQUNNLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDMUI7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sWUFBTyxHQUFHLEtBQUssQ0FBQztRQUN6Qjs7V0FFRztRQUNNLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFMUI7OztXQUdHO1FBQ00sVUFBSyxHQUFxQixNQUFNLENBQUM7UUFHMUM7OztXQUdHO1FBQ00sY0FBUyxHQUFHLEtBQUssQ0FBQztRQUUzQjs7V0FFRztRQUNNLFVBQUssR0FBRyxLQUFLLENBQUM7UUFPYixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFJM0MsWUFBTyxHQUFHLEtBQUssQ0FBQztRQXlGaEI7O1dBRUc7UUFDTyxvQkFBZSxHQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUUsR0FBRyxDQUFDLENB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LFdBQVc7c0JBQXBCLE1BQU07Z0JBRWMsTUFBTTtzQkFBMUIsU0FBUzt1QkFBQyxRQUFRO2dCQTJEbkIsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuXHRBZnRlclZpZXdJbml0LFxuXHRDb21wb25lbnQsXG5cdEVsZW1lbnRSZWYsXG5cdElucHV0LFxuXHRPdXRwdXQsXG5cdEhvc3RMaXN0ZW5lcixcblx0RXZlbnRFbWl0dGVyLFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NoaWxkXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tIFwiQGFuZ3VsYXIvZm9ybXNcIjtcblxuLyoqXG4gKiBgY2RzLXNlbGVjdGAgcHJvdmlkZXMgYSBzdHlsZWQgYHNlbGVjdGAgY29tcG9uZW50LiBHZXQgc3RhcnRlZCB3aXRoIGltcG9ydGluZyB0aGUgbW9kdWxlOlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7IFNlbGVjdE1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogYGBgaHRtbFxuICogPGNkcy1zZWxlY3QgWyhuZ01vZGVsKV09XCJtb2RlbFwiPlxuICogXHQ8b3B0aW9uIHZhbHVlPVwiZGVmYXVsdFwiIGRpc2FibGVkIHNlbGVjdGVkIGhpZGRlbj5DaG9vc2UgYW4gb3B0aW9uPC9vcHRpb24+XG4gKiBcdDxvcHRpb24gdmFsdWU9XCJvcHRpb24xXCI+T3B0aW9uIDE8L29wdGlvbj5cbiAqXHQ8b3B0aW9uIHZhbHVlPVwib3B0aW9uMlwiPk9wdGlvbiAyPC9vcHRpb24+XG4gKiBcdDxvcHRpb24gdmFsdWU9XCJvcHRpb24zXCI+T3B0aW9uIDM8L29wdGlvbj5cbiAqIDwvY2RzLXNlbGVjdD5cbiAqXHRgYGBcbiAqXG4gKiBbU2VlIGRlbW9dKC4uLy4uLz9wYXRoPS9zdG9yeS9jb21wb25lbnRzLXNlbGVjdC0tYmFzaWMpXG4gKi9cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogXCJjZHMtc2VsZWN0LCBpYm0tc2VsZWN0XCIsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGRpdlxuXHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHQnY2RzLS1mb3JtLWl0ZW0nOiAhc2tlbGV0b24sXG5cdFx0XHRcdCdjZHMtLXNlbGVjdC0tZmx1aWQnOiBmbHVpZCAmJiAhc2tlbGV0b25cblx0XHRcdH1cIj5cblx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJza2VsZXRvbiAmJiAhZmx1aWRcIj5cblx0XHRcdFx0PGRpdiAqbmdJZj1cImxhYmVsXCIgY2xhc3M9XCJjZHMtLWxhYmVsIGNkcy0tc2tlbGV0b25cIj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImNkcy0tc2VsZWN0IGNkcy0tc2tlbGV0b25cIj48L2Rpdj5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cInNrZWxldG9uICYmIGZsdWlkXCI+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLWxpc3QtYm94X193cmFwcGVyLS1mbHVpZFwiPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLWxpc3QtYm94IGNkcy0tc2tlbGV0b25cIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLWxpc3QtYm94X19sYWJlbFwiPjwvZGl2PlxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzcz1cImNkcy0tbGlzdC1ib3hfX2ZpZWxkXCI+PC9kaXY+XG5cdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8ZGl2XG5cdFx0XHRcdCpuZ0lmPVwiIXNrZWxldG9uXCJcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdFwiXG5cdFx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWlubGluZSc6IGRpc3BsYXkgPT09ICdpbmxpbmUnLFxuXHRcdFx0XHRcdCdjZHMtLXNlbGVjdC0tbGlnaHQnOiB0aGVtZSA9PT0gJ2xpZ2h0Jyxcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWludmFsaWQnOiBpbnZhbGlkLFxuXHRcdFx0XHRcdCdjZHMtLXNlbGVjdC0td2FybmluZyc6IHdhcm4sXG5cdFx0XHRcdFx0J2Nkcy0tc2VsZWN0LS1kaXNhYmxlZCc6IGRpc2FibGVkLFxuXHRcdFx0XHRcdCdjZHMtLXNlbGVjdC0tcmVhZG9ubHknOiByZWFkb25seSxcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWZsdWlkLS1pbnZhbGlkJzogZmx1aWQgJiYgaW52YWxpZCxcblx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtLWZsdWlkLS1mb2N1cyc6IGZsdWlkICYmIGZvY3VzZWQsXG5cdFx0XHRcdFx0J2Nkcy0tc2VsZWN0LS1kZWNvcmF0b3InOiAhIWRlY29yYXRvclxuXHRcdFx0XHR9XCI+XG5cdFx0XHRcdDxsYWJlbFxuXHRcdFx0XHRcdCpuZ0lmPVwibGFiZWxcIlxuXHRcdFx0XHRcdFtmb3JdPVwiaWRcIlxuXHRcdFx0XHRcdGNsYXNzPVwiY2RzLS1sYWJlbFwiXG5cdFx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdFx0J2Nkcy0tbGFiZWwtLWRpc2FibGVkJzogZGlzYWJsZWQsXG5cdFx0XHRcdFx0XHQnY2RzLS12aXN1YWxseS1oaWRkZW4nOiBoaWRlTGFiZWxcblx0XHRcdFx0XHR9XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKGxhYmVsKVwiPnt7bGFiZWx9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUobGFiZWwpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwibGFiZWxcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2xhYmVsPlxuXHRcdFx0XHQ8ZGl2ICpuZ0lmPVwiZGlzcGxheSA9PT0gJ2lubGluZSc7IGVsc2Ugbm9JbmxpbmVcIiBjbGFzcz1cImNkcy0tc2VsZWN0LWlucHV0LS1pbmxpbmVfX3dyYXBwZXJcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibm9JbmxpbmVcIj48L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXZcblx0XHRcdFx0XHQqbmdJZj1cImhlbHBlclRleHQgJiYgIWludmFsaWQgJiYgIXdhcm4gJiYgIXNrZWxldG9uICYmICFmbHVpZFwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLWZvcm1fX2hlbHBlci10ZXh0XCJcblx0XHRcdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdFx0XHQnY2RzLS1mb3JtX19oZWxwZXItdGV4dC0tZGlzYWJsZWQnOiBkaXNhYmxlZFxuXHRcdFx0XHRcdH1cIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaGVscGVyVGV4dClcIj57e2hlbHBlclRleHR9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaGVscGVyVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJoZWxwZXJUZXh0XCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Rpdj5cblx0XHQ8L2Rpdj5cblxuXHRcdDwhLS0gc2VsZWN0IGVsZW1lbnQ6IGR5bmFtaWNhbGx5IHByb2plY3RlZCBiYXNlZCBvbiAnZGlzcGxheScgdmFyaWFudCAtLT5cblx0XHQ8bmctdGVtcGxhdGUgI25vSW5saW5lPlxuXHRcdFx0PGRpdiBjbGFzcz1cImNkcy0tc2VsZWN0LWlucHV0X193cmFwcGVyXCIgW2F0dHIuZGF0YS1pbnZhbGlkXT1cIihpbnZhbGlkID8gdHJ1ZSA6IG51bGwpXCI+XG5cdFx0XHRcdDxzZWxlY3Rcblx0XHRcdFx0XHQjc2VsZWN0XG5cdFx0XHRcdFx0W2F0dHIuaWRdPVwiaWRcIlxuXHRcdFx0XHRcdFthdHRyLmFyaWEtbGFiZWxdPVwiYXJpYUxhYmVsXCJcblx0XHRcdFx0XHRbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuXHRcdFx0XHRcdChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50KVwiXG5cdFx0XHRcdFx0W2F0dHIuYXJpYS1pbnZhbGlkXT1cImludmFsaWQgPyAndHJ1ZScgOiBudWxsXCJcblx0XHRcdFx0XHRbYXR0ci5hcmlhLXJlYWRvbmx5XT1cInJlYWRvbmx5ID8gJ3RydWUnIDogbnVsbFwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdC1pbnB1dFwiXG5cdFx0XHRcdFx0W25nQ2xhc3NdPVwie1xuXHRcdFx0XHRcdFx0J2Nkcy0tc2VsZWN0LWlucHV0LS1zbSc6IHNpemUgPT09ICdzbScsXG5cdFx0XHRcdFx0XHQnY2RzLS1zZWxlY3QtaW5wdXQtLW1kJzogc2l6ZSA9PT0gJ21kJyxcblx0XHRcdFx0XHRcdCdjZHMtLXNlbGVjdC1pbnB1dC0tbGcnOiBzaXplID09PSAnbGcnXG5cdFx0XHRcdFx0fVwiXG5cdFx0XHRcdFx0KG1vdXNlZG93bik9XCJvbk1vdXNlRG93bigkZXZlbnQpXCJcblx0XHRcdFx0XHQoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG5cdFx0XHRcdFx0KGZvY3VzKT1cImZsdWlkID8gaGFuZGxlRm9jdXMoJGV2ZW50KSA6IG51bGxcIlxuXHRcdFx0XHRcdChibHVyKT1cImZsdWlkID8gaGFuZGxlRm9jdXMoJGV2ZW50KSA6IG51bGxcIj5cblx0XHRcdFx0XHQ8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG5cdFx0XHRcdDwvc2VsZWN0PlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Zm9jdXNhYmxlPVwiZmFsc2VcIlxuXHRcdFx0XHRcdHByZXNlcnZlQXNwZWN0UmF0aW89XCJ4TWlkWU1pZCBtZWV0XCJcblx0XHRcdFx0XHRzdHlsZT1cIndpbGwtY2hhbmdlOiB0cmFuc2Zvcm07XCJcblx0XHRcdFx0XHR4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcblx0XHRcdFx0XHRjbGFzcz1cImNkcy0tc2VsZWN0X19hcnJvd1wiXG5cdFx0XHRcdFx0d2lkdGg9XCIxNlwiXG5cdFx0XHRcdFx0aGVpZ2h0PVwiMTZcIlxuXHRcdFx0XHRcdHZpZXdCb3g9XCIwIDAgMTYgMTZcIlxuXHRcdFx0XHRcdGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuXHRcdFx0XHRcdDxwYXRoIGQ9XCJNOCAxMUwzIDYgMy43IDUuMyA4IDkuNiAxMi4zIDUuMyAxMyA2elwiPjwvcGF0aD5cblx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdDxzdmdcblx0XHRcdFx0XHQqbmdJZj1cImludmFsaWRcIlxuXHRcdFx0XHRcdGNkc0ljb249XCJ3YXJuaW5nLS1maWxsZWRcIlxuXHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdF9faW52YWxpZC1pY29uXCI+XG5cdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0Km5nSWY9XCIhaW52YWxpZCAmJiB3YXJuXCJcblx0XHRcdFx0XHRjZHNJY29uPVwid2FybmluZy0tYWx0LS1maWxsZWRcIlxuXHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0Y2xhc3M9XCJjZHMtLXNlbGVjdF9faW52YWxpZC1pY29uIGNkcy0tc2VsZWN0X19pbnZhbGlkLWljb24tLXdhcm5pbmdcIj5cblx0XHRcdFx0PC9zdmc+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCJkZWNvcmF0b3JcIj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1zZWxlY3RfX2lubmVyLXdyYXBwZXItLWRlY29yYXRvclwiPlxuXHRcdFx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRlY29yYXRvclwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiZmx1aWRcIj5cblx0XHRcdFx0XHQ8aHIgY2xhc3M9XCJjZHMtLXNlbGVjdF9fZGl2aWRlclwiIC8+XG5cdFx0XHRcdFx0PGRpdlxuXHRcdFx0XHRcdFx0Km5nSWY9XCJpbnZhbGlkICYmIGludmFsaWRUZXh0XCIgcm9sZT1cImFsZXJ0XCIgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj5cblx0XHRcdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZShpbnZhbGlkVGV4dClcIj57e2ludmFsaWRUZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiaW52YWxpZFRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxkaXYgKm5nSWY9XCIhaW52YWxpZCAmJiB3YXJuXCIgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIj5cblx0XHRcdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZSh3YXJuVGV4dClcIj57e3dhcm5UZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUod2FyblRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwid2FyblRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdDwvZGl2PlxuXHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFmbHVpZFwiPlxuXHRcdFx0XHQ8ZGl2XG5cdFx0XHRcdFx0Km5nSWY9XCJpbnZhbGlkICYmIGludmFsaWRUZXh0XCIgcm9sZT1cImFsZXJ0XCIgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIj5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCI+e3tpbnZhbGlkVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0PG5nLXRlbXBsYXRlICpuZ0lmPVwiaXNUZW1wbGF0ZShpbnZhbGlkVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCJpbnZhbGlkVGV4dFwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8ZGl2ICpuZ0lmPVwiIWludmFsaWQgJiYgd2FyblwiIGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFpc1RlbXBsYXRlKHdhcm5UZXh0KVwiPnt7d2FyblRleHR9fTwvbmctY29udGFpbmVyPlxuXHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUod2FyblRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwid2FyblRleHRcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbmctY29udGFpbmVyPlxuXHRcdDwvbmctdGVtcGxhdGU+XG5cdGAsXG5cdHByb3ZpZGVyczogW1xuXHRcdHtcblx0XHRcdHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuXHRcdFx0dXNlRXhpc3Rpbmc6IFNlbGVjdCxcblx0XHRcdG11bHRpOiB0cnVlXG5cdFx0fVxuXHRdXG59KVxuZXhwb3J0IGNsYXNzIFNlbGVjdCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBZnRlclZpZXdJbml0IHtcblx0QElucHV0KCkgc2V0IHZhbHVlKHYpIHtcblx0XHR0aGlzLl92YWx1ZSA9IHY7XG5cdFx0aWYgKHRoaXMuc2VsZWN0KSB7XG5cdFx0XHR0aGlzLnNlbGVjdC5uYXRpdmVFbGVtZW50LnZhbHVlID0gdGhpcy5fdmFsdWU7XG5cdFx0fVxuXHR9XG5cblx0Z2V0IHZhbHVlKCkge1xuXHRcdHJldHVybiB0aGlzLl92YWx1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUcmFja3MgdGhlIHRvdGFsIG51bWJlciBvZiBzZWxlY3RzIGluc3RhbnRpYXRlZC4gVXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgSURzXG5cdCAqL1xuXHRzdGF0aWMgc2VsZWN0Q291bnQgPSAwO1xuXG5cdC8qKlxuXHQgKiBgaW5saW5lYCBvciBgZGVmYXVsdGAgc2VsZWN0IGRpc3BsYXlzXG5cdCAqL1xuXHRASW5wdXQoKSBkaXNwbGF5OiBcImlubGluZVwiIHwgXCJkZWZhdWx0XCIgPSBcImRlZmF1bHRcIjtcblx0LyoqXG5cdCAqIExhYmVsIGZvciB0aGUgc2VsZWN0LiBBcHBlYXJzIGFib3ZlIHRoZSBpbnB1dC5cblx0ICovXG5cdEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXHQvKipcblx0ICogT3B0aW9uYWwgaGVscGVyIHRleHQgdGhhdCBhcHBlYXJzIHVuZGVyIHRoZSBsYWJlbC5cblx0ICovXG5cdEBJbnB1dCgpIGhlbHBlclRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBpbnZhbGlkIHRleHQuXG5cdCAqL1xuXHRASW5wdXQoKSBpbnZhbGlkVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAgKiBTZXQgdG8gYHRydWVgIHRvIHNob3cgYSB3YXJuaW5nIChjb250ZW50cyBzZXQgYnkgd2FybmluZ1RleHQpXG5cdCAgKi9cblx0QElucHV0KCkgd2FybiA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0cyB0aGUgd2FybmluZyB0ZXh0XG5cdCAqL1xuXHRASW5wdXQoKSB3YXJuVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55Pjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIHVuaXF1ZSBJRC4gRGVmYXVsdHMgdG8gYHNlbGVjdC0ke3RvdGFsIGNvdW50IG9mIHNlbGVjdHMgaW5zdGFudGlhdGVkfWBcblx0ICovXG5cdEBJbnB1dCgpIGlkID0gYHNlbGVjdC0ke1NlbGVjdC5zZWxlY3RDb3VudCsrfWA7XG5cdC8qKlxuXHQgKiBOdW1iZXIgaW5wdXQgZmllbGQgcmVuZGVyIHNpemVcblx0ICovXG5cdEBJbnB1dCgpIHNpemU6IFwic21cIiB8IFwibWRcIiB8IFwibGdcIiA9IFwibWRcIjtcblx0LyoqXG5cdCAqIFNldCB0byB0cnVlIHRvIGRpc2FibGUgY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byB0cnVlIGZvciBhIGxvYWRpbmcgc2VsZWN0LlxuXHQgKi9cblx0QElucHV0KCkgc2tlbGV0b24gPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIGFuIGludmFsaWQgc2VsZWN0IGNvbXBvbmVudC5cblx0ICovXG5cdEBJbnB1dCgpIGludmFsaWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgZm9yIHJlYWRvbmx5IHN0YXRlLlxuXHQgKi9cblx0QElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcblxuXHQvKipcblx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdjUgLSBVc2UgYGNkc0xheWVyYCBkaXJlY3RpdmUgaW5zdGVhZFxuXHQgKiBgbGlnaHRgIG9yIGBkYXJrYCBzZWxlY3QgdGhlbWVcblx0ICovXG5cdEBJbnB1dCgpIHRoZW1lOiBcImxpZ2h0XCIgfCBcImRhcmtcIiA9IFwiZGFya1wiO1xuXHRASW5wdXQoKSBhcmlhTGFiZWw6IHN0cmluZztcblxuXHQvKipcblx0ICogU3BlY2lmeSB3aGV0aGVyIHRoZSB2aXNpYmxlIGxhYmVsIHNob3VsZCBiZSBoaWRkZW4gYnV0IHN0aWxsIGF2YWlsYWJsZVxuXHQgKiB0byBhc3Npc3RpdmUgdGVjaG5vbG9neS5cblx0ICovXG5cdEBJbnB1dCgpIGhpZGVMYWJlbCA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBFeHBlcmltZW50YWw6IGVuYWJsZSBmbHVpZCBzdGF0ZVxuXHQgKi9cblx0QElucHV0KCkgZmx1aWQgPSBmYWxzZTtcblxuXHQvKipcblx0ICogKipFeHBlcmltZW50YWwqKjogT3B0aW9uYWwgZGVjb3JhdG9yIChlLmcuIEFJIGxhYmVsKS5cblx0ICovXG5cdEBJbnB1dCgpIGRlY29yYXRvcjogVGVtcGxhdGVSZWY8YW55PjtcblxuXHRAT3V0cHV0KCkgdmFsdWVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cblx0QFZpZXdDaGlsZChcInNlbGVjdFwiKSBzZWxlY3Q6IEVsZW1lbnRSZWY7XG5cblx0Zm9jdXNlZCA9IGZhbHNlO1xuXG5cdHByb3RlY3RlZCBfdmFsdWU7XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdGlmIChcblx0XHRcdHRoaXMudmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuXHRcdFx0dGhpcy52YWx1ZSAhPT0gbnVsbCAmJlxuXHRcdFx0dGhpcy5zZWxlY3QgJiZcblx0XHRcdHRoaXMuc2VsZWN0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgIT09IHRoaXMudmFsdWVcblx0XHQpIHtcblx0XHRcdHRoaXMuc2VsZWN0Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSB0aGlzLnZhbHVlO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZWNlaXZlcyBhIHZhbHVlIGZyb20gdGhlIG1vZGVsLlxuXHQgKi9cblx0d3JpdGVWYWx1ZShvYmo6IGFueSkge1xuXHRcdHRoaXMudmFsdWUgPSBvYmo7XG5cdH1cblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIGEgbGlzdGVuZXIgdGhhdCBub3RpZmllcyB0aGUgbW9kZWwgd2hlbiB0aGUgY29udHJvbCB1cGRhdGVzXG5cdCAqL1xuXHRyZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpIHtcblx0XHR0aGlzLm9uQ2hhbmdlSGFuZGxlciA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyBhIGxpc3RlbmVyIHRoYXQgbm90aWZpZXMgdGhlIG1vZGVsIHdoZW4gdGhlIGNvbnRyb2wgaXMgYmx1cnJlZFxuXHQgKi9cblx0cmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuXHRcdHRoaXMub25Ub3VjaGVkSGFuZGxlciA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgdGhlIGRpc2FibGVkIHN0YXRlIHRocm91Z2ggdGhlIG1vZGVsXG5cdCAqL1xuXHRzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmRpc2FibGVkID0gaXNEaXNhYmxlZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIHRoZSBjaGFuZ2UgZXZlbnQgZnJvbSB0aGUgYHNlbGVjdGAuXG5cdCAqIFNlbmRzIGV2ZW50cyB0byB0aGUgY2hhbmdlIGhhbmRsZXIgYW5kIGVtaXRzIGEgYHNlbGVjdGVkYCBldmVudC5cblx0ICovXG5cdG9uQ2hhbmdlKGV2ZW50KSB7XG5cdFx0dGhpcy52YWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcblx0XHR0aGlzLm9uQ2hhbmdlSGFuZGxlcihldmVudC50YXJnZXQudmFsdWUpO1xuXHRcdHRoaXMudmFsdWVDaGFuZ2UuZW1pdChldmVudC50YXJnZXQudmFsdWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIExpc3RlbnMgZm9yIHRoZSBob3N0IGJsdXJyaW5nLCBhbmQgbm90aWZpZXMgdGhlIG1vZGVsXG5cdCAqL1xuXHRASG9zdExpc3RlbmVyKFwiZm9jdXNvdXRcIilcblx0Zm9jdXNPdXQoKSB7XG5cdFx0dGhpcy5vblRvdWNoZWRIYW5kbGVyKCk7XG5cdH1cblxuXHRwdWJsaWMgaXNUZW1wbGF0ZSh2YWx1ZSkge1xuXHRcdHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFRlbXBsYXRlUmVmO1xuXHR9XG5cblx0b25Nb3VzZURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcblx0XHQvKipcblx0XHQgKiBUaGlzIHByZXZlbnRzIHRoZSBzZWxlY3QgZnJvbSBvcGVuaW5nIHdpdGggbW91c2Vcblx0XHQgKi9cblx0XHRpZiAodGhpcy5yZWFkb25seSkge1xuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdCg8SFRNTEVsZW1lbnQ+ZXZlbnQudGFyZ2V0KS5mb2N1cygpO1xuXHRcdH1cblx0fVxuXG5cdG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuXHRcdGNvbnN0IHNlbGVjdEFjY2Vzc0tleXMgPSBbXCJBcnJvd0Rvd25cIiwgXCJBcnJvd1VwXCIsIFwiQXJyb3dMZWZ0XCIsIFwiQXJyb3dSaWdodFwiLCBcIiBcIl07XG5cdFx0LyoqXG5cdFx0ICogVGhpcyBwcmV2ZW50cyB0aGUgc2VsZWN0IGZyb20gb3BlbmluZyBmb3IgdGhlIGFib3ZlIGtleXNcblx0XHQgKi9cblx0XHRpZiAodGhpcy5yZWFkb25seSAmJiBzZWxlY3RBY2Nlc3NLZXlzLmluY2x1ZGVzKGV2ZW50LmtleSkpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG5cblx0aGFuZGxlRm9jdXMoZXZlbnQ6IEZvY3VzRXZlbnQpIHtcblx0XHR0aGlzLmZvY3VzZWQgPSBldmVudC50eXBlID09PSBcImZvY3VzXCI7XG5cdH1cblxuXHQvKipcblx0ICogcGxhY2Vob2xkZXIgZGVjbGFyYXRpb25zLiBSZXBsYWNlZCBieSB0aGUgZnVuY3Rpb25zIHByb3ZpZGVkIHRvIGByZWdpc3Rlck9uQ2hhbmdlYCBhbmQgYHJlZ2lzdGVyT25Ub3VjaGVkYFxuXHQgKi9cblx0cHJvdGVjdGVkIG9uQ2hhbmdlSGFuZGxlciA9IChfOiBhbnkpID0+IHsgfTtcblx0cHJvdGVjdGVkIG9uVG91Y2hlZEhhbmRsZXIgPSAoKSA9PiB7IH07XG5cbn1cbiJdfQ==