@alauda-fe/common
Version:
Alauda frontend team common codes.
239 lines • 33.7 kB
JavaScript
import { ButtonModule, IconModule, InputModule } from '@alauda/ui';
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, forwardRef } from '@angular/core';
import { FormsModule, NG_VALIDATORS, NG_VALUE_ACCESSOR, } from '@angular/forms';
import { mergeLeft } from 'ramda';
import { CalcPipe, K8S_RESOURCE_LABEL_KEY_NAME_PATTERN, K8S_RESOURCE_LABEL_KEY_PREFIX_PATTERN, K8S_RESOURCE_LABEL_VALUE_PATTERN, PurePipe, createNestedFormControl, } from '../../core/public-api';
import { EffectDirectiveModule } from '../../effect-directive/module';
import { TranslateModule } from '../../translate/public-api';
import { ErrorsMapperModule } from '../errors-mapper/public-api';
import { ValidatorsModule } from '../validators/public-api';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../../translate/translate.pipe";
import * as i3 from "@angular/forms";
import * as i4 from "@alauda/ui";
import * as i5 from "../validators/function-validator.directive";
import * as i6 from "../validators/maxlength-minlength-validator.directive";
import * as i7 from "../errors-mapper/errors-mapper-component/component";
import * as i8 from "../../effect-directive/e2e-attribute-binding.directive";
import * as i9 from "../../effect-directive/validators.directive";
const _c0 = a0 => ({ key: a0 });
const _c1 = a0 => ({ duplicated: a0 });
function LabelsEditorComponent_tr_12_acl_errors_mapper_5_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "acl-errors-mapper", 20);
i0.ɵɵpipe(1, "translate");
} if (rf & 2) {
i0.ɵɵnextContext();
const key_r4 = i0.ɵɵreference(3);
i0.ɵɵproperty("errors", key_r4.errors)("errorsMapper", i0.ɵɵpureFunction1(7, _c1, i0.ɵɵpipeBind2(1, 2, "label_key_already_exists", i0.ɵɵpureFunction1(5, _c0, key_r4.errors == null ? null : key_r4.errors.duplicated))));
} }
function LabelsEditorComponent_tr_12_acl_errors_mapper_9_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "acl-errors-mapper", 21);
} if (rf & 2) {
i0.ɵɵnextContext();
const value_r5 = i0.ɵɵreference(8);
i0.ɵɵproperty("errors", value_r5.errors);
} }
function LabelsEditorComponent_tr_12_Template(rf, ctx) { if (rf & 1) {
const _r1 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "tr")(1, "td")(2, "input", 13, 0);
i0.ɵɵpipe(4, "calc");
i0.ɵɵlistener("ngModelChange", function LabelsEditorComponent_tr_12_Template_input_ngModelChange_2_listener($event) { const index_r2 = i0.ɵɵrestoreView(_r1).index; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.editLabel(index_r2, "key", $event)); });
i0.ɵɵelementEnd();
i0.ɵɵtemplate(5, LabelsEditorComponent_tr_12_acl_errors_mapper_5_Template, 2, 9, "acl-errors-mapper", 14);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(6, "td")(7, "input", 15, 1);
i0.ɵɵlistener("ngModelChange", function LabelsEditorComponent_tr_12_Template_input_ngModelChange_7_listener($event) { const index_r2 = i0.ɵɵrestoreView(_r1).index; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.editLabel(index_r2, "value", $event)); });
i0.ɵɵelementEnd();
i0.ɵɵtemplate(9, LabelsEditorComponent_tr_12_acl_errors_mapper_9_Template, 1, 1, "acl-errors-mapper", 16);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(10, "td", 17)(11, "button", 18);
i0.ɵɵlistener("click", function LabelsEditorComponent_tr_12_Template_button_click_11_listener() { const index_r2 = i0.ɵɵrestoreView(_r1).index; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.removeLabel(index_r2)); });
i0.ɵɵelement(12, "aui-icon", 19);
i0.ɵɵelementEnd()()();
} if (rf & 2) {
const label_r6 = ctx.$implicit;
const index_r2 = ctx.index;
const key_r4 = i0.ɵɵreference(3);
const value_r5 = i0.ɵɵreference(8);
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵclassProp("duplicated", ctx_r2.duplicatedRows[index_r2]);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngModel", label_r6.key)("aclValidateFn", i0.ɵɵpipeBind3(4, 10, ctx_r2.validateLabelKey, ctx_r2.duplicatedRows, index_r2));
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngIf", ctx_r2.submitted || key_r4.dirty);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngModel", label_r6.value)("pattern", ctx_r2.K8S_RESOURCE_LABEL_VALUE_PATTERN.pattern);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx_r2.submitted || value_r5.dirty);
i0.ɵɵadvance(2);
i0.ɵɵproperty("square", true)("plain", true);
} }
function LabelsEditorComponent_tr_13_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "tr")(1, "td", 9)(2, "div", 22);
i0.ɵɵtext(3);
i0.ɵɵpipe(4, "translate");
i0.ɵɵelementEnd()()();
} if (rf & 2) {
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(4, 1, "no_label"));
} }
export class LabelsEditorComponent extends createNestedFormControl() {
constructor() {
super(...arguments);
this.K8S_RESOURCE_LABEL_VALUE_PATTERN = K8S_RESOURCE_LABEL_VALUE_PATTERN;
this.duplicatedRows = {};
this.validateLabelKey = (duplicatedRows, index) => (control) => mergeLeft(this.keyDuplicated(duplicatedRows, index)(control), this.keyPattern(control));
}
addLabel() {
this.model.push({ key: '', value: '' });
}
editLabel(index, key, value) {
this.model[index][key] = value;
this.emitModel();
}
removeLabel(index) {
this.model.splice(index, 1);
this.emitModel();
}
writeValue(value) {
super.writeValue(value);
this.checkDuplicatedRows();
}
emitValue(value) {
super.emitValue(value);
this.checkDuplicatedRows();
}
valueIn(value) {
return Object.entries(value ?? {}).map(([key, value]) => ({
key,
value,
}));
}
modelOut(model) {
return model.reduce((acc, { key, value }) => {
const k = key.trim();
if (k) {
acc[k] = value.trim();
}
return acc;
}, {});
}
checkDuplicatedRows() {
this.duplicatedRows = (this.model ?? []).reduce((acc, { key }, index, labels) => {
if (!key) {
return acc;
}
for (const [i, label] of labels.entries()) {
if (i !== index && label.key === key) {
acc[index] = true;
break;
}
}
return acc;
}, {});
}
keyPattern(control) {
if (!control.value) {
return null;
}
const [name, prefix = ''] = control.value.split('/').reverse();
if (name.length > 63 ||
K8S_RESOURCE_LABEL_KEY_NAME_PATTERN.pattern.test(name) === false) {
return { pattern: true };
}
if (!!prefix &&
(prefix.length > 253 ||
K8S_RESOURCE_LABEL_KEY_PREFIX_PATTERN.pattern.test(prefix) === false)) {
return { pattern: true };
}
return null;
}
keyDuplicated(duplicatedRows, index) {
return (control) => {
const key = control.value;
if (duplicatedRows[index]) {
return { duplicated: key };
}
return null;
};
}
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵLabelsEditorComponent_BaseFactory; return function LabelsEditorComponent_Factory(t) { return (ɵLabelsEditorComponent_BaseFactory || (ɵLabelsEditorComponent_BaseFactory = i0.ɵɵgetInheritedFactory(LabelsEditorComponent)))(t || LabelsEditorComponent); }; })(); }
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: LabelsEditorComponent, selectors: [["acl-labels-editor"]], standalone: true, features: [i0.ɵɵProvidersFeature([
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => LabelsEditorComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => LabelsEditorComponent),
multi: true,
},
]), i0.ɵɵInheritDefinitionFeature, i0.ɵɵStandaloneFeature], decls: 22, vars: 15, consts: [["key", "ngModel"], ["value", "ngModel"], [1, "acl-array-form-table", "mp-sticky-table-header", "mp-sticky-table-actions"], ["required", "", "width", "50%"], ["width", "50%"], [2, "min-width", "44px"], [3, "duplicated", 4, "ngFor", "ngForOf"], [4, "ngIf"], [1, "acl-array-form-table--row-action"], ["colspan", "100"], [1, "acl-array-form-table__bottom-control-buttons"], ["aui-button", "primary", "size", "mini", "type", "button", 3, "click", "plain", "disabled"], ["icon", "plus_circle"], ["aui-input", "", "size", "small", "name", "key", "required", "", 3, "ngModelChange", "ngModel", "aclValidateFn"], [3, "errors", "errorsMapper", 4, "ngIf"], ["aui-input", "", "size", "small", "name", "value", "aclMaxlength", "63", 3, "ngModelChange", "ngModel", "pattern"], [3, "errors", 4, "ngIf"], [1, "acl-array-form-table__action-col"], ["aui-button", "text", "size", "small", "type", "button", 3, "click", "square", "plain"], ["icon", "minus_circle"], [3, "errors", "errorsMapper"], [3, "errors"], [1, "placeholder"]], template: function LabelsEditorComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "table", 2)(1, "thead")(2, "tr")(3, "th", 3)(4, "span");
i0.ɵɵtext(5);
i0.ɵɵpipe(6, "translate");
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(7, "th", 4);
i0.ɵɵtext(8);
i0.ɵɵpipe(9, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelement(10, "th", 5);
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(11, "tbody");
i0.ɵɵtemplate(12, LabelsEditorComponent_tr_12_Template, 13, 14, "tr", 6)(13, LabelsEditorComponent_tr_13_Template, 5, 3, "tr", 7);
i0.ɵɵelementStart(14, "tr", 8)(15, "td", 9)(16, "div", 10)(17, "button", 11);
i0.ɵɵlistener("click", function LabelsEditorComponent_Template_button_click_17_listener() { return ctx.addLabel(); });
i0.ɵɵelement(18, "aui-icon", 12);
i0.ɵɵelementStart(19, "span");
i0.ɵɵtext(20);
i0.ɵɵpipe(21, "translate");
i0.ɵɵelementEnd()()()()()()();
} if (rf & 2) {
i0.ɵɵclassProp("submitted", ctx.submitted);
i0.ɵɵadvance(5);
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(6, 9, "key"));
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(9, 11, "value"));
i0.ɵɵadvance(4);
i0.ɵɵproperty("ngForOf", ctx.model);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", !(ctx.model == null ? null : ctx.model.length));
i0.ɵɵadvance(4);
i0.ɵɵproperty("plain", true)("disabled", (ctx.model == null ? null : ctx.model.length) >= 50);
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(21, 13, "add"), " ");
} }, dependencies: [CommonModule, i1.NgForOf, i1.NgIf, TranslateModule, i2.TranslatePipe, FormsModule, i3.DefaultValueAccessor, i3.NgControlStatus, i3.RequiredValidator, i3.PatternValidator, i3.NgModel, InputModule, i4.InputComponent, ValidatorsModule, i5.FunctionValidatorDirective, i6.MaxLengthValidatorDirective, ErrorsMapperModule, i7.ErrorsMapperComponent, IconModule, i4.IconComponent, ButtonModule, i4.ButtonComponent, CalcPipe,
EffectDirectiveModule, i8.E2eAttributeBindingDirective, i9.ValidatorsDirective], styles: ["[_nghost-%COMP%] {display:block;width:100%}[_nghost-%COMP%] .acl-array-form-table tbody td{vertical-align:top;line-height:var(--aui-inline-height-s)}[_nghost-%COMP%] .acl-array-form-table tbody tr .placeholder{text-align:center;color:rgb(var(--aui-color-help-text))}[_nghost-%COMP%] .acl-array-form-table tbody tr.duplicated{background-color:rgb(var(--aui-color-r-7))}"], changeDetection: 0 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LabelsEditorComponent, [{
type: Component,
args: [{ standalone: true, selector: 'acl-labels-editor', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
CommonModule,
TranslateModule,
FormsModule,
InputModule,
ValidatorsModule,
ErrorsMapperModule,
IconModule,
ButtonModule,
PurePipe,
CalcPipe,
EffectDirectiveModule,
], providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => LabelsEditorComponent),
multi: true,
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => LabelsEditorComponent),
multi: true,
},
], template: "<table\n class=\"acl-array-form-table mp-sticky-table-header mp-sticky-table-actions\"\n [class.submitted]=\"submitted\"\n>\n <thead>\n <tr>\n <th\n required\n width=\"50%\"\n >\n <span>{{ 'key' | translate }}</span>\n </th>\n <th width=\"50%\">{{ 'value' | translate }}</th>\n <th style=\"min-width: 44px\"></th>\n </tr>\n </thead>\n <tbody>\n <tr\n *ngFor=\"let label of model; let index = index\"\n [class.duplicated]=\"duplicatedRows[index]\"\n >\n <td>\n <input\n aui-input\n size=\"small\"\n name=\"key\"\n #key=\"ngModel\"\n [ngModel]=\"label.key\"\n (ngModelChange)=\"editLabel(index, 'key', $event)\"\n required\n [aclValidateFn]=\"validateLabelKey | calc: duplicatedRows:index\"\n />\n <acl-errors-mapper\n *ngIf=\"submitted || key.dirty\"\n [errors]=\"key.errors\"\n [errorsMapper]=\"{\n duplicated:\n 'label_key_already_exists'\n | translate: { key: key.errors?.duplicated }\n }\"\n ></acl-errors-mapper>\n </td>\n <td>\n <input\n aui-input\n size=\"small\"\n name=\"value\"\n #value=\"ngModel\"\n [ngModel]=\"label.value\"\n (ngModelChange)=\"editLabel(index, 'value', $event)\"\n aclMaxlength=\"63\"\n [pattern]=\"K8S_RESOURCE_LABEL_VALUE_PATTERN.pattern\"\n />\n <acl-errors-mapper\n *ngIf=\"submitted || value.dirty\"\n [errors]=\"value.errors\"\n ></acl-errors-mapper>\n </td>\n <td class=\"acl-array-form-table__action-col\">\n <button\n aui-button=\"text\"\n size=\"small\"\n type=\"button\"\n [square]=\"true\"\n [plain]=\"true\"\n (click)=\"removeLabel(index)\"\n >\n <aui-icon icon=\"minus_circle\"></aui-icon>\n </button>\n </td>\n </tr>\n <tr *ngIf=\"!model?.length\">\n <td colspan=\"100\">\n <div class=\"placeholder\">{{ 'no_label' | translate }}</div>\n </td>\n </tr>\n <tr class=\"acl-array-form-table--row-action\">\n <td colspan=\"100\">\n <div class=\"acl-array-form-table__bottom-control-buttons\">\n <button\n aui-button=\"primary\"\n [plain]=\"true\"\n size=\"mini\"\n type=\"button\"\n (click)=\"addLabel()\"\n [disabled]=\"model?.length >= 50\"\n >\n <aui-icon icon=\"plus_circle\"></aui-icon>\n <span>\n {{ 'add' | translate }}\n </span>\n </button>\n </div>\n </td>\n </tr>\n </tbody>\n</table>\n", styles: [":host::ng-deep{display:block;width:100%}:host::ng-deep .acl-array-form-table tbody td{vertical-align:top;line-height:var(--aui-inline-height-s)}:host::ng-deep .acl-array-form-table tbody tr .placeholder{text-align:center;color:rgb(var(--aui-color-help-text))}:host::ng-deep .acl-array-form-table tbody tr.duplicated{background-color:rgb(var(--aui-color-r-7))}\n"] }]
}], null, null); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(LabelsEditorComponent, { className: "LabelsEditorComponent" }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21tb24vc3JjL2Zvcm0vbGFiZWxzLWVkaXRvci9jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvZm9ybS9sYWJlbHMtZWRpdG9yL3RlbXBsYXRlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBRUwsV0FBVyxFQUNYLGFBQWEsRUFDYixpQkFBaUIsR0FDbEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRWxDLE9BQU8sRUFDTCxRQUFRLEVBQ1IsbUNBQW1DLEVBQ25DLHFDQUFxQyxFQUNyQyxnQ0FBZ0MsRUFDaEMsUUFBUSxFQUNSLHVCQUF1QixHQUN4QixNQUFNLHVCQUF1QixDQUFDO0FBQy9CLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7SUNVcEQsd0NBUXFCOzs7OztJQUxuQixBQURBLHNDQUFxQixtTEFLbkI7OztJQWNKLHdDQUdxQjs7OztJQURuQix3Q0FBdUI7Ozs7SUFqQ3pCLEFBREYsQUFKRiwwQkFHQyxTQUNLLG1CQVVB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QUNFLE9BQU8sRUFBRSxhQUFhO3dCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxzQkFBc0IsQ0FBQzt3QkFDcEQsS0FBSyxFQUFFLElBQUk7cUJBQ1o7aUJBQ0Y7O2tGQUVVLHFCQUFxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJ1dHRvbk1vZHVsZSwgSWNvbk1vZHVsZSwgSW5wdXRNb2R1bGUgfSBmcm9tICdAYWxhdWRhL3VpJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBmb3J3YXJkUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBBYnN0cmFjdENvbnRyb2wsXG4gIEZvcm1zTW9kdWxlLFxuICBOR19WQUxJREFUT1JTLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgbWVyZ2VMZWZ0IH0gZnJvbSAncmFtZGEnO1xuXG5pbXBvcnQge1xuICBDYWxjUGlwZSxcbiAgSzhTX1JFU09VUkNFX0xBQkVMX0tFWV9OQU1FX1BBVFRFUk4sXG4gIEs4U19SRVNPVVJDRV9MQUJFTF9LRVlfUFJFRklYX1BBVFRFUk4sXG4gIEs4U19SRVNPVVJDRV9MQUJFTF9WQUxVRV9QQVRURVJOLFxuICBQdXJlUGlwZSxcbiAgY3JlYXRlTmVzdGVkRm9ybUNvbnRyb2wsXG59IGZyb20gJy4uLy4uL2NvcmUvcHVibGljLWFwaSc7XG5pbXBvcnQgeyBFZmZlY3REaXJlY3RpdmVNb2R1bGUgfSBmcm9tICcuLi8uLi9lZmZlY3QtZGlyZWN0aXZlL21vZHVsZSc7XG5pbXBvcnQgeyBUcmFuc2xhdGVNb2R1bGUgfSBmcm9tICcuLi8uLi90cmFuc2xhdGUvcHVibGljLWFwaSc7XG5pbXBvcnQgeyBFcnJvcnNNYXBwZXJNb2R1bGUgfSBmcm9tICcuLi9lcnJvcnMtbWFwcGVyL3B1YmxpYy1hcGknO1xuaW1wb3J0IHsgVmFsaWRhdG9yc01vZHVsZSB9IGZyb20gJy4uL3ZhbGlkYXRvcnMvcHVibGljLWFwaSc7XG5cbkBDb21wb25lbnQoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ2FjbC1sYWJlbHMtZWRpdG9yJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RlbXBsYXRlLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zdHlsZS5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFRyYW5zbGF0ZU1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBJbnB1dE1vZHVsZSxcbiAgICBWYWxpZGF0b3JzTW9kdWxlLFxuICAgIEVycm9yc01hcHBlck1vZHVsZSxcbiAgICBJY29uTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBQdXJlUGlwZSxcbiAgICBDYWxjUGlwZSxcbiAgICBFZmZlY3REaXJlY3RpdmVNb2R1bGUsXG4gIF0sXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTGFiZWxzRWRpdG9yQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IExhYmVsc0VkaXRvckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZSxcbiAgICB9LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBMYWJlbHNFZGl0b3JDb21wb25lbnQgZXh0ZW5kcyBjcmVhdGVOZXN0ZWRGb3JtQ29udHJvbDxcbiAgUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgUGFpcltdXG4+KCkge1xuICBLOFNfUkVTT1VSQ0VfTEFCRUxfVkFMVUVfUEFUVEVSTiA9IEs4U19SRVNPVVJDRV9MQUJFTF9WQUxVRV9QQVRURVJOO1xuICBkdXBsaWNhdGVkUm93czogUmVjb3JkPG51bWJlciwgYm9vbGVhbj4gPSB7fTtcblxuICBhZGRMYWJlbCgpIHtcbiAgICB0aGlzLm1vZGVsLnB1c2goeyBrZXk6ICcnLCB2YWx1ZTogJycgfSk7XG4gIH1cblxuICBlZGl0TGFiZWwoaW5kZXg6IG51bWJlciwga2V5OiBrZXlvZiBQYWlyLCB2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5tb2RlbFtpbmRleF1ba2V5XSA9IHZhbHVlO1xuICAgIHRoaXMuZW1pdE1vZGVsKCk7XG4gIH1cblxuICByZW1vdmVMYWJlbChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy5tb2RlbC5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMuZW1pdE1vZGVsKCk7XG4gIH1cblxuICB2YWxpZGF0ZUxhYmVsS2V5ID1cbiAgICAoZHVwbGljYXRlZFJvd3M6IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+LCBpbmRleDogbnVtYmVyKSA9PlxuICAgIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpID0+XG4gICAgICBtZXJnZUxlZnQoXG4gICAgICAgIHRoaXMua2V5RHVwbGljYXRlZChkdXBsaWNhdGVkUm93cywgaW5kZXgpKGNvbnRyb2wpLFxuICAgICAgICB0aGlzLmtleVBhdHRlcm4oY29udHJvbCksXG4gICAgICApO1xuXG4gIG92ZXJyaWRlIHdyaXRlVmFsdWUodmFsdWU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiB2b2lkIHtcbiAgICBzdXBlci53cml0ZVZhbHVlKHZhbHVlKTtcblxuICAgIHRoaXMuY2hlY2tEdXBsaWNhdGVkUm93cygpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZW1pdFZhbHVlKHZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogdm9pZCB7XG4gICAgc3VwZXIuZW1pdFZhbHVlKHZhbHVlKTtcblxuICAgIHRoaXMuY2hlY2tEdXBsaWNhdGVkUm93cygpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHZhbHVlSW4odmFsdWU6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBQYWlyW10ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyh2YWx1ZSA/PyB7fSkubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7XG4gICAgICBrZXksXG4gICAgICB2YWx1ZSxcbiAgICB9KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgbW9kZWxPdXQobW9kZWw6IFBhaXJbXSk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIHJldHVybiBtb2RlbC5yZWR1Y2UoKGFjYywgeyBrZXksIHZhbHVlIH0pID0+IHtcbiAgICAgIGNvbnN0IGsgPSBrZXkudHJpbSgpO1xuICAgICAgaWYgKGspIHtcbiAgICAgICAgYWNjW2tdID0gdmFsdWUudHJpbSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tEdXBsaWNhdGVkUm93cygpIHtcbiAgICB0aGlzLmR1cGxpY2F0ZWRSb3dzID0gKHRoaXMubW9kZWwgPz8gW10pLnJlZHVjZShcbiAgICAgIChhY2MsIHsga2V5IH0sIGluZGV4LCBsYWJlbHMpID0+IHtcbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBbaSwgbGFiZWxdIG9mIGxhYmVscy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICBpZiAoaSAhPT0gaW5kZXggJiYgbGFiZWwua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICAgIGFjY1tpbmRleF0gPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAge30gYXMgUmVjb3JkPG51bWJlciwgYm9vbGVhbj4sXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUga2V5UGF0dGVybihjb250cm9sOiBBYnN0cmFjdENvbnRyb2w8c3RyaW5nPikge1xuICAgIGlmICghY29udHJvbC52YWx1ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IFtuYW1lLCBwcmVmaXggPSAnJ10gPSBjb250cm9sLnZhbHVlLnNwbGl0KCcvJykucmV2ZXJzZSgpO1xuICAgIGlmIChcbiAgICAgIG5hbWUubGVuZ3RoID4gNjMgfHxcbiAgICAgIEs4U19SRVNPVVJDRV9MQUJFTF9LRVlfTkFNRV9QQVRURVJOLnBhdHRlcm4udGVzdChuYW1lKSA9PT0gZmFsc2VcbiAgICApIHtcbiAgICAgIHJldHVybiB7IHBhdHRlcm46IHRydWUgfTtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICAhIXByZWZpeCAmJlxuICAgICAgKHByZWZpeC5sZW5ndGggPiAyNTMgfHxcbiAgICAgICAgSzhTX1JFU09VUkNFX0xBQkVMX0tFWV9QUkVGSVhfUEFUVEVSTi5wYXR0ZXJuLnRlc3QocHJlZml4KSA9PT0gZmFsc2UpXG4gICAgKSB7XG4gICAgICByZXR1cm4geyBwYXR0ZXJuOiB0cnVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGtleUR1cGxpY2F0ZWQoXG4gICAgZHVwbGljYXRlZFJvd3M6IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+LFxuICAgIGluZGV4OiBudW1iZXIsXG4gICkge1xuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSBjb250cm9sLnZhbHVlO1xuICAgICAgaWYgKGR1cGxpY2F0ZWRSb3dzW2luZGV4XSkge1xuICAgICAgICByZXR1cm4geyBkdXBsaWNhdGVkOiBrZXkgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gIH1cbn1cblxuaW50ZXJmYWNlIFBhaXIge1xuICBrZXk6IHN0cmluZztcbiAgdmFsdWU6IHN0cmluZztcbn1cbiIsIjx0YWJsZVxuICBjbGFzcz1cImFjbC1hcnJheS1mb3JtLXRhYmxlIG1wLXN0aWNreS10YWJsZS1oZWFkZXIgbXAtc3RpY2t5LXRhYmxlLWFjdGlvbnNcIlxuICBbY2xhc3Muc3VibWl0dGVkXT1cInN1Ym1pdHRlZFwiXG4+XG4gIDx0aGVhZD5cbiAgICA8dHI+XG4gICAgICA8dGhcbiAgICAgICAgcmVxdWlyZWRcbiAgICAgICAgd2lkdGg9XCI1MCVcIlxuICAgICAgPlxuICAgICAgICA8c3Bhbj57eyAna2V5JyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgIDwvdGg+XG4gICAgICA8dGggd2lkdGg9XCI1MCVcIj57eyAndmFsdWUnIHwgdHJhbnNsYXRlIH19PC90aD5cbiAgICAgIDx0aCBzdHlsZT1cIm1pbi13aWR0aDogNDRweFwiPjwvdGg+XG4gICAgPC90cj5cbiAgPC90aGVhZD5cbiAgPHRib2R5PlxuICAgIDx0clxuICAgICAgKm5nRm9yPVwibGV0IGxhYmVsIG9mIG1vZGVsOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgICBbY2xhc3MuZHVwbGljYXRlZF09XCJkdXBsaWNhdGVkUm93c1tpbmRleF1cIlxuICAgID5cbiAgICAgIDx0ZD5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgYXVpLWlucHV0XG4gICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICBuYW1lPVwia2V5XCJcbiAgICAgICAgICAja2V5PVwibmdNb2RlbFwiXG4gICAgICAgICAgW25nTW9kZWxdPVwibGFiZWwua2V5XCJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJlZGl0TGFiZWwoaW5kZXgsICdrZXknLCAkZXZlbnQpXCJcbiAgICAgICAgICByZXF1aXJlZFxuICAgICAgICAgIFthY2xWYWxpZGF0ZUZuXT1cInZhbGlkYXRlTGFiZWxLZXkgfCBjYWxjOiBkdXBsaWNhdGVkUm93czppbmRleFwiXG4gICAgICAgIC8+XG4gICAgICAgIDxhY2wtZXJyb3JzLW1hcHBlclxuICAgICAgICAgICpuZ0lmPVwic3VibWl0dGVkIHx8IGtleS5kaXJ0eVwiXG4gICAgICAgICAgW2Vycm9yc109XCJrZXkuZXJyb3JzXCJcbiAgICAgICAgICBbZXJyb3JzTWFwcGVyXT1cIntcbiAgICAgICAgICAgIGR1cGxpY2F0ZWQ6XG4gICAgICAgICAgICAgICdsYWJlbF9rZXlfYWxyZWFkeV9leGlzdHMnXG4gICAgICAgICAgICAgIHwgdHJhbnNsYXRlOiB7IGtleToga2V5LmVycm9ycz8uZHVwbGljYXRlZCB9XG4gICAgICAgICAgfVwiXG4gICAgICAgID48L2FjbC1lcnJvcnMtbWFwcGVyPlxuICAgICAgPC90ZD5cbiAgICAgIDx0ZD5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgYXVpLWlucHV0XG4gICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICBuYW1lPVwidmFsdWVcIlxuICAgICAgICAgICN2YWx1ZT1cIm5nTW9kZWxcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cImxhYmVsLnZhbHVlXCJcbiAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJlZGl0TGFiZWwoaW5kZXgsICd2YWx1ZScsICRldmVudClcIlxuICAgICAgICAgIGFjbE1heGxlbmd0aD1cIjYzXCJcbiAgICAgICAgICBbcGF0dGVybl09XCJLOFNfUkVTT1VSQ0VfTEFCRUxfVkFMVUVfUEFUVEVSTi5wYXR0ZXJuXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGFjbC1lcnJvcnMtbWFwcGVyXG4gICAgICAgICAgKm5nSWY9XCJzdWJtaXR0ZWQgfHwgdmFsdWUuZGlydHlcIlxuICAgICAgICAgIFtlcnJvcnNdPVwidmFsdWUuZXJyb3JzXCJcbiAgICAgICAgPjwvYWNsLWVycm9ycy1tYXBwZXI+XG4gICAgICA8L3RkPlxuICAgICAgPHRkIGNsYXNzPVwiYWNsLWFycmF5LWZvcm0tdGFibGVfX2FjdGlvbi1jb2xcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGF1aS1idXR0b249XCJ0ZXh0XCJcbiAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIFtzcXVhcmVdPVwidHJ1ZVwiXG4gICAgICAgICAgW3BsYWluXT1cInRydWVcIlxuICAgICAgICAgIChjbGljayk9XCJyZW1vdmVMYWJlbChpbmRleClcIlxuICAgICAgICA+XG4gICAgICAgICAgPGF1aS1pY29uIGljb249XCJtaW51c19jaXJjbGVcIj48L2F1aS1pY29uPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHIgKm5nSWY9XCIhbW9kZWw/Lmxlbmd0aFwiPlxuICAgICAgPHRkIGNvbHNwYW49XCIxMDBcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBsYWNlaG9sZGVyXCI+e3sgJ25vX2xhYmVsJyB8IHRyYW5zbGF0ZSB9fTwvZGl2PlxuICAgICAgPC90ZD5cbiAgICA8L3RyPlxuICAgIDx0ciBjbGFzcz1cImFjbC1hcnJheS1mb3JtLXRhYmxlLS1yb3ctYWN0aW9uXCI+XG4gICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWNsLWFycmF5LWZvcm0tdGFibGVfX2JvdHRvbS1jb250cm9sLWJ1dHRvbnNcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBhdWktYnV0dG9uPVwicHJpbWFyeVwiXG4gICAgICAgICAgICBbcGxhaW5dPVwidHJ1ZVwiXG4gICAgICAgICAgICBzaXplPVwibWluaVwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIChjbGljayk9XCJhZGRMYWJlbCgpXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJtb2RlbD8ubGVuZ3RoID49IDUwXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8YXVpLWljb24gaWNvbj1cInBsdXNfY2lyY2xlXCI+PC9hdWktaWNvbj5cbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICB7eyAnYWRkJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgPC90Ym9keT5cbjwvdGFibGU+XG4iXX0=