UNPKG

carbon-components-angular

Version:
507 lines 46.3 kB
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, Optional, Output, TemplateRef, ViewChild, HostListener } from "@angular/core"; import { NG_VALUE_ACCESSOR } from "@angular/forms"; import { CHECKBOX_GROUP_HOST } from "./checkbox-group-host"; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "carbon-components-angular/icon"; /** * Defines the set of states for a checkbox component. */ export var CheckboxState; (function (CheckboxState) { CheckboxState[CheckboxState["Init"] = 0] = "Init"; CheckboxState[CheckboxState["Indeterminate"] = 1] = "Indeterminate"; CheckboxState[CheckboxState["Checked"] = 2] = "Checked"; CheckboxState[CheckboxState["Unchecked"] = 3] = "Unchecked"; })(CheckboxState || (CheckboxState = {})); /** * Get started with importing the module: * * ```typescript * import { CheckboxModule } from 'carbon-components-angular'; * ``` * * [See demo](../../?path=/story/components-checkbox--basic) */ export class Checkbox { /** * Creates an instance of `Checkbox`. */ constructor(changeDetectorRef, hostGroup) { this.changeDetectorRef = changeDetectorRef; this.hostGroup = hostGroup; /** * Set to `true` for a disabled checkbox. */ this.disabled = false; /** * Set to `true` for a loading checkbox. */ this.skeleton = false; /** * Set to `true` to hide the checkbox labels. */ this.hideLabel = false; /** * The unique id for the checkbox component. */ this.id = `checkbox-${Checkbox.checkboxCount}`; /** * Optional title for the `<label>` element. */ this.title = ""; /** * Emits click event. */ this.click = new EventEmitter(); /** * Emits an event when the value of the checkbox changes. * * Allows double biding with the `checked` Input. */ this.checkedChange = new EventEmitter(); /** * Emits event notifying other classes when a change in state occurs specifically * on an indeterminate checkbox. */ this.indeterminateChange = new EventEmitter(); /** * Set to `true` if the input checkbox is selected (or checked). */ this._checked = false; /** * Set to `true` if the input checkbox is in state indeterminate. */ this._indeterminate = false; /** * Keeps a reference to the checkboxes current state, as defined in `CheckboxState`. */ this.currentCheckboxState = CheckboxState.Init; this.helperId = `checkbox-helper-${Checkbox.helperIdCounter++}`; /** * Called when checkbox is blurred. Needed to properly implement `ControlValueAccessor`. */ this.onTouched = () => { }; /** * Method set in `registerOnChange` to propagate changes back to the form. */ this.propagateChange = (_) => { }; Checkbox.checkboxCount++; } /** * Set the checkbox's indeterminate state to match the parameter and transition the view to reflect the change. * * Allows double binding with the `indeterminateChange` Output. */ set indeterminate(indeterminate) { if (indeterminate === this._indeterminate) { return; } this._indeterminate = indeterminate; if (this._indeterminate) { this.transitionCheckboxState(CheckboxState.Indeterminate); } else { this.transitionCheckboxState(this.checked ? CheckboxState.Checked : CheckboxState.Unchecked); } if (this.inputCheckbox && this.inputCheckbox.nativeElement) { this.inputCheckbox.nativeElement.indeterminate = indeterminate; } this.changeDetectorRef.markForCheck(); this.indeterminateChange.emit(this._indeterminate); } /** * Reflects whether the checkbox state is indeterminate. */ get indeterminate() { return this._indeterminate; } /** * Sets the `checked` state. `true` for checked, `false` for unchecked * * Allows double binding with the `checkedChange` Output. */ set checked(checked) { this.setChecked(checked, false); } /** * Returns value `true` if state is selected for the checkbox. */ get checked() { return this._checked; } get effectiveReadOnly() { const own = this.readOnly; const group = this.hostGroup?.readOnly ?? false; return !!(own !== undefined ? own : group); } get effectiveInvalid() { const own = this.invalid; const group = this.hostGroup?.invalid ?? false; return !!(own !== undefined ? own : group); } get effectiveWarn() { const own = this.warn; const group = this.hostGroup?.warn ?? false; return !!(own !== undefined ? own : group); } /** * Toggle the selected state of the checkbox. */ toggle() { if (this.effectiveReadOnly) { return; } // Flip checked and reset indeterminate this.setChecked(!this.checked, true); } /** * Writes a value from `ngModel` to the component. * * In this case the value is the `checked` property. * * @param value boolean, corresponds to the `checked` property. */ writeValue(value) { // Set checked and reset indeterminate this.setChecked(!!value, true); } /** * Sets a method in order to propagate changes back to the form. */ registerOnChange(fn) { this.propagateChange = fn; } /** * Registers a callback to be triggered when the control has been touched. * @param fn Callback to be triggered when the checkbox is touched. */ registerOnTouched(fn) { this.onTouched = fn; } /** * `ControlValueAccessor` method to programmatically disable the checkbox. * * ex: `this.formGroup.get("myCheckbox").disable();` * * @param isDisabled `true` to disable the checkbox */ setDisabledState(isDisabled) { this.disabled = isDisabled; this.changeDetectorRef.markForCheck(); } /** * Invoked by `CheckboxGroup` when group `readOnly`, `invalid`, `warn` change so `OnPush` * checkboxes still refresh inherited state from `CHECKBOX_GROUP_HOST`. */ markForCheckFromGroup() { this.changeDetectorRef.markForCheck(); } focusOut() { this.onTouched(); } /** * Executes on the event of a change within `Checkbox` to block propagation. */ onChange(event) { event.stopPropagation(); } /** * Handles click events on the `Checkbox` and emits changes to other classes. */ onClick(event) { if (this.effectiveReadOnly) { event.preventDefault(); if (this.click.observers.length) { this.click.emit(); } return; } if (this.click.observers.length) { // Disable default checkbox activation behavior which flips checked and resets indeterminate. // This allows the parent component to control the checked/indeterminate properties. event.preventDefault(); this.click.emit(); return; } if (!this.disabled) { this.toggle(); this.transitionCheckboxState(this._checked ? CheckboxState.Checked : CheckboxState.Unchecked); this.emitChangeEvent(); } } /** * Handles changes between checkbox states. */ transitionCheckboxState(newState) { this.currentCheckboxState = newState; } /** * Creates instance of `CheckboxChange` used to propagate the change event. */ emitChangeEvent() { this.checkedChange.emit(this.checked); this.propagateChange(this.checked); } /** * Updates the checkbox if it is in the indeterminate state. */ ngAfterViewInit() { if (this.indeterminate && this.inputCheckbox && this.inputCheckbox.nativeElement) { this.inputCheckbox.nativeElement.indeterminate = true; } } /** * Returns `true` when the provided value is a `TemplateRef`. */ isTemplate(value) { return value instanceof TemplateRef; } /** * Sets checked state and optionally resets indeterminate state. */ setChecked(checked, resetIndeterminate) { if (checked === this._checked) { return; } this._checked = checked; // Reset indeterminate if requested if (resetIndeterminate && this._indeterminate) { this._indeterminate = false; Promise.resolve().then(() => { this.indeterminateChange.emit(this._indeterminate); }); } this.changeDetectorRef.markForCheck(); } } /** * Variable used for creating unique ids for checkbox components. */ Checkbox.checkboxCount = 0; Checkbox.helperIdCounter = 0; Checkbox.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Checkbox, deps: [{ token: i0.ChangeDetectorRef }, { token: CHECKBOX_GROUP_HOST, optional: true }], target: i0.ɵɵFactoryTarget.Component }); Checkbox.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Checkbox, selector: "cds-checkbox, ibm-checkbox", inputs: { disabled: "disabled", skeleton: "skeleton", hideLabel: "hideLabel", name: "name", id: "id", required: "required", value: "value", ariaLabel: "ariaLabel", ariaLabelledby: "ariaLabelledby", title: "title", helperText: "helperText", invalid: "invalid", invalidText: "invalidText", warn: "warn", warnText: "warnText", readOnly: "readOnly", decorator: "decorator", indeterminate: "indeterminate", checked: "checked" }, outputs: { click: "click", checkedChange: "checkedChange", indeterminateChange: "indeterminateChange" }, host: { listeners: { "focusout": "focusOut()" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Checkbox, multi: true } ], viewQueries: [{ propertyName: "inputCheckbox", first: true, predicate: ["inputCheckbox"], descendants: true }], ngImport: i0, template: ` <div class="cds--form-item cds--checkbox-wrapper" [ngClass]="{ 'cds--checkbox-wrapper--invalid': !effectiveReadOnly && effectiveInvalid, 'cds--checkbox-wrapper--warning': !effectiveReadOnly && !effectiveInvalid && effectiveWarn, 'cds--checkbox-wrapper--readonly': effectiveReadOnly, 'cds--checkbox-wrapper--decorator': !!decorator }"> <input #inputCheckbox class="cds--checkbox" type="checkbox" [id]="id + '_input'" [value]="value" [name]="name" [required]="required" [checked]="checked" [disabled]="disabled" [attr.data-invalid]="(!effectiveReadOnly && effectiveInvalid) ? true : null" [attr.aria-readonly]="effectiveReadOnly ? true : null" [attr.aria-labelledby]="ariaLabelledby" [attr.aria-describedby]="(helperText && !effectiveInvalid && !effectiveWarn) ? helperId : null" (change)="onChange($event)" (click)="onClick($event)"> <label [for]="id + '_input'" [attr.aria-label]="ariaLabel" [attr.title]="title || null" class="cds--checkbox-label" [ngClass]="{ 'cds--skeleton' : skeleton }"> <span [ngClass]="{'cds--visually-hidden' : hideLabel}" class="cds--checkbox-label-text"> <ng-content></ng-content> <ng-container *ngIf="decorator"> <div class="cds--checkbox-wrapper-inner--decorator"> <ng-template [ngTemplateOutlet]="decorator"></ng-template> </div> </ng-container> </span> </label> <div class="cds--checkbox__validation-msg"> <ng-container *ngIf="!effectiveReadOnly && effectiveInvalid"> <svg cdsIcon="warning--filled" size="16" class="cds--checkbox__invalid-icon"> </svg> <div class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="$any(invalidText)"></ng-template> </div> </ng-container> <ng-container *ngIf="!effectiveReadOnly && !effectiveInvalid && effectiveWarn"> <svg cdsIcon="warning--alt--filled" size="16" class="cds--checkbox__invalid-icon cds--checkbox__invalid-icon--warning"> </svg> <div class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="$any(warnText)"></ng-template> </div> </ng-container> </div> <div *ngIf="helperText && !effectiveInvalid && !effectiveWarn" class="cds--form__helper-text" [id]="helperId"> <ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="$any(helperText)"></ng-template> </div> </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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Checkbox, decorators: [{ type: Component, args: [{ selector: "cds-checkbox, ibm-checkbox", template: ` <div class="cds--form-item cds--checkbox-wrapper" [ngClass]="{ 'cds--checkbox-wrapper--invalid': !effectiveReadOnly && effectiveInvalid, 'cds--checkbox-wrapper--warning': !effectiveReadOnly && !effectiveInvalid && effectiveWarn, 'cds--checkbox-wrapper--readonly': effectiveReadOnly, 'cds--checkbox-wrapper--decorator': !!decorator }"> <input #inputCheckbox class="cds--checkbox" type="checkbox" [id]="id + '_input'" [value]="value" [name]="name" [required]="required" [checked]="checked" [disabled]="disabled" [attr.data-invalid]="(!effectiveReadOnly && effectiveInvalid) ? true : null" [attr.aria-readonly]="effectiveReadOnly ? true : null" [attr.aria-labelledby]="ariaLabelledby" [attr.aria-describedby]="(helperText && !effectiveInvalid && !effectiveWarn) ? helperId : null" (change)="onChange($event)" (click)="onClick($event)"> <label [for]="id + '_input'" [attr.aria-label]="ariaLabel" [attr.title]="title || null" class="cds--checkbox-label" [ngClass]="{ 'cds--skeleton' : skeleton }"> <span [ngClass]="{'cds--visually-hidden' : hideLabel}" class="cds--checkbox-label-text"> <ng-content></ng-content> <ng-container *ngIf="decorator"> <div class="cds--checkbox-wrapper-inner--decorator"> <ng-template [ngTemplateOutlet]="decorator"></ng-template> </div> </ng-container> </span> </label> <div class="cds--checkbox__validation-msg"> <ng-container *ngIf="!effectiveReadOnly && effectiveInvalid"> <svg cdsIcon="warning--filled" size="16" class="cds--checkbox__invalid-icon"> </svg> <div class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="$any(invalidText)"></ng-template> </div> </ng-container> <ng-container *ngIf="!effectiveReadOnly && !effectiveInvalid && effectiveWarn"> <svg cdsIcon="warning--alt--filled" size="16" class="cds--checkbox__invalid-icon cds--checkbox__invalid-icon--warning"> </svg> <div class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="$any(warnText)"></ng-template> </div> </ng-container> </div> <div *ngIf="helperText && !effectiveInvalid && !effectiveWarn" class="cds--form__helper-text" [id]="helperId"> <ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="$any(helperText)"></ng-template> </div> </div> `, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: Checkbox, multi: true } ], changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CHECKBOX_GROUP_HOST] }] }]; }, propDecorators: { disabled: [{ type: Input }], skeleton: [{ type: Input }], hideLabel: [{ type: Input }], name: [{ type: Input }], id: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], ariaLabel: [{ type: Input }], ariaLabelledby: [{ type: Input }], title: [{ type: Input }], helperText: [{ type: Input }], invalid: [{ type: Input }], invalidText: [{ type: Input }], warn: [{ type: Input }], warnText: [{ type: Input }], readOnly: [{ type: Input }], decorator: [{ type: Input }], indeterminate: [{ type: Input }], checked: [{ type: Input }], click: [{ type: Output }], checkedChange: [{ type: Output }], indeterminateChange: [{ type: Output }], inputCheckbox: [{ type: ViewChild, args: ["inputCheckbox"] }], focusOut: [{ type: HostListener, args: ["focusout"] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NoZWNrYm94L2NoZWNrYm94LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRU4sdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFDTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFdBQVcsRUFDWCxTQUFTLEVBQ1QsWUFBWSxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBd0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsbUJBQW1CLEVBQXFCLE1BQU0sdUJBQXVCLENBQUM7Ozs7QUFFL0U7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxhQUtYO0FBTEQsV0FBWSxhQUFhO0lBQ3hCLGlEQUFJLENBQUE7SUFDSixtRUFBYSxDQUFBO0lBQ2IsdURBQU8sQ0FBQTtJQUNQLDJEQUFTLENBQUE7QUFDVixDQUFDLEVBTFcsYUFBYSxLQUFiLGFBQWEsUUFLeEI7QUFFRDs7Ozs7Ozs7R0FRRztBQXNGSCxNQUFNLE9BQU8sUUFBUTtJQTBLcEI7O09BRUc7SUFDSCxZQUNXLGlCQUFvQyxFQUNHLFNBQW1DO1FBRDFFLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDRyxjQUFTLEdBQVQsU0FBUyxDQUEwQjtRQXZLckY7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00sYUFBUSxHQUFHLEtBQUssQ0FBQztRQUMxQjs7V0FFRztRQUNNLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFLM0I7O1dBRUc7UUFDTSxPQUFFLEdBQUcsWUFBWSxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7UUFZbkQ7O1dBRUc7UUFDTSxVQUFLLEdBQUcsRUFBRSxDQUFDO1FBeUZwQjs7V0FFRztRQUNPLFVBQUssR0FBRyxJQUFJLFlB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clZpZXdJbml0LFxuXHRDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdENvbXBvbmVudCxcblx0RWxlbWVudFJlZixcblx0RXZlbnRFbWl0dGVyLFxuXHRJbmplY3QsXG5cdElucHV0LFxuXHRPcHRpb25hbCxcblx0T3V0cHV0LFxuXHRUZW1wbGF0ZVJlZixcblx0Vmlld0NoaWxkLFxuXHRIb3N0TGlzdGVuZXJcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IE5HX1ZBTFVFX0FDQ0VTU09SLCBDb250cm9sVmFsdWVBY2Nlc3NvciB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgQ2hlY2tib3hWYWx1ZSB9IGZyb20gXCIuL2NoZWNrYm94LnR5cGVzXCI7XG5pbXBvcnQgeyBDSEVDS0JPWF9HUk9VUF9IT1NULCBDaGVja2JveEdyb3VwSG9zdCB9IGZyb20gXCIuL2NoZWNrYm94LWdyb3VwLWhvc3RcIjtcblxuLyoqXG4gKiBEZWZpbmVzIHRoZSBzZXQgb2Ygc3RhdGVzIGZvciBhIGNoZWNrYm94IGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGVudW0gQ2hlY2tib3hTdGF0ZSB7XG5cdEluaXQsXG5cdEluZGV0ZXJtaW5hdGUsXG5cdENoZWNrZWQsXG5cdFVuY2hlY2tlZFxufVxuXG4vKipcbiAqIEdldCBzdGFydGVkIHdpdGggaW1wb3J0aW5nIHRoZSBtb2R1bGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgQ2hlY2tib3hNb2R1bGUgfSBmcm9tICdjYXJib24tY29tcG9uZW50cy1hbmd1bGFyJztcbiAqIGBgYFxuICpcbiAqIFtTZWUgZGVtb10oLi4vLi4vP3BhdGg9L3N0b3J5L2NvbXBvbmVudHMtY2hlY2tib3gtLWJhc2ljKVxuICovXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLWNoZWNrYm94LCBpYm0tY2hlY2tib3hcIixcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1mb3JtLWl0ZW0gY2RzLS1jaGVja2JveC13cmFwcGVyXCJcblx0XHRcdFtuZ0NsYXNzXT1cIntcblx0XHRcdFx0J2Nkcy0tY2hlY2tib3gtd3JhcHBlci0taW52YWxpZCc6ICFlZmZlY3RpdmVSZWFkT25seSAmJiBlZmZlY3RpdmVJbnZhbGlkLFxuXHRcdFx0XHQnY2RzLS1jaGVja2JveC13cmFwcGVyLS13YXJuaW5nJzogIWVmZmVjdGl2ZVJlYWRPbmx5ICYmICFlZmZlY3RpdmVJbnZhbGlkICYmIGVmZmVjdGl2ZVdhcm4sXG5cdFx0XHRcdCdjZHMtLWNoZWNrYm94LXdyYXBwZXItLXJlYWRvbmx5JzogZWZmZWN0aXZlUmVhZE9ubHksXG5cdFx0XHRcdCdjZHMtLWNoZWNrYm94LXdyYXBwZXItLWRlY29yYXRvcic6ICEhZGVjb3JhdG9yXG5cdFx0XHR9XCI+XG5cdFx0XHQ8aW5wdXRcblx0XHRcdFx0I2lucHV0Q2hlY2tib3hcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLWNoZWNrYm94XCJcblx0XHRcdFx0dHlwZT1cImNoZWNrYm94XCJcblx0XHRcdFx0W2lkXT1cImlkICsgJ19pbnB1dCdcIlxuXHRcdFx0XHRbdmFsdWVdPVwidmFsdWVcIlxuXHRcdFx0XHRbbmFtZV09XCJuYW1lXCJcblx0XHRcdFx0W3JlcXVpcmVkXT1cInJlcXVpcmVkXCJcblx0XHRcdFx0W2NoZWNrZWRdPVwiY2hlY2tlZFwiXG5cdFx0XHRcdFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG5cdFx0XHRcdFthdHRyLmRhdGEtaW52YWxpZF09XCIoIWVmZmVjdGl2ZVJlYWRPbmx5ICYmIGVmZmVjdGl2ZUludmFsaWQpID8gdHJ1ZSA6IG51bGxcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLXJlYWRvbmx5XT1cImVmZmVjdGl2ZVJlYWRPbmx5ID8gdHJ1ZSA6IG51bGxcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsbGVkYnldPVwiYXJpYUxhYmVsbGVkYnlcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWRlc2NyaWJlZGJ5XT1cIihoZWxwZXJUZXh0ICYmICFlZmZlY3RpdmVJbnZhbGlkICYmICFlZmZlY3RpdmVXYXJuKSA/IGhlbHBlcklkIDogbnVsbFwiXG5cdFx0XHRcdChjaGFuZ2UpPVwib25DaGFuZ2UoJGV2ZW50KVwiXG5cdFx0XHRcdChjbGljayk9XCJvbkNsaWNrKCRldmVudClcIj5cblx0XHRcdDxsYWJlbFxuXHRcdFx0XHRbZm9yXT1cImlkICsgJ19pbnB1dCdcIlxuXHRcdFx0XHRbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFMYWJlbFwiXG5cdFx0XHRcdFthdHRyLnRpdGxlXT1cInRpdGxlIHx8IG51bGxcIlxuXHRcdFx0XHRjbGFzcz1cImNkcy0tY2hlY2tib3gtbGFiZWxcIlxuXHRcdFx0XHRbbmdDbGFzc109XCJ7XG5cdFx0XHRcdFx0J2Nkcy0tc2tlbGV0b24nIDogc2tlbGV0b25cblx0XHRcdFx0fVwiPlxuXHRcdFx0XHQ8c3BhbiBbbmdDbGFzc109XCJ7J2Nkcy0tdmlzdWFsbHktaGlkZGVuJyA6IGhpZGVMYWJlbH1cIiBjbGFzcz1cImNkcy0tY2hlY2tib3gtbGFiZWwtdGV4dFwiPlxuXHRcdFx0XHRcdDxuZy1jb250ZW50PjwvbmctY29udGVudD5cblx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiZGVjb3JhdG9yXCI+XG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1jaGVja2JveC13cmFwcGVyLWlubmVyLS1kZWNvcmF0b3JcIj5cblx0XHRcdFx0XHRcdFx0PG5nLXRlbXBsYXRlIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImRlY29yYXRvclwiPjwvbmctdGVtcGxhdGU+XG5cdFx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PC9zcGFuPlxuXHRcdFx0PC9sYWJlbD5cblx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLWNoZWNrYm94X192YWxpZGF0aW9uLW1zZ1wiPlxuXHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWVmZmVjdGl2ZVJlYWRPbmx5ICYmIGVmZmVjdGl2ZUludmFsaWRcIj5cblx0XHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0XHRjZHNJY29uPVwid2FybmluZy0tZmlsbGVkXCJcblx0XHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0XHRjbGFzcz1cImNkcy0tY2hlY2tib3hfX2ludmFsaWQtaWNvblwiPlxuXHRcdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjZHMtLWZvcm0tcmVxdWlyZW1lbnRcIj5cblx0XHRcdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZShpbnZhbGlkVGV4dClcIj57e2ludmFsaWRUZXh0fX08L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaW52YWxpZFRleHQpXCIgW25nVGVtcGxhdGVPdXRsZXRdPVwiJGFueShpbnZhbGlkVGV4dClcIj48L25nLXRlbXBsYXRlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L25nLWNvbnRhaW5lcj5cblx0XHRcdFx0PG5nLWNvbnRhaW5lciAqbmdJZj1cIiFlZmZlY3RpdmVSZWFkT25seSAmJiAhZWZmZWN0aXZlSW52YWxpZCAmJiBlZmZlY3RpdmVXYXJuXCI+XG5cdFx0XHRcdFx0PHN2Z1xuXHRcdFx0XHRcdFx0Y2RzSWNvbj1cIndhcm5pbmctLWFsdC0tZmlsbGVkXCJcblx0XHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0XHRjbGFzcz1cImNkcy0tY2hlY2tib3hfX2ludmFsaWQtaWNvbiBjZHMtLWNoZWNrYm94X19pbnZhbGlkLWljb24tLXdhcm5pbmdcIj5cblx0XHRcdFx0XHQ8L3N2Zz5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2RzLS1mb3JtLXJlcXVpcmVtZW50XCI+XG5cdFx0XHRcdFx0XHQ8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzVGVtcGxhdGUod2FyblRleHQpXCI+e3t3YXJuVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdFx0XHQ8bmctdGVtcGxhdGUgKm5nSWY9XCJpc1RlbXBsYXRlKHdhcm5UZXh0KVwiIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIiRhbnkod2FyblRleHQpXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PC9uZy1jb250YWluZXI+XG5cdFx0XHQ8L2Rpdj5cblx0XHRcdDxkaXZcblx0XHRcdFx0Km5nSWY9XCJoZWxwZXJUZXh0ICYmICFlZmZlY3RpdmVJbnZhbGlkICYmICFlZmZlY3RpdmVXYXJuXCJcblx0XHRcdFx0Y2xhc3M9XCJjZHMtLWZvcm1fX2hlbHBlci10ZXh0XCJcblx0XHRcdFx0W2lkXT1cImhlbHBlcklkXCI+XG5cdFx0XHRcdDxuZy1jb250YWluZXIgKm5nSWY9XCIhaXNUZW1wbGF0ZShoZWxwZXJUZXh0KVwiPnt7aGVscGVyVGV4dH19PC9uZy1jb250YWluZXI+XG5cdFx0XHRcdDxuZy10ZW1wbGF0ZSAqbmdJZj1cImlzVGVtcGxhdGUoaGVscGVyVGV4dClcIiBbbmdUZW1wbGF0ZU91dGxldF09XCIkYW55KGhlbHBlclRleHQpXCI+PC9uZy10ZW1wbGF0ZT5cblx0XHRcdDwvZGl2PlxuXHRcdDwvZGl2PlxuXHRgLFxuXHRwcm92aWRlcnM6IFtcblx0XHR7XG5cdFx0XHRwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcblx0XHRcdHVzZUV4aXN0aW5nOiBDaGVja2JveCxcblx0XHRcdG11bHRpOiB0cnVlXG5cdFx0fVxuXHRdLFxuXHRjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBDaGVja2JveCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBBZnRlclZpZXdJbml0IHtcblx0LyoqXG5cdCAqIFZhcmlhYmxlIHVzZWQgZm9yIGNyZWF0aW5nIHVuaXF1ZSBpZHMgZm9yIGNoZWNrYm94IGNvbXBvbmVudHMuXG5cdCAqL1xuXHRzdGF0aWMgY2hlY2tib3hDb3VudCA9IDA7XG5cblx0cHJpdmF0ZSBzdGF0aWMgaGVscGVySWRDb3VudGVyID0gMDtcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCBmb3IgYSBkaXNhYmxlZCBjaGVja2JveC5cblx0ICovXG5cdEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBTZXQgdG8gYHRydWVgIGZvciBhIGxvYWRpbmcgY2hlY2tib3guXG5cdCAqL1xuXHRASW5wdXQoKSBza2VsZXRvbiA9IGZhbHNlO1xuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCB0byBoaWRlIHRoZSBjaGVja2JveCBsYWJlbHMuXG5cdCAqL1xuXHRASW5wdXQoKSBoaWRlTGFiZWwgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldHMgdGhlIG5hbWUgYXR0cmlidXRlIG9uIHRoZSBgaW5wdXRgIGVsZW1lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSBuYW1lOiBzdHJpbmc7XG5cdC8qKlxuXHQgKiBUaGUgdW5pcXVlIGlkIGZvciB0aGUgY2hlY2tib3ggY29tcG9uZW50LlxuXHQgKi9cblx0QElucHV0KCkgaWQgPSBgY2hlY2tib3gtJHtDaGVja2JveC5jaGVja2JveENvdW50fWA7XG5cdC8qKlxuXHQgKiBSZWZsZWN0cyB0aGUgcmVxdWlyZWQgYXR0cmlidXRlIG9mIHRoZSBgaW5wdXRgIGVsZW1lbnQuXG5cdCAqL1xuXHRASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbjtcblx0LyoqXG5cdCAqIFNldHMgdGhlIHZhbHVlIGF0dHJpYnV0ZSBvbiB0aGUgYGlucHV0YCBlbGVtZW50LlxuXHQgKi9cblx0QElucHV0KCkgdmFsdWU6IENoZWNrYm94VmFsdWU7XG5cdEBJbnB1dCgpIGFyaWFMYWJlbDogc3RyaW5nO1xuXHRASW5wdXQoKSBhcmlhTGFiZWxsZWRieTogc3RyaW5nO1xuXG5cdC8qKlxuXHQgKiBPcHRpb25hbCB0aXRsZSBmb3IgdGhlIGA8bGFiZWw+YCBlbGVtZW50LlxuXHQgKi9cblx0QElucHV0KCkgdGl0bGUgPSBcIlwiO1xuXG5cdC8qKlxuXHQgKiBPcHRpb25hbCBoZWxwZXIgdGV4dCBkaXNwbGF5ZWQgYmVsb3cgdGhlIGNoZWNrYm94IGxhYmVsLlxuXHQgKiBOb3Qgc2hvd24gd2hlbiBgaW52YWxpZGAgb3IgYHdhcm5gIGlzIGB0cnVlYC5cblx0ICovXG5cdEBJbnB1dCgpIGhlbHBlclRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gc2hvdyB0aGUgY2hlY2tib3ggaW4gYW4gaW52YWxpZC9lcnJvciBzdGF0ZS5cblx0ICogV2hlbiBvbWl0dGVkIGluc2lkZSBhIGBjZHMtY2hlY2tib3gtZ3JvdXBgLCB0aGUgZ3JvdXAncyBgaW52YWxpZGAgdmFsdWUgYXBwbGllcy5cblx0ICovXG5cdEBJbnB1dCgpIGludmFsaWQ/OiBib29sZWFuO1xuXG5cdC8qKlxuXHQgKiBUaGUgZXJyb3IgbWVzc2FnZSBkaXNwbGF5ZWQgd2hlbiBgaW52YWxpZGAgaXMgYHRydWVgLlxuXHQgKi9cblx0QElucHV0KCkgaW52YWxpZFRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgdG8gc2hvdyB0aGUgY2hlY2tib3ggaW4gYSB3YXJuaW5nIHN0YXRlLlxuXHQgKiBXaGVuIG9taXR0ZWQgaW5zaWRlIGEgYGNkcy1jaGVja2JveC1ncm91cGAsIHRoZSBncm91cCdzIGB3YXJuYCB2YWx1ZSBhcHBsaWVzLlxuXHQgKi9cblx0QElucHV0KCkgd2Fybj86IGJvb2xlYW47XG5cblx0LyoqXG5cdCAqIFRoZSB3YXJuaW5nIG1lc3NhZ2UgZGlzcGxheWVkIHdoZW4gYHdhcm5gIGlzIGB0cnVlYCBhbmQgYGludmFsaWRgIGlzIGBmYWxzZWAuXG5cdCAqL1xuXHRASW5wdXQoKSB3YXJuVGV4dDogc3RyaW5nIHwgVGVtcGxhdGVSZWY8YW55PjtcblxuXHQvKipcblx0ICogV2hlbiBgdHJ1ZWAsIHRoZSBjaGVja2JveCBjYW5ub3QgYmUgdG9nZ2xlZCAobWF0Y2hlcyBgcmVhZG9ubHlgIGF0dHJpYnV0ZSBzZW1hbnRpY3MgZm9yIGZvcm0gY29udHJvbHMpLlxuXHQgKiBXaGVuIG9taXR0ZWQgaW5zaWRlIGEgYGNkcy1jaGVja2JveC1ncm91cGAsIHRoZSBncm91cCdzIGByZWFkT25seWAgdmFsdWUgYXBwbGllcy5cblx0ICovXG5cdEBJbnB1dCgpIHJlYWRPbmx5PzogYm9vbGVhbjtcblxuXHQvKipcblx0ICogT3B0aW9uYWwgYFRlbXBsYXRlUmVmYCAoZS5nLiBBSSBsYWJlbCkgcmVuZGVyZWQgbmV4dCB0byB0aGUgbGFiZWwgdGV4dC5cblx0ICovXG5cdEBJbnB1dCgpIGRlY29yYXRvcjogVGVtcGxhdGVSZWY8YW55PjtcblxuXHQvKipcblx0ICogU2V0IHRoZSBjaGVja2JveCdzIGluZGV0ZXJtaW5hdGUgc3RhdGUgdG8gbWF0Y2ggdGhlIHBhcmFtZXRlciBhbmQgdHJhbnNpdGlvbiB0aGUgdmlldyB0byByZWZsZWN0IHRoZSBjaGFuZ2UuXG5cdCAqXG5cdCAqIEFsbG93cyBkb3VibGUgYmluZGluZyB3aXRoIHRoZSBgaW5kZXRlcm1pbmF0ZUNoYW5nZWAgT3V0cHV0LlxuXHQgKi9cblx0QElucHV0KCkgc2V0IGluZGV0ZXJtaW5hdGUoaW5kZXRlcm1pbmF0ZTogYm9vbGVhbikge1xuXHRcdGlmIChpbmRldGVybWluYXRlID09PSB0aGlzLl9pbmRldGVybWluYXRlKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy5faW5kZXRlcm1pbmF0ZSA9IGluZGV0ZXJtaW5hdGU7XG5cblx0XHRpZiAodGhpcy5faW5kZXRlcm1pbmF0ZSkge1xuXHRcdFx0dGhpcy50cmFuc2l0aW9uQ2hlY2tib3hTdGF0ZShDaGVja2JveFN0YXRlLkluZGV0ZXJtaW5hdGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnRyYW5zaXRpb25DaGVja2JveFN0YXRlKHRoaXMuY2hlY2tlZCA/IENoZWNrYm94U3RhdGUuQ2hlY2tlZCA6IENoZWNrYm94U3RhdGUuVW5jaGVja2VkKTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5pbnB1dENoZWNrYm94ICYmIHRoaXMuaW5wdXRDaGVja2JveC5uYXRpdmVFbGVtZW50KSB7XG5cdFx0XHR0aGlzLmlucHV0Q2hlY2tib3gubmF0aXZlRWxlbWVudC5pbmRldGVybWluYXRlID0gaW5kZXRlcm1pbmF0ZTtcblx0XHR9XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0XHR0aGlzLmluZGV0ZXJtaW5hdGVDaGFuZ2UuZW1pdCh0aGlzLl9pbmRldGVybWluYXRlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZWZsZWN0cyB3aGV0aGVyIHRoZSBjaGVja2JveCBzdGF0ZSBpcyBpbmRldGVybWluYXRlLlxuXHQgKi9cblx0Z2V0IGluZGV0ZXJtaW5hdGUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2luZGV0ZXJtaW5hdGU7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyB0aGUgYGNoZWNrZWRgIHN0YXRlLiBgdHJ1ZWAgZm9yIGNoZWNrZWQsIGBmYWxzZWAgZm9yIHVuY2hlY2tlZFxuXHQgKlxuXHQgKiBBbGxvd3MgZG91YmxlIGJpbmRpbmcgd2l0aCB0aGUgYGNoZWNrZWRDaGFuZ2VgIE91dHB1dC5cblx0ICovXG5cdEBJbnB1dCgpIHNldCBjaGVja2VkIChjaGVja2VkOiBib29sZWFuKSB7XG5cdFx0dGhpcy5zZXRDaGVja2VkKGNoZWNrZWQsIGZhbHNlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIHZhbHVlIGB0cnVlYCBpZiBzdGF0ZSBpcyBzZWxlY3RlZCBmb3IgdGhlIGNoZWNrYm94LlxuXHQgKi9cblx0Z2V0IGNoZWNrZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2NoZWNrZWQ7XG5cdH1cblxuXHQvKipcblx0ICogRW1pdHMgY2xpY2sgZXZlbnQuXG5cdCAqL1xuXHRAT3V0cHV0KCkgY2xpY2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cblx0LyoqXG5cdCAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gdGhlIHZhbHVlIG9mIHRoZSBjaGVja2JveCBjaGFuZ2VzLlxuXHQgKlxuXHQgKiBBbGxvd3MgZG91YmxlIGJpZGluZyB3aXRoIHRoZSBgY2hlY2tlZGAgSW5wdXQuXG5cdCAqL1xuXHRAT3V0cHV0KCkgY2hlY2tlZENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuXHQvKipcblx0ICogRW1pdHMgZXZlbnQgbm90aWZ5aW5nIG90aGVyIGNsYXNzZXMgd2hlbiBhIGNoYW5nZSBpbiBzdGF0ZSBvY2N1cnMgc3BlY2lmaWNhbGx5XG5cdCAqIG9uIGFuIGluZGV0ZXJtaW5hdGUgY2hlY2tib3guXG5cdCAqL1xuXHRAT3V0cHV0KCkgaW5kZXRlcm1pbmF0ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuXHQvKipcblx0ICogU2V0IHRvIGB0cnVlYCBpZiB0aGUgaW5wdXQgY2hlY2tib3ggaXMgc2VsZWN0ZWQgKG9yIGNoZWNrZWQpLlxuXHQgKi9cblx0X2NoZWNrZWQgPSBmYWxzZTtcblx0LyoqXG5cdCAqIFNldCB0byBgdHJ1ZWAgaWYgdGhlIGlucHV0IGNoZWNrYm94IGlzIGluIHN0YXRlIGluZGV0ZXJtaW5hdGUuXG5cdCAqL1xuXHRfaW5kZXRlcm1pbmF0ZSA9IGZhbHNlO1xuXG5cdC8qKlxuXHQgKiBLZWVwcyBhIHJlZmVyZW5jZSB0byB0aGUgY2hlY2tib3hlcyBjdXJyZW50IHN0YXRlLCBhcyBkZWZpbmVkIGluIGBDaGVja2JveFN0YXRlYC5cblx0ICovXG5cdGN1cnJlbnRDaGVja2JveFN0YXRlID0gQ2hlY2tib3hTdGF0ZS5Jbml0O1xuXG5cdC8qKlxuXHQgKiBNYWludGFpbnMgYSByZWZlcmVuY2UgdG8gdGhlIHZpZXcgRE9NIGVsZW1lbnQgb2YgdGhlIGBDaGVja2JveGAuXG5cdCAqL1xuXHRAVmlld0NoaWxkKFwiaW5wdXRDaGVja2JveFwiKSBpbnB1dENoZWNrYm94OiBFbGVtZW50UmVmO1xuXG5cdHJlYWRvbmx5IGhlbHBlcklkID0gYGNoZWNrYm94LWhlbHBlci0ke0NoZWNrYm94LmhlbHBlcklkQ291bnRlcisrfWA7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgYENoZWNrYm94YC5cblx0ICovXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByb3RlY3RlZCBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG5cdFx0QE9wdGlvbmFsKCkgQEluamVjdChDSEVDS0JPWF9HUk9VUF9IT1NUKSBwcml2YXRlIGhvc3RHcm91cDogQ2hlY2tib3hHcm91cEhvc3QgfCBudWxsXG5cdCkge1xuXHRcdENoZWNrYm94LmNoZWNrYm94Q291bnQrKztcblx0fVxuXG5cdGdldCBlZmZlY3RpdmVSZWFkT25seSgpOiBib29sZWFuIHtcblx0XHRjb25zdCBvd24gPSB0aGlzLnJlYWRPbmx5O1xuXHRcdGNvbnN0IGdyb3VwID0gdGhpcy5ob3N0R3JvdXA/LnJlYWRPbmx5ID8/IGZhbHNlO1xuXHRcdHJldHVybiAhIShvd24gIT09IHVuZGVmaW5lZCA/IG93biA6IGdyb3VwKTtcblx0fVxuXG5cdGdldCBlZmZlY3RpdmVJbnZhbGlkKCk6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IG93biA9IHRoaXMuaW52YWxpZDtcblx0XHRjb25zdCBncm91cCA9IHRoaXMuaG9zdEdyb3VwPy5pbnZhbGlkID8/IGZhbHNlO1xuXHRcdHJldHVybiAhIShvd24gIT09IHVuZGVmaW5lZCA/IG93biA6IGdyb3VwKTtcblx0fVxuXG5cdGdldCBlZmZlY3RpdmVXYXJuKCk6IGJvb2xlYW4ge1xuXHRcdGNvbnN0IG93biA9IHRoaXMud2Fybjtcblx0XHRjb25zdCBncm91cCA9IHRoaXMuaG9zdEdyb3VwPy53YXJuID8/IGZhbHNlO1xuXHRcdHJldHVybiAhIShvd24gIT09IHVuZGVmaW5lZCA/IG93biA6IGdyb3VwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBUb2dnbGUgdGhlIHNlbGVjdGVkIHN0YXRlIG9mIHRoZSBjaGVja2JveC5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGUoKSB7XG5cdFx0aWYgKHRoaXMuZWZmZWN0aXZlUmVhZE9ubHkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Ly8gRmxpcCBjaGVja2VkIGFuZCByZXNldCBpbmRldGVybWluYXRlXG5cdFx0dGhpcy5zZXRDaGVja2VkKCF0aGlzLmNoZWNrZWQsIHRydWUpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFdyaXRlcyBhIHZhbHVlIGZyb20gYG5nTW9kZWxgIHRvIHRoZSBjb21wb25lbnQuXG5cdCAqXG5cdCAqIEluIHRoaXMgY2FzZSB0aGUgdmFsdWUgaXMgdGhlIGBjaGVja2VkYCBwcm9wZXJ0eS5cblx0ICpcblx0ICogQHBhcmFtIHZhbHVlIGJvb2xlYW4sIGNvcnJlc3BvbmRzIHRvIHRoZSBgY2hlY2tlZGAgcHJvcGVydHkuXG5cdCAqL1xuXHRwdWJsaWMgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KSB7XG5cdFx0Ly8gU2V0IGNoZWNrZWQgYW5kIHJlc2V0IGluZGV0ZXJtaW5hdGVcblx0XHR0aGlzLnNldENoZWNrZWQoISF2YWx1ZSwgdHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBhIG1ldGhvZCBpbiBvcmRlciB0byBwcm9wYWdhdGUgY2hhbmdlcyBiYWNrIHRvIHRoZSBmb3JtLlxuXHQgKi9cblx0cHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSkge1xuXHRcdHRoaXMucHJvcGFnYXRlQ2hhbmdlID0gZm47XG5cdH1cblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgdG8gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIGNvbnRyb2wgaGFzIGJlZW4gdG91Y2hlZC5cblx0ICogQHBhcmFtIGZuIENhbGxiYWNrIHRvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSBjaGVja2JveCBpcyB0b3VjaGVkLlxuXHQgKi9cblx0cHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpIHtcblx0XHR0aGlzLm9uVG91Y2hlZCA9IGZuO1xuXHR9XG5cblx0LyoqXG5cdCAqIGBDb250cm9sVmFsdWVBY2Nlc3NvcmAgbWV0aG9kIHRvIHByb2dyYW1tYXRpY2FsbHkgZGlzYWJsZSB0aGUgY2hlY2tib3guXG5cdCAqXG5cdCAqIGV4OiBgdGhpcy5mb3JtR3JvdXAuZ2V0KFwibXlDaGVja2JveFwiKS5kaXNhYmxlKCk7YFxuXHQgKlxuXHQgKiBAcGFyYW0gaXNEaXNhYmxlZCBgdHJ1ZWAgdG8gZGlzYWJsZSB0aGUgY2hlY2tib3hcblx0ICovXG5cdHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbikge1xuXHRcdHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuXHRcdHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG5cdH1cblxuXHQvKipcblx0ICogSW52b2tlZCBieSBgQ2hlY2tib3hHcm91cGAgd2hlbiBncm91cCBgcmVhZE9ubHlgLCBgaW52YWxpZGAsIGB3YXJuYCBjaGFuZ2Ugc28gYE9uUHVzaGBcblx0ICogY2hlY2tib3hlcyBzdGlsbCByZWZyZXNoIGluaGVyaXRlZCBzdGF0ZSBmcm9tIGBDSEVDS0JPWF9HUk9VUF9IT1NUYC5cblx0ICovXG5cdG1hcmtGb3JDaGVja0Zyb21Hcm91cCgpOiB2b2lkIHtcblx0XHR0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuXHR9XG5cblx0QEhvc3RMaXN0ZW5lcihcImZvY3Vzb3V0XCIpXG5cdGZvY3VzT3V0KCkge1xuXHRcdHRoaXMub25Ub3VjaGVkKCk7XG5cdH1cblxuXHQvKipcblx0ICogRXhlY3V0ZXMgb24gdGhlIGV2ZW50IG9mIGEgY2hhbmdlIHdpdGhpbiBgQ2hlY2tib3hgIHRvIGJsb2NrIHByb3BhZ2F0aW9uLlxuXHQgKi9cblx0b25DaGFuZ2UoZXZlbnQ6IEV2ZW50KSB7XG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH1cblxuXHQvKipcblx0ICogSGFuZGxlcyBjbGljayBldmVudHMgb24gdGhlIGBDaGVja2JveGAgYW5kIGVtaXRzIGNoYW5nZXMgdG8gb3RoZXIgY2xhc3Nlcy5cblx0ICovXG5cdG9uQ2xpY2soZXZlbnQ6IEV2ZW50KSB7XG5cdFx0aWYgKHRoaXMuZWZmZWN0aXZlUmVhZE9ubHkpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRpZiAodGhpcy5jbGljay5vYnNlcnZlcnMubGVuZ3RoKSB7XG5cdFx0XHRcdHRoaXMuY2xpY2suZW1pdCgpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAodGhpcy5jbGljay5vYnNlcnZlcnMubGVuZ3RoKSB7XG5cdFx0XHQvLyBEaXNhYmxlIGRlZmF1bHQgY2hlY2tib3ggYWN0aXZhdGlvbiBiZWhhdmlvciB3aGljaCBmbGlwcyBjaGVja2VkIGFuZCByZXNldHMgaW5kZXRlcm1pbmF0ZS5cblx0XHRcdC8vIFRoaXMgYWxsb3dzIHRoZSBwYXJlbnQgY29tcG9uZW50IHRvIGNvbnRyb2wgdGhlIGNoZWNrZWQvaW5kZXRlcm1pbmF0ZSBwcm9wZXJ0aWVzLlxuXHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdHRoaXMuY2xpY2suZW1pdCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRpZiAoIXRoaXMuZGlzYWJsZWQpIHtcblx0XHRcdHRoaXMudG9nZ2xlKCk7XG5cdFx0XHR0aGlzLnRyYW5zaXRpb25DaGVja2JveFN0YXRlKHRoaXMuX2NoZWNrZWQgPyBDaGVja2JveFN0YXRlLkNoZWNrZWQgOiBDaGVja2JveFN0YXRlLlVuY2hlY2tlZCk7XG5cdFx0XHR0aGlzLmVtaXRDaGFuZ2VFdmVudCgpO1xuXHRcdH1cblx0fVxuXG5cblx0LyoqXG5cdCAqIENhbGxlZCB3aGVuIGNoZWNrYm94IGlzIGJsdXJyZWQuIE5lZWRlZCB0byBwcm9wZXJseSBpbXBsZW1lbnQgYENvbnRyb2xWYWx1ZUFjY2Vzc29yYC5cblx0ICovXG5cdG9uVG91Y2hlZDogKCkgPT4gYW55ID0gKCkgPT4ge307XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgY2hhbmdlcyBiZXR3ZWVuIGNoZWNrYm94IHN0YXRlcy5cblx0ICovXG5cdHRyYW5zaXRpb25DaGVja2JveFN0YXRlKG5ld1N0YXRlOiBDaGVja2JveFN0YXRlKSB7XG5cdFx0dGhpcy5jdXJyZW50Q2hlY2tib3hTdGF0ZSA9IG5ld1N0YXRlO1xuXHR9XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgaW5zdGFuY2Ugb2YgYENoZWNrYm94Q2hhbmdlYCB1c2VkIHRvIHByb3BhZ2F0ZSB0aGUgY2hhbmdlIGV2ZW50LlxuXHQgKi9cblx0ZW1pdENoYW5nZUV2ZW50KCkge1xuXHRcdHRoaXMuY2hlY2tlZENoYW5nZS5lbWl0KHRoaXMuY2hlY2tlZCk7XG5cdFx0dGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy5jaGVja2VkKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSBjaGVja2JveCBpZiBpdCBpcyBpbiB0aGUgaW5kZXRlcm1pbmF0ZSBzdGF0ZS5cblx0ICovXG5cdG5nQWZ0ZXJWaWV3SW5pdCgpIHtcblx0XHRpZiAodGhpcy5pbmRldGVybWluYXRlICYmIHRoaXMuaW5wdXRDaGVja2JveCAmJiB0aGlzLmlucHV0Q2hlY2tib3gubmF0aXZlRWxlbWVudCkge1xuXHRcdFx0dGhpcy5pbnB1dENoZWNrYm94Lm5hdGl2ZUVsZW1lbnQuaW5kZXRlcm1pbmF0ZSA9IHRydWU7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIE1ldGhvZCBzZXQgaW4gYHJlZ2lzdGVyT25DaGFuZ2VgIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzIGJhY2sgdG8gdGhlIGZvcm0uXG5cdCAqL1xuXHRwcm9wYWdhdGVDaGFuZ2UgPSAoXzogYW55KSA9PiB7fTtcblxuXHQvKipcblx0ICogUmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgYSBgVGVtcGxhdGVSZWZgLlxuXHQgKi9cblx0aXNUZW1wbGF0ZSh2YWx1ZTogYW55KTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGVtcGxhdGVSZWY7XG5cdH1cblxuXHQvKipcblx0ICogU2V0cyBjaGVja2VkIHN0YXRlIGFuZCBvcHRpb25hbGx5IHJlc2V0cyBpbmRldGVybWluYXRlIHN0YXRlLlxuXHQgKi9cblx0cHJpdmF0ZSBzZXRDaGVja2VkKGNoZWNrZWQ6IGJvb2xlYW4sIHJlc2V0SW5kZXRlcm1pbmF0ZTogYm9vbGVhbikge1xuXHRcdGlmIChjaGVja2VkID09PSB0aGlzLl9jaGVja2VkKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuX2NoZWNrZWQgPSBjaGVja2VkO1xuXHRcdC8vIFJlc2V0IGluZGV0ZXJtaW5hdGUgaWYgcmVxdWVzdGVkXG5cdFx0aWYgKHJlc2V0SW5kZXRlcm1pbmF0ZSAmJiB0aGlzLl9pbmRldGVybWluYXRlKSB7XG5cdFx0XHR0aGlzLl9pbmRldGVybWluYXRlID0gZmFsc2U7XG5cdFx0XHRQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcblx0XHRcdFx0dGhpcy5pbmRldGVybWluYXRlQ2hhbmdlLmVtaXQodGhpcy5faW5kZXRlcm1pbmF0ZSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0fVxufVxuIl19