ngx-material-entity 15.3.1 → 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 +1 -1
- 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 +1 -1
- 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-input/file-input.component.d.ts +1 -1
- package/components/input/input.component.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/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/{esm2020 → esm2022}/components/input/file/file-default-input/file-default-input.component.mjs +4 -4
- 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/{fesm2020 → fesm2022}/ngx-material-entity.mjs +1225 -376
- package/fesm2022/ngx-material-entity.mjs.map +1 -0
- package/package.json +11 -17
- package/utilities/date.utilities.d.ts +1 -1
- 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 -277
- 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 -96
- 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-image-input/file-image-input.component.mjs +0 -100
- package/esm2020/components/input/file/file-input/dragDrop.directive.mjs +0 -63
- package/esm2020/components/input/file/file-input/file-input.component.mjs +0 -198
- package/esm2020/components/input/input.component.mjs +0 -755
- package/esm2020/components/input/input.module.mjs +0 -173
- 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 -198
- 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 -905
- package/fesm2015/ngx-material-entity.mjs +0 -6322
- 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/file.utilities.mjs +0 -0
- /package/{esm2020 → esm2022}/utilities/selection.utilities.mjs +0 -0
|
@@ -1,905 +0,0 @@
|
|
|
1
|
-
import { DecoratorTypes } from '../decorators/base/decorator-types.enum';
|
|
2
|
-
import { LodashUtilities } from '../encapsulation/lodash.utilities';
|
|
3
|
-
import { ReflectUtilities } from '../encapsulation/reflect.utilities';
|
|
4
|
-
import { DateUtilities } from './date.utilities';
|
|
5
|
-
import { FileUtilities } from './file.utilities';
|
|
6
|
-
/**
|
|
7
|
-
* Contains HelperMethods around handling Entities and their property-metadata.
|
|
8
|
-
*/
|
|
9
|
-
export class EntityUtilities {
|
|
10
|
-
/**
|
|
11
|
-
* Gets the properties to omit when updating the entity.
|
|
12
|
-
*
|
|
13
|
-
* @param entity - The entity to get the properties which should be left out for updating from.
|
|
14
|
-
* @returns The properties which should be left out for updating an Entity.
|
|
15
|
-
*/
|
|
16
|
-
static getOmitForUpdate(entity) {
|
|
17
|
-
const res = [];
|
|
18
|
-
for (const key of ReflectUtilities.ownKeys(entity)) {
|
|
19
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
20
|
-
if (metadata.omitForUpdate) {
|
|
21
|
-
res.push(key);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return res;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Gets the properties to omit when creating new entities.
|
|
28
|
-
*
|
|
29
|
-
* @param entity - The entity to get the properties which should be left out for creating from.
|
|
30
|
-
* @returns The properties which should be left out for creating a new Entity.
|
|
31
|
-
*/
|
|
32
|
-
static getOmitForCreate(entity) {
|
|
33
|
-
const res = [];
|
|
34
|
-
for (const key of ReflectUtilities.ownKeys(entity)) {
|
|
35
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
36
|
-
if (metadata.omitForCreate) {
|
|
37
|
-
res.push(key);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return res;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Returns the given entity without the values that should be omitted for creation.
|
|
44
|
-
*
|
|
45
|
-
* @param entity - The entity with all its values.
|
|
46
|
-
* @returns The reduced entity object.
|
|
47
|
-
*/
|
|
48
|
-
static getWithoutOmitCreateValues(entity) {
|
|
49
|
-
return LodashUtilities.omit(entity, EntityUtilities.getOmitForCreate(entity));
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Returns the given entity without the values that should be omitted for updating.
|
|
53
|
-
* This also handles omitting keys for @object or @array values and removes values that haven't been changed by default.
|
|
54
|
-
*
|
|
55
|
-
* @param entity - The entity with all its values.
|
|
56
|
-
* @param entityPriorChanges - The entity before any changes were applied.
|
|
57
|
-
* @param http - The angular HttpClient. Used to fetch files.
|
|
58
|
-
* @returns The reduced entity object.
|
|
59
|
-
*/
|
|
60
|
-
static async getWithoutOmitUpdateValues(entity, entityPriorChanges, http) {
|
|
61
|
-
const res = {};
|
|
62
|
-
for (const key of EntityUtilities.keysOf(entity, false, true)) {
|
|
63
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
64
|
-
const type = EntityUtilities.getPropertyType(entity, key);
|
|
65
|
-
if (!(await EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type, http))) {
|
|
66
|
-
switch (type) {
|
|
67
|
-
case DecoratorTypes.OBJECT:
|
|
68
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
|
-
res[key] = LodashUtilities.omit(entity[key], EntityUtilities.getOmitForCreate(entity[key]));
|
|
70
|
-
break;
|
|
71
|
-
case DecoratorTypes.ARRAY:
|
|
72
|
-
res[key] = entity[key]
|
|
73
|
-
.map(value => LodashUtilities.omit(value, EntityUtilities.getOmitForCreate(value)));
|
|
74
|
-
break;
|
|
75
|
-
default:
|
|
76
|
-
res[key] = entity[key];
|
|
77
|
-
break;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return res;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Gets all properties on the given entity which are files.
|
|
85
|
-
*
|
|
86
|
-
* @param entity - The entity to check for file properties.
|
|
87
|
-
* @param omit - Whether to leave out values that are omitted for create or delete.
|
|
88
|
-
* @returns The keys of all file properties on the given entity.
|
|
89
|
-
*/
|
|
90
|
-
static getFileProperties(entity, omit) {
|
|
91
|
-
const res = [];
|
|
92
|
-
for (const key of ReflectUtilities.ownKeys(entity)) {
|
|
93
|
-
const type = EntityUtilities.getPropertyType(entity, key);
|
|
94
|
-
if (type === DecoratorTypes.FILE_DEFAULT || type === DecoratorTypes.FILE_IMAGE) {
|
|
95
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
96
|
-
if (!(metadata.omitForCreate && omit === 'create') && !(metadata.omitForUpdate && omit === 'update')) {
|
|
97
|
-
res.push(key);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return res;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Gets the metadata included in an property.
|
|
105
|
-
*
|
|
106
|
-
* @param entity - The entity with the property to get the metadata from.
|
|
107
|
-
* @param propertyKey - The property on the given Entity to get the metadata from.
|
|
108
|
-
* @param type - For secure Typing, defines the returned PropertyConfig.
|
|
109
|
-
* @returns The metadata of the property.
|
|
110
|
-
* @throws When no metadata can be found for the given property.
|
|
111
|
-
*/
|
|
112
|
-
static getPropertyMetadata(entity, propertyKey,
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
114
|
-
type) {
|
|
115
|
-
const metadata = ReflectUtilities.getMetadata('metadata', entity, propertyKey);
|
|
116
|
-
if (metadata == null) {
|
|
117
|
-
throw new Error(`Could not find metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
118
|
-
}
|
|
119
|
-
return metadata;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Gets the type of the property-metadata.
|
|
123
|
-
*
|
|
124
|
-
* @param entity - The entity with the property to get the type from.
|
|
125
|
-
* @param propertyKey - The property on the given Entity to get the type from.
|
|
126
|
-
* @returns The type of the metadata.
|
|
127
|
-
* @throws Will throw an error if no metadata can be found for the given property.
|
|
128
|
-
*/
|
|
129
|
-
static getPropertyType(entity, propertyKey) {
|
|
130
|
-
try {
|
|
131
|
-
const propertyType = ReflectUtilities.getMetadata('type', entity, propertyKey);
|
|
132
|
-
if (propertyType == null) {
|
|
133
|
-
throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
134
|
-
}
|
|
135
|
-
return propertyType;
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
throw new Error(`Could not find type metadata for property ${String(propertyKey)} on the entity ${JSON.stringify(entity)}`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Sets all property values based on a given entity data-object.
|
|
143
|
-
*
|
|
144
|
-
* @param target - The target object that needs to be constructed (if called inside an Entity constructor its usually this).
|
|
145
|
-
* @param entity - The data object to get the property values from.
|
|
146
|
-
* @alias new
|
|
147
|
-
* @alias build
|
|
148
|
-
* @alias construct
|
|
149
|
-
*/
|
|
150
|
-
static new(target, entity) {
|
|
151
|
-
for (const key in target) {
|
|
152
|
-
const type = EntityUtilities.getPropertyType(target, key);
|
|
153
|
-
let value = entity ? ReflectUtilities.get(entity, key) : undefined;
|
|
154
|
-
switch (type) {
|
|
155
|
-
case DecoratorTypes.OBJECT:
|
|
156
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
157
|
-
const objectMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.OBJECT);
|
|
158
|
-
value = new objectMetadata.EntityClass(value);
|
|
159
|
-
break;
|
|
160
|
-
case DecoratorTypes.ARRAY:
|
|
161
|
-
const inputArray = value;
|
|
162
|
-
const resArray = [];
|
|
163
|
-
if (inputArray) {
|
|
164
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
165
|
-
const arrayMetadata = EntityUtilities.getPropertyMetadata(target, key, DecoratorTypes.ARRAY);
|
|
166
|
-
for (const item of inputArray) {
|
|
167
|
-
const itemWithMetadata = new arrayMetadata.EntityClass(item);
|
|
168
|
-
resArray.push(itemWithMetadata);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
value = resArray;
|
|
172
|
-
break;
|
|
173
|
-
default:
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
ReflectUtilities.set(target, key, value);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Checks if the values on an entity are valid.
|
|
181
|
-
* Also checks all the validators given by the metadata ("required", "maxLength" etc.).
|
|
182
|
-
*
|
|
183
|
-
* @param entity - The entity to validate.
|
|
184
|
-
* @param omit - Whether to check for creating or editing validity.
|
|
185
|
-
* @returns Whether or not the entity is valid.
|
|
186
|
-
*/
|
|
187
|
-
static isEntityValid(entity, omit) {
|
|
188
|
-
for (const key in entity) {
|
|
189
|
-
if (!EntityUtilities.isPropertyValid(entity, key, omit)) {
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Checks if a single property value is valid.
|
|
197
|
-
*
|
|
198
|
-
* @param entity - The entity where the property is from.
|
|
199
|
-
* @param key - The name of the property.
|
|
200
|
-
* @param omit - Whether to check if the given entity is valid for creation or updating.
|
|
201
|
-
* @returns Whether or not the property value is valid.
|
|
202
|
-
* @throws Throws when it extracts an unknown metadata type.
|
|
203
|
-
*/
|
|
204
|
-
static isPropertyValid(entity, key, omit) {
|
|
205
|
-
const type = EntityUtilities.getPropertyType(entity, key);
|
|
206
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key, type);
|
|
207
|
-
if (metadata.omitForCreate && omit === 'create') {
|
|
208
|
-
return true;
|
|
209
|
-
}
|
|
210
|
-
if (metadata.omitForUpdate && omit === 'update') {
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
213
|
-
if (metadata.required(entity) && type !== DecoratorTypes.HAS_MANY) {
|
|
214
|
-
if (entity[key] == null || entity[key] === '') {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
if (!metadata.required(entity)) {
|
|
219
|
-
if (entity[key] == null || entity[key] === '') {
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
switch (type) {
|
|
224
|
-
case DecoratorTypes.BOOLEAN_DROPDOWN:
|
|
225
|
-
break;
|
|
226
|
-
case DecoratorTypes.BOOLEAN_CHECKBOX:
|
|
227
|
-
case DecoratorTypes.BOOLEAN_TOGGLE:
|
|
228
|
-
const entityBoolean = entity[key];
|
|
229
|
-
const booleanMetadata = metadata;
|
|
230
|
-
if (!EntityUtilities.isBooleanValid(entity, entityBoolean, booleanMetadata)) {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
break;
|
|
234
|
-
case DecoratorTypes.STRING_DROPDOWN:
|
|
235
|
-
break;
|
|
236
|
-
case DecoratorTypes.STRING:
|
|
237
|
-
case DecoratorTypes.STRING_AUTOCOMPLETE:
|
|
238
|
-
const entityString = entity[key];
|
|
239
|
-
const stringMetadata = metadata;
|
|
240
|
-
if (!EntityUtilities.isStringValid(entityString, stringMetadata)) {
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
break;
|
|
244
|
-
case DecoratorTypes.STRING_TEXTBOX:
|
|
245
|
-
const entityTextbox = entity[key];
|
|
246
|
-
const textboxMetadata = metadata;
|
|
247
|
-
if (!EntityUtilities.isTextboxValid(entityTextbox, textboxMetadata)) {
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
case DecoratorTypes.STRING_PASSWORD:
|
|
252
|
-
const entityPassword = entity[key];
|
|
253
|
-
const passwordMetadata = metadata;
|
|
254
|
-
const confirmPassword = ReflectUtilities.getMetadata(this.CONFIRM_PASSWORD_KEY, entity, key);
|
|
255
|
-
if (!EntityUtilities.isPasswordValid(entityPassword, passwordMetadata, confirmPassword)) {
|
|
256
|
-
return false;
|
|
257
|
-
}
|
|
258
|
-
break;
|
|
259
|
-
case DecoratorTypes.NUMBER_DROPDOWN:
|
|
260
|
-
return true;
|
|
261
|
-
case DecoratorTypes.NUMBER:
|
|
262
|
-
case DecoratorTypes.NUMBER_SLIDER:
|
|
263
|
-
const entityNumber = entity[key];
|
|
264
|
-
const numberMetadata = metadata;
|
|
265
|
-
if (!EntityUtilities.isNumberValid(entityNumber, numberMetadata)) {
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
break;
|
|
269
|
-
case DecoratorTypes.OBJECT:
|
|
270
|
-
const entityObject = entity[key];
|
|
271
|
-
for (const parameterKey in entityObject) {
|
|
272
|
-
const value = entityObject[parameterKey];
|
|
273
|
-
if (!metadata.omit.includes(parameterKey)
|
|
274
|
-
&& !(!metadata.required(entity) && (value == null || value == ''))) {
|
|
275
|
-
if (!EntityUtilities.isPropertyValid(entityObject, parameterKey, omit)) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
break;
|
|
281
|
-
case DecoratorTypes.ARRAY_STRING_CHIPS:
|
|
282
|
-
case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS:
|
|
283
|
-
case DecoratorTypes.ARRAY_DATE:
|
|
284
|
-
case DecoratorTypes.ARRAY_DATE_TIME:
|
|
285
|
-
case DecoratorTypes.ARRAY_DATE_RANGE:
|
|
286
|
-
case DecoratorTypes.ARRAY:
|
|
287
|
-
const entityArray = entity[key];
|
|
288
|
-
// eslint-disable-next-line max-len
|
|
289
|
-
const arrayMetadata = metadata;
|
|
290
|
-
if (arrayMetadata.required(entity) && !entityArray.length) {
|
|
291
|
-
return false;
|
|
292
|
-
}
|
|
293
|
-
break;
|
|
294
|
-
case DecoratorTypes.DATE:
|
|
295
|
-
const entityDate = new Date(entity[key]);
|
|
296
|
-
const dateMetadata = metadata;
|
|
297
|
-
if (!EntityUtilities.isDateValid(entityDate, dateMetadata)) {
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
break;
|
|
301
|
-
case DecoratorTypes.DATE_RANGE:
|
|
302
|
-
const entityDateRange = LodashUtilities.cloneDeep(entity[key]);
|
|
303
|
-
const dateRangeMetadata = metadata;
|
|
304
|
-
if (!EntityUtilities.isDateRangeValid(entity, entityDateRange, dateRangeMetadata)) {
|
|
305
|
-
return false;
|
|
306
|
-
}
|
|
307
|
-
break;
|
|
308
|
-
case DecoratorTypes.DATE_TIME:
|
|
309
|
-
const entityDateTime = new Date(entity[key]);
|
|
310
|
-
const dateTimeMetadata = metadata;
|
|
311
|
-
const hasTime = ReflectUtilities.hasMetadata(this.TIME_KEY, entity, key);
|
|
312
|
-
if (!EntityUtilities.isDateTimeValid(entityDateTime, dateTimeMetadata, hasTime)) {
|
|
313
|
-
return false;
|
|
314
|
-
}
|
|
315
|
-
break;
|
|
316
|
-
case DecoratorTypes.FILE_DEFAULT:
|
|
317
|
-
case DecoratorTypes.FILE_IMAGE:
|
|
318
|
-
const entityFile = entity[key];
|
|
319
|
-
const entityFileMetadata = metadata;
|
|
320
|
-
if (!EntityUtilities.isFileDataValid(entityFile, entityFileMetadata)) {
|
|
321
|
-
return false;
|
|
322
|
-
}
|
|
323
|
-
break;
|
|
324
|
-
case DecoratorTypes.REFERENCES_MANY:
|
|
325
|
-
case DecoratorTypes.REFERENCES_ONE:
|
|
326
|
-
case DecoratorTypes.HAS_MANY:
|
|
327
|
-
break;
|
|
328
|
-
case DecoratorTypes.CUSTOM:
|
|
329
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, max-len
|
|
330
|
-
const customMetadata = metadata;
|
|
331
|
-
if (!customMetadata.isValid(entity[key], omit)) {
|
|
332
|
-
return false;
|
|
333
|
-
}
|
|
334
|
-
break;
|
|
335
|
-
default:
|
|
336
|
-
throw new Error(`Could not validate the input because the DecoratorType ${type} is not known`);
|
|
337
|
-
}
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
|
-
static isBooleanValid(entity, value, metadata) {
|
|
341
|
-
if (metadata.required(entity) && !value) {
|
|
342
|
-
return false;
|
|
343
|
-
}
|
|
344
|
-
return true;
|
|
345
|
-
}
|
|
346
|
-
static isStringValid(value, metadata) {
|
|
347
|
-
if (metadata.maxLength && value.length > metadata.maxLength) {
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
if (metadata.minLength && value.length < metadata.minLength) {
|
|
351
|
-
return false;
|
|
352
|
-
}
|
|
353
|
-
if (metadata.regex && !value.match(metadata.regex)) {
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
static isTextboxValid(value, metadata) {
|
|
359
|
-
if (metadata.maxLength && value.length > metadata.maxLength) {
|
|
360
|
-
return false;
|
|
361
|
-
}
|
|
362
|
-
if (metadata.minLength && value.length < metadata.minLength) {
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
return true;
|
|
366
|
-
}
|
|
367
|
-
static isPasswordValid(value, metadata, confirmPassword) {
|
|
368
|
-
if (value !== confirmPassword) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
if (metadata.maxLength && value.length > metadata.maxLength) {
|
|
372
|
-
return false;
|
|
373
|
-
}
|
|
374
|
-
if (metadata.minLength && value.length < metadata.minLength) {
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
if (metadata.regex && !value.match(metadata.regex)) {
|
|
378
|
-
return false;
|
|
379
|
-
}
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
static isNumberValid(value, metadata) {
|
|
383
|
-
if (metadata.max && value > metadata.max) {
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
|
-
if (metadata.min && value < metadata.min) {
|
|
387
|
-
return false;
|
|
388
|
-
}
|
|
389
|
-
return true;
|
|
390
|
-
}
|
|
391
|
-
static isDateValid(value, metadata) {
|
|
392
|
-
if (metadata.min && value.getTime() < metadata.min(value).getTime()) {
|
|
393
|
-
return false;
|
|
394
|
-
}
|
|
395
|
-
if (metadata.max && value.getTime() > metadata.max(value).getTime()) {
|
|
396
|
-
return false;
|
|
397
|
-
}
|
|
398
|
-
if (metadata.filter && !metadata.filter(value)) {
|
|
399
|
-
return false;
|
|
400
|
-
}
|
|
401
|
-
return true;
|
|
402
|
-
}
|
|
403
|
-
static isDateRangeValid(entity, value, metadata) {
|
|
404
|
-
if (metadata.required(entity)) {
|
|
405
|
-
if (!value.start) {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
if (!value.end) {
|
|
409
|
-
return false;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
value.start = new Date(value.start);
|
|
413
|
-
value.end = new Date(value.end);
|
|
414
|
-
if (metadata.minStart && value.start.getTime() < metadata.minStart(value.start).getTime()) {
|
|
415
|
-
return false;
|
|
416
|
-
}
|
|
417
|
-
if (metadata.maxStart && value.start.getTime() > metadata.maxStart(value.start).getTime()) {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
|
-
if (metadata.minEnd && value.end.getTime() < metadata.minEnd(value.end).getTime()) {
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
if (metadata.maxEnd && value.end.getTime() > metadata.maxEnd(value.end).getTime()) {
|
|
424
|
-
return false;
|
|
425
|
-
}
|
|
426
|
-
if (metadata.filter) {
|
|
427
|
-
if (!metadata.filter(value.start)) {
|
|
428
|
-
return false;
|
|
429
|
-
}
|
|
430
|
-
if (!metadata.filter(value.end)) {
|
|
431
|
-
return false;
|
|
432
|
-
}
|
|
433
|
-
if (value.values) {
|
|
434
|
-
for (const date of value.values) {
|
|
435
|
-
if (!metadata.filter(date)) {
|
|
436
|
-
return false;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return true;
|
|
442
|
-
}
|
|
443
|
-
static isDateTimeValid(value, metadata, hasTime) {
|
|
444
|
-
if (!hasTime) {
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
447
|
-
if (metadata.minDate && value.getTime() < metadata.minDate(value).getTime()) {
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
if (metadata.maxDate && value.getTime() > metadata.maxDate(value).getTime()) {
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
if (metadata.filterDate && !metadata.filterDate(value)) {
|
|
454
|
-
return false;
|
|
455
|
-
}
|
|
456
|
-
const time = {
|
|
457
|
-
hours: value.getHours(),
|
|
458
|
-
minutes: value.getMinutes()
|
|
459
|
-
};
|
|
460
|
-
if (metadata.minTime) {
|
|
461
|
-
const minTime = metadata.minTime(value);
|
|
462
|
-
if (!(time.hours > minTime.hours
|
|
463
|
-
|| (time.hours === minTime.hours
|
|
464
|
-
&& time.minutes >= minTime.minutes))) {
|
|
465
|
-
return false;
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (metadata.maxTime) {
|
|
469
|
-
const maxTime = metadata.maxTime(value);
|
|
470
|
-
if (!(time.hours < maxTime.hours
|
|
471
|
-
|| (time.hours === maxTime.hours
|
|
472
|
-
&& time.minutes <= maxTime.minutes))) {
|
|
473
|
-
return false;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
if (metadata.filterTime) {
|
|
477
|
-
if (!metadata.filterTime(time)) {
|
|
478
|
-
return false;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
return true;
|
|
482
|
-
}
|
|
483
|
-
static isFileDataValid(value, metadata) {
|
|
484
|
-
const files = metadata.multiple ? value : [value];
|
|
485
|
-
let fileSizeTotal = 0;
|
|
486
|
-
for (const file of files) {
|
|
487
|
-
if (!file.name || !file.file && !file.url) {
|
|
488
|
-
return false;
|
|
489
|
-
}
|
|
490
|
-
if (!FileUtilities.isMimeTypeValid(file.type, metadata.allowedMimeTypes)) {
|
|
491
|
-
return false;
|
|
492
|
-
}
|
|
493
|
-
if (FileUtilities.transformToMegaBytes(file.size, 'B') > metadata.maxSize) {
|
|
494
|
-
return false;
|
|
495
|
-
}
|
|
496
|
-
fileSizeTotal += file.size;
|
|
497
|
-
if (FileUtilities.transformToMegaBytes(fileSizeTotal, 'B') > metadata.maxSizeTotal) {
|
|
498
|
-
return false;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
return true;
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Checks if an entity is "dirty" (if its values have changed).
|
|
505
|
-
*
|
|
506
|
-
* @param entity - The entity after all changes.
|
|
507
|
-
* @param entityPriorChanges - The entity before the changes.
|
|
508
|
-
* @param http - The angular HttpClient. Used to fetch files.
|
|
509
|
-
* @returns Whether or not the entity is dirty.
|
|
510
|
-
*/
|
|
511
|
-
static async isDirty(entity, entityPriorChanges, http) {
|
|
512
|
-
if (!entityPriorChanges) {
|
|
513
|
-
return false;
|
|
514
|
-
}
|
|
515
|
-
const differences = await EntityUtilities.differencesForDirty(entity, entityPriorChanges, http);
|
|
516
|
-
return differences.length ? true : false;
|
|
517
|
-
}
|
|
518
|
-
static async differencesForDirty(entity, entityPriorChanges, http) {
|
|
519
|
-
const res = [];
|
|
520
|
-
for (const key of ReflectUtilities.ownKeys(entity)) {
|
|
521
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
522
|
-
const type = EntityUtilities.getPropertyType(entity, key);
|
|
523
|
-
if (!(await EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type, http))) {
|
|
524
|
-
res.push({
|
|
525
|
-
key: key,
|
|
526
|
-
before: entityPriorChanges[key],
|
|
527
|
-
after: entity[key]
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
else {
|
|
531
|
-
// This is needed to set blob file data so that it is only requested once.
|
|
532
|
-
entityPriorChanges[key] = LodashUtilities.cloneDeep(entity[key]);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return res;
|
|
536
|
-
}
|
|
537
|
-
// TODO Remove
|
|
538
|
-
/**
|
|
539
|
-
* Compares two Entities and returns their difference in an object.
|
|
540
|
-
*
|
|
541
|
-
* @param entity - The first entity to compare.
|
|
542
|
-
* @param entityPriorChanges - The second entity to compare.
|
|
543
|
-
* @returns The difference between the two Entities in form of a Partial.
|
|
544
|
-
*/
|
|
545
|
-
// static async difference<EntityType extends BaseEntityType<EntityType>>(
|
|
546
|
-
// entity: EntityType,
|
|
547
|
-
// entityPriorChanges: EntityType
|
|
548
|
-
// ): Promise<Partial<EntityType>> {
|
|
549
|
-
// const res: Partial<EntityType> = {};
|
|
550
|
-
// for (const key in entity) {
|
|
551
|
-
// const metadata: PropertyDecoratorConfigInternal = EntityUtilities.getPropertyMetadata(entity, key);
|
|
552
|
-
// const type: DecoratorTypes = EntityUtilities.getPropertyType(entity, key);
|
|
553
|
-
// if (!(await EntityUtilities.isEqual(entity[key], entityPriorChanges[key], metadata, type))) {
|
|
554
|
-
// res[key] = entity[key];
|
|
555
|
-
// }
|
|
556
|
-
// }
|
|
557
|
-
// return res;
|
|
558
|
-
// }
|
|
559
|
-
/**
|
|
560
|
-
* Checks if two given values are equal.
|
|
561
|
-
* It uses the isEqual method from LodashUtilities and extends it with functionality regarding Dates.
|
|
562
|
-
*
|
|
563
|
-
* @param value - The updated value.
|
|
564
|
-
* @param valuePriorChanges - The value before any changes.
|
|
565
|
-
* @param metadata - The metadata of the property.
|
|
566
|
-
* @param type - The type of the property.
|
|
567
|
-
* @param http - The angular HttpClient. Used to fetch files.
|
|
568
|
-
* @returns Whether or not the given values are equal.
|
|
569
|
-
*/
|
|
570
|
-
static async isEqual(value, valuePriorChanges, metadata, type, http) {
|
|
571
|
-
switch (type) {
|
|
572
|
-
case DecoratorTypes.DATE_RANGE:
|
|
573
|
-
return EntityUtilities.isEqualDateRange(value, valuePriorChanges, metadata.filter);
|
|
574
|
-
case DecoratorTypes.DATE:
|
|
575
|
-
return EntityUtilities.isEqualDate(value, valuePriorChanges);
|
|
576
|
-
case DecoratorTypes.DATE_TIME:
|
|
577
|
-
return EntityUtilities.isEqualDateTime(value, valuePriorChanges);
|
|
578
|
-
case DecoratorTypes.ARRAY_DATE:
|
|
579
|
-
case DecoratorTypes.ARRAY_DATE_TIME:
|
|
580
|
-
return EntityUtilities.isEqualArrayDate(value, valuePriorChanges);
|
|
581
|
-
case DecoratorTypes.ARRAY_DATE_RANGE:
|
|
582
|
-
return EntityUtilities.isEqualArrayDateRange(value, valuePriorChanges, metadata.filter);
|
|
583
|
-
case DecoratorTypes.ARRAY_STRING_CHIPS:
|
|
584
|
-
case DecoratorTypes.ARRAY_STRING_AUTOCOMPLETE_CHIPS:
|
|
585
|
-
return EntityUtilities.isEqualArrayString(value, valuePriorChanges);
|
|
586
|
-
case DecoratorTypes.FILE_IMAGE:
|
|
587
|
-
case DecoratorTypes.FILE_DEFAULT:
|
|
588
|
-
// eslint-disable-next-line max-len
|
|
589
|
-
return EntityUtilities.isEqualFile(value, valuePriorChanges, metadata.multiple, http);
|
|
590
|
-
case DecoratorTypes.CUSTOM:
|
|
591
|
-
// eslint-disable-next-line max-len, @typescript-eslint/no-explicit-any
|
|
592
|
-
return EntityUtilities.isEqualCustom(value, valuePriorChanges, metadata);
|
|
593
|
-
default:
|
|
594
|
-
return LodashUtilities.isEqual(value, valuePriorChanges);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
static isEqualArrayString(value, valuePriorChanges) {
|
|
598
|
-
const stringArray = LodashUtilities.cloneDeep(value).sort();
|
|
599
|
-
const stringArrayPriorChanges = LodashUtilities.cloneDeep(valuePriorChanges).sort();
|
|
600
|
-
return LodashUtilities.isEqual(stringArray, stringArrayPriorChanges);
|
|
601
|
-
}
|
|
602
|
-
static isEqualArrayDate(value, valuePriorChanges) {
|
|
603
|
-
const newValue = value.map(v => new Date(v)).sort();
|
|
604
|
-
const newValuePriorChanges = valuePriorChanges.map(v => new Date(v)).sort();
|
|
605
|
-
return LodashUtilities.isEqual(newValue, newValuePriorChanges);
|
|
606
|
-
}
|
|
607
|
-
static isEqualArrayDateRange(value, valuePriorChanges, filter) {
|
|
608
|
-
const dateRanges = value.sort();
|
|
609
|
-
const dateRangesPriorChanges = valuePriorChanges.sort();
|
|
610
|
-
if (dateRanges.length !== dateRangesPriorChanges.length) {
|
|
611
|
-
return false;
|
|
612
|
-
}
|
|
613
|
-
for (let i = 0; i < dateRanges.length; i++) {
|
|
614
|
-
if (!EntityUtilities.isEqualDateRange(dateRanges[i], dateRangesPriorChanges[i], filter)) {
|
|
615
|
-
return false;
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return true;
|
|
619
|
-
}
|
|
620
|
-
static isEqualDateTime(value, valuePriorChanges) {
|
|
621
|
-
const date = new Date(value);
|
|
622
|
-
const datePriorChanges = new Date(valuePriorChanges);
|
|
623
|
-
return LodashUtilities.isEqual(date, datePriorChanges);
|
|
624
|
-
}
|
|
625
|
-
static isEqualDate(value, valuePriorChanges) {
|
|
626
|
-
const date = new Date(value);
|
|
627
|
-
const datePriorChanges = new Date(valuePriorChanges);
|
|
628
|
-
date.setHours(0, 0, 0, 0);
|
|
629
|
-
datePriorChanges.setHours(0, 0, 0, 0);
|
|
630
|
-
return LodashUtilities.isEqual(date, datePriorChanges);
|
|
631
|
-
}
|
|
632
|
-
static isEqualDateRange(value, valuePriorChanges, filter) {
|
|
633
|
-
const dateRange = LodashUtilities.cloneDeep(value);
|
|
634
|
-
dateRange.start = new Date(value.start);
|
|
635
|
-
dateRange.end = new Date(value.end);
|
|
636
|
-
dateRange.values = DateUtilities.getDatesBetween(dateRange.start, dateRange.end, filter);
|
|
637
|
-
const dateRangePriorChanges = LodashUtilities.cloneDeep(valuePriorChanges);
|
|
638
|
-
dateRangePriorChanges.start = new Date(valuePriorChanges.start);
|
|
639
|
-
dateRangePriorChanges.end = new Date(valuePriorChanges.end);
|
|
640
|
-
dateRangePriorChanges.values = DateUtilities.getDatesBetween(dateRangePriorChanges.start, dateRangePriorChanges.end, filter);
|
|
641
|
-
return LodashUtilities.isEqual(dateRange, dateRangePriorChanges);
|
|
642
|
-
}
|
|
643
|
-
// TODO: Find a way to use blobs with jest
|
|
644
|
-
/* istanbul ignore next */
|
|
645
|
-
static async isEqualFile(value, valuePriorChanges, multiple, http) {
|
|
646
|
-
if (value == null) {
|
|
647
|
-
if (valuePriorChanges == null) {
|
|
648
|
-
return true;
|
|
649
|
-
}
|
|
650
|
-
else {
|
|
651
|
-
return false;
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
const files = multiple ? value.sort() : [value].sort();
|
|
655
|
-
const filesPriorChanges = multiple ? valuePriorChanges.sort() : [valuePriorChanges].sort();
|
|
656
|
-
if (files.length !== filesPriorChanges.length) {
|
|
657
|
-
return false;
|
|
658
|
-
}
|
|
659
|
-
for (let i = 0; i < files.length; i++) {
|
|
660
|
-
// checks this before actually getting any files due to performance reasons.
|
|
661
|
-
if (!LodashUtilities.isEqual(LodashUtilities.omit(files[i], 'file'), LodashUtilities.omit(filesPriorChanges[i], 'file'))) {
|
|
662
|
-
return false;
|
|
663
|
-
}
|
|
664
|
-
if (filesPriorChanges[i].file && !files[i].file) {
|
|
665
|
-
files[i] = await FileUtilities.getFileData(files[i], http);
|
|
666
|
-
value = files[i];
|
|
667
|
-
}
|
|
668
|
-
if (files[i].file && !filesPriorChanges[i].file) {
|
|
669
|
-
filesPriorChanges[i] = await FileUtilities.getFileData(filesPriorChanges[i], http);
|
|
670
|
-
valuePriorChanges = filesPriorChanges[i];
|
|
671
|
-
}
|
|
672
|
-
if (!LodashUtilities.isEqual(await files[i].file?.text(), await filesPriorChanges[i].file?.text())) {
|
|
673
|
-
return false;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
return true;
|
|
677
|
-
}
|
|
678
|
-
static isEqualCustom(value, valuePriorChanges,
|
|
679
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
680
|
-
metadata) {
|
|
681
|
-
if (!metadata.isEqual(value, valuePriorChanges, metadata)) {
|
|
682
|
-
return false;
|
|
683
|
-
}
|
|
684
|
-
return true;
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Compare function for sorting entity keys by their order value.
|
|
688
|
-
*
|
|
689
|
-
* @param a - First key of entity.
|
|
690
|
-
* @param b - Second key of entity.
|
|
691
|
-
* @param entity - Current entity (used to get metadata of entity keys).
|
|
692
|
-
* @returns 0 if both values have the same order, a negative value if 'a' comes before 'b', a positive value if 'a' comes behind 'b'.
|
|
693
|
-
*/
|
|
694
|
-
static compareOrder(a, b, entity) {
|
|
695
|
-
const metadataA = EntityUtilities.getPropertyMetadata(entity, a);
|
|
696
|
-
const metadataB = EntityUtilities.getPropertyMetadata(entity, b);
|
|
697
|
-
if (metadataA.position.order === -1) {
|
|
698
|
-
if (metadataB.position.order === -1) {
|
|
699
|
-
return 0;
|
|
700
|
-
}
|
|
701
|
-
return 1;
|
|
702
|
-
}
|
|
703
|
-
else if (metadataB.position.order === -1) {
|
|
704
|
-
return -1;
|
|
705
|
-
}
|
|
706
|
-
return metadataA.position.order - metadataB.position.order;
|
|
707
|
-
}
|
|
708
|
-
/**
|
|
709
|
-
* Gets the bootstrap column values for "lg", "md", "sm".
|
|
710
|
-
*
|
|
711
|
-
* @param entity - Entity to get the bootstrap column values of the key.
|
|
712
|
-
* @param key - Key of the property to get bootstrap column values from.
|
|
713
|
-
* @param type - Defines for which screen size the column values should be returned.
|
|
714
|
-
* @returns Bootstrap column value.
|
|
715
|
-
*/
|
|
716
|
-
static getWidth(entity, key, type) {
|
|
717
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
718
|
-
switch (type) {
|
|
719
|
-
case 'lg':
|
|
720
|
-
return metadata.defaultWidths[0];
|
|
721
|
-
case 'md':
|
|
722
|
-
return metadata.defaultWidths[1];
|
|
723
|
-
case 'sm':
|
|
724
|
-
return metadata.defaultWidths[2];
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
/**
|
|
728
|
-
* Resets all changes on an entity.
|
|
729
|
-
*
|
|
730
|
-
* @param entity - The entity to reset.
|
|
731
|
-
* @param entityPriorChanges - The entity before any changes.
|
|
732
|
-
*/
|
|
733
|
-
static resetChangesOnEntity(entity, entityPriorChanges) {
|
|
734
|
-
for (const key in entityPriorChanges) {
|
|
735
|
-
ReflectUtilities.set(entity, key, ReflectUtilities.get(entityPriorChanges, key));
|
|
736
|
-
if (ReflectUtilities.hasMetadata(this.METADATA_KEYS_TO_RESET_KEY, entity, key)) {
|
|
737
|
-
for (const k of ReflectUtilities.getMetadata(this.METADATA_KEYS_TO_RESET_KEY, entity, key)) {
|
|
738
|
-
if (ReflectUtilities.hasMetadata(k, entity, key)) {
|
|
739
|
-
ReflectUtilities.defineMetadata(k, undefined, entity, key);
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
static getEntityRows(entity, tab, hideOmitForCreate, hideOmitForEdit, additionalOmitValues) {
|
|
746
|
-
const res = [];
|
|
747
|
-
const keys = EntityUtilities.keysOf(entity, hideOmitForCreate, hideOmitForEdit)
|
|
748
|
-
.filter(k => !additionalOmitValues.includes(k));
|
|
749
|
-
const numberOfRows = EntityUtilities.getNumberOfRows(keys, entity, tab);
|
|
750
|
-
for (let i = 1; i <= numberOfRows; i++) {
|
|
751
|
-
const row = {
|
|
752
|
-
row: i,
|
|
753
|
-
keys: EntityUtilities.getKeysForRow(keys, entity, i, tab)
|
|
754
|
-
};
|
|
755
|
-
res.push(row);
|
|
756
|
-
}
|
|
757
|
-
if (EntityUtilities.getKeysForRow(keys, entity, -1, tab).length) {
|
|
758
|
-
const lastRow = {
|
|
759
|
-
row: numberOfRows + 1,
|
|
760
|
-
keys: EntityUtilities.getKeysForRow(keys, entity, -1, tab)
|
|
761
|
-
};
|
|
762
|
-
res.push(lastRow);
|
|
763
|
-
}
|
|
764
|
-
return res;
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Gets the tabs that are used to display the given entity.
|
|
768
|
-
*
|
|
769
|
-
* @param entity - The entity to get the rows from.
|
|
770
|
-
* @param hideOmitForCreate - Whether or not keys with the metadata omitForCreate should be filtered out.
|
|
771
|
-
* @param hideOmitForEdit - Whether or not keys with the metadata omitForUpdate should be filtered out.
|
|
772
|
-
* @param additionalOmitValues - Additional omit values.
|
|
773
|
-
* @returns The sorted Tabs containing the rows and the keys to display in that row.
|
|
774
|
-
*/
|
|
775
|
-
static getEntityTabs(entity, hideOmitForCreate = false, hideOmitForEdit = false, additionalOmitValues = []) {
|
|
776
|
-
const res = [];
|
|
777
|
-
const keys = EntityUtilities.keysOf(entity, hideOmitForCreate, hideOmitForEdit)
|
|
778
|
-
.filter(k => !additionalOmitValues.includes(k));
|
|
779
|
-
const numberOfTabs = EntityUtilities.getNumberOfTabs(keys, entity);
|
|
780
|
-
// eslint-disable-next-line max-len
|
|
781
|
-
const firstTabRows = EntityUtilities.getEntityRows(entity, -1, hideOmitForCreate, hideOmitForEdit, additionalOmitValues);
|
|
782
|
-
if (firstTabRows.length) {
|
|
783
|
-
const firstTab = {
|
|
784
|
-
tabName: EntityUtilities.getFirstTabName(entity),
|
|
785
|
-
tab: -1,
|
|
786
|
-
rows: firstTabRows
|
|
787
|
-
};
|
|
788
|
-
res.push(firstTab);
|
|
789
|
-
}
|
|
790
|
-
for (let i = 2; i <= numberOfTabs; i++) {
|
|
791
|
-
const rows = EntityUtilities.getEntityRows(entity, i, hideOmitForCreate, hideOmitForEdit, additionalOmitValues);
|
|
792
|
-
if (rows.length) {
|
|
793
|
-
const tab = {
|
|
794
|
-
tabName: EntityUtilities.getTabName(entity, i),
|
|
795
|
-
tab: i,
|
|
796
|
-
rows: rows
|
|
797
|
-
};
|
|
798
|
-
res.push(tab);
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
return res;
|
|
802
|
-
}
|
|
803
|
-
static getKeysForRow(keys, entity, row, tab) {
|
|
804
|
-
return keys
|
|
805
|
-
.filter(k => EntityUtilities.getPropertyMetadata(entity, k).position.row === row)
|
|
806
|
-
.filter(k => EntityUtilities.getPropertyMetadata(entity, k).position.tab === tab)
|
|
807
|
-
.sort((a, b) => EntityUtilities.compareOrder(a, b, entity));
|
|
808
|
-
}
|
|
809
|
-
static getNumberOfRows(keys, entity, tab) {
|
|
810
|
-
return keys
|
|
811
|
-
.filter(k => EntityUtilities.getPropertyMetadata(entity, k).position.tab === tab)
|
|
812
|
-
.map(k => EntityUtilities.getPropertyMetadata(entity, k).position.row)
|
|
813
|
-
.sort((a, b) => (a > b ? -1 : 1))[0];
|
|
814
|
-
}
|
|
815
|
-
static getNumberOfTabs(keys, entity) {
|
|
816
|
-
return keys
|
|
817
|
-
.map(k => EntityUtilities.getPropertyMetadata(entity, k).position.tab)
|
|
818
|
-
.sort((a, b) => (a > b ? -1 : 1))[0];
|
|
819
|
-
}
|
|
820
|
-
static getTabName(entity, tab) {
|
|
821
|
-
const providedTabName = ReflectUtilities.ownKeys(entity)
|
|
822
|
-
.map(k => EntityUtilities.getPropertyMetadata(entity, k))
|
|
823
|
-
.find(m => m.position.tab === tab && m.position.tabName)?.position.tabName;
|
|
824
|
-
return providedTabName ?? `Tab ${tab}`;
|
|
825
|
-
}
|
|
826
|
-
static getFirstTabName(entity) {
|
|
827
|
-
const providedTabName = ReflectUtilities.ownKeys(entity)
|
|
828
|
-
.map(k => EntityUtilities.getPropertyMetadata(entity, k))
|
|
829
|
-
.find(m => m.position.tabName && m.position.tab === -1)?.position.tabName;
|
|
830
|
-
return providedTabName ?? 'Tab 1';
|
|
831
|
-
}
|
|
832
|
-
/**
|
|
833
|
-
* Gets the keys of the provided entity correctly typed.
|
|
834
|
-
*
|
|
835
|
-
* @param entity - The entity to get the keys of.
|
|
836
|
-
* @param hideOmitForCreate - Whether or not keys with the metadata omitForCreate should be filtered out.
|
|
837
|
-
* @param hideOmitForEdit - Whether or not keys with the metadata omitForUpdate should be filtered out.
|
|
838
|
-
* @returns An array of keys of the entity.
|
|
839
|
-
*/
|
|
840
|
-
static keysOf(entity, hideOmitForCreate = false, hideOmitForEdit = false) {
|
|
841
|
-
let keys = ReflectUtilities.ownKeys(entity);
|
|
842
|
-
const dontDisplayKeys = EntityUtilities.getDontDisplayKeys(entity);
|
|
843
|
-
keys = keys.filter(k => !dontDisplayKeys.includes(k));
|
|
844
|
-
if (hideOmitForCreate) {
|
|
845
|
-
const omitForCreateKeys = EntityUtilities.getOmitForCreate(entity);
|
|
846
|
-
keys = keys.filter(k => !omitForCreateKeys.includes(k));
|
|
847
|
-
}
|
|
848
|
-
if (hideOmitForEdit) {
|
|
849
|
-
const omitForUpdateKeys = EntityUtilities.getOmitForUpdate(entity);
|
|
850
|
-
keys = keys.filter(k => !omitForUpdateKeys.includes(k));
|
|
851
|
-
}
|
|
852
|
-
return keys;
|
|
853
|
-
}
|
|
854
|
-
static getDontDisplayKeys(entity) {
|
|
855
|
-
const res = [];
|
|
856
|
-
for (const key of ReflectUtilities.ownKeys(entity)) {
|
|
857
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key);
|
|
858
|
-
if (!metadata.display(entity)) {
|
|
859
|
-
res.push(key);
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
return res;
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
/**
|
|
866
|
-
* The key for all keys of metadata that should be set to undefined when the entity gets reset.
|
|
867
|
-
*/
|
|
868
|
-
EntityUtilities.METADATA_KEYS_TO_RESET_KEY = 'metadataKeysToReset';
|
|
869
|
-
/**
|
|
870
|
-
* The key for the metadata that saves the single preview image value on image properties.
|
|
871
|
-
*/
|
|
872
|
-
EntityUtilities.SINGLE_PREVIEW_IMAGE_KEY = 'singlePreviewImage';
|
|
873
|
-
/**
|
|
874
|
-
* The key for the metadata that saves the multi preview images value on image properties.
|
|
875
|
-
*/
|
|
876
|
-
EntityUtilities.MULTI_PREVIEW_IMAGES_KEY = 'multiPreviewImages';
|
|
877
|
-
/**
|
|
878
|
-
* The key for the metadata that saves the filenames value on file properties.
|
|
879
|
-
*/
|
|
880
|
-
EntityUtilities.FILENAMES_KEY = 'fileNames';
|
|
881
|
-
/**
|
|
882
|
-
* The key for the metadata that saves the confirm password value on password properties.
|
|
883
|
-
*/
|
|
884
|
-
EntityUtilities.CONFIRM_PASSWORD_KEY = 'confirmPassword';
|
|
885
|
-
/**
|
|
886
|
-
* The key for the metadata that saves the time value on date time properties.
|
|
887
|
-
*/
|
|
888
|
-
EntityUtilities.TIME_KEY = 'time';
|
|
889
|
-
/**
|
|
890
|
-
* The key for the metadata that saves the date range value on date range properties.
|
|
891
|
-
*/
|
|
892
|
-
EntityUtilities.DATE_RANGE_KEY = 'dateRange';
|
|
893
|
-
/**
|
|
894
|
-
* The key for the metadata that saves the date range start value on date range properties.
|
|
895
|
-
*/
|
|
896
|
-
EntityUtilities.DATE_RANGE_START_KEY = 'dateRangeStart';
|
|
897
|
-
/**
|
|
898
|
-
* The key for the metadata that saves the date range end value on date range properties.
|
|
899
|
-
*/
|
|
900
|
-
EntityUtilities.DATE_RANGE_END_KEY = 'dateRangeEnd';
|
|
901
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc, @typescript-eslint/typedef
|
|
902
|
-
EntityUtilities.construct = EntityUtilities.new;
|
|
903
|
-
// eslint-disable-next-line @typescript-eslint/member-ordering, jsdoc/require-jsdoc, @typescript-eslint/typedef
|
|
904
|
-
EntityUtilities.build = EntityUtilities.new;
|
|
905
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LnV0aWxpdGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1tYXRlcmlhbC1lbnRpdHkvc3JjL3V0aWxpdGllcy9lbnRpdHkudXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE9BQU8sRUFBaUIsY0FBYyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFXeEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFvQmpEOztHQUVHO0FBQ0gsTUFBTSxPQUFnQixlQUFlO0lBK0NqQzs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBZ0QsTUFBa0I7UUFDckYsTUFBTSxHQUFHLEdBQXlCLEVBQUUsQ0FBQztRQUNyQyxLQUFLLE1BQU0sR0FBRyxJQUFJLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUNoRCxNQUFNLFFBQVEsR0FBb0MsZUFBZSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNuRyxJQUFJLFFBQVEsQ0FBQyxhQUFhLEVBQUU7Z0JBQ3hCLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDakI7U0FDSjtRQUNELE9BQU8sR0FBRyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFnRCxNQUFrQjtRQUNyRixNQUFNLEdBQUcsR0FBeUIsRUFBRSxDQUFDO1FBQ3JDLEtBQUssTUFBTSxHQUFHLElBQUksZ0JBQWdCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2hELE1B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aW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IERhdGVGaWx0ZXJGbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RhdGVwaWNrZXInO1xuaW1wb3J0IHsgQmFzZUVudGl0eVR5cGUgfSBmcm9tICcuLi9jbGFzc2VzL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBEYXRlUmFuZ2VBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsLCBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9hcnJheS9hcnJheS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBEZWNvcmF0b3JUeXBlLCBEZWNvcmF0b3JUeXBlcyB9IGZyb20gJy4uL2RlY29yYXRvcnMvYmFzZS9kZWNvcmF0b3ItdHlwZXMuZW51bSc7XG5pbXBvcnQgeyBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9iYXNlL3Byb3BlcnR5LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IFRvZ2dsZUJvb2xlYW5EZWNvcmF0b3JDb25maWdJbnRlcm5hbCB9IGZyb20gJy4uL2RlY29yYXRvcnMvYm9vbGVhbi9ib29sZWFuLWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IEN1c3RvbURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9jdXN0b20vY3VzdG9tLWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IERhdGVSYW5nZURhdGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCwgRGF0ZVRpbWVEYXRlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwsIERlZmF1bHREYXRlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi9kZWNvcmF0b3JzL2RhdGUvZGF0ZS1kZWNvcmF0b3ItaW50ZXJuYWwuZGF0YSc7XG5pbXBvcnQgeyBEYXRlUmFuZ2UgfSBmcm9tICcuLi9kZWNvcmF0b3JzL2RhdGUvZGF0ZS1kZWNvcmF0b3IuZGF0YSc7XG5pbXBvcnQgeyBEZWZhdWx0RmlsZURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9maWxlL2ZpbGUtZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgRmlsZURhdGEgfSBmcm9tICcuLi9kZWNvcmF0b3JzL2ZpbGUvZmlsZS1kZWNvcmF0b3IuZGF0YSc7XG5pbXBvcnQgeyBEZWZhdWx0TnVtYmVyRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgfSBmcm9tICcuLi9kZWNvcmF0b3JzL251bWJlci9udW1iZXItZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgRGVmYXVsdE9iamVjdERlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9vYmplY3Qvb2JqZWN0LWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IERlZmF1bHRTdHJpbmdEZWNvcmF0b3JDb25maWdJbnRlcm5hbCwgUGFzc3dvcmRTdHJpbmdEZWNvcmF0b3JDb25maWdJbnRlcm5hbCwgVGV4dGJveFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9zdHJpbmcvc3RyaW5nLWRlY29yYXRvci1pbnRlcm5hbC5kYXRhJztcbmltcG9ydCB7IExvZGFzaFV0aWxpdGllcyB9IGZyb20gJy4uL2VuY2Fwc3VsYXRpb24vbG9kYXNoLnV0aWxpdGllcyc7XG5pbXBvcnQgeyBSZWZsZWN0VXRpbGl0aWVzIH0gZnJvbSAnLi4vZW5jYXBzdWxhdGlvbi9yZWZsZWN0LnV0aWxpdGllcyc7XG5pbXBvcnQgeyBEYXRlVXRpbGl0aWVzIH0gZnJvbSAnLi9kYXRlLnV0aWxpdGllcyc7XG5pbXBvcnQgeyBGaWxlVXRpbGl0aWVzIH0gZnJvbSAnLi9maWxlLnV0aWxpdGllcyc7XG5cbi8qKlxuICogU2hvd3MgaW5mb3JtYXRpb24gYWJvdXQgZGlmZmVyZW5jZXMgYmV0d2VlbiB0d28gZW50aXRpZXMuXG4gKi9cbmludGVyZmFjZSBEaWZmZXJlbmNlPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4ge1xuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgd2hlcmUgdGhlIHR3byBlbnRpdGllcyBoYXZlIGRpZmZlcmVudCB2YWx1ZXMuXG4gICAgICovXG4gICAga2V5OiBrZXlvZiBFbnRpdHlUeXBlLFxuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSBiZWZvcmUgYW55IGNoYW5nZXMuXG4gICAgICovXG4gICAgYmVmb3JlOiB1bmtub3duLFxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHZhbHVlIGFmdGVyIGNoYW5nZXMuXG4gICAgICovXG4gICAgYWZ0ZXI6IHVua25vd25cbn1cblxuLyoqXG4gKiBDb250YWlucyBIZWxwZXJNZXRob2RzIGFyb3VuZCBoYW5kbGluZyBFbnRpdGllcyBhbmQgdGhlaXIgcHJvcGVydHktbWV0YWRhdGEuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFbnRpdHlVdGlsaXRpZXMge1xuXG4gICAgLyoqXG4gICAgICogVGhlIGtleSBmb3IgYWxsIGtleXMgb2YgbWV0YWRhdGEgdGhhdCBzaG91bGQgYmUgc2V0IHRvIHVuZGVmaW5lZCB3aGVuIHRoZSBlbnRpdHkgZ2V0cyByZXNldC5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgTUVUQURBVEFfS0VZU19UT19SRVNFVF9LRVk6IHN0cmluZyA9ICdtZXRhZGF0YUtleXNUb1Jlc2V0JztcblxuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgZm9yIHRoZSBtZXRhZGF0YSB0aGF0IHNhdmVzIHRoZSBzaW5nbGUgcHJldmlldyBpbWFnZSB2YWx1ZSBvbiBpbWFnZSBwcm9wZXJ0aWVzLlxuICAgICAqL1xuICAgIHN0YXRpYyByZWFkb25seSBTSU5HTEVfUFJFVklFV19JTUFHRV9LRVk6IHN0cmluZyA9ICdzaW5nbGVQcmV2aWV3SW1hZ2UnO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGtleSBmb3IgdGhlIG1ldGFkYXRhIHRoYXQgc2F2ZXMgdGhlIG11bHRpIHByZXZpZXcgaW1hZ2VzIHZhbHVlIG9uIGltYWdlIHByb3BlcnRpZXMuXG4gICAgICovXG4gICAgc3RhdGljIHJlYWRvbmx5IE1VTFRJX1BSRVZJRVdfSU1BR0VTX0tFWTogc3RyaW5nID0gJ211bHRpUHJldmlld0ltYWdlcyc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUga2V5IGZvciB0aGUgbWV0YWRhdGEgdGhhdCBzYXZlcyB0aGUgZmlsZW5hbWVzIHZhbHVlIG9uIGZpbGUgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgRklMRU5BTUVTX0tFWTogc3RyaW5nID0gJ2ZpbGVOYW1lcyc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUga2V5IGZvciB0aGUgbWV0YWRhdGEgdGhhdCBzYXZlcyB0aGUgY29uZmlybSBwYXNzd29yZCB2YWx1ZSBvbiBwYXNzd29yZCBwcm9wZXJ0aWVzLlxuICAgICAqL1xuICAgIHN0YXRpYyByZWFkb25seSBDT05GSVJNX1BBU1NXT1JEX0tFWTogc3RyaW5nID0gJ2NvbmZpcm1QYXNzd29yZCc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUga2V5IGZvciB0aGUgbWV0YWRhdGEgdGhhdCBzYXZlcyB0aGUgdGltZSB2YWx1ZSBvbiBkYXRlIHRpbWUgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgVElNRV9LRVk6IHN0cmluZyA9ICd0aW1lJztcblxuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgZm9yIHRoZSBtZXRhZGF0YSB0aGF0IHNhdmVzIHRoZSBkYXRlIHJhbmdlIHZhbHVlIG9uIGRhdGUgcmFuZ2UgcHJvcGVydGllcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgcmVhZG9ubHkgREFURV9SQU5HRV9LRVk6IHN0cmluZyA9ICdkYXRlUmFuZ2UnO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGtleSBmb3IgdGhlIG1ldGFkYXRhIHRoYXQgc2F2ZXMgdGhlIGRhdGUgcmFuZ2Ugc3RhcnQgdmFsdWUgb24gZGF0ZSByYW5nZSBwcm9wZXJ0aWVzLlxuICAgICAqL1xuICAgIHN0YXRpYyByZWFkb25seSBEQVRFX1JBTkdFX1NUQVJUX0tFWTogc3RyaW5nID0gJ2RhdGVSYW5nZVN0YXJ0JztcblxuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgZm9yIHRoZSBtZXRhZGF0YSB0aGF0IHNhdmVzIHRoZSBkYXRlIHJhbmdlIGVuZCB2YWx1ZSBvbiBkYXRlIHJhbmdlIHByb3BlcnRpZXMuXG4gICAgICovXG4gICAgc3RhdGljIHJlYWRvbmx5IERBVEVfUkFOR0VfRU5EX0tFWTogc3RyaW5nID0gJ2RhdGVSYW5nZUVuZCc7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBwcm9wZXJ0aWVzIHRvIG9taXQgd2hlbiB1cGRhdGluZyB0aGUgZW50aXR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgdG8gZ2V0IHRoZSBwcm9wZXJ0aWVzIHdoaWNoIHNob3VsZCBiZSBsZWZ0IG91dCBmb3IgdXBkYXRpbmcgZnJvbS5cbiAgICAgKiBAcmV0dXJucyBUaGUgcHJvcGVydGllcyB3aGljaCBzaG91bGQgYmUgbGVmdCBvdXQgZm9yIHVwZGF0aW5nIGFuIEVudGl0eS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0T21pdEZvclVwZGF0ZTxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KGVudGl0eTogRW50aXR5VHlwZSk6IChrZXlvZiBFbnRpdHlUeXBlKVtdIHtcbiAgICAgICAgY29uc3QgcmVzOiAoa2V5b2YgRW50aXR5VHlwZSlbXSA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBSZWZsZWN0VXRpbGl0aWVzLm93bktleXMoZW50aXR5KSkge1xuICAgICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGtleSk7XG4gICAgICAgICAgICBpZiAobWV0YWRhdGEub21pdEZvclVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHJlcy5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBwcm9wZXJ0aWVzIHRvIG9taXQgd2hlbiBjcmVhdGluZyBuZXcgZW50aXRpZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byBnZXQgdGhlIHByb3BlcnRpZXMgd2hpY2ggc2hvdWxkIGJlIGxlZnQgb3V0IGZvciBjcmVhdGluZyBmcm9tLlxuICAgICAqIEByZXR1cm5zIFRoZSBwcm9wZXJ0aWVzIHdoaWNoIHNob3VsZCBiZSBsZWZ0IG91dCBmb3IgY3JlYXRpbmcgYSBuZXcgRW50aXR5LlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRPbWl0Rm9yQ3JlYXRlPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oZW50aXR5OiBFbnRpdHlUeXBlKTogKGtleW9mIEVudGl0eVR5cGUpW10ge1xuICAgICAgICBjb25zdCByZXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFJlZmxlY3RVdGlsaXRpZXMub3duS2V5cyhlbnRpdHkpKSB7XG4gICAgICAgICAgICBjb25zdCBtZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eU1ldGFkYXRhKGVudGl0eSwga2V5KTtcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YS5vbWl0Rm9yQ3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgcmVzLnB1c2goa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGdpdmVuIGVudGl0eSB3aXRob3V0IHRoZSB2YWx1ZXMgdGhhdCBzaG91bGQgYmUgb21pdHRlZCBmb3IgY3JlYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB3aXRoIGFsbCBpdHMgdmFsdWVzLlxuICAgICAqIEByZXR1cm5zIFRoZSByZWR1Y2VkIGVudGl0eSBvYmplY3QuXG4gICAgICovXG4gICAgc3RhdGljIGdldFdpdGhvdXRPbWl0Q3JlYXRlVmFsdWVzPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oZW50aXR5OiBFbnRpdHlUeXBlKTogUGFydGlhbDxFbnRpdHlUeXBlPiB7XG4gICAgICAgIHJldHVybiBMb2Rhc2hVdGlsaXRpZXMub21pdChlbnRpdHksIEVudGl0eVV0aWxpdGllcy5nZXRPbWl0Rm9yQ3JlYXRlKGVudGl0eSkpIGFzIFBhcnRpYWw8RW50aXR5VHlwZT47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZ2l2ZW4gZW50aXR5IHdpdGhvdXQgdGhlIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBvbWl0dGVkIGZvciB1cGRhdGluZy5cbiAgICAgKiBUaGlzIGFsc28gaGFuZGxlcyBvbWl0dGluZyBrZXlzIGZvciBAb2JqZWN0IG9yIEBhcnJheSB2YWx1ZXMgYW5kIHJlbW92ZXMgdmFsdWVzIHRoYXQgaGF2ZW4ndCBiZWVuIGNoYW5nZWQgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHdpdGggYWxsIGl0cyB2YWx1ZXMuXG4gICAgICogQHBhcmFtIGVudGl0eVByaW9yQ2hhbmdlcyAtIFRoZSBlbnRpdHkgYmVmb3JlIGFueSBjaGFuZ2VzIHdlcmUgYXBwbGllZC5cbiAgICAgKiBAcGFyYW0gaHR0cCAtIFRoZSBhbmd1bGFyIEh0dHBDbGllbnQuIFVzZWQgdG8gZmV0Y2ggZmlsZXMuXG4gICAgICogQHJldHVybnMgVGhlIHJlZHVjZWQgZW50aXR5IG9iamVjdC5cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZ2V0V2l0aG91dE9taXRVcGRhdGVWYWx1ZXM8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICBlbnRpdHlQcmlvckNoYW5nZXM6IEVudGl0eVR5cGUsXG4gICAgICAgIGh0dHA6IEh0dHBDbGllbnRcbiAgICApOiBQcm9taXNlPFBhcnRpYWw8RW50aXR5VHlwZT4+IHtcbiAgICAgICAgY29uc3QgcmVzOiBQYXJ0aWFsPEVudGl0eVR5cGU+ID0ge307XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIEVudGl0eVV0aWxpdGllcy5rZXlzT2YoZW50aXR5LCBmYWxzZSwgdHJ1ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBrZXkpO1xuICAgICAgICAgICAgY29uc3QgdHlwZTogRGVjb3JhdG9yVHlwZXMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlUeXBlKGVudGl0eSwga2V5KTtcbiAgICAgICAgICAgIGlmICghKGF3YWl0IEVudGl0eVV0aWxpdGllcy5pc0VxdWFsKGVudGl0eVtrZXldLCBlbnRpdHlQcmlvckNoYW5nZXNba2V5XSwgbWV0YWRhdGEsIHR5cGUsIGh0dHApKSkge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLk9CSkVDVDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgICAgICAgICAgICAocmVzW2tleV0gYXMgb2JqZWN0KSA9IExvZGFzaFV0aWxpdGllcy5vbWl0KGVudGl0eVtrZXldIGFzIGFueSwgRW50aXR5VXRpbGl0aWVzLmdldE9taXRGb3JDcmVhdGUoZW50aXR5W2tleV0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkFSUkFZOlxuICAgICAgICAgICAgICAgICAgICAgICAgKHJlc1trZXldIGFzIG9iamVjdFtdKSA9IChlbnRpdHlba2V5XSBhcyBvYmplY3RbXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKHZhbHVlID0+IExvZGFzaFV0aWxpdGllcy5vbWl0KHZhbHVlLCBFbnRpdHlVdGlsaXRpZXMuZ2V0T21pdEZvckNyZWF0ZSh2YWx1ZSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzW2tleV0gPSBlbnRpdHlba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYWxsIHByb3BlcnRpZXMgb24gdGhlIGdpdmVuIGVudGl0eSB3aGljaCBhcmUgZmlsZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byBjaGVjayBmb3IgZmlsZSBwcm9wZXJ0aWVzLlxuICAgICAqIEBwYXJhbSBvbWl0IC0gV2hldGhlciB0byBsZWF2ZSBvdXQgdmFsdWVzIHRoYXQgYXJlIG9taXR0ZWQgZm9yIGNyZWF0ZSBvciBkZWxldGUuXG4gICAgICogQHJldHVybnMgVGhlIGtleXMgb2YgYWxsIGZpbGUgcHJvcGVydGllcyBvbiB0aGUgZ2l2ZW4gZW50aXR5LlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRGaWxlUHJvcGVydGllczxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KFxuICAgICAgICBlbnRpdHk6IEVudGl0eVR5cGUsXG4gICAgICAgIG9taXQ/OiAnY3JlYXRlJyB8ICd1cGRhdGUnXG4gICAgKTogKGtleW9mIEVudGl0eVR5cGUpW10ge1xuICAgICAgICBjb25zdCByZXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFJlZmxlY3RVdGlsaXRpZXMub3duS2V5cyhlbnRpdHkpKSB7XG4gICAgICAgICAgICBjb25zdCB0eXBlOiBEZWNvcmF0b3JUeXBlcyA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eVR5cGUoZW50aXR5LCBrZXkpO1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09IERlY29yYXRvclR5cGVzLkZJTEVfREVGQVVMVCB8fCB0eXBlID09PSBEZWNvcmF0b3JUeXBlcy5GSUxFX0lNQUdFKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCEobWV0YWRhdGEub21pdEZvckNyZWF0ZSAmJiBvbWl0ID09PSAnY3JlYXRlJykgJiYgIShtZXRhZGF0YS5vbWl0Rm9yVXBkYXRlICYmIG9taXQgPT09ICd1cGRhdGUnKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIG1ldGFkYXRhIGluY2x1ZGVkIGluIGFuIHByb3BlcnR5LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgd2l0aCB0aGUgcHJvcGVydHkgdG8gZ2V0IHRoZSBtZXRhZGF0YSBmcm9tLlxuICAgICAqIEBwYXJhbSBwcm9wZXJ0eUtleSAtIFRoZSBwcm9wZXJ0eSBvbiB0aGUgZ2l2ZW4gRW50aXR5IHRvIGdldCB0aGUgbWV0YWRhdGEgZnJvbS5cbiAgICAgKiBAcGFyYW0gdHlwZSAtIEZvciBzZWN1cmUgVHlwaW5nLCBkZWZpbmVzIHRoZSByZXR1cm5lZCBQcm9wZXJ0eUNvbmZpZy5cbiAgICAgKiBAcmV0dXJucyBUaGUgbWV0YWRhdGEgb2YgdGhlIHByb3BlcnR5LlxuICAgICAqIEB0aHJvd3MgV2hlbiBubyBtZXRhZGF0YSBjYW4gYmUgZm91bmQgZm9yIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UHJvcGVydHlNZXRhZGF0YTxcbiAgICAgICAgRW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+LFxuICAgICAgICBUIGV4dGVuZHMgRGVjb3JhdG9yVHlwZXMsXG4gICAgICAgIEN1c3RvbU1ldGFkYXRhVHlwZSBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gICAgPihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICBwcm9wZXJ0eUtleToga2V5b2YgRW50aXR5VHlwZSxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgICB0eXBlPzogVFxuICAgICk6IERlY29yYXRvclR5cGU8VCwgQ3VzdG9tTWV0YWRhdGFUeXBlPiB7XG4gICAgICAgIGNvbnN0IG1ldGFkYXRhOiB1bmtub3duID0gUmVmbGVjdFV0aWxpdGllcy5nZXRNZXRhZGF0YSgnbWV0YWRhdGEnLCBlbnRpdHksIHByb3BlcnR5S2V5KTtcbiAgICAgICAgaWYgKG1ldGFkYXRhID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ291bGQgbm90IGZpbmQgbWV0YWRhdGEgZm9yIHByb3BlcnR5ICR7U3RyaW5nKHByb3BlcnR5S2V5KX0gb24gdGhlIGVudGl0eSAke0pTT04uc3RyaW5naWZ5KGVudGl0eSl9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWV0YWRhdGEgYXMgRGVjb3JhdG9yVHlwZTxULCBDdXN0b21NZXRhZGF0YVR5cGU+O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHR5cGUgb2YgdGhlIHByb3BlcnR5LW1ldGFkYXRhLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgd2l0aCB0aGUgcHJvcGVydHkgdG8gZ2V0IHRoZSB0eXBlIGZyb20uXG4gICAgICogQHBhcmFtIHByb3BlcnR5S2V5IC0gVGhlIHByb3BlcnR5IG9uIHRoZSBnaXZlbiBFbnRpdHkgdG8gZ2V0IHRoZSB0eXBlIGZyb20uXG4gICAgICogQHJldHVybnMgVGhlIHR5cGUgb2YgdGhlIG1ldGFkYXRhLlxuICAgICAqIEB0aHJvd3MgV2lsbCB0aHJvdyBhbiBlcnJvciBpZiBubyBtZXRhZGF0YSBjYW4gYmUgZm91bmQgZm9yIHRoZSBnaXZlbiBwcm9wZXJ0eS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0UHJvcGVydHlUeXBlPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSwgcHJvcGVydHlLZXk6IGtleW9mIEVudGl0eVR5cGVcbiAgICApOiBEZWNvcmF0b3JUeXBlcyB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0eVR5cGU6IHVua25vd24gPSBSZWZsZWN0VXRpbGl0aWVzLmdldE1ldGFkYXRhKCd0eXBlJywgZW50aXR5LCBwcm9wZXJ0eUtleSk7XG4gICAgICAgICAgICBpZiAocHJvcGVydHlUeXBlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBDb3VsZCBub3QgZmluZCB0eXBlIG1ldGFkYXRhIGZvciBwcm9wZXJ0eSAke1N0cmluZyhwcm9wZXJ0eUtleSl9IG9uIHRoZSBlbnRpdHkgJHtKU09OLnN0cmluZ2lmeShlbnRpdHkpfWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5VHlwZSBhcyBEZWNvcmF0b3JUeXBlcztcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ291bGQgbm90IGZpbmQgdHlwZSBtZXRhZGF0YSBmb3IgcHJvcGVydHkgJHtTdHJpbmcocHJvcGVydHlLZXkpfSBvbiB0aGUgZW50aXR5ICR7SlNPTi5zdHJpbmdpZnkoZW50aXR5KX1gXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBhbGwgcHJvcGVydHkgdmFsdWVzIGJhc2VkIG9uIGEgZ2l2ZW4gZW50aXR5IGRhdGEtb2JqZWN0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IHRoYXQgbmVlZHMgdG8gYmUgY29uc3RydWN0ZWQgKGlmIGNhbGxlZCBpbnNpZGUgYW4gRW50aXR5IGNvbnN0cnVjdG9yIGl0cyB1c3VhbGx5IHRoaXMpLlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZGF0YSBvYmplY3QgdG8gZ2V0IHRoZSBwcm9wZXJ0eSB2YWx1ZXMgZnJvbS5cbiAgICAgKiBAYWxpYXMgbmV3XG4gICAgICogQGFsaWFzIGJ1aWxkXG4gICAgICogQGFsaWFzIGNvbnN0cnVjdFxuICAgICAqL1xuICAgIHN0YXRpYyBuZXc8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+Pih0YXJnZXQ6IEVudGl0eVR5cGUsIGVudGl0eT86IEVudGl0eVR5cGUpOiB2b2lkIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGFyZ2V0KSB7XG4gICAgICAgICAgICBjb25zdCB0eXBlOiBEZWNvcmF0b3JUeXBlcyA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eVR5cGUodGFyZ2V0LCBrZXkpO1xuICAgICAgICAgICAgbGV0IHZhbHVlOiB1bmtub3duID0gZW50aXR5ID8gUmVmbGVjdFV0aWxpdGllcy5nZXQoZW50aXR5LCBrZXkpIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5PQkpFQ1Q6XG4gICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9iamVjdE1ldGFkYXRhOiBEZWZhdWx0T2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8YW55PlxuICAgICAgICAgICAgICAgICAgICAgICAgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YSh0YXJnZXQsIGtleSwgRGVjb3JhdG9yVHlwZXMuT0JKRUNUKTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgb2JqZWN0TWV0YWRhdGEuRW50aXR5Q2xhc3ModmFsdWUgYXMgb2JqZWN0IHwgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWTpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5wdXRBcnJheTogRW50aXR5VHlwZVtdIHwgdW5kZWZpbmVkID0gdmFsdWUgYXMgRW50aXR5VHlwZVtdIHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNBcnJheTogRW50aXR5VHlwZVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dEFycmF5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJyYXlNZXRhZGF0YTogRW50aXR5QXJyYXlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxhbnk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YSh0YXJnZXQsIGtleSwgRGVjb3JhdG9yVHlwZXMuQVJSQVkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGlucHV0QXJyYXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtV2l0aE1ldGFkYXRhOiBFbnRpdHlUeXBlID0gbmV3IGFycmF5TWV0YWRhdGEuRW50aXR5Q2xhc3MoaXRlbSkgYXMgRW50aXR5VHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNBcnJheS5wdXNoKGl0ZW1XaXRoTWV0YWRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gcmVzQXJyYXk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgUmVmbGVjdFV0aWxpdGllcy5zZXQodGFyZ2V0LCBrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L21lbWJlci1vcmRlcmluZywganNkb2MvcmVxdWlyZS1qc2RvYywgQHR5cGVzY3JpcHQtZXNsaW50L3R5cGVkZWZcbiAgICBzdGF0aWMgY29uc3RydWN0ID0gRW50aXR5VXRpbGl0aWVzLm5ldztcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L21lbWJlci1vcmRlcmluZywganNkb2MvcmVxdWlyZS1qc2RvYywgQHR5cGVzY3JpcHQtZXNsaW50L3R5cGVkZWZcbiAgICBzdGF0aWMgYnVpbGQgPSBFbnRpdHlVdGlsaXRpZXMubmV3O1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSB2YWx1ZXMgb24gYW4gZW50aXR5IGFyZSB2YWxpZC5cbiAgICAgKiBBbHNvIGNoZWNrcyBhbGwgdGhlIHZhbGlkYXRvcnMgZ2l2ZW4gYnkgdGhlIG1ldGFkYXRhIChcInJlcXVpcmVkXCIsIFwibWF4TGVuZ3RoXCIgZXRjLikuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byB2YWxpZGF0ZS5cbiAgICAgKiBAcGFyYW0gb21pdCAtIFdoZXRoZXIgdG8gY2hlY2sgZm9yIGNyZWF0aW5nIG9yIGVkaXRpbmcgdmFsaWRpdHkuXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgdGhlIGVudGl0eSBpcyB2YWxpZC5cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNFbnRpdHlWYWxpZDxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KGVudGl0eTogRW50aXR5VHlwZSwgb21pdDogJ2NyZWF0ZScgfCAndXBkYXRlJyk6IGJvb2xlYW4ge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBlbnRpdHkpIHtcbiAgICAgICAgICAgIGlmICghRW50aXR5VXRpbGl0aWVzLmlzUHJvcGVydHlWYWxpZChlbnRpdHksIGtleSwgb21pdCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIHNpbmdsZSBwcm9wZXJ0eSB2YWx1ZSBpcyB2YWxpZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHdoZXJlIHRoZSBwcm9wZXJ0eSBpcyBmcm9tLlxuICAgICAqIEBwYXJhbSBrZXkgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkuXG4gICAgICogQHBhcmFtIG9taXQgLSBXaGV0aGVyIHRvIGNoZWNrIGlmIHRoZSBnaXZlbiBlbnRpdHkgaXMgdmFsaWQgZm9yIGNyZWF0aW9uIG9yIHVwZGF0aW5nLlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IHRoZSBwcm9wZXJ0eSB2YWx1ZSBpcyB2YWxpZC5cbiAgICAgKiBAdGhyb3dzIFRocm93cyB3aGVuIGl0IGV4dHJhY3RzIGFuIHVua25vd24gbWV0YWRhdGEgdHlwZS5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyBpc1Byb3BlcnR5VmFsaWQ8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICBrZXk6IGtleW9mIEVudGl0eVR5cGUsXG4gICAgICAgIG9taXQ6ICdjcmVhdGUnIHwgJ3VwZGF0ZSdcbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdHlwZTogRGVjb3JhdG9yVHlwZXMgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlUeXBlKGVudGl0eSwga2V5KTtcbiAgICAgICAgY29uc3QgbWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGtleSwgdHlwZSk7XG5cbiAgICAgICAgaWYgKG1ldGFkYXRhLm9taXRGb3JDcmVhdGUgJiYgb21pdCA9PT0gJ2NyZWF0ZScpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5vbWl0Rm9yVXBkYXRlICYmIG9taXQgPT09ICd1cGRhdGUnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KSAmJiB0eXBlICE9PSBEZWNvcmF0b3JUeXBlcy5IQVNfTUFOWSkge1xuICAgICAgICAgICAgaWYgKGVudGl0eVtrZXldID09IG51bGwgfHwgZW50aXR5W2tleV0gPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KSkge1xuICAgICAgICAgICAgaWYgKGVudGl0eVtrZXldID09IG51bGwgfHwgZW50aXR5W2tleV0gPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkJPT0xFQU5fRFJPUERPV046XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkJPT0xFQU5fQ0hFQ0tCT1g6XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkJPT0xFQU5fVE9HR0xFOlxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eUJvb2xlYW46IGJvb2xlYW4gPSBlbnRpdHlba2V5XSBhcyBib29sZWFuO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJvb2xlYW5NZXRhZGF0YTogVG9nZ2xlQm9vbGVhbkRlY29yYXRvckNvbmZpZ0ludGVybmFsID0gbWV0YWRhdGEgYXMgVG9nZ2xlQm9vbGVhbkRlY29yYXRvckNvbmZpZ0ludGVybmFsO1xuICAgICAgICAgICAgICAgIGlmICghRW50aXR5VXRpbGl0aWVzLmlzQm9vbGVhblZhbGlkKGVudGl0eSwgZW50aXR5Qm9vbGVhbiwgYm9vbGVhbk1ldGFkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5TVFJJTkdfRFJPUERPV046XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLlNUUklORzpcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuU1RSSU5HX0FVVE9DT01QTEVURTpcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHlTdHJpbmc6IHN0cmluZyA9IGVudGl0eVtrZXldIGFzIHN0cmluZztcbiAgICAgICAgICAgICAgICBjb25zdCBzdHJpbmdNZXRhZGF0YTogRGVmYXVsdFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsID0gbWV0YWRhdGEgYXMgRGVmYXVsdFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsO1xuICAgICAgICAgICAgICAgIGlmICghRW50aXR5VXRpbGl0aWVzLmlzU3RyaW5nVmFsaWQoZW50aXR5U3RyaW5nLCBzdHJpbmdNZXRhZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuU1RSSU5HX1RFWFRCT1g6XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5VGV4dGJveDogc3RyaW5nID0gZW50aXR5W2tleV0gYXMgc3RyaW5nO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHRib3hNZXRhZGF0YTogVGV4dGJveFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsID0gbWV0YWRhdGEgYXMgVGV4dGJveFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsO1xuICAgICAgICAgICAgICAgIGlmICghRW50aXR5VXRpbGl0aWVzLmlzVGV4dGJveFZhbGlkKGVudGl0eVRleHRib3gsIHRleHRib3hNZXRhZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuU1RSSU5HX1BBU1NXT1JEOlxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eVBhc3N3b3JkOiBzdHJpbmcgPSBlbnRpdHlba2V5XSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFzc3dvcmRNZXRhZGF0YTogUGFzc3dvcmRTdHJpbmdEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IG1ldGFkYXRhIGFzIFBhc3N3b3JkU3RyaW5nRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uZmlybVBhc3N3b3JkOiBzdHJpbmcgPSBSZWZsZWN0VXRpbGl0aWVzLmdldE1ldGFkYXRhKHRoaXMuQ09ORklSTV9QQVNTV09SRF9LRVksIGVudGl0eSwga2V5KSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgICAgaWYgKCFFbnRpdHlVdGlsaXRpZXMuaXNQYXNzd29yZFZhbGlkKGVudGl0eVBhc3N3b3JkLCBwYXNzd29yZE1ldGFkYXRhLCBjb25maXJtUGFzc3dvcmQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLk5VTUJFUl9EUk9QRE9XTjpcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuTlVNQkVSOlxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5OVU1CRVJfU0xJREVSOlxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eU51bWJlcjogbnVtYmVyID0gZW50aXR5W2tleV0gYXMgbnVtYmVyO1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck1ldGFkYXRhOiBEZWZhdWx0TnVtYmVyRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBtZXRhZGF0YSBhcyBEZWZhdWx0TnVtYmVyRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw7XG4gICAgICAgICAgICAgICAgaWYgKCFFbnRpdHlVdGlsaXRpZXMuaXNOdW1iZXJWYWxpZChlbnRpdHlOdW1iZXIsIG51bWJlck1ldGFkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5PQkpFQ1Q6XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5T2JqZWN0OiBFbnRpdHlUeXBlID0gZW50aXR5W2tleV0gYXMgRW50aXR5VHlwZTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHBhcmFtZXRlcktleSBpbiBlbnRpdHlPYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWU6IHVua25vd24gPSBlbnRpdHlPYmplY3RbcGFyYW1ldGVyS2V5XTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgIShtZXRhZGF0YSBhcyBEZWZhdWx0T2JqZWN0RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8RW50aXR5VHlwZT4pLm9taXQuaW5jbHVkZXMocGFyYW1ldGVyS2V5KVxuICAgICAgICAgICAgICAgICAgICAgICAgJiYgISghbWV0YWRhdGEucmVxdWlyZWQoZW50aXR5KSAmJiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSA9PSAnJykpXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFFbnRpdHlVdGlsaXRpZXMuaXNQcm9wZXJ0eVZhbGlkKGVudGl0eU9iamVjdCwgcGFyYW1ldGVyS2V5LCBvbWl0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuQVJSQVlfU1RSSU5HX0NISVBTOlxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWV9TVFJJTkdfQVVUT0NPTVBMRVRFX0NISVBTOlxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFOlxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFX1RJTUU6XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkFSUkFZX0RBVEVfUkFOR0U6XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkFSUkFZOlxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eUFycmF5OiB1bmtub3duW10gPSBlbnRpdHlba2V5XSBhcyB1bmtub3duW107XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheU1ldGFkYXRhOiBFbnRpdHlBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGU+ID0gbWV0YWRhdGEgYXMgRW50aXR5QXJyYXlEZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlPjtcbiAgICAgICAgICAgICAgICBpZiAoYXJyYXlNZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpICYmICFlbnRpdHlBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuREFURTpcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHlEYXRlOiBEYXRlID0gbmV3IERhdGUoZW50aXR5W2tleV0gYXMgRGF0ZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZU1ldGFkYXRhOiBEZWZhdWx0RGF0ZURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gbWV0YWRhdGEgYXMgRGVmYXVsdERhdGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbDtcbiAgICAgICAgICAgICAgICBpZiAoIUVudGl0eVV0aWxpdGllcy5pc0RhdGVWYWxpZChlbnRpdHlEYXRlLCBkYXRlTWV0YWRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkRBVEVfUkFOR0U6XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5RGF0ZVJhbmdlOiBEYXRlUmFuZ2UgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGVudGl0eVtrZXldIGFzIERhdGVSYW5nZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVJhbmdlTWV0YWRhdGE6IERhdGVSYW5nZURhdGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IG1ldGFkYXRhIGFzIERhdGVSYW5nZURhdGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbDtcbiAgICAgICAgICAgICAgICBpZiAoIUVudGl0eVV0aWxpdGllcy5pc0RhdGVSYW5nZVZhbGlkKGVudGl0eSwgZW50aXR5RGF0ZVJhbmdlLCBkYXRlUmFuZ2VNZXRhZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuREFURV9USU1FOlxuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eURhdGVUaW1lOiBEYXRlID0gbmV3IERhdGUoZW50aXR5W2tleV0gYXMgRGF0ZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGF0ZVRpbWVNZXRhZGF0YTogRGF0ZVRpbWVEYXRlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBtZXRhZGF0YSBhcyBEYXRlVGltZURhdGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbDtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXNUaW1lOiBib29sZWFuID0gUmVmbGVjdFV0aWxpdGllcy5oYXNNZXRhZGF0YSh0aGlzLlRJTUVfS0VZLCBlbnRpdHksIGtleSk7XG4gICAgICAgICAgICAgICAgaWYgKCFFbnRpdHlVdGlsaXRpZXMuaXNEYXRlVGltZVZhbGlkKGVudGl0eURhdGVUaW1lLCBkYXRlVGltZU1ldGFkYXRhLCBoYXNUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5GSUxFX0RFRkFVTFQ6XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkZJTEVfSU1BR0U6XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5RmlsZTogRmlsZURhdGEgfCBGaWxlRGF0YVtdID0gZW50aXR5W2tleV0gYXMgRmlsZURhdGEgfCBGaWxlRGF0YVtdO1xuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eUZpbGVNZXRhZGF0YTogRGVmYXVsdEZpbGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IG1ldGFkYXRhIGFzIERlZmF1bHRGaWxlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw7XG4gICAgICAgICAgICAgICAgaWYgKCFFbnRpdHlVdGlsaXRpZXMuaXNGaWxlRGF0YVZhbGlkKGVudGl0eUZpbGUsIGVudGl0eUZpbGVNZXRhZGF0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuUkVGRVJFTkNFU19NQU5ZOlxuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5SRUZFUkVOQ0VTX09ORTpcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuSEFTX01BTlk6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkNVU1RPTTpcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSwgbWF4LWxlblxuICAgICAgICAgICAgICAgIGNvbnN0IGN1c3RvbU1ldGFkYXRhOiBDdXN0b21EZWNvcmF0b3JDb25maWdJbnRlcm5hbDxFbnRpdHlUeXBlLCBhbnksIGFueSwgYW55PiA9IG1ldGFkYXRhIGFzIEN1c3RvbURlY29yYXRvckNvbmZpZ0ludGVybmFsPEVudGl0eVR5cGUsIGFueSwgYW55LCBhbnk+O1xuICAgICAgICAgICAgICAgIGlmICghY3VzdG9tTWV0YWRhdGEuaXNWYWxpZChlbnRpdHlba2V5XSwgb21pdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgdmFsaWRhdGUgdGhlIGlucHV0IGJlY2F1c2UgdGhlIERlY29yYXRvclR5cGUgJHt0eXBlfSBpcyBub3Qga25vd25gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBpc0Jvb2xlYW5WYWxpZDxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KFxuICAgICAgICBlbnRpdHk6IEVudGl0eVR5cGUsXG4gICAgICAgIHZhbHVlOiBib29sZWFuLFxuICAgICAgICBtZXRhZGF0YTogVG9nZ2xlQm9vbGVhbkRlY29yYXRvckNvbmZpZ0ludGVybmFsXG4gICAgKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpICYmICF2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzU3RyaW5nVmFsaWQodmFsdWU6IHN0cmluZywgbWV0YWRhdGE6IERlZmF1bHRTdHJpbmdEZWNvcmF0b3JDb25maWdJbnRlcm5hbCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAobWV0YWRhdGEubWF4TGVuZ3RoICYmIHZhbHVlLmxlbmd0aCA+IG1ldGFkYXRhLm1heExlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5taW5MZW5ndGggJiYgdmFsdWUubGVuZ3RoIDwgbWV0YWRhdGEubWluTGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGFkYXRhLnJlZ2V4ICYmICF2YWx1ZS5tYXRjaChtZXRhZGF0YS5yZWdleCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBpc1RleHRib3hWYWxpZCh2YWx1ZTogc3RyaW5nLCBtZXRhZGF0YTogVGV4dGJveFN0cmluZ0RlY29yYXRvckNvbmZpZ0ludGVybmFsKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChtZXRhZGF0YS5tYXhMZW5ndGggJiYgdmFsdWUubGVuZ3RoID4gbWV0YWRhdGEubWF4TGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGFkYXRhLm1pbkxlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPCBtZXRhZGF0YS5taW5MZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBpc1Bhc3N3b3JkVmFsaWQodmFsdWU6IHN0cmluZywgbWV0YWRhdGE6IFBhc3N3b3JkU3RyaW5nRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwsIGNvbmZpcm1QYXNzd29yZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gY29uZmlybVBhc3N3b3JkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGFkYXRhLm1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiBtZXRhZGF0YS5tYXhMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEubWluTGVuZ3RoICYmIHZhbHVlLmxlbmd0aCA8IG1ldGFkYXRhLm1pbkxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5yZWdleCAmJiAhdmFsdWUubWF0Y2gobWV0YWRhdGEucmVnZXgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNOdW1iZXJWYWxpZCh2YWx1ZTogbnVtYmVyLCBtZXRhZGF0YTogRGVmYXVsdE51bWJlckRlY29yYXRvckNvbmZpZ0ludGVybmFsKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChtZXRhZGF0YS5tYXggJiYgdmFsdWUgPiBtZXRhZGF0YS5tYXgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEubWluICYmIHZhbHVlIDwgbWV0YWRhdGEubWluKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNEYXRlVmFsaWQodmFsdWU6IERhdGUsIG1ldGFkYXRhOiBEZWZhdWx0RGF0ZURlY29yYXRvckNvbmZpZ0ludGVybmFsKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChtZXRhZGF0YS5taW4gJiYgdmFsdWUuZ2V0VGltZSgpIDwgbWV0YWRhdGEubWluKHZhbHVlKS5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEubWF4ICYmIHZhbHVlLmdldFRpbWUoKSA+IG1ldGFkYXRhLm1heCh2YWx1ZSkuZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGFkYXRhLmZpbHRlciAmJiAhbWV0YWRhdGEuZmlsdGVyKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRGF0ZVJhbmdlVmFsaWQ8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICB2YWx1ZTogRGF0ZVJhbmdlLFxuICAgICAgICBtZXRhZGF0YTogRGF0ZVJhbmdlRGF0ZURlY29yYXRvckNvbmZpZ0ludGVybmFsXG4gICAgKTogYm9vbGVhbiB7XG4gICAgICAgIGlmIChtZXRhZGF0YS5yZXF1aXJlZChlbnRpdHkpKSB7XG4gICAgICAgICAgICBpZiAoISh2YWx1ZS5zdGFydCBhcyBEYXRlIHwgdW5kZWZpbmVkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghKHZhbHVlLmVuZCBhcyBEYXRlIHwgdW5kZWZpbmVkKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YWx1ZS5zdGFydCA9IG5ldyBEYXRlKHZhbHVlLnN0YXJ0KTtcbiAgICAgICAgdmFsdWUuZW5kID0gbmV3IERhdGUodmFsdWUuZW5kKTtcbiAgICAgICAgaWYgKG1ldGFkYXRhLm1pblN0YXJ0ICYmIHZhbHVlLnN0YXJ0LmdldFRpbWUoKSA8IG1ldGFkYXRhLm1pblN0YXJ0KHZhbHVlLnN0YXJ0KS5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEubWF4U3RhcnQgJiYgdmFsdWUuc3RhcnQuZ2V0VGltZSgpID4gbWV0YWRhdGEubWF4U3RhcnQodmFsdWUuc3RhcnQpLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5taW5FbmQgJiYgdmFsdWUuZW5kLmdldFRpbWUoKSA8IG1ldGFkYXRhLm1pbkVuZCh2YWx1ZS5lbmQpLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5tYXhFbmQgJiYgdmFsdWUuZW5kLmdldFRpbWUoKSA+IG1ldGFkYXRhLm1heEVuZCh2YWx1ZS5lbmQpLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5maWx0ZXIpIHtcbiAgICAgICAgICAgIGlmICghbWV0YWRhdGEuZmlsdGVyKHZhbHVlLnN0YXJ0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbWV0YWRhdGEuZmlsdGVyKHZhbHVlLmVuZCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUudmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBkYXRlIG9mIHZhbHVlLnZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW1ldGFkYXRhLmZpbHRlcihkYXRlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRGF0ZVRpbWVWYWxpZCh2YWx1ZTogRGF0ZSwgbWV0YWRhdGE6IERhdGVUaW1lRGF0ZURlY29yYXRvckNvbmZpZ0ludGVybmFsLCBoYXNUaW1lOiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghaGFzVGltZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5taW5EYXRlICYmIHZhbHVlLmdldFRpbWUoKSA8IG1ldGFkYXRhLm1pbkRhdGUodmFsdWUpLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5tYXhEYXRlICYmIHZhbHVlLmdldFRpbWUoKSA+IG1ldGFkYXRhLm1heERhdGUodmFsdWUpLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhZGF0YS5maWx0ZXJEYXRlICYmICFtZXRhZGF0YS5maWx0ZXJEYXRlKHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRpbWU6IFRpbWUgPSB7XG4gICAgICAgICAgICBob3VyczogdmFsdWUuZ2V0SG91cnMoKSxcbiAgICAgICAgICAgIG1pbnV0ZXM6IHZhbHVlLmdldE1pbnV0ZXMoKVxuICAgICAgICB9O1xuICAgICAgICBpZiAobWV0YWRhdGEubWluVGltZSkge1xuICAgICAgICAgICAgY29uc3QgbWluVGltZTogVGltZSA9IG1ldGFkYXRhLm1pblRpbWUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgICAgIHRpbWUuaG91cnMgPiBtaW5UaW1lLmhvdXJzXG4gICAgICAgICAgICAgICAgICAgIHx8IChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWUuaG91cnMgPT09IG1pblRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIHRpbWUubWludXRlcyA+PSBtaW5UaW1lLm1pbnV0ZXNcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEubWF4VGltZSkge1xuICAgICAgICAgICAgY29uc3QgbWF4VGltZTogVGltZSA9IG1ldGFkYXRhLm1heFRpbWUodmFsdWUpO1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgICAgIHRpbWUuaG91cnMgPCBtYXhUaW1lLmhvdXJzXG4gICAgICAgICAgICAgICAgICAgIHx8IChcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWUuaG91cnMgPT09IG1heFRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIHRpbWUubWludXRlcyA8PSBtYXhUaW1lLm1pbnV0ZXNcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobWV0YWRhdGEuZmlsdGVyVGltZSkge1xuICAgICAgICAgICAgaWYgKCFtZXRhZGF0YS5maWx0ZXJUaW1lKHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRmlsZURhdGFWYWxpZCh2YWx1ZTogRmlsZURhdGEgfCBGaWxlRGF0YVtdLCBtZXRhZGF0YTogRGVmYXVsdEZpbGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBmaWxlczogRmlsZURhdGFbXSA9IG1ldGFkYXRhLm11bHRpcGxlID8gdmFsdWUgYXMgRmlsZURhdGFbXSA6IFt2YWx1ZSBhcyBGaWxlRGF0YV07XG4gICAgICAgIGxldCBmaWxlU2l6ZVRvdGFsOiBudW1iZXIgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgZmlsZXMpIHtcbiAgICAgICAgICAgIGlmICghZmlsZS5uYW1lIHx8ICFmaWxlLmZpbGUgJiYgIWZpbGUudXJsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFGaWxlVXRpbGl0aWVzLmlzTWltZVR5cGVWYWxpZChmaWxlLnR5cGUsIG1ldGFkYXRhLmFsbG93ZWRNaW1lVHlwZXMpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKEZpbGVVdGlsaXRpZXMudHJhbnNmb3JtVG9NZWdhQnl0ZXMoZmlsZS5zaXplLCAnQicpID4gbWV0YWRhdGEubWF4U2l6ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbGVTaXplVG90YWwgKz0gZmlsZS5zaXplO1xuICAgICAgICAgICAgaWYgKEZpbGVVdGlsaXRpZXMudHJhbnNmb3JtVG9NZWdhQnl0ZXMoZmlsZVNpemVUb3RhbCwgJ0InKSA+IG1ldGFkYXRhLm1heFNpemVUb3RhbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYW4gZW50aXR5IGlzIFwiZGlydHlcIiAoaWYgaXRzIHZhbHVlcyBoYXZlIGNoYW5nZWQpLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBlbnRpdHkgYWZ0ZXIgYWxsIGNoYW5nZXMuXG4gICAgICogQHBhcmFtIGVudGl0eVByaW9yQ2hhbmdlcyAtIFRoZSBlbnRpdHkgYmVmb3JlIHRoZSBjaGFuZ2VzLlxuICAgICAqIEBwYXJhbSBodHRwIC0gVGhlIGFuZ3VsYXIgSHR0cENsaWVudC4gVXNlZCB0byBmZXRjaCBmaWxlcy5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgZW50aXR5IGlzIGRpcnR5LlxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBpc0RpcnR5PEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSxcbiAgICAgICAgZW50aXR5UHJpb3JDaGFuZ2VzOiBFbnRpdHlUeXBlLFxuICAgICAgICBodHRwOiBIdHRwQ2xpZW50XG4gICAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGlmICghKGVudGl0eVByaW9yQ2hhbmdlcyBhcyBFbnRpdHlUeXBlIHwgdW5kZWZpbmVkKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRpZmZlcmVuY2VzOiBEaWZmZXJlbmNlPEVudGl0eVR5cGU+W10gPSBhd2FpdCBFbnRpdHlVdGlsaXRpZXMuZGlmZmVyZW5jZXNGb3JEaXJ0eShlbnRpdHksIGVudGl0eVByaW9yQ2hhbmdlcywgaHR0cCk7XG4gICAgICAgIHJldHVybiBkaWZmZXJlbmNlcy5sZW5ndGggPyB0cnVlIDogZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZGlmZmVyZW5jZXNGb3JEaXJ0eTxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KFxuICAgICAgICBlbnRpdHk6IEVudGl0eVR5cGUsXG4gICAgICAgIGVudGl0eVByaW9yQ2hhbmdlczogRW50aXR5VHlwZSxcbiAgICAgICAgaHR0cDogSHR0cENsaWVudFxuICAgICk6IFByb21pc2U8RGlmZmVyZW5jZTxFbnRpdHlUeXBlPltdPiB7XG4gICAgICAgIGNvbnN0IHJlczogRGlmZmVyZW5jZTxFbnRpdHlUeXBlPltdID0gW107XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIFJlZmxlY3RVdGlsaXRpZXMub3duS2V5cyhlbnRpdHkpKSB7XG4gICAgICAgICAgICBjb25zdCBtZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eU1ldGFkYXRhKGVudGl0eSwga2V5KTtcbiAgICAgICAgICAgIGNvbnN0IHR5cGU6IERlY29yYXRvclR5cGVzID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5VHlwZShlbnRpdHksIGtleSk7XG4gICAgICAgICAgICBpZiAoIShhd2FpdCBFbnRpdHlVdGlsaXRpZXMuaXNFcXVhbChlbnRpdHlba2V5XSwgZW50aXR5UHJpb3JDaGFuZ2VzW2tleV0sIG1ldGFkYXRhLCB0eXBlLCBodHRwKSkpIHtcbiAgICAgICAgICAgICAgICByZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBiZWZvcmU6IGVudGl0eVByaW9yQ2hhbmdlc1trZXldLFxuICAgICAgICAgICAgICAgICAgICBhZnRlcjogZW50aXR5W2tleV1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIHRvIHNldCBibG9iIGZpbGUgZGF0YSBzbyB0aGF0IGl0IGlzIG9ubHkgcmVxdWVzdGVkIG9uY2UuXG4gICAgICAgICAgICAgICAgZW50aXR5UHJpb3JDaGFuZ2VzW2tleV0gPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGVudGl0eVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8vIFRPRE8gUmVtb3ZlXG4gICAgLyoqXG4gICAgICogQ29tcGFyZXMgdHdvIEVudGl0aWVzIGFuZCByZXR1cm5zIHRoZWlyIGRpZmZlcmVuY2UgaW4gYW4gb2JqZWN0LlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIFRoZSBmaXJzdCBlbnRpdHkgdG8gY29tcGFyZS5cbiAgICAgKiBAcGFyYW0gZW50aXR5UHJpb3JDaGFuZ2VzIC0gVGhlIHNlY29uZCBlbnRpdHkgdG8gY29tcGFyZS5cbiAgICAgKiBAcmV0dXJucyBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28gRW50aXRpZXMgaW4gZm9ybSBvZiBhIFBhcnRpYWwuXG4gICAgICovXG4gICAgLy8gc3RhdGljIGFzeW5jIGRpZmZlcmVuY2U8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAvLyAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgIC8vICAgICBlbnRpdHlQcmlvckNoYW5nZXM6IEVudGl0eVR5cGVcbiAgICAvLyApOiBQcm9taXNlPFBhcnRpYWw8RW50aXR5VHlwZT4+IHtcbiAgICAvLyAgICAgY29uc3QgcmVzOiBQYXJ0aWFsPEVudGl0eVR5cGU+ID0ge307XG4gICAgLy8gICAgIGZvciAoY29uc3Qga2V5IGluIGVudGl0eSkge1xuICAgIC8vICAgICAgICAgY29uc3QgbWV0YWRhdGE6IFByb3BlcnR5RGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwgPSBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGtleSk7XG4gICAgLy8gICAgICAgICBjb25zdCB0eXBlOiBEZWNvcmF0b3JUeXBlcyA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eVR5cGUoZW50aXR5LCBrZXkpO1xuICAgIC8vICAgICAgICAgaWYgKCEoYXdhaXQgRW50aXR5VXRpbGl0aWVzLmlzRXF1YWwoZW50aXR5W2tleV0sIGVudGl0eVByaW9yQ2hhbmdlc1trZXldLCBtZXRhZGF0YSwgdHlwZSkpKSB7XG4gICAgLy8gICAgICAgICAgICAgcmVzW2tleV0gPSBlbnRpdHlba2V5XTtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgfVxuICAgIC8vICAgICByZXR1cm4gcmVzO1xuICAgIC8vIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0d28gZ2l2ZW4gdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgKiBJdCB1c2VzIHRoZSBpc0VxdWFsIG1ldGhvZCBmcm9tIExvZGFzaFV0aWxpdGllcyBhbmQgZXh0ZW5kcyBpdCB3aXRoIGZ1bmN0aW9uYWxpdHkgcmVnYXJkaW5nIERhdGVzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHZhbHVlIC0gVGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHZhbHVlUHJpb3JDaGFuZ2VzIC0gVGhlIHZhbHVlIGJlZm9yZSBhbnkgY2hhbmdlcy5cbiAgICAgKiBAcGFyYW0gbWV0YWRhdGEgLSBUaGUgbWV0YWRhdGEgb2YgdGhlIHByb3BlcnR5LlxuICAgICAqIEBwYXJhbSB0eXBlIC0gVGhlIHR5cGUgb2YgdGhlIHByb3BlcnR5LlxuICAgICAqIEBwYXJhbSBodHRwIC0gVGhlIGFuZ3VsYXIgSHR0cENsaWVudC4gVXNlZCB0byBmZXRjaCBmaWxlcy5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgZ2l2ZW4gdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgaXNFcXVhbChcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICAgIHZhbHVlUHJpb3JDaGFuZ2VzOiB1bmtub3duLFxuICAgICAgICBtZXRhZGF0YTogUHJvcGVydHlEZWNvcmF0b3JDb25maWdJbnRlcm5hbCxcbiAgICAgICAgdHlwZTogRGVjb3JhdG9yVHlwZXMsXG4gICAgICAgIGh0dHA6IEh0dHBDbGllbnRcbiAgICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkRBVEVfUkFOR0U6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVudGl0eVV0aWxpdGllcy5pc0VxdWFsRGF0ZVJhbmdlKFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVQcmlvckNoYW5nZXMsXG4gICAgICAgICAgICAgICAgICAgIChtZXRhZGF0YSBhcyBEYXRlUmFuZ2VEYXRlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWwpLmZpbHRlclxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkRBVEU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVudGl0eVV0aWxpdGllcy5pc0VxdWFsRGF0ZSh2YWx1ZSwgdmFsdWVQcmlvckNoYW5nZXMpO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5EQVRFX1RJTUU6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVudGl0eVV0aWxpdGllcy5pc0VxdWFsRGF0ZVRpbWUodmFsdWUsIHZhbHVlUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuQVJSQVlfREFURTpcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuQVJSQVlfREFURV9USU1FOlxuICAgICAgICAgICAgICAgIHJldHVybiBFbnRpdHlVdGlsaXRpZXMuaXNFcXVhbEFycmF5RGF0ZSh2YWx1ZSwgdmFsdWVQcmlvckNoYW5nZXMpO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWV9EQVRFX1JBTkdFOlxuICAgICAgICAgICAgICAgIHJldHVybiBFbnRpdHlVdGlsaXRpZXMuaXNFcXVhbEFycmF5RGF0ZVJhbmdlKFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVQcmlvckNoYW5nZXMsXG4gICAgICAgICAgICAgICAgICAgIChtZXRhZGF0YSBhcyBEYXRlUmFuZ2VBcnJheURlY29yYXRvckNvbmZpZ0ludGVybmFsKS5maWx0ZXJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSBEZWNvcmF0b3JUeXBlcy5BUlJBWV9TVFJJTkdfQ0hJUFM6XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkFSUkFZX1NUUklOR19BVVRPQ09NUExFVEVfQ0hJUFM6XG4gICAgICAgICAgICAgICAgcmV0dXJuIEVudGl0eVV0aWxpdGllcy5pc0VxdWFsQXJyYXlTdHJpbmcodmFsdWUsIHZhbHVlUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuRklMRV9JTUFHRTpcbiAgICAgICAgICAgIGNhc2UgRGVjb3JhdG9yVHlwZXMuRklMRV9ERUZBVUxUOlxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgICAgICAgICAgcmV0dXJuIEVudGl0eVV0aWxpdGllcy5pc0VxdWFsRmlsZSh2YWx1ZSwgdmFsdWVQcmlvckNoYW5nZXMsIChtZXRhZGF0YSBhcyBEZWZhdWx0RmlsZURlY29yYXRvckNvbmZpZ0ludGVybmFsKS5tdWx0aXBsZSwgaHR0cCk7XG4gICAgICAgICAgICBjYXNlIERlY29yYXRvclR5cGVzLkNVU1RPTTpcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlbiwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICAgICAgICAgIHJldHVybiBFbnRpdHlVdGlsaXRpZXMuaXNFcXVhbEN1c3RvbSh2YWx1ZSwgdmFsdWVQcmlvckNoYW5nZXMsIG1ldGFkYXRhIGFzIEN1c3RvbURlY29yYXRvckNvbmZpZ0ludGVybmFsPGFueSwgYW55LCBhbnksIGFueT4pO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm4gTG9kYXNoVXRpbGl0aWVzLmlzRXF1YWwodmFsdWUsIHZhbHVlUHJpb3JDaGFuZ2VzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRXF1YWxBcnJheVN0cmluZyh2YWx1ZTogdW5rbm93biwgdmFsdWVQcmlvckNoYW5nZXM6IHVua25vd24pOiBib29sZWFuIHwgUHJvbWlzZUxpa2U8Ym9vbGVhbj4ge1xuICAgICAgICBjb25zdCBzdHJpbmdBcnJheTogc3RyaW5nW10gPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHZhbHVlIGFzIHN0cmluZ1tdKS5zb3J0KCk7XG4gICAgICAgIGNvbnN0IHN0cmluZ0FycmF5UHJpb3JDaGFuZ2VzOiBzdHJpbmdbXSA9IExvZGFzaFV0aWxpdGllcy5jbG9uZURlZXAodmFsdWVQcmlvckNoYW5nZXMgYXMgc3RyaW5nW10pLnNvcnQoKTtcbiAgICAgICAgcmV0dXJuIExvZGFzaFV0aWxpdGllcy5pc0VxdWFsKHN0cmluZ0FycmF5LCBzdHJpbmdBcnJheVByaW9yQ2hhbmdlcyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNFcXVhbEFycmF5RGF0ZSh2YWx1ZTogdW5rbm93biwgdmFsdWVQcmlvckNoYW5nZXM6IHVua25vd24pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgbmV3VmFsdWU6IERhdGVbXSA9ICh2YWx1ZSBhcyBEYXRlW10pLm1hcCh2ID0+IG5ldyBEYXRlKHYpKS5zb3J0KCk7XG4gICAgICAgIGNvbnN0IG5ld1ZhbHVlUHJpb3JDaGFuZ2VzOiBEYXRlW10gPSAodmFsdWVQcmlvckNoYW5nZXMgYXMgRGF0ZVtdKS5tYXAodiA9PiBuZXcgRGF0ZSh2KSkuc29ydCgpO1xuICAgICAgICByZXR1cm4gTG9kYXNoVXRpbGl0aWVzLmlzRXF1YWwobmV3VmFsdWUsIG5ld1ZhbHVlUHJpb3JDaGFuZ2VzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBpc0VxdWFsQXJyYXlEYXRlUmFuZ2UodmFsdWU6IHVua25vd24sIHZhbHVlUHJpb3JDaGFuZ2VzOiB1bmtub3duLCBmaWx0ZXI/OiBEYXRlRmlsdGVyRm48RGF0ZT4pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZGF0ZVJhbmdlczogRGF0ZVJhbmdlW10gPSAodmFsdWUgYXMgRGF0ZVJhbmdlW10pLnNvcnQoKTtcbiAgICAgICAgY29uc3QgZGF0ZVJhbmdlc1ByaW9yQ2hhbmdlczogRGF0ZVJhbmdlW10gPSAodmFsdWVQcmlvckNoYW5nZXMgYXMgRGF0ZVJhbmdlW10pLnNvcnQoKTtcbiAgICAgICAgaWYgKGRhdGVSYW5nZXMubGVuZ3RoICE9PSBkYXRlUmFuZ2VzUHJpb3JDaGFuZ2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCBkYXRlUmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIUVudGl0eVV0aWxpdGllcy5pc0VxdWFsRGF0ZVJhbmdlKGRhdGVSYW5nZXNbaV0sIGRhdGVSYW5nZXNQcmlvckNoYW5nZXNbaV0sIGZpbHRlcikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNFcXVhbERhdGVUaW1lKHZhbHVlOiB1bmtub3duLCB2YWx1ZVByaW9yQ2hhbmdlczogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBkYXRlOiBEYXRlID0gbmV3IERhdGUodmFsdWUgYXMgRGF0ZSk7XG4gICAgICAgIGNvbnN0IGRhdGVQcmlvckNoYW5nZXM6IERhdGUgPSBuZXcgRGF0ZSh2YWx1ZVByaW9yQ2hhbmdlcyBhcyBEYXRlKTtcbiAgICAgICAgcmV0dXJuIExvZGFzaFV0aWxpdGllcy5pc0VxdWFsKGRhdGUsIGRhdGVQcmlvckNoYW5nZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRXF1YWxEYXRlKHZhbHVlOiB1bmtub3duLCB2YWx1ZVByaW9yQ2hhbmdlczogdW5rbm93bik6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBkYXRlOiBEYXRlID0gbmV3IERhdGUodmFsdWUgYXMgRGF0ZSk7XG4gICAgICAgIGNvbnN0IGRhdGVQcmlvckNoYW5nZXM6IERhdGUgPSBuZXcgRGF0ZSh2YWx1ZVByaW9yQ2hhbmdlcyBhcyBEYXRlKTtcbiAgICAgICAgZGF0ZS5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgICAgZGF0ZVByaW9yQ2hhbmdlcy5zZXRIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgICAgcmV0dXJuIExvZGFzaFV0aWxpdGllcy5pc0VxdWFsKGRhdGUsIGRhdGVQcmlvckNoYW5nZXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzRXF1YWxEYXRlUmFuZ2UodmFsdWU6IHVua25vd24sIHZhbHVlUHJpb3JDaGFuZ2VzOiB1bmtub3duLCBmaWx0ZXI/OiBEYXRlRmlsdGVyRm48RGF0ZT4pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgZGF0ZVJhbmdlOiBEYXRlUmFuZ2UgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHZhbHVlKSBhcyBEYXRlUmFuZ2U7XG4gICAgICAgIGRhdGVSYW5nZS5zdGFydCA9IG5ldyBEYXRlKCh2YWx1ZSBhcyBEYXRlUmFuZ2UpLnN0YXJ0KTtcbiAgICAgICAgZGF0ZVJhbmdlLmVuZCA9IG5ldyBEYXRlKCh2YWx1ZSBhcyBEYXRlUmFuZ2UpLmVuZCk7XG4gICAgICAgIGRhdGVSYW5nZS52YWx1ZXMgPSBEYXRlVXRpbGl0aWVzLmdldERhdGVzQmV0d2VlbihcbiAgICAgICAgICAgIGRhdGVSYW5nZS5zdGFydCxcbiAgICAgICAgICAgIGRhdGVSYW5nZS5lbmQsXG4gICAgICAgICAgICBmaWx0ZXJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZGF0ZVJhbmdlUHJpb3JDaGFuZ2VzOiBEYXRlUmFuZ2UgPSBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKHZhbHVlUHJpb3JDaGFuZ2VzKSBhcyBEYXRlUmFuZ2U7XG4gICAgICAgIGRhdGVSYW5nZVByaW9yQ2hhbmdlcy5zdGFydCA9IG5ldyBEYXRlKCh2YWx1ZVByaW9yQ2hhbmdlcyBhcyBEYXRlUmFuZ2UpLnN0YXJ0KTtcbiAgICAgICAgZGF0ZVJhbmdlUHJpb3JDaGFuZ2VzLmVuZCA9IG5ldyBEYXRlKCh2YWx1ZVByaW9yQ2hhbmdlcyBhcyBEYXRlUmFuZ2UpLmVuZCk7XG4gICAgICAgIGRhdGVSYW5nZVByaW9yQ2hhbmdlcy52YWx1ZXMgPSBEYXRlVXRpbGl0aWVzLmdldERhdGVzQmV0d2VlbihcbiAgICAgICAgICAgIGRhdGVSYW5nZVByaW9yQ2hhbmdlcy5zdGFydCxcbiAgICAgICAgICAgIGRhdGVSYW5nZVByaW9yQ2hhbmdlcy5lbmQsXG4gICAgICAgICAgICBmaWx0ZXJcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIExvZGFzaFV0aWxpdGllcy5pc0VxdWFsKGRhdGVSYW5nZSwgZGF0ZVJhbmdlUHJpb3JDaGFuZ2VzKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBGaW5kIGEgd2F5IHRvIHVzZSBibG9icyB3aXRoIGplc3RcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHByaXZhdGUgc3RhdGljIGFzeW5jIGlzRXF1YWxGaWxlKHZhbHVlOiB1bmtub3duLCB2YWx1ZVByaW9yQ2hhbmdlczogdW5rbm93biwgbXVsdGlwbGU6IGJvb2xlYW4sIGh0dHA6IEh0dHBDbGllbnQpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVByaW9yQ2hhbmdlcyA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlsZXM6IEZpbGVEYXRhW10gPSBtdWx0aXBsZSA/ICh2YWx1ZSBhcyBGaWxlRGF0YVtdKS5zb3J0KCkgOiBbdmFsdWUgYXMgRmlsZURhdGFdLnNvcnQoKTtcbiAgICAgICAgY29uc3QgZmlsZXNQcmlvckNoYW5nZXM6IEZpbGVEYXRhW10gPSBtdWx0aXBsZSA/ICh2YWx1ZVByaW9yQ2hhbmdlcyBhcyBGaWxlRGF0YVtdKS5zb3J0KCkgOiBbdmFsdWVQcmlvckNoYW5nZXMgYXMgRmlsZURhdGFdLnNvcnQoKTtcbiAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCAhPT0gZmlsZXNQcmlvckNoYW5nZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaTogbnVtYmVyID0gMDsgaSA8IGZpbGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAvLyBjaGVja3MgdGhpcyBiZWZvcmUgYWN0dWFsbHkgZ2V0dGluZyBhbnkgZmlsZXMgZHVlIHRvIHBlcmZvcm1hbmNlIHJlYXNvbnMuXG4gICAgICAgICAgICBpZiAoIUxvZGFzaFV0aWxpdGllcy5pc0VxdWFsKExvZGFzaFV0aWxpdGllcy5vbWl0KGZpbGVzW2ldLCAnZmlsZScpLCBMb2Rhc2hVdGlsaXRpZXMub21pdChmaWxlc1ByaW9yQ2hhbmdlc1tpXSwgJ2ZpbGUnKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZmlsZXNQcmlvckNoYW5nZXNbaV0uZmlsZSAmJiAhZmlsZXNbaV0uZmlsZSkge1xuICAgICAgICAgICAgICAgIGZpbGVzW2ldID0gYXdhaXQgRmlsZVV0aWxpdGllcy5nZXRGaWxlRGF0YShmaWxlc1tpXSwgaHR0cCk7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBmaWxlc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChmaWxlc1tpXS5maWxlICYmICFmaWxlc1ByaW9yQ2hhbmdlc1tpXS5maWxlKSB7XG4gICAgICAgICAgICAgICAgZmlsZXNQcmlvckNoYW5nZXNbaV0gPSBhd2FpdCBGaWxlVXRpbGl0aWVzLmdldEZpbGVEYXRhKGZpbGVzUHJpb3JDaGFuZ2VzW2ldLCBodHRwKTtcbiAgICAgICAgICAgICAgICB2YWx1ZVByaW9yQ2hhbmdlcyA9IGZpbGVzUHJpb3JDaGFuZ2VzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFMb2Rhc2hVdGlsaXRpZXMuaXNFcXVhbChhd2FpdCBmaWxlc1tpXS5maWxlPy50ZXh0KCksIGF3YWl0IGZpbGVzUHJpb3JDaGFuZ2VzW2ldLmZpbGU/LnRleHQoKSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNFcXVhbEN1c3RvbShcbiAgICAgICAgdmFsdWU6IHVua25vd24sXG4gICAgICAgIHZhbHVlUHJpb3JDaGFuZ2VzOiB1bmtub3duLFxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgICBtZXRhZGF0YTogQ3VzdG9tRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw8YW55LCBhbnksIGFueSwgYW55PlxuICAgICk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIW1ldGFkYXRhLmlzRXF1YWwodmFsdWUsIHZhbHVlUHJpb3JDaGFuZ2VzLCBtZXRhZGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wYXJlIGZ1bmN0aW9uIGZvciBzb3J0aW5nIGVudGl0eSBrZXlzIGJ5IHRoZWlyIG9yZGVyIHZhbHVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGEgLSBGaXJzdCBrZXkgb2YgZW50aXR5LlxuICAgICAqIEBwYXJhbSBiIC0gU2Vjb25kIGtleSBvZiBlbnRpdHkuXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEN1cnJlbnQgZW50aXR5ICh1c2VkIHRvIGdldCBtZXRhZGF0YSBvZiBlbnRpdHkga2V5cykuXG4gICAgICogQHJldHVybnMgMCBpZiBib3RoIHZhbHVlcyBoYXZlIHRoZSBzYW1lIG9yZGVyLCBhIG5lZ2F0aXZlIHZhbHVlIGlmICdhJyBjb21lcyBiZWZvcmUgJ2InLCBhIHBvc2l0aXZlIHZhbHVlIGlmICdhJyBjb21lcyBiZWhpbmQgJ2InLlxuICAgICAqL1xuICAgIHN0YXRpYyBjb21wYXJlT3JkZXI8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgYToga2V5b2YgRW50aXR5VHlwZSxcbiAgICAgICAgYjoga2V5b2YgRW50aXR5VHlwZSxcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlXG4gICAgKTogbnVtYmVyIHtcbiAgICAgICAgY29uc3QgbWV0YWRhdGFBOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBhKTtcbiAgICAgICAgY29uc3QgbWV0YWRhdGFCOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBiKTtcblxuICAgICAgICBpZiAobWV0YWRhdGFBLnBvc2l0aW9uLm9yZGVyID09PSAtMSkge1xuICAgICAgICAgICAgaWYgKG1ldGFkYXRhQi5wb3NpdGlvbi5vcmRlciA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1ldGFkYXRhQi5wb3NpdGlvbi5vcmRlciA9PT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWV0YWRhdGFBLnBvc2l0aW9uLm9yZGVyIC0gbWV0YWRhdGFCLnBvc2l0aW9uLm9yZGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGJvb3RzdHJhcCBjb2x1bW4gdmFsdWVzIGZvciBcImxnXCIsIFwibWRcIiwgXCJzbVwiLlxuICAgICAqXG4gICAgICogQHBhcmFtIGVudGl0eSAtIEVudGl0eSB0byBnZXQgdGhlIGJvb3RzdHJhcCBjb2x1bW4gdmFsdWVzIG9mIHRoZSBrZXkuXG4gICAgICogQHBhcmFtIGtleSAtIEtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0IGJvb3RzdHJhcCBjb2x1bW4gdmFsdWVzIGZyb20uXG4gICAgICogQHBhcmFtIHR5cGUgLSBEZWZpbmVzIGZvciB3aGljaCBzY3JlZW4gc2l6ZSB0aGUgY29sdW1uIHZhbHVlcyBzaG91bGQgYmUgcmV0dXJuZWQuXG4gICAgICogQHJldHVybnMgQm9vdHN0cmFwIGNvbHVtbiB2YWx1ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0V2lkdGg8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICBrZXk6IGtleW9mIEVudGl0eVR5cGUsIHR5cGU6ICdsZycgfCAnbWQnIHwgJ3NtJ1xuICAgICk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG1ldGFkYXRhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBrZXkpO1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2xnJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YWRhdGEuZGVmYXVsdFdpZHRoc1swXTtcbiAgICAgICAgICAgIGNhc2UgJ21kJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YWRhdGEuZGVmYXVsdFdpZHRoc1sxXTtcbiAgICAgICAgICAgIGNhc2UgJ3NtJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0YWRhdGEuZGVmYXVsdFdpZHRoc1syXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2V0cyBhbGwgY2hhbmdlcyBvbiBhbiBlbnRpdHkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byByZXNldC5cbiAgICAgKiBAcGFyYW0gZW50aXR5UHJpb3JDaGFuZ2VzIC0gVGhlIGVudGl0eSBiZWZvcmUgYW55IGNoYW5nZXMuXG4gICAgICovXG4gICAgc3RhdGljIHJlc2V0Q2hhbmdlc09uRW50aXR5PEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oZW50aXR5OiBFbnRpdHlUeXBlLCBlbnRpdHlQcmlvckNoYW5nZXM6IEVudGl0eVR5cGUpOiB2b2lkIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZW50aXR5UHJpb3JDaGFuZ2VzKSB7XG4gICAgICAgICAgICBSZWZsZWN0VXRpbGl0aWVzLnNldChlbnRpdHksIGtleSwgUmVmbGVjdFV0aWxpdGllcy5nZXQoZW50aXR5UHJpb3JDaGFuZ2VzLCBrZXkpKTtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0VXRpbGl0aWVzLmhhc01ldGFkYXRhKHRoaXMuTUVUQURBVEFfS0VZU19UT19SRVNFVF9LRVksIGVudGl0eSwga2V5KSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgayBvZiAoUmVmbGVjdFV0aWxpdGllcy5nZXRNZXRhZGF0YSh0aGlzLk1FVEFEQVRBX0tFWVNfVE9fUkVTRVRfS0VZLCBlbnRpdHksIGtleSkgYXMgc3RyaW5nW10pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChSZWZsZWN0VXRpbGl0aWVzLmhhc01ldGFkYXRhKGssIGVudGl0eSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgUmVmbGVjdFV0aWxpdGllcy5kZWZpbmVNZXRhZGF0YShrLCB1bmRlZmluZWQsIGVudGl0eSwga2V5KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGdldEVudGl0eVJvd3M8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICB0YWI6IG51bWJlcixcbiAgICAgICAgaGlkZU9taXRGb3JDcmVhdGU6IGJvb2xlYW4sXG4gICAgICAgIGhpZGVPbWl0Rm9yRWRpdDogYm9vbGVhbixcbiAgICAgICAgYWRkaXRpb25hbE9taXRWYWx1ZXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdXG4gICAgKTogRW50aXR5Um93PEVudGl0eVR5cGU+W10ge1xuICAgICAgICBjb25zdCByZXM6IEVudGl0eVJvdzxFbnRpdHlUeXBlPltdID0gW107XG5cbiAgICAgICAgY29uc3Qga2V5czogKGtleW9mIEVudGl0eVR5cGUpW10gPSBFbnRpdHlVdGlsaXRpZXMua2V5c09mKGVudGl0eSwgaGlkZU9taXRGb3JDcmVhdGUsIGhpZGVPbWl0Rm9yRWRpdClcbiAgICAgICAgICAgIC5maWx0ZXIoayA9PiAhYWRkaXRpb25hbE9taXRWYWx1ZXMuaW5jbHVkZXMoaykpO1xuICAgICAgICBjb25zdCBudW1iZXJPZlJvd3M6IG51bWJlciA9IEVudGl0eVV0aWxpdGllcy5nZXROdW1iZXJPZlJvd3M8RW50aXR5VHlwZT4oa2V5cywgZW50aXR5LCB0YWIpO1xuICAgICAgICBmb3IgKGxldCBpOiBudW1iZXIgPSAxOyBpIDw9IG51bWJlck9mUm93czsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCByb3c6IEVudGl0eVJvdzxFbnRpdHlUeXBlPiA9IHtcbiAgICAgICAgICAgICAgICByb3c6IGksXG4gICAgICAgICAgICAgICAga2V5czogRW50aXR5VXRpbGl0aWVzLmdldEtleXNGb3JSb3c8RW50aXR5VHlwZT4oa2V5cywgZW50aXR5LCBpLCB0YWIpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVzLnB1c2gocm93KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChFbnRpdHlVdGlsaXRpZXMuZ2V0S2V5c0ZvclJvdzxFbnRpdHlUeXBlPihrZXlzLCBlbnRpdHksIC0xLCB0YWIpLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgbGFzdFJvdzogRW50aXR5Um93PEVudGl0eVR5cGU+ID0ge1xuICAgICAgICAgICAgICAgIHJvdzogbnVtYmVyT2ZSb3dzICsgMSxcbiAgICAgICAgICAgICAgICBrZXlzOiBFbnRpdHlVdGlsaXRpZXMuZ2V0S2V5c0ZvclJvdzxFbnRpdHlUeXBlPihrZXlzLCBlbnRpdHksIC0xLCB0YWIpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmVzLnB1c2gobGFzdFJvdyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIHRhYnMgdGhhdCBhcmUgdXNlZCB0byBkaXNwbGF5IHRoZSBnaXZlbiBlbnRpdHkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byBnZXQgdGhlIHJvd3MgZnJvbS5cbiAgICAgKiBAcGFyYW0gaGlkZU9taXRGb3JDcmVhdGUgLSBXaGV0aGVyIG9yIG5vdCBrZXlzIHdpdGggdGhlIG1ldGFkYXRhIG9taXRGb3JDcmVhdGUgc2hvdWxkIGJlIGZpbHRlcmVkIG91dC5cbiAgICAgKiBAcGFyYW0gaGlkZU9taXRGb3JFZGl0IC0gV2hldGhlciBvciBub3Qga2V5cyB3aXRoIHRoZSBtZXRhZGF0YSBvbWl0Rm9yVXBkYXRlIHNob3VsZCBiZSBmaWx0ZXJlZCBvdXQuXG4gICAgICogQHBhcmFtIGFkZGl0aW9uYWxPbWl0VmFsdWVzIC0gQWRkaXRpb25hbCBvbWl0IHZhbHVlcy5cbiAgICAgKiBAcmV0dXJucyBUaGUgc29ydGVkIFRhYnMgY29udGFpbmluZyB0aGUgcm93cyBhbmQgdGhlIGtleXMgdG8gZGlzcGxheSBpbiB0aGF0IHJvdy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RW50aXR5VGFiczxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KFxuICAgICAgICBlbnRpdHk6IEVudGl0eVR5cGUsXG4gICAgICAgIGhpZGVPbWl0Rm9yQ3JlYXRlOiBib29sZWFuID0gZmFsc2UsXG4gICAgICAgIGhpZGVPbWl0Rm9yRWRpdDogYm9vbGVhbiA9IGZhbHNlLFxuICAgICAgICBhZGRpdGlvbmFsT21pdFZhbHVlczogKGtleW9mIEVudGl0eVR5cGUpW10gPSBbXVxuICAgICk6IEVudGl0eVRhYjxFbnRpdHlUeXBlPltdIHtcbiAgICAgICAgY29uc3QgcmVzOiBFbnRpdHlUYWI8RW50aXR5VHlwZT5bXSA9IFtdO1xuICAgICAgICBjb25zdCBrZXlzOiAoa2V5b2YgRW50aXR5VHlwZSlbXSA9IEVudGl0eVV0aWxpdGllcy5rZXlzT2YoZW50aXR5LCBoaWRlT21pdEZvckNyZWF0ZSwgaGlkZU9taXRGb3JFZGl0KVxuICAgICAgICAgICAgLmZpbHRlcihrID0+ICFhZGRpdGlvbmFsT21pdFZhbHVlcy5pbmNsdWRlcyhrKSk7XG4gICAgICAgIGNvbnN0IG51bWJlck9mVGFiczogbnVtYmVyID0gRW50aXR5VXRpbGl0aWVzLmdldE51bWJlck9mVGFiczxFbnRpdHlUeXBlPihrZXlzLCBlbnRpdHkpO1xuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgICAgIGNvbnN0IGZpcnN0VGFiUm93czogRW50aXR5Um93PEVudGl0eVR5cGU+W10gPSBFbnRpdHlVdGlsaXRpZXMuZ2V0RW50aXR5Um93czxFbnRpdHlUeXBlPihlbnRpdHksIC0xLCBoaWRlT21pdEZvckNyZWF0ZSwgaGlkZU9taXRGb3JFZGl0LCBhZGRpdGlvbmFsT21pdFZhbHVlcyk7XG4gICAgICAgIGlmIChmaXJzdFRhYlJvd3MubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdFRhYjogRW50aXR5VGFiPEVudGl0eVR5cGU+ID0ge1xuICAgICAgICAgICAgICAgIHRhYk5hbWU6IEVudGl0eVV0aWxpdGllcy5nZXRGaXJzdFRhYk5hbWUoZW50aXR5KSxcbiAgICAgICAgICAgICAgICB0YWI6IC0xLFxuICAgICAgICAgICAgICAgIHJvd3M6IGZpcnN0VGFiUm93c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZpcnN0VGFiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGk6IG51bWJlciA9IDI7IGkgPD0gbnVtYmVyT2ZUYWJzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHJvd3M6IEVudGl0eVJvdzxFbnRpdHlUeXBlPltdID0gRW50aXR5VXRpbGl0aWVzLmdldEVudGl0eVJvd3M8RW50aXR5VHlwZT4oXG4gICAgICAgICAgICAgICAgZW50aXR5LCBpLCBoaWRlT21pdEZvckNyZWF0ZSwgaGlkZU9taXRGb3JFZGl0LCBhZGRpdGlvbmFsT21pdFZhbHVlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChyb3dzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRhYjogRW50aXR5VGFiPEVudGl0eVR5cGU+ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YWJOYW1lOiBFbnRpdHlVdGlsaXRpZXMuZ2V0VGFiTmFtZShlbnRpdHksIGkpLFxuICAgICAgICAgICAgICAgICAgICB0YWI6IGksXG4gICAgICAgICAgICAgICAgICAgIHJvd3M6IHJvd3NcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlcy5wdXNoKHRhYik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGdldEtleXNGb3JSb3c8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihcbiAgICAgICAga2V5czogKGtleW9mIEVudGl0eVR5cGUpW10sXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSxcbiAgICAgICAgcm93OiBudW1iZXIsXG4gICAgICAgIHRhYjogbnVtYmVyXG4gICAgKTogKGtleW9mIEVudGl0eVR5cGUpW10ge1xuICAgICAgICByZXR1cm4ga2V5c1xuICAgICAgICAgICAgLmZpbHRlcihrID0+IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eU1ldGFkYXRhKGVudGl0eSwgaykucG9zaXRpb24ucm93ID09PSByb3cpXG4gICAgICAgICAgICAuZmlsdGVyKGsgPT4gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBrKS5wb3NpdGlvbi50YWIgPT09IHRhYilcbiAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiBFbnRpdHlVdGlsaXRpZXMuY29tcGFyZU9yZGVyKGEsIGIsIGVudGl0eSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGdldE51bWJlck9mUm93czxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KFxuICAgICAgICBrZXlzOiAoa2V5b2YgRW50aXR5VHlwZSlbXSxcbiAgICAgICAgZW50aXR5OiBFbnRpdHlUeXBlLFxuICAgICAgICB0YWI6IG51bWJlclxuICAgICk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiBrZXlzXG4gICAgICAgICAgICAuZmlsdGVyKGsgPT4gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBrKS5wb3NpdGlvbi50YWIgPT09IHRhYilcbiAgICAgICAgICAgIC5tYXAoayA9PiBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGspLnBvc2l0aW9uLnJvdylcbiAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiAoYSA+IGIgPyAtMSA6IDEpKVswXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBnZXROdW1iZXJPZlRhYnM8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihrZXlzOiAoa2V5b2YgRW50aXR5VHlwZSlbXSwgZW50aXR5OiBFbnRpdHlUeXBlKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIGtleXNcbiAgICAgICAgICAgIC5tYXAoayA9PiBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGspLnBvc2l0aW9uLnRhYilcbiAgICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiAoYSA+IGIgPyAtMSA6IDEpKVswXTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRUYWJOYW1lPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oZW50aXR5OiBFbnRpdHlUeXBlLCB0YWI6IG51bWJlcik6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVkVGFiTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gUmVmbGVjdFV0aWxpdGllcy5vd25LZXlzKGVudGl0eSlcbiAgICAgICAgICAgIC5tYXAoayA9PiBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGspKVxuICAgICAgICAgICAgLmZpbmQobSA9PiBtLnBvc2l0aW9uLnRhYiA9PT0gdGFiICYmIG0ucG9zaXRpb24udGFiTmFtZSk/LnBvc2l0aW9uLnRhYk5hbWU7XG4gICAgICAgIHJldHVybiBwcm92aWRlZFRhYk5hbWUgPz8gYFRhYiAke3RhYn1gO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGdldEZpcnN0VGFiTmFtZTxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+KGVudGl0eTogRW50aXR5VHlwZSk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHByb3ZpZGVkVGFiTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gUmVmbGVjdFV0aWxpdGllcy5vd25LZXlzKGVudGl0eSlcbiAgICAgICAgICAgIC5tYXAoayA9PiBFbnRpdHlVdGlsaXRpZXMuZ2V0UHJvcGVydHlNZXRhZGF0YShlbnRpdHksIGspKVxuICAgICAgICAgICAgLmZpbmQobSA9PiBtLnBvc2l0aW9uLnRhYk5hbWUgJiYgbS5wb3NpdGlvbi50YWIgPT09IC0xKT8ucG9zaXRpb24udGFiTmFtZTtcbiAgICAgICAgcmV0dXJuIHByb3ZpZGVkVGFiTmFtZSA/PyAnVGFiIDEnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGtleXMgb2YgdGhlIHByb3ZpZGVkIGVudGl0eSBjb3JyZWN0bHkgdHlwZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB0byBnZXQgdGhlIGtleXMgb2YuXG4gICAgICogQHBhcmFtIGhpZGVPbWl0Rm9yQ3JlYXRlIC0gV2hldGhlciBvciBub3Qga2V5cyB3aXRoIHRoZSBtZXRhZGF0YSBvbWl0Rm9yQ3JlYXRlIHNob3VsZCBiZSBmaWx0ZXJlZCBvdXQuXG4gICAgICogQHBhcmFtIGhpZGVPbWl0Rm9yRWRpdCAtIFdoZXRoZXIgb3Igbm90IGtleXMgd2l0aCB0aGUgbWV0YWRhdGEgb21pdEZvclVwZGF0ZSBzaG91bGQgYmUgZmlsdGVyZWQgb3V0LlxuICAgICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGtleXMgb2YgdGhlIGVudGl0eS5cbiAgICAgKi9cbiAgICBzdGF0aWMga2V5c09mPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4oXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSxcbiAgICAgICAgaGlkZU9taXRGb3JDcmVhdGU6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICAgICAgaGlkZU9taXRGb3JFZGl0OiBib29sZWFuID0gZmFsc2VcbiAgICApOiAoa2V5b2YgRW50aXR5VHlwZSlbXSB7XG4gICAgICAgIGxldCBrZXlzOiAoa2V5b2YgRW50aXR5VHlwZSlbXSA9IFJlZmxlY3RVdGlsaXRpZXMub3duS2V5cyhlbnRpdHkpO1xuICAgICAgICBjb25zdCBkb250RGlzcGxheUtleXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdID0gRW50aXR5VXRpbGl0aWVzLmdldERvbnREaXNwbGF5S2V5cyhlbnRpdHkpO1xuICAgICAgICBrZXlzID0ga2V5cy5maWx0ZXIoayA9PiAhZG9udERpc3BsYXlLZXlzLmluY2x1ZGVzKGspKTtcbiAgICAgICAgaWYgKGhpZGVPbWl0Rm9yQ3JlYXRlKSB7XG4gICAgICAgICAgICBjb25zdCBvbWl0Rm9yQ3JlYXRlS2V5czogKGtleW9mIEVudGl0eVR5cGUpW10gPSBFbnRpdHlVdGlsaXRpZXMuZ2V0T21pdEZvckNyZWF0ZShlbnRpdHkpO1xuICAgICAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGsgPT4gIW9taXRGb3JDcmVhdGVLZXlzLmluY2x1ZGVzKGspKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlkZU9taXRGb3JFZGl0KSB7XG4gICAgICAgICAgICBjb25zdCBvbWl0Rm9yVXBkYXRlS2V5czogKGtleW9mIEVudGl0eVR5cGUpW10gPSBFbnRpdHlVdGlsaXRpZXMuZ2V0T21pdEZvclVwZGF0ZShlbnRpdHkpO1xuICAgICAgICAgICAga2V5cyA9IGtleXMuZmlsdGVyKGsgPT4gIW9taXRGb3JVcGRhdGVLZXlzLmluY2x1ZGVzKGspKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBnZXREb250RGlzcGxheUtleXM8RW50aXR5VHlwZSBleHRlbmRzIEJhc2VFbnRpdHlUeXBlPEVudGl0eVR5cGU+PihlbnRpdHk6IEVudGl0eVR5cGUpOiAoa2V5b2YgRW50aXR5VHlwZSlbXSB7XG4gICAgICAgIGNvbnN0IHJlczogKGtleW9mIEVudGl0eVR5cGUpW10gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgUmVmbGVjdFV0aWxpdGllcy5vd25LZXlzKGVudGl0eSkpIHtcbiAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhOiBQcm9wZXJ0eURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoZW50aXR5LCBrZXkpO1xuICAgICAgICAgICAgaWYgKCFtZXRhZGF0YS5kaXNwbGF5KGVudGl0eSkpIHtcbiAgICAgICAgICAgICAgICByZXMucHVzaChrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxufVxuXG4vKipcbiAqIEEgcm93IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgaG93IHRvIGRpc3BsYXkgYW4gZW50aXR5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVudGl0eVJvdzxFbnRpdHlUeXBlIGV4dGVuZHMgQmFzZUVudGl0eVR5cGU8RW50aXR5VHlwZT4+IHtcbiAgICAvKipcbiAgICAgKiBUaGUgcm93IGluIHdoaWNoIHRoaXMgc2hvdWxkIGJlIGRpc3BsYXllZC5cbiAgICAgKi9cbiAgICByb3c6IG51bWJlcixcbiAgICAvKipcbiAgICAgKiBUaGUga2V5cyBvZiB0aGUgdmFsdWVzIHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZCBpbiB0aGF0IHJvdy5cbiAgICAgKi9cbiAgICBrZXlzOiAoa2V5b2YgRW50aXR5VHlwZSlbXVxufVxuXG4vKipcbiAqIEEgdGFiIHRoYXQgY29udGFpbnMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBob3cgdG8gZGlzcGxheSBhbiBlbnRpdHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5VGFiPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4ge1xuICAgIC8qKlxuICAgICAqIFRoZSB0YWIgaW4gd2hpY2ggdGhlIHJvd3Mgc2hvdWxkIGJlIGRpc3BsYXllZC5cbiAgICAgKi9cbiAgICB0YWI6IG51bWJlcixcbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSB0byBkaXNwbGF5IGluc2lkZSB0aGUgdGFiLlxuICAgICAqL1xuICAgIHRhYk5hbWU6IHN0cmluZyxcbiAgICAvKipcbiAgICAgKiBUaGUgcm93cyB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQgaW5zaWRlIHRoaXMgdGFiLC5cbiAgICAgKi9cbiAgICByb3dzOiBFbnRpdHlSb3c8RW50aXR5VHlwZT5bXVxufSJdfQ==
|