ngx-material-entity 15.3.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/classes/entity.model.d.ts +2 -2
- package/components/confirm-dialog/confirm-dialog-data.d.ts +1 -1
- package/components/edit-page/edit-page.component.d.ts +4 -2
- package/components/edit-page/page-edit-data.builder.d.ts +1 -1
- package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +1 -0
- package/components/input/array/array-table.class.d.ts +4 -2
- package/components/input/base-input.component.d.ts +5 -1
- package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +1 -1
- package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +1 -1
- package/components/input/file/file-default-input/file-default-input.component.d.ts +0 -2
- package/components/input/file/file-image-input/file-image-input.component.d.ts +3 -2
- package/components/input/file/file-input/file-input.component.d.ts +4 -2
- package/components/input/input.component.d.ts +9 -4
- package/components/input/input.module.d.ts +2 -1
- package/components/table/display-column-value/base-display-column-value.component.d.ts +1 -1
- package/components/table/display-column-value/display-column-value.component.d.ts +1 -1
- package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +3 -1
- package/components/table/table-data.builder.d.ts +1 -1
- package/components/table/table-data.d.ts +1 -1
- package/components/table/table.component.d.ts +1 -1
- package/decorators/base/decorator-types.enum.d.ts +1 -1
- package/decorators/base/property-decorator.data.d.ts +1 -1
- package/decorators/file/file-decorator.data.d.ts +1 -1
- package/decorators/number/number-decorator.data.d.ts +1 -1
- package/decorators/string/string-decorator.data.d.ts +1 -1
- package/encapsulation/jszip.utilities.d.ts +1 -1
- package/encapsulation/uuid.utilities.d.ts +11 -0
- package/esm2022/classes/base.builder.mjs +44 -0
- package/esm2022/classes/entity.model.mjs +26 -0
- package/esm2022/components/confirm-dialog/confirm-dialog-data.builder.mjs +58 -0
- package/esm2022/components/confirm-dialog/confirm-dialog.component.mjs +60 -0
- package/esm2022/components/edit-page/edit-page.component.mjs +291 -0
- package/esm2022/components/input/array/array-date-input/array-date-input.component.mjs +23 -0
- package/esm2022/components/input/array/array-date-range-input/array-date-range-input.component.mjs +49 -0
- package/esm2022/components/input/array/array-date-time-input/array-date-time-input.component.mjs +49 -0
- package/esm2022/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +50 -0
- package/esm2022/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +69 -0
- package/esm2022/components/input/array/array-table.class.mjs +100 -0
- package/esm2022/components/input/base-input.component.mjs +88 -0
- package/esm2022/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +21 -0
- package/esm2022/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +17 -0
- package/esm2022/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +21 -0
- package/esm2022/components/input/custom/custom.component.mjs +28 -0
- package/esm2022/components/input/date/date-input/date-input.component.mjs +19 -0
- package/esm2022/components/input/date/date-range-input/date-range-input.component.mjs +68 -0
- package/esm2022/components/input/date/date-time-input/date-time-input.component.mjs +69 -0
- package/esm2022/components/input/file/file-default-input/file-default-input.component.mjs +18 -0
- package/esm2022/components/input/file/file-image-input/file-image-input.component.mjs +101 -0
- package/esm2022/components/input/file/file-input/dragDrop.directive.mjs +62 -0
- package/esm2022/components/input/file/file-input/file-input.component.mjs +206 -0
- package/esm2022/components/input/input.component.mjs +849 -0
- package/esm2022/components/input/input.module.mjs +172 -0
- package/esm2022/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +23 -0
- package/esm2022/components/input/number/number-input/number-input.component.mjs +16 -0
- package/esm2022/components/input/number/number-slider-input/number-slider-input.component.mjs +17 -0
- package/esm2022/components/input/relations/references-many-input/references-many-input.component.mjs +102 -0
- package/esm2022/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +36 -0
- package/esm2022/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +23 -0
- package/esm2022/components/input/string/string-input/string-input.component.mjs +16 -0
- package/esm2022/components/input/string/string-password-input/string-password-input.component.mjs +39 -0
- package/esm2022/components/input/string/string-textbox-input/string-textbox-input.component.mjs +17 -0
- package/esm2022/components/table/create-dialog/create-dialog-data.builder.mjs +42 -0
- package/esm2022/components/table/create-dialog/create-entity-dialog-data.builder.mjs +32 -0
- package/esm2022/components/table/create-dialog/create-entity-dialog.component.mjs +107 -0
- package/esm2022/components/table/display-column-value/base-display-column-value.component.mjs +28 -0
- package/esm2022/components/table/display-column-value/display-column-value.component.mjs +37 -0
- package/esm2022/components/table/edit-dialog/edit-data.builder.mjs +106 -0
- package/esm2022/components/table/edit-dialog/edit-entity-dialog.component.mjs +209 -0
- package/esm2022/components/table/edit-dialog/edit-entity.builder.mjs +39 -0
- package/esm2022/components/table/table-data.builder.mjs +269 -0
- package/esm2022/components/table/table.component.mjs +348 -0
- package/esm2022/decorators/array/array-decorator-internal.data.mjs +286 -0
- package/esm2022/decorators/array/array-decorator.data.mjs +21 -0
- package/esm2022/decorators/base/property-decorator-internal.data.mjs +82 -0
- package/esm2022/decorators/base/property-decorator.data.mjs +56 -0
- package/esm2022/decorators/boolean/boolean-decorator-internal.data.mjs +43 -0
- package/esm2022/decorators/boolean/boolean-decorator.data.mjs +11 -0
- package/esm2022/decorators/custom/custom-decorator-internal.data.mjs +35 -0
- package/{esm2020 → esm2022}/decorators/date/date-decorator-internal.data.mjs +43 -1
- package/esm2022/decorators/date/date-decorator.data.mjs +11 -0
- package/esm2022/decorators/file/file-decorator-internal.data.mjs +143 -0
- package/esm2022/decorators/file/file-decorator.data.mjs +64 -0
- package/esm2022/decorators/has-many/has-many-decorator-internal.data.mjs +42 -0
- package/esm2022/decorators/number/number-decorator-internal.data.mjs +76 -0
- package/esm2022/decorators/number/number-decorator.data.mjs +11 -0
- package/esm2022/decorators/object/object-decorator-internal.data.mjs +20 -0
- package/esm2022/decorators/object/object-decorator.data.mjs +22 -0
- package/esm2022/decorators/references-many/references-many-decorator-internal.data.mjs +48 -0
- package/esm2022/decorators/references-one/references-one-decorator-internal.data.mjs +24 -0
- package/esm2022/decorators/string/string-decorator-internal.data.mjs +114 -0
- package/esm2022/decorators/string/string-decorator.data.mjs +11 -0
- package/esm2022/encapsulation/uuid.utilities.mjs +15 -0
- package/esm2022/services/entity.service.mjs +276 -0
- package/esm2022/utilities/date.utilities.mjs +159 -0
- package/esm2022/utilities/entity.utilities.mjs +905 -0
- package/esm2022/utilities/file.utilities.mjs +180 -0
- package/{fesm2020 → fesm2022}/ngx-material-entity.mjs +1355 -484
- package/fesm2022/ngx-material-entity.mjs.map +1 -0
- package/package.json +11 -17
- package/utilities/date.utilities.d.ts +1 -1
- package/utilities/entity.utilities.d.ts +7 -3
- package/utilities/file.utilities.d.ts +6 -2
- package/esm2020/classes/base.builder.mjs +0 -42
- package/esm2020/classes/entity.model.mjs +0 -22
- package/esm2020/components/confirm-dialog/confirm-dialog-data.builder.mjs +0 -44
- package/esm2020/components/confirm-dialog/confirm-dialog.component.mjs +0 -57
- package/esm2020/components/edit-page/edit-page.component.mjs +0 -274
- package/esm2020/components/input/array/array-date-input/array-date-input.component.mjs +0 -26
- package/esm2020/components/input/array/array-date-range-input/array-date-range-input.component.mjs +0 -50
- package/esm2020/components/input/array/array-date-time-input/array-date-time-input.component.mjs +0 -49
- package/esm2020/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +0 -49
- package/esm2020/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +0 -70
- package/esm2020/components/input/array/array-table.class.mjs +0 -93
- package/esm2020/components/input/base-input.component.mjs +0 -64
- package/esm2020/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +0 -21
- package/esm2020/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +0 -17
- package/esm2020/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +0 -21
- package/esm2020/components/input/custom/custom.component.mjs +0 -26
- package/esm2020/components/input/date/date-input/date-input.component.mjs +0 -22
- package/esm2020/components/input/date/date-range-input/date-range-input.component.mjs +0 -71
- package/esm2020/components/input/date/date-time-input/date-time-input.component.mjs +0 -71
- package/esm2020/components/input/file/file-default-input/file-default-input.component.mjs +0 -23
- package/esm2020/components/input/file/file-image-input/file-image-input.component.mjs +0 -98
- package/esm2020/components/input/file/file-input/dragDrop.directive.mjs +0 -63
- package/esm2020/components/input/file/file-input/file-input.component.mjs +0 -195
- package/esm2020/components/input/input.component.mjs +0 -746
- package/esm2020/components/input/input.module.mjs +0 -169
- package/esm2020/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +0 -26
- package/esm2020/components/input/number/number-input/number-input.component.mjs +0 -16
- package/esm2020/components/input/number/number-slider-input/number-slider-input.component.mjs +0 -17
- package/esm2020/components/input/relations/references-many-input/references-many-input.component.mjs +0 -100
- package/esm2020/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +0 -34
- package/esm2020/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +0 -26
- package/esm2020/components/input/string/string-input/string-input.component.mjs +0 -16
- package/esm2020/components/input/string/string-password-input/string-password-input.component.mjs +0 -42
- package/esm2020/components/input/string/string-textbox-input/string-textbox-input.component.mjs +0 -17
- package/esm2020/components/table/create-dialog/create-dialog-data.builder.mjs +0 -32
- package/esm2020/components/table/create-dialog/create-entity-dialog-data.builder.mjs +0 -26
- package/esm2020/components/table/create-dialog/create-entity-dialog.component.mjs +0 -100
- package/esm2020/components/table/display-column-value/base-display-column-value.component.mjs +0 -27
- package/esm2020/components/table/display-column-value/display-column-value.component.mjs +0 -33
- package/esm2020/components/table/edit-dialog/edit-data.builder.mjs +0 -76
- package/esm2020/components/table/edit-dialog/edit-entity-dialog.component.mjs +0 -195
- package/esm2020/components/table/edit-dialog/edit-entity.builder.mjs +0 -29
- package/esm2020/components/table/table-data.builder.mjs +0 -205
- package/esm2020/components/table/table.component.mjs +0 -333
- package/esm2020/decorators/array/array-decorator-internal.data.mjs +0 -150
- package/esm2020/decorators/array/array-decorator.data.mjs +0 -7
- package/esm2020/decorators/base/property-decorator-internal.data.mjs +0 -58
- package/esm2020/decorators/base/property-decorator.data.mjs +0 -6
- package/esm2020/decorators/boolean/boolean-decorator-internal.data.mjs +0 -33
- package/esm2020/decorators/boolean/boolean-decorator.data.mjs +0 -7
- package/esm2020/decorators/custom/custom-decorator-internal.data.mjs +0 -27
- package/esm2020/decorators/date/date-decorator.data.mjs +0 -7
- package/esm2020/decorators/file/file-decorator-internal.data.mjs +0 -97
- package/esm2020/decorators/file/file-decorator.data.mjs +0 -7
- package/esm2020/decorators/has-many/has-many-decorator-internal.data.mjs +0 -32
- package/esm2020/decorators/number/number-decorator-internal.data.mjs +0 -54
- package/esm2020/decorators/number/number-decorator.data.mjs +0 -7
- package/esm2020/decorators/object/object-decorator-internal.data.mjs +0 -14
- package/esm2020/decorators/object/object-decorator.data.mjs +0 -7
- package/esm2020/decorators/references-many/references-many-decorator-internal.data.mjs +0 -30
- package/esm2020/decorators/references-one/references-one-decorator-internal.data.mjs +0 -16
- package/esm2020/decorators/string/string-decorator-internal.data.mjs +0 -72
- package/esm2020/decorators/string/string-decorator.data.mjs +0 -7
- package/esm2020/services/entity.service.mjs +0 -274
- package/esm2020/utilities/date.utilities.mjs +0 -159
- package/esm2020/utilities/entity.utilities.mjs +0 -896
- package/esm2020/utilities/file.utilities.mjs +0 -176
- package/fesm2015/ngx-material-entity.mjs +0 -6300
- package/fesm2015/ngx-material-entity.mjs.map +0 -1
- package/fesm2020/ngx-material-entity.mjs.map +0 -1
- /package/{esm2020 → esm2022}/components/confirm-dialog/confirm-dialog-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/edit-page/edit-data.route.mjs +0 -0
- /package/{esm2020 → esm2022}/components/edit-page/page-edit-data.builder.mjs +0 -0
- /package/{esm2020 → esm2022}/components/get-validation-error-message.function.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/create-dialog/create-entity-dialog-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/default.actions.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/edit-dialog/edit-entity-data.mjs +0 -0
- /package/{esm2020 → esm2022}/components/table/table-data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/array/array.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/base-property.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/decorator-types.enum.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/base/dropdown-value.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/boolean/boolean.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/custom/custom-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/custom/custom.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/date/date.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/file/file.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/has-many/has-many-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/has-many/has-many.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/number/number.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/object/object.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-many/references-many-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-many/references-many.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-one/references-one-decorator.data.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/references-one/references-one.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/decorators/string/string.decorator.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/js-2-xml.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/jszip.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/lodash.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/encapsulation/reflect.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/default-false.function.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/default-true.function.mjs +0 -0
- /package/{esm2020 → esm2022}/functions/is-async-function.function.mjs +0 -0
- /package/{esm2020 → esm2022}/mocks/placeholder-data.png.mjs +0 -0
- /package/{esm2020 → esm2022}/ngx-material-entity.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/services/unsaved-changes.guard.mjs +0 -0
- /package/{esm2020 → esm2022}/utilities/selection.utilities.mjs +0 -0
|
@@ -1,746 +0,0 @@
|
|
|
1
|
-
import { SelectionModel } from '@angular/cdk/collections';
|
|
2
|
-
import { Component, EnvironmentInjector, EventEmitter, Inject, Input, Output, TemplateRef, ViewChild, inject } from '@angular/core';
|
|
3
|
-
import { MatDialog } from '@angular/material/dialog';
|
|
4
|
-
import { MatPaginator } from '@angular/material/paginator';
|
|
5
|
-
import { MatSort } from '@angular/material/sort';
|
|
6
|
-
import { MatTableDataSource } from '@angular/material/table';
|
|
7
|
-
import { Router } from '@angular/router';
|
|
8
|
-
import { firstValueFrom } from 'rxjs';
|
|
9
|
-
import { DecoratorTypes } from '../../decorators/base/decorator-types.enum';
|
|
10
|
-
import { LodashUtilities } from '../../encapsulation/lodash.utilities';
|
|
11
|
-
import { ReflectUtilities } from '../../encapsulation/reflect.utilities';
|
|
12
|
-
import { defaultFalse } from '../../functions/default-false.function';
|
|
13
|
-
import { DateUtilities } from '../../utilities/date.utilities';
|
|
14
|
-
import { EntityUtilities } from '../../utilities/entity.utilities';
|
|
15
|
-
import { SelectionUtilities } from '../../utilities/selection.utilities';
|
|
16
|
-
import { ConfirmDialogDataBuilder } from '../confirm-dialog/confirm-dialog-data.builder';
|
|
17
|
-
import { NgxMatEntityConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component';
|
|
18
|
-
import { NGX_GET_VALIDATION_ERROR_MESSAGE } from '../get-validation-error-message.function';
|
|
19
|
-
import { CreateDialogDataBuilder } from '../table/create-dialog/create-dialog-data.builder';
|
|
20
|
-
import { BaseTableActionInternal } from '../table/table-data.builder';
|
|
21
|
-
import * as i0 from "@angular/core";
|
|
22
|
-
import * as i1 from "@angular/material/dialog";
|
|
23
|
-
import * as i2 from "@angular/router";
|
|
24
|
-
import * as i3 from "@angular/common";
|
|
25
|
-
import * as i4 from "@angular/material/input";
|
|
26
|
-
import * as i5 from "@angular/material/form-field";
|
|
27
|
-
import * as i6 from "@angular/forms";
|
|
28
|
-
import * as i7 from "@angular/material/select";
|
|
29
|
-
import * as i8 from "@angular/material/core";
|
|
30
|
-
import * as i9 from "@angular/material/checkbox";
|
|
31
|
-
import * as i10 from "@angular/material/table";
|
|
32
|
-
import * as i11 from "@angular/material/button";
|
|
33
|
-
import * as i12 from "@angular/material/tabs";
|
|
34
|
-
import * as i13 from "@angular/material/menu";
|
|
35
|
-
import * as i14 from "@angular/material/progress-spinner";
|
|
36
|
-
import * as i15 from "@angular/material/paginator";
|
|
37
|
-
import * as i16 from "./string/string-input/string-input.component";
|
|
38
|
-
import * as i17 from "./string/string-textbox-input/string-textbox-input.component";
|
|
39
|
-
import * as i18 from "./string/string-autocomplete-input/string-autocomplete-input.component";
|
|
40
|
-
import * as i19 from "./string/string-dropdown-input/string-dropdown-input.component";
|
|
41
|
-
import * as i20 from "./string/string-password-input/string-password-input.component";
|
|
42
|
-
import * as i21 from "./boolean/boolean-checkbox-input/boolean-checkbox-input.component";
|
|
43
|
-
import * as i22 from "./boolean/boolean-toggle-input/boolean-toggle-input.component";
|
|
44
|
-
import * as i23 from "./boolean/boolean-dropdown-input/boolean-dropdown-input.component";
|
|
45
|
-
import * as i24 from "./number/number-input/number-input.component";
|
|
46
|
-
import * as i25 from "./number/number-dropdown-input/number-dropdown-input.component";
|
|
47
|
-
import * as i26 from "./number/number-slider-input/number-slider-input.component";
|
|
48
|
-
import * as i27 from "./array/array-string-chips-input/array-string-chips-input.component";
|
|
49
|
-
import * as i28 from "./array/array-string-autocomplete-chips/array-string-autocomplete-chips.component";
|
|
50
|
-
import * as i29 from "./date/date-input/date-input.component";
|
|
51
|
-
import * as i30 from "./date/date-range-input/date-range-input.component";
|
|
52
|
-
import * as i31 from "./date/date-time-input/date-time-input.component";
|
|
53
|
-
import * as i32 from "./array/array-date-input/array-date-input.component";
|
|
54
|
-
import * as i33 from "./array/array-date-time-input/array-date-time-input.component";
|
|
55
|
-
import * as i34 from "./array/array-date-range-input/array-date-range-input.component";
|
|
56
|
-
import * as i35 from "./file/file-image-input/file-image-input.component";
|
|
57
|
-
import * as i36 from "./file/file-default-input/file-default-input.component";
|
|
58
|
-
import * as i37 from "./relations/references-many-input/references-many-input.component";
|
|
59
|
-
import * as i38 from "./custom/custom.component";
|
|
60
|
-
/**
|
|
61
|
-
* The default input component. It gets the metadata of the property from the given @Input "entity" and @Input "propertyKey"
|
|
62
|
-
* and displays the input field accordingly.
|
|
63
|
-
*
|
|
64
|
-
* You can also define a method that generates error-messages and if the input should be hidden when its metadata says
|
|
65
|
-
* that it should be omitted for creating or updating.
|
|
66
|
-
* The last part being mostly relevant if you want to use this component inside an ngFor.
|
|
67
|
-
*/
|
|
68
|
-
export class NgxMatEntityInputComponent {
|
|
69
|
-
constructor(dialog, injector, router, defaultGetValidationErrorMessage) {
|
|
70
|
-
this.dialog = dialog;
|
|
71
|
-
this.injector = injector;
|
|
72
|
-
this.router = router;
|
|
73
|
-
this.defaultGetValidationErrorMessage = defaultGetValidationErrorMessage;
|
|
74
|
-
this.inputChangeEvent = new EventEmitter();
|
|
75
|
-
this.entityArraySelection = new SelectionModel(true, []);
|
|
76
|
-
this.isArrayItemValid = false;
|
|
77
|
-
this.isArrayItemDirty = false;
|
|
78
|
-
this.hasManyIsLoading = true;
|
|
79
|
-
this.hasManyDataSource = new MatTableDataSource();
|
|
80
|
-
this.hasManySelection = new SelectionModel(true, []);
|
|
81
|
-
this.isHasManyEntityValid = false;
|
|
82
|
-
this.isHasManyEntityDirty = false;
|
|
83
|
-
this.DecoratorTypes = DecoratorTypes;
|
|
84
|
-
this.EntityUtilities = EntityUtilities;
|
|
85
|
-
this.DateUtilities = DateUtilities;
|
|
86
|
-
this.SelectionUtilities = SelectionUtilities;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Checks if the input with the given key on the given property is readonly.
|
|
90
|
-
*
|
|
91
|
-
* @param property - The property on which to check the input.
|
|
92
|
-
* @param key - The key for the input to check.
|
|
93
|
-
* @returns Whether or not the input is readonly.
|
|
94
|
-
*/
|
|
95
|
-
isPropertyReadOnly(property, key) {
|
|
96
|
-
return this.injector.runInContext(() => {
|
|
97
|
-
if (this.internalIsReadOnly || this.metadataDefaultObject?.isReadOnly(property)) {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
const metadata = EntityUtilities.getPropertyMetadata(property, key);
|
|
101
|
-
return metadata.isReadOnly(property);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* This is needed for the inputs to work inside an ngFor.
|
|
106
|
-
*
|
|
107
|
-
* @param index - The index of the element in the ngFor.
|
|
108
|
-
* @returns The index.
|
|
109
|
-
*/
|
|
110
|
-
trackByFn(index) {
|
|
111
|
-
return index;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Gets the value to display in the column.
|
|
115
|
-
* Runs in environment context to enable injection.
|
|
116
|
-
*
|
|
117
|
-
* @param entity - The entity to get the value from.
|
|
118
|
-
* @param displayColumn - The display column to get the value from.
|
|
119
|
-
* @returns The value of the display column.
|
|
120
|
-
*/
|
|
121
|
-
getDisplayColumnValue(entity, displayColumn) {
|
|
122
|
-
return this.injector.runInContext(() => {
|
|
123
|
-
return displayColumn.value(entity);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
ngOnInit() {
|
|
127
|
-
if (!this.entity) {
|
|
128
|
-
throw new Error('Missing required Input data "entity"');
|
|
129
|
-
}
|
|
130
|
-
this.internalEntity = this.entity;
|
|
131
|
-
if (this.propertyKey == null) {
|
|
132
|
-
throw new Error('Missing required Input data "propertyKey"');
|
|
133
|
-
}
|
|
134
|
-
this.internalPropertyKey = this.propertyKey;
|
|
135
|
-
this.internalGetValidationErrorMessage = this.getValidationErrorMessage ?? this.defaultGetValidationErrorMessage;
|
|
136
|
-
this.internalIsReadOnly = this.isReadOnly ?? false;
|
|
137
|
-
this.type = EntityUtilities.getPropertyType(this.internalEntity, this.internalPropertyKey);
|
|
138
|
-
if (this.validEmpty === true) {
|
|
139
|
-
// eslint-disable-next-line max-len
|
|
140
|
-
const currentMetadata = ReflectUtilities.getMetadata('metadata', this.internalEntity, this.internalPropertyKey);
|
|
141
|
-
// eslint-disable-next-line max-len
|
|
142
|
-
ReflectUtilities.defineMetadata('metadata', { ...currentMetadata, required: defaultFalse }, this.internalEntity, this.internalPropertyKey);
|
|
143
|
-
}
|
|
144
|
-
this.metadata = EntityUtilities.getPropertyMetadata(this.internalEntity, this.internalPropertyKey, this.type);
|
|
145
|
-
switch (this.type) {
|
|
146
|
-
case DecoratorTypes.OBJECT:
|
|
147
|
-
this.initObjectInput();
|
|
148
|
-
break;
|
|
149
|
-
case DecoratorTypes.ARRAY:
|
|
150
|
-
this.initEntityArray();
|
|
151
|
-
break;
|
|
152
|
-
case DecoratorTypes.HAS_MANY:
|
|
153
|
-
this.initHasMany();
|
|
154
|
-
break;
|
|
155
|
-
case DecoratorTypes.REFERENCES_ONE:
|
|
156
|
-
this.initReferencesOne();
|
|
157
|
-
break;
|
|
158
|
-
default:
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
initReferencesOne() {
|
|
163
|
-
this.metadataReferencesOne = this.metadata;
|
|
164
|
-
void this.injector.runInContext(async () => {
|
|
165
|
-
this.referencesOneAllReferencedEntities = await this.metadataReferencesOne.getReferencedEntities();
|
|
166
|
-
// eslint-disable-next-line max-len
|
|
167
|
-
this.referencesOneDropdownValues = this.metadataReferencesOne.getDropdownValues(LodashUtilities.cloneDeep(this.referencesOneAllReferencedEntities));
|
|
168
|
-
this.setReferencesOneObject();
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
initHasMany() {
|
|
172
|
-
this.metadataHasMany = this.metadata;
|
|
173
|
-
this.hasManyImportAction = new BaseTableActionInternal({
|
|
174
|
-
...this.metadataHasMany.tableData.baseData.importActionData,
|
|
175
|
-
action: () => this.startImportJson()
|
|
176
|
-
});
|
|
177
|
-
this.injector.runInContext(() => {
|
|
178
|
-
this.hasManyAllowCreate = this.metadataHasMany.tableData.baseData.allowCreate();
|
|
179
|
-
this.hasManyEntityService = inject(this.metadataHasMany.tableData.baseData.EntityServiceClass);
|
|
180
|
-
this.hasManyCreateBaseUrl = this.metadataHasMany.createBaseUrl(this.internalEntity, this.metadataHasMany);
|
|
181
|
-
});
|
|
182
|
-
const givenDisplayColumns = this.metadataHasMany.tableData.baseData.displayColumns.map((v) => v.displayName);
|
|
183
|
-
if (this.metadataHasMany.tableData.baseData.tableActions.filter(tA => tA.type === 'multi-select').length) {
|
|
184
|
-
this.displayedHasManyColumns = ['select'].concat(givenDisplayColumns);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
this.displayedHasManyColumns = givenDisplayColumns;
|
|
188
|
-
}
|
|
189
|
-
this.hasManyDataSource.sortingDataAccessor = (entity, header) => {
|
|
190
|
-
return this.injector.runInContext(() => {
|
|
191
|
-
// eslint-disable-next-line max-len
|
|
192
|
-
return this.metadataHasMany.tableData.baseData.displayColumns.find((dp) => dp.displayName === header)?.value(entity);
|
|
193
|
-
});
|
|
194
|
-
};
|
|
195
|
-
this.hasManyDataSource.sort = this.hasManySort;
|
|
196
|
-
this.hasManyDataSource.filterPredicate = (entity, filter) => {
|
|
197
|
-
const searchStr = this.metadataHasMany.tableData.baseData.searchString(entity);
|
|
198
|
-
const formattedSearchString = searchStr.toLowerCase();
|
|
199
|
-
const formattedFilterString = filter.toLowerCase();
|
|
200
|
-
return formattedSearchString.includes(formattedFilterString);
|
|
201
|
-
};
|
|
202
|
-
this.hasManyDataSource.filter = this.hasManyFilter;
|
|
203
|
-
this.hasManyDataSource.paginator = this.hasManyPaginator;
|
|
204
|
-
this.hasManyEntityService.entitiesSubject.subscribe((entities) => {
|
|
205
|
-
this.hasManyDataSource.data = entities;
|
|
206
|
-
this.hasManySelection.clear();
|
|
207
|
-
});
|
|
208
|
-
this.injector.runInContext(() => {
|
|
209
|
-
const readBaseUrl = this.metadataHasMany.readBaseUrl(this.internalEntity, this.metadataHasMany);
|
|
210
|
-
void this.hasManyEntityService.read(readBaseUrl).then(() => {
|
|
211
|
-
this.hasManyIsLoading = false;
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
initEntityArray() {
|
|
216
|
-
this.metadataEntityArray = this.metadata;
|
|
217
|
-
if (this.internalEntity[this.internalPropertyKey] == null) {
|
|
218
|
-
this.internalEntity[this.internalPropertyKey] = [];
|
|
219
|
-
}
|
|
220
|
-
this.entityArrayValues = this.internalEntity[this.internalPropertyKey];
|
|
221
|
-
if (!this.metadataEntityArray.createInline && !this.metadataEntityArray.createDialogData) {
|
|
222
|
-
this.metadataEntityArray.createDialogData = {
|
|
223
|
-
title: 'Add'
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
const givenDisplayColumns = this.metadataEntityArray.displayColumns.map((v) => v.displayName);
|
|
227
|
-
if (givenDisplayColumns.find(s => s === 'select')) {
|
|
228
|
-
throw new Error(`The name "select" for a display column is reserved.
|
|
229
|
-
Please choose a different name.`);
|
|
230
|
-
}
|
|
231
|
-
this.entityArrayDisplayedColumns = this.internalIsReadOnly ? givenDisplayColumns : ['select'].concat(givenDisplayColumns);
|
|
232
|
-
this.entityArrayDataSource = new MatTableDataSource();
|
|
233
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
234
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass();
|
|
235
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
236
|
-
this.arrayItemInlineTabs = EntityUtilities.getEntityTabs(this.arrayItem, true);
|
|
237
|
-
this.addArrayItemDialogData = new CreateDialogDataBuilder(this.metadataEntityArray.createDialogData)
|
|
238
|
-
.withDefault('createButtonLabel', 'Add')
|
|
239
|
-
.withDefault('title', 'Add to array')
|
|
240
|
-
.getResult();
|
|
241
|
-
this.arrayItemDialogTabs = EntityUtilities.getEntityTabs(this.arrayItem, true);
|
|
242
|
-
this.editArrayItemDialogData = this.metadataEntityArray.editDialogData;
|
|
243
|
-
}
|
|
244
|
-
initObjectInput() {
|
|
245
|
-
this.metadataDefaultObject = this.metadata;
|
|
246
|
-
this.objectProperty = this.internalEntity[this.internalPropertyKey];
|
|
247
|
-
this.objectPropertyTabs = EntityUtilities.getEntityTabs(this.objectProperty, this.hideOmitForCreate, this.hideOmitForEdit, this.metadataDefaultObject.omit);
|
|
248
|
-
}
|
|
249
|
-
startImportJson() {
|
|
250
|
-
const input = document.createElement('input');
|
|
251
|
-
input.type = 'file';
|
|
252
|
-
input.accept = 'application/json';
|
|
253
|
-
input.onchange = async () => {
|
|
254
|
-
if (input.files) {
|
|
255
|
-
this.importJson(input.files[0]);
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
input.click();
|
|
259
|
-
}
|
|
260
|
-
importJson(file) {
|
|
261
|
-
const dialogData = new ConfirmDialogDataBuilder(this.hasManyImportAction.confirmDialogData)
|
|
262
|
-
.withDefault('text', this.metadataHasMany.tableData.baseData.importActionData.confirmDialogData?.text)
|
|
263
|
-
.withDefault('title', this.hasManyImportAction.displayName)
|
|
264
|
-
.getResult();
|
|
265
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
266
|
-
data: dialogData,
|
|
267
|
-
autoFocus: false,
|
|
268
|
-
restoreFocus: false
|
|
269
|
-
});
|
|
270
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
271
|
-
if (res == true) {
|
|
272
|
-
void this.hasManyEntityService.import(file);
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Sets the references one object using the input id.
|
|
278
|
-
*/
|
|
279
|
-
setReferencesOneObject() {
|
|
280
|
-
// eslint-disable-next-line max-len
|
|
281
|
-
const foundEntity = this.metadataReferencesOne.getEntityForId(this.internalEntity[this.internalPropertyKey], this.referencesOneAllReferencedEntities);
|
|
282
|
-
this.referencesOneObject = new this.metadataReferencesOne.EntityClass(foundEntity);
|
|
283
|
-
this.referencesOnePropertyTabs = EntityUtilities.getEntityTabs(this.referencesOneObject);
|
|
284
|
-
this.emitChange();
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Edits an entity. This either calls the edit-Method provided by the user or uses a default edit-dialog.
|
|
288
|
-
*
|
|
289
|
-
* @param entity - The entity that should be updated.
|
|
290
|
-
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
291
|
-
*/
|
|
292
|
-
editHasManyEntity(entity) {
|
|
293
|
-
if (!(this.hasManyAllowUpdate(entity) || this.hasManyAllowRead(entity))) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
if (!this.metadataHasMany.tableData.baseData.EntityClass) {
|
|
297
|
-
throw new Error('No "EntityClass" specified for this table');
|
|
298
|
-
}
|
|
299
|
-
if (this.metadataHasMany.tableData.baseData.edit) {
|
|
300
|
-
this.metadataHasMany.tableData.baseData.edit(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
if (this.metadataHasMany.tableData.baseData.defaultEdit == 'page') {
|
|
304
|
-
this.editHasManyDefaultPage(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
void this.editHasManyDefaultDialog(new this.metadataHasMany.tableData.baseData.EntityClass(entity));
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Whether updating the provided entity from the has many property is allowed.
|
|
311
|
-
*
|
|
312
|
-
* @param entity - A single value of the has many property that the user wants to edit.
|
|
313
|
-
* @returns True when the user can edit the provided entity and false otherwise.
|
|
314
|
-
*/
|
|
315
|
-
hasManyAllowUpdate(entity) {
|
|
316
|
-
return this.injector.runInContext(() => {
|
|
317
|
-
return this.metadataHasMany.tableData.baseData.allowUpdate(entity);
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Whether viewing the provided entity from the has many property is allowed.
|
|
322
|
-
*
|
|
323
|
-
* @param entity - A single value of the has many property that the user wants to view.
|
|
324
|
-
* @returns True when the user can view the provided entity and false otherwise.
|
|
325
|
-
*/
|
|
326
|
-
hasManyAllowRead(entity) {
|
|
327
|
-
return this.injector.runInContext(() => {
|
|
328
|
-
return this.metadataHasMany.tableData.baseData.allowRead(entity);
|
|
329
|
-
});
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Whether deleting the provided entity from the has many property is allowed.
|
|
333
|
-
*
|
|
334
|
-
* @param entity - A single value of the has many property that the user wants to delete.
|
|
335
|
-
* @returns True when the user can delete the provided entity and false otherwise.
|
|
336
|
-
*/
|
|
337
|
-
hasManyAllowDelete(entity) {
|
|
338
|
-
return this.injector.runInContext(() => {
|
|
339
|
-
return this.metadataHasMany.tableData.baseData.allowDelete(entity);
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
editHasManyDefaultPage(entity) {
|
|
343
|
-
void this.router.navigate(['', this.hasManyEntityService.editBaseRoute, entity[this.hasManyEntityService.idKey]]);
|
|
344
|
-
}
|
|
345
|
-
async editHasManyDefaultDialog(entity) {
|
|
346
|
-
this.hasManyEntity = LodashUtilities.cloneDeep(entity);
|
|
347
|
-
this.hasManyEntityPriorChanges = LodashUtilities.cloneDeep(this.hasManyEntity);
|
|
348
|
-
this.hasManyUpdateTabs = EntityUtilities.getEntityTabs(this.hasManyEntity, false, true);
|
|
349
|
-
await this.checkHasManyEntity();
|
|
350
|
-
this.editHasManyDialogRef = this.dialog.open(this.editHasManyDialog, {
|
|
351
|
-
minWidth: '60%',
|
|
352
|
-
autoFocus: false,
|
|
353
|
-
restoreFocus: false
|
|
354
|
-
});
|
|
355
|
-
const res = await firstValueFrom(this.editHasManyDialogRef.afterClosed());
|
|
356
|
-
if (res === 0) {
|
|
357
|
-
const data = this.hasManyDataSource.data;
|
|
358
|
-
// eslint-disable-next-line max-len
|
|
359
|
-
data[this.hasManyDataSource.data.findIndex((e) => e[this.hasManyEntityService.idKey] === entity[this.hasManyEntityService.idKey])] = entity;
|
|
360
|
-
this.hasManyDataSource.data = data;
|
|
361
|
-
this.hasManySelection.clear();
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Tries to save the changes and close the dialog afterwards.
|
|
366
|
-
* Also handles the confirmation if required.
|
|
367
|
-
*/
|
|
368
|
-
dialogEditHasMany() {
|
|
369
|
-
if (this.internalIsReadOnly || !this.isHasManyEntityValid || !this.isHasManyEntityDirty) {
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
if (!this.metadataHasMany.tableData.editData.editRequiresConfirmDialog) {
|
|
373
|
-
this.dialogConfirmEditHasMany();
|
|
374
|
-
return;
|
|
375
|
-
}
|
|
376
|
-
// eslint-disable-next-line max-len
|
|
377
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.editData.confirmEditDialogData)
|
|
378
|
-
.withDefault('text', ['Do you really want to save all changes?'])
|
|
379
|
-
.withDefault('confirmButtonLabel', 'Save')
|
|
380
|
-
.withDefault('title', 'Edit')
|
|
381
|
-
.getResult();
|
|
382
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
383
|
-
data: dialogData,
|
|
384
|
-
autoFocus: false,
|
|
385
|
-
restoreFocus: false
|
|
386
|
-
});
|
|
387
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
388
|
-
if (res == true) {
|
|
389
|
-
this.dialogConfirmEditHasMany();
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
dialogConfirmEditHasMany() {
|
|
394
|
-
void this.hasManyEntityService.update(this.hasManyEntity, this.hasManyEntityPriorChanges)
|
|
395
|
-
.then(() => {
|
|
396
|
-
this.editHasManyDialogRef.close(1);
|
|
397
|
-
this.emitChange();
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Tries to delete the entity and close the dialog afterwards.
|
|
402
|
-
* Also handles the confirmation if required.
|
|
403
|
-
*/
|
|
404
|
-
deleteHasManyEntity() {
|
|
405
|
-
if (!this.metadataHasMany.tableData.editData.deleteRequiresConfirmDialog) {
|
|
406
|
-
this.confirmDeleteHasManyEntity();
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
// eslint-disable-next-line max-len
|
|
410
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.editData.confirmDeleteDialogData)
|
|
411
|
-
.withDefault('text', ['Do you really want to delete this entity?'])
|
|
412
|
-
.withDefault('type', 'delete')
|
|
413
|
-
.withDefault('confirmButtonLabel', 'Delete')
|
|
414
|
-
.withDefault('title', 'Delete')
|
|
415
|
-
.getResult();
|
|
416
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
417
|
-
data: dialogData,
|
|
418
|
-
autoFocus: false,
|
|
419
|
-
restoreFocus: false
|
|
420
|
-
});
|
|
421
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
422
|
-
if (res == true) {
|
|
423
|
-
this.confirmDeleteHasManyEntity();
|
|
424
|
-
}
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
confirmDeleteHasManyEntity() {
|
|
428
|
-
void this.hasManyEntityService.delete(this.hasManyEntityPriorChanges).then(() => {
|
|
429
|
-
this.editHasManyDialogRef.close(2);
|
|
430
|
-
this.emitChange();
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Cancels the editing of the has many entity and closes the dialog.
|
|
435
|
-
*/
|
|
436
|
-
dialogCancelEditHasMany() {
|
|
437
|
-
EntityUtilities.resetChangesOnEntity(this.hasManyEntity, this.hasManyEntityPriorChanges);
|
|
438
|
-
this.editHasManyDialogRef.close(0);
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Creates a new Entity. This either calls the create-Method provided by the user or uses a default create-dialog.
|
|
442
|
-
*
|
|
443
|
-
* @throws When no EntityClass was provided, as a new call is needed to initialize metadata.
|
|
444
|
-
*/
|
|
445
|
-
createHasManyEntity() {
|
|
446
|
-
this.injector.runInContext(() => {
|
|
447
|
-
if (this.metadataHasMany.tableData.baseData.allowCreate()) {
|
|
448
|
-
if (!this.metadataHasMany.tableData.baseData.EntityClass) {
|
|
449
|
-
throw new Error('No "EntityClass" specified for this table');
|
|
450
|
-
}
|
|
451
|
-
if (this.metadataHasMany.tableData.baseData.create) {
|
|
452
|
-
this.metadataHasMany.tableData.baseData.create(new this.metadataHasMany.tableData.baseData.EntityClass());
|
|
453
|
-
}
|
|
454
|
-
else {
|
|
455
|
-
this.createHasManyDefault(new this.metadataHasMany.tableData.baseData.EntityClass());
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
createHasManyDefault(entity) {
|
|
461
|
-
this.hasManyEntity = entity;
|
|
462
|
-
this.hasManyCreateTabs = EntityUtilities.getEntityTabs(this.hasManyEntity, true);
|
|
463
|
-
this.checkIsHasManyEntityValid('create');
|
|
464
|
-
this.createHasManyDialogRef = this.dialog.open(this.createHasManyDialog, {
|
|
465
|
-
minWidth: '60%',
|
|
466
|
-
autoFocus: false,
|
|
467
|
-
restoreFocus: false
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Creates the has many entity over the dialog.
|
|
472
|
-
*/
|
|
473
|
-
dialogCreateHasMany() {
|
|
474
|
-
if (!this.isHasManyEntityValid) {
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
if (!this.metadataHasMany.tableData.createDialogData.createRequiresConfirmDialog) {
|
|
478
|
-
this.dialogConfirmCreateHasMany();
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
// eslint-disable-next-line max-len
|
|
482
|
-
const dialogData = new ConfirmDialogDataBuilder(this.metadataHasMany.tableData.createDialogData.confirmCreateDialogData)
|
|
483
|
-
.withDefault('text', ['Do you really want to create this entity?'])
|
|
484
|
-
.withDefault('confirmButtonLabel', 'Create')
|
|
485
|
-
.withDefault('title', 'Create')
|
|
486
|
-
.getResult();
|
|
487
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
488
|
-
data: dialogData,
|
|
489
|
-
autoFocus: false,
|
|
490
|
-
restoreFocus: false
|
|
491
|
-
});
|
|
492
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
493
|
-
if (res == true) {
|
|
494
|
-
this.dialogConfirmCreateHasMany();
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
dialogConfirmCreateHasMany() {
|
|
499
|
-
void this.hasManyEntityService.create(this.hasManyEntity, this.hasManyCreateBaseUrl).then(() => {
|
|
500
|
-
this.createHasManyDialogRef.close();
|
|
501
|
-
this.emitChange();
|
|
502
|
-
});
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Cancels the creating of the has many entity and closes the dialog.
|
|
506
|
-
*/
|
|
507
|
-
dialogCancelCreateHasMany() {
|
|
508
|
-
this.createHasManyDialogRef.close();
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Runs the TableAction for all selected entries.
|
|
512
|
-
* Also handles confirmation with an additional dialog if configured.
|
|
513
|
-
*
|
|
514
|
-
* @param action - The TableAction to run.
|
|
515
|
-
*/
|
|
516
|
-
runHasManyTableAction(action) {
|
|
517
|
-
const requireConfirmDialog = this.injector.runInContext(() => {
|
|
518
|
-
return action.requireConfirmDialog(this.hasManySelection.selected);
|
|
519
|
-
});
|
|
520
|
-
if (!requireConfirmDialog) {
|
|
521
|
-
this.confirmRunHasManyTableAction(action);
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
const dialogData = new ConfirmDialogDataBuilder(action.confirmDialogData)
|
|
525
|
-
.withDefault('text', [`Do you really want to run this action on ${this.hasManySelection.selected.length} entries?`])
|
|
526
|
-
.withDefault('title', action.displayName)
|
|
527
|
-
.getResult();
|
|
528
|
-
const dialogRef = this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
529
|
-
data: dialogData,
|
|
530
|
-
autoFocus: false,
|
|
531
|
-
restoreFocus: false
|
|
532
|
-
});
|
|
533
|
-
dialogRef.afterClosed().subscribe(res => {
|
|
534
|
-
if (res == true) {
|
|
535
|
-
this.confirmRunHasManyTableAction(action);
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
confirmRunHasManyTableAction(action) {
|
|
540
|
-
void this.injector.runInContext(async () => {
|
|
541
|
-
await action.action(this.hasManySelection.selected);
|
|
542
|
-
this.emitChange();
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Checks if an TableAction is disabled (e.g. Because no entries have been selected).
|
|
547
|
-
*
|
|
548
|
-
* @param action - The TableAction to check.
|
|
549
|
-
* @returns Whether or not the Action can be used.
|
|
550
|
-
*/
|
|
551
|
-
hasManyTableActionDisabled(action) {
|
|
552
|
-
return this.injector.runInContext(() => {
|
|
553
|
-
return !action.enabled(this.hasManySelection.selected);
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Applies the search input to filter the table entries.
|
|
558
|
-
*
|
|
559
|
-
* @param event - The keyup-event which contains the search-string of the user.
|
|
560
|
-
*/
|
|
561
|
-
applyHasManyFilter(event) {
|
|
562
|
-
const filterValue = event.target.value;
|
|
563
|
-
this.hasManyDataSource.filter = filterValue.trim().toLowerCase();
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Checks if the entity is valid for updating and if it is dirty.
|
|
567
|
-
*/
|
|
568
|
-
async checkHasManyEntity() {
|
|
569
|
-
this.checkIsHasManyEntityValid('update');
|
|
570
|
-
this.isHasManyEntityDirty = await EntityUtilities.isDirty(this.hasManyEntity, this.hasManyEntityPriorChanges);
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Checks if the entity is valid.
|
|
574
|
-
*
|
|
575
|
-
* @param omit - Whether values omitted for create or update should be left out.
|
|
576
|
-
*/
|
|
577
|
-
checkIsHasManyEntityValid(omit) {
|
|
578
|
-
this.isHasManyEntityValid = EntityUtilities.isEntityValid(this.hasManyEntity, omit);
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Checks whether the array item is valid and if the array item is dirty.
|
|
582
|
-
*/
|
|
583
|
-
checkArrayItem() {
|
|
584
|
-
this.checkIsArrayItemValid();
|
|
585
|
-
void this.checkIsArrayItemDirty();
|
|
586
|
-
}
|
|
587
|
-
/**
|
|
588
|
-
* Checks if the array item is dirty.
|
|
589
|
-
*/
|
|
590
|
-
async checkIsArrayItemDirty() {
|
|
591
|
-
this.isArrayItemDirty = await EntityUtilities.isDirty(this.arrayItem, this.arrayItemPriorChanges);
|
|
592
|
-
}
|
|
593
|
-
/**
|
|
594
|
-
* Checks if the arrayItem is valid.
|
|
595
|
-
*/
|
|
596
|
-
checkIsArrayItemValid() {
|
|
597
|
-
this.isArrayItemValid = EntityUtilities.isEntityValid(this.arrayItem, 'create');
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Emits that a the value has been changed.
|
|
601
|
-
*/
|
|
602
|
-
emitChange() {
|
|
603
|
-
this.inputChangeEvent.emit();
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* Tries to add an item to the entity array.
|
|
607
|
-
* Does this either inline if the "createInline"-metadata is set to true
|
|
608
|
-
* or in a separate dialog if it is set to false.
|
|
609
|
-
*/
|
|
610
|
-
async addEntity() {
|
|
611
|
-
if (this.metadataEntityArray.createInline) {
|
|
612
|
-
if (!this.metadataEntityArray.allowDuplicates) {
|
|
613
|
-
for (const v of this.entityArrayValues) {
|
|
614
|
-
if ((await EntityUtilities.isEqual(this.arrayItem, v, this.metadata, this.metadataEntityArray.itemType))) {
|
|
615
|
-
this.dialog.open(NgxMatEntityConfirmDialogComponent, {
|
|
616
|
-
data: this.metadataEntityArray.duplicatesErrorDialog,
|
|
617
|
-
autoFocus: false,
|
|
618
|
-
restoreFocus: false
|
|
619
|
-
});
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
625
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
626
|
-
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
627
|
-
this.checkIsArrayItemValid();
|
|
628
|
-
this.emitChange();
|
|
629
|
-
}
|
|
630
|
-
else {
|
|
631
|
-
this.addArrayItemDialogRef = this.dialog.open(this.addArrayItemDialog, {
|
|
632
|
-
minWidth: '60%',
|
|
633
|
-
autoFocus: false,
|
|
634
|
-
restoreFocus: false
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
/**
|
|
639
|
-
* Adds the array item defined in the dialog.
|
|
640
|
-
*/
|
|
641
|
-
addArrayItem() {
|
|
642
|
-
if (!this.isArrayItemValid) {
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
this.entityArrayValues.push(LodashUtilities.cloneDeep(this.arrayItem));
|
|
646
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
647
|
-
this.closeAddArrayItemDialog();
|
|
648
|
-
}
|
|
649
|
-
/**
|
|
650
|
-
* Cancels adding the array item defined in the dialog.
|
|
651
|
-
*/
|
|
652
|
-
closeAddArrayItemDialog() {
|
|
653
|
-
this.addArrayItemDialogRef.close();
|
|
654
|
-
EntityUtilities.resetChangesOnEntity(this.arrayItem, this.arrayItemPriorChanges);
|
|
655
|
-
this.checkIsArrayItemValid();
|
|
656
|
-
this.emitChange();
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Edits an entity array item.
|
|
660
|
-
*
|
|
661
|
-
* @param entity - The entity that has been clicked.
|
|
662
|
-
*/
|
|
663
|
-
editArrayItem(entity) {
|
|
664
|
-
this.indexOfEditedArrayItem = this.entityArrayValues.indexOf(entity);
|
|
665
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass(entity);
|
|
666
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
667
|
-
this.checkArrayItem();
|
|
668
|
-
this.editArrayItemDialogRef = this.dialog.open(this.editArrayItemDialog, {
|
|
669
|
-
minWidth: '60%',
|
|
670
|
-
autoFocus: false,
|
|
671
|
-
restoreFocus: false
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
/**
|
|
675
|
-
* Saves changes on the array item in the dialog.
|
|
676
|
-
*/
|
|
677
|
-
saveArrayItem() {
|
|
678
|
-
this.entityArrayValues[this.indexOfEditedArrayItem] = LodashUtilities.cloneDeep(this.arrayItem);
|
|
679
|
-
this.entityArrayDataSource.data = this.entityArrayValues;
|
|
680
|
-
this.closeEditArrayItemDialog();
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Closes the edit array item dialog and resets changes.
|
|
684
|
-
*/
|
|
685
|
-
closeEditArrayItemDialog() {
|
|
686
|
-
this.editArrayItemDialogRef.close();
|
|
687
|
-
this.arrayItem = new this.metadataEntityArray.EntityClass();
|
|
688
|
-
this.arrayItemPriorChanges = LodashUtilities.cloneDeep(this.arrayItem);
|
|
689
|
-
this.checkArrayItem();
|
|
690
|
-
this.emitChange();
|
|
691
|
-
}
|
|
692
|
-
/**
|
|
693
|
-
* Removes all selected entries from the entity array.
|
|
694
|
-
*/
|
|
695
|
-
removeFromEntityArray() {
|
|
696
|
-
SelectionUtilities.remove(this.entityArraySelection, this.entityArrayValues, this.entityArrayDataSource);
|
|
697
|
-
this.emitChange();
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
NgxMatEntityInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: NgxMatEntityInputComponent, deps: [{ token: i1.MatDialog }, { token: i0.EnvironmentInjector }, { token: i2.Router }, { token: NGX_GET_VALIDATION_ERROR_MESSAGE }], target: i0.ɵɵFactoryTarget.Component });
|
|
701
|
-
NgxMatEntityInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.3", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: { entity: "entity", propertyKey: "propertyKey", getValidationErrorMessage: "getValidationErrorMessage", hideOmitForCreate: "hideOmitForCreate", hideOmitForEdit: "hideOmitForEdit", validEmpty: "validEmpty", isReadOnly: "isReadOnly" }, outputs: { inputChangeEvent: "inputChangeEvent" }, viewQueries: [{ propertyName: "addArrayItemDialog", first: true, predicate: ["addArrayItemDialog"], descendants: true }, { propertyName: "editArrayItemDialog", first: true, predicate: ["editArrayItemDialog"], descendants: true }, { propertyName: "hasManyPaginator", first: true, predicate: MatPaginator, descendants: true, static: true }, { propertyName: "hasManySort", first: true, predicate: MatSort, descendants: true, static: true }, { propertyName: "hasManyFilter", first: true, predicate: ["filter"], descendants: true, static: true }, { propertyName: "createHasManyDialog", first: true, predicate: ["createHasManyDialog"], descendants: true }, { propertyName: "editHasManyDialog", first: true, predicate: ["editHasManyDialog"], descendants: true }], ngImport: i0, template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_MANY\">\n <references-many-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </references-many-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <mat-tab-group *ngIf=\"objectPropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of objectPropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"objectPropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of objectPropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references one ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_ONE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"internalEntity[internalPropertyKey]\"\n [name]=\"internalPropertyKey.toString() + 'input'\"\n #inputModel=\"ngModel\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n (ngModelChange)=\"setReferencesOneObject()\"\n >\n <mat-option *ngIf=\"!metadata.required(entity)\">-</mat-option>\n <mat-option *ngFor=\"let value of referencesOneDropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n <mat-tab-group *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of referencesOnePropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of referencesOnePropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <mat-tab-group *ngIf=\"arrayItemInlineTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemInlineTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"arrayItemInlineTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArraySelection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"entityArrayDataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!entityArrayDataSource.data.length\" (change)=\"$event ? SelectionUtilities.masterToggle(entityArraySelection, entityArrayDataSource) : null\"\n [checked]=\"entityArraySelection.hasValue() && SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\"\n [indeterminate]=\"entityArraySelection.hasValue() && !SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? entityArraySelection.toggle(entity) : null\" [checked]=\"entityArraySelection.isSelected(entity)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell (click)=\"editArrayItem(entity)\" class=\"entity\" *matCellDef=\"let entity\">\n {{getDisplayColumnValue(entity, dCol)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"entityArrayDisplayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: entityArrayDisplayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !entityArrayDataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n <div class=\"hasMany\" *ngSwitchCase=\"DecoratorTypes.HAS_MANY\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n\n <div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n <div\n *ngIf=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-2]=\"hasManyAllowCreate\"\n [class.col-lg-4]=\"!hasManyAllowCreate\"\n [class.col-md-3]=\"hasManyAllowCreate\"\n [class.col-md-6]=\"!hasManyAllowCreate\"\n [class.col-sm-6]=\"hasManyAllowCreate\"\n [class.col-sm-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngIf=\"metadataHasMany.tableData.baseData.allowJsonImport\" type=\"button\" [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\" mat-menu-item>\n {{hasManyImportAction.displayName}}\n </button>\n <button type=\"button\" *ngFor=\"let action of metadataHasMany.tableData.baseData.tableActions\" [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"hasManyAllowCreate\"\n [class.col-lg-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" (click)=\"createHasManyEntity()\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n </div>\n\n <div class=\"mat-elevation-z8 elevation-container\">\n <mat-table [dataSource]=\"hasManyDataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? SelectionUtilities.masterToggle(hasManySelection, hasManyDataSource) : null\" [checked]=\"hasManySelection.hasValue() && SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\" [indeterminate]=\"hasManySelection.hasValue() && !SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\" class=\"entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? hasManySelection.toggle(entity) : null\" [checked]=\"hasManySelection.isSelected(entity)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of metadataHasMany.tableData.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" [class.enabled]=\"hasManyAllowUpdate(entity) || hasManyAllowRead(entity)\" (click)=\"editHasManyEntity(entity)\" *matCellDef=\"let entity\">\n {{getDisplayColumnValue(entity, dCol)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedHasManyColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedHasManyColumns\"></mat-row>\n </mat-table>\n\n <mat-spinner *ngIf=\"hasManyIsLoading && metadataHasMany.tableData.baseData.displayLoadingSpinner\">\n </mat-spinner>\n\n <mat-paginator [length]=\"hasManyDataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isArrayItemValid\">\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeAddArrayItemDialog()\" class=\"cancel-button\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"saveArrayItem()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\">\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeEditArrayItemDialog()\" class=\"cancel-button\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createDialogData.title}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyCreateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyCreateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyCreateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyCreateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogCreateHasMany()\" mat-raised-button [disabled]=\"!isHasManyEntityValid\">\n {{metadataHasMany.tableData.createDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelCreateHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n <button type=\"button\" *ngIf=\"hasManyAllowDelete(hasManyEntity)\" mat-raised-button (click)=\"deleteHasManyEntity()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyUpdateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyUpdateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyUpdateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyUpdateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogEditHasMany()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\">\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelEditHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form> \n</ng-template>", styles: [".mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}mat-spinner{margin:10px auto}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}.entityArray .elevation-container{border-radius:5px;padding:15px;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .entity:hover{cursor:pointer}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{border-radius:5px;padding:5px;margin-bottom:15px}.hasMany .mat-column-select{flex:0 0 75px}.hasMany .enabled:hover{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i3.NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator"], exportAs: ["matSelect"] }, { kind: "component", type: i8.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i9.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex"], exportAs: ["matCheckbox"] }, { kind: "component", type: i10.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i10.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i10.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i10.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i10.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i10.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i10.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i10.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i10.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i10.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i1.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: i1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "component", type: i11.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i12.MatTab, selector: "mat-tab", inputs: ["disabled"], exportAs: ["matTab"] }, { kind: "component", type: i12.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple", "fitInkBarToContent", "mat-stretch-tabs"], exportAs: ["matTabGroup"] }, { kind: "component", type: i13.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i13.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i13.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i14.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i15.MatPaginator, selector: "mat-paginator", inputs: ["disabled"], exportAs: ["matPaginator"] }, { kind: "component", type: i16.StringInputComponent, selector: "string-input" }, { kind: "component", type: i17.StringTextboxInputComponent, selector: "string-textbox-input" }, { kind: "component", type: i18.StringAutocompleteInputComponent, selector: "string-autocomplete-input" }, { kind: "component", type: i19.StringDropdownInputComponent, selector: "string-dropdown-input" }, { kind: "component", type: i20.StringPasswordInputComponent, selector: "string-password-input" }, { kind: "component", type: i21.BooleanCheckboxInputComponent, selector: "boolean-checkbox-input" }, { kind: "component", type: i22.BooleanToggleInputComponent, selector: "boolean-toggle-input" }, { kind: "component", type: i23.BooleanDropdownInputComponent, selector: "boolean-dropdown-input" }, { kind: "component", type: i24.NumberInputComponent, selector: "number-input" }, { kind: "component", type: i25.NumberDropdownInputComponent, selector: "number-dropdown-input" }, { kind: "component", type: i26.NumberSliderInputComponent, selector: "number-slider-input" }, { kind: "component", type: i27.ArrayStringChipsInputComponent, selector: "array-string-chips-input" }, { kind: "component", type: i28.ArrayStringAutocompleteChipsComponent, selector: "array-string-autocomplete-chips" }, { kind: "component", type: i29.DateInputComponent, selector: "date-input" }, { kind: "component", type: i30.DateRangeInputComponent, selector: "date-range-input" }, { kind: "component", type: i31.DateTimeInputComponent, selector: "date-time-input" }, { kind: "component", type: i32.ArrayDateInputComponent, selector: "array-date-input" }, { kind: "component", type: i33.ArrayDateTimeInputComponent, selector: "array-date-time-input" }, { kind: "component", type: i34.ArrayDateRangeInputComponent, selector: "array-date-range-input" }, { kind: "component", type: i35.FileImageInputComponent, selector: "file-image-input" }, { kind: "component", type: i36.FileDefaultInputComponent, selector: "file-default-input" }, { kind: "component", type: i37.ReferencesManyInputComponent, selector: "references-many-input" }, { kind: "component", type: i38.CustomInputComponent, selector: "custom-input" }, { kind: "component", type: NgxMatEntityInputComponent, selector: "ngx-mat-entity-input", inputs: ["entity", "propertyKey", "getValidationErrorMessage", "hideOmitForCreate", "hideOmitForEdit", "validEmpty", "isReadOnly"], outputs: ["inputChangeEvent"] }] });
|
|
702
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.3", ngImport: i0, type: NgxMatEntityInputComponent, decorators: [{
|
|
703
|
-
type: Component,
|
|
704
|
-
args: [{ selector: 'ngx-mat-entity-input', template: "<div [ngSwitch]=\"type\" *ngIf=\"!(hideOmitForCreate && metadata.omitForCreate) && !(hideOmitForEdit && metadata.omitForUpdate)\">\n <!-------------------------------------------->\n <!-----------------Strings-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.STRING\">\n <string-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_TEXTBOX\">\n <string-textbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-textbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_AUTOCOMPLETE\">\n <string-autocomplete-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-autocomplete-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_DROPDOWN\">\n <string-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.STRING_PASSWORD\">\n <string-password-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </string-password-input>\n </div>\n\n <!-------------------------------------------->\n <!-----------------Booleans------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_CHECKBOX\">\n <boolean-checkbox-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-checkbox-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_TOGGLE\">\n <boolean-toggle-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-toggle-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.BOOLEAN_DROPDOWN\">\n <boolean-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </boolean-dropdown-input>\n </div>\n\n <!-------------------------------------------->\n <!------------------Numbers------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER\">\n <number-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_DROPDOWN\">\n <number-dropdown-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-dropdown-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.NUMBER_SLIDER\">\n <number-slider-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </number-slider-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE\">\n <array-date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_TIME\">\n <array-date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-time-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_DATE_RANGE\">\n <array-date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_CHIPS\">\n <array-string-chips-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-chips-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS\">\n <array-string-autocomplete-chips\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </array-string-autocomplete-chips>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Dates-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.DATE\">\n <date-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_RANGE\">\n <date-range-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-range-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.DATE_TIME\">\n <date-time-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </date-time-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Files-------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.FILE_DEFAULT\">\n <file-default-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-default-input>\n </div>\n <div *ngSwitchCase=\"DecoratorTypes.FILE_IMAGE\">\n <file-image-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </file-image-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references many ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_MANY\">\n <references-many-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </references-many-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Custom------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.CUSTOM\">\n <custom-input\n (inputChangeEvent)=\"emitChange()\"\n [entity]=\"internalEntity\"\n [key]=\"internalPropertyKey\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [isReadOnly]=\"internalIsReadOnly\"\n >\n </custom-input>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Object------------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.OBJECT\">\n <b>{{metadataDefaultObject.displayName}}</b>\n <!-- iterates over the object properties -->\n <mat-tab-group *ngIf=\"objectPropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of objectPropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"objectPropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of objectPropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"objectProperty\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"isPropertyReadOnly(objectProperty, key)\"\n class=\"col-lg-{{EntityUtilities.getWidth(objectProperty, key, 'lg')}} col-md-{{EntityUtilities.getWidth(objectProperty, key, 'md')}} col-sm-{{EntityUtilities.getWidth(objectProperty, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------- references one ------------->\n <!-------------------------------------------->\n <div *ngSwitchCase=\"DecoratorTypes.REFERENCES_ONE\">\n <mat-form-field>\n <mat-label>{{metadata.displayName}}</mat-label>\n <mat-select [(ngModel)]=\"internalEntity[internalPropertyKey]\"\n [name]=\"internalPropertyKey.toString() + 'input'\"\n #inputModel=\"ngModel\"\n [disabled]=\"internalIsReadOnly\"\n [required]=\"metadata.required(entity)\"\n (ngModelChange)=\"setReferencesOneObject()\"\n >\n <mat-option *ngIf=\"!metadata.required(entity)\">-</mat-option>\n <mat-option *ngFor=\"let value of referencesOneDropdownValues\" [value]=\"value.value\">{{value.displayName}}</mat-option>\n </mat-select>\n <mat-error>{{internalGetValidationErrorMessage(inputModel)}}</mat-error>\n </mat-form-field>\n <!-- iterates over the references one properties -->\n <mat-tab-group *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of referencesOnePropertyTabs; let tI = index; trackBy: trackByFn\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows;\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let rI = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"referencesOnePropertyTabs && referencesOnePropertyTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of referencesOnePropertyTabs[0].rows\">\n <ngx-mat-entity-input *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"referencesOneObject\"\n [propertyKey]=\"key\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n [hideOmitForCreate]=\"hideOmitForCreate\"\n [hideOmitForEdit]=\"hideOmitForEdit\"\n [validEmpty]=\"!metadata.required(entity)\"\n [isReadOnly]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(referencesOneObject, key, 'lg')}} col-md-{{EntityUtilities.getWidth(referencesOneObject, key, 'md')}} col-sm-{{EntityUtilities.getWidth(referencesOneObject, key, 'sm')}}\"\n (inputChangeEvent)=\"emitChange()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!-------------------Array-------------------->\n <!-------------------------------------------->\n <div class=\"entityArray\" *ngSwitchCase=\"DecoratorTypes.ARRAY\">\n <div class=\"mat-elevation-z8 elevation-container\">\n <div class=\"array-headline\">\n <b>{{metadataEntityArray.displayName}}</b>\n </div>\n <div *ngIf=\"metadataEntityArray.createInline && !internalIsReadOnly\">\n <mat-tab-group *ngIf=\"arrayItemInlineTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemInlineTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n\n <div *ngIf=\"arrayItemInlineTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemInlineTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys; let i = index; trackBy: trackByFn\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </div>\n\n <div class=\"buttons\" *ngIf=\"!internalIsReadOnly\">\n <button type=\"button\" mat-raised-button\n [disabled]=\"metadataEntityArray.createInline && !isArrayItemValid\"\n (click)=\"addEntity()\">\n {{metadataEntityArray.addButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button\n [disabled]=\"!entityArraySelection.selected.length\"\n (click)=\"removeFromEntityArray()\">\n {{metadataEntityArray.removeButtonLabel}}\n </button>\n </div>\n \n <mat-table [dataSource]=\"entityArrayDataSource\">\n <!-- select Column -->\n <ng-container matColumnDef=\"select\" *ngIf=\"!internalIsReadOnly\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox\n [disabled]=\"!entityArrayDataSource.data.length\" (change)=\"$event ? SelectionUtilities.masterToggle(entityArraySelection, entityArrayDataSource) : null\"\n [checked]=\"entityArraySelection.hasValue() && SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\"\n [indeterminate]=\"entityArraySelection.hasValue() && !SelectionUtilities.isAllSelected(entityArraySelection, entityArrayDataSource)\">\n </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? entityArraySelection.toggle(entity) : null\" [checked]=\"entityArraySelection.isSelected(entity)\"></mat-checkbox>\n </mat-cell>\n </ng-container>\n \n <ng-container *ngFor=\"let dCol of metadataEntityArray.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell (click)=\"editArrayItem(entity)\" class=\"entity\" *matCellDef=\"let entity\">\n {{getDisplayColumnValue(entity, dCol)}}\n </mat-cell>\n </ng-container>\n \n <mat-header-row *matHeaderRowDef=\"entityArrayDisplayedColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: entityArrayDisplayedColumns\"></mat-row>\n </mat-table>\n \n <div class=\"array-error\" *ngIf=\"metadataEntityArray.required && !entityArrayDataSource.data.length\">\n {{metadataEntityArray.missingErrorMessage}}\n </div>\n </div>\n </div>\n\n <!-------------------------------------------->\n <!------------------ has many ---------------->\n <!-------------------------------------------->\n <div class=\"hasMany\" *ngSwitchCase=\"DecoratorTypes.HAS_MANY\">\n <h2 class=\"title\">{{metadataHasMany.tableData.baseData.title}}</h2>\n\n <div class=\"row\">\n <mat-form-field class=\"col-lg-8 col-md-6 col-sm-12\">\n <mat-label>{{metadataHasMany.tableData.baseData.searchLabel}}</mat-label>\n <input matInput (keyup)=\"applyHasManyFilter($event)\">\n </mat-form-field>\n <div\n *ngIf=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-2]=\"hasManyAllowCreate\"\n [class.col-lg-4]=\"!hasManyAllowCreate\"\n [class.col-md-3]=\"hasManyAllowCreate\"\n [class.col-md-6]=\"!hasManyAllowCreate\"\n [class.col-sm-6]=\"hasManyAllowCreate\"\n [class.col-sm-12]=\"!hasManyAllowCreate\"\n >\n <button type=\"button\" class=\"actions-button\" [matMenuTriggerFor]=\"menu\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.tableActionsLabel}}\n </button>\n </div>\n <mat-menu #menu=\"matMenu\">\n <button *ngIf=\"metadataHasMany.tableData.baseData.allowJsonImport\" type=\"button\" [disabled]=\"hasManyTableActionDisabled(hasManyImportAction)\" (click)=\"runHasManyTableAction(hasManyImportAction)\" mat-menu-item>\n {{hasManyImportAction.displayName}}\n </button>\n <button type=\"button\" *ngFor=\"let action of metadataHasMany.tableData.baseData.tableActions\" [disabled]=\"hasManyTableActionDisabled(action)\" (click)=\"runHasManyTableAction(action)\" mat-menu-item>\n {{action.displayName}}\n </button>\n </mat-menu>\n\n <div\n *ngIf=\"hasManyAllowCreate\"\n [class.col-lg-2]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-lg-4]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-3]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-md-6]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-6]=\"metadataHasMany.tableData.baseData.tableActions.length\"\n [class.col-sm-12]=\"!metadataHasMany.tableData.baseData.tableActions.length\"\n >\n <button type=\"button\" class=\"create-button\" (click)=\"createHasManyEntity()\" mat-raised-button>\n {{metadataHasMany.tableData.baseData.createButtonLabel}}\n </button>\n </div>\n </div>\n\n <div class=\"mat-elevation-z8 elevation-container\">\n <mat-table [dataSource]=\"hasManyDataSource\" matSort>\n <!-- select Column -->\n <ng-container matColumnDef=\"select\">\n <mat-header-cell *matHeaderCellDef>\n <mat-checkbox (change)=\"$event ? SelectionUtilities.masterToggle(hasManySelection, hasManyDataSource) : null\" [checked]=\"hasManySelection.hasValue() && SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\" [indeterminate]=\"hasManySelection.hasValue() && !SelectionUtilities.isAllSelected(hasManySelection, hasManyDataSource)\"> </mat-checkbox>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let entity\" class=\"entity\">\n <mat-checkbox (click)=\"$event.stopPropagation()\" (change)=\"$event ? hasManySelection.toggle(entity) : null\" [checked]=\"hasManySelection.isSelected(entity)\"> </mat-checkbox>\n </mat-cell>\n </ng-container>\n\n <ng-container *ngFor=\"let dCol of metadataHasMany.tableData.baseData.displayColumns\" [matColumnDef]=\"dCol.displayName\">\n <mat-header-cell *matHeaderCellDef mat-sort-header>\n {{dCol.displayName}}\n </mat-header-cell>\n <mat-cell class=\"entity\" [class.enabled]=\"hasManyAllowUpdate(entity) || hasManyAllowRead(entity)\" (click)=\"editHasManyEntity(entity)\" *matCellDef=\"let entity\">\n {{getDisplayColumnValue(entity, dCol)}}\n </mat-cell>\n </ng-container>\n\n <mat-header-row *matHeaderRowDef=\"displayedHasManyColumns\"></mat-header-row>\n <mat-row *matRowDef=\"let row; columns: displayedHasManyColumns\"></mat-row>\n </mat-table>\n\n <mat-spinner *ngIf=\"hasManyIsLoading && metadataHasMany.tableData.baseData.displayLoadingSpinner\">\n </mat-spinner>\n\n <mat-paginator [length]=\"hasManyDataSource.filteredData.length\" [pageIndex]=\"0\" [pageSize]=\"10\" [pageSizeOptions]=\"[5, 10, 25, 50]\"></mat-paginator>\n </div>\n </div>\n\n <div *ngSwitchDefault>ERROR: The type {{type}} is not known.</div>\n</div>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<!--------------------------------------------------------->\n<!--------------------Add Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #addArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{addArrayItemDialogData.title}}</div>\n </div>\n\n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n [getValidationErrorMessage]=\"internalGetValidationErrorMessage\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsArrayItemValid()\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" mat-raised-button (click)=\"addArrayItem()\" [disabled]=\"!isArrayItemValid\">\n {{addArrayItemDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeAddArrayItemDialog()\" class=\"cancel-button\">\n {{addArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Edit Array Item Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #editArrayItemDialog>\n <div class=\"mat-dialog-title\">\n <div>{{editArrayItemDialogData.title(arrayItemPriorChanges)}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"arrayItemDialogTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of arrayItemDialogTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"arrayItemDialogTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of arrayItemDialogTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"arrayItem\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(arrayItem, key, 'lg')}} col-md-{{EntityUtilities.getWidth(arrayItem, key, 'md')}} col-sm-{{EntityUtilities.getWidth(arrayItem, key, 'sm')}}\"\n (inputChangeEvent)=\"checkArrayItem()\"\n [isReadOnly]=\"isPropertyReadOnly(arrayItem, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"saveArrayItem()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isArrayItemValid || !isArrayItemDirty\">\n {{editArrayItemDialogData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"closeEditArrayItemDialog()\" class=\"cancel-button\">\n {{editArrayItemDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n</ng-template>\n\n<!--------------------------------------------------------->\n<!--------------------Create Has Many Dialog---------------->\n<!--------------------------------------------------------->\n<ng-template #createHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.createDialogData.title}}</div>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyCreateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyCreateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyCreateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyCreateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForCreate]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkIsHasManyEntityValid('create')\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogCreateHasMany()\" mat-raised-button [disabled]=\"!isHasManyEntityValid\">\n {{metadataHasMany.tableData.createDialogData.createButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelCreateHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.createDialogData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form>\n \n</ng-template>\n\n<ng-template #editHasManyDialog>\n <div class=\"mat-dialog-title\">\n <div>{{metadataHasMany.tableData.editData.title(hasManyEntityPriorChanges)}}</div>\n <button type=\"button\" *ngIf=\"hasManyAllowDelete(hasManyEntity)\" mat-raised-button (click)=\"deleteHasManyEntity()\" color=\"warn\" class=\"delete-button\" tabindex=\"-1\">\n {{metadataHasMany.tableData.editData.deleteButtonLabel}}\n </button>\n </div>\n \n <form>\n <mat-dialog-content>\n <mat-tab-group *ngIf=\"hasManyUpdateTabs.length > 1\" preserveContent>\n <mat-tab *ngFor=\"let tab of hasManyUpdateTabs\" [label]=\"tab.tabName\">\n <div class=\"row\" *ngFor=\"let row of tab.rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </mat-tab>\n </mat-tab-group>\n \n <div *ngIf=\"hasManyUpdateTabs.length <= 1\">\n <div class=\"row\" *ngFor=\"let row of hasManyUpdateTabs[0].rows\">\n <ngx-mat-entity-input\n *ngFor=\"let key of row.keys\"\n [entity]=\"hasManyEntity\"\n [propertyKey]=\"key\"\n [hideOmitForEdit]=\"true\"\n class=\"col-lg-{{EntityUtilities.getWidth(hasManyEntity, key, 'lg')}} col-md-{{EntityUtilities.getWidth(hasManyEntity, key, 'md')}} col-sm-{{EntityUtilities.getWidth(hasManyEntity, key, 'sm')}}\"\n (inputChangeEvent)=\"checkHasManyEntity()\"\n [isReadOnly]=\"isPropertyReadOnly(hasManyEntity, key)\"\n >\n </ngx-mat-entity-input>\n </div>\n </div>\n </mat-dialog-content>\n \n <mat-dialog-actions>\n <button type=\"submit\" (click)=\"dialogEditHasMany()\" mat-raised-button [disabled]=\"internalIsReadOnly || !isHasManyEntityValid || !isHasManyEntityDirty\">\n {{metadataHasMany.tableData.editData.confirmButtonLabel}}\n </button>\n <button type=\"button\" mat-raised-button (click)=\"dialogCancelEditHasMany()\" class=\"cancel-button\">\n {{metadataHasMany.tableData.editData.cancelButtonLabel}}\n </button>\n </mat-dialog-actions>\n </form> \n</ng-template>", styles: [".mdc-data-table__row:last-child .mdc-data-table__cell{border-bottom:1px solid rgba(0,0,0,.12)}.mat-dialog-title{padding:12px 20px;display:flex;justify-content:space-between;align-items:center}.mat-dialog-title div{font-size:var(--mdc-dialog-subhead-size, 14px);font-weight:var(--mdc-dialog-subhead-weight, 500)}::ng-deep .mdc-dialog .mdc-dialog__content{padding:6px 20px!important}mat-dialog-actions{justify-content:space-between;align-items:center;padding-left:20px;padding-right:20px}mat-spinner{margin:10px auto}::ng-deep .mat-mdc-tab-body-wrapper{margin-left:-12px;margin-right:-12px}::ng-deep mat-tab-body{padding-top:10px;padding-left:12px;padding-right:12px}::ng-deep mat-tab-body .mat-mdc-tab-body-content{overflow:initial}::ng-deep .mat-mdc-form-field.mat-form-field-disabled label{color:#0009}::ng-deep .mat-mdc-form-field.mat-form-field-disabled input,::ng-deep .mat-mdc-form-field.mat-form-field-disabled textarea,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-disabled,::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-select-value{color:#000}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled{opacity:1}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-mdc-chip.mat-mdc-standard-chip.mat-mdc-chip-disabled button{opacity:.2}::ng-deep .mat-mdc-form-field.mat-form-field-disabled .mat-date-range-input-inner:disabled{color:#000}::ng-deep .mat-mdc-form-field .mat-mdc-slide-toggle{opacity:1}.entityArray .elevation-container{border-radius:5px;padding:15px;margin-bottom:15px;margin-top:15px}.entityArray .array-headline{padding-bottom:10px}.entityArray .buttons{display:flex;justify-content:space-between;margin-bottom:10px;margin-top:5px}.entityArray mat-table{border:1px solid #E0E0E0;border-radius:5px;padding-top:5px;padding-bottom:25px}.entityArray .mat-column-select{flex:0 0 75px}.entityArray .entity:hover{cursor:pointer}.entityArray .array-error{display:flex;align-items:center;justify-content:center;margin-top:-25.8px;border:1px solid #E0E0E0;background-color:#f8d3d7;color:#721c24;height:25.8px;border-bottom-left-radius:5px;border-bottom-right-radius:5px}.hasMany button{width:100%;height:56px;line-height:24px;font-size:16px}.hasMany .title{text-align:center}.hasMany .elevation-container{border-radius:5px;padding:5px;margin-bottom:15px}.hasMany .mat-column-select{flex:0 0 75px}.hasMany .enabled:hover{cursor:pointer}\n"] }]
|
|
705
|
-
}], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: i0.EnvironmentInjector }, { type: i2.Router }, { type: undefined, decorators: [{
|
|
706
|
-
type: Inject,
|
|
707
|
-
args: [NGX_GET_VALIDATION_ERROR_MESSAGE]
|
|
708
|
-
}] }]; }, propDecorators: { entity: [{
|
|
709
|
-
type: Input
|
|
710
|
-
}], propertyKey: [{
|
|
711
|
-
type: Input
|
|
712
|
-
}], getValidationErrorMessage: [{
|
|
713
|
-
type: Input
|
|
714
|
-
}], hideOmitForCreate: [{
|
|
715
|
-
type: Input
|
|
716
|
-
}], hideOmitForEdit: [{
|
|
717
|
-
type: Input
|
|
718
|
-
}], validEmpty: [{
|
|
719
|
-
type: Input
|
|
720
|
-
}], isReadOnly: [{
|
|
721
|
-
type: Input
|
|
722
|
-
}], inputChangeEvent: [{
|
|
723
|
-
type: Output
|
|
724
|
-
}], addArrayItemDialog: [{
|
|
725
|
-
type: ViewChild,
|
|
726
|
-
args: ['addArrayItemDialog']
|
|
727
|
-
}], editArrayItemDialog: [{
|
|
728
|
-
type: ViewChild,
|
|
729
|
-
args: ['editArrayItemDialog']
|
|
730
|
-
}], hasManyPaginator: [{
|
|
731
|
-
type: ViewChild,
|
|
732
|
-
args: [MatPaginator, { static: true }]
|
|
733
|
-
}], hasManySort: [{
|
|
734
|
-
type: ViewChild,
|
|
735
|
-
args: [MatSort, { static: true }]
|
|
736
|
-
}], hasManyFilter: [{
|
|
737
|
-
type: ViewChild,
|
|
738
|
-
args: ['filter', { static: true }]
|
|
739
|
-
}], createHasManyDialog: [{
|
|
740
|
-
type: ViewChild,
|
|
741
|
-
args: ['createHasManyDialog']
|
|
742
|
-
}], editHasManyDialog: [{
|
|
743
|
-
type: ViewChild,
|
|
744
|
-
args: ['editHasManyDialog']
|
|
745
|
-
}] } });
|
|
746
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1hdGVyaWFsLWVudGl0eS9zcmMvY29tcG9uZW50cy9pbnB1dC9pbnB1dC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWF0ZXJpYWwtZW50aXR5L3NyYy9jb21wb25lbnRzL2lucHV0L2lucHV0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU1SSxPQUFPLEVBQUUsU0FBUyxFQUFnQixNQUFNLDBCQUEwQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBTTVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUN2RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFFdEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdDQUFn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RSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDekcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7O3VIQTF6QlEsMEJBQTBCLG9HQXlJdkIsZ0NBQWdDOzJHQXpJbkMsMEJBQTBCLDJtQkErRnhCLFlBQVksNEZBRVosT0FBTyw0WEM3SXRCLDY3c0NBc3hCYywyaFREMXVCRCwwQkFBMEI7MkZBQTFCLDBCQUEwQjtrQkFMdEMsU0FBUzsrQkFDSSxzQkFBc0I7OzBCQTZJM0IsTUFBTTsyQkFBQyxnQ0FBZ0M7NENBbkk1QyxNQUFNO3NCQURMLEtBQUs7Z0JBUU4sV0FBVztzQkFEVixLQUFLO2dCQVFOLHlCQUF5QjtzQkFEeEIsS0FBSztnQkFXTixpQkFBaUI7c0JBRGhCLEtBQUs7Z0JBVU4sZUFBZTtzQkFEZCxLQUFLO2dCQVVOLFVBQVU7c0JBRFQsS0FBSztnQkFVTixVQUFVO3NCQURULEtBQUs7Z0JBS04sZ0JBQWdCO3NCQURmLE1BQU07Z0JBSVAsa0JBQWtCO3NCQURqQixTQUFTO3VCQUFDLG9CQUFvQjtnQkFLL0IsbUJBQW1CO3NCQURsQixTQUFTO3VCQUFDLHFCQUFxQjtnQkE2QmhDLGdCQUFnQjtzQkFEZixTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBR3pDLFdBQVc7c0JBRFYsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUdwQyxhQUFhO3NCQURaLFNBQVM7dUJBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFRckMsbUJBQW1CO3NCQURsQixTQUFTO3VCQUFDLHFCQUFxQjtnQkFJaEMsaUJBQWlCO3NCQURoQixTQUFTO3VCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNlbGVjdGlvbk1vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcbmltcG9ydCB7IENvbXBvbmVudCwgRW52aXJvbm1lbnRJbmplY3RvciwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ01vZGVsIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dSZWYgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0UGFnaW5hdG9yIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvcGFnaW5hdG9yJztcbmltcG9ydCB7IE1hdFNvcnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7IE1hdFRhYmxlRGF0YVNvdXJjZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYmxlJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQmFzZUVudGl0eVR5cGUgfSBmcm9tICcuLi8uLi9jbGFzc2VzL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBFZGl0QXJyYXlJdGVtRGlhbG9nRGF0YUludGVybmFsLCBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9hcnJheS9hcnJheS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBEZWNvcmF0b3JUeXBlcyB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvYmFzZS9kZWNvcmF0b3ItdHlwZXMuZW51bSc7XG5pbXBvcnQgeyBEcm9wZG93blZhbHVlIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9iYXNlL2Ryb3Bkb3duLXZhbHVlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9iYXNlL3Byb3BlcnR5LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IEhhc01hbnlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvaGFzLW1hbnkvaGFzLW1hbnktZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgRGVmYXVsdE9iamVjdERlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vLi4vZGVjb3JhdG9ycy9vYmplY3Qvb2JqZWN0LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IFJlZmVyZW5jZXNPbmVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uLy4uL2RlY29yYXRvcnMvcmVmZXJlbmNlcy1vbmUvcmVmZXJlbmNlcy1vbmUtZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgTG9kYXNoVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vZW5jYXBzdWxhdGlvbi9sb2Rhc2gudXRpbGl0aWVzJztcbmltcG9ydCB7IFJlZmxlY3RVdGlsaXRpZXMgfSBmcm9tICcuLi8uLi9lbmNhcHN1bGF0aW9uL3JlZmxlY3QudXRpbGl0aWVzJztcbmltcG9ydCB7IGRlZmF1bHRGYWxzZSB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9kZWZhdWx0LWZhbHNlLmZ1bmN0aW9uJztcbmltcG9ydCB7IEVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9lbnRpdHkuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2RhdGUudXRpbGl0aWVzJztcbmltcG9ydCB7IEVudGl0eVRhYiwgRW50aXR5VXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2VudGl0eS51dGlsaXRpZXMnO1xuaW1wb3J0IHsgU2VsZWN0aW9uVXRpbGl0aWVzIH0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL3NlbGVjdGlvbi51dGlsaXRpZXMnO1xuaW1wb3J0IHsgQ29uZmlybURpYWxvZ0RhdGFCdWlsZGVyLCBDb25maXJtRGlhbG9nRGF0YUludGVybmFsIH0gZnJvbSAnLi4vY29uZmlybS1kaWFsb2cvY29uZmlybS1kaWFsb2ctZGF0YS5idWlsZGVyJztcbmltcG9ydCB7IE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQgfSBmcm9tICcuLi9jb25maXJtLWRpYWxvZy9jb25maXJtLWRpYWxvZy5jb21wb25lbnQnO1xuaW1wb3J0IHsgTkdYX0dFVF9WQUxJREFUSU9OX0VSUk9SX01FU1NBR0UgfSBmcm9tICcuLi9nZXQtdmFsaWRhdGlvbi1lcnJvci1tZXNzYWdlLmZ1bmN0aW9uJztcbmltcG9ydCB7IENyZWF0ZURpYWxvZ0RhdGFCdWlsZGVyLCBDcmVhdGVEaWFsb2dEYXRhSW50ZXJuYWwgfSBmcm9tICcuLi90YWJsZS9jcmVhdGUtZGlhbG9nL2NyZWF0ZS1kaWFsb2ctZGF0YS5idWlsZGVyJztcbmltcG9ydCB7IERpc3BsYXlDb2x1bW4gfSBmcm9tICcuLi90YWJsZS90YWJsZS1kYXRhJztcbmltcG9ydCB7IEJhc2VUYWJsZUFjdGlvbkludGVybmFsLCBUYWJsZUFjdGlvbkludGVybmFsIH0gZnJvbSAnLi4vdGFibGUvdGFibGUtZGF0YS5idWlsZGVyJztcblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBpbnB1dCBjb21wb25lbnQuIEl0IGdldHMgdGhlIG1ldGFkYXRhIG9mIHRoZSBwcm9wZXJ0eSBmcm9tIHRoZSBnaXZlbiBASW5wdXQgXCJlbnRpdHlcIiBhbmQgQElucHV0IFwicHJvcGVydHlLZXlcIlxuICogYW5kIGRpc3BsYXlzIHRoZSBpbnB1dCBmaWVsZCBhY2NvcmRpbmdseS5cbiAqXG4gKiBZb3UgY2FuIGFsc28gZGVmaW5lIGEgbWV0aG9kIHRoYXQgZ2VuZXJhdGVzIGVycm9yLW1lc3NhZ2VzIGFuZCBpZiB0aGUgaW5wdXQgc2hvdWxkIGJlIGhpZGRlbiB3aGVuIGl0cyBtZXRhZGF0YSBzYXlzXG4gKiB0aGF0IGl0IHNob3VsZCBiZSBvbWl0dGVkIGZvciBjcmVhdGluZyBvciB1cGRhdGluZy5cbiAqIFRoZSBsYXN0IHBhcnQgYmVpbmcgbW9zdGx5IHJlbGV2YW50IGlmIHlvdSB3YW50IHRvIHVzZSB0aGlzIGNvbXBvbmVudCBpbnNpZGUgYW4gbmdGb3IuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbmd4LW1hdC1lbnRpdHktaW5wdXQnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9pbnB1dC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vaW5wdXQuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOZ3hNYXRFbnRpdHlJbnB1dENvbXBvbmVudDxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKipcbiAgICAgKiBUaGUgZW50aXR5IG9uIHdoaWNoIHRoZSBwcm9wZXJ0eSBleGlzdHMuIFVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgXCJwcm9wZXJ0eUtleVwiXG4gICAgICogdG8gZGV0ZXJtaW5lIHRoZSBwcm9wZXJ0eSBmb3Igd2hpY2ggdGhlIGlucHV0IHNob3VsZCBiZSBnZW5lcmF0ZWQuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBlbnRpdHk/OiBFbnRpdHlUeXBlO1xuICAgIGludGVybmFsRW50aXR5ITogRW50aXR5VHlwZTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBnZW5lcmF0ZSB0aGUgaW5wdXQgZm9yLiBVc2VkIGluIGNvbmp1bmN0aW9uIHdpdGggdGhlIFwiZW50aXR5XCIuXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwcm9wZXJ0eUtleT86IGtleW9mIEVudGl0eVR5cGU7XG4gICAgaW50ZXJuYWxQcm9wZXJ0eUtleSE6IGtleW9mIEVudGl0eVR5cGU7XG5cbiAgICAvKipcbiAgICAgKiAob3B0aW9uYWwpIEEgY3VzdG9tIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHRoZSBlcnJvci1tZXNzYWdlIGZvciBpbnZhbGlkIGlucHV0cy5cbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2U/OiAobW9kZWw6IE5nTW9kZWwpID0+IHN0cmluZztcbiAgICBpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2UhOiAobW9kZWw6IE5nTW9kZWwpID0+IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gaGlkZSBhIHZhbHVlIGlmIGl0IGlzIG9taXR0ZWQgZm9yIGNyZWF0aW9uLlxuICAgICAqIElzIHVzZWQgaW50ZXJuYWxseSBmb3IgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBoaWRlT21pdEZvckNyZWF0ZT86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIGhpZGUgYSB2YWx1ZSBpZiBpdCBpcyBvbWl0dGVkIGZvciBlZGl0aW5nLlxuICAgICAqIElzIHVzZWQgaW50ZXJuYWxseSBmb3IgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBoaWRlT21pdEZvckVkaXQ/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciBvciBub3QgYW4gZW1wdHkgdmFsdWUgc2hvdWxkIGJlIHZhbGlkLlxuICAgICAqIElzIHVzZWQgaW50ZXJuYWxseSBmb3IgdGhlIG9iamVjdCBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgdmFsaWRFbXB0eT86IGJvb2xlYW47IC8vIFRPRE9cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IHRoZSBpbnB1dCBzaG91bGQgYmUgcmVhZG9ubHkuXG4gICAgICogSW4gdGhhdCBjYXNlIGl0IGlzIGRpc2FibGVkLCBidXQgbW9zdCBvZiB0aGUgZGVmYXVsdCBzdHlsaW5nIGlzIG92ZXJ3cml0dGVuLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGlzUmVhZE9ubHk/OiBib29sZWFuO1xuICAgIGludGVybmFsSXNSZWFkT25seSE6IGJvb2xlYW47XG5cbiAgICBAT3V0cHV0KClcbiAgICBpbnB1dENoYW5nZUV2ZW50OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICBAVmlld0NoaWxkKCdhZGRBcnJheUl0ZW1EaWFsb2cnKVxuICAgIGFkZEFycmF5SXRlbURpYWxvZyE6IFRlbXBsYXRlUmVmPHVua25vd24+O1xuICAgIGFkZEFycmF5SXRlbURpYWxvZ1JlZiE6IE1hdERpYWxvZ1JlZjx1bmtub3duPjtcblxuICAgIEBWaWV3Q2hpbGQoJ2VkaXRBcnJheUl0ZW1EaWFsb2cnKVxuICAgIGVkaXRBcnJheUl0ZW1EaWFsb2chOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcbiAgICBlZGl0QXJyYXlJdGVtRGlhbG9nUmVmITogTWF0RGlhbG9nUmVmPHVua25vd24+O1xuXG4gICAgdHlwZSE6IERlY29yYXRvclR5cGVzO1xuICAgIG1ldGFkYXRhITogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDtcblxuICAgIG1ldGFkYXRhRGVmYXVsdE9iamVjdCE6IERlZmF1bHRPYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICBvYmplY3RQcm9wZXJ0eSE6IEVudGl0eVR5cGU7XG4gICAgb2JqZWN0UHJvcGVydHlUYWJzITogRW50aXR5VGFiPEVudGl0eVR5cGU+W107XG5cbiAgICBtZXRhZGF0YUVudGl0eUFycmF5ITogRW50aXR5QXJyYXlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICBlbnRpdHlBcnJheVZhbHVlcyE6IEVudGl0eVR5cGVbXTtcbiAgICBhcnJheUl0ZW0hOiBFbnRpdHlUeXBlO1xuICAgIGFycmF5SXRlbVByaW9yQ2hhbmdlcyE6IEVudGl0eVR5cGU7XG4gICAgYXJyYXlJdGVtSW5saW5lVGFicyE6IEVudGl0eVRhYjxFbnRpdHlUeXBlPltdO1xuICAgIGVudGl0eUFycmF5RGF0YVNvdXJjZSE6IE1hdFRhYmxlRGF0YVNvdXJjZTxFbnRpdHlUeXBlPjtcbiAgICBlbnRpdHlBcnJheVNlbGVjdGlvbjogU2VsZWN0aW9uTW9kZWw8RW50aXR5VHlwZT4gPSBuZXcgU2VsZWN0aW9uTW9kZWw8RW50aXR5VHlwZT4odHJ1ZSwgW10pO1xuICAgIGVudGl0eUFycmF5RGlzcGxheWVkQ29sdW1ucyE6IHN0cmluZ1tdO1xuICAgIGlzQXJyYXlJdGVtVmFsaWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBpc0FycmF5SXRlbURpcnR5OiBib29sZWFuID0gZmFsc2U7XG4gICAgaW5kZXhPZkVkaXRlZEFycmF5SXRlbSE6IG51bWJlcjtcbiAgICBhZGRBcnJheUl0ZW1EaWFsb2dEYXRhITogQ3JlYXRlRGlhbG9nRGF0YUludGVybmFsO1xuICAgIGFycmF5SXRlbURpYWxvZ1RhYnMhOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXTtcbiAgICBlZGl0QXJyYXlJdGVtRGlhbG9nRGF0YSE6IEVkaXRBcnJheUl0ZW1EaWFsb2dEYXRhSW50ZXJuYWw8RW50aXR5VHlwZT47XG5cbiAgICBtZXRhZGF0YUhhc01hbnkhOiBIYXNNYW55RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZSwgRW50aXR5VHlwZT47XG4gICAgaGFzTWFueUlzTG9hZGluZzogYm9vbGVhbiA9IHRydWU7XG4gICAgQFZpZXdDaGlsZChNYXRQYWdpbmF0b3IsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgaGFzTWFueVBhZ2luYXRvciE6IE1hdFBhZ2luYXRvcjtcbiAgICBAVmlld0NoaWxkKE1hdFNvcnQsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgaGFzTWFueVNvcnQhOiBNYXRTb3J0O1xuICAgIEBWaWV3Q2hpbGQoJ2ZpbHRlcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgaGFzTWFueUZpbHRlciE6IHN0cmluZztcbiAgICBkaXNwbGF5ZWRIYXNNYW55Q29sdW1ucyE6IHN0cmluZ1tdO1xuICAgIGhhc01hbnlEYXRhU291cmNlOiBNYXRUYWJsZURhdGFTb3VyY2U8RW50aXR5VHlwZT4gPSBuZXcgTWF0VGFibGVEYXRhU291cmNlKCk7XG4gICAgaGFzTWFueVNlbGVjdGlvbjogU2VsZWN0aW9uTW9kZWw8RW50aXR5VHlwZT4gPSBuZXcgU2VsZWN0aW9uTW9kZWw8RW50aXR5VHlwZT4odHJ1ZSwgW10pO1xuICAgIGhhc01hbnlJbXBvcnRBY3Rpb24hOiBCYXNlVGFibGVBY3Rpb25JbnRlcm5hbDtcbiAgICBwcml2YXRlIGhhc01hbnlFbnRpdHlTZXJ2aWNlITogRW50aXR5U2VydmljZTxFbnRpdHlUeXBlPjtcbiAgICBAVmlld0NoaWxkKCdjcmVhdGVIYXNNYW55RGlhbG9nJylcbiAgICBjcmVhdGVIYXNNYW55RGlhbG9nITogVGVtcGxhdGVSZWY8dW5rbm93bj47XG4gICAgY3JlYXRlSGFzTWFueURpYWxvZ1JlZiE6IE1hdERpYWxvZ1JlZjx1bmtub3duPjtcbiAgICBAVmlld0NoaWxkKCdlZGl0SGFzTWFueURpYWxvZycpXG4gICAgZWRpdEhhc01hbnlEaWFsb2chOiBUZW1wbGF0ZVJlZjx1bmtub3duPjtcbiAgICBlZGl0SGFzTWFueURpYWxvZ1JlZiE6IE1hdERpYWxvZ1JlZjx1bmtub3duPjtcbiAgICBoYXNNYW55RW50aXR5ITogRW50aXR5VHlwZTtcbiAgICBoYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzITogRW50aXR5VHlwZTtcbiAgICBpc0hhc01hbnlFbnRpdHlWYWxpZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGlzSGFzTWFueUVudGl0eURpcnR5OiBib29sZWFuID0gZmFsc2U7XG4gICAgaGFzTWFueUFsbG93Q3JlYXRlITogYm9vbGVhbjtcbiAgICBoYXNNYW55Q3JlYXRlVGFicyE6IEVudGl0eVRhYjxFbnRpdHlUeXBlPltdO1xuICAgIGhhc01hbnlVcGRhdGVUYWJzITogRW50aXR5VGFiPEVudGl0eVR5cGU+W107XG4gICAgcHJpdmF0ZSBoYXNNYW55Q3JlYXRlQmFzZVVybCE6IHN0cmluZztcblxuICAgIG1ldGFkYXRhUmVmZXJlbmNlc09uZSE6IFJlZmVyZW5jZXNPbmVEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICByZWZlcmVuY2VzT25lT2JqZWN0ITogRW50aXR5VHlwZTtcbiAgICByZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzITogRW50aXR5VGFiPEVudGl0eVR5cGU+W107XG4gICAgcmVmZXJlbmNlc09uZUFsbFJlZmVyZW5jZWRFbnRpdGllcyE6IEVudGl0eVR5cGVbXTtcbiAgICByZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZXMhOiBEcm9wZG93blZhbHVlPHN0cmluZz5bXTtcblxuICAgIHJlYWRvbmx5IERlY29yYXRvclR5cGVzOiB0eXBlb2YgRGVjb3JhdG9yVHlwZXMgPSBEZWNvcmF0b3JUeXBlcztcblxuICAgIEVudGl0eVV0aWxpdGllczogdHlwZW9mIEVudGl0eVV0aWxpdGllcyA9IEVudGl0eVV0aWxpdGllcztcbiAgICBEYXRlVXRpbGl0aWVzOiB0eXBlb2YgRGF0ZVV0aWxpdGllcyA9IERhdGVVdGlsaXRpZXM7XG4gICAgU2VsZWN0aW9uVXRpbGl0aWVzOiB0eXBlb2YgU2VsZWN0aW9uVXRpbGl0aWVzID0gU2VsZWN0aW9uVXRpbGl0aWVzO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3IsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXIsXG4gICAgICAgIEBJbmplY3QoTkdYX0dFVF9WQUxJREFUSU9OX0VSUk9SX01FU1NBR0UpXG4gICAgICAgIHByb3RlY3RlZCByZWFkb25seSBkZWZhdWx0R2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZTogKG1vZGVsOiBOZ01vZGVsKSA9PiBzdHJpbmdcbiAgICApIHt9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGlucHV0IHdpdGggdGhlIGdpdmVuIGtleSBvbiB0aGUgZ2l2ZW4gcHJvcGVydHkgaXMgcmVhZG9ubHkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgLSBUaGUgcHJvcGVydHkgb24gd2hpY2ggdG8gY2hlY2sgdGhlIGlucHV0LlxuICAgICAqIEBwYXJhbSBrZXkgLSBUaGUga2V5IGZvciB0aGUgaW5wdXQgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgdGhlIGlucHV0IGlzIHJlYWRvbmx5LlxuICAgICAqL1xuICAgIGlzUHJvcGVydHlSZWFkT25seShwcm9wZXJ0eTogRW50aXR5VHlwZSwga2V5OiBrZXlvZiBFbnRpdHlUeXBlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnRlcm5hbElzUmVhZE9ubHkgfHwgdGhpcy5tZXRhZGF0YURlZmF1bHRPYmplY3Q/LmlzUmVhZE9ubHkocHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eU1ldGFkYXRhKHByb3BlcnR5LCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhLmlzUmVhZE9ubHkocHJvcGVydHkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIG5lZWRlZCBmb3IgdGhlIGlucHV0cyB0byB3b3JrIGluc2lkZSBhbiBuZ0Zvci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgZWxlbWVudCBpbiB0aGUgbmdGb3IuXG4gICAgICogQHJldHVybnMgVGhlIGluZGV4LlxuICAgICAqL1xuICAgIHRyYWNrQnlGbihpbmRleDogdW5rbm93bik6IHVua25vd24ge1xuICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgdmFsdWUgdG8gZGlzcGxheSBpbiB0aGUgY29sdW1uLlxuICAgICAqIFJ1bnMgaW4gZW52aXJvbm1lbnQgY29udGV4dCB0byBlbmFibGUgaW5qZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdG8gZ2V0IHRoZSB2YWx1ZSBmcm9tLlxuICAgICAqIEBwYXJhbSBkaXNwbGF5Q29sdW1uIC0gVGhlIGRpc3BsYXkgY29sdW1uIHRvIGdldCB0aGUgdmFsdWUgZnJvbS5cbiAgICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgb2YgdGhlIGRpc3BsYXkgY29sdW1uLlxuICAgICAqL1xuICAgIGdldERpc3BsYXlDb2x1bW5WYWx1ZShlbnRpdHk6IEVudGl0eVR5cGUsIGRpc3BsYXlDb2x1bW46IERpc3BsYXlDb2x1bW48RW50aXR5VHlwZT4pOiB1bmtub3duIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBkaXNwbGF5Q29sdW1uLnZhbHVlKGVudGl0eSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZW50aXR5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgcmVxdWlyZWQgSW5wdXQgZGF0YSBcImVudGl0eVwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnRlcm5hbEVudGl0eSA9IHRoaXMuZW50aXR5O1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BlcnR5S2V5ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyByZXF1aXJlZCBJbnB1dCBkYXRhIFwicHJvcGVydHlLZXlcIicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW50ZXJuYWxQcm9wZXJ0eUtleSA9IHRoaXMucHJvcGVydHlLZXk7XG5cbiAgICAgICAgdGhpcy5pbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2UgPSB0aGlzLmdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2UgPz8gdGhpcy5kZWZhdWx0R2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZTtcbiAgICAgICAgdGhpcy5pbnRlcm5hbElzUmVhZE9ubHkgPSB0aGlzLmlzUmVhZE9ubHkgPz8gZmFsc2U7XG5cbiAgICAgICAgdGhpcy50eXBlID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5VHlwZSh0aGlzLmludGVybmFsRW50aXR5LCB0aGlzLmludGVybmFsUHJvcGVydHlLZXkpO1xuICAgICAgICBpZiAodGhpcy52YWxpZEVtcHR5ID09PSB0cnVlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgY29uc3QgY3VycmVudE1ldGFkYXRhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gUmVmbGVjdFV0aWxpdGllcy5nZXRNZXRhZGF0YSgnbWV0YWRhdGEnLCB0aGlzLmludGVybmFsRW50aXR5LCB0aGlzLmludGVybmFsUHJvcGVydHlLZXkpIGFzIFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgUmVmbGVjdFV0aWxpdGllcy5kZWZpbmVNZXRhZGF0YSgnbWV0YWRhdGEnLCB7IC4uLmN1cnJlbnRNZXRhZGF0YSwgcmVxdWlyZWQ6IGRlZmF1bHRGYWxzZSB9LCB0aGlzLmludGVybmFsRW50aXR5LCB0aGlzLmludGVybmFsUHJvcGVydHlLZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWV0YWRhdGEgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YSh0aGlzLmludGVybmFsRW50aXR5LCB0aGlzLmludGVybmFsUHJvcGVydHlLZXksIHRoaXMudHlwZSk7XG5cbiAgICAgICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuT0JKRUNUOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdE9iamVjdElucHV0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkFSUkFZOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdEVudGl0eUFycmF5KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkhBU19NQU5ZOlxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdEhhc01hbnkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuUkVGRVJFTkNFU19PTkU6XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0UmVmZXJlbmNlc09uZSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdFJlZmVyZW5jZXNPbmUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lID0gdGhpcy5tZXRhZGF0YSBhcyBSZWZlcmVuY2VzT25lRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT47XG5cbiAgICAgICAgdm9pZCB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlZmVyZW5jZXNPbmVBbGxSZWZlcmVuY2VkRW50aXRpZXMgPSBhd2FpdCB0aGlzLm1ldGFkYXRhUmVmZXJlbmNlc09uZS5nZXRSZWZlcmVuY2VkRW50aXRpZXMoKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgICAgICB0aGlzLnJlZmVyZW5jZXNPbmVEcm9wZG93blZhbHVlcyA9IHRoaXMubWV0YWRhdGFSZWZlcmVuY2VzT25lLmdldERyb3Bkb3duVmFsdWVzKExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5yZWZlcmVuY2VzT25lQWxsUmVmZXJlbmNlZEVudGl0aWVzKSk7XG4gICAgICAgICAgICB0aGlzLnNldFJlZmVyZW5jZXNPbmVPYmplY3QoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0SGFzTWFueSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZXRhZGF0YUhhc01hbnkgPSB0aGlzLm1ldGFkYXRhIGFzIEhhc01hbnlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlLCBFbnRpdHlUeXBlPjtcbiAgICAgICAgdGhpcy5oYXNNYW55SW1wb3J0QWN0aW9uID0gbmV3IEJhc2VUYWJsZUFjdGlvbkludGVybmFsKHtcbiAgICAgICAgICAgIC4uLnRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5pbXBvcnRBY3Rpb25EYXRhLFxuICAgICAgICAgICAgYWN0aW9uOiAoKSA9PiB0aGlzLnN0YXJ0SW1wb3J0SnNvbigpXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueUFsbG93Q3JlYXRlID0gdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmFsbG93Q3JlYXRlKCk7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlID0gaW5qZWN0PEVudGl0eVNlcnZpY2U8RW50aXR5VHlwZT4+KHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlTZXJ2aWNlQ2xhc3MpO1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55Q3JlYXRlQmFzZVVybCA9IHRoaXMubWV0YWRhdGFIYXNNYW55LmNyZWF0ZUJhc2VVcmwodGhpcy5pbnRlcm5hbEVudGl0eSwgdGhpcy5tZXRhZGF0YUhhc01hbnkpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBnaXZlbkRpc3BsYXlDb2x1bW5zOiBzdHJpbmdbXSA9IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5kaXNwbGF5Q29sdW1ucy5tYXAoKHYpID0+IHYuZGlzcGxheU5hbWUpO1xuICAgICAgICBpZiAodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5maWx0ZXIodEEgPT4gdEEudHlwZSA9PT0gJ211bHRpLXNlbGVjdCcpLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRIYXNNYW55Q29sdW1ucyA9IFsnc2VsZWN0J10uY29uY2F0KGdpdmVuRGlzcGxheUNvbHVtbnMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5kaXNwbGF5ZWRIYXNNYW55Q29sdW1ucyA9IGdpdmVuRGlzcGxheUNvbHVtbnM7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhhc01hbnlEYXRhU291cmNlLnNvcnRpbmdEYXRhQWNjZXNzb3IgPSAoZW50aXR5OiBFbnRpdHlUeXBlLCBoZWFkZXI6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGlzcGxheUNvbHVtbnMuZmluZCgoZHApID0+IGRwLmRpc3BsYXlOYW1lID09PSBoZWFkZXIpPy52YWx1ZShlbnRpdHkpIGFzIHN0cmluZztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc01hbnlEYXRhU291cmNlLnNvcnQgPSB0aGlzLmhhc01hbnlTb3J0O1xuICAgICAgICB0aGlzLmhhc01hbnlEYXRhU291cmNlLmZpbHRlclByZWRpY2F0ZSA9IChlbnRpdHk6IEVudGl0eVR5cGUsIGZpbHRlcjogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZWFyY2hTdHI6IHN0cmluZyA9IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5zZWFyY2hTdHJpbmcoZW50aXR5KTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZFNlYXJjaFN0cmluZzogc3RyaW5nID0gc2VhcmNoU3RyLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRGaWx0ZXJTdHJpbmc6IHN0cmluZyA9IGZpbHRlci50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdHRlZFNlYXJjaFN0cmluZy5pbmNsdWRlcyhmb3JtYXR0ZWRGaWx0ZXJTdHJpbmcpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhc01hbnlEYXRhU291cmNlLmZpbHRlciA9IHRoaXMuaGFzTWFueUZpbHRlcjtcbiAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5wYWdpbmF0b3IgPSB0aGlzLmhhc01hbnlQYWdpbmF0b3I7XG5cbiAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5lbnRpdGllc1N1YmplY3Quc3Vic2NyaWJlKChlbnRpdGllcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5oYXNNYW55RGF0YVNvdXJjZS5kYXRhID0gZW50aXRpZXM7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlYWRCYXNlVXJsOiBzdHJpbmcgPSB0aGlzLm1ldGFkYXRhSGFzTWFueS5yZWFkQmFzZVVybCh0aGlzLmludGVybmFsRW50aXR5LCB0aGlzLm1ldGFkYXRhSGFzTWFueSk7XG4gICAgICAgICAgICB2b2lkIHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UucmVhZChyZWFkQmFzZVVybCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXNNYW55SXNMb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0RW50aXR5QXJyYXkoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheSA9IHRoaXMubWV0YWRhdGEgYXMgRW50aXR5QXJyYXlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxFbnRpdHlbdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5XSA9PSBudWxsKSB7XG4gICAgICAgICAgICAodGhpcy5pbnRlcm5hbEVudGl0eVt0aGlzLmludGVybmFsUHJvcGVydHlLZXldIGFzIEVudGl0eVR5cGVbXSkgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVudGl0eUFycmF5VmFsdWVzID0gdGhpcy5pbnRlcm5hbEVudGl0eVt0aGlzLmludGVybmFsUHJvcGVydHlLZXldIGFzIEVudGl0eVR5cGVbXTtcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lICYmICF0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlRGlhbG9nRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmNyZWF0ZURpYWxvZ0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdBZGQnXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdpdmVuRGlzcGxheUNvbHVtbnM6IHN0cmluZ1tdID0gdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmRpc3BsYXlDb2x1bW5zLm1hcCgodikgPT4gdi5kaXNwbGF5TmFtZSk7XG4gICAgICAgIGlmIChnaXZlbkRpc3BsYXlDb2x1bW5zLmZpbmQocyA9PiBzID09PSAnc2VsZWN0JykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgVGhlIG5hbWUgXCJzZWxlY3RcIiBmb3IgYSBkaXNwbGF5IGNvbHVtbiBpcyByZXNlcnZlZC5cbiAgICAgICAgICAgICAgICBQbGVhc2UgY2hvb3NlIGEgZGlmZmVyZW50IG5hbWUuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVudGl0eUFycmF5RGlzcGxheWVkQ29sdW1ucyA9IHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5ID8gZ2l2ZW5EaXNwbGF5Q29sdW1ucyA6IFsnc2VsZWN0J10uY29uY2F0KGdpdmVuRGlzcGxheUNvbHVtbnMpO1xuICAgICAgICB0aGlzLmVudGl0eUFycmF5RGF0YVNvdXJjZSA9IG5ldyBNYXRUYWJsZURhdGFTb3VyY2UoKTtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXM7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtID0gbmV3IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5FbnRpdHlDbGFzcygpO1xuICAgICAgICB0aGlzLmFycmF5SXRlbVByaW9yQ2hhbmdlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5hcnJheUl0ZW0pO1xuICAgICAgICB0aGlzLmFycmF5SXRlbUlubGluZVRhYnMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyh0aGlzLmFycmF5SXRlbSwgdHJ1ZSk7XG5cbiAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1EaWFsb2dEYXRhID0gbmV3IENyZWF0ZURpYWxvZ0RhdGFCdWlsZGVyKHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5jcmVhdGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCdjcmVhdGVCdXR0b25MYWJlbCcsICdBZGQnKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsICdBZGQgdG8gYXJyYXknKVxuICAgICAgICAgICAgLmdldFJlc3VsdCgpO1xuICAgICAgICB0aGlzLmFycmF5SXRlbURpYWxvZ1RhYnMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyh0aGlzLmFycmF5SXRlbSwgdHJ1ZSk7XG5cbiAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRGlhbG9nRGF0YSA9IHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5lZGl0RGlhbG9nRGF0YTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRPYmplY3RJbnB1dCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tZXRhZGF0YURlZmF1bHRPYmplY3QgPSB0aGlzLm1ldGFkYXRhIGFzIERlZmF1bHRPYmplY3REZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICAgICAgdGhpcy5vYmplY3RQcm9wZXJ0eSA9IHRoaXMuaW50ZXJuYWxFbnRpdHlbdGhpcy5pbnRlcm5hbFByb3BlcnR5S2V5XSBhcyBFbnRpdHlUeXBlO1xuICAgICAgICB0aGlzLm9iamVjdFByb3BlcnR5VGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKFxuICAgICAgICAgICAgdGhpcy5vYmplY3RQcm9wZXJ0eSxcbiAgICAgICAgICAgIHRoaXMuaGlkZU9taXRGb3JDcmVhdGUsXG4gICAgICAgICAgICB0aGlzLmhpZGVPbWl0Rm9yRWRpdCxcbiAgICAgICAgICAgIHRoaXMubWV0YWRhdGFEZWZhdWx0T2JqZWN0Lm9taXRcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXJ0SW1wb3J0SnNvbigpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgICAgICBpbnB1dC50eXBlID0gJ2ZpbGUnO1xuICAgICAgICBpbnB1dC5hY2NlcHQgPSAnYXBwbGljYXRpb24vanNvbic7XG4gICAgICAgIGlucHV0Lm9uY2hhbmdlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlucHV0LmZpbGVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbXBvcnRKc29uKGlucHV0LmZpbGVzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaW5wdXQuY2xpY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGltcG9ydEpzb24oZmlsZTogRmlsZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLmhhc01hbnlJbXBvcnRBY3Rpb24uY29uZmlybURpYWxvZ0RhdGEpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ3RleHQnLCB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuaW1wb3J0QWN0aW9uRGF0YS5jb25maXJtRGlhbG9nRGF0YT8udGV4dCApXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ3RpdGxlJywgdGhpcy5oYXNNYW55SW1wb3J0QWN0aW9uLmRpc3BsYXlOYW1lKVxuICAgICAgICAgICAgLmdldFJlc3VsdCgpO1xuICAgICAgICBjb25zdCBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCBib29sZWFuPiA9IHRoaXMuZGlhbG9nLm9wZW4oTmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgICAgZGF0YTogZGlhbG9nRGF0YSxcbiAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXMgPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHZvaWQgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5pbXBvcnQoZmlsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHJlZmVyZW5jZXMgb25lIG9iamVjdCB1c2luZyB0aGUgaW5wdXQgaWQuXG4gICAgICovXG4gICAgc2V0UmVmZXJlbmNlc09uZU9iamVjdCgpOiB2b2lkIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgY29uc3QgZm91bmRFbnRpdHk6IEVudGl0eVR5cGUgfCB1bmRlZmluZWQgPSB0aGlzLm1ldGFkYXRhUmVmZXJlbmNlc09uZS5nZXRFbnRpdHlGb3JJZCh0aGlzLmludGVybmFsRW50aXR5W3RoaXMuaW50ZXJuYWxQcm9wZXJ0eUtleV0gYXMgc3RyaW5nLCB0aGlzLnJlZmVyZW5jZXNPbmVBbGxSZWZlcmVuY2VkRW50aXRpZXMpO1xuICAgICAgICB0aGlzLnJlZmVyZW5jZXNPbmVPYmplY3QgPSBuZXcgdGhpcy5tZXRhZGF0YVJlZmVyZW5jZXNPbmUuRW50aXR5Q2xhc3MoZm91bmRFbnRpdHkpO1xuICAgICAgICB0aGlzLnJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5VGFicyh0aGlzLnJlZmVyZW5jZXNPbmVPYmplY3QpO1xuICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFZGl0cyBhbiBlbnRpdHkuIFRoaXMgZWl0aGVyIGNhbGxzIHRoZSBlZGl0LU1ldGhvZCBwcm92aWRlZCBieSB0aGUgdXNlciBvciB1c2VzIGEgZGVmYXVsdCBlZGl0LWRpYWxvZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWQuXG4gICAgICogQHRocm93cyBXaGVuIG5vIEVudGl0eUNsYXNzIHdhcyBwcm92aWRlZCwgYXMgYSBuZXcgY2FsbCBpcyBuZWVkZWQgdG8gaW5pdGlhbGl6ZSBtZXRhZGF0YS5cbiAgICAgKi9cbiAgICBlZGl0SGFzTWFueUVudGl0eShlbnRpdHk6IEVudGl0eVR5cGUpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEodGhpcy5oYXNNYW55QWxsb3dVcGRhdGUoZW50aXR5KSB8fCB0aGlzLmhhc01hbnlBbGxvd1JlYWQoZW50aXR5KSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBcIkVudGl0eUNsYXNzXCIgc3BlY2lmaWVkIGZvciB0aGlzIHRhYmxlJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5lZGl0KSB7XG4gICAgICAgICAgICB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZWRpdChuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKGVudGl0eSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuZGVmYXVsdEVkaXQgPT0gJ3BhZ2UnKSB7XG4gICAgICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGVmYXVsdFBhZ2UobmV3IHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcyhlbnRpdHkpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2b2lkIHRoaXMuZWRpdEhhc01hbnlEZWZhdWx0RGlhbG9nKG5ldyB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuRW50aXR5Q2xhc3MoZW50aXR5KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB1cGRhdGluZyB0aGUgcHJvdmlkZWQgZW50aXR5IGZyb20gdGhlIGhhcyBtYW55IHByb3BlcnR5IGlzIGFsbG93ZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gQSBzaW5nbGUgdmFsdWUgb2YgdGhlIGhhcyBtYW55IHByb3BlcnR5IHRoYXQgdGhlIHVzZXIgd2FudHMgdG8gZWRpdC5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIGVkaXQgdGhlIHByb3ZpZGVkIGVudGl0eSBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgICAqL1xuICAgIGhhc01hbnlBbGxvd1VwZGF0ZShlbnRpdHk6IEVudGl0eVR5cGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dVcGRhdGUoZW50aXR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB2aWV3aW5nIHRoZSBwcm92aWRlZCBlbnRpdHkgZnJvbSB0aGUgaGFzIG1hbnkgcHJvcGVydHkgaXMgYWxsb3dlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBBIHNpbmdsZSB2YWx1ZSBvZiB0aGUgaGFzIG1hbnkgcHJvcGVydHkgdGhhdCB0aGUgdXNlciB3YW50cyB0byB2aWV3LlxuICAgICAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgdXNlciBjYW4gdmlldyB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93UmVhZChlbnRpdHk6IEVudGl0eVR5cGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5qZWN0b3IucnVuSW5Db250ZXh0KCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dSZWFkKGVudGl0eSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgZGVsZXRpbmcgdGhlIHByb3ZpZGVkIGVudGl0eSBmcm9tIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSBpcyBhbGxvd2VkLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEEgc2luZ2xlIHZhbHVlIG9mIHRoZSBoYXMgbWFueSBwcm9wZXJ0eSB0aGF0IHRoZSB1c2VyIHdhbnRzIHRvIGRlbGV0ZS5cbiAgICAgKiBAcmV0dXJucyBUcnVlIHdoZW4gdGhlIHVzZXIgY2FuIGRlbGV0ZSB0aGUgcHJvdmlkZWQgZW50aXR5IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICovXG4gICAgaGFzTWFueUFsbG93RGVsZXRlKGVudGl0eTogRW50aXR5VHlwZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5hbGxvd0RlbGV0ZShlbnRpdHkpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGVkaXRIYXNNYW55RGVmYXVsdFBhZ2UoZW50aXR5OiBFbnRpdHlUeXBlKTogdm9pZCB7XG4gICAgICAgIHZvaWQgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWycnLCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmVkaXRCYXNlUm91dGUsIGVudGl0eVt0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmlkS2V5XV0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZWRpdEhhc01hbnlEZWZhdWx0RGlhbG9nKGVudGl0eTogRW50aXR5VHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmhhc01hbnlFbnRpdHkgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGVudGl0eSk7XG4gICAgICAgIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcyA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5oYXNNYW55RW50aXR5KTtcbiAgICAgICAgdGhpcy5oYXNNYW55VXBkYXRlVGFicyA9IEVudGl0eVV0aWxpdGllcy5nZXRFbnRpdHlUYWJzKHRoaXMuaGFzTWFueUVudGl0eSwgZmFsc2UsIHRydWUpO1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNrSGFzTWFueUVudGl0eSgpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuZWRpdEhhc01hbnlEaWFsb2csXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbWluV2lkdGg6ICc2MCUnLFxuICAgICAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXM6IG51bWJlciA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuZWRpdEhhc01hbnlEaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKSkgYXMgbnVtYmVyO1xuICAgICAgICBpZiAocmVzID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhOiBFbnRpdHlUeXBlW10gPSB0aGlzLmhhc01hbnlEYXRhU291cmNlLmRhdGE7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgZGF0YVt0aGlzLmhhc01hbnlEYXRhU291cmNlLmRhdGEuZmluZEluZGV4KChlKSA9PiBlW3RoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuaWRLZXldID09PSBlbnRpdHlbdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS5pZEtleV0pXSA9IGVudGl0eTtcbiAgICAgICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UuZGF0YSA9IGRhdGE7XG4gICAgICAgICAgICB0aGlzLmhhc01hbnlTZWxlY3Rpb24uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIHNhdmUgdGhlIGNoYW5nZXMgYW5kIGNsb3NlIHRoZSBkaWFsb2cgYWZ0ZXJ3YXJkcy5cbiAgICAgKiBBbHNvIGhhbmRsZXMgdGhlIGNvbmZpcm1hdGlvbiBpZiByZXF1aXJlZC5cbiAgICAgKi9cbiAgICBkaWFsb2dFZGl0SGFzTWFueSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaW50ZXJuYWxJc1JlYWRPbmx5IHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eVZhbGlkIHx8ICF0aGlzLmlzSGFzTWFueUVudGl0eURpcnR5KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuZWRpdFJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICBjb25zdCBkaWFsb2dEYXRhOiBDb25maXJtRGlhbG9nRGF0YUludGVybmFsID0gbmV3IENvbmZpcm1EaWFsb2dEYXRhQnVpbGRlcih0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuY29uZmlybUVkaXREaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gc2F2ZSBhbGwgY2hhbmdlcz8nXSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgnY29uZmlybUJ1dHRvbkxhYmVsJywgJ1NhdmUnKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsICdFZGl0JylcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZ0NvbmZpcm1FZGl0SGFzTWFueSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcHJpdmF0ZSBkaWFsb2dDb25maXJtRWRpdEhhc01hbnkoKTogdm9pZCB7XG4gICAgICAgIHZvaWQgdGhpcy5oYXNNYW55RW50aXR5U2VydmljZS51cGRhdGUodGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0SGFzTWFueURpYWxvZ1JlZi5jbG9zZSgxKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIGRlbGV0ZSB0aGUgZW50aXR5IGFuZCBjbG9zZSB0aGUgZGlhbG9nIGFmdGVyd2FyZHMuXG4gICAgICogQWxzbyBoYW5kbGVzIHRoZSBjb25maXJtYXRpb24gaWYgcmVxdWlyZWQuXG4gICAgICovXG4gICAgZGVsZXRlSGFzTWFueUVudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuZWRpdERhdGEuZGVsZXRlUmVxdWlyZXNDb25maXJtRGlhbG9nKSB7XG4gICAgICAgICAgICB0aGlzLmNvbmZpcm1EZWxldGVIYXNNYW55RW50aXR5KCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNvbmZpcm1EZWxldGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gZGVsZXRlIHRoaXMgZW50aXR5PyddKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0eXBlJywgJ2RlbGV0ZScpXG4gICAgICAgICAgICAud2l0aERlZmF1bHQoJ2NvbmZpcm1CdXR0b25MYWJlbCcsICdEZWxldGUnKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0aXRsZScsICdEZWxldGUnKVxuICAgICAgICAgICAgLmdldFJlc3VsdCgpO1xuICAgICAgICBjb25zdCBkaWFsb2dSZWY6IE1hdERpYWxvZ1JlZjxOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCBib29sZWFuPiA9IHRoaXMuZGlhbG9nLm9wZW4oTmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgICAgZGF0YTogZGlhbG9nRGF0YSxcbiAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUocmVzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXMgPT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlybURlbGV0ZUhhc01hbnlFbnRpdHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb25maXJtRGVsZXRlSGFzTWFueUVudGl0eSgpOiB2b2lkIHtcbiAgICAgICAgdm9pZCB0aGlzLmhhc01hbnlFbnRpdHlTZXJ2aWNlLmRlbGV0ZSh0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lZGl0SGFzTWFueURpYWxvZ1JlZi5jbG9zZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIHRoZSBlZGl0aW5nIG9mIHRoZSBoYXMgbWFueSBlbnRpdHkgYW5kIGNsb3NlcyB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIGRpYWxvZ0NhbmNlbEVkaXRIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5oYXNNYW55RW50aXR5LCB0aGlzLmhhc01hbnlFbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICB0aGlzLmVkaXRIYXNNYW55RGlhbG9nUmVmLmNsb3NlKDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgRW50aXR5LiBUaGlzIGVpdGhlciBjYWxscyB0aGUgY3JlYXRlLU1ldGhvZCBwcm92aWRlZCBieSB0aGUgdXNlciBvciB1c2VzIGEgZGVmYXVsdCBjcmVhdGUtZGlhbG9nLlxuICAgICAqXG4gICAgICogQHRocm93cyBXaGVuIG5vIEVudGl0eUNsYXNzIHdhcyBwcm92aWRlZCwgYXMgYSBuZXcgY2FsbCBpcyBuZWVkZWQgdG8gaW5pdGlhbGl6ZSBtZXRhZGF0YS5cbiAgICAgKi9cbiAgICBjcmVhdGVIYXNNYW55RW50aXR5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmFsbG93Q3JlYXRlKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5FbnRpdHlDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIFwiRW50aXR5Q2xhc3NcIiBzcGVjaWZpZWQgZm9yIHRoaXMgdGFibGUnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5jcmVhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmNyZWF0ZShuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGVmYXVsdChuZXcgdGhpcy5tZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLkVudGl0eUNsYXNzKCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVIYXNNYW55RGVmYXVsdChlbnRpdHk6IEVudGl0eVR5cGUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5oYXNNYW55RW50aXR5ID0gZW50aXR5O1xuICAgICAgICB0aGlzLmhhc01hbnlDcmVhdGVUYWJzID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVRhYnModGhpcy5oYXNNYW55RW50aXR5LCB0cnVlKTtcbiAgICAgICAgdGhpcy5jaGVja0lzSGFzTWFueUVudGl0eVZhbGlkKCdjcmVhdGUnKTtcbiAgICAgICAgdGhpcy5jcmVhdGVIYXNNYW55RGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuY3JlYXRlSGFzTWFueURpYWxvZyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogJzYwJScsXG4gICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgaGFzIG1hbnkgZW50aXR5IG92ZXIgdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBkaWFsb2dDcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuaXNIYXNNYW55RW50aXR5VmFsaWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNyZWF0ZVJlcXVpcmVzQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5kaWFsb2dDb25maXJtQ3JlYXRlSGFzTWFueSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIGNvbnN0IGRpYWxvZ0RhdGE6IENvbmZpcm1EaWFsb2dEYXRhSW50ZXJuYWwgPSBuZXcgQ29uZmlybURpYWxvZ0RhdGFCdWlsZGVyKHRoaXMubWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5jcmVhdGVEaWFsb2dEYXRhLmNvbmZpcm1DcmVhdGVEaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgWydEbyB5b3UgcmVhbGx5IHdhbnQgdG8gY3JlYXRlIHRoaXMgZW50aXR5PyddKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCdjb25maXJtQnV0dG9uTGFiZWwnLCAnQ3JlYXRlJylcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCAnQ3JlYXRlJylcbiAgICAgICAgICAgIC5nZXRSZXN1bHQoKTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8Tmd4TWF0RW50aXR5Q29uZmlybURpYWxvZ0NvbXBvbmVudCwgYm9vbGVhbj4gPSB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgIGRhdGE6IGRpYWxvZ0RhdGEsXG4gICAgICAgICAgICBhdXRvRm9jdXM6IGZhbHNlLFxuICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgICAgICBpZiAocmVzID09IHRydWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZ0NvbmZpcm1DcmVhdGVIYXNNYW55KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBwcml2YXRlIGRpYWxvZ0NvbmZpcm1DcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICB2b2lkIHRoaXMuaGFzTWFueUVudGl0eVNlcnZpY2UuY3JlYXRlKHRoaXMuaGFzTWFueUVudGl0eSwgdGhpcy5oYXNNYW55Q3JlYXRlQmFzZVVybCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUhhc01hbnlEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIHRoZSBjcmVhdGluZyBvZiB0aGUgaGFzIG1hbnkgZW50aXR5IGFuZCBjbG9zZXMgdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBkaWFsb2dDYW5jZWxDcmVhdGVIYXNNYW55KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNyZWF0ZUhhc01hbnlEaWFsb2dSZWYuY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSdW5zIHRoZSBUYWJsZUFjdGlvbiBmb3IgYWxsIHNlbGVjdGVkIGVudHJpZXMuXG4gICAgICogQWxzbyBoYW5kbGVzIGNvbmZpcm1hdGlvbiB3aXRoIGFuIGFkZGl0aW9uYWwgZGlhbG9nIGlmIGNvbmZpZ3VyZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYWN0aW9uIC0gVGhlIFRhYmxlQWN0aW9uIHRvIHJ1bi5cbiAgICAgKi9cbiAgICBydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uOiBUYWJsZUFjdGlvbkludGVybmFsPEVudGl0eVR5cGU+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHJlcXVpcmVDb25maXJtRGlhbG9nOiBib29sZWFuID0gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5yZXF1aXJlQ29uZmlybURpYWxvZyh0aGlzLmhhc01hbnlTZWxlY3Rpb24uc2VsZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFyZXF1aXJlQ29uZmlybURpYWxvZykge1xuICAgICAgICAgICAgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGlhbG9nRGF0YTogQ29uZmlybURpYWxvZ0RhdGFJbnRlcm5hbCA9IG5ldyBDb25maXJtRGlhbG9nRGF0YUJ1aWxkZXIoYWN0aW9uLmNvbmZpcm1EaWFsb2dEYXRhKVxuICAgICAgICAgICAgLndpdGhEZWZhdWx0KCd0ZXh0JywgW2BEbyB5b3UgcmVhbGx5IHdhbnQgdG8gcnVuIHRoaXMgYWN0aW9uIG9uICR7dGhpcy5oYXNNYW55U2VsZWN0aW9uLnNlbGVjdGVkLmxlbmd0aH0gZW50cmllcz9gXSlcbiAgICAgICAgICAgIC53aXRoRGVmYXVsdCgndGl0bGUnLCBhY3Rpb24uZGlzcGxheU5hbWUpXG4gICAgICAgICAgICAuZ2V0UmVzdWx0KCk7XG4gICAgICAgIGNvbnN0IGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIGJvb2xlYW4+ID0gdGhpcy5kaWFsb2cub3BlbihOZ3hNYXRFbnRpdHlDb25maXJtRGlhbG9nQ29tcG9uZW50LCB7XG4gICAgICAgICAgICBkYXRhOiBkaWFsb2dEYXRhLFxuICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgIHJlc3RvcmVGb2N1czogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShyZXMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlcyA9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maXJtUnVuSGFzTWFueVRhYmxlQWN0aW9uKGFjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgY29uZmlybVJ1bkhhc01hbnlUYWJsZUFjdGlvbihhY3Rpb246IFRhYmxlQWN0aW9uSW50ZXJuYWw8RW50aXR5VHlwZT4pOiB2b2lkIHtcbiAgICAgICAgdm9pZCB0aGlzLmluamVjdG9yLnJ1bkluQ29udGV4dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBhY3Rpb24uYWN0aW9uKHRoaXMuaGFzTWFueVNlbGVjdGlvbi5zZWxlY3RlZCk7XG4gICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGFuIFRhYmxlQWN0aW9uIGlzIGRpc2FibGVkIChlLmcuIEJlY2F1c2Ugbm8gZW50cmllcyBoYXZlIGJlZW4gc2VsZWN0ZWQpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGFjdGlvbiAtIFRoZSBUYWJsZUFjdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgQWN0aW9uIGNhbiBiZSB1c2VkLlxuICAgICAqL1xuICAgIGhhc01hbnlUYWJsZUFjdGlvbkRpc2FibGVkKGFjdGlvbjogVGFibGVBY3Rpb25JbnRlcm5hbDxFbnRpdHlUeXBlPik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICFhY3Rpb24uZW5hYmxlZCh0aGlzLmhhc01hbnlTZWxlY3Rpb24uc2VsZWN0ZWQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIHRoZSBzZWFyY2ggaW5wdXQgdG8gZmlsdGVyIHRoZSB0YWJsZSBlbnRyaWVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGtleXVwLWV2ZW50IHdoaWNoIGNvbnRhaW5zIHRoZSBzZWFyY2gtc3RyaW5nIG9mIHRoZSB1c2VyLlxuICAgICAqL1xuICAgIGFwcGx5SGFzTWFueUZpbHRlcihldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmlsdGVyVmFsdWU6IHN0cmluZyA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG4gICAgICAgIHRoaXMuaGFzTWFueURhdGFTb3VyY2UuZmlsdGVyID0gZmlsdGVyVmFsdWUudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBlbnRpdHkgaXMgdmFsaWQgZm9yIHVwZGF0aW5nIGFuZCBpZiBpdCBpcyBkaXJ0eS5cbiAgICAgKi9cbiAgICBhc3luYyBjaGVja0hhc01hbnlFbnRpdHkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgndXBkYXRlJyk7XG4gICAgICAgIHRoaXMuaXNIYXNNYW55RW50aXR5RGlydHkgPSBhd2FpdCBFbnRpdHlVdGlsaXRpZXMuaXNEaXJ0eSh0aGlzLmhhc01hbnlFbnRpdHksIHRoaXMuaGFzTWFueUVudGl0eVByaW9yQ2hhbmdlcyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBlbnRpdHkgaXMgdmFsaWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb21pdCAtIFdoZXRoZXIgdmFsdWVzIG9taXR0ZWQgZm9yIGNyZWF0ZSBvciB1cGRhdGUgc2hvdWxkIGJlIGxlZnQgb3V0LlxuICAgICAqL1xuICAgIGNoZWNrSXNIYXNNYW55RW50aXR5VmFsaWQob21pdDogJ2NyZWF0ZScgfCAndXBkYXRlJyk6IHZvaWQge1xuICAgICAgICB0aGlzLmlzSGFzTWFueUVudGl0eVZhbGlkID0gRW50aXR5VXRpbGl0aWVzLmlzRW50aXR5VmFsaWQodGhpcy5oYXNNYW55RW50aXR5LCBvbWl0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgYXJyYXkgaXRlbSBpcyB2YWxpZCBhbmQgaWYgdGhlIGFycmF5IGl0ZW0gaXMgZGlydHkuXG4gICAgICovXG4gICAgY2hlY2tBcnJheUl0ZW0oKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgIHZvaWQgdGhpcy5jaGVja0lzQXJyYXlJdGVtRGlydHkoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGFycmF5IGl0ZW0gaXMgZGlydHkuXG4gICAgICovXG4gICAgYXN5bmMgY2hlY2tJc0FycmF5SXRlbURpcnR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmlzQXJyYXlJdGVtRGlydHkgPSBhd2FpdCBFbnRpdHlVdGlsaXRpZXMuaXNEaXJ0eSh0aGlzLmFycmF5SXRlbSwgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYXJyYXlJdGVtIGlzIHZhbGlkLlxuICAgICAqL1xuICAgIGNoZWNrSXNBcnJheUl0ZW1WYWxpZCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pc0FycmF5SXRlbVZhbGlkID0gRW50aXR5VXRpbGl0aWVzLmlzRW50aXR5VmFsaWQodGhpcy5hcnJheUl0ZW0sICdjcmVhdGUnKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyB0aGF0IGEgdGhlIHZhbHVlIGhhcyBiZWVuIGNoYW5nZWQuXG4gICAgICovXG4gICAgZW1pdENoYW5nZSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pbnB1dENoYW5nZUV2ZW50LmVtaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUcmllcyB0byBhZGQgYW4gaXRlbSB0byB0aGUgZW50aXR5IGFycmF5LlxuICAgICAqIERvZXMgdGhpcyBlaXRoZXIgaW5saW5lIGlmIHRoZSBcImNyZWF0ZUlubGluZVwiLW1ldGFkYXRhIGlzIHNldCB0byB0cnVlXG4gICAgICogb3IgaW4gYSBzZXBhcmF0ZSBkaWFsb2cgaWYgaXQgaXMgc2V0IHRvIGZhbHNlLlxuICAgICAqL1xuICAgIGFzeW5jIGFkZEVudGl0eSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5jcmVhdGVJbmxpbmUpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LmFsbG93RHVwbGljYXRlcykge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdiBvZiB0aGlzLmVudGl0eUFycmF5VmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgoYXdhaXQgRW50aXR5VXRpbGl0aWVzLmlzRXF1YWwodGhpcy5hcnJheUl0ZW0sIHYsIHRoaXMubWV0YWRhdGEsIHRoaXMubWV0YWRhdGFFbnRpdHlBcnJheS5pdGVtVHlwZSkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpYWxvZy5vcGVuKE5neE1hdEVudGl0eUNvbmZpcm1EaWFsb2dDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuZHVwbGljYXRlc0Vycm9yRGlhbG9nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Gb2N1czogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVudGl0eUFycmF5VmFsdWVzLnB1c2goTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSkpO1xuICAgICAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXM7XG4gICAgICAgICAgICBFbnRpdHlVdGlsaXRpZXMucmVzZXRDaGFuZ2VzT25FbnRpdHkodGhpcy5hcnJheUl0ZW0sIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgICAgIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgICAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuYWRkQXJyYXlJdGVtRGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEFycmF5SXRlbURpYWxvZyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1pbldpZHRoOiAnNjAlJyxcbiAgICAgICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVzdG9yZUZvY3VzOiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIHRoZSBhcnJheSBpdGVtIGRlZmluZWQgaW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBhZGRBcnJheUl0ZW0oKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5pc0FycmF5SXRlbVZhbGlkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheVZhbHVlcy5wdXNoKExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5hcnJheUl0ZW0pKTtcbiAgICAgICAgdGhpcy5lbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXM7XG5cbiAgICAgICAgdGhpcy5jbG9zZUFkZEFycmF5SXRlbURpYWxvZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgYWRkaW5nIHRoZSBhcnJheSBpdGVtIGRlZmluZWQgaW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBjbG9zZUFkZEFycmF5SXRlbURpYWxvZygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hZGRBcnJheUl0ZW1EaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgRW50aXR5VXRpbGl0aWVzLnJlc2V0Q2hhbmdlc09uRW50aXR5KHRoaXMuYXJyYXlJdGVtLCB0aGlzLmFycmF5SXRlbVByaW9yQ2hhbmdlcyk7XG4gICAgICAgIHRoaXMuY2hlY2tJc0FycmF5SXRlbVZhbGlkKCk7XG4gICAgICAgIHRoaXMuZW1pdENoYW5nZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGFuIGVudGl0eSBhcnJheSBpdGVtLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdGhhdCBoYXMgYmVlbiBjbGlja2VkLlxuICAgICAqL1xuICAgIGVkaXRBcnJheUl0ZW0oZW50aXR5OiBFbnRpdHlUeXBlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaW5kZXhPZkVkaXRlZEFycmF5SXRlbSA9IHRoaXMuZW50aXR5QXJyYXlWYWx1ZXMuaW5kZXhPZihlbnRpdHkpO1xuICAgICAgICB0aGlzLmFycmF5SXRlbSA9IG5ldyB0aGlzLm1ldGFkYXRhRW50aXR5QXJyYXkuRW50aXR5Q2xhc3MoZW50aXR5KTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW1QcmlvckNoYW5nZXMgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHRoaXMuYXJyYXlJdGVtKTtcblxuICAgICAgICB0aGlzLmNoZWNrQXJyYXlJdGVtKCk7XG5cbiAgICAgICAgdGhpcy5lZGl0QXJyYXlJdGVtRGlhbG9nUmVmID0gdGhpcy5kaWFsb2cub3BlbihcbiAgICAgICAgICAgIHRoaXMuZWRpdEFycmF5SXRlbURpYWxvZyxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogJzYwJScsXG4gICAgICAgICAgICAgICAgYXV0b0ZvY3VzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN0b3JlRm9jdXM6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZXMgY2hhbmdlcyBvbiB0aGUgYXJyYXkgaXRlbSBpbiB0aGUgZGlhbG9nLlxuICAgICAqL1xuICAgIHNhdmVBcnJheUl0ZW0oKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZW50aXR5QXJyYXlWYWx1ZXNbdGhpcy5pbmRleE9mRWRpdGVkQXJyYXlJdGVtXSA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodGhpcy5hcnJheUl0ZW0pO1xuICAgICAgICB0aGlzLmVudGl0eUFycmF5RGF0YVNvdXJjZS5kYXRhID0gdGhpcy5lbnRpdHlBcnJheVZhbHVlcztcblxuICAgICAgICB0aGlzLmNsb3NlRWRpdEFycmF5SXRlbURpYWxvZygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgZWRpdCBhcnJheSBpdGVtIGRpYWxvZyBhbmQgcmVzZXRzIGNoYW5nZXMuXG4gICAgICovXG4gICAgY2xvc2VFZGl0QXJyYXlJdGVtRGlhbG9nKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmVkaXRBcnJheUl0ZW1EaWFsb2dSZWYuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5hcnJheUl0ZW0gPSBuZXcgdGhpcy5tZXRhZGF0YUVudGl0eUFycmF5LkVudGl0eUNsYXNzKCk7XG4gICAgICAgIHRoaXMuYXJyYXlJdGVtUHJpb3JDaGFuZ2VzID0gTG9kYXNoVXRpbGl0aWVzLmNsb25lRGVlcCh0aGlzLmFycmF5SXRlbSk7XG4gICAgICAgIHRoaXMuY2hlY2tBcnJheUl0ZW0oKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgc2VsZWN0ZWQgZW50cmllcyBmcm9tIHRoZSBlbnRpdHkgYXJyYXkuXG4gICAgICovXG4gICAgcmVtb3ZlRnJvbUVudGl0eUFycmF5KCk6IHZvaWQge1xuICAgICAgICBTZWxlY3Rpb25VdGlsaXRpZXMucmVtb3ZlKHRoaXMuZW50aXR5QXJyYXlTZWxlY3Rpb24sIHRoaXMuZW50aXR5QXJyYXlWYWx1ZXMsIHRoaXMuZW50aXR5QXJyYXlEYXRhU291cmNlKTtcbiAgICAgICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gICAgfVxufSIsIjxkaXYgW25nU3dpdGNoXT1cInR5cGVcIiAqbmdJZj1cIiEoaGlkZU9taXRGb3JDcmVhdGUgJiYgbWV0YWRhdGEub21pdEZvckNyZWF0ZSkgJiYgIShoaWRlT21pdEZvckVkaXQgJiYgbWV0YWRhdGEub21pdEZvclVwZGF0ZSlcIj5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS1TdHJpbmdzLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5TVFJJTkdcIj5cbiAgICAgICAgPHN0cmluZy1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvc3RyaW5nLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlNUUklOR19URVhUQk9YXCI+XG4gICAgICAgIDxzdHJpbmctdGV4dGJveC1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvc3RyaW5nLXRleHRib3gtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuU1RSSU5HX0FVVE9DT01QTEVURVwiPlxuICAgICAgICA8c3RyaW5nLWF1dG9jb21wbGV0ZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvc3RyaW5nLWF1dG9jb21wbGV0ZS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5TVFJJTkdfRFJPUERPV05cIj5cbiAgICAgICAgPHN0cmluZy1kcm9wZG93bi1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvc3RyaW5nLWRyb3Bkb3duLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlNUUklOR19QQVNTV09SRFwiPlxuICAgICAgICA8c3RyaW5nLXBhc3N3b3JkLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9zdHJpbmctcGFzc3dvcmQtaW5wdXQ+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS1Cb29sZWFucy0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5CT09MRUFOX0NIRUNLQk9YXCI+XG4gICAgICAgIDxib29sZWFuLWNoZWNrYm94LWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9ib29sZWFuLWNoZWNrYm94LWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkJPT0xFQU5fVE9HR0xFXCI+XG4gICAgICAgIDxib29sZWFuLXRvZ2dsZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYm9vbGVhbi10b2dnbGUtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQk9PTEVBTl9EUk9QRE9XTlwiPlxuICAgICAgICA8Ym9vbGVhbi1kcm9wZG93bi1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYm9vbGVhbi1kcm9wZG93bi1pbnB1dD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS1OdW1iZXJzLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLk5VTUJFUlwiPlxuICAgICAgICA8bnVtYmVyLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9udW1iZXItaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuTlVNQkVSX0RST1BET1dOXCI+XG4gICAgICAgIDxudW1iZXItZHJvcGRvd24taW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L251bWJlci1kcm9wZG93bi1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5OVU1CRVJfU0xJREVSXCI+XG4gICAgICAgIDxudW1iZXItc2xpZGVyLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9udW1iZXItc2xpZGVyLWlucHV0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS1BcnJheS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQVJSQVlfREFURVwiPlxuICAgICAgICA8YXJyYXktZGF0ZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYXJyYXktZGF0ZS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFX1RJTUVcIj5cbiAgICAgICAgPGFycmF5LWRhdGUtdGltZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvYXJyYXktZGF0ZS10aW1lLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkFSUkFZX0RBVEVfUkFOR0VcIj5cbiAgICAgICAgPGFycmF5LWRhdGUtcmFuZ2UtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2FycmF5LWRhdGUtcmFuZ2UtaW5wdXQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQVJSQVlfU1RSSU5HX0NISVBTXCI+XG4gICAgICAgIDxhcnJheS1zdHJpbmctY2hpcHMtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2FycmF5LXN0cmluZy1jaGlwcy1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5BUlJBWV9TVFJJTkdfQVVUT0NPTVBMRVRFX0NISVBTXCI+XG4gICAgICAgIDxhcnJheS1zdHJpbmctYXV0b2NvbXBsZXRlLWNoaXBzXG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9hcnJheS1zdHJpbmctYXV0b2NvbXBsZXRlLWNoaXBzPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS1EYXRlcy0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuREFURVwiPlxuICAgICAgICA8ZGF0ZS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvZGF0ZS1pbnB1dD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5EQVRFX1JBTkdFXCI+XG4gICAgICAgIDxkYXRlLXJhbmdlLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9kYXRlLXJhbmdlLWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkRBVEVfVElNRVwiPlxuICAgICAgICA8ZGF0ZS10aW1lLWlucHV0XG4gICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJlbWl0Q2hhbmdlKClcIlxuICAgICAgICAgICAgW2VudGl0eV09XCJpbnRlcm5hbEVudGl0eVwiXG4gICAgICAgICAgICBba2V5XT1cImludGVybmFsUHJvcGVydHlLZXlcIlxuICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImludGVybmFsSXNSZWFkT25seVwiXG4gICAgICAgID5cbiAgICAgICAgPC9kYXRlLXRpbWUtaW5wdXQ+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLUZpbGVzLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5GSUxFX0RFRkFVTFRcIj5cbiAgICAgICAgPGZpbGUtZGVmYXVsdC1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvZmlsZS1kZWZhdWx0LWlucHV0PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLkZJTEVfSU1BR0VcIj5cbiAgICAgICAgPGZpbGUtaW1hZ2UtaW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2ZpbGUtaW1hZ2UtaW5wdXQ+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0gcmVmZXJlbmNlcyBtYW55IC0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2ICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5SRUZFUkVOQ0VTX01BTllcIj5cbiAgICAgICAgPHJlZmVyZW5jZXMtbWFueS1pbnB1dFxuICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgIFtlbnRpdHldPVwiaW50ZXJuYWxFbnRpdHlcIlxuICAgICAgICAgICAgW2tleV09XCJpbnRlcm5hbFByb3BlcnR5S2V5XCJcbiAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICBbaXNSZWFkT25seV09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICA+XG4gICAgICAgIDwvcmVmZXJlbmNlcy1tYW55LWlucHV0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS1DdXN0b20tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPGRpdiAqbmdTd2l0Y2hDYXNlPVwiRGVjb3JhdG9yVHlwZXMuQ1VTVE9NXCI+XG4gICAgICAgIDxjdXN0b20taW5wdXRcbiAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICBbZW50aXR5XT1cImludGVybmFsRW50aXR5XCJcbiAgICAgICAgICAgIFtrZXldPVwiaW50ZXJuYWxQcm9wZXJ0eUtleVwiXG4gICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaW50ZXJuYWxJc1JlYWRPbmx5XCJcbiAgICAgICAgPlxuICAgICAgICA8L2N1c3RvbS1pbnB1dD5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tT2JqZWN0LS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLk9CSkVDVFwiPlxuICAgICAgICA8Yj57e21ldGFkYXRhRGVmYXVsdE9iamVjdC5kaXNwbGF5TmFtZX19PC9iPlxuICAgICAgICA8IS0tIGl0ZXJhdGVzIG92ZXIgdGhlIG9iamVjdCBwcm9wZXJ0aWVzIC0tPlxuICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cIm9iamVjdFByb3BlcnR5VGFicy5sZW5ndGggPiAxXCIgcHJlc2VydmVDb250ZW50PlxuICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiBvYmplY3RQcm9wZXJ0eVRhYnM7IGxldCB0SSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93cztcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0ICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXM7IGxldCBySSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJvYmplY3RQcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwiaGlkZU9taXRGb3JDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJoaWRlT21pdEZvckVkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbGlkRW1wdHldPVwiIW1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaXNQcm9wZXJ0eVJlYWRPbmx5KG9iamVjdFByb3BlcnR5LCBrZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKG9iamVjdFByb3BlcnR5LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKG9iamVjdFByb3BlcnR5LCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKG9iamVjdFByb3BlcnR5LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICA8L21hdC10YWItZ3JvdXA+XG5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm9iamVjdFByb3BlcnR5VGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2Ygb2JqZWN0UHJvcGVydHlUYWJzWzBdLnJvd3NcIj5cbiAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXQgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5czsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUZuXCJcbiAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJvYmplY3RQcm9wZXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwiaGlkZU9taXRGb3JDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cImhpZGVPbWl0Rm9yRWRpdFwiXG4gICAgICAgICAgICAgICAgICAgIFt2YWxpZEVtcHR5XT1cIiFtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpXCJcbiAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaXNQcm9wZXJ0eVJlYWRPbmx5KG9iamVjdFByb3BlcnR5LCBrZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgob2JqZWN0UHJvcGVydHksIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0gcmVmZXJlbmNlcyBvbmUgLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgKm5nU3dpdGNoQ2FzZT1cIkRlY29yYXRvclR5cGVzLlJFRkVSRU5DRVNfT05FXCI+XG4gICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+e3ttZXRhZGF0YS5kaXNwbGF5TmFtZX19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICA8bWF0LXNlbGVjdCBbKG5nTW9kZWwpXT1cImludGVybmFsRW50aXR5W2ludGVybmFsUHJvcGVydHlLZXldXCJcbiAgICAgICAgICAgICAgICBbbmFtZV09XCJpbnRlcm5hbFByb3BlcnR5S2V5LnRvU3RyaW5nKCkgKyAnaW5wdXQnXCJcbiAgICAgICAgICAgICAgICAjaW5wdXRNb2RlbD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpbnRlcm5hbElzUmVhZE9ubHlcIlxuICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpXCJcbiAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRSZWZlcmVuY2VzT25lT2JqZWN0KClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0lmPVwiIW1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIj4tPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCB2YWx1ZSBvZiByZWZlcmVuY2VzT25lRHJvcGRvd25WYWx1ZXNcIiBbdmFsdWVdPVwidmFsdWUudmFsdWVcIj57e3ZhbHVlLmRpc3BsYXlOYW1lfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yPnt7aW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlKGlucHV0TW9kZWwpfX08L21hdC1lcnJvcj5cbiAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPCEtLSBpdGVyYXRlcyBvdmVyIHRoZSByZWZlcmVuY2VzIG9uZSBwcm9wZXJ0aWVzIC0tPlxuICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cInJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnMgJiYgcmVmZXJlbmNlc09uZVByb3BlcnR5VGFicy5sZW5ndGggPiAxXCIgcHJlc2VydmVDb250ZW50PlxuICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiByZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzOyBsZXQgdEkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUZuXCIgW2xhYmVsXT1cInRhYi50YWJOYW1lXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgdGFiLnJvd3M7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dCAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzOyBsZXQgckkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUZuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwicmVmZXJlbmNlc09uZU9iamVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwiaGlkZU9taXRGb3JDcmVhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJoaWRlT21pdEZvckVkaXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbGlkRW1wdHldPVwiIW1ldGFkYXRhLnJlcXVpcmVkKGVudGl0eSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChyZWZlcmVuY2VzT25lT2JqZWN0LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKHJlZmVyZW5jZXNPbmVPYmplY3QsIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgocmVmZXJlbmNlc09uZU9iamVjdCwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImVtaXRDaGFuZ2UoKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuXG4gICAgICAgIDxkaXYgKm5nSWY9XCJyZWZlcmVuY2VzT25lUHJvcGVydHlUYWJzICYmIHJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnMubGVuZ3RoIDw9IDFcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIHJlZmVyZW5jZXNPbmVQcm9wZXJ0eVRhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dCAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cInJlZmVyZW5jZXNPbmVPYmplY3RcIlxuICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yQ3JlYXRlXT1cImhpZGVPbWl0Rm9yQ3JlYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJoaWRlT21pdEZvckVkaXRcIlxuICAgICAgICAgICAgICAgICAgICBbdmFsaWRFbXB0eV09XCIhbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KVwiXG4gICAgICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChyZWZlcmVuY2VzT25lT2JqZWN0LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKHJlZmVyZW5jZXNPbmVPYmplY3QsIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgocmVmZXJlbmNlc09uZU9iamVjdCwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiZW1pdENoYW5nZSgpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tQXJyYXktLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDxkaXYgY2xhc3M9XCJlbnRpdHlBcnJheVwiICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5BUlJBWVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWVsZXZhdGlvbi16OCBlbGV2YXRpb24tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXJyYXktaGVhZGxpbmVcIj5cbiAgICAgICAgICAgICAgICA8Yj57e21ldGFkYXRhRW50aXR5QXJyYXkuZGlzcGxheU5hbWV9fTwvYj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIm1ldGFkYXRhRW50aXR5QXJyYXkuY3JlYXRlSW5saW5lICYmICFpbnRlcm5hbElzUmVhZE9ubHlcIj5cbiAgICAgICAgICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cImFycmF5SXRlbUlubGluZVRhYnMubGVuZ3RoID4gMVwiIHByZXNlcnZlQ29udGVudD5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiBhcnJheUl0ZW1JbmxpbmVUYWJzXCIgW2xhYmVsXT1cInRhYi50YWJOYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzOyBsZXQgaSA9IGluZGV4OyB0cmFja0J5OiB0cmFja0J5Rm5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImFycmF5SXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwcm9wZXJ0eUtleV09XCJrZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzQXJyYXlJdGVtVmFsaWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgICAgIDwvbWF0LXRhYi1ncm91cD5cblxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJhcnJheUl0ZW1JbmxpbmVUYWJzLmxlbmd0aCA8PSAxXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGFycmF5SXRlbUlubGluZVRhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5czsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUZuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImFycmF5SXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yQ3JlYXRlXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtnZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXT1cImludGVybmFsR2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiY2hlY2tJc0FycmF5SXRlbVZhbGlkKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ1dHRvbnNcIiAqbmdJZj1cIiFpbnRlcm5hbElzUmVhZE9ubHlcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtcmFpc2VkLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwibWV0YWRhdGFFbnRpdHlBcnJheS5jcmVhdGVJbmxpbmUgJiYgIWlzQXJyYXlJdGVtVmFsaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRkRW50aXR5KClcIj5cbiAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUVudGl0eUFycmF5LmFkZEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBtYXQtcmFpc2VkLWJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWVudGl0eUFycmF5U2VsZWN0aW9uLnNlbGVjdGVkLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVGcm9tRW50aXR5QXJyYXkoKVwiPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhRW50aXR5QXJyYXkucmVtb3ZlQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIFxuICAgICAgICAgICAgPG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJlbnRpdHlBcnJheURhdGFTb3VyY2VcIj5cbiAgICAgICAgICAgICAgICA8IS0tIHNlbGVjdCBDb2x1bW4gLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIiAqbmdJZj1cIiFpbnRlcm5hbElzUmVhZE9ubHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWVudGl0eUFycmF5RGF0YVNvdXJjZS5kYXRhLmxlbmd0aFwiIChjaGFuZ2UpPVwiJGV2ZW50ID8gU2VsZWN0aW9uVXRpbGl0aWVzLm1hc3RlclRvZ2dsZShlbnRpdHlBcnJheVNlbGVjdGlvbiwgZW50aXR5QXJyYXlEYXRhU291cmNlKSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cImVudGl0eUFycmF5U2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgU2VsZWN0aW9uVXRpbGl0aWVzLmlzQWxsU2VsZWN0ZWQoZW50aXR5QXJyYXlTZWxlY3Rpb24sIGVudGl0eUFycmF5RGF0YVNvdXJjZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbmRldGVybWluYXRlXT1cImVudGl0eUFycmF5U2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgIVNlbGVjdGlvblV0aWxpdGllcy5pc0FsbFNlbGVjdGVkKGVudGl0eUFycmF5U2VsZWN0aW9uLCBlbnRpdHlBcnJheURhdGFTb3VyY2UpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtaGVhZGVyLWNlbGw+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbnRpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChjaGFuZ2UpPVwiJGV2ZW50ID8gZW50aXR5QXJyYXlTZWxlY3Rpb24udG9nZ2xlKGVudGl0eSkgOiBudWxsXCIgW2NoZWNrZWRdPVwiZW50aXR5QXJyYXlTZWxlY3Rpb24uaXNTZWxlY3RlZChlbnRpdHkpXCI+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNlbGw+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBkQ29sIG9mIG1ldGFkYXRhRW50aXR5QXJyYXkuZGlzcGxheUNvbHVtbnNcIiBbbWF0Q29sdW1uRGVmXT1cImRDb2wuZGlzcGxheU5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7ZENvbC5kaXNwbGF5TmFtZX19XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWhlYWRlci1jZWxsPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNlbGwgKGNsaWNrKT1cImVkaXRBcnJheUl0ZW0oZW50aXR5KVwiIGNsYXNzPVwiZW50aXR5XCIgKm1hdENlbGxEZWY9XCJsZXQgZW50aXR5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7e2dldERpc3BsYXlDb2x1bW5WYWx1ZShlbnRpdHksIGRDb2wpfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2VsbD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIDxtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZW50aXR5QXJyYXlEaXNwbGF5ZWRDb2x1bW5zXCI+PC9tYXQtaGVhZGVyLXJvdz5cbiAgICAgICAgICAgICAgICA8bWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZW50aXR5QXJyYXlEaXNwbGF5ZWRDb2x1bW5zXCI+PC9tYXQtcm93PlxuICAgICAgICAgICAgPC9tYXQtdGFibGU+XG4gICAgICAgIFxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFycmF5LWVycm9yXCIgKm5nSWY9XCJtZXRhZGF0YUVudGl0eUFycmF5LnJlcXVpcmVkICYmICFlbnRpdHlBcnJheURhdGFTb3VyY2UuZGF0YS5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhRW50aXR5QXJyYXkubWlzc2luZ0Vycm9yTWVzc2FnZX19XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuICAgIDwhLS0tLS0tLS0tLS0tLS0tLS0tIGhhcyBtYW55IC0tLS0tLS0tLS0tLS0tLS0+XG4gICAgPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT5cbiAgICA8ZGl2IGNsYXNzPVwiaGFzTWFueVwiICpuZ1N3aXRjaENhc2U9XCJEZWNvcmF0b3JUeXBlcy5IQVNfTUFOWVwiPlxuICAgICAgICA8aDIgY2xhc3M9XCJ0aXRsZVwiPnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50aXRsZX19PC9oMj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJjb2wtbGctOCBjb2wtbWQtNiBjb2wtc20tMTJcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5zZWFyY2hMYWJlbH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IChrZXl1cCk9XCJhcHBseUhhc01hbnlGaWx0ZXIoJGV2ZW50KVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy0yXT1cImhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy00XT1cIiFoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtM109XCJoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtNl09XCIhaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTZdPVwiaGFzTWFueUFsbG93Q3JlYXRlXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTEyXT1cIiFoYXNNYW55QWxsb3dDcmVhdGVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYWN0aW9ucy1idXR0b25cIiBbbWF0TWVudVRyaWdnZXJGb3JdPVwibWVudVwiIG1hdC1yYWlzZWQtYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zTGFiZWx9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bWF0LW1lbnUgI21lbnU9XCJtYXRNZW51XCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEuYWxsb3dKc29uSW1wb3J0XCIgdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJoYXNNYW55VGFibGVBY3Rpb25EaXNhYmxlZChoYXNNYW55SW1wb3J0QWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oaGFzTWFueUltcG9ydEFjdGlvbilcIiBtYXQtbWVudS1pdGVtPlxuICAgICAgICAgICAgICAgICAgICB7e2hhc01hbnlJbXBvcnRBY3Rpb24uZGlzcGxheU5hbWV9fVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0Zvcj1cImxldCBhY3Rpb24gb2YgbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnNcIiBbZGlzYWJsZWRdPVwiaGFzTWFueVRhYmxlQWN0aW9uRGlzYWJsZWQoYWN0aW9uKVwiIChjbGljayk9XCJydW5IYXNNYW55VGFibGVBY3Rpb24oYWN0aW9uKVwiIG1hdC1tZW51LWl0ZW0+XG4gICAgICAgICAgICAgICAgICAgIHt7YWN0aW9uLmRpc3BsYXlOYW1lfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvbWF0LW1lbnU+XG5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cImhhc01hbnlBbGxvd0NyZWF0ZVwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy0yXT1cIm1ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuYmFzZURhdGEudGFibGVBY3Rpb25zLmxlbmd0aFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmNvbC1sZy00XT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtM109XCJtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5jb2wtbWQtNl09XCIhbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTZdPVwibWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS50YWJsZUFjdGlvbnMubGVuZ3RoXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuY29sLXNtLTEyXT1cIiFtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLnRhYmxlQWN0aW9ucy5sZW5ndGhcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY3JlYXRlLWJ1dHRvblwiIChjbGljayk9XCJjcmVhdGVIYXNNYW55RW50aXR5KClcIiBtYXQtcmFpc2VkLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmNyZWF0ZUJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwibWF0LWVsZXZhdGlvbi16OCBlbGV2YXRpb24tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8bWF0LXRhYmxlIFtkYXRhU291cmNlXT1cImhhc01hbnlEYXRhU291cmNlXCIgbWF0U29ydD5cbiAgICAgICAgICAgICAgICA8IS0tIHNlbGVjdCBDb2x1bW4gLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNoYW5nZSk9XCIkZXZlbnQgPyBTZWxlY3Rpb25VdGlsaXRpZXMubWFzdGVyVG9nZ2xlKGhhc01hbnlTZWxlY3Rpb24sIGhhc01hbnlEYXRhU291cmNlKSA6IG51bGxcIiBbY2hlY2tlZF09XCJoYXNNYW55U2VsZWN0aW9uLmhhc1ZhbHVlKCkgJiYgU2VsZWN0aW9uVXRpbGl0aWVzLmlzQWxsU2VsZWN0ZWQoaGFzTWFueVNlbGVjdGlvbiwgaGFzTWFueURhdGFTb3VyY2UpXCIgW2luZGV0ZXJtaW5hdGVdPVwiaGFzTWFueVNlbGVjdGlvbi5oYXNWYWx1ZSgpICYmICFTZWxlY3Rpb25VdGlsaXRpZXMuaXNBbGxTZWxlY3RlZChoYXNNYW55U2VsZWN0aW9uLCBoYXNNYW55RGF0YVNvdXJjZSlcIj4gPC9tYXQtY2hlY2tib3g+XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWhlYWRlci1jZWxsPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZW50aXR5XCIgY2xhc3M9XCJlbnRpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtY2hlY2tib3ggKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiIChjaGFuZ2UpPVwiJGV2ZW50ID8gaGFzTWFueVNlbGVjdGlvbi50b2dnbGUoZW50aXR5KSA6IG51bGxcIiBbY2hlY2tlZF09XCJoYXNNYW55U2VsZWN0aW9uLmlzU2VsZWN0ZWQoZW50aXR5KVwiPiA8L21hdC1jaGVja2JveD5cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtY2VsbD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGRDb2wgb2YgbWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5iYXNlRGF0YS5kaXNwbGF5Q29sdW1uc1wiIFttYXRDb2x1bW5EZWZdPVwiZENvbC5kaXNwbGF5TmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7ZENvbC5kaXNwbGF5TmFtZX19XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWhlYWRlci1jZWxsPlxuICAgICAgICAgICAgICAgICAgICA8bWF0LWNlbGwgY2xhc3M9XCJlbnRpdHlcIiBbY2xhc3MuZW5hYmxlZF09XCJoYXNNYW55QWxsb3dVcGRhdGUoZW50aXR5KSB8fCBoYXNNYW55QWxsb3dSZWFkKGVudGl0eSlcIiAoY2xpY2spPVwiZWRpdEhhc01hbnlFbnRpdHkoZW50aXR5KVwiICptYXRDZWxsRGVmPVwibGV0IGVudGl0eVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tnZXREaXNwbGF5Q29sdW1uVmFsdWUoZW50aXR5LCBkQ29sKX19XG4gICAgICAgICAgICAgICAgICAgIDwvbWF0LWNlbGw+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgICA8bWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZEhhc01hbnlDb2x1bW5zXCI+PC9tYXQtaGVhZGVyLXJvdz5cbiAgICAgICAgICAgICAgICA8bWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZGlzcGxheWVkSGFzTWFueUNvbHVtbnNcIj48L21hdC1yb3c+XG4gICAgICAgICAgICA8L21hdC10YWJsZT5cblxuICAgICAgICAgICAgPG1hdC1zcGlubmVyICpuZ0lmPVwiaGFzTWFueUlzTG9hZGluZyAmJiBtZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmJhc2VEYXRhLmRpc3BsYXlMb2FkaW5nU3Bpbm5lclwiPlxuICAgICAgICAgICAgPC9tYXQtc3Bpbm5lcj5cblxuICAgICAgICAgICAgPG1hdC1wYWdpbmF0b3IgW2xlbmd0aF09XCJoYXNNYW55RGF0YVNvdXJjZS5maWx0ZXJlZERhdGEubGVuZ3RoXCIgW3BhZ2VJbmRleF09XCIwXCIgW3BhZ2VTaXplXT1cIjEwXCIgW3BhZ2VTaXplT3B0aW9uc109XCJbNSwgMTAsIDI1LCA1MF1cIj48L21hdC1wYWdpbmF0b3I+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiAqbmdTd2l0Y2hEZWZhdWx0PkVSUk9SOiBUaGUgdHlwZSB7e3R5cGV9fSBpcyBub3Qga25vd24uPC9kaXY+XG48L2Rpdj5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuXG5cblxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48IS0tLS0tLS0tLS0tLS0tLS0tLS0tQWRkIEFycmF5IEl0ZW0gRGlhbG9nLS0tLS0tLS0tLS0tLS0tLT5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPG5nLXRlbXBsYXRlICNhZGRBcnJheUl0ZW1EaWFsb2c+XG4gICAgPGRpdiBjbGFzcz1cIm1hdC1kaWFsb2ctdGl0bGVcIj5cbiAgICAgICAgPGRpdj57e2FkZEFycmF5SXRlbURpYWxvZ0RhdGEudGl0bGV9fTwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGZvcm0+XG4gICAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cImFycmF5SXRlbURpYWxvZ1RhYnMubGVuZ3RoID4gMVwiIHByZXNlcnZlQ29udGVudD5cbiAgICAgICAgICAgICAgICA8bWF0LXRhYiAqbmdGb3I9XCJsZXQgdGFiIG9mIGFycmF5SXRlbURpYWxvZ1RhYnNcIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgdGFiLnJvd3NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiYXJyYXlJdGVtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2dldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VdPVwiaW50ZXJuYWxHZXRWYWxpZGF0aW9uRXJyb3JNZXNzYWdlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzQXJyYXlJdGVtVmFsaWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYXJyYXlJdGVtRGlhbG9nVGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGFycmF5SXRlbURpYWxvZ1RhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJhcnJheUl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbZ2V0VmFsaWRhdGlvbkVycm9yTWVzc2FnZV09XCJpbnRlcm5hbEdldFZhbGlkYXRpb25FcnJvck1lc3NhZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0lzQXJyYXlJdGVtVmFsaWQoKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICBcbiAgICAgICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJhZGRBcnJheUl0ZW0oKVwiIFtkaXNhYmxlZF09XCIhaXNBcnJheUl0ZW1WYWxpZFwiPlxuICAgICAgICAgICAgICAgIHt7YWRkQXJyYXlJdGVtRGlhbG9nRGF0YS5jcmVhdGVCdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJjbG9zZUFkZEFycmF5SXRlbURpYWxvZygpXCIgY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAge3thZGRBcnJheUl0ZW1EaWFsb2dEYXRhLmNhbmNlbEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L2Zvcm0+XG5cbjwvbmctdGVtcGxhdGU+XG5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLUVkaXQgQXJyYXkgSXRlbSBEaWFsb2ctLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48bmctdGVtcGxhdGUgI2VkaXRBcnJheUl0ZW1EaWFsb2c+XG4gICAgPGRpdiBjbGFzcz1cIm1hdC1kaWFsb2ctdGl0bGVcIj5cbiAgICAgICAgPGRpdj57e2VkaXRBcnJheUl0ZW1EaWFsb2dEYXRhLnRpdGxlKGFycmF5SXRlbVByaW9yQ2hhbmdlcyl9fTwvZGl2PlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxmb3JtPlxuICAgICAgICA8bWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICAgICAgPG1hdC10YWItZ3JvdXAgKm5nSWY9XCJhcnJheUl0ZW1EaWFsb2dUYWJzLmxlbmd0aCA+IDFcIiBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiBhcnJheUl0ZW1EaWFsb2dUYWJzXCIgW2xhYmVsXT1cInRhYi50YWJOYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIHRhYi5yb3dzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZW50aXR5XT1cImFycmF5SXRlbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0FycmF5SXRlbSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaXNSZWFkT25seV09XCJpc1Byb3BlcnR5UmVhZE9ubHkoYXJyYXlJdGVtLCBrZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICAgIDwvbWF0LXRhYi1ncm91cD5cbiAgICAgICAgXG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiYXJyYXlJdGVtRGlhbG9nVGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGFycmF5SXRlbURpYWxvZ1RhYnNbMF0ucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICA8bmd4LW1hdC1lbnRpdHktaW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJhcnJheUl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JFZGl0XT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoYXJyYXlJdGVtLCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGFycmF5SXRlbSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChhcnJheUl0ZW0sIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0FycmF5SXRlbSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImlzUHJvcGVydHlSZWFkT25seShhcnJheUl0ZW0sIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgIFxuICAgICAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgKGNsaWNrKT1cInNhdmVBcnJheUl0ZW0oKVwiIG1hdC1yYWlzZWQtYnV0dG9uIFtkaXNhYmxlZF09XCJpbnRlcm5hbElzUmVhZE9ubHkgfHwgIWlzQXJyYXlJdGVtVmFsaWQgfHwgIWlzQXJyYXlJdGVtRGlydHlcIj5cbiAgICAgICAgICAgICAgICB7e2VkaXRBcnJheUl0ZW1EaWFsb2dEYXRhLmNvbmZpcm1CdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJjbG9zZUVkaXRBcnJheUl0ZW1EaWFsb2coKVwiIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiPlxuICAgICAgICAgICAgICAgIHt7ZWRpdEFycmF5SXRlbURpYWxvZ0RhdGEuY2FuY2VsQnV0dG9uTGFiZWx9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvZm9ybT5cbjwvbmctdGVtcGxhdGU+XG5cbjwhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLUNyZWF0ZSBIYXMgTWFueSBEaWFsb2ctLS0tLS0tLS0tLS0tLS0tPlxuPCEtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0+XG48bmctdGVtcGxhdGUgI2NyZWF0ZUhhc01hbnlEaWFsb2c+XG4gICAgPGRpdiBjbGFzcz1cIm1hdC1kaWFsb2ctdGl0bGVcIj5cbiAgICAgICAgPGRpdj57e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGlhbG9nRGF0YS50aXRsZX19PC9kaXY+XG4gICAgPC9kaXY+XG4gICAgXG4gICAgPGZvcm0+XG4gICAgICAgIDxtYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgICAgICA8bWF0LXRhYi1ncm91cCAqbmdJZj1cImhhc01hbnlDcmVhdGVUYWJzLmxlbmd0aCA+IDFcIiBwcmVzZXJ2ZUNvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPG1hdC10YWIgKm5nRm9yPVwibGV0IHRhYiBvZiBoYXNNYW55Q3JlYXRlVGFic1wiIFtsYWJlbF09XCJ0YWIudGFiTmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicm93XCIgKm5nRm9yPVwibGV0IHJvdyBvZiB0YWIucm93c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGtleSBvZiByb3cua2V5c1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2VudGl0eV09XCJoYXNNYW55RW50aXR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaGlkZU9taXRGb3JDcmVhdGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtbGcte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnbGcnKX19IGNvbC1tZC17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdtZCcpfX0gY29sLXNtLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ3NtJyl9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgnY3JlYXRlJylcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJoYXNNYW55Q3JlYXRlVGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGhhc01hbnlDcmVhdGVUYWJzWzBdLnJvd3NcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiaGFzTWFueUVudGl0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckNyZWF0ZV09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLWxnLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ2xnJyl9fSBjb2wtbWQte3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnbWQnKX19IGNvbC1zbS17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdzbScpfX1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0Q2hhbmdlRXZlbnQpPVwiY2hlY2tJc0hhc01hbnlFbnRpdHlWYWxpZCgnY3JlYXRlJylcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDwvbmd4LW1hdC1lbnRpdHktaW5wdXQ+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgICAgIFxuICAgICAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgKGNsaWNrKT1cImRpYWxvZ0NyZWF0ZUhhc01hbnkoKVwiIG1hdC1yYWlzZWQtYnV0dG9uIFtkaXNhYmxlZF09XCIhaXNIYXNNYW55RW50aXR5VmFsaWRcIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGlhbG9nRGF0YS5jcmVhdGVCdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJkaWFsb2dDYW5jZWxDcmVhdGVIYXNNYW55KClcIiBjbGFzcz1cImNhbmNlbC1idXR0b25cIj5cbiAgICAgICAgICAgICAgICB7e21ldGFkYXRhSGFzTWFueS50YWJsZURhdGEuY3JlYXRlRGlhbG9nRGF0YS5jYW5jZWxCdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9mb3JtPlxuICAgIFxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNlZGl0SGFzTWFueURpYWxvZz5cbiAgICA8ZGl2IGNsYXNzPVwibWF0LWRpYWxvZy10aXRsZVwiPlxuICAgICAgICA8ZGl2Pnt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS50aXRsZShoYXNNYW55RW50aXR5UHJpb3JDaGFuZ2VzKX19PC9kaXY+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0lmPVwiaGFzTWFueUFsbG93RGVsZXRlKGhhc01hbnlFbnRpdHkpXCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cImRlbGV0ZUhhc01hbnlFbnRpdHkoKVwiIGNvbG9yPVwid2FyblwiIGNsYXNzPVwiZGVsZXRlLWJ1dHRvblwiIHRhYmluZGV4PVwiLTFcIj5cbiAgICAgICAgICAgIHt7bWV0YWRhdGFIYXNNYW55LnRhYmxlRGF0YS5lZGl0RGF0YS5kZWxldGVCdXR0b25MYWJlbH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIFxuICAgIDxmb3JtPlxuICAgICAgICA8bWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICAgICAgPG1hdC10YWItZ3JvdXAgKm5nSWY9XCJoYXNNYW55VXBkYXRlVGFicy5sZW5ndGggPiAxXCIgcHJlc2VydmVDb250ZW50PlxuICAgICAgICAgICAgICAgIDxtYXQtdGFiICpuZ0Zvcj1cImxldCB0YWIgb2YgaGFzTWFueVVwZGF0ZVRhYnNcIiBbbGFiZWxdPVwidGFiLnRhYk5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgdGFiLnJvd3NcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZ3gtbWF0LWVudGl0eS1pbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBrZXkgb2Ygcm93LmtleXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiaGFzTWFueUVudGl0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Byb3BlcnR5S2V5XT1cImtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2hpZGVPbWl0Rm9yRWRpdF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXRDaGFuZ2VFdmVudCk9XCJjaGVja0hhc01hbnlFbnRpdHkoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lzUmVhZE9ubHldPVwiaXNQcm9wZXJ0eVJlYWRPbmx5KGhhc01hbnlFbnRpdHksIGtleSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ3gtbWF0LWVudGl0eS1pbnB1dD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgICAgICBcbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJoYXNNYW55VXBkYXRlVGFicy5sZW5ndGggPD0gMVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3dcIiAqbmdGb3I9XCJsZXQgcm93IG9mIGhhc01hbnlVcGRhdGVUYWJzWzBdLnJvd3NcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5neC1tYXQtZW50aXR5LWlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQga2V5IG9mIHJvdy5rZXlzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtlbnRpdHldPVwiaGFzTWFueUVudGl0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlLZXldPVwia2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtoaWRlT21pdEZvckVkaXRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC1sZy17e0VudGl0eVV0aWxpdGllcy5nZXRXaWR0aChoYXNNYW55RW50aXR5LCBrZXksICdsZycpfX0gY29sLW1kLXt7RW50aXR5VXRpbGl0aWVzLmdldFdpZHRoKGhhc01hbnlFbnRpdHksIGtleSwgJ21kJyl9fSBjb2wtc20te3tFbnRpdHlVdGlsaXRpZXMuZ2V0V2lkdGgoaGFzTWFueUVudGl0eSwga2V5LCAnc20nKX19XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dENoYW5nZUV2ZW50KT1cImNoZWNrSGFzTWFueUVudGl0eSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpc1JlYWRPbmx5XT1cImlzUHJvcGVydHlSZWFkT25seShoYXNNYW55RW50aXR5LCBrZXkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8L25neC1tYXQtZW50aXR5LWlucHV0PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICAgICAgICBcbiAgICAgICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cInN1Ym1pdFwiIChjbGljayk9XCJkaWFsb2dFZGl0SGFzTWFueSgpXCIgbWF0LXJhaXNlZC1idXR0b24gW2Rpc2FibGVkXT1cImludGVybmFsSXNSZWFkT25seSB8fCAhaXNIYXNNYW55RW50aXR5VmFsaWQgfHwgIWlzSGFzTWFueUVudGl0eURpcnR5XCI+XG4gICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNvbmZpcm1CdXR0b25MYWJlbH19XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1yYWlzZWQtYnV0dG9uIChjbGljayk9XCJkaWFsb2dDYW5jZWxFZGl0SGFzTWFueSgpXCIgY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCI+XG4gICAgICAgICAgICAgICAge3ttZXRhZGF0YUhhc01hbnkudGFibGVEYXRhLmVkaXREYXRhLmNhbmNlbEJ1dHRvbkxhYmVsfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L2Zvcm0+ICAgIFxuPC9uZy10ZW1wbGF0ZT4iXX0=
|