@alauda-fe/custom-resource-quota
Version:
custom resource
727 lines • 104 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { ButtonComponent, FORM_MODULE, IconComponent, INPUT_GROUP_MODULE, InputComponent, SELECT_MODULE, TooltipDirective, } from '@alauda/ui';
import { TranslateService, bind, ValidateRowDuplicateService, isEqual, publishRef, ObservableInput, ArrayFormTableComponent, ArrayFormTableHeaderDirective, TRANSLATE_MODULE, ArrayFormTableRowDirective, DeclareDirective, PurePipe, ParseJsonTranslatePipe, ERRORS_MAPPER_MODULE, ArrayFormTableRowControlDirective, } from '@alauda-fe/common';
import { AsyncPipe, NgClass, NgForOf, NgIf } from '@angular/common';
import { ChangeDetectionStrategy, Component, Injector, Input, } from '@angular/core';
import { ControlContainer, FormGroup, ReactiveFormsModule, Validators, } from '@angular/forms';
import { cloneDeep, flatMap, groupBy, has, isObject, omit, pick, remove, toPairs, } from 'lodash-es';
import { BaseResourceFormArrayComponent } from 'ng-resource-form-util';
import { BehaviorSubject, Observable, combineLatest, debounceTime, distinctUntilChanged, map, takeUntil, tap, } from 'rxjs';
import { ActionType, QuotaItemType, } from '../types';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@alauda-fe/common";
import * as i3 from "@alauda/ui";
const _c0 = (a0, a1, a2, a3, a4) => [a0, a1, a2, a3, a4];
const _c1 = (a0, a1, a2, a3, a4, a5, a6) => [a0, a1, a2, a3, a4, a5, a6];
const _c2 = a0 => ({ excludesTypes: a0 });
const _c3 = (a0, a1) => ({ keyInvalid: a0, keyDuplicated: a1 });
const _c4 = a0 => ({ pattern: a0 });
const _c5 = a0 => ({ "tw-mt-8": a0 });
function CustomResourceQuotaFormComponent_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0, 5);
i0.ɵɵelementStart(1, "th", 6);
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "th", 6);
i0.ɵɵtext(5);
i0.ɵɵpipe(6, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵclassMap((ctx_r0.form.controls == null ? null : ctx_r0.form.controls.length) ? "tw-required-mark" : "");
i0.ɵɵadvance();
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(3, 6, "type"), " ");
i0.ɵɵadvance(2);
i0.ɵɵclassMap((ctx_r0.form.controls == null ? null : ctx_r0.form.controls.length) ? "tw-required-mark" : "");
i0.ɵɵadvance();
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(6, 8, "value"), " ");
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_container_1_aui_option_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "aui-option", 14);
i0.ɵɵpipe(1, "aclParseJsonTranslate");
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "aclParseJsonTranslate");
i0.ɵɵelementEnd();
} if (rf & 2) {
const state_r4 = ctx.declare;
const item_r5 = i0.ɵɵnextContext().$implicit;
i0.ɵɵnextContext();
const disabledTemplate_r6 = i0.ɵɵreference(3);
i0.ɵɵproperty("value", item_r5.key)("label", i0.ɵɵpipeBind1(1, 7, item_r5.name))("disabled", state_r4.isDisabled)("auiTooltip", disabledTemplate_r6)("auiTooltipContext", i0.ɵɵpureFunction1(11, _c2, state_r4.excludesTypes))("auiTooltipDisabled", !state_r4.isDisabled);
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(3, 9, item_r5.name), " ");
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_container_1_aui_option_1_Template, 4, 13, "aui-option", 13);
i0.ɵɵpipe(2, "async");
i0.ɵɵpipe(3, "pure");
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const item_r5 = ctx.$implicit;
const options_r7 = i0.ɵɵnextContext().declare;
const index_r8 = i0.ɵɵnextContext().index;
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance();
i0.ɵɵproperty("declare", i0.ɵɵpipeBindV(3, 3, i0.ɵɵpureFunction7(11, _c1, ctx_r0.form == null ? null : ctx_r0.form.value, ctx_r0.getKindDisabledState, item_r5, options_r7, index_r8, ctx_r0.podContainerIndex, i0.ɵɵpipeBind1(2, 1, ctx_r0.kindDisabledStateTrigger$$))));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_template_2_li_4_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "li");
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "aclParseJsonTranslate");
i0.ɵɵelementEnd();
} if (rf & 2) {
const t_r9 = ctx.$implicit;
i0.ɵɵadvance();
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(2, 1, t_r9), " ");
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_template_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 15);
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "translate");
i0.ɵɵelementEnd();
i0.ɵɵelementStart(3, "ul", 16);
i0.ɵɵtemplate(4, CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_template_2_li_4_Template, 3, 3, "li", 12);
i0.ɵɵelementEnd();
} if (rf & 2) {
const excludesTypes_r10 = ctx.excludesTypes;
i0.ɵɵadvance();
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(2, 2, "custom_resource_kind_excludes_tip"), " ");
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngForOf", excludesTypes_r10);
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_container_1_Template, 4, 19, "ng-container", 12)(2, CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_ng_template_2_Template, 5, 4, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const options_r7 = ctx.declare;
i0.ɵɵadvance();
i0.ɵɵproperty("ngForOf", options_r7);
} }
function CustomResourceQuotaFormComponent_ng_container_2_acl_errors_mapper_8_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "acl-errors-mapper", 17);
i0.ɵɵpipe(1, "translate");
i0.ɵɵpipe(2, "translate");
} if (rf & 2) {
const control_r3 = i0.ɵɵnextContext().$implicit;
i0.ɵɵproperty("errors", (control_r3.errors == null ? null : control_r3.errors.duplicateError) || control_r3.get("key").errors)("errorsMapper", i0.ɵɵpureFunction2(6, _c3, i0.ɵɵpipeBind1(1, 2, "invalid_pattern"), i0.ɵɵpipeBind1(2, 4, "type_duplicated_errors")));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_span_4_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 24);
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
const context_r11 = i0.ɵɵnextContext(2).declare;
i0.ɵɵadvance();
i0.ɵɵtextInterpolate(context_r11.resourceUnit || i0.ɵɵpipeBind1(2, 1, context_r11.unit));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_aui_icon_5_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "aui-icon", 25);
i0.ɵɵpipe(1, "translate");
} if (rf & 2) {
const context_r11 = i0.ɵɵnextContext(2).declare;
i0.ɵɵproperty("auiTooltip", i0.ɵɵpipeBind1(1, 1, context_r11.description));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_acl_errors_mapper_6_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "acl-errors-mapper", 17);
i0.ɵɵpipe(1, "translate");
} if (rf & 2) {
const control_r3 = i0.ɵɵnextContext(3).$implicit;
i0.ɵɵproperty("errors", control_r3.get("value").errors)("errorsMapper", i0.ɵɵpureFunction1(4, _c4, i0.ɵɵpipeBind1(1, 2, "support_positive_integer")));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "div", 19)(2, "aui-input-group", 20);
i0.ɵɵelement(3, "input", 21);
i0.ɵɵtemplate(4, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_span_4_Template, 3, 3, "span", 22);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(5, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_aui_icon_5_Template, 2, 3, "aui-icon", 23);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(6, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_acl_errors_mapper_6_Template, 2, 6, "acl-errors-mapper", 11);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const context_r11 = i0.ɵɵnextContext().declare;
const control_r3 = i0.ɵɵnextContext().$implicit;
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance(3);
i0.ɵɵproperty("min", 0);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", context_r11.resourceUnit || context_r11.unit && context_r11.unit !== "unit_ge");
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", context_r11 == null ? null : context_r11.description);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", control_r3.get("value").dirty || (ctx_r0.controlContainer == null ? null : ctx_r0.controlContainer.formDirective == null ? null : ctx_r0.controlContainer.formDirective.submitted));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_span_4_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 24);
i0.ɵɵtext(1);
i0.ɵɵpipe(2, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
const c_r12 = i0.ɵɵnextContext().$implicit;
i0.ɵɵadvance();
i0.ɵɵtextInterpolate(c_r12.resourceUnit || i0.ɵɵpipeBind1(2, 1, c_r12.unit));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_span_5_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "span", 30);
i0.ɵɵpipe(1, "translate");
i0.ɵɵtext(2);
i0.ɵɵpipe(3, "translate");
i0.ɵɵelementEnd();
} if (rf & 2) {
const c_r12 = i0.ɵɵnextContext().$implicit;
i0.ɵɵproperty("title", i0.ɵɵpipeBind1(1, 2, c_r12.name));
i0.ɵɵadvance(2);
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(3, 4, c_r12.name));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_aui_icon_6_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "aui-icon", 25);
i0.ɵɵpipe(1, "translate");
} if (rf & 2) {
const c_r12 = i0.ɵɵnextContext().$implicit;
i0.ɵɵproperty("auiTooltip", i0.ɵɵpipeBind1(1, 1, c_r12.description));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_acl_errors_mapper_7_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelement(0, "acl-errors-mapper", 17);
i0.ɵɵpipe(1, "translate");
} if (rf & 2) {
let tmp_10_0;
const c_r12 = i0.ɵɵnextContext().$implicit;
const control_r3 = i0.ɵɵnextContext(3).$implicit;
i0.ɵɵproperty("errors", (tmp_10_0 = control_r3.get("value")) == null ? null : tmp_10_0.controls == null ? null : tmp_10_0.controls[c_r12.key] == null ? null : tmp_10_0.controls[c_r12.key].errors)("errorsMapper", i0.ɵɵpureFunction1(4, _c4, i0.ɵɵpipeBind1(1, 2, "support_positive_integer")));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 27)(1, "div", 19)(2, "aui-input-group", 20);
i0.ɵɵelement(3, "input", 28);
i0.ɵɵtemplate(4, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_span_4_Template, 3, 3, "span", 22)(5, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_span_5_Template, 4, 6, "span", 29);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(6, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_aui_icon_6_Template, 2, 3, "aui-icon", 23);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(7, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_acl_errors_mapper_7_Template, 2, 6, "acl-errors-mapper", 11);
i0.ɵɵelementEnd();
} if (rf & 2) {
let tmp_15_0;
const c_r12 = ctx.$implicit;
const i_r13 = ctx.index;
const control_r3 = i0.ɵɵnextContext(3).$implicit;
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(7, _c5, !!i_r13));
i0.ɵɵadvance(3);
i0.ɵɵproperty("formControlName", c_r12.key)("min", 0);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", c_r12.resourceUnit || c_r12.unit && c_r12.unit !== "unit_ge");
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", c_r12.name);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", c_r12 == null ? null : c_r12.description);
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", ((tmp_15_0 = control_r3.get("value")) == null ? null : tmp_15_0.controls == null ? null : tmp_15_0.controls[c_r12.key] == null ? null : tmp_15_0.controls[c_r12.key].dirty) || (ctx_r0.controlContainer == null ? null : ctx_r0.controlContainer.formDirective == null ? null : ctx_r0.controlContainer.formDirective.submitted));
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_div_1_Template, 8, 9, "div", 26);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const context_r11 = i0.ɵɵnextContext().declare;
i0.ɵɵadvance();
i0.ɵɵproperty("ngForOf", context_r11 == null ? null : context_r11.groupResources);
} }
function CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementContainerStart(0);
i0.ɵɵtemplate(1, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_1_Template, 7, 4, "ng-container", 18)(2, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_ng_container_2_Template, 2, 1, "ng-container", 18);
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
const context_r11 = ctx.declare;
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", !(context_r11 == null ? null : context_r11.groupResources));
i0.ɵɵadvance();
i0.ɵɵproperty("ngIf", context_r11 == null ? null : context_r11.groupResources);
} }
function CustomResourceQuotaFormComponent_ng_container_2_Template(rf, ctx) { if (rf & 1) {
const _r2 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0, 7);
i0.ɵɵelementStart(1, "td", 8)(2, "aui-select", 9);
i0.ɵɵlistener("valueChange", function CustomResourceQuotaFormComponent_ng_container_2_Template_aui_select_valueChange_2_listener() { const control_r3 = i0.ɵɵrestoreView(_r2).$implicit; return i0.ɵɵresetView(control_r3.get("value").patchValue("")); })("show", function CustomResourceQuotaFormComponent_ng_container_2_Template_aui_select_show_2_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.refreshKindDisabledState()); });
i0.ɵɵtemplate(3, CustomResourceQuotaFormComponent_ng_container_2_ng_container_3_Template, 4, 1, "ng-container", 10);
i0.ɵɵpipe(4, "async");
i0.ɵɵelementStart(5, "aui-option-placeholder");
i0.ɵɵtext(6);
i0.ɵɵpipe(7, "translate");
i0.ɵɵelementEnd()();
i0.ɵɵtemplate(8, CustomResourceQuotaFormComponent_ng_container_2_acl_errors_mapper_8_Template, 3, 9, "acl-errors-mapper", 11);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(9, "td", 8);
i0.ɵɵtemplate(10, CustomResourceQuotaFormComponent_ng_container_2_ng_container_10_Template, 3, 2, "ng-container", 10);
i0.ɵɵpipe(11, "async");
i0.ɵɵpipe(12, "async");
i0.ɵɵpipe(13, "pure");
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
let tmp_4_0;
const control_r3 = ctx.$implicit;
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵproperty("formGroup", control_r3);
i0.ɵɵadvance(2);
i0.ɵɵproperty("readonly", (tmp_4_0 = control_r3.get("disabled")) == null ? null : tmp_4_0.value);
i0.ɵɵadvance();
i0.ɵɵproperty("declare", i0.ɵɵpipeBind1(4, 6, ctx_r0.customResourceLimitsMixed$));
i0.ɵɵadvance(3);
i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(7, 8, "no_data"), " ");
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", (control_r3.errors == null ? null : control_r3.errors.duplicateError) || control_r3.get("key").dirty || (ctx_r0.controlContainer == null ? null : ctx_r0.controlContainer.formDirective == null ? null : ctx_r0.controlContainer.formDirective.submitted));
i0.ɵɵadvance(2);
i0.ɵɵproperty("declare", i0.ɵɵpipeBindV(13, 14, i0.ɵɵpureFunction5(20, _c0, control_r3.get("key").value, ctx_r0.getResourceQuotaContext, i0.ɵɵpipeBind1(11, 10, ctx_r0.translate.locale$), i0.ɵɵpipeBind1(12, 12, ctx_r0.customResourceLimitsMixed$), control_r3)));
} }
function CustomResourceQuotaFormComponent_ng_container_3_Template(rf, ctx) { if (rf & 1) {
const _r14 = i0.ɵɵgetCurrentView();
i0.ɵɵelementContainerStart(0);
i0.ɵɵelementStart(1, "button", 31);
i0.ɵɵlistener("click", function CustomResourceQuotaFormComponent_ng_container_3_Template_button_click_1_listener() { const index_r15 = i0.ɵɵrestoreView(_r14).index; const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.remove(index_r15)); });
i0.ɵɵelement(2, "aui-icon", 32);
i0.ɵɵelementEnd();
i0.ɵɵelementContainerEnd();
} if (rf & 2) {
let tmp_3_0;
const control_r16 = ctx.$implicit;
i0.ɵɵadvance();
i0.ɵɵproperty("disabled", (tmp_3_0 = control_r16.get("disabled")) == null ? null : tmp_3_0.value)("square", true)("plain", true);
} }
const QuotaTypes = ['StorageQuota', 'ExtendedResource', 'OtherQuota'];
const QUOTA_KEY_PATTERN = /^(([\da-z]([\da-z-]*[\da-z])?(\.[\da-z]([\da-z-]*[\da-z])?)*)\/?([\dA-Za-z]([\w.-]*[\dA-Za-z])?)?)$/;
const DEFAULT_RESOURCE_QUOTA = new Set([
QuotaItemType.CPU_LIMITS,
QuotaItemType.CPU_REQUESTS,
QuotaItemType.MEMORY_LIMITS,
QuotaItemType.MEMORY_REQUESTS,
QuotaItemType.PODS,
'cpu',
'memory',
]);
export class CustomResourceQuotaFormComponent extends BaseResourceFormArrayComponent {
constructor(controlContainer, injector, translate, rowDupService) {
super(injector);
this.controlContainer = controlContainer;
this.translate = translate;
this.rowDupService = rowDupService;
this.maxLimits = {};
this.actionType = ActionType.CREATE;
this.customResourceLimits = [];
this.podContainersResources = [
{
limits: {},
requests: {},
},
];
this.podContainerIndex = 0;
this.kindDisabledStateTrigger$$ = new BehaviorSubject(0);
this.customResourceLimitsWithGroup = [];
this.excludeCustomResourceConfigs = {};
this.customResourceLimitsWithGroup$ = this.customResourceLimits$.pipe(map(customResource => {
const byGroup = groupBy(customResource, 'group');
const result = toPairs(byGroup)
.filter(groupItems => groupItems[1]?.length > 1)
.map(([key, values]) => {
const groupI18n = byGroup[key].find(i => !!i.groupI18n)?.groupI18n;
return this.convertCustomResourceData({
key,
groupI18n,
groupResources: values.map(v => this.convertCustomResourceData(v)),
});
});
this.customResourceLimitsWithGroup = result;
return result;
}), publishRef());
this.customResourceLimitsWithNoGroup$ = this.customResourceLimits$.pipe(map(customResource => {
const byGroup = groupBy(customResource, 'group');
return toPairs(byGroup)
.filter(groupItems => groupItems[1]?.length === 1)
.map(([_, values]) => {
return this.convertCustomResourceData(values[0]);
});
}), publishRef());
this.customResourceLimitsMixed$ = combineLatest([
this.customResourceLimitsWithGroup$,
this.customResourceLimitsWithNoGroup$,
]).pipe(map(([a, b]) => [...a, ...b]), publishRef());
this.convertCustomResourceData = ({ key, descriptionEn, descriptionZh, labelEn, labelZh, groupResources, resourceUnit, excludeResources, groupI18n, }) => {
return {
key: `${key}`,
name: groupResources
? groupI18n || key
: labelZh
? {
en: labelEn,
zh: labelZh,
}
: key,
unit: 'unit_ge',
resourceUnit,
description: {
zh: descriptionZh,
en: descriptionEn,
},
groupResources,
excludeResources,
};
};
}
ngAfterViewInit() {
super.ngAfterViewInit();
this.form.valueChanges
.pipe(debounceTime(0), distinctUntilChanged(isEqual), takeUntil(this.destroy$))
.subscribe(() => this.form.controls.forEach(ctrl => ctrl.updateValueAndValidity()));
combineLatest([this.maxLimits$, this.customResourceLimitsMixed$])
.pipe(takeUntil(this.destroy$), tap(([maxLimits, customResourceLimitsMixed]) => {
const defaultQuotaItemsModel = this.getDefaultQuotaItemsModel(maxLimits, customResourceLimitsMixed);
if (this.actionType === ActionType.CREATE) {
if (maxLimits) {
if (this.form.length) {
this.form.clear();
}
defaultQuotaItemsModel.forEach((model, index) => this.form.insert(index, this.createNewQuotaItemControl(model)));
}
else {
this.form.clear();
}
}
else {
requestAnimationFrame(() => {
const keyVisibleModels = cloneDeep(this.formModel
.filter(model => model.value)
.map(model => {
return {
...model,
};
}));
const targetQuotaFormModel = this.getDefaultQuotaItemsModel(keyVisibleModels?.reduce((acc, curr) => {
acc[curr.key] = curr.value;
return acc;
}, {}), customResourceLimitsMixed);
this.form.clear();
targetQuotaFormModel.forEach(model => {
this.form.push(this.createNewQuotaItemControl(model, keyVisibleModels));
});
this.cdr.markForCheck();
});
}
}))
.subscribe();
}
getOnFormArrayResizeFn() {
return () => this.createNewQuotaItemControl();
}
adaptFormModel(formModel) {
const transferredModel = formModel?.reduce((acc, { key, value }) => {
if (isObject(value)) {
Object.entries(value)?.forEach(([k, v]) => {
acc[k] = v;
});
}
else {
acc[key] = value;
}
return acc;
}, {});
return {
...this.excludeCustomResourceConfigs,
...transferredModel,
};
}
adaptResourceModel(resource) {
return this.selfAdaptResourceModel(resource, true);
}
selfAdaptResourceModel(resource, needCache = false) {
const targetGroupResource = [];
if (needCache) {
this.excludeCustomResourceConfigs =
omit(resource, this.customResourceLimits?.map(config => config.key)) || {};
}
const visibleCustomResourceConfigMap = pick(resource, this.customResourceLimits?.map(config => config.key));
const targetResources = isObject(visibleCustomResourceConfigMap)
? Object.keys(visibleCustomResourceConfigMap).map(k => ({
[k]: visibleCustomResourceConfigMap[k],
}))
: [];
if (this.customResourceLimitsWithGroup?.length) {
this.customResourceLimitsWithGroup.forEach(group => {
if (group.groupResources?.length &&
group.groupResources.some(r => targetResources.some(s => has(s, r.key)))) {
const filters = group.groupResources.filter(r => targetResources.some(s => has(s, r.key)));
targetGroupResource.push({
[group.key]: filters.reduce((acc, curr) => {
return {
...acc,
...targetResources.find(r => has(r, curr.key)),
};
}, {}),
});
filters.forEach(filter => {
remove(targetResources, obj => has(obj, filter.key));
});
}
});
}
const wrapper = (item) => {
const [key, value] = Object.entries(item).flat();
const type = this.getQuotaType(key);
return {
type,
key,
value,
};
};
return [...targetGroupResource, ...targetResources].map(wrapper);
}
refreshKindDisabledState() {
this.kindDisabledStateTrigger$$.next(Date.now());
}
getKindDisabledState(models, currQuotaType, quotaTypes, inModelIndex, podContainerIndex, _SELF_REFRESH_NUMBER) {
const formValueItems = this.selfAdaptResourceModel(this.podContainersResources
?.filter((_, i) => i !== podContainerIndex)
?.reduce((acc, curr) => {
return {
...acc,
...curr?.limits,
};
}, {}));
const mergedFormValueItems = [
...formValueItems,
...(models || []).filter((model, index) => index !== inModelIndex &&
!formValueItems.some(item => item.key === model.key)),
];
const getMatchedItems = (excludeResources) => {
const excludeKeys = excludeResources.split(',');
return mergedFormValueItems.filter(item => isObject(item.value)
? excludeKeys.some(key => has(item.value, key))
: excludeKeys.includes(item.key));
};
const getExcludesTypes = (matched) => matched
.map(m => quotaTypes.find(q => q.key === m.key)?.name)
.filter(Boolean);
const processExcludeResources = (excludeResources) => {
const matched = getMatchedItems(excludeResources);
return {
isDisabled: matched.length > 0,
excludesTypes: getExcludesTypes(matched),
};
};
if (currQuotaType.groupResources) {
for (const context of currQuotaType.groupResources) {
if (context.excludeResources) {
const result = processExcludeResources(context.excludeResources);
if (result.isDisabled)
return result;
}
}
return { isDisabled: false };
}
if (currQuotaType.excludeResources) {
return processExcludeResources(currQuotaType.excludeResources);
}
return { isDisabled: false };
}
getResourceQuotaContext(key, _locale, customResourceLimits, control) {
const { unit, description, groupResources, excludeResources, resourceUnit, } = customResourceLimits?.find(custom => custom.key === key) || {};
const originValue = control.get('value')?.value;
control.removeControl('value');
control.addControl('value', groupResources?.length
? this.fb.group(groupResources.reduce((acc, curr) => {
acc[curr.key] = this.fb.control(originValue?.[curr.key], [
Validators.required,
]);
return acc;
}, {}))
: this.fb.control(isObject(originValue) ? '' : originValue, [
Validators.required,
]));
return groupResources?.length
? {
groupResources,
}
: this.getQuotaContext({
unit,
resourceUnit,
description,
excludeResources,
});
}
createNewQuotaItemControl(model, keyVisibleModels) {
return this.fb.group({
key: [
model?.key || '',
[Validators.required, this.keyDuplicateValidator, this.keyValidator],
],
value: model?.groupResources
? this.fb.group(model.groupResources.reduce((acc, curr) => {
acc[curr.key] = this.fb.control(keyVisibleModels?.find(v => v.key === curr.key)
?.value ??
model.value ??
'', [Validators.required]);
return acc;
}, {}))
: [
(keyVisibleModels?.find(v => v.key === model.key) ?? model)
?.value ?? '',
[Validators.required],
],
}, {
validators: [
this.rowDupService.createFormArrayValidator({
rowKeys: [{ keyDuplicated: ['key'] }],
formArray: this.form,
}),
],
});
}
keyDuplicateValidator(ctrl) {
const key = ctrl.value;
return DEFAULT_RESOURCE_QUOTA.has(key)
? {
keyDuplicated: true,
}
: null;
}
keyValidator(ctrl) {
const key = ctrl.value;
return !key || QUOTA_KEY_PATTERN.test(key)
? null
: {
keyInvalid: true,
};
}
getFormModel(model) {
return {
type: 'ExtendedResource',
key: '',
value: '',
...model,
};
}
getQuotaContext(context) {
return {
unit: 'unit_Gi',
...context,
};
}
getQuotaType(key) {
const isCustomResource = this.customResourceLimits?.some(resource => resource.key === key);
if (isCustomResource) {
return 'ExtendedResource';
}
return 'OtherQuota';
}
getDefaultQuotaItemsModel(model, customResourceLimits) {
const getFormModelByKey = (key) => {
const hasCustomResourceLimit = customResourceLimits?.some(resource => resource.key === key);
if (hasCustomResourceLimit) {
return this.getFormModel({
type: 'ExtendedResource',
key,
value: null,
});
}
return null;
};
const keys = Object.keys(model ?? {});
let result = [];
const groupedLimits = customResourceLimits.filter(c => !!c.groupResources?.length &&
c.groupResources.some(r => keys.includes(r.key)));
const groupedLimitsKeys = flatMap(groupedLimits, arr => arr.groupResources).map(r => r.key);
result = result.concat(groupedLimits.map(g => ({
type: 'ExtendedResource',
key: g.key,
groupResources: g.groupResources.map(r => ({
type: 'ExtendedResource',
key: r.key,
value: null,
})),
})));
return result.concat(keys
.filter(k => !groupedLimitsKeys.includes(k))
.map(r => getFormModelByKey(r))
.filter(Boolean));
}
static { this.ɵfac = function CustomResourceQuotaFormComponent_Factory(t) { return new (t || CustomResourceQuotaFormComponent)(i0.ɵɵdirectiveInject(i1.ControlContainer), i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i2.TranslateService), i0.ɵɵdirectiveInject(i2.ValidateRowDuplicateService)); }; }
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CustomResourceQuotaFormComponent, selectors: [["acl-custom-resource-quota-form"]], inputs: { maxLimits: "maxLimits", actionType: "actionType", customResourceLimits: "customResourceLimits", podContainersResources: "podContainersResources", podContainerIndex: "podContainerIndex" }, standalone: true, features: [i0.ɵɵProvidersFeature([ValidateRowDuplicateService]), i0.ɵɵInheritDefinitionFeature, i0.ɵɵStandaloneFeature], decls: 4, vars: 4, consts: [["disabledTemplate", ""], [3, "add", "remove", "formGroup", "rows", "resourceName", "rowSeparator"], ["auiFormItemControl", "", "required", "", 4, "aclArrayFormTableHeader"], [3, "formGroup", 4, "aclArrayFormTableRow"], [4, "aclArrayFormTableRowControl"], ["auiFormItemControl", "", "required", ""], ["width", "50%"], [3, "formGroup"], [1, "!tw-align-top"], ["auiFormItemControl", "", "formControlName", "key", 3, "valueChange", "show", "readonly"], [4, "declare"], [3, "errors", "errorsMapper", 4, "ngIf"], [4, "ngFor", "ngForOf"], [3, "value", "label", "disabled", "auiTooltip", "auiTooltipContext", "auiTooltipDisabled", 4, "declare"], [3, "value", "label", "disabled", "auiTooltip", "auiTooltipContext", "auiTooltipDisabled"], [1, "tw-mb-4"], [1, "acl-tooltip-ul"], [3, "errors", "errorsMapper"], [4, "ngIf"], [1, "tw-flex", "tw-items-center"], [1, "tw-flex-1"], ["aui-input", "", "auiFormItemControl", "", "formControlName", "value", 3, "min"], ["auiInputAddonAfter", "", 4, "ngIf"], ["class", "tw-question tw-ml-8", "icon", "question_circle", 3, "auiTooltip", 4, "ngIf"], ["auiInputAddonAfter", ""], ["icon", "question_circle", 1, "tw-question", "tw-ml-8", 3, "auiTooltip"], ["formGroupName", "value", 3, "ngClass", 4, "ngFor", "ngForOf"], ["formGroupName", "value", 3, "ngClass"], ["aui-input", "", "auiFormItemControl", "", 3, "formControlName", "min"], ["class", "tw-max-w-[100px] tw-text-overflow", "auiInputAddonBefore", "", 3, "title", 4, "ngIf"], ["auiInputAddonBefore", "", 1, "tw-max-w-[100px]", "tw-text-overflow", 3, "title"], ["aui-button", "text", "type", "button", 3, "click", "disabled", "square", "plain"], ["icon", "minus_circle"]], template: function CustomResourceQuotaFormComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "acl-array-form-table", 1);
i0.ɵɵlistener("add", function CustomResourceQuotaFormComponent_Template_acl_array_form_table_add_0_listener() { return ctx.add(); })("remove", function CustomResourceQuotaFormComponent_Template_acl_array_form_table_remove_0_listener($event) { return ctx.remove($event); });
i0.ɵɵtemplate(1, CustomResourceQuotaFormComponent_ng_container_1_Template, 7, 10, "ng-container", 2)(2, CustomResourceQuotaFormComponent_ng_container_2_Template, 14, 26, "ng-container", 3)(3, CustomResourceQuotaFormComponent_ng_container_3_Template, 3, 3, "ng-container", 4);
i0.ɵɵelementEnd();
} if (rf & 2) {
i0.ɵɵproperty("formGroup", ctx.form)("rows", ctx.form.controls)("resourceName", "gpu_improve")("rowSeparator", true);
} }, dependencies: [ArrayFormTableComponent,
ReactiveFormsModule, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgControlStatusGroup, i1.FormGroupDirective, i1.FormControlName, i1.FormGroupName, ArrayFormTableHeaderDirective, i2.TranslatePipe, ArrayFormTableRowDirective, i3.SelectComponent, i3.OptionComponent, i3.OptionPlaceholderComponent, DeclareDirective,
AsyncPipe,
NgForOf,
PurePipe,
ParseJsonTranslatePipe,
TooltipDirective, i2.ErrorsMapperComponent, NgIf, i3.InputGroupComponent, i3.InputAddonAfterDirective, i3.InputAddonBeforeDirective, InputComponent, i3.FormItemControlDirective, IconComponent,
NgClass,
ArrayFormTableRowControlDirective,
ButtonComponent], styles: ["[_nghost-%COMP%] .aui-select .aui-input[readonly]{background-color:rgb(var(--aui-color-n-8))}"], changeDetection: 0 }); }
}
__decorate([
ObservableInput(),
__metadata("design:type", Observable)
], CustomResourceQuotaFormComponent.prototype, "maxLimits$", void 0);
__decorate([
ObservableInput(),
__metadata("design:type", Observable)
], CustomResourceQuotaFormComponent.prototype, "customResourceLimits$", void 0);
__decorate([
bind,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Array, Object, Array, Number, Number, Number]),
__metadata("design:returntype", Object)
], CustomResourceQuotaFormComponent.prototype, "getKindDisabledState", null);
__decorate([
bind,
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, String, Array, FormGroup]),
__metadata("design:returntype", Object)
], CustomResourceQuotaFormComponent.prototype, "getResourceQuotaContext", null);
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CustomResourceQuotaFormComponent, [{
type: Component,
args: [{ standalone: true, selector: 'acl-custom-resource-quota-form', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ValidateRowDuplicateService], imports: [
ArrayFormTableComponent,
ReactiveFormsModule,
ArrayFormTableHeaderDirective,
TRANSLATE_MODULE,
ArrayFormTableRowDirective,
SELECT_MODULE,
DeclareDirective,
AsyncPipe,
NgForOf,
PurePipe,
ParseJsonTranslatePipe,
TooltipDirective,
ERRORS_MAPPER_MODULE,
NgIf,
INPUT_GROUP_MODULE,
InputComponent,
FORM_MODULE,
IconComponent,
NgClass,
ArrayFormTableRowControlDirective,
ButtonComponent,
], template: "<acl-array-form-table\n [formGroup]=\"$any(form)\"\n [rows]=\"form.controls\"\n (add)=\"add()\"\n (remove)=\"remove($event)\"\n [resourceName]=\"'gpu_improve'\"\n [rowSeparator]=\"true\"\n>\n <ng-container\n *aclArrayFormTableHeader\n auiFormItemControl\n required\n >\n <th\n width=\"50%\"\n [class]=\"form.controls?.length ? 'tw-required-mark' : ''\"\n >\n {{ 'type' | translate }}\n </th>\n <th\n width=\"50%\"\n [class]=\"form.controls?.length ? 'tw-required-mark' : ''\"\n >\n {{ 'value' | translate }}\n </th>\n </ng-container>\n\n <ng-container\n *aclArrayFormTableRow=\"let control; let index = index\"\n [formGroup]=\"control\"\n >\n <td class=\"!tw-align-top\">\n <!-- \u6269\u5C55\u8D44\u6E90 -->\n <aui-select\n auiFormItemControl\n formControlName=\"key\"\n [readonly]=\"control.get('disabled')?.value\"\n (valueChange)=\"control.get('value').patchValue('')\"\n (show)=\"refreshKindDisabledState()\"\n >\n <ng-container *declare=\"customResourceLimitsMixed$ | async as options\">\n <ng-container *ngFor=\"let item of options\">\n <aui-option\n *declare=\"\n form?.value\n | pure\n : getKindDisabledState\n : item\n : options\n : index\n : podContainerIndex\n : (kindDisabledStateTrigger$$ | async) as state\n \"\n [value]=\"item.key\"\n [label]=\"item.name | aclParseJsonTranslate\"\n [disabled]=\"state.isDisabled\"\n [auiTooltip]=\"disabledTemplate\"\n [auiTooltipContext]=\"{\n excludesTypes: state.excludesTypes,\n }\"\n [auiTooltipDisabled]=\"!state.isDisabled\"\n >\n {{ item.name | aclParseJsonTranslate }}\n </aui-option>\n </ng-container>\n <ng-template\n #disabledTemplate\n let-excludesTypes=\"excludesTypes\"\n >\n <div class=\"tw-mb-4\">\n {{ 'custom_resource_kind_excludes_tip' | translate }}\n </div>\n <ul class=\"acl-tooltip-ul\">\n <li *ngFor=\"let t of excludesTypes\">\n {{ t | aclParseJsonTranslate }}\n </li>\n </ul>\n </ng-template>\n </ng-container>\n <aui-option-placeholder>\n {{ 'no_data' | translate }}\n </aui-option-placeholder>\n </aui-select>\n <acl-errors-mapper\n *ngIf=\"\n control.errors?.duplicateError ||\n control.get('key').dirty ||\n $any(controlContainer?.formDirective)?.submitted\n \"\n [errors]=\"control.errors?.duplicateError || control.get('key').errors\"\n [errorsMapper]=\"{\n keyInvalid: 'invalid_pattern' | translate,\n keyDuplicated: 'type_duplicated_errors' | translate,\n }\"\n ></acl-errors-mapper>\n </td>\n <td class=\"!tw-align-top\">\n <ng-container\n *declare=\"\n control.get('key').value\n | pure\n : getResourceQuotaContext\n : (translate.locale$ | async)\n : (customResourceLimitsMixed$ | async)\n : control as context\n \"\n >\n <ng-container *ngIf=\"!context?.groupResources\">\n <div class=\"tw-flex tw-items-center\">\n <aui-input-group class=\"tw-flex-1\">\n <input\n aui-input\n auiFormItemControl\n formControlName=\"value\"\n [min]=\"0\"\n />\n <span\n *ngIf=\"\n context.resourceUnit ||\n (context.unit && context.unit !== 'unit_ge')\n \"\n auiInputAddonAfter\n >{{ context.resourceUnit || (context.unit | translate) }}</span\n >\n </aui-input-group>\n <aui-icon\n *ngIf=\"context?.description\"\n class=\"tw-question tw-ml-8\"\n icon=\"question_circle\"\n [auiTooltip]=\"context.description | translate\"\n ></aui-icon>\n </div>\n <acl-errors-mapper\n *ngIf=\"\n control.get('value').dirty ||\n $any(controlContainer?.formDirective)?.submitted\n \"\n [errors]=\"control.get('value').errors\"\n [errorsMapper]=\"{\n pattern: 'support_positive_integer' | translate,\n }\"\n ></acl-errors-mapper>\n </ng-container>\n\n <!-- groupResources -->\n <ng-container *ngIf=\"context?.groupResources\">\n <div\n *ngFor=\"let c of context?.groupResources; let i = index\"\n formGroupName=\"value\"\n [ngClass]=\"{ 'tw-mt-8': !!i }\"\n >\n <div class=\"tw-flex tw-items-center\">\n <aui-input-group class=\"tw-flex-1\">\n <input\n aui-input\n auiFormItemControl\n [formControlName]=\"c.key\"\n [min]=\"0\"\n />\n <span\n *ngIf=\"c.resourceUnit || (c.unit && c.unit !== 'unit_ge')\"\n auiInputAddonAfter\n >{{ c.resourceUnit || (c.unit | translate) }}</span\n >\n <span\n *ngIf=\"c.name\"\n class=\"tw-max-w-[100px] tw-text-overflow\"\n [title]=\"c.name | translate\"\n auiInputAddonBefore\n >{{ c.name | translate }}</span\n >\n </aui-input-group>\n <aui-icon\n *ngIf=\"c?.description\"\n class=\"tw-question tw-ml-8\"\n icon=\"question_circle\"\n [auiTooltip]=\"c.description | translate\"\n ></aui-icon>\n </div>\n <acl-errors-mapper\n *ngIf=\"\n control.get('value')?.controls?.[c.key]?.dirty ||\n $any(controlContainer?.formDirective)?.submitted\n \"\n [errors]=\"control.get('value')?.controls?.[c.key]?.errors\"\n [errorsMapper]=\"{\n pattern: 'support_positive_integer' | translate,\n }\"\n ></acl-errors-mapper>\n </div>\n </ng-container>\n </ng-container>\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 [disabled]=\"control.get('disabled')?.value\"\n (click)=\"remove(index)\"\n [square]=\"true\"\n [plain]=\"true\"\n >\n <aui-icon icon=\"minus_circle\"></aui-icon>\n </button>\n </ng-container>\n</acl-array-form-table>\n", styles: [":host ::ng-deep .aui-select .aui-input[readonly]{background-color:rgb(var(--aui-color-n-8))}\n"] }]
}], () => [{ type: i1.ControlContainer }, { type: i0.Injector }, { type: i2.TranslateService }, { type: i2.ValidateRowDuplicateService }], { maxLimits: [{
type: Input
}], maxLimits$: [], actionType: [{
type: Input
}], customResourceLimits: [{
type: Input
}], customResourceLimits$: [], podContainersResources: [{
type: Input
}], podContainerIndex: [{
type: Input
}], getKindDisabledState: [], getResourceQuotaContext: [] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CustomResourceQuotaFormComponent, { className: "CustomResourceQuotaFormComponent", filePath: "custom-resource-form/component.ts", lineNumber: 147 }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbW9kdWxlcy9jdXN0b20tcmVzb3VyY2UtcXVvdGEvc3JjL2N1c3RvbS1yZXNvdXJjZS1mb3JtL2NvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL21vZHVsZXMvY3VzdG9tLXJlc291cmNlLXF1b3RhL3NyYy9jdXN0b20tcmVzb3VyY2UtZm9ybS90ZW1wbGF0ZS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFdBQVcsRUFDWCxhQUFhLEVBQ2Isa0JBQWtCLEVBQ2xCLGNBQWMsRUFDZCxhQUFhLEVBQ2IsZ0JBQWdCLEdBQ2pCLE1BQU0sWUFBWSxDQUFDO0FBQ3BCLE9BQU8sRUFFTCxnQkFBZ0IsRUFDaEIsSUFBSSxFQUNKLDJCQUEyQixFQUMzQixPQUFPLEVBQ1AsVUFBVSxFQUdWLGVBQWUsRUFDZix1QkFBdUIsRUFDdkIsNkJBQTZCLEVBQzdCLGdCQUFnQixFQUNoQiwwQkFBMEIsRUFDMUIsZ0JBQWdCLEVBQ2hCLFFBQVEsRUFDUixzQkFBc0IsRUFDdEIsb0JBQW9CLEVBQ3BCLGlDQUFpQyxHQUNsQyxNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRSxPQUFPLEVBRUwsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsS0FBSyxHQUNOLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxnQkFBZ0IsRUFFaEIsU0FBUyxFQUNULG1CQUFtQixFQUNuQixVQUFVLEdBQ1gsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQ0wsU0FBUyxFQUNULE9BQU8sRUFDUCxPQUFPLEVBQ1AsR0FBRyxFQUNILFFBQVEsRUFDUixJQUFJLEVBQ0osSUFBSSxFQUNKLE1BQU0sRUFDTixP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