@engie-group/fluid-design-system-angular
Version:
Fluid Design System Angular
227 lines • 31.6 kB
JavaScript
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, Output, ViewEncapsulation, } from '@angular/core';
import { FormFieldDirective } from '../form-field/form-field.directive';
import { IconButtonComponent } from '../icon-button/icon-button.component';
import { IconComponent } from '../icon/icon.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class FormItemComponent {
constructor() {
this.formItemClassName = 'nj-form-item';
/**
* @ignore
*/
this.isVisible = false;
/**
* @ignore
*/
this.passwordNotice = '';
/**
* @ignore
*/
this.passwordButtonLabel = '';
/**
* @ignore
*/
this.isMultiline = false;
/**
* Form item size
*/
this.size = 'medium';
/**
* Whether the form-item label is floating
*/
this.isFloatingLabel = true;
/**
* Whether the form-item's icon (or custom icon) is clickable
*/
this.isIconClickable = true;
/**
* Additional form-item css classes
*/
this.additionalClass = '';
/**
* Outputs icon click
*/
this.iconClick = new EventEmitter();
/**
* Outputs icon keydown
*/
this.iconKeydown = new EventEmitter();
/**
* Outputs icon click
*/
this.wrapperClick = new EventEmitter();
}
/**
* Whether form-item is in success state
*/
set hasSuccess(value) {
this._hasSuccess = value;
this.setAriaAttributes();
}
get hasSuccess() {
return this._hasSuccess;
}
/**
* Whether form-item is in error state
*/
set hasError(value) {
this._hasError = value;
this.setAriaAttributes();
}
get hasError() {
return this._hasError;
}
/**
* Whether the form-item has a hint substring
*/
set hasHint(value) {
this._hasHint = value;
this.setAriaAttributes();
}
get hasHint() {
return this._hasHint;
}
ngAfterContentInit() {
const tagName = this.formField?.tagName?.toLowerCase();
this.isPassword = this.formField?.type === 'password';
this.isMultiline = tagName === 'textarea';
this.passwordButtonLabel = this.passwordButtonLabelShow;
this.setAriaAttributes();
if (this.isRequired) {
this.formField.element.setAttribute('required', 'required');
}
}
/**
* @ignore
*/
iconClickHandler(event) {
if (!this.isIconClickable) {
return;
}
this.iconClick.emit(event);
}
/**
* @ignore
*/
iconKeydownHandler(event) {
event?.preventDefault();
if (!this.isIconClickable) {
return;
}
this.iconKeydown.emit(event);
}
/**
* @ignore
*/
toggleVisibility() {
if (this.isVisible) {
this.formField.type = 'password';
this.passwordNotice = this.passwordNoticeIsHidden;
this.passwordButtonLabel = this.passwordButtonLabelShow;
}
else {
this.formField.type = 'text';
this.passwordNotice = this.passwordNoticeIsVisible;
this.passwordButtonLabel = this.passwordButtonLabelHide;
}
this.isVisible = !this.isVisible;
}
/**
* @ignore
*/
getSubscriptId() {
return `${this.inputId}-subscript`;
}
/**
* @ignore
*/
setAriaAttributes() {
if (this.formField?.element) {
if (this.hasError) {
this.formField.element.setAttribute('aria-invalid', 'true');
}
if (this.hasError || this.hasSuccess || this.hasHint) {
this.formField.element.setAttribute('aria-describedby', this.getSubscriptId());
}
}
}
/**
* @ignore
*/
isCustomSelect() {
const type = this.formField?.type;
return this.isSelect && type === 'text';
}
/**
* @ignore
*/
getFormItemSizeClass() {
let sizeModifier;
switch (this.size) {
case 'small':
sizeModifier = 'sm';
break;
case 'large':
sizeModifier = 'lg';
break;
case 'xlarge':
sizeModifier = 'xl';
break;
default:
break;
}
return sizeModifier ? `${this.formItemClassName}--${sizeModifier}` : '';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: FormItemComponent, isStandalone: true, selector: "nj-form-item", inputs: { inputId: "inputId", size: "size", isFloatingLabel: "isFloatingLabel", isDisabled: "isDisabled", isRequired: "isRequired", hasSuccess: "hasSuccess", hasError: "hasError", hasHint: "hasHint", hasCustomIcon: "hasCustomIcon", isIconClickable: "isIconClickable", iconName: "iconName", additionalClass: "additionalClass", passwordButtonLabelShow: "passwordButtonLabelShow", passwordButtonLabelHide: "passwordButtonLabelHide", passwordNoticeIsVisible: "passwordNoticeIsVisible", passwordNoticeIsHidden: "passwordNoticeIsHidden", isSelect: "isSelect" }, outputs: { iconClick: "iconClick", iconKeydown: "iconKeydown", wrapperClick: "wrapperClick" }, queries: [{ propertyName: "formField", first: true, predicate: FormFieldDirective, descendants: true }], ngImport: i0, template: "<div class=\"nj-form-item\"\n [class.nj-form-item--static]=\"!isFloatingLabel\"\n [class.nj-form-item--disabled]=\"isDisabled\"\n [class.nj-form-item--error]=\"hasError\"\n [class.nj-form-item--success]=\"hasSuccess\"\n [class.nj-form-item--password]=\"isPassword\"\n [class.nj-form-item--select]=\"isSelect\"\n [class.nj-form-item--visible]=\"isVisible\"\n [class.nj-form-item--textarea]=\"isMultiline\"\n [ngClass]=\"[getFormItemSizeClass(), additionalClass]\">\n <div class=\"nj-form-item__field-wrapper\" (click)=\"wrapperClick.emit($event)\">\n <ng-content select=\"[njFormField]\"></ng-content>\n <label class=\"nj-form-item__label\" [attr.for]=\"inputId\" [attr.aria-hidden]=\"isCustomSelect() ? 'true' : null\">\n <ng-content select=\"[njFormLabel]\"></ng-content>\n <span *ngIf=\"isRequired\" class=\"nj-form-item__required-asterisk\">*</span>\n </label>\n <nj-icon-button\n *ngIf=\"isPassword\"\n size=\"sm\"\n variant=\"tertiary\"\n [label]=\"passwordButtonLabel\"\n [icon]=\"iconName || 'visibility'\"\n (click)=\"toggleVisibility()\"\n [ariaPressed]=\"isVisible\"\n additionalClass=\"nj-form-item__password-button\"\n >\n </nj-icon-button>\n <nj-icon class=\"nj-form-item__icon\"\n *ngIf=\"!isPassword && !isMultiline && !hasCustomIcon && iconName\"\n [name]=\"iconName\"\n variant=\"inherit\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\">\n </nj-icon>\n <div class=\"nj-form-item__icon\" *ngIf=\"!isPassword && !isMultiline && hasCustomIcon\" [attr.tabindex]=\"isIconClickable ? 0 : null\"\n (click)=\"iconClickHandler($event)\" (keydown)=\"iconKeydownHandler($event)\">\n <ng-content select=\"[njFormCustomIcon]\"></ng-content>\n </div>\n <p *ngIf=\"isPassword\" class=\"nj-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ passwordNotice }}</p>\n <ng-content select=\"[njFormAdditionalContent]\"></ng-content>\n </div>\n <div class=\"nj-form-item__subscript\" *ngIf=\"hasError || hasSuccess || hasHint\" [attr.id]=\"getSubscriptId()\">\n <nj-icon *ngIf=\"hasError\" class=\"nj-form-item__subscript-icon\" name=\"warning\" size=\"inherit\" variant=\"inherit\"></nj-icon>\n <nj-icon *ngIf=\"hasSuccess && !hasError\" class=\"nj-form-item__subscript-icon\" name=\"check\" size=\"inherit\" variant=\"inherit\"></nj-icon>\n <ng-content select=\"[njFormSubscript]\"></ng-content>\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "nj-icon", inputs: ["size", "variant"] }, { kind: "component", type: IconButtonComponent, selector: "nj-icon-button", inputs: ["type", "ariaPressed", "ariaDescribedby", "isDisabled", "tabIndex", "variant", "size", "hasCustomIcon", "icon", "label", "additionalClass"], outputs: ["buttonClick"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: FormItemComponent, decorators: [{
type: Component,
args: [{ selector: 'nj-form-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [IconComponent, IconButtonComponent, FormFieldDirective, CommonModule], template: "<div class=\"nj-form-item\"\n [class.nj-form-item--static]=\"!isFloatingLabel\"\n [class.nj-form-item--disabled]=\"isDisabled\"\n [class.nj-form-item--error]=\"hasError\"\n [class.nj-form-item--success]=\"hasSuccess\"\n [class.nj-form-item--password]=\"isPassword\"\n [class.nj-form-item--select]=\"isSelect\"\n [class.nj-form-item--visible]=\"isVisible\"\n [class.nj-form-item--textarea]=\"isMultiline\"\n [ngClass]=\"[getFormItemSizeClass(), additionalClass]\">\n <div class=\"nj-form-item__field-wrapper\" (click)=\"wrapperClick.emit($event)\">\n <ng-content select=\"[njFormField]\"></ng-content>\n <label class=\"nj-form-item__label\" [attr.for]=\"inputId\" [attr.aria-hidden]=\"isCustomSelect() ? 'true' : null\">\n <ng-content select=\"[njFormLabel]\"></ng-content>\n <span *ngIf=\"isRequired\" class=\"nj-form-item__required-asterisk\">*</span>\n </label>\n <nj-icon-button\n *ngIf=\"isPassword\"\n size=\"sm\"\n variant=\"tertiary\"\n [label]=\"passwordButtonLabel\"\n [icon]=\"iconName || 'visibility'\"\n (click)=\"toggleVisibility()\"\n [ariaPressed]=\"isVisible\"\n additionalClass=\"nj-form-item__password-button\"\n >\n </nj-icon-button>\n <nj-icon class=\"nj-form-item__icon\"\n *ngIf=\"!isPassword && !isMultiline && !hasCustomIcon && iconName\"\n [name]=\"iconName\"\n variant=\"inherit\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\">\n </nj-icon>\n <div class=\"nj-form-item__icon\" *ngIf=\"!isPassword && !isMultiline && hasCustomIcon\" [attr.tabindex]=\"isIconClickable ? 0 : null\"\n (click)=\"iconClickHandler($event)\" (keydown)=\"iconKeydownHandler($event)\">\n <ng-content select=\"[njFormCustomIcon]\"></ng-content>\n </div>\n <p *ngIf=\"isPassword\" class=\"nj-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ passwordNotice }}</p>\n <ng-content select=\"[njFormAdditionalContent]\"></ng-content>\n </div>\n <div class=\"nj-form-item__subscript\" *ngIf=\"hasError || hasSuccess || hasHint\" [attr.id]=\"getSubscriptId()\">\n <nj-icon *ngIf=\"hasError\" class=\"nj-form-item__subscript-icon\" name=\"warning\" size=\"inherit\" variant=\"inherit\"></nj-icon>\n <nj-icon *ngIf=\"hasSuccess && !hasError\" class=\"nj-form-item__subscript-icon\" name=\"check\" size=\"inherit\" variant=\"inherit\"></nj-icon>\n <ng-content select=\"[njFormSubscript]\"></ng-content>\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
}], propDecorators: { inputId: [{
type: Input
}], size: [{
type: Input
}], isFloatingLabel: [{
type: Input
}], isDisabled: [{
type: Input
}], isRequired: [{
type: Input
}], hasSuccess: [{
type: Input
}], hasError: [{
type: Input
}], hasHint: [{
type: Input
}], hasCustomIcon: [{
type: Input
}], isIconClickable: [{
type: Input
}], iconName: [{
type: Input
}], additionalClass: [{
type: Input
}], passwordButtonLabelShow: [{
type: Input
}], passwordButtonLabelHide: [{
type: Input
}], passwordNoticeIsVisible: [{
type: Input
}], passwordNoticeIsHidden: [{
type: Input
}], isSelect: [{
type: Input
}], iconClick: [{
type: Output
}], iconKeydown: [{
type: Output
}], wrapperClick: [{
type: Output
}], formField: [{
type: ContentChild,
args: [FormFieldDirective]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1pdGVtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2Zvcm0taXRlbS9mb3JtLWl0ZW0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvZm9ybS1pdGVtL2Zvcm0taXRlbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUVMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUN0RSxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxzQ0FBc0MsQ0FBQztBQUN6RSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7OztBQVlyRCxNQUFNLE9BQU8saUJBQWlCO0lBVDlCO1FBV21CLHNCQUFpQixHQUFHLGNBQWMsQ0FBQztRQXNCcEQ7O1dBRUc7UUFDSCxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBRWxCOztXQUVHO1FBQ0gsbUJBQWMsR0FBRyxFQUFFLENBQUM7UUFFcEI7O1dBRUc7UUFDSCx3QkFBbUIsR0FBRyxFQUFFLENBQUM7UUFFekI7O1dBRUc7UUFDSCxnQkFBVyxHQUFHLEtBQUssQ0FBQztRQU9wQjs7V0FFRztRQUNNLFNBQUksR0FBaUIsUUFBUSxDQUFDO1FBRXZDOztXQUVHO1FBQ00sb0JBQWUsR0FBRyxJQUFJLENBQUM7UUF3RGhDOztXQUVHO1FBQ00sb0JBQWUsR0FBRyxJQUFJLENBQUM7UUFPaEM7O1dBRUc7UUFDTSxvQkFBZSxHQUFXLEVBQUUsQ0FBQztRQThCdEM7O1dBRUc7UUFDTyxjQUFTLEdBQTZCLElB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QkFBaUI7bUdBQWpCLGlCQUFpQiwwdkJBb0xkLGtCQUFrQixnREM3TWxDLGdnRkErQ0EsZ0ZEeEJZLGFBQWEsaUZBQUUsbUJBQW1CLDBPQUFzQixZQUFZOzs0RkFFbkUsaUJBQWlCO2tCQVQ3QixTQUFTOytCQUNFLGNBQWMsbUJBR1AsdUJBQXVCLENBQUMsTUFBTSxpQkFDaEMsaUJBQWlCLENBQUMsSUFBSSxjQUN6QixJQUFJLFdBQ1AsQ0FBQyxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxDQUFDOzhCQWlEdEUsT0FBTztzQkFBZixLQUFLO2dCQUtHLElBQUk7c0JBQVosS0FBSztnQkFLRyxlQUFlO3NCQUF2QixLQUFLO2dCQUtHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBS0csVUFBVTtzQkFBbEIsS0FBSztnQkFNRixVQUFVO3NCQURiLEtBQUs7Z0JBY0YsUUFBUTtzQkFEWCxLQUFLO2dCQWNGLE9BQU87c0JBRFYsS0FBSztnQkFhRyxhQUFhO3NCQUFyQixLQUFLO2dCQUtHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBS0csUUFBUTtzQkFBaEIsS0FBSztnQkFLRyxlQUFlO3NCQUF2QixLQUFLO2dCQU1HLHVCQUF1QjtzQkFBL0IsS0FBSztnQkFNRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBS0csdUJBQXVCO3NCQUEvQixLQUFLO2dCQU1HLHNCQUFzQjtzQkFBOUIsS0FBSztnQkFLRyxRQUFRO3NCQUFoQixLQUFLO2dCQUtJLFNBQVM7c0JBQWxCLE1BQU07Z0JBT0csV0FBVztzQkFBcEIsTUFBTTtnQkFPRyxZQUFZO3NCQUFyQixNQUFNO2dCQU8yQixTQUFTO3NCQUExQyxZQUFZO3VCQUFDLGtCQUFrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tbW9uTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Rm9ybUZpZWxkRGlyZWN0aXZlfSBmcm9tICcuLi9mb3JtLWZpZWxkL2Zvcm0tZmllbGQuZGlyZWN0aXZlJztcbmltcG9ydCB7SWNvbkJ1dHRvbkNvbXBvbmVudH0gZnJvbSAnLi4vaWNvbi1idXR0b24vaWNvbi1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7SWNvbkNvbXBvbmVudH0gZnJvbSAnLi4vaWNvbi9pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQge0Zvcm1JdGVtU2l6ZX0gZnJvbSAnLi9mb3JtLWl0ZW0ubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduai1mb3JtLWl0ZW0nLFxuICB0ZW1wbGF0ZVVybDogJy4vZm9ybS1pdGVtLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZm9ybS1pdGVtLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbSWNvbkNvbXBvbmVudCwgSWNvbkJ1dHRvbkNvbXBvbmVudCwgRm9ybUZpZWxkRGlyZWN0aXZlLCBDb21tb25Nb2R1bGVdXG59KVxuZXhwb3J0IGNsYXNzIEZvcm1JdGVtQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBmb3JtSXRlbUNsYXNzTmFtZSA9ICduai1mb3JtLWl0ZW0nO1xuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBwcml2YXRlIF9oYXNFcnJvcjogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcHJpdmF0ZSBfaGFzU3VjY2VzczogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcHJpdmF0ZSBfaGFzSGludDogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNQYXNzd29yZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNWaXNpYmxlID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHBhc3N3b3JkTm90aWNlID0gJyc7XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHBhc3N3b3JkQnV0dG9uTGFiZWwgPSAnJztcblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNNdWx0aWxpbmUgPSBmYWxzZTtcblxuICAvKipcbiAgICogSW5wdXQgaWQgYW5kIGxhYmVsIGZvciBhdHRyaWJ1dGUsIG5lZWRlZCBmb3IgZm9jdXMgdG8gd29yayBwcm9wZXJseVxuICAgKi9cbiAgQElucHV0KCkgaW5wdXRJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBGb3JtIGl0ZW0gc2l6ZVxuICAgKi9cbiAgQElucHV0KCkgc2l6ZTogRm9ybUl0ZW1TaXplID0gJ21lZGl1bSc7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGZvcm0taXRlbSBsYWJlbCBpcyBmbG9hdGluZ1xuICAgKi9cbiAgQElucHV0KCkgaXNGbG9hdGluZ0xhYmVsID0gdHJ1ZTtcblxuICAvKipcbiAgICogV2hldGhlciBmb3JtLWl0ZW0gaXMgZGlzYWJsZWQgb3Igbm90XG4gICAqL1xuICBASW5wdXQoKSBpc0Rpc2FibGVkOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGZvcm0taXRlbSBpcyByZXF1aXJlZCBvciBub3RcbiAgICovXG4gIEBJbnB1dCgpIGlzUmVxdWlyZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZm9ybS1pdGVtIGlzIGluIHN1Y2Nlc3Mgc3RhdGVcbiAgICovXG4gIEBJbnB1dCgpXG4gIHNldCBoYXNTdWNjZXNzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5faGFzU3VjY2VzcyA9IHZhbHVlO1xuICAgIHRoaXMuc2V0QXJpYUF0dHJpYnV0ZXMoKTtcbiAgfVxuXG4gIGdldCBoYXNTdWNjZXNzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9oYXNTdWNjZXNzO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgZm9ybS1pdGVtIGlzIGluIGVycm9yIHN0YXRlXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgaGFzRXJyb3IodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9oYXNFcnJvciA9IHZhbHVlO1xuICAgIHRoaXMuc2V0QXJpYUF0dHJpYnV0ZXMoKTtcbiAgfVxuXG4gIGdldCBoYXNFcnJvcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGFzRXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZm9ybS1pdGVtIGhhcyBhIGhpbnQgc3Vic3RyaW5nXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgaGFzSGludCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2hhc0hpbnQgPSB2YWx1ZTtcbiAgICB0aGlzLnNldEFyaWFBdHRyaWJ1dGVzKCk7XG4gIH1cblxuICBnZXQgaGFzSGludCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGFzSGludDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBmb3JtLWl0ZW0gaGFzIGEgY3VzdG9tIGljb25cbiAgICovXG4gIEBJbnB1dCgpIGhhc0N1c3RvbUljb246IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGZvcm0taXRlbSdzIGljb24gKG9yIGN1c3RvbSBpY29uKSBpcyBjbGlja2FibGVcbiAgICovXG4gIEBJbnB1dCgpIGlzSWNvbkNsaWNrYWJsZSA9IHRydWU7XG5cbiAgLyoqXG4gICAqIE1hdGVyaWFsIGljb24gbmFtZVxuICAgKi9cbiAgQElucHV0KCkgaWNvbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBmb3JtLWl0ZW0gY3NzIGNsYXNzZXNcbiAgICovXG4gIEBJbnB1dCgpIGFkZGl0aW9uYWxDbGFzczogc3RyaW5nID0gJyc7XG5cbiAgLyoqXG4gICAqIExhYmVsIGZvciB0aGUgYnV0dG9uIHRvIHRvZ2dsZSBwYXNzd29yZCB2aXNpYmlsaXR5IHdoZW4gcGFzc3dvcmQgaXMgaGlkZGVuLlxuICAgKiBAZXhhbXBsZSBcIlNob3cgcGFzc3dvcmRcIlxuICAgKi9cbiAgQElucHV0KCkgcGFzc3dvcmRCdXR0b25MYWJlbFNob3c/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIExhYmVsIGZvciB0aGUgYnV0dG9uIHRvIHRvZ2dsZSBwYXNzd29yZCB2aXNpYmlsaXR5IHdoZW4gcGFzc3dvcmQgaXMgdmlzaWJsZS5cbiAgICogQGV4YW1wbGUgXCJIaWRlIHBhc3N3b3JkXCJcbiAgICovXG4gIEBJbnB1dCgpIHBhc3N3b3JkQnV0dG9uTGFiZWxIaWRlPzogc3RyaW5nO1xuICAvKipcbiAgICogTGFiZWwgdG8gYW5ub3VuY2Ugd2hlbiBwYXNzd29yZCBiZWNvbWVzIHZpc2libGUuXG4gICAqIEBleGFtcGxlIFwiUGFzc3dvcmQgaXMgdmlzaWJsZVwiXG4gICAqL1xuICBASW5wdXQoKSBwYXNzd29yZE5vdGljZUlzVmlzaWJsZT86IHN0cmluZztcblxuICAvKipcbiAgICogTGFiZWwgdG8gYW5ub3VuY2Ugd2hlbiBwYXNzd29yZCBiZWNvbWVzIGhpZGRlbi5cbiAgICogQGV4YW1wbGUgXCJQYXNzd29yZCBpcyBoaWRkZW5cIlxuICAgKi9cbiAgQElucHV0KCkgcGFzc3dvcmROb3RpY2VJc0hpZGRlbj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciBmb3JtLWl0ZW0gaXMgYSBzZWxlY3Qgb3Igbm90XG4gICAqL1xuICBASW5wdXQoKSBpc1NlbGVjdDogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3V0cHV0cyBpY29uIGNsaWNrXG4gICAqL1xuICBAT3V0cHV0KCkgaWNvbkNsaWNrOiBFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFxuICAgIE1vdXNlRXZlbnRcbiAgPigpO1xuXG4gIC8qKlxuICAgKiBPdXRwdXRzIGljb24ga2V5ZG93blxuICAgKi9cbiAgQE91dHB1dCgpIGljb25LZXlkb3duOiBFdmVudEVtaXR0ZXI8S2V5Ym9hcmRFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFxuICAgIEtleWJvYXJkRXZlbnRcbiAgPigpO1xuXG4gIC8qKlxuICAgKiBPdXRwdXRzIGljb24gY2xpY2tcbiAgICovXG4gIEBPdXRwdXQoKSB3cmFwcGVyQ2xpY2s6IEV2ZW50RW1pdHRlcjxNb3VzZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgTW91c2VFdmVudFxuICA+KCk7XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIEBDb250ZW50Q2hpbGQoRm9ybUZpZWxkRGlyZWN0aXZlKSBmb3JtRmllbGQ6IEZvcm1GaWVsZERpcmVjdGl2ZTtcblxuICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgY29uc3QgdGFnTmFtZSA9IHRoaXMuZm9ybUZpZWxkPy50YWdOYW1lPy50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMuaXNQYXNzd29yZCA9IHRoaXMuZm9ybUZpZWxkPy50eXBlID09PSAncGFzc3dvcmQnO1xuICAgIHRoaXMuaXNNdWx0aWxpbmUgPSB0YWdOYW1lID09PSAndGV4dGFyZWEnO1xuICAgIHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbCA9IHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbFNob3c7XG4gICAgdGhpcy5zZXRBcmlhQXR0cmlidXRlcygpO1xuICAgIGlmICh0aGlzLmlzUmVxdWlyZWQpIHtcbiAgICAgIHRoaXMuZm9ybUZpZWxkLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdyZXF1aXJlZCcsICdyZXF1aXJlZCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBpY29uQ2xpY2tIYW5kbGVyKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmlzSWNvbkNsaWNrYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmljb25DbGljay5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBpY29uS2V5ZG93bkhhbmRsZXIoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIXRoaXMuaXNJY29uQ2xpY2thYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaWNvbktleWRvd24uZW1pdChldmVudCk7XG4gIH1cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdG9nZ2xlVmlzaWJpbGl0eSgpIHtcbiAgICBpZiAodGhpcy5pc1Zpc2libGUpIHtcbiAgICAgIHRoaXMuZm9ybUZpZWxkLnR5cGUgPSAncGFzc3dvcmQnO1xuICAgICAgdGhpcy5wYXNzd29yZE5vdGljZSA9IHRoaXMucGFzc3dvcmROb3RpY2VJc0hpZGRlbjtcbiAgICAgIHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbCA9IHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbFNob3c7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZm9ybUZpZWxkLnR5cGUgPSAndGV4dCc7XG4gICAgICB0aGlzLnBhc3N3b3JkTm90aWNlID0gdGhpcy5wYXNzd29yZE5vdGljZUlzVmlzaWJsZTtcbiAgICAgIHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbCA9IHRoaXMucGFzc3dvcmRCdXR0b25MYWJlbEhpZGU7XG4gICAgfVxuICAgIHRoaXMuaXNWaXNpYmxlID0gIXRoaXMuaXNWaXNpYmxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGdldFN1YnNjcmlwdElkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMuaW5wdXRJZH0tc3Vic2NyaXB0YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBzZXRBcmlhQXR0cmlidXRlcygpIHtcbiAgICBpZiAodGhpcy5mb3JtRmllbGQ/LmVsZW1lbnQpIHtcbiAgICAgIGlmICh0aGlzLmhhc0Vycm9yKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWludmFsaWQnLCAndHJ1ZScpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5oYXNFcnJvciB8fCB0aGlzLmhhc1N1Y2Nlc3MgfHwgdGhpcy5oYXNIaW50KSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JywgdGhpcy5nZXRTdWJzY3JpcHRJZCgpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNDdXN0b21TZWxlY3QoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZm9ybUZpZWxkPy50eXBlO1xuICAgIHJldHVybiB0aGlzLmlzU2VsZWN0ICYmIHR5cGUgPT09ICd0ZXh0JztcbiAgfVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBnZXRGb3JtSXRlbVNpemVDbGFzcygpOiBzdHJpbmcge1xuICAgIGxldCBzaXplTW9kaWZpZXI6IHN0cmluZztcbiAgICBzd2l0Y2ggKHRoaXMuc2l6ZSkge1xuICAgICAgY2FzZSAnc21hbGwnOlxuICAgICAgICBzaXplTW9kaWZpZXIgPSAnc20nO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2xhcmdlJzpcbiAgICAgICAgc2l6ZU1vZGlmaWVyID0gJ2xnJztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd4bGFyZ2UnOlxuICAgICAgICBzaXplTW9kaWZpZXIgPSAneGwnO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gc2l6ZU1vZGlmaWVyID8gYCR7dGhpcy5mb3JtSXRlbUNsYXNzTmFtZX0tLSR7c2l6ZU1vZGlmaWVyfWAgOiAnJztcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm5qLWZvcm0taXRlbVwiXG4gICAgIFtjbGFzcy5uai1mb3JtLWl0ZW0tLXN0YXRpY109XCIhaXNGbG9hdGluZ0xhYmVsXCJcbiAgICAgW2NsYXNzLm5qLWZvcm0taXRlbS0tZGlzYWJsZWRdPVwiaXNEaXNhYmxlZFwiXG4gICAgIFtjbGFzcy5uai1mb3JtLWl0ZW0tLWVycm9yXT1cImhhc0Vycm9yXCJcbiAgICAgW2NsYXNzLm5qLWZvcm0taXRlbS0tc3VjY2Vzc109XCJoYXNTdWNjZXNzXCJcbiAgICAgW2NsYXNzLm5qLWZvcm0taXRlbS0tcGFzc3dvcmRdPVwiaXNQYXNzd29yZFwiXG4gICAgIFtjbGFzcy5uai1mb3JtLWl0ZW0tLXNlbGVjdF09XCJpc1NlbGVjdFwiXG4gICAgIFtjbGFzcy5uai1mb3JtLWl0ZW0tLXZpc2libGVdPVwiaXNWaXNpYmxlXCJcbiAgICAgW2NsYXNzLm5qLWZvcm0taXRlbS0tdGV4dGFyZWFdPVwiaXNNdWx0aWxpbmVcIlxuICAgICBbbmdDbGFzc109XCJbZ2V0Rm9ybUl0ZW1TaXplQ2xhc3MoKSwgYWRkaXRpb25hbENsYXNzXVwiPlxuICA8ZGl2IGNsYXNzPVwibmotZm9ybS1pdGVtX19maWVsZC13cmFwcGVyXCIgKGNsaWNrKT1cIndyYXBwZXJDbGljay5lbWl0KCRldmVudClcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbbmpGb3JtRmllbGRdXCI+PC9uZy1jb250ZW50PlxuICAgIDxsYWJlbCBjbGFzcz1cIm5qLWZvcm0taXRlbV9fbGFiZWxcIiBbYXR0ci5mb3JdPVwiaW5wdXRJZFwiIFthdHRyLmFyaWEtaGlkZGVuXT1cImlzQ3VzdG9tU2VsZWN0KCkgPyAndHJ1ZScgOiBudWxsXCI+XG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbbmpGb3JtTGFiZWxdXCI+PC9uZy1jb250ZW50PlxuICAgICAgPHNwYW4gKm5nSWY9XCJpc1JlcXVpcmVkXCIgY2xhc3M9XCJuai1mb3JtLWl0ZW1fX3JlcXVpcmVkLWFzdGVyaXNrXCI+Kjwvc3Bhbj5cbiAgICA8L2xhYmVsPlxuICAgIDxuai1pY29uLWJ1dHRvblxuICAgICAgKm5nSWY9XCJpc1Bhc3N3b3JkXCJcbiAgICAgIHNpemU9XCJzbVwiXG4gICAgICB2YXJpYW50PVwidGVydGlhcnlcIlxuICAgICAgW2xhYmVsXT1cInBhc3N3b3JkQnV0dG9uTGFiZWxcIlxuICAgICAgW2ljb25dPVwiaWNvbk5hbWUgfHwgJ3Zpc2liaWxpdHknXCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGVWaXNpYmlsaXR5KClcIlxuICAgICAgW2FyaWFQcmVzc2VkXT1cImlzVmlzaWJsZVwiXG4gICAgICBhZGRpdGlvbmFsQ2xhc3M9XCJuai1mb3JtLWl0ZW1fX3Bhc3N3b3JkLWJ1dHRvblwiXG4gICAgPlxuICAgIDwvbmotaWNvbi1idXR0b24+XG4gICAgPG5qLWljb24gY2xhc3M9XCJuai1mb3JtLWl0ZW1fX2ljb25cIlxuICAgICAgICAgICAgICpuZ0lmPVwiIWlzUGFzc3dvcmQgJiYgIWlzTXVsdGlsaW5lICYmICFoYXNDdXN0b21JY29uICYmIGljb25OYW1lXCJcbiAgICAgICAgICAgICBbbmFtZV09XCJpY29uTmFtZVwiXG4gICAgICAgICAgICAgdmFyaWFudD1cImluaGVyaXRcIlxuICAgICAgICAgICAgIChjbGljayk9XCJpY29uQ2xpY2tIYW5kbGVyKCRldmVudClcIlxuICAgICAgICAgICAgIChrZXlkb3duKT1cImljb25LZXlkb3duSGFuZGxlcigkZXZlbnQpXCI+XG4gICAgPC9uai1pY29uPlxuICAgIDxkaXYgY2xhc3M9XCJuai1mb3JtLWl0ZW1fX2ljb25cIiAqbmdJZj1cIiFpc1Bhc3N3b3JkICYmICFpc011bHRpbGluZSAmJiBoYXNDdXN0b21JY29uXCIgW2F0dHIudGFiaW5kZXhdPVwiaXNJY29uQ2xpY2thYmxlID8gMCA6IG51bGxcIlxuICAgICAgICAgKGNsaWNrKT1cImljb25DbGlja0hhbmRsZXIoJGV2ZW50KVwiIChrZXlkb3duKT1cImljb25LZXlkb3duSGFuZGxlcigkZXZlbnQpXCI+XG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbbmpGb3JtQ3VzdG9tSWNvbl1cIj48L25nLWNvbnRlbnQ+XG4gICAgPC9kaXY+XG4gICAgPHAgKm5nSWY9XCJpc1Bhc3N3b3JkXCIgY2xhc3M9XCJuai1zci1vbmx5XCIgYXJpYS1saXZlPVwicG9saXRlXCIgYXJpYS1hdG9taWM9XCJ0cnVlXCI+e3sgcGFzc3dvcmROb3RpY2UgfX08L3A+XG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW25qRm9ybUFkZGl0aW9uYWxDb250ZW50XVwiPjwvbmctY29udGVudD5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJuai1mb3JtLWl0ZW1fX3N1YnNjcmlwdFwiICpuZ0lmPVwiaGFzRXJyb3IgfHwgaGFzU3VjY2VzcyB8fCBoYXNIaW50XCIgW2F0dHIuaWRdPVwiZ2V0U3Vic2NyaXB0SWQoKVwiPlxuICAgIDxuai1pY29uICpuZ0lmPVwiaGFzRXJyb3JcIiBjbGFzcz1cIm5qLWZvcm0taXRlbV9fc3Vic2NyaXB0LWljb25cIiBuYW1lPVwid2FybmluZ1wiIHNpemU9XCJpbmhlcml0XCIgdmFyaWFudD1cImluaGVyaXRcIj48L25qLWljb24+XG4gICAgPG5qLWljb24gKm5nSWY9XCJoYXNTdWNjZXNzICYmICFoYXNFcnJvclwiIGNsYXNzPVwibmotZm9ybS1pdGVtX19zdWJzY3JpcHQtaWNvblwiIG5hbWU9XCJjaGVja1wiIHNpemU9XCJpbmhlcml0XCIgdmFyaWFudD1cImluaGVyaXRcIj48L25qLWljb24+XG4gICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW25qRm9ybVN1YnNjcmlwdF1cIj48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=