@alauda-fe/common
Version:
Alauda frontend team common codes.
273 lines • 37.6 kB
JavaScript
import { ButtonModule, IconModule, InputModule, TooltipModule, } from '@alauda/ui';
import { NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Injector, Input, Optional, } from '@angular/core';
import { ControlContainer, ReactiveFormsModule, } from '@angular/forms';
import { BaseResourceFormComponent } from 'ng-resource-form-util';
import { DUPLICATE_ERROR_KEY, DUPLICATION_JUSTIFY_STRATEGY, ValidateRowDuplicateService, } from '../../core/public-api';
import { DisabledContainerComponent } from '../../disabled-container/public-api';
import { EffectDirectiveModule } from '../../effect-directive/public-api';
import { ERRORS_MAPPER_MODULE } from '../../form/public-api';
import { TRANSLATE_MODULE, TranslateService } from '../../translate/public-api';
import { ArrayFormTableModule } from '../form/module';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "../../core/public-api";
import * as i3 from "../../translate/public-api";
import * as i4 from "../form/component";
import * as i5 from "@alauda/ui";
import * as i6 from "../../effect-directive/e2e-attribute-binding.directive";
import * as i7 from "../../form/errors-mapper/errors-mapper-component/component";
import * as i8 from "../../translate/translate.pipe";
function StringArrayFormTableComponent_ng_container_1_input_2_Template(rf, ctx) { if (rf & 1) {
const _r1 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "input", 7);
i0.ɵɵlistener("blur", function StringArrayFormTableComponent_ng_container_1_input_2_Template_input_blur_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onBlur()); });
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
const control_r4 = ctx_r2.$implicit;
const index_r5 = ctx_r2.index;
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵproperty("formControl", control_r4)("placeholder", ctx_r1.placeholder)("readonly", ctx_r1.isItemReadonly(index_r5));
} }
function StringArrayFormTableComponent_ng_container_1_div_3_Template(rf, ctx) { if (rf & 1) {
const _r6 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 8)(1, "textarea", 9);
i0.ɵɵlistener("blur", function StringArrayFormTableComponent_ng_container_1_div_3_Template_textarea_blur_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onBlur()); });
i0.ɵɵelementEnd()();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
const control_r4 = ctx_r2.$implicit;
const index_r5 = ctx_r2.index;
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵattribute("data-value", control_r4.value);
i0.ɵɵadvance();
i0.ɵɵproperty("placeholder", ctx_r1.placeholder)("formControl", control_r4)("readonly", ctx_r1.isItemReadonly(index_r5));
} }
function StringArrayFormTableComponent_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "td");
i0.ɵɵtemplate(2, StringArrayFormTableComponent_ng_container_1_input_2_Template, 1, 3, "input", 5)(3, StringArrayFormTableComponent_ng_container_1_div_3_Template, 2, 4, "div", 6);
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", !ctx_r1.multiLineValue);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", ctx_r1.multiLineValue);
} }
function StringArrayFormTableComponent_ng_container_2_Template(rf, ctx) { if (rf & 1) {
const _r7 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "button", 10);
i0.ɵɵlistener("click", function StringArrayFormTableComponent_ng_container_2_Template_button_click_1_listener() { const index_r8 = i0.ɵɵrestoreView(_r7).index; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.remove(index_r8)); });
i0.ɵɵelement(2, "aui-icon", 11);
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const index_r8 = ctx.index;
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("square", true)("plain", true)("disabled", ctx_r1.minLines && ctx_r1.minLines >= ctx_r1.length || ctx_r1.isItemReadonly(index_r8));
i0.ɵɵadvance();
i0.ɵɵproperty("auiTooltip", ctx_r1.isItemReadonly(index_r8) && ctx_r1.readonlyTooltip)("auiTooltipDisabled", !ctx_r1.isItemReadonly(index_r8));
} }
function StringArrayFormTableComponent_ng_container_3_td_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "td", 13);
i0.ɵɵelement(1, "acl-errors-mapper", 14);
i0.ɵɵelementEnd();
} if (rf & 2) {
const control_r9 = i0.ɵɵnextContext().$implicit;
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("errors", control_r9.errors)("errorsMapper", ctx_r1.errorMapper);
} }
function StringArrayFormTableComponent_ng_container_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, StringArrayFormTableComponent_ng_container_3_td_1_Template, 2, 2, "td", 12);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const control_r9 = ctx.$implicit;
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", control_r9.dirty || (ctx_r1.controlContainer == null ? null : ctx_r1.controlContainer.formDirective == null ? null : ctx_r1.controlContainer.formDirective.submitted));
} }
function StringArrayFormTableComponent_ng_container_4_Template(rf, ctx) { if (rf & 1) {
const _r10 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "acl-disabled-container", 15)(2, "button", 16);
i0.ɵɵlistener("click", function StringArrayFormTableComponent_ng_container_4_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.add(ctx_r1.length)); });
i0.ɵɵelement(3, "aui-icon", 17);
i0.ɵɵtext(4);
i0.ɵɵpipe(5, "translate");
i0.ɵɵelementEnd()();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r1 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("isAllowed", true)("isDisabled", ctx_r1.maxLines && ctx_r1.length >= ctx_r1.maxLines)("tooltip", ctx_r1.maxLinesTooltip);
i0.ɵɵadvance();
i0.ɵɵproperty("plain", true);
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(5, 5, "add"), " ");
} }
export class StringArrayFormTableComponent extends BaseResourceFormComponent {
set errorMapper(errorMapper) {
this._errorMapper = {
...this._errorMapper,
...errorMapper,
};
}
get errorMapper() {
return this._errorMapper;
}
constructor(injector, controlContainer, rowDup, translate) {
super(injector);
this.injector = injector;
this.controlContainer = controlContainer;
this.rowDup = rowDup;
this.translate = translate;
this.placeholder = '';
this.validators = [];
this.enableDuplicateCheck = false;
this.maxLines = 0;
this.maxLinesTooltip = '';
this.minLines = 0;
this.readonlyItems = [];
this._errorMapper = {
[DUPLICATE_ERROR_KEY]: this.translate.get('value_duplication'),
};
}
get length() {
return this.form.length;
}
ngOnChanges({ validators, enableDuplicateCheck }) {
if (validators?.currentValue && this.form) {
this.form.controls.forEach(formControl => {
formControl.setValidators(validators.currentValue);
// 避免动态增加或者移除 validators 的时候表单校验不生效
formControl.updateValueAndValidity();
});
}
if (enableDuplicateCheck?.currentValue !==
enableDuplicateCheck?.previousValue &&
this.form) {
this.form.controls.forEach(formControl => {
formControl[enableDuplicateCheck?.currentValue
? 'addValidators'
: 'removeValidators'](this.duplicateValidator);
formControl.updateValueAndValidity();
});
}
}
createForm() {
return this.fb.array([]);
}
adaptResourceModel(resource) {
if (!resource) {
return [];
}
return resource.sort((v1, v2) => {
const isReadonly1 = this.isReadonly(v1);
const isReadonly2 = this.isReadonly(v2);
if (isReadonly1 === isReadonly2) {
return 0;
}
return isReadonly1 ? -1 : 1;
});
}
getDefaultFormModel() {
return [];
}
add(index = this.form.length) {
this.form.insert(index, this.getOnFormArrayResizeFn()());
this.cdr.markForCheck();
}
remove(index) {
this.form.removeAt(index);
this.cdr.markForCheck();
}
getOnFormArrayResizeFn() {
this.duplicateValidator =
this.duplicateValidator ||
(this.enableDuplicateCheck &&
this.rowDup.createFormArrayValidator({
rowKeys: ['0'],
valueMapFn: (value) => value,
formArray: this.form,
strategy: DUPLICATION_JUSTIFY_STRATEGY.FULL,
}));
return () => this.fb.control('', [...(this.validators ?? []), this.duplicateValidator].filter(Boolean));
}
isItemReadonly(index) {
const control = this.form.controls[index];
return control.valid && this.isReadonly(control.value);
}
isReadonly(item) {
return this.readonlyItems.some(checkedItem => {
if (!checkedItem) {
return false;
}
if (typeof checkedItem === 'string') {
return checkedItem === item;
}
return checkedItem.test(item);
});
}
static { this.ɵfac = function StringArrayFormTableComponent_Factory(t) { return new (t || StringArrayFormTableComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i1.ControlContainer, 8), i0.ɵɵdirectiveInject(i2.ValidateRowDuplicateService), i0.ɵɵdirectiveInject(i3.TranslateService)); }; }
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: StringArrayFormTableComponent, selectors: [["acl-string-array-form-table"]], inputs: { multiLineValue: "multiLineValue", resourceName: "resourceName", resourceNameTranslated: "resourceNameTranslated", placeholder: "placeholder", validators: "validators", enableDuplicateCheck: "enableDuplicateCheck", errorMapper: "errorMapper", maxLines: "maxLines", maxLinesTooltip: "maxLinesTooltip", minLines: "minLines", readonlyItems: "readonlyItems", readonlyTooltip: "readonlyTooltip" }, standalone: true, features: [i0.ɵɵProvidersFeature([ValidateRowDuplicateService]), i0.ɵɵInheritDefinitionFeature, i0.ɵɵNgOnChangesFeature, i0.ɵɵStandaloneFeature], decls: 5, vars: 3, consts: [[3, "add", "remove", "resourceName", "resourceNameTranslated", "rows"], [4, "aclArrayFormTableRow"], [4, "aclArrayFormTableRowControl"], [4, "aclArrayFormTableRowError"], [4, "aclArrayFormTableFooter"], ["aui-input", "", 3, "formControl", "placeholder", "readonly", "blur", 4, "ngIf"], ["class", "textarea-wrapper", 4, "ngIf"], ["aui-input", "", 3, "blur", "formControl", "placeholder", "readonly"], [1, "textarea-wrapper"], ["aui-input", "", "rows", "1", 3, "blur", "placeholder", "formControl", "readonly"], ["aui-button", "text", "type", "button", 3, "click", "square", "plain", "disabled"], ["icon", "minus_circle", 3, "auiTooltip", "auiTooltipDisabled"], ["class", "acl-table-form-error-hint", "colspan", "2", 4, "ngIf"], ["colspan", "2", 1, "acl-table-form-error-hint"], [3, "errors", "errorsMapper"], [3, "isAllowed", "isDisabled", "tooltip"], ["aui-button", "primary", "type", "button", "size", "mini", 3, "click", "plain"], ["icon", "plus_circle"]], template: function StringArrayFormTableComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "acl-array-form-table", 0);
i0.ɵɵlistener("add", function StringArrayFormTableComponent_Template_acl_array_form_table_add_0_listener() { return ctx.add(ctx.form.length); })("remove", function StringArrayFormTableComponent_Template_acl_array_form_table_remove_0_listener($event) { return ctx.remove($event); });
i0.ɵɵtemplate(1, StringArrayFormTableComponent_ng_container_1_Template, 4, 2, "ng-container", 1)(2, StringArrayFormTableComponent_ng_container_2_Template, 3, 5, "ng-container", 2)(3, StringArrayFormTableComponent_ng_container_3_Template, 2, 1, "ng-container", 3)(4, StringArrayFormTableComponent_ng_container_4_Template, 6, 7, "ng-container", 4);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("resourceName", ctx.resourceName)("resourceNameTranslated", ctx.resourceNameTranslated)("rows", ctx.form.controls);
} }, dependencies: [ArrayFormTableModule, i4.ArrayFormTableComponent, i4.ArrayFormTableFooterDirective, i4.ArrayFormTableRowControlDirective, i4.ArrayFormTableRowDirective, i4.ArrayFormTableRowErrorDirective, NgIf,
InputModule, i5.InputComponent, ReactiveFormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.FormControlDirective, ButtonModule, i5.ButtonComponent, IconModule, i5.IconComponent, TooltipModule, i5.TooltipDirective, DisabledContainerComponent,
EffectDirectiveModule, i6.E2eAttributeBindingDirective, i7.ErrorsMapperComponent, i8.TranslatePipe], styles: ["[_nghost-%COMP%]{display:block;flex:1}[_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%]{display:grid;align-items:stretch}[_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%]:after, [_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]{grid-area:1/1;width:auto;padding:3px 5px;font:inherit;resize:none;max-height:252px}[_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%]:after{content:attr(data-value) \" \";visibility:hidden;white-space:pre-wrap}[_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%] textarea[_ngcontent-%COMP%]{overflow:auto;height:auto!important}[_nghost-%COMP%] .textarea-wrapper[_ngcontent-%COMP%]:focus-within textarea[_ngcontent-%COMP%]:focus{outline:none}[_nghost-%COMP%] acl-disabled-container[_ngcontent-%COMP%]{flex:1;display:flex}[_nghost-%COMP%] .acl-disabled-container{flex:1;display:flex}"], changeDetection: 0 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(StringArrayFormTableComponent, [{
type: Component,
args: [{ selector: 'acl-string-array-form-table', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
ArrayFormTableModule,
NgIf,
InputModule,
ReactiveFormsModule,
ButtonModule,
IconModule,
TooltipModule,
DisabledContainerComponent,
EffectDirectiveModule,
ERRORS_MAPPER_MODULE,
TRANSLATE_MODULE,
], providers: [ValidateRowDuplicateService], template: "<acl-array-form-table\n [resourceName]=\"resourceName\"\n [resourceNameTranslated]=\"resourceNameTranslated\"\n (add)=\"add(form.length)\"\n (remove)=\"remove($event)\"\n [rows]=\"form.controls\"\n>\n <!-- Input row -->\n <ng-container *aclArrayFormTableRow=\"let control; let index = index\">\n <td>\n <input\n *ngIf=\"!multiLineValue\"\n (blur)=\"onBlur()\"\n aui-input\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n [readonly]=\"isItemReadonly(index)\"\n />\n\n <div\n *ngIf=\"multiLineValue\"\n class=\"textarea-wrapper\"\n [attr.data-value]=\"control.value\"\n >\n <textarea\n (blur)=\"onBlur()\"\n [placeholder]=\"placeholder\"\n aui-input\n [formControl]=\"control\"\n [readonly]=\"isItemReadonly(index)\"\n rows=\"1\"\n ></textarea>\n </div>\n </td>\n </ng-container>\n\n <ng-container *aclArrayFormTableRowControl=\"let control; let index = index\">\n <button\n aui-button=\"text\"\n type=\"button\"\n [square]=\"true\"\n [plain]=\"true\"\n [disabled]=\"(minLines && minLines >= length) || isItemReadonly(index)\"\n (click)=\"remove(index)\"\n >\n <aui-icon\n icon=\"minus_circle\"\n [auiTooltip]=\"isItemReadonly(index) && readonlyTooltip\"\n [auiTooltipDisabled]=\"!isItemReadonly(index)\"\n ></aui-icon>\n </button>\n </ng-container>\n\n <!-- Input error row -->\n <ng-container *aclArrayFormTableRowError=\"let control\">\n <td\n class=\"acl-table-form-error-hint\"\n colspan=\"2\"\n *ngIf=\"control.dirty || $any(controlContainer?.formDirective)?.submitted\"\n >\n <acl-errors-mapper\n [errors]=\"control.errors\"\n [errorsMapper]=\"errorMapper\"\n ></acl-errors-mapper>\n </td>\n </ng-container>\n\n <ng-container *aclArrayFormTableFooter>\n <acl-disabled-container\n [isAllowed]=\"true\"\n [isDisabled]=\"maxLines && length >= maxLines\"\n [tooltip]=\"maxLinesTooltip\"\n >\n <button\n aui-button=\"primary\"\n type=\"button\"\n size=\"mini\"\n [plain]=\"true\"\n (click)=\"add(length)\"\n >\n <aui-icon icon=\"plus_circle\"></aui-icon>\n {{ 'add' | translate }}\n </button>\n </acl-disabled-container>\n </ng-container>\n</acl-array-form-table>\n", styles: [":host{display:block;flex:1}:host .textarea-wrapper{display:grid;align-items:stretch}:host .textarea-wrapper:after,:host .textarea-wrapper textarea{grid-area:1/1;width:auto;padding:3px 5px;font:inherit;resize:none;max-height:252px}:host .textarea-wrapper:after{content:attr(data-value) \" \";visibility:hidden;white-space:pre-wrap}:host .textarea-wrapper textarea{overflow:auto;height:auto!important}:host .textarea-wrapper:focus-within textarea:focus{outline:none}:host acl-disabled-container{flex:1;display:flex}:host ::ng-deep .acl-disabled-container{flex:1;display:flex}\n"] }]
}], () => [{ type: i0.Injector }, { type: i1.ControlContainer, decorators: [{
type: Optional
}] }, { type: i2.ValidateRowDuplicateService }, { type: i3.TranslateService }], { multiLineValue: [{
type: Input
}], resourceName: [{
type: Input
}], resourceNameTranslated: [{
type: Input
}], placeholder: [{
type: Input
}], validators: [{
type: Input
}], enableDuplicateCheck: [{
type: Input
}], errorMapper: [{
type: Input
}], maxLines: [{
type: Input
}], maxLinesTooltip: [{
type: Input
}], minLines: [{
type: Input
}], readonlyItems: [{
type: Input
}], readonlyTooltip: [{
type: Input
}] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(StringArrayFormTableComponent, { className: "StringArrayFormTableComponent" }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21tb24vc3JjL2FycmF5LWZvcm0tdGFibGUvc3RyaW5nLWFycmF5LWZvcm0vY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21tb24vc3JjL2FycmF5LWZvcm0tdGFibGUvc3RyaW5nLWFycmF5LWZvcm0vdGVtcGxhdGUuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsYUFBYSxHQUNkLE1BQU0sWUFBWSxDQUFDO0FBQ3BCLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsS0FBSyxFQUdMLFFBQVEsR0FFVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZ0JBQWdCLEVBRWhCLG1CQUFtQixHQUVwQixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRWxFLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsNEJBQTRCLEVBRTVCLDJCQUEyQixHQUM1QixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzdELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7Ozs7Ozs7SUN6QmhELGdDQU9FO0lBTEEsd01BQVEs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QUNwQixnQkFBZ0I7aUJBQ2pCLGFBQ1UsQ0FBQywyQkFBMkIsQ0FBQzs7c0JBd0RyQyxRQUFROzhGQWpEWCxjQUFjO2tCQURiLEtBQUs7WUFJTixZQUFZO2tCQURYLEtBQUs7WUFJTixzQkFBc0I7a0JBRHJCLEtBQUs7WUFJTixXQUFXO2tCQURWLEtBQUs7WUFJTixVQUFVO2tCQURULEtBQUs7WUFJTixvQkFBb0I7a0JBRG5CLEtBQUs7WUFJRixXQUFXO2tCQURkLEtBQUs7WUFZRyxRQUFRO2tCQUFoQixLQUFLO1lBRUcsZUFBZTtrQkFBdkIsS0FBSztZQUVHLFFBQVE7a0JBQWhCLEtBQUs7WUFHTixhQUFhO2tCQURaLEtBQUs7WUFJTixlQUFlO2tCQURkLEtBQUs7O2tGQTNDSyw2QkFBNkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBCdXR0b25Nb2R1bGUsXG4gIEljb25Nb2R1bGUsXG4gIElucHV0TW9kdWxlLFxuICBUb29sdGlwTW9kdWxlLFxufSBmcm9tICdAYWxhdWRhL3VpJztcbmltcG9ydCB7IE5nSWYgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIFNpbXBsZUNoYW5nZXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQ29udHJvbENvbnRhaW5lcixcbiAgRm9ybUFycmF5LFxuICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICBWYWxpZGF0b3JGbixcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQmFzZVJlc291cmNlRm9ybUNvbXBvbmVudCB9IGZyb20gJ25nLXJlc291cmNlLWZvcm0tdXRpbCc7XG5cbmltcG9ydCB7XG4gIERVUExJQ0FURV9FUlJPUl9LRVksXG4gIERVUExJQ0FUSU9OX0pVU1RJRllfU1RSQVRFR1ksXG4gIFN0cmluZ01hcCxcbiAgVmFsaWRhdGVSb3dEdXBsaWNhdGVTZXJ2aWNlLFxufSBmcm9tICcuLi8uLi9jb3JlL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgRGlzYWJsZWRDb250YWluZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9kaXNhYmxlZC1jb250YWluZXIvcHVibGljLWFwaSc7XG5pbXBvcnQgeyBFZmZlY3REaXJlY3RpdmVNb2R1bGUgfSBmcm9tICcuLi8uLi9lZmZlY3QtZGlyZWN0aXZlL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgRVJST1JTX01BUFBFUl9NT0RVTEUgfSBmcm9tICcuLi8uLi9mb3JtL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgVFJBTlNMQVRFX01PRFVMRSwgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3RyYW5zbGF0ZS9wdWJsaWMtYXBpJztcbmltcG9ydCB7IEFycmF5Rm9ybVRhYmxlTW9kdWxlIH0gZnJvbSAnLi4vZm9ybS9tb2R1bGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhY2wtc3RyaW5nLWFycmF5LWZvcm0tdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGVtcGxhdGUuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3N0eWxlcy5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQXJyYXlGb3JtVGFibGVNb2R1bGUsXG4gICAgTmdJZixcbiAgICBJbnB1dE1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBJY29uTW9kdWxlLFxuICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgRGlzYWJsZWRDb250YWluZXJDb21wb25lbnQsXG4gICAgRWZmZWN0RGlyZWN0aXZlTW9kdWxlLFxuICAgIEVSUk9SU19NQVBQRVJfTU9EVUxFLFxuICAgIFRSQU5TTEFURV9NT0RVTEUsXG4gIF0sXG4gIHByb3ZpZGVyczogW1ZhbGlkYXRlUm93RHVwbGljYXRlU2VydmljZV0sXG59KVxuZXhwb3J0IGNsYXNzIFN0cmluZ0FycmF5Rm9ybVRhYmxlQ29tcG9uZW50XG4gIGV4dGVuZHMgQmFzZVJlc291cmNlRm9ybUNvbXBvbmVudDxzdHJpbmdbXSwgc3RyaW5nW10sIEZvcm1BcnJheT5cbiAgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlc1xue1xuICBASW5wdXQoKVxuICBtdWx0aUxpbmVWYWx1ZTogYm9vbGVhbjtcblxuICBASW5wdXQoKVxuICByZXNvdXJjZU5hbWU6IHN0cmluZztcblxuICBASW5wdXQoKVxuICByZXNvdXJjZU5hbWVUcmFuc2xhdGVkOiBzdHJpbmc7XG5cbiAgQElucHV0KClcbiAgcGxhY2Vob2xkZXIgPSAnJztcblxuICBASW5wdXQoKVxuICB2YWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gW107XG5cbiAgQElucHV0KClcbiAgZW5hYmxlRHVwbGljYXRlQ2hlY2sgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBzZXQgZXJyb3JNYXBwZXIoZXJyb3JNYXBwZXI6IFN0cmluZ01hcCkge1xuICAgIHRoaXMuX2Vycm9yTWFwcGVyID0ge1xuICAgICAgLi4udGhpcy5fZXJyb3JNYXBwZXIsXG4gICAgICAuLi5lcnJvck1hcHBlcixcbiAgICB9O1xuICB9XG5cbiAgZ2V0IGVycm9yTWFwcGVyKCkge1xuICAgIHJldHVybiB0aGlzLl9lcnJvck1hcHBlcjtcbiAgfVxuXG4gIEBJbnB1dCgpIG1heExpbmVzID0gMDtcblxuICBASW5wdXQoKSBtYXhMaW5lc1Rvb2x0aXAgPSAnJztcblxuICBASW5wdXQoKSBtaW5MaW5lcyA9IDA7XG5cbiAgQElucHV0KClcbiAgcmVhZG9ubHlJdGVtczogQXJyYXk8c3RyaW5nIHwgUmVnRXhwPiA9IFtdO1xuXG4gIEBJbnB1dCgpXG4gIHJlYWRvbmx5VG9vbHRpcDogc3RyaW5nO1xuXG4gIHByaXZhdGUgX2Vycm9yTWFwcGVyOiBTdHJpbmdNYXAgPSB7XG4gICAgW0RVUExJQ0FURV9FUlJPUl9LRVldOiB0aGlzLnRyYW5zbGF0ZS5nZXQoJ3ZhbHVlX2R1cGxpY2F0aW9uJyksXG4gIH07XG5cbiAgcHJpdmF0ZSBkdXBsaWNhdGVWYWxpZGF0b3I6IFZhbGlkYXRvckZuO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBvdmVycmlkZSBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgQE9wdGlvbmFsKCkgcHVibGljIHJlYWRvbmx5IGNvbnRyb2xDb250YWluZXI6IENvbnRyb2xDb250YWluZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSByb3dEdXA6IFZhbGlkYXRlUm93RHVwbGljYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IpO1xuICB9XG5cbiAgZ2V0IGxlbmd0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtLmxlbmd0aDtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKHsgdmFsaWRhdG9ycywgZW5hYmxlRHVwbGljYXRlQ2hlY2sgfTogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICh2YWxpZGF0b3JzPy5jdXJyZW50VmFsdWUgJiYgdGhpcy5mb3JtKSB7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMuZm9yRWFjaChmb3JtQ29udHJvbCA9PiB7XG4gICAgICAgIGZvcm1Db250cm9sLnNldFZhbGlkYXRvcnModmFsaWRhdG9ycy5jdXJyZW50VmFsdWUpO1xuICAgICAgICAvLyDpgb/lhY3liqjmgIHlop7liqDmiJbogIXnp7vpmaQgdmFsaWRhdG9ycyDnmoTml7blgJnooajljZXmoKHpqozkuI3nlJ/mlYhcbiAgICAgICAgZm9ybUNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGVuYWJsZUR1cGxpY2F0ZUNoZWNrPy5jdXJyZW50VmFsdWUgIT09XG4gICAgICAgIGVuYWJsZUR1cGxpY2F0ZUNoZWNrPy5wcmV2aW91c1ZhbHVlICYmXG4gICAgICB0aGlzLmZvcm1cbiAgICApIHtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9scy5mb3JFYWNoKGZvcm1Db250cm9sID0+IHtcbiAgICAgICAgZm9ybUNvbnRyb2xbXG4gICAgICAgICAgZW5hYmxlRHVwbGljYXRlQ2hlY2s/LmN1cnJlbnRWYWx1ZVxuICAgICAgICAgICAgPyAnYWRkVmFsaWRhdG9ycydcbiAgICAgICAgICAgIDogJ3JlbW92ZVZhbGlkYXRvcnMnXG4gICAgICAgIF0odGhpcy5kdXBsaWNhdGVWYWxpZGF0b3IpO1xuICAgICAgICBmb3JtQ29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGVGb3JtKCkge1xuICAgIHJldHVybiB0aGlzLmZiLmFycmF5KFtdKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFkYXB0UmVzb3VyY2VNb2RlbChyZXNvdXJjZTogc3RyaW5nW10pIHtcbiAgICBpZiAoIXJlc291cmNlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc291cmNlLnNvcnQoKHYxOiBzdHJpbmcsIHYyOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGlzUmVhZG9ubHkxID0gdGhpcy5pc1JlYWRvbmx5KHYxKTtcbiAgICAgIGNvbnN0IGlzUmVhZG9ubHkyID0gdGhpcy5pc1JlYWRvbmx5KHYyKTtcblxuICAgICAgaWYgKGlzUmVhZG9ubHkxID09PSBpc1JlYWRvbmx5Mikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpc1JlYWRvbmx5MSA/IC0xIDogMTtcbiAgICB9KTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldERlZmF1bHRGb3JtTW9kZWwoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGFkZChpbmRleCA9IHRoaXMuZm9ybS5sZW5ndGgpIHtcbiAgICB0aGlzLmZvcm0uaW5zZXJ0KGluZGV4LCB0aGlzLmdldE9uRm9ybUFycmF5UmVzaXplRm4oKSgpKTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHJlbW92ZShpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5mb3JtLnJlbW92ZUF0KGluZGV4KTtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldE9uRm9ybUFycmF5UmVzaXplRm4oKSB7XG4gICAgdGhpcy5kdXBsaWNhdGVWYWxpZGF0b3IgPVxuICAgICAgdGhpcy5kdXBsaWNhdGVWYWxpZGF0b3IgfHxcbiAgICAgICh0aGlzLmVuYWJsZUR1cGxpY2F0ZUNoZWNrICYmXG4gICAgICAgIHRoaXMucm93RHVwLmNyZWF0ZUZvcm1BcnJheVZhbGlkYXRvcih7XG4gICAgICAgICAgcm93S2V5czogWycwJ10sXG4gICAgICAgICAgdmFsdWVNYXBGbjogKHZhbHVlOiBzdHJpbmcpID0+IHZhbHVlLFxuICAgICAgICAgIGZvcm1BcnJheTogdGhpcy5mb3JtLFxuICAgICAgICAgIHN0cmF0ZWd5OiBEVVBMSUNBVElPTl9KVVNUSUZZX1NUUkFURUdZLkZVTEwsXG4gICAgICAgIH0pKTtcblxuICAgIHJldHVybiAoKSA9PlxuICAgICAgdGhpcy5mYi5jb250cm9sKFxuICAgICAgICAnJyxcbiAgICAgICAgWy4uLih0aGlzLnZhbGlkYXRvcnMgPz8gW10pLCB0aGlzLmR1cGxpY2F0ZVZhbGlkYXRvcl0uZmlsdGVyKEJvb2xlYW4pLFxuICAgICAgKTtcbiAgfVxuXG4gIGlzSXRlbVJlYWRvbmx5KGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmNvbnRyb2xzW2luZGV4XTtcbiAgICByZXR1cm4gY29udHJvbC52YWxpZCAmJiB0aGlzLmlzUmVhZG9ubHkoY29udHJvbC52YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIGlzUmVhZG9ubHkoaXRlbTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZG9ubHlJdGVtcy5zb21lKGNoZWNrZWRJdGVtID0+IHtcbiAgICAgIGlmICghY2hlY2tlZEl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjaGVja2VkSXRlbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGNoZWNrZWRJdGVtID09PSBpdGVtO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2hlY2tlZEl0ZW0udGVzdChpdGVtKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPGFjbC1hcnJheS1mb3JtLXRhYmxlXG4gIFtyZXNvdXJjZU5hbWVdPVwicmVzb3VyY2VOYW1lXCJcbiAgW3Jlc291cmNlTmFtZVRyYW5zbGF0ZWRdPVwicmVzb3VyY2VOYW1lVHJhbnNsYXRlZFwiXG4gIChhZGQpPVwiYWRkKGZvcm0ubGVuZ3RoKVwiXG4gIChyZW1vdmUpPVwicmVtb3ZlKCRldmVudClcIlxuICBbcm93c109XCJmb3JtLmNvbnRyb2xzXCJcbj5cbiAgPCEtLSBJbnB1dCByb3cgLS0+XG4gIDxuZy1jb250YWluZXIgKmFjbEFycmF5Rm9ybVRhYmxlUm93PVwibGV0IGNvbnRyb2w7IGxldCBpbmRleCA9IGluZGV4XCI+XG4gICAgPHRkPlxuICAgICAgPGlucHV0XG4gICAgICAgICpuZ0lmPVwiIW11bHRpTGluZVZhbHVlXCJcbiAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgICBhdWktaW5wdXRcbiAgICAgICAgW2Zvcm1Db250cm9sXT1cImNvbnRyb2xcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgICBbcmVhZG9ubHldPVwiaXNJdGVtUmVhZG9ubHkoaW5kZXgpXCJcbiAgICAgIC8+XG5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nSWY9XCJtdWx0aUxpbmVWYWx1ZVwiXG4gICAgICAgIGNsYXNzPVwidGV4dGFyZWEtd3JhcHBlclwiXG4gICAgICAgIFthdHRyLmRhdGEtdmFsdWVdPVwiY29udHJvbC52YWx1ZVwiXG4gICAgICA+XG4gICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICAgICAgICAgIGF1aS1pbnB1dFxuICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjb250cm9sXCJcbiAgICAgICAgICBbcmVhZG9ubHldPVwiaXNJdGVtUmVhZG9ubHkoaW5kZXgpXCJcbiAgICAgICAgICByb3dzPVwiMVwiXG4gICAgICAgID48L3RleHRhcmVhPlxuICAgICAgPC9kaXY+XG4gICAgPC90ZD5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqYWNsQXJyYXlGb3JtVGFibGVSb3dDb250cm9sPVwibGV0IGNvbnRyb2w7IGxldCBpbmRleCA9IGluZGV4XCI+XG4gICAgPGJ1dHRvblxuICAgICAgYXVpLWJ1dHRvbj1cInRleHRcIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbc3F1YXJlXT1cInRydWVcIlxuICAgICAgW3BsYWluXT1cInRydWVcIlxuICAgICAgW2Rpc2FibGVkXT1cIihtaW5MaW5lcyAmJiBtaW5MaW5lcyA+PSBsZW5ndGgpIHx8IGlzSXRlbVJlYWRvbmx5KGluZGV4KVwiXG4gICAgICAoY2xpY2spPVwicmVtb3ZlKGluZGV4KVwiXG4gICAgPlxuICAgICAgPGF1aS1pY29uXG4gICAgICAgIGljb249XCJtaW51c19jaXJjbGVcIlxuICAgICAgICBbYXVpVG9vbHRpcF09XCJpc0l0ZW1SZWFkb25seShpbmRleCkgJiYgcmVhZG9ubHlUb29sdGlwXCJcbiAgICAgICAgW2F1aVRvb2x0aXBEaXNhYmxlZF09XCIhaXNJdGVtUmVhZG9ubHkoaW5kZXgpXCJcbiAgICAgID48L2F1aS1pY29uPlxuICAgIDwvYnV0dG9uPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8IS0tIElucHV0IGVycm9yIHJvdyAtLT5cbiAgPG5nLWNvbnRhaW5lciAqYWNsQXJyYXlGb3JtVGFibGVSb3dFcnJvcj1cImxldCBjb250cm9sXCI+XG4gICAgPHRkXG4gICAgICBjbGFzcz1cImFjbC10YWJsZS1mb3JtLWVycm9yLWhpbnRcIlxuICAgICAgY29sc3Bhbj1cIjJcIlxuICAgICAgKm5nSWY9XCJjb250cm9sLmRpcnR5IHx8ICRhbnkoY29udHJvbENvbnRhaW5lcj8uZm9ybURpcmVjdGl2ZSk/LnN1Ym1pdHRlZFwiXG4gICAgPlxuICAgICAgPGFjbC1lcnJvcnMtbWFwcGVyXG4gICAgICAgIFtlcnJvcnNdPVwiY29udHJvbC5lcnJvcnNcIlxuICAgICAgICBbZXJyb3JzTWFwcGVyXT1cImVycm9yTWFwcGVyXCJcbiAgICAgID48L2FjbC1lcnJvcnMtbWFwcGVyPlxuICAgIDwvdGQ+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKmFjbEFycmF5Rm9ybVRhYmxlRm9vdGVyPlxuICAgIDxhY2wtZGlzYWJsZWQtY29udGFpbmVyXG4gICAgICBbaXNBbGxvd2VkXT1cInRydWVcIlxuICAgICAgW2lzRGlzYWJsZWRdPVwibWF4TGluZXMgJiYgbGVuZ3RoID49IG1heExpbmVzXCJcbiAgICAgIFt0b29sdGlwXT1cIm1heExpbmVzVG9vbHRpcFwiXG4gICAgPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBhdWktYnV0dG9uPVwicHJpbWFyeVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBzaXplPVwibWluaVwiXG4gICAgICAgIFtwbGFpbl09XCJ0cnVlXCJcbiAgICAgICAgKGNsaWNrKT1cImFkZChsZW5ndGgpXCJcbiAgICAgID5cbiAgICAgICAgPGF1aS1pY29uIGljb249XCJwbHVzX2NpcmNsZVwiPjwvYXVpLWljb24+XG4gICAgICAgIHt7ICdhZGQnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2FjbC1kaXNhYmxlZC1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC9hY2wtYXJyYXktZm9ybS10YWJsZT5cbiJdfQ==