ngx-material-entity 18.2.6 → 20.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/fesm2022/ngx-material-entity.mjs +154 -150
- package/fesm2022/ngx-material-entity.mjs.map +1 -1
- package/index.d.ts +4501 -3
- package/package.json +10 -12
- package/classes/base.builder.d.ts +0 -37
- package/classes/entity.model.d.ts +0 -27
- package/components/confirm-dialog/confirm-dialog-data.builder.d.ts +0 -24
- package/components/confirm-dialog/confirm-dialog-data.d.ts +0 -48
- package/components/confirm-dialog/confirm-dialog.component.d.ts +0 -36
- package/components/create-page/create-data.route.d.ts +0 -16
- package/components/create-page/create-page.component.d.ts +0 -141
- package/components/create-page/page-create-data.builder.d.ts +0 -18
- package/components/custom-table/custom-table-configuration.model.d.ts +0 -65
- package/components/custom-table/custom-table.component.d.ts +0 -111
- package/components/edit-page/edit-data.route.d.ts +0 -16
- package/components/edit-page/edit-page.component.d.ts +0 -167
- package/components/edit-page/page-edit-data.builder.d.ts +0 -18
- package/components/form/form.component.d.ts +0 -64
- package/components/input/array/array-date-input/array-date-input.component.d.ts +0 -17
- package/components/input/array/array-date-range-input/array-date-range-input.component.d.ts +0 -25
- package/components/input/array/array-date-time-input/array-date-time-input.component.d.ts +0 -26
- package/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.d.ts +0 -30
- package/components/input/array/array-string-chips-input/array-string-chips-input.component.d.ts +0 -36
- package/components/input/array/array-table.class.d.ts +0 -56
- package/components/input/base-input.component.d.ts +0 -64
- package/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.d.ts +0 -10
- package/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.d.ts +0 -13
- package/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.d.ts +0 -10
- package/components/input/custom/custom.component.d.ts +0 -13
- package/components/input/date/date-input/date-input.component.d.ts +0 -11
- package/components/input/date/date-range-input/date-range-input.component.d.ts +0 -22
- package/components/input/date/date-time-input/date-time-input.component.d.ts +0 -32
- package/components/input/file/file-default-input/file-default-input.component.d.ts +0 -11
- package/components/input/file/file-image-input/file-image-input.component.d.ts +0 -28
- package/components/input/file/file-input/file-input.component.d.ts +0 -45
- package/components/input/input.component.d.ts +0 -590
- package/components/input/number/number-dropdown-input/number-dropdown-input.component.d.ts +0 -24
- package/components/input/number/number-input/number-input.component.d.ts +0 -9
- package/components/input/number/number-slider-input/number-slider-input.component.d.ts +0 -10
- package/components/input/relations/references-many-input/references-many-input.component.d.ts +0 -43
- package/components/input/string/string-autocomplete-input/string-autocomplete-input.component.d.ts +0 -19
- package/components/input/string/string-dropdown-input/string-dropdown-input.component.d.ts +0 -24
- package/components/input/string/string-input/string-input.component.d.ts +0 -9
- package/components/input/string/string-password-input/string-password-input.component.d.ts +0 -31
- package/components/input/string/string-textbox-input/string-textbox-input.component.d.ts +0 -9
- package/components/table/create-dialog/create-data.builder.d.ts +0 -25
- package/components/table/create-dialog/create-entity-data.builder.d.ts +0 -21
- package/components/table/create-dialog/create-entity-data.d.ts +0 -19
- package/components/table/create-dialog/create-entity-dialog.component.d.ts +0 -77
- package/components/table/default.actions.d.ts +0 -25
- package/components/table/display-column-value/base-display-column-value.component.d.ts +0 -15
- package/components/table/display-column-value/display-column-value.component.d.ts +0 -26
- package/components/table/edit-dialog/edit-data.builder.d.ts +0 -44
- package/components/table/edit-dialog/edit-entity-data.d.ts +0 -27
- package/components/table/edit-dialog/edit-entity-dialog.component.d.ts +0 -118
- package/components/table/edit-dialog/edit-entity.builder.d.ts +0 -23
- package/components/table/table-data.builder.d.ts +0 -102
- package/components/table/table-data.d.ts +0 -340
- package/components/table/table.component.d.ts +0 -119
- package/components/tooltip/tooltip.component.d.ts +0 -14
- package/decorators/array/array-decorator-internal.data.d.ts +0 -129
- package/decorators/array/array-decorator.data.d.ts +0 -252
- package/decorators/array/array.decorator.d.ts +0 -9
- package/decorators/base/base-property.decorator.d.ts +0 -9
- package/decorators/base/decorator-types.enum.d.ts +0 -48
- package/decorators/base/dropdown-value.interface.d.ts +0 -14
- package/decorators/base/property-decorator-internal.data.d.ts +0 -41
- package/decorators/base/property-decorator.data.d.ts +0 -88
- package/decorators/boolean/boolean-decorator-internal.data.d.ts +0 -26
- package/decorators/boolean/boolean-decorator.data.d.ts +0 -39
- package/decorators/boolean/boolean.decorator.d.ts +0 -7
- package/decorators/custom/custom-decorator-internal.data.d.ts +0 -17
- package/decorators/custom/custom-decorator.data.d.ts +0 -35
- package/decorators/custom/custom.decorator.d.ts +0 -9
- package/decorators/date/date-decorator-internal.data.d.ts +0 -45
- package/decorators/date/date-decorator.data.d.ts +0 -126
- package/decorators/date/date.decorator.d.ts +0 -7
- package/decorators/file/file-decorator-internal.data.d.ts +0 -93
- package/decorators/file/file-decorator.data.d.ts +0 -88
- package/decorators/file/file.decorator.d.ts +0 -8
- package/decorators/has-many/has-many-decorator-internal.data.d.ts +0 -16
- package/decorators/has-many/has-many-decorator.data.d.ts +0 -34
- package/decorators/has-many/has-many.decorator.d.ts +0 -8
- package/decorators/number/number-decorator-internal.data.d.ts +0 -38
- package/decorators/number/number-decorator.data.d.ts +0 -63
- package/decorators/number/number.decorator.d.ts +0 -7
- package/decorators/object/object-decorator-internal.data.d.ts +0 -23
- package/decorators/object/object-decorator.data.d.ts +0 -42
- package/decorators/object/object.decorator.d.ts +0 -8
- package/decorators/references-many/references-many-decorator-internal.data.d.ts +0 -30
- package/decorators/references-many/references-many-decorator.data.d.ts +0 -63
- package/decorators/references-many/references-many.decorator.d.ts +0 -8
- package/decorators/references-one/references-one-decorator-internal.data.d.ts +0 -16
- package/decorators/references-one/references-one-decorator.data.d.ts +0 -32
- package/decorators/references-one/references-one.decorator.d.ts +0 -8
- package/decorators/string/string-decorator-internal.data.d.ts +0 -56
- package/decorators/string/string-decorator.data.d.ts +0 -116
- package/decorators/string/string.decorator.d.ts +0 -7
- package/default-global-configuration-values.d.ts +0 -13
- package/directives/drag-drop.directive.d.ts +0 -29
- package/directives/dynamic-style-class.directive.d.ts +0 -24
- package/directives/included-in.directive.d.ts +0 -14
- package/directives/number.directive.d.ts +0 -16
- package/directives/password-match.directive.d.ts +0 -14
- package/directives/tooltip.directive.d.ts +0 -42
- package/encapsulation/js-2-xml.utilities.d.ts +0 -14
- package/encapsulation/jszip.utilities.d.ts +0 -12
- package/encapsulation/lodash.utilities.d.ts +0 -60
- package/encapsulation/reflect.utilities.d.ts +0 -59
- package/encapsulation/uuid.utilities.d.ts +0 -10
- package/esm2022/classes/base.builder.mjs +0 -47
- package/esm2022/classes/entity.model.mjs +0 -26
- package/esm2022/components/confirm-dialog/confirm-dialog-data.builder.mjs +0 -57
- package/esm2022/components/confirm-dialog/confirm-dialog-data.mjs +0 -2
- package/esm2022/components/confirm-dialog/confirm-dialog.component.mjs +0 -71
- package/esm2022/components/create-page/create-data.route.mjs +0 -12
- package/esm2022/components/create-page/create-page.component.mjs +0 -276
- package/esm2022/components/create-page/page-create-data.builder.mjs +0 -30
- package/esm2022/components/custom-table/custom-table-configuration.model.mjs +0 -37
- package/esm2022/components/custom-table/custom-table.component.mjs +0 -213
- package/esm2022/components/edit-page/edit-data.route.mjs +0 -12
- package/esm2022/components/edit-page/edit-page.component.mjs +0 -362
- package/esm2022/components/edit-page/page-edit-data.builder.mjs +0 -33
- package/esm2022/components/form/form.component.mjs +0 -106
- package/esm2022/components/input/array/array-date-input/array-date-input.component.mjs +0 -56
- package/esm2022/components/input/array/array-date-range-input/array-date-range-input.component.mjs +0 -82
- package/esm2022/components/input/array/array-date-time-input/array-date-time-input.component.mjs +0 -82
- package/esm2022/components/input/array/array-string-autocomplete-chips/array-string-autocomplete-chips.component.mjs +0 -81
- package/esm2022/components/input/array/array-string-chips-input/array-string-chips-input.component.mjs +0 -74
- package/esm2022/components/input/array/array-table.class.mjs +0 -107
- package/esm2022/components/input/base-input.component.mjs +0 -102
- package/esm2022/components/input/boolean/boolean-checkbox-input/boolean-checkbox-input.component.mjs +0 -29
- package/esm2022/components/input/boolean/boolean-dropdown-input/boolean-dropdown-input.component.mjs +0 -40
- package/esm2022/components/input/boolean/boolean-toggle-input/boolean-toggle-input.component.mjs +0 -29
- package/esm2022/components/input/custom/custom.component.mjs +0 -28
- package/esm2022/components/input/date/date-input/date-input.component.mjs +0 -28
- package/esm2022/components/input/date/date-range-input/date-range-input.component.mjs +0 -84
- package/esm2022/components/input/date/date-time-input/date-time-input.component.mjs +0 -90
- package/esm2022/components/input/file/file-default-input/file-default-input.component.mjs +0 -18
- package/esm2022/components/input/file/file-image-input/file-image-input.component.mjs +0 -104
- package/esm2022/components/input/file/file-input/file-input.component.mjs +0 -228
- package/esm2022/components/input/input.component.mjs +0 -1367
- package/esm2022/components/input/number/number-dropdown-input/number-dropdown-input.component.mjs +0 -65
- package/esm2022/components/input/number/number-input/number-input.component.mjs +0 -23
- package/esm2022/components/input/number/number-slider-input/number-slider-input.component.mjs +0 -27
- package/esm2022/components/input/relations/references-many-input/references-many-input.component.mjs +0 -145
- package/esm2022/components/input/string/string-autocomplete-input/string-autocomplete-input.component.mjs +0 -56
- package/esm2022/components/input/string/string-dropdown-input/string-dropdown-input.component.mjs +0 -65
- package/esm2022/components/input/string/string-input/string-input.component.mjs +0 -23
- package/esm2022/components/input/string/string-password-input/string-password-input.component.mjs +0 -107
- package/esm2022/components/input/string/string-textbox-input/string-textbox-input.component.mjs +0 -24
- package/esm2022/components/table/create-dialog/create-data.builder.mjs +0 -56
- package/esm2022/components/table/create-dialog/create-entity-data.builder.mjs +0 -32
- package/esm2022/components/table/create-dialog/create-entity-data.mjs +0 -2
- package/esm2022/components/table/create-dialog/create-entity-dialog.component.mjs +0 -180
- package/esm2022/components/table/default.actions.mjs +0 -83
- package/esm2022/components/table/display-column-value/base-display-column-value.component.mjs +0 -27
- package/esm2022/components/table/display-column-value/display-column-value.component.mjs +0 -41
- package/esm2022/components/table/edit-dialog/edit-data.builder.mjs +0 -136
- package/esm2022/components/table/edit-dialog/edit-entity-data.mjs +0 -2
- package/esm2022/components/table/edit-dialog/edit-entity-dialog.component.mjs +0 -295
- package/esm2022/components/table/edit-dialog/edit-entity.builder.mjs +0 -39
- package/esm2022/components/table/table-data.builder.mjs +0 -304
- package/esm2022/components/table/table-data.mjs +0 -2
- package/esm2022/components/table/table.component.mjs +0 -324
- package/esm2022/components/tooltip/tooltip.component.mjs +0 -26
- package/esm2022/decorators/array/array-decorator-internal.data.mjs +0 -310
- package/esm2022/decorators/array/array-decorator.data.mjs +0 -51
- package/esm2022/decorators/array/array.decorator.mjs +0 -37
- package/esm2022/decorators/base/base-property.decorator.mjs +0 -17
- package/esm2022/decorators/base/decorator-types.enum.mjs +0 -35
- package/esm2022/decorators/base/dropdown-value.interface.mjs +0 -2
- package/esm2022/decorators/base/property-decorator-internal.data.mjs +0 -101
- package/esm2022/decorators/base/property-decorator.data.mjs +0 -59
- package/esm2022/decorators/boolean/boolean-decorator-internal.data.mjs +0 -45
- package/esm2022/decorators/boolean/boolean-decorator.data.mjs +0 -11
- package/esm2022/decorators/boolean/boolean.decorator.mjs +0 -21
- package/esm2022/decorators/custom/custom-decorator-internal.data.mjs +0 -34
- package/esm2022/decorators/custom/custom-decorator.data.mjs +0 -2
- package/esm2022/decorators/custom/custom.decorator.mjs +0 -13
- package/esm2022/decorators/date/date-decorator-internal.data.mjs +0 -92
- package/esm2022/decorators/date/date-decorator.data.mjs +0 -11
- package/esm2022/decorators/date/date.decorator.mjs +0 -22
- package/esm2022/decorators/file/file-decorator-internal.data.mjs +0 -143
- package/esm2022/decorators/file/file-decorator.data.mjs +0 -59
- package/esm2022/decorators/file/file.decorator.mjs +0 -25
- package/esm2022/decorators/has-many/has-many-decorator-internal.data.mjs +0 -41
- package/esm2022/decorators/has-many/has-many-decorator.data.mjs +0 -2
- package/esm2022/decorators/has-many/has-many.decorator.mjs +0 -13
- package/esm2022/decorators/number/number-decorator-internal.data.mjs +0 -68
- package/esm2022/decorators/number/number-decorator.data.mjs +0 -11
- package/esm2022/decorators/number/number.decorator.mjs +0 -22
- package/esm2022/decorators/object/object-decorator-internal.data.mjs +0 -42
- package/esm2022/decorators/object/object-decorator.data.mjs +0 -22
- package/esm2022/decorators/object/object.decorator.mjs +0 -20
- package/esm2022/decorators/references-many/references-many-decorator-internal.data.mjs +0 -55
- package/esm2022/decorators/references-many/references-many-decorator.data.mjs +0 -2
- package/esm2022/decorators/references-many/references-many.decorator.mjs +0 -13
- package/esm2022/decorators/references-one/references-one-decorator-internal.data.mjs +0 -34
- package/esm2022/decorators/references-one/references-one-decorator.data.mjs +0 -2
- package/esm2022/decorators/references-one/references-one.decorator.mjs +0 -12
- package/esm2022/decorators/string/string-decorator-internal.data.mjs +0 -119
- package/esm2022/decorators/string/string-decorator.data.mjs +0 -11
- package/esm2022/decorators/string/string.decorator.mjs +0 -29
- package/esm2022/default-global-configuration-values.mjs +0 -91
- package/esm2022/directives/drag-drop.directive.mjs +0 -60
- package/esm2022/directives/dynamic-style-class.directive.mjs +0 -51
- package/esm2022/directives/included-in.directive.mjs +0 -33
- package/esm2022/directives/number.directive.mjs +0 -37
- package/esm2022/directives/password-match.directive.mjs +0 -30
- package/esm2022/directives/tooltip.directive.mjs +0 -142
- package/esm2022/encapsulation/js-2-xml.utilities.mjs +0 -17
- package/esm2022/encapsulation/jszip.utilities.mjs +0 -16
- package/esm2022/encapsulation/lodash.utilities.mjs +0 -80
- package/esm2022/encapsulation/reflect.utilities.mjs +0 -79
- package/esm2022/encapsulation/uuid.utilities.mjs +0 -14
- package/esm2022/functions/default-false.function.mjs +0 -9
- package/esm2022/functions/default-style-classes.function.mjs +0 -7
- package/esm2022/functions/default-true.function.mjs +0 -9
- package/esm2022/functions/dropdown-values-to-function.function.mjs +0 -15
- package/esm2022/functions/get-changes-tooltip-content.function.mjs +0 -23
- package/esm2022/functions/get-config-value.function.mjs +0 -14
- package/esm2022/functions/get-validation-error-message.function.mjs +0 -54
- package/esm2022/functions/get-validation-errors-tooltip-content.function.mjs +0 -23
- package/esm2022/functions/is-async-function.function.mjs +0 -9
- package/esm2022/functions/table-column-value-to-sort-value.function.mjs +0 -33
- package/esm2022/global-configuration-values.mjs +0 -27
- package/esm2022/mocks/placeholder-data.png.mjs +0 -3
- package/esm2022/ngx-material-entity.mjs +0 -5
- package/esm2022/public-api.mjs +0 -68
- package/esm2022/services/entity.service.mjs +0 -269
- package/esm2022/services/unsaved-changes.guard.mjs +0 -13
- package/esm2022/utilities/date.utilities.mjs +0 -138
- package/esm2022/utilities/entity.utilities.mjs +0 -611
- package/esm2022/utilities/file.utilities.mjs +0 -172
- package/esm2022/utilities/selection.utilities.mjs +0 -49
- package/esm2022/utilities/validation.utilities.mjs +0 -543
- package/functions/default-false.function.d.ts +0 -6
- package/functions/default-style-classes.function.d.ts +0 -6
- package/functions/default-true.function.d.ts +0 -6
- package/functions/dropdown-values-to-function.function.d.ts +0 -11
- package/functions/get-changes-tooltip-content.function.d.ts +0 -13
- package/functions/get-config-value.function.d.ts +0 -7
- package/functions/get-validation-error-message.function.d.ts +0 -5
- package/functions/get-validation-errors-tooltip-content.function.d.ts +0 -12
- package/functions/is-async-function.function.d.ts +0 -6
- package/functions/table-column-value-to-sort-value.function.d.ts +0 -9
- package/global-configuration-values.d.ts +0 -205
- package/mocks/placeholder-data.png.d.ts +0 -1
- package/public-api.d.ts +0 -60
- package/services/entity.service.d.ts +0 -146
- package/services/unsaved-changes.guard.d.ts +0 -23
- package/utilities/date.utilities.d.ts +0 -92
- package/utilities/entity.utilities.d.ts +0 -236
- package/utilities/file.utilities.d.ts +0 -67
- package/utilities/selection.utilities.d.ts +0 -28
- package/utilities/validation.utilities.d.ts +0 -58
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { BehaviorSubject, firstValueFrom } from 'rxjs';
|
|
2
|
-
import { DecoratorTypes } from '../decorators/base/decorator-types.enum';
|
|
3
|
-
import { LodashUtilities } from '../encapsulation/lodash.utilities';
|
|
4
|
-
import { EntityUtilities } from '../utilities/entity.utilities';
|
|
5
|
-
import { FileUtilities } from '../utilities/file.utilities';
|
|
6
|
-
/**
|
|
7
|
-
* A generic EntityService class.
|
|
8
|
-
* Offers basic CRUD-functionality.
|
|
9
|
-
* You should create a service for every Entity you have.
|
|
10
|
-
* If you extend from this you need to make sure that the extended Service can be injected.
|
|
11
|
-
*/
|
|
12
|
-
export class EntityService {
|
|
13
|
-
http;
|
|
14
|
-
injector;
|
|
15
|
-
/**
|
|
16
|
-
* The default route segment that comes before the id when editing an entity in a separate page, if no extra route has been provided.
|
|
17
|
-
*/
|
|
18
|
-
editBaseRoute = 'entities';
|
|
19
|
-
/**
|
|
20
|
-
* The complete route that is used to create an entity in a separate page, if no extra route has been provided.
|
|
21
|
-
*/
|
|
22
|
-
createBaseRoute = 'entities/create';
|
|
23
|
-
/**
|
|
24
|
-
* The key which holds the id value.
|
|
25
|
-
* @default 'id'
|
|
26
|
-
*/
|
|
27
|
-
idKey = 'id';
|
|
28
|
-
/**
|
|
29
|
-
* A subject of all the entity values.
|
|
30
|
-
* Can be subscribed to when you want to do a specific thing whenever the entities change.
|
|
31
|
-
*/
|
|
32
|
-
entitiesSubject = new BehaviorSubject([]);
|
|
33
|
-
/**
|
|
34
|
-
* When frequently trying to find a single entity by an id (eg. When nesting relations)
|
|
35
|
-
* you might send a lot of unnecessary requests.
|
|
36
|
-
* Therefore the findById method tries to look in the already existing entities first,
|
|
37
|
-
* IF the entities have been requested in the last READ_EXPIRATION_IN_MS milliseconds.
|
|
38
|
-
* @default 900000 (5 minutes)
|
|
39
|
-
*/
|
|
40
|
-
READ_EXPIRATION_IN_MS = 900000;
|
|
41
|
-
/**
|
|
42
|
-
* Gets the entities in an array from the internal entitiesSubject.
|
|
43
|
-
* @returns The current entities in form of an array.
|
|
44
|
-
*/
|
|
45
|
-
get entities() {
|
|
46
|
-
return this.entitiesSubject.value;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* The last time that the entities have been requested from the api.
|
|
50
|
-
*/
|
|
51
|
-
lastRead;
|
|
52
|
-
constructor(http, injector) {
|
|
53
|
-
this.http = http;
|
|
54
|
-
this.injector = injector;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Creates a new Entity and pushes it to the entities array.
|
|
58
|
-
* @param entity - The data of the entity to create.
|
|
59
|
-
* All values that should be omitted will be removed from it inside this method.
|
|
60
|
-
* @param baseUrl - The base url to send the post request to.
|
|
61
|
-
* This can be used if you want to create an entity belonging to another, like "customers/{id}/invoices".
|
|
62
|
-
* @returns A Promise of the created entity.
|
|
63
|
-
*/
|
|
64
|
-
async create(entity, baseUrl = this.baseUrl) {
|
|
65
|
-
const body = EntityUtilities.getWithoutOmitCreateValues(entity);
|
|
66
|
-
const filePropertyKeys = EntityUtilities.getFileProperties(entity);
|
|
67
|
-
if (!filePropertyKeys.length) {
|
|
68
|
-
return await this.createWithJson(body, baseUrl);
|
|
69
|
-
}
|
|
70
|
-
return await this.createWithFormData(body, filePropertyKeys, entity, baseUrl);
|
|
71
|
-
}
|
|
72
|
-
// TODO: Find a way to use blobs with jest
|
|
73
|
-
/* istanbul ignore next */
|
|
74
|
-
/**
|
|
75
|
-
* Imports everything from the provided json file.
|
|
76
|
-
* @param file - The json file to import from.
|
|
77
|
-
* @returns All entities that have been imported.
|
|
78
|
-
*/
|
|
79
|
-
async import(file) {
|
|
80
|
-
const formData = new FormData();
|
|
81
|
-
formData.append('import', file);
|
|
82
|
-
const result = await firstValueFrom(this.http.post(`${this.baseUrl}/import`, formData));
|
|
83
|
-
this.entities.push(...result);
|
|
84
|
-
this.entitiesSubject.next(this.entities);
|
|
85
|
-
return result;
|
|
86
|
-
}
|
|
87
|
-
// TODO: Find a way to use blobs with jest
|
|
88
|
-
/* istanbul ignore next */
|
|
89
|
-
/**
|
|
90
|
-
* Creates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
|
|
91
|
-
* All file values are stored inside their respective property key and their name.
|
|
92
|
-
* Form data is able to handle setting multiple files to the same key.
|
|
93
|
-
* @param body - The body Of the request.
|
|
94
|
-
* @param filePropertyKeys - All property keys that are files and need to be added to the form data.
|
|
95
|
-
* @param entity - The entity to create. This is needed in addition to the body because the body doesn't contain any metadata.
|
|
96
|
-
* @param baseUrl - The base url to send the post request to.
|
|
97
|
-
* This can be used if you want to create an entity belonging to another, like "customers/{id}/invoices".
|
|
98
|
-
* @returns The created entity from the server.
|
|
99
|
-
*/
|
|
100
|
-
async createWithFormData(body, filePropertyKeys, entity, baseUrl = this.baseUrl) {
|
|
101
|
-
const formData = new FormData();
|
|
102
|
-
formData.append('body', JSON.stringify(LodashUtilities.omit(body, filePropertyKeys)));
|
|
103
|
-
for (const key of filePropertyKeys) {
|
|
104
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT);
|
|
105
|
-
if (metadata.multiple) {
|
|
106
|
-
const fileDataValues = body[key];
|
|
107
|
-
for (const value of fileDataValues) {
|
|
108
|
-
formData.append(key, (await FileUtilities.getFileData(value, this.http)).file, value.name);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
const fileData = body[key];
|
|
113
|
-
formData.append(key, (await FileUtilities.getFileData(fileData, this.http)).file, fileData.name);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const e = await firstValueFrom(this.http.post(baseUrl, formData));
|
|
117
|
-
if (!e) {
|
|
118
|
-
throw new Error(`
|
|
119
|
-
The created entity was not returned in the response.
|
|
120
|
-
If you want to provide a logic that allows that
|
|
121
|
-
you need to override the create methods of this class.
|
|
122
|
-
`);
|
|
123
|
-
}
|
|
124
|
-
this.entities.push(e);
|
|
125
|
-
this.entitiesSubject.next(this.entities);
|
|
126
|
-
return e;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Creates the entity with a normal json body in contrast to creating it with form data when the entity contains files.
|
|
130
|
-
* @param body - The body Of the request.
|
|
131
|
-
* @param baseUrl - The base url to send the post request to.
|
|
132
|
-
* This can be used if you want to create an entity belonging to another, like "customers/{id}/invoices".
|
|
133
|
-
* @returns The created entity from the server.
|
|
134
|
-
*/
|
|
135
|
-
async createWithJson(body, baseUrl = this.baseUrl) {
|
|
136
|
-
const e = await firstValueFrom(this.http.post(baseUrl, body));
|
|
137
|
-
if (!e) {
|
|
138
|
-
throw new Error(`
|
|
139
|
-
The created entity was not returned in the response.
|
|
140
|
-
If you want to provide a logic that allows that
|
|
141
|
-
you need to override the create methods of this class.
|
|
142
|
-
`);
|
|
143
|
-
}
|
|
144
|
-
this.entities.push(e);
|
|
145
|
-
this.entitiesSubject.next(this.entities);
|
|
146
|
-
return e;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Gets all existing entities and pushes them to the entities array.
|
|
150
|
-
* @param baseUrl - The base url for the request. Defaults to the baseUrl on the service.
|
|
151
|
-
* @returns A Promise of all received Entities.
|
|
152
|
-
*/
|
|
153
|
-
async read(baseUrl = this.baseUrl) {
|
|
154
|
-
const e = await firstValueFrom(this.http.get(baseUrl));
|
|
155
|
-
this.entitiesSubject.next(e);
|
|
156
|
-
this.lastRead = new Date();
|
|
157
|
-
return e;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Tries to find an entity with the given id.
|
|
161
|
-
* @param id - The id of the entity to find.
|
|
162
|
-
* @returns The found entity.
|
|
163
|
-
*/
|
|
164
|
-
async findById(id) {
|
|
165
|
-
if (this.lastRead == undefined
|
|
166
|
-
|| (Date.now() - this.lastRead.getTime()) > this.READ_EXPIRATION_IN_MS) {
|
|
167
|
-
return firstValueFrom(this.http.get(`${this.baseUrl}/${id}`));
|
|
168
|
-
}
|
|
169
|
-
return this.entities.find(e => e[this.idKey] === id) ?? firstValueFrom(this.http.get(`${this.baseUrl}/${id}`));
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Updates a specific Entity.
|
|
173
|
-
* @param entity - The updated Entity
|
|
174
|
-
* All values that should be omitted will be removed from it inside this method.
|
|
175
|
-
* @param entityPriorChanges - The current Entity.
|
|
176
|
-
* It Is used to get changed values and only update them instead of sending the whole entity data.
|
|
177
|
-
*/
|
|
178
|
-
async update(entity, entityPriorChanges) {
|
|
179
|
-
const filePropertyKeys = EntityUtilities.getFileProperties(entityPriorChanges);
|
|
180
|
-
const body = await this.entityToUpdateRequestBody(entity, entityPriorChanges);
|
|
181
|
-
if (!filePropertyKeys.length) {
|
|
182
|
-
await this.updateWithJson(body, entityPriorChanges[this.idKey]);
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
await this.updateWithFormData(body, filePropertyKeys, entity, entityPriorChanges[this.idKey]);
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Builds the update request body from the given entity before and after its changes.
|
|
189
|
-
* @param entity - The entity with changed values.
|
|
190
|
-
* @param entityPriorChanges - The entity before any changes.
|
|
191
|
-
* @returns A partial of only the changed values.
|
|
192
|
-
*/
|
|
193
|
-
async entityToUpdateRequestBody(entity, entityPriorChanges) {
|
|
194
|
-
return await EntityUtilities.getWithoutOmitUpdateValues(entity, entityPriorChanges, this.http, this.injector);
|
|
195
|
-
}
|
|
196
|
-
// TODO: Find a way to use blobs with jest
|
|
197
|
-
/* istanbul ignore next */
|
|
198
|
-
/**
|
|
199
|
-
* Updates the entity with form data when the entity contains files in contrast to creating it with a normal json body.
|
|
200
|
-
* All file values are stored inside their respective property key and their name.
|
|
201
|
-
* Form data is able to handle setting multiple files to the same key.
|
|
202
|
-
* @param body - The request body. Already contains only properties that have changed.
|
|
203
|
-
* @param filePropertyKeys - The keys of all properties which are files and need to separately be appended to the form data.
|
|
204
|
-
* @param entity - The original entity. Is needed to get the metadata of all the files.
|
|
205
|
-
* @param id - The id of the entity to update.
|
|
206
|
-
*/
|
|
207
|
-
async updateWithFormData(body, filePropertyKeys, entity, id) {
|
|
208
|
-
const formData = new FormData();
|
|
209
|
-
formData.append('body', JSON.stringify(LodashUtilities.omit(body, filePropertyKeys)));
|
|
210
|
-
for (const key of filePropertyKeys) {
|
|
211
|
-
const metadata = EntityUtilities.getPropertyMetadata(entity, key, DecoratorTypes.FILE_DEFAULT);
|
|
212
|
-
if (metadata.multiple) {
|
|
213
|
-
const fileDataValues = body[key];
|
|
214
|
-
for (const value of fileDataValues) {
|
|
215
|
-
formData.append(key, (await FileUtilities.getFileData(value, this.http)).file, value.name);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
const fileData = body[key];
|
|
220
|
-
formData.append(key, (await FileUtilities.getFileData(fileData, this.http)).file, fileData.name);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, formData));
|
|
224
|
-
if (!updatedEntity) {
|
|
225
|
-
// eslint-disable-next-line no-console
|
|
226
|
-
console.warn('The updated entity was not returned in the response. Applying the changes from the request body.');
|
|
227
|
-
for (const key in body) {
|
|
228
|
-
this.entities[this.entities.findIndex(e => e[this.idKey] === id)][key]
|
|
229
|
-
= body[key];
|
|
230
|
-
}
|
|
231
|
-
this.entitiesSubject.next(this.entities);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
|
|
235
|
-
this.entitiesSubject.next(this.entities);
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Updates the entity with a normal json body in contrast to updating it with form data when the entity contains files.
|
|
239
|
-
* @param body - The body of the Request. Has already removed all unnecessary values.
|
|
240
|
-
* @param id - The id of the entity to update.
|
|
241
|
-
*/
|
|
242
|
-
async updateWithJson(body, id) {
|
|
243
|
-
const updatedEntity = await firstValueFrom(this.http.patch(`${this.baseUrl}/${id}`, body));
|
|
244
|
-
if (!updatedEntity) {
|
|
245
|
-
// eslint-disable-next-line no-console
|
|
246
|
-
console.warn('The updated entity was not returned in the response. Applying the changes from the request body.');
|
|
247
|
-
const foundEntity = this.entities[this.entities.findIndex(e => e[this.idKey] === id)];
|
|
248
|
-
for (const key in body) {
|
|
249
|
-
foundEntity[key]
|
|
250
|
-
= body[key];
|
|
251
|
-
}
|
|
252
|
-
this.entitiesSubject.next(this.entities);
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
this.entities[this.entities.findIndex(e => e[this.idKey] === id)] = updatedEntity;
|
|
256
|
-
this.entitiesSubject.next(this.entities);
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Deletes a specific Entity.
|
|
260
|
-
* @param entity - The entity to delete.
|
|
261
|
-
*/
|
|
262
|
-
async delete(entity) {
|
|
263
|
-
await firstValueFrom(this.http.delete(`${this.baseUrl}/${entity[this.idKey]}`));
|
|
264
|
-
// the == comparison instead of === is to catch ids that are numbers.
|
|
265
|
-
this.entities.splice(this.entities.findIndex(e => e[this.idKey] === entity[this.idKey]), 1);
|
|
266
|
-
this.entitiesSubject.next(this.entities);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWF0ZXJpYWwtZW50aXR5L3NyYy9zZXJ2aWNlcy9lbnRpdHkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUd2RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFHekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQWdCLGFBQWE7SUEyREE7SUFBcUM7SUE1Q3BFOztPQUVHO0lBQ00sYUFBYSxHQUFXLFVBQVUsQ0FBQztJQUU1Qzs7T0FFRztJQUNNLGVBQWUsR0FBVyxpQkFBaUIsQ0FBQztJQUVyRDs7O09BR0c7SUFDTSxLQUFLLEdBQXFCLElBQXdCLENBQUM7SUFFNUQ7OztPQUdHO0lBQ00sZUFBZSxHQUFrQyxJQUFJLGVBQWUsQ0FBZSxFQUFFLENBQUMsQ0FBQztJQUVoRzs7Ozs7O09BTUc7SUFDZ0IscUJBQXFCLEdBQVcsTUFBTSxDQUFDO0lBRTFEOzs7T0FHRztJQUNILElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUM7SUFDdEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUSxDQUFRO0lBRWhCLFlBQStCLElBQWdCLEVBQXFCLFFBQTZCO1FBQWxFLFNBQUksR0FBSixJQUFJLENBQVk7UUFBcUIsYUFBUSxHQUFSLFFBQVEsQ0FBcUI7SUFBRyxDQUFDO0lBRXJHOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQWtC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Q0FBQztJQUM3QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFrQjtRQUMzQixNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN0RixxRUFBcUU7UUFDckUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDN0MsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEVudmlyb25tZW50SW5qZWN0b3IgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgZmlyc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQmFzZUVudGl0eVR5cGUgfSBmcm9tICcuLi9jbGFzc2VzL2VudGl0eS5tb2RlbCc7XG5pbXBvcnQgeyBEZWNvcmF0b3JUeXBlcyB9IGZyb20gJy4uL2RlY29yYXRvcnMvYmFzZS9kZWNvcmF0b3ItdHlwZXMuZW51bSc7XG5pbXBvcnQgeyBEZWZhdWx0RmlsZURlY29yYXRvckNvbmZpZ0ludGVybmFsIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9maWxlL2ZpbGUtZGVjb3JhdG9yLWludGVybmFsLmRhdGEnO1xuaW1wb3J0IHsgRmlsZURhdGEgfSBmcm9tICcuLi9kZWNvcmF0b3JzL2ZpbGUvZmlsZS1kZWNvcmF0b3IuZGF0YSc7XG5pbXBvcnQgeyBMb2Rhc2hVdGlsaXRpZXMgfSBmcm9tICcuLi9lbmNhcHN1bGF0aW9uL2xvZGFzaC51dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5VXRpbGl0aWVzIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2VudGl0eS51dGlsaXRpZXMnO1xuaW1wb3J0IHsgRmlsZVV0aWxpdGllcyB9IGZyb20gJy4uL3V0aWxpdGllcy9maWxlLnV0aWxpdGllcyc7XG5cbi8qKlxuICogQSBnZW5lcmljIEVudGl0eVNlcnZpY2UgY2xhc3MuXG4gKiBPZmZlcnMgYmFzaWMgQ1JVRC1mdW5jdGlvbmFsaXR5LlxuICogWW91IHNob3VsZCBjcmVhdGUgYSBzZXJ2aWNlIGZvciBldmVyeSBFbnRpdHkgeW91IGhhdmUuXG4gKiBJZiB5b3UgZXh0ZW5kIGZyb20gdGhpcyB5b3UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgZXh0ZW5kZWQgU2VydmljZSBjYW4gYmUgaW5qZWN0ZWQuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFbnRpdHlTZXJ2aWNlPEVudGl0eVR5cGUgZXh0ZW5kcyBCYXNlRW50aXR5VHlwZTxFbnRpdHlUeXBlPj4ge1xuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIHVybCB1c2VkIGZvciBhcGkgcmVxdWVzdHMuIElmIHUgd2FudCB0byBoYXZlIG1vcmUgY29udHJvbCBvdmVyIHRoaXMsXG4gICAgICogeW91IGNhbiBvdmVycmlkZSB0aGUgY3JlYXRlLCByZWFkLCB1cGRhdGUgYW5kIGRlbGV0ZSBtZXRob2RzLlxuICAgICAqXG4gICAgICogQ3JlYXRlIFNlbmRzIGEgUE9TVC1SZXF1ZXN0IHRvIGJhc2VVcmwuXG4gICAgICpcbiAgICAgKiBSZWFkIFNlbmRzIGEgR0VULVJlcXVlc3QgdG8gYmFzZVVybC5cbiAgICAgKlxuICAgICAqIFVwZGF0ZSBTZW5kcyBhIFBBVENILVJlcXVlc3QgdG8gYmFzZVVybC97aWR9LlxuICAgICAqXG4gICAgICogRGVsZXRlIFNlbmRzIGEgREVMLVJlcXVlc3QgdG8gYmFzZVVybC97aWR9LlxuICAgICAqL1xuICAgIGFic3RyYWN0IHJlYWRvbmx5IGJhc2VVcmw6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IHJvdXRlIHNlZ21lbnQgdGhhdCBjb21lcyBiZWZvcmUgdGhlIGlkIHdoZW4gZWRpdGluZyBhbiBlbnRpdHkgaW4gYSBzZXBhcmF0ZSBwYWdlLCBpZiBubyBleHRyYSByb3V0ZSBoYXMgYmVlbiBwcm92aWRlZC5cbiAgICAgKi9cbiAgICByZWFkb25seSBlZGl0QmFzZVJvdXRlOiBzdHJpbmcgPSAnZW50aXRpZXMnO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbXBsZXRlIHJvdXRlIHRoYXQgaXMgdXNlZCB0byBjcmVhdGUgYW4gZW50aXR5IGluIGEgc2VwYXJhdGUgcGFnZSwgaWYgbm8gZXh0cmEgcm91dGUgaGFzIGJlZW4gcHJvdmlkZWQuXG4gICAgICovXG4gICAgcmVhZG9ubHkgY3JlYXRlQmFzZVJvdXRlOiBzdHJpbmcgPSAnZW50aXRpZXMvY3JlYXRlJztcblxuICAgIC8qKlxuICAgICAqIFRoZSBrZXkgd2hpY2ggaG9sZHMgdGhlIGlkIHZhbHVlLlxuICAgICAqIEBkZWZhdWx0ICdpZCdcbiAgICAgKi9cbiAgICByZWFkb25seSBpZEtleToga2V5b2YgRW50aXR5VHlwZSA9ICdpZCcgYXMga2V5b2YgRW50aXR5VHlwZTtcblxuICAgIC8qKlxuICAgICAqIEEgc3ViamVjdCBvZiBhbGwgdGhlIGVudGl0eSB2YWx1ZXMuXG4gICAgICogQ2FuIGJlIHN1YnNjcmliZWQgdG8gd2hlbiB5b3Ugd2FudCB0byBkbyBhIHNwZWNpZmljIHRoaW5nIHdoZW5ldmVyIHRoZSBlbnRpdGllcyBjaGFuZ2UuXG4gICAgICovXG4gICAgcmVhZG9ubHkgZW50aXRpZXNTdWJqZWN0OiBCZWhhdmlvclN1YmplY3Q8RW50aXR5VHlwZVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RW50aXR5VHlwZVtdPihbXSk7XG5cbiAgICAvKipcbiAgICAgKiBXaGVuIGZyZXF1ZW50bHkgdHJ5aW5nIHRvIGZpbmQgYSBzaW5nbGUgZW50aXR5IGJ5IGFuIGlkIChlZy4gV2hlbiBuZXN0aW5nIHJlbGF0aW9ucylcbiAgICAgKiB5b3UgbWlnaHQgc2VuZCBhIGxvdCBvZiB1bm5lY2Vzc2FyeSByZXF1ZXN0cy5cbiAgICAgKiBUaGVyZWZvcmUgdGhlIGZpbmRCeUlkIG1ldGhvZCB0cmllcyB0byBsb29rIGluIHRoZSBhbHJlYWR5IGV4aXN0aW5nIGVudGl0aWVzIGZpcnN0LFxuICAgICAqIElGIHRoZSBlbnRpdGllcyBoYXZlIGJlZW4gcmVxdWVzdGVkIGluIHRoZSBsYXN0IFJFQURfRVhQSVJBVElPTl9JTl9NUyBtaWxsaXNlY29uZHMuXG4gICAgICogQGRlZmF1bHQgOTAwMDAwICg1IG1pbnV0ZXMpXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IFJFQURfRVhQSVJBVElPTl9JTl9NUzogbnVtYmVyID0gOTAwMDAwO1xuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZW50aXRpZXMgaW4gYW4gYXJyYXkgZnJvbSB0aGUgaW50ZXJuYWwgZW50aXRpZXNTdWJqZWN0LlxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IGVudGl0aWVzIGluIGZvcm0gb2YgYW4gYXJyYXkuXG4gICAgICovXG4gICAgZ2V0IGVudGl0aWVzKCk6IEVudGl0eVR5cGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVudGl0aWVzU3ViamVjdC52YWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbGFzdCB0aW1lIHRoYXQgdGhlIGVudGl0aWVzIGhhdmUgYmVlbiByZXF1ZXN0ZWQgZnJvbSB0aGUgYXBpLlxuICAgICAqL1xuICAgIGxhc3RSZWFkPzogRGF0ZTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBodHRwOiBIdHRwQ2xpZW50LCBwcm90ZWN0ZWQgcmVhZG9ubHkgaW5qZWN0b3I6IEVudmlyb25tZW50SW5qZWN0b3IpIHt9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IEVudGl0eSBhbmQgcHVzaGVzIGl0IHRvIHRoZSBlbnRpdGllcyBhcnJheS5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGRhdGEgb2YgdGhlIGVudGl0eSB0byBjcmVhdGUuXG4gICAgICogQWxsIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBvbWl0dGVkIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIGl0IGluc2lkZSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAcGFyYW0gYmFzZVVybCAtIFRoZSBiYXNlIHVybCB0byBzZW5kIHRoZSBwb3N0IHJlcXVlc3QgdG8uXG4gICAgICogVGhpcyBjYW4gYmUgdXNlZCBpZiB5b3Ugd2FudCB0byBjcmVhdGUgYW4gZW50aXR5IGJlbG9uZ2luZyB0byBhbm90aGVyLCBsaWtlIFwiY3VzdG9tZXJzL3tpZH0vaW52b2ljZXNcIi5cbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2Ugb2YgdGhlIGNyZWF0ZWQgZW50aXR5LlxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZShlbnRpdHk6IEVudGl0eVR5cGUsIGJhc2VVcmw6IHN0cmluZyA9IHRoaXMuYmFzZVVybCk6IFByb21pc2U8RW50aXR5VHlwZT4ge1xuICAgICAgICBjb25zdCBib2R5OiBQYXJ0aWFsPEVudGl0eVR5cGU+ID0gRW50aXR5VXRpbGl0aWVzLmdldFdpdGhvdXRPbWl0Q3JlYXRlVmFsdWVzKGVudGl0eSk7XG4gICAgICAgIGNvbnN0IGZpbGVQcm9wZXJ0eUtleXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdID0gRW50aXR5VXRpbGl0aWVzLmdldEZpbGVQcm9wZXJ0aWVzKGVudGl0eSk7XG4gICAgICAgIGlmICghZmlsZVByb3BlcnR5S2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZVdpdGhKc29uKGJvZHksIGJhc2VVcmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNyZWF0ZVdpdGhGb3JtRGF0YShib2R5LCBmaWxlUHJvcGVydHlLZXlzLCBlbnRpdHksIGJhc2VVcmwpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IEZpbmQgYSB3YXkgdG8gdXNlIGJsb2JzIHdpdGggamVzdFxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgLyoqXG4gICAgICogSW1wb3J0cyBldmVyeXRoaW5nIGZyb20gdGhlIHByb3ZpZGVkIGpzb24gZmlsZS5cbiAgICAgKiBAcGFyYW0gZmlsZSAtIFRoZSBqc29uIGZpbGUgdG8gaW1wb3J0IGZyb20uXG4gICAgICogQHJldHVybnMgQWxsIGVudGl0aWVzIHRoYXQgaGF2ZSBiZWVuIGltcG9ydGVkLlxuICAgICAqL1xuICAgIGFzeW5jIGltcG9ydChmaWxlOiBGaWxlKTogUHJvbWlzZTxFbnRpdHlUeXBlW10+IHtcbiAgICAgICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnaW1wb3J0JywgZmlsZSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogRW50aXR5VHlwZVtdID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5odHRwLnBvc3Q8RW50aXR5VHlwZVtdPihgJHt0aGlzLmJhc2VVcmx9L2ltcG9ydGAsIGZvcm1EYXRhKSk7XG4gICAgICAgIHRoaXMuZW50aXRpZXMucHVzaCguLi5yZXN1bHQpO1xuICAgICAgICB0aGlzLmVudGl0aWVzU3ViamVjdC5uZXh0KHRoaXMuZW50aXRpZXMpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIFRPRE86IEZpbmQgYSB3YXkgdG8gdXNlIGJsb2JzIHdpdGggamVzdFxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyB0aGUgZW50aXR5IHdpdGggZm9ybSBkYXRhIHdoZW4gdGhlIGVudGl0eSBjb250YWlucyBmaWxlcyBpbiBjb250cmFzdCB0byBjcmVhdGluZyBpdCB3aXRoIGEgbm9ybWFsIGpzb24gYm9keS5cbiAgICAgKiBBbGwgZmlsZSB2YWx1ZXMgYXJlIHN0b3JlZCBpbnNpZGUgdGhlaXIgcmVzcGVjdGl2ZSBwcm9wZXJ0eSBrZXkgYW5kIHRoZWlyIG5hbWUuXG4gICAgICogRm9ybSBkYXRhIGlzIGFibGUgdG8gaGFuZGxlIHNldHRpbmcgbXVsdGlwbGUgZmlsZXMgdG8gdGhlIHNhbWUga2V5LlxuICAgICAqIEBwYXJhbSBib2R5IC0gVGhlIGJvZHkgT2YgdGhlIHJlcXVlc3QuXG4gICAgICogQHBhcmFtIGZpbGVQcm9wZXJ0eUtleXMgLSBBbGwgcHJvcGVydHkga2V5cyB0aGF0IGFyZSBmaWxlcyBhbmQgbmVlZCB0byBiZSBhZGRlZCB0byB0aGUgZm9ybSBkYXRhLlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHRvIGNyZWF0ZS4gVGhpcyBpcyBuZWVkZWQgaW4gYWRkaXRpb24gdG8gdGhlIGJvZHkgYmVjYXVzZSB0aGUgYm9keSBkb2Vzbid0IGNvbnRhaW4gYW55IG1ldGFkYXRhLlxuICAgICAqIEBwYXJhbSBiYXNlVXJsIC0gVGhlIGJhc2UgdXJsIHRvIHNlbmQgdGhlIHBvc3QgcmVxdWVzdCB0by5cbiAgICAgKiBUaGlzIGNhbiBiZSB1c2VkIGlmIHlvdSB3YW50IHRvIGNyZWF0ZSBhbiBlbnRpdHkgYmVsb25naW5nIHRvIGFub3RoZXIsIGxpa2UgXCJjdXN0b21lcnMve2lkfS9pbnZvaWNlc1wiLlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIGVudGl0eSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZVdpdGhGb3JtRGF0YShcbiAgICAgICAgYm9keTogUGFydGlhbDxFbnRpdHlUeXBlPixcbiAgICAgICAgZmlsZVByb3BlcnR5S2V5czogKGtleW9mIEVudGl0eVR5cGUpW10sXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSxcbiAgICAgICAgYmFzZVVybDogc3RyaW5nID0gdGhpcy5iYXNlVXJsXG4gICAgKTogUHJvbWlzZTxFbnRpdHlUeXBlPiB7XG4gICAgICAgIGNvbnN0IGZvcm1EYXRhOiBGb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ2JvZHknLCBKU09OLnN0cmluZ2lmeShMb2Rhc2hVdGlsaXRpZXMub21pdChib2R5LCBmaWxlUHJvcGVydHlLZXlzKSkpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBmaWxlUHJvcGVydHlLZXlzKSB7XG4gICAgICAgICAgICBjb25zdCBtZXRhZGF0YTogRGVmYXVsdEZpbGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbCA9IEVudGl0eVV0aWxpdGllcy5nZXRQcm9wZXJ0eU1ldGFkYXRhKFxuICAgICAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgRGVjb3JhdG9yVHlwZXMuRklMRV9ERUZBVUxUXG4gICAgICAgICAgICApIGFzIERlZmF1bHRGaWxlRGVjb3JhdG9yQ29uZmlnSW50ZXJuYWw7XG4gICAgICAgICAgICBpZiAobWV0YWRhdGEubXVsdGlwbGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlRGF0YVZhbHVlczogRmlsZURhdGFbXSA9IGJvZHlba2V5XSBhcyBGaWxlRGF0YVtdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZmlsZURhdGFWYWx1ZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSBhcyBzdHJpbmcsIChhd2FpdCBGaWxlVXRpbGl0aWVzLmdldEZpbGVEYXRhKHZhbHVlLCB0aGlzLmh0dHApKS5maWxlLCB2YWx1ZS5uYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWxlRGF0YTogRmlsZURhdGEgPSBib2R5W2tleV0gYXMgRmlsZURhdGE7XG4gICAgICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKGtleSBhcyBzdHJpbmcsIChhd2FpdCBGaWxlVXRpbGl0aWVzLmdldEZpbGVEYXRhKGZpbGVEYXRhLCB0aGlzLmh0dHApKS5maWxlLCBmaWxlRGF0YS5uYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlOiBFbnRpdHlUeXBlIHwgdW5kZWZpbmVkID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5odHRwLnBvc3Q8RW50aXR5VHlwZSB8IHVuZGVmaW5lZD4oYmFzZVVybCwgZm9ybURhdGEpKTtcbiAgICAgICAgaWYgKCFlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFxuICAgICAgICAgICAgICAgIFRoZSBjcmVhdGVkIGVudGl0eSB3YXMgbm90IHJldHVybmVkIGluIHRoZSByZXNwb25zZS5cbiAgICAgICAgICAgICAgICBJZiB5b3Ugd2FudCB0byBwcm92aWRlIGEgbG9naWMgdGhhdCBhbGxvd3MgdGhhdFxuICAgICAgICAgICAgICAgIHlvdSBuZWVkIHRvIG92ZXJyaWRlIHRoZSBjcmVhdGUgbWV0aG9kcyBvZiB0aGlzIGNsYXNzLlxuICAgICAgICAgICAgYCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbnRpdGllcy5wdXNoKGUpO1xuICAgICAgICB0aGlzLmVudGl0aWVzU3ViamVjdC5uZXh0KHRoaXMuZW50aXRpZXMpO1xuICAgICAgICByZXR1cm4gZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRoZSBlbnRpdHkgd2l0aCBhIG5vcm1hbCBqc29uIGJvZHkgaW4gY29udHJhc3QgdG8gY3JlYXRpbmcgaXQgd2l0aCBmb3JtIGRhdGEgd2hlbiB0aGUgZW50aXR5IGNvbnRhaW5zIGZpbGVzLlxuICAgICAqIEBwYXJhbSBib2R5IC0gVGhlIGJvZHkgT2YgdGhlIHJlcXVlc3QuXG4gICAgICogQHBhcmFtIGJhc2VVcmwgLSBUaGUgYmFzZSB1cmwgdG8gc2VuZCB0aGUgcG9zdCByZXF1ZXN0IHRvLlxuICAgICAqIFRoaXMgY2FuIGJlIHVzZWQgaWYgeW91IHdhbnQgdG8gY3JlYXRlIGFuIGVudGl0eSBiZWxvbmdpbmcgdG8gYW5vdGhlciwgbGlrZSBcImN1c3RvbWVycy97aWR9L2ludm9pY2VzXCIuXG4gICAgICogQHJldHVybnMgVGhlIGNyZWF0ZWQgZW50aXR5IGZyb20gdGhlIHNlcnZlci5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlV2l0aEpzb24oYm9keTogUGFydGlhbDxFbnRpdHlUeXBlPiwgYmFzZVVybDogc3RyaW5nID0gdGhpcy5iYXNlVXJsKTogUHJvbWlzZTxFbnRpdHlUeXBlPiB7XG4gICAgICAgIGNvbnN0IGU6IEVudGl0eVR5cGUgfCB1bmRlZmluZWQgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbSh0aGlzLmh0dHAucG9zdDxFbnRpdHlUeXBlIHwgdW5kZWZpbmVkPihiYXNlVXJsLCBib2R5KSk7XG4gICAgICAgIGlmICghZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBcbiAgICAgICAgICAgICAgICBUaGUgY3JlYXRlZCBlbnRpdHkgd2FzIG5vdCByZXR1cm5lZCBpbiB0aGUgcmVzcG9uc2UuXG4gICAgICAgICAgICAgICAgSWYgeW91IHdhbnQgdG8gcHJvdmlkZSBhIGxvZ2ljIHRoYXQgYWxsb3dzIHRoYXRcbiAgICAgICAgICAgICAgICB5b3UgbmVlZCB0byBvdmVycmlkZSB0aGUgY3JlYXRlIG1ldGhvZHMgb2YgdGhpcyBjbGFzcy5cbiAgICAgICAgICAgIGApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZW50aXRpZXMucHVzaChlKTtcbiAgICAgICAgdGhpcy5lbnRpdGllc1N1YmplY3QubmV4dCh0aGlzLmVudGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgZXhpc3RpbmcgZW50aXRpZXMgYW5kIHB1c2hlcyB0aGVtIHRvIHRoZSBlbnRpdGllcyBhcnJheS5cbiAgICAgKiBAcGFyYW0gYmFzZVVybCAtIFRoZSBiYXNlIHVybCBmb3IgdGhlIHJlcXVlc3QuIERlZmF1bHRzIHRvIHRoZSBiYXNlVXJsIG9uIHRoZSBzZXJ2aWNlLlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSBvZiBhbGwgcmVjZWl2ZWQgRW50aXRpZXMuXG4gICAgICovXG4gICAgYXN5bmMgcmVhZChiYXNlVXJsID0gdGhpcy5iYXNlVXJsKTogUHJvbWlzZTxFbnRpdHlUeXBlW10+IHtcbiAgICAgICAgY29uc3QgZTogRW50aXR5VHlwZVtdID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5odHRwLmdldDxFbnRpdHlUeXBlW10+KGJhc2VVcmwpKTtcbiAgICAgICAgdGhpcy5lbnRpdGllc1N1YmplY3QubmV4dChlKTtcbiAgICAgICAgdGhpcy5sYXN0UmVhZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHJldHVybiBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWVzIHRvIGZpbmQgYW4gZW50aXR5IHdpdGggdGhlIGdpdmVuIGlkLlxuICAgICAqIEBwYXJhbSBpZCAtIFRoZSBpZCBvZiB0aGUgZW50aXR5IHRvIGZpbmQuXG4gICAgICogQHJldHVybnMgVGhlIGZvdW5kIGVudGl0eS5cbiAgICAgKi9cbiAgICBhc3luYyBmaW5kQnlJZChpZDogRW50aXR5VHlwZVtrZXlvZiBFbnRpdHlUeXBlXSk6IFByb21pc2U8RW50aXR5VHlwZT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLmxhc3RSZWFkID09IHVuZGVmaW5lZFxuICAgICAgICAgICAgfHwgKERhdGUubm93KCkgLSB0aGlzLmxhc3RSZWFkLmdldFRpbWUoKSkgPiB0aGlzLlJFQURfRVhQSVJBVElPTl9JTl9NU1xuICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmaXJzdFZhbHVlRnJvbSh0aGlzLmh0dHAuZ2V0PEVudGl0eVR5cGU+KGAke3RoaXMuYmFzZVVybH0vJHtpZH1gKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuZW50aXRpZXMuZmluZChlID0+IGVbdGhpcy5pZEtleV0gPT09IGlkKSA/PyBmaXJzdFZhbHVlRnJvbSh0aGlzLmh0dHAuZ2V0PEVudGl0eVR5cGU+KGAke3RoaXMuYmFzZVVybH0vJHtpZH1gKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyBhIHNwZWNpZmljIEVudGl0eS5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIHVwZGF0ZWQgRW50aXR5XG4gICAgICogQWxsIHZhbHVlcyB0aGF0IHNob3VsZCBiZSBvbWl0dGVkIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIGl0IGluc2lkZSB0aGlzIG1ldGhvZC5cbiAgICAgKiBAcGFyYW0gZW50aXR5UHJpb3JDaGFuZ2VzIC0gVGhlIGN1cnJlbnQgRW50aXR5LlxuICAgICAqIEl0IElzIHVzZWQgdG8gZ2V0IGNoYW5nZWQgdmFsdWVzIGFuZCBvbmx5IHVwZGF0ZSB0aGVtIGluc3RlYWQgb2Ygc2VuZGluZyB0aGUgd2hvbGUgZW50aXR5IGRhdGEuXG4gICAgICovXG4gICAgYXN5bmMgdXBkYXRlKGVudGl0eTogRW50aXR5VHlwZSwgZW50aXR5UHJpb3JDaGFuZ2VzOiBFbnRpdHlUeXBlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGZpbGVQcm9wZXJ0eUtleXM6IChrZXlvZiBFbnRpdHlUeXBlKVtdID0gRW50aXR5VXRpbGl0aWVzLmdldEZpbGVQcm9wZXJ0aWVzKGVudGl0eVByaW9yQ2hhbmdlcyk7XG4gICAgICAgIGNvbnN0IGJvZHk6IFBhcnRpYWw8RW50aXR5VHlwZT4gPSBhd2FpdCB0aGlzLmVudGl0eVRvVXBkYXRlUmVxdWVzdEJvZHkoZW50aXR5LCBlbnRpdHlQcmlvckNoYW5nZXMpO1xuICAgICAgICBpZiAoIWZpbGVQcm9wZXJ0eUtleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZVdpdGhKc29uKGJvZHksIGVudGl0eVByaW9yQ2hhbmdlc1t0aGlzLmlkS2V5XSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVXaXRoRm9ybURhdGEoYm9keSwgZmlsZVByb3BlcnR5S2V5cywgZW50aXR5LCBlbnRpdHlQcmlvckNoYW5nZXNbdGhpcy5pZEtleV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkcyB0aGUgdXBkYXRlIHJlcXVlc3QgYm9keSBmcm9tIHRoZSBnaXZlbiBlbnRpdHkgYmVmb3JlIGFuZCBhZnRlciBpdHMgY2hhbmdlcy5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIGVudGl0eSB3aXRoIGNoYW5nZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBlbnRpdHlQcmlvckNoYW5nZXMgLSBUaGUgZW50aXR5IGJlZm9yZSBhbnkgY2hhbmdlcy5cbiAgICAgKiBAcmV0dXJucyBBIHBhcnRpYWwgb2Ygb25seSB0aGUgY2hhbmdlZCB2YWx1ZXMuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFzeW5jIGVudGl0eVRvVXBkYXRlUmVxdWVzdEJvZHkoZW50aXR5OiBFbnRpdHlUeXBlLCBlbnRpdHlQcmlvckNoYW5nZXM6IEVudGl0eVR5cGUpOiBQcm9taXNlPFBhcnRpYWw8RW50aXR5VHlwZT4+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IEVudGl0eVV0aWxpdGllcy5nZXRXaXRob3V0T21pdFVwZGF0ZVZhbHVlcyhlbnRpdHksIGVudGl0eVByaW9yQ2hhbmdlcywgdGhpcy5odHRwLCB0aGlzLmluamVjdG9yKTtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBGaW5kIGEgd2F5IHRvIHVzZSBibG9icyB3aXRoIGplc3RcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIGVudGl0eSB3aXRoIGZvcm0gZGF0YSB3aGVuIHRoZSBlbnRpdHkgY29udGFpbnMgZmlsZXMgaW4gY29udHJhc3QgdG8gY3JlYXRpbmcgaXQgd2l0aCBhIG5vcm1hbCBqc29uIGJvZHkuXG4gICAgICogQWxsIGZpbGUgdmFsdWVzIGFyZSBzdG9yZWQgaW5zaWRlIHRoZWlyIHJlc3BlY3RpdmUgcHJvcGVydHkga2V5IGFuZCB0aGVpciBuYW1lLlxuICAgICAqIEZvcm0gZGF0YSBpcyBhYmxlIHRvIGhhbmRsZSBzZXR0aW5nIG11bHRpcGxlIGZpbGVzIHRvIHRoZSBzYW1lIGtleS5cbiAgICAgKiBAcGFyYW0gYm9keSAtIFRoZSByZXF1ZXN0IGJvZHkuIEFscmVhZHkgY29udGFpbnMgb25seSBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSBjaGFuZ2VkLlxuICAgICAqIEBwYXJhbSBmaWxlUHJvcGVydHlLZXlzIC0gVGhlIGtleXMgb2YgYWxsIHByb3BlcnRpZXMgd2hpY2ggYXJlIGZpbGVzIGFuZCBuZWVkIHRvIHNlcGFyYXRlbHkgYmUgYXBwZW5kZWQgdG8gdGhlIGZvcm0gZGF0YS5cbiAgICAgKiBAcGFyYW0gZW50aXR5IC0gVGhlIG9yaWdpbmFsIGVudGl0eS4gSXMgbmVlZGVkIHRvIGdldCB0aGUgbWV0YWRhdGEgb2YgYWxsIHRoZSBmaWxlcy5cbiAgICAgKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIGVudGl0eSB0byB1cGRhdGUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFzeW5jIHVwZGF0ZVdpdGhGb3JtRGF0YShcbiAgICAgICAgYm9keTogUGFydGlhbDxFbnRpdHlUeXBlPixcbiAgICAgICAgZmlsZVByb3BlcnR5S2V5czogKGtleW9mIEVudGl0eVR5cGUpW10sXG4gICAgICAgIGVudGl0eTogRW50aXR5VHlwZSxcbiAgICAgICAgaWQ6IEVudGl0eVR5cGVba2V5b2YgRW50aXR5VHlwZV1cbiAgICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgZm9ybURhdGE6IEZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnYm9keScsIEpTT04uc3RyaW5naWZ5KExvZGFzaFV0aWxpdGllcy5vbWl0KGJvZHksIGZpbGVQcm9wZXJ0eUtleXMpKSk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGZpbGVQcm9wZXJ0eUtleXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG1ldGFkYXRhOiBEZWZhdWx0RmlsZURlY29yYXRvckNvbmZpZ0ludGVybmFsID0gRW50aXR5VXRpbGl0aWVzLmdldFByb3BlcnR5TWV0YWRhdGEoXG4gICAgICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICBEZWNvcmF0b3JUeXBlcy5GSUxFX0RFRkFVTFRcbiAgICAgICAgICAgICkgYXMgRGVmYXVsdEZpbGVEZWNvcmF0b3JDb25maWdJbnRlcm5hbDtcbiAgICAgICAgICAgIGlmIChtZXRhZGF0YS5tdWx0aXBsZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVEYXRhVmFsdWVzOiBGaWxlRGF0YVtdID0gYm9keVtrZXldIGFzIEZpbGVEYXRhW107XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBmaWxlRGF0YVZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoa2V5IGFzIHN0cmluZywgKGF3YWl0IEZpbGVVdGlsaXRpZXMuZ2V0RmlsZURhdGEodmFsdWUsIHRoaXMuaHR0cCkpLmZpbGUsIHZhbHVlLm5hbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVEYXRhOiBGaWxlRGF0YSA9IGJvZHlba2V5XSBhcyBGaWxlRGF0YTtcbiAgICAgICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoa2V5IGFzIHN0cmluZywgKGF3YWl0IEZpbGVVdGlsaXRpZXMuZ2V0RmlsZURhdGEoZmlsZURhdGEsIHRoaXMuaHR0cCkpLmZpbGUsIGZpbGVEYXRhLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRFbnRpdHk6IEVudGl0eVR5cGUgfCB1bmRlZmluZWQgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgICAgICAgIHRoaXMuaHR0cC5wYXRjaDxFbnRpdHlUeXBlIHwgdW5kZWZpbmVkPihgJHt0aGlzLmJhc2VVcmx9LyR7aWR9YCwgZm9ybURhdGEpXG4gICAgICAgICk7XG4gICAgICAgIGlmICghdXBkYXRlZEVudGl0eSkge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignVGhlIHVwZGF0ZWQgZW50aXR5IHdhcyBub3QgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlLiBBcHBseWluZyB0aGUgY2hhbmdlcyBmcm9tIHRoZSByZXF1ZXN0IGJvZHkuJyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBib2R5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbnRpdGllc1t0aGlzLmVudGl0aWVzLmZpbmRJbmRleChlID0+IGVbdGhpcy5pZEtleV0gPT09IGlkKV1ba2V5XVxuICAgICAgICAgICAgICAgICAgICA9IGJvZHlba2V5XSBhcyBFbnRpdHlUeXBlW0V4dHJhY3Q8a2V5b2YgRW50aXR5VHlwZSwgc3RyaW5nPl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVudGl0aWVzU3ViamVjdC5uZXh0KHRoaXMuZW50aXRpZXMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZW50aXRpZXNbdGhpcy5lbnRpdGllcy5maW5kSW5kZXgoZSA9PiBlW3RoaXMuaWRLZXldID09PSBpZCldID0gdXBkYXRlZEVudGl0eTtcbiAgICAgICAgdGhpcy5lbnRpdGllc1N1YmplY3QubmV4dCh0aGlzLmVudGl0aWVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSBlbnRpdHkgd2l0aCBhIG5vcm1hbCBqc29uIGJvZHkgaW4gY29udHJhc3QgdG8gdXBkYXRpbmcgaXQgd2l0aCBmb3JtIGRhdGEgd2hlbiB0aGUgZW50aXR5IGNvbnRhaW5zIGZpbGVzLlxuICAgICAqIEBwYXJhbSBib2R5IC0gVGhlIGJvZHkgb2YgdGhlIFJlcXVlc3QuIEhhcyBhbHJlYWR5IHJlbW92ZWQgYWxsIHVubmVjZXNzYXJ5IHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gaWQgLSBUaGUgaWQgb2YgdGhlIGVudGl0eSB0byB1cGRhdGUuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFzeW5jIHVwZGF0ZVdpdGhKc29uKGJvZHk6IFBhcnRpYWw8RW50aXR5VHlwZT4sIGlkOiBFbnRpdHlUeXBlW2tleW9mIEVudGl0eVR5cGVdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRFbnRpdHk6IEVudGl0eVR5cGUgfCB1bmRlZmluZWQgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgICAgICAgIHRoaXMuaHR0cC5wYXRjaDxFbnRpdHlUeXBlIHwgdW5kZWZpbmVkPihgJHt0aGlzLmJhc2VVcmx9LyR7aWR9YCwgYm9keSlcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF1cGRhdGVkRW50aXR5KSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKCdUaGUgdXBkYXRlZCBlbnRpdHkgd2FzIG5vdCByZXR1cm5lZCBpbiB0aGUgcmVzcG9uc2UuIEFwcGx5aW5nIHRoZSBjaGFuZ2VzIGZyb20gdGhlIHJlcXVlc3QgYm9keS4nKTtcbiAgICAgICAgICAgIGNvbnN0IGZvdW5kRW50aXR5OiBFbnRpdHlUeXBlID0gdGhpcy5lbnRpdGllc1t0aGlzLmVudGl0aWVzLmZpbmRJbmRleChlID0+IGVbdGhpcy5pZEtleV0gPT09IGlkKV07XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBib2R5KSB7XG4gICAgICAgICAgICAgICAgZm91bmRFbnRpdHlba2V5XVxuICAgICAgICAgICAgICAgICAgICA9IGJvZHlba2V5XSBhcyBFbnRpdHlUeXBlW0V4dHJhY3Q8a2V5b2YgRW50aXR5VHlwZSwgc3RyaW5nPl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVudGl0aWVzU3ViamVjdC5uZXh0KHRoaXMuZW50aXRpZXMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZW50aXRpZXNbdGhpcy5lbnRpdGllcy5maW5kSW5kZXgoZSA9PiBlW3RoaXMuaWRLZXldID09PSBpZCldID0gdXBkYXRlZEVudGl0eTtcbiAgICAgICAgdGhpcy5lbnRpdGllc1N1YmplY3QubmV4dCh0aGlzLmVudGl0aWVzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgc3BlY2lmaWMgRW50aXR5LlxuICAgICAqIEBwYXJhbSBlbnRpdHkgLSBUaGUgZW50aXR5IHRvIGRlbGV0ZS5cbiAgICAgKi9cbiAgICBhc3luYyBkZWxldGUoZW50aXR5OiBFbnRpdHlUeXBlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuaHR0cC5kZWxldGU8dm9pZD4oYCR7dGhpcy5iYXNlVXJsfS8ke2VudGl0eVt0aGlzLmlkS2V5XX1gKSk7XG4gICAgICAgIC8vIHRoZSA9PSBjb21wYXJpc29uIGluc3RlYWQgb2YgPT09IGlzIHRvIGNhdGNoIGlkcyB0aGF0IGFyZSBudW1iZXJzLlxuICAgICAgICB0aGlzLmVudGl0aWVzLnNwbGljZSh0aGlzLmVudGl0aWVzLmZpbmRJbmRleChlID0+IGVbdGhpcy5pZEtleV0gPT09IGVudGl0eVt0aGlzLmlkS2V5XSksIDEpO1xuICAgICAgICB0aGlzLmVudGl0aWVzU3ViamVjdC5uZXh0KHRoaXMuZW50aXRpZXMpO1xuICAgIH1cbn0iXX0=
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A guard that checks if the user has unsaved changes and then prompts a confirmation from him.
|
|
3
|
-
* Is used by the ngx-material-entity edit and create pages.
|
|
4
|
-
* @param component - The component, can be either an edit or create page.
|
|
5
|
-
* @returns An observable containing whether or not the user can continue.
|
|
6
|
-
*/
|
|
7
|
-
export const UnsavedChangesGuard = async (component) => {
|
|
8
|
-
if (component.canDeactivate()) {
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
return await component.openConfirmNavigationDialog();
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5zYXZlZC1jaGFuZ2VzLmd1YXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LW1hdGVyaWFsLWVudGl0eS9zcmMvc2VydmljZXMvdW5zYXZlZC1jaGFuZ2VzLmd1YXJkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUF3QyxLQUFLLEVBQUUsU0FBNkIsRUFBRSxFQUFFO0lBQzVHLElBQUksU0FBUyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUM7UUFDNUIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNELE9BQU8sTUFBTSxTQUFTLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztBQUN6RCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDYW5EZWFjdGl2YXRlRm4gfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG4vKipcbiAqIEludGVyZmFjZSBkZWZpbml0aW9uIGZvciBhIHBhZ2UgdGhhdCBjYW4gd29yayB3aXRoIHRoZSBVbnNhdmVkQ2hhbmdlc0d1YXJkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFVuc2F2ZWRDaGFuZ2VzUGFnZSB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgcGFnZSBjYW4gYmUgbGVmdCB3aXRob3V0IGNvbmZpcm1hdGlvbiBvZiB1bnNhdmVkIGNoYW5nZXMuXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgdGhlIHBhZ2UgY2FuIGJlIGxlZnQgd2l0aG91dCBjb25maXJtYXRpb24uXG4gICAgICovXG4gICAgY2FuRGVhY3RpdmF0ZTogKCkgPT4gYm9vbGVhbixcbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgY29uZmlybSBkaWFsb2cgZm9yIG5hdmlnYXRpbmcgd2l0aCB1bnNhdmVkIGNoYW5nZXMuXG4gICAgICogQHJldHVybnMgVGhlIHRoZSBwcm9taXNlIGJvb2xlYW4gcmVzdWx0IG9mIHRoZSBjb25maXJtIGRpYWxvZy5cbiAgICAgKi9cbiAgICBvcGVuQ29uZmlybU5hdmlnYXRpb25EaWFsb2c6ICgpID0+IFByb21pc2U8Ym9vbGVhbj5cbn1cblxuLyoqXG4gKiBBIGd1YXJkIHRoYXQgY2hlY2tzIGlmIHRoZSB1c2VyIGhhcyB1bnNhdmVkIGNoYW5nZXMgYW5kIHRoZW4gcHJvbXB0cyBhIGNvbmZpcm1hdGlvbiBmcm9tIGhpbS5cbiAqIElzIHVzZWQgYnkgdGhlIG5neC1tYXRlcmlhbC1lbnRpdHkgZWRpdCBhbmQgY3JlYXRlIHBhZ2VzLlxuICogQHBhcmFtIGNvbXBvbmVudCAtIFRoZSBjb21wb25lbnQsIGNhbiBiZSBlaXRoZXIgYW4gZWRpdCBvciBjcmVhdGUgcGFnZS5cbiAqIEByZXR1cm5zIEFuIG9ic2VydmFibGUgY29udGFpbmluZyB3aGV0aGVyIG9yIG5vdCB0aGUgdXNlciBjYW4gY29udGludWUuXG4gKi9cbmV4cG9ydCBjb25zdCBVbnNhdmVkQ2hhbmdlc0d1YXJkOiBDYW5EZWFjdGl2YXRlRm48VW5zYXZlZENoYW5nZXNQYWdlPiA9IGFzeW5jIChjb21wb25lbnQ6IFVuc2F2ZWRDaGFuZ2VzUGFnZSkgPT4ge1xuICAgIGlmIChjb21wb25lbnQuY2FuRGVhY3RpdmF0ZSgpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gYXdhaXQgY29tcG9uZW50Lm9wZW5Db25maXJtTmF2aWdhdGlvbkRpYWxvZygpO1xufTsiXX0=
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { LodashUtilities } from '../encapsulation/lodash.utilities';
|
|
2
|
-
import { defaultTrue } from '../functions/default-true.function';
|
|
3
|
-
const DAY_IN_MS = 1000 * 60 * 60 * 24;
|
|
4
|
-
/**
|
|
5
|
-
* Contains Helper Functions for handling date properties.
|
|
6
|
-
*/
|
|
7
|
-
export class DateUtilities {
|
|
8
|
-
/**
|
|
9
|
-
* The default filter function to user when none was provided by the user.
|
|
10
|
-
*/
|
|
11
|
-
static defaultDateFilter = defaultTrue;
|
|
12
|
-
/**
|
|
13
|
-
* Gets the given value as a date value.
|
|
14
|
-
* @param value - The value to get as a date.
|
|
15
|
-
* @returns The given value as a date.
|
|
16
|
-
*/
|
|
17
|
-
static asDate(value) {
|
|
18
|
-
return value;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Gets the default times used by the DateTime picker when nothing is specified by the user.
|
|
22
|
-
* @param format - The time format. Defaults to 24.
|
|
23
|
-
* @param minuteSteps - The steps from one time value to the next. Defaults to 30.
|
|
24
|
-
* @returns Times in the 24 hour format from 0:00 until 23:30 in 30 minute steps.
|
|
25
|
-
*/
|
|
26
|
-
static getDefaultTimes(format = 24, minuteSteps = 30) {
|
|
27
|
-
const res = [{ displayName: '-', value: undefined }];
|
|
28
|
-
for (let hour = 0; hour < 24; hour++) {
|
|
29
|
-
for (let minute = 0; minute < 60; minute += minuteSteps) {
|
|
30
|
-
res.push(DateUtilities.getTimeDropdownValue(format, hour, minute));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return res;
|
|
34
|
-
}
|
|
35
|
-
static getTimeDropdownValue(format, hour, minute) {
|
|
36
|
-
const displayHour = DateUtilities.getFormattedHour(format, LodashUtilities.cloneDeep(hour));
|
|
37
|
-
const displayMinute = DateUtilities.getFormattedMinute(format, hour, minute);
|
|
38
|
-
return {
|
|
39
|
-
displayName: `${displayHour}:${displayMinute}`,
|
|
40
|
-
value: {
|
|
41
|
-
hours: hour,
|
|
42
|
-
minutes: minute
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
static getFormattedHour(format, hour) {
|
|
47
|
-
if (format === 12 && hour > 12) {
|
|
48
|
-
hour -= 12;
|
|
49
|
-
}
|
|
50
|
-
return hour;
|
|
51
|
-
}
|
|
52
|
-
static getFormattedMinute(format, hour, minute) {
|
|
53
|
-
let res = `${minute}`;
|
|
54
|
-
if (format === 12) {
|
|
55
|
-
res = hour > 12 ? `${minute} PM` : `${minute} AM`;
|
|
56
|
-
}
|
|
57
|
-
if (minute.toString().length === 1) {
|
|
58
|
-
res = '0'.concat(res);
|
|
59
|
-
}
|
|
60
|
-
return res;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Gets the Time object from the given date.
|
|
64
|
-
* @param value - The date to get the time object from.
|
|
65
|
-
* @returns The Time object build from the date value.
|
|
66
|
-
*/
|
|
67
|
-
static getTimeFromDate(value) {
|
|
68
|
-
if (!value) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
hours: new Date(value).getHours(),
|
|
73
|
-
minutes: new Date(value).getMinutes()
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Gets the dates between the two given gates. Does additional filtering based on the provided DateRange metadata.
|
|
78
|
-
* @param startDate - The start date.
|
|
79
|
-
* @param endDate - The end date.
|
|
80
|
-
* @param filter - The custom filter from the metadata.
|
|
81
|
-
* @returns All dates between the two provided dates. Includes start and end date.
|
|
82
|
-
*/
|
|
83
|
-
static getDatesBetween(startDate, endDate, filter) {
|
|
84
|
-
const clonedStartDate = new Date(startDate);
|
|
85
|
-
const res = [];
|
|
86
|
-
while (clonedStartDate.getFullYear() < endDate.getFullYear()
|
|
87
|
-
|| clonedStartDate.getMonth() < endDate.getMonth()
|
|
88
|
-
|| clonedStartDate.getDate() <= endDate.getDate()) {
|
|
89
|
-
res.push(new Date(clonedStartDate));
|
|
90
|
-
clonedStartDate.setTime(clonedStartDate.getTime() + DAY_IN_MS);
|
|
91
|
-
}
|
|
92
|
-
return filter ? res.filter(d => filter(d)) : res;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Get all valid times for the dropdown of a datetime property.
|
|
96
|
-
* @param times - All given times to filter.
|
|
97
|
-
* @param date - The date of the datetime.
|
|
98
|
-
* @param min - The function that defines the minimum time.
|
|
99
|
-
* @param max - The function that defines the maximum time.
|
|
100
|
-
* @param filter - A filter function to do more specific time filtering. This could be e.g. The removal of lunch breaks.
|
|
101
|
-
* @returns All valid dropdown values for the datetime property.
|
|
102
|
-
*/
|
|
103
|
-
static getValidTimesForDropdown(times, date, min, max, filter) {
|
|
104
|
-
if (min) {
|
|
105
|
-
const minTime = min(date);
|
|
106
|
-
times = times.filter(t => !t.value
|
|
107
|
-
|| t.value.hours > minTime.hours
|
|
108
|
-
|| (t.value.hours === minTime.hours
|
|
109
|
-
&& t.value.minutes >= minTime.minutes));
|
|
110
|
-
}
|
|
111
|
-
if (max) {
|
|
112
|
-
const maxTime = max(date);
|
|
113
|
-
times = times.filter(t => !t.value
|
|
114
|
-
|| t.value.hours < maxTime.hours
|
|
115
|
-
|| (t.value.hours === maxTime.hours
|
|
116
|
-
&& t.value.minutes <= maxTime.minutes));
|
|
117
|
-
}
|
|
118
|
-
if (filter) {
|
|
119
|
-
times = times.filter(t => !t.value || filter(t.value));
|
|
120
|
-
}
|
|
121
|
-
return times;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Checks if the time object has processable hours and minutes properties.
|
|
125
|
-
* Doesn't check custom validators like min/max from the metadata configuration.
|
|
126
|
-
* @param time - The time to check.
|
|
127
|
-
* @returns Whether or not the time object is unprocessable.
|
|
128
|
-
*/
|
|
129
|
-
static timeIsUnprocessable(time) {
|
|
130
|
-
return time?.hours == undefined
|
|
131
|
-
|| typeof time.hours !== 'number'
|
|
132
|
-
|| Number.isNaN(time.hours)
|
|
133
|
-
|| time.minutes == undefined
|
|
134
|
-
|| typeof time.minutes !== 'number'
|
|
135
|
-
|| Number.isNaN(time.minutes);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS51dGlsaXRpZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbWF0ZXJpYWwtZW50aXR5L3NyYy91dGlsaXRpZXMvZGF0ZS51dGlsaXRpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUVqRSxNQUFNLFNBQVMsR0FBVyxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUEyQzlDOztHQUVHO0FBQ0gsTUFBTSxPQUFnQixhQUFhO0lBRS9COztPQUVHO0lBQ0gsTUFBTSxDQUFDLGlCQUFpQixHQUEwQyxXQUFXLENBQUM7SUFFOUU7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBYztRQUN4QixPQUFPLEtBQWEsQ0FBQztJQUN6QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsZUFBZSxDQUFDLFNBQWtCLEVBQUUsRUFBRSxjQUEyQixFQUFFO1FBQ3RFLE1BQU0sR0FBRyxHQUEwQixDQUFDLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBNEIsRUFBRSxDQUFDLENBQUM7UUFDL0YsS0FBSyxJQUFJLElBQUksR0FBUyxDQUFDLEVBQUUsSUFBSSxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ3pDLEtBQUssSUFBSSxNQUFNLEdBQVcsQ0FBQyxFQUFFLE1BQU0sR0FBRyxFQUFFLEVBQUUsTUFBTSxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUM5RCxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsSUFBWSxFQUFFLE1BQWdCLENBQUMsQ0FBQyxDQUFDO1lBQ3pGLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxH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QztJQUNqQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsbUJBQW1CLENBQUMsSUFBVztRQUNsQyxPQUFPLElBQUksRUFBRSxLQUFLLElBQUksU0FBUztlQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLEtBQUssUUFBUTtlQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7ZUFDeEIsSUFBSSxDQUFDLE9BQU8sSUFBSSxTQUFTO2VBQ3pCLE9BQU8sSUFBSSxDQUFDLE9BQU8sS0FBSyxRQUFRO2VBQ2hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlRmlsdGVyRm4gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kYXRlcGlja2VyJztcblxuaW1wb3J0IHsgRHJvcGRvd25WYWx1ZSB9IGZyb20gJy4uL2RlY29yYXRvcnMvYmFzZS9kcm9wZG93bi12YWx1ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTG9kYXNoVXRpbGl0aWVzIH0gZnJvbSAnLi4vZW5jYXBzdWxhdGlvbi9sb2Rhc2gudXRpbGl0aWVzJztcbmltcG9ydCB7IGRlZmF1bHRUcnVlIH0gZnJvbSAnLi4vZnVuY3Rpb25zL2RlZmF1bHQtdHJ1ZS5mdW5jdGlvbic7XG5cbmNvbnN0IERBWV9JTl9NUzogbnVtYmVyID0gMTAwMCAqIDYwICogNjAgKiAyNDtcblxuLyoqXG4gKiBIZWxwZXIgdHlwZSBmb3IgaG91cnMgYW5kIG1pbnV0ZXMuXG4gKi9cbnR5cGUgRW51bWVyYXRlPE4gZXh0ZW5kcyBudW1iZXIsIEFjYyBleHRlbmRzIG51bWJlcltdID0gW10+ID0gQWNjWydsZW5ndGgnXSBleHRlbmRzIE5cbiAgICA/IEFjY1tudW1iZXJdXG4gICAgOiBFbnVtZXJhdGU8TiwgWy4uLkFjYywgQWNjWydsZW5ndGgnXV0+O1xuXG4vKipcbiAqIEhlbHBlciB0eXBlIGZvciBob3VycyBhbmQgbWludXRlcy5cbiAqL1xudHlwZSBSYW5nZTxGIGV4dGVuZHMgbnVtYmVyLCBUIGV4dGVuZHMgbnVtYmVyPiA9IEV4Y2x1ZGU8RW51bWVyYXRlPFQ+LCBFbnVtZXJhdGU8Rj4+O1xuXG4vKipcbiAqIFRoZSBwb3NzaWJsZSBob3VyIHZhbHVlcy4gUmFuZ2VzIGZyb20gMCB0byAyMy5cbiAqL1xuZXhwb3J0IHR5cGUgSG91ciA9IFJhbmdlPDAsIDI0PjtcblxuLyoqXG4gKiBUaGUgcG9zc2libGUgbWludXRlIHZhbHVlcy4gUmFuZ2VzIGZyb20gMCB0byA1OS5cbiAqL1xuZXhwb3J0IHR5cGUgTWludXRlID0gUmFuZ2U8MCwgNjA+O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSB0aW1lIHZhbHVlIHdpdGggaG91cnMgYW5kIG1pbnV0ZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFRpbWUgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIGhvdXJzIGluIHRoZSAyNCBob3VyIGZvcm1hdC5cbiAgICAgKi9cbiAgICBob3VyczogSG91cixcbiAgICAvKipcbiAgICAgKiBUaGUgbWludXRlcyBvZiB0aGUgdGltZS5cbiAgICAgKi9cbiAgICBtaW51dGVzOiBNaW51dGVcbn07XG5cbi8qKlxuICogVmFsaWQgc3RlcHMgZnJvbSBvbmUgdGltZSB2YWx1ZSB0byB0aGUgbmV4dC4gTmVlZHMgdG8gYmUgYWJsZSB0byBkaXZpZGUgNjAgbWludXRlcyB3aXRob3V0IHJlbWFpbmRlci5cbiAqL1xudHlwZSBNaW51dGVTdGVwcyA9IDEgfCAyIHwgMyB8IDQgfCA1IHwgNiB8IDEwIHwgMTIgfCAxNSB8IDIwIHwgMzAgfCA2MDtcblxuLyoqXG4gKiBDb250YWlucyBIZWxwZXIgRnVuY3Rpb25zIGZvciBoYW5kbGluZyBkYXRlIHByb3BlcnRpZXMuXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBEYXRlVXRpbGl0aWVzIHtcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IGZpbHRlciBmdW5jdGlvbiB0byB1c2VyIHdoZW4gbm9uZSB3YXMgcHJvdmlkZWQgYnkgdGhlIHVzZXIuXG4gICAgICovXG4gICAgc3RhdGljIGRlZmF1bHREYXRlRmlsdGVyOiBEYXRlRmlsdGVyRm48RGF0ZSB8IG51bGwgfCB1bmRlZmluZWQ+ID0gZGVmYXVsdFRydWU7XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBnaXZlbiB2YWx1ZSBhcyBhIGRhdGUgdmFsdWUuXG4gICAgICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIGdldCBhcyBhIGRhdGUuXG4gICAgICogQHJldHVybnMgVGhlIGdpdmVuIHZhbHVlIGFzIGEgZGF0ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgYXNEYXRlKHZhbHVlOiB1bmtub3duKTogRGF0ZSB7XG4gICAgICAgIHJldHVybiB2YWx1ZSBhcyBEYXRlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGRlZmF1bHQgdGltZXMgdXNlZCBieSB0aGUgRGF0ZVRpbWUgcGlja2VyIHdoZW4gbm90aGluZyBpcyBzcGVjaWZpZWQgYnkgdGhlIHVzZXIuXG4gICAgICogQHBhcmFtIGZvcm1hdCAtIFRoZSB0aW1lIGZvcm1hdC4gRGVmYXVsdHMgdG8gMjQuXG4gICAgICogQHBhcmFtIG1pbnV0ZVN0ZXBzIC0gVGhlIHN0ZXBzIGZyb20gb25lIHRpbWUgdmFsdWUgdG8gdGhlIG5leHQuIERlZmF1bHRzIHRvIDMwLlxuICAgICAqIEByZXR1cm5zIFRpbWVzIGluIHRoZSAyNCBob3VyIGZvcm1hdCBmcm9tIDA6MDAgdW50aWwgMjM6MzAgaW4gMzAgbWludXRlIHN0ZXBzLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXREZWZhdWx0VGltZXMoZm9ybWF0OiAxMiB8IDI0ID0gMjQsIG1pbnV0ZVN0ZXBzOiBNaW51dGVTdGVwcyA9IDMwKTogRHJvcGRvd25WYWx1ZTxUaW1lPltdIHtcbiAgICAgICAgY29uc3QgcmVzOiBEcm9wZG93blZhbHVlPFRpbWU+W10gPSBbeyBkaXNwbGF5TmFtZTogJy0nLCB2YWx1ZTogdW5kZWZpbmVkIGFzIHVua25vd24gYXMgVGltZSB9XTtcbiAgICAgICAgZm9yIChsZXQgaG91cjogSG91ciA9IDA7IGhvdXIgPCAyNDsgaG91cisrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBtaW51dGU6IE1pbnV0ZSA9IDA7IG1pbnV0ZSA8IDYwOyBtaW51dGUgKz0gbWludXRlU3RlcHMpIHtcbiAgICAgICAgICAgICAgICByZXMucHVzaChEYXRlVXRpbGl0aWVzLmdldFRpbWVEcm9wZG93blZhbHVlKGZvcm1hdCwgaG91ciBhcyBIb3VyLCBtaW51dGUgYXMgTWludXRlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRUaW1lRHJvcGRvd25WYWx1ZShmb3JtYXQ6IDEyIHwgMjQsIGhvdXI6IEhvdXIsIG1pbnV0ZTogTWludXRlKTogRHJvcGRvd25WYWx1ZTxUaW1lPiB7XG4gICAgICAgIGNvbnN0IGRpc3BsYXlIb3VyOiBudW1iZXIgPSBEYXRlVXRpbGl0aWVzLmdldEZvcm1hdHRlZEhvdXIoZm9ybWF0LCBMb2Rhc2hVdGlsaXRpZXMuY2xvbmVEZWVwKGhvdXIpKTtcbiAgICAgICAgY29uc3QgZGlzcGxheU1pbnV0ZTogc3RyaW5nID0gRGF0ZVV0aWxpdGllcy5nZXRGb3JtYXR0ZWRNaW51dGUoZm9ybWF0LCBob3VyLCBtaW51dGUpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGlzcGxheU5hbWU6IGAke2Rpc3BsYXlIb3VyfToke2Rpc3BsYXlNaW51dGV9YCxcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgICAgaG91cnM6IGhvdXIsXG4gICAgICAgICAgICAgICAgbWludXRlczogbWludXRlXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ2V0Rm9ybWF0dGVkSG91cihmb3JtYXQ6IDEyIHwgMjQsIGhvdXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGlmIChmb3JtYXQgPT09IDEyICYmIGhvdXIgPiAxMikge1xuICAgICAgICAgICAgaG91ciAtPSAxMjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaG91cjtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRGb3JtYXR0ZWRNaW51dGUoZm9ybWF0OiAxMiB8IDI0LCBob3VyOiBudW1iZXIsIG1pbnV0ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICAgICAgbGV0IHJlczogc3RyaW5nID0gYCR7bWludXRlfWA7XG4gICAgICAgIGlmIChmb3JtYXQgPT09IDEyKSB7XG4gICAgICAgICAgICByZXMgPSBob3VyID4gMTIgPyBgJHttaW51dGV9IFBNYCA6IGAke21pbnV0ZX0gQU1gO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtaW51dGUudG9TdHJpbmcoKS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHJlcyA9ICcwJy5jb25jYXQocmVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIFRpbWUgb2JqZWN0IGZyb20gdGhlIGdpdmVuIGRhdGUuXG4gICAgICogQHBhcmFtIHZhbHVlIC0gVGhlIGRhdGUgdG8gZ2V0IHRoZSB0aW1lIG9iamVjdCBmcm9tLlxuICAgICAqIEByZXR1cm5zIFRoZSBUaW1lIG9iamVjdCBidWlsZCBmcm9tIHRoZSBkYXRlIHZhbHVlLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRUaW1lRnJvbURhdGUodmFsdWU/OiBEYXRlKTogVGltZSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhvdXJzOiBuZXcgRGF0ZSh2YWx1ZSkuZ2V0SG91cnMoKSBhcyBIb3VyLFxuICAgICAgICAgICAgbWludXRlczogbmV3IERhdGUodmFsdWUpLmdldE1pbnV0ZXMoKSBhcyBNaW51dGVcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBkYXRlcyBiZXR3ZWVuIHRoZSB0d28gZ2l2ZW4gZ2F0ZXMuIERvZXMgYWRkaXRpb25hbCBmaWx0ZXJpbmcgYmFzZWQgb24gdGhlIHByb3ZpZGVkIERhdGVSYW5nZSBtZXRhZGF0YS5cbiAgICAgKiBAcGFyYW0gc3RhcnREYXRlIC0gVGhlIHN0YXJ0IGRhdGUuXG4gICAgICogQHBhcmFtIGVuZERhdGUgLSBUaGUgZW5kIGRhdGUuXG4gICAgICogQHBhcmFtIGZpbHRlciAtIFRoZSBjdXN0b20gZmlsdGVyIGZyb20gdGhlIG1ldGFkYXRhLlxuICAgICAqIEByZXR1cm5zIEFsbCBkYXRlcyBiZXR3ZWVuIHRoZSB0d28gcHJvdmlkZWQgZGF0ZXMuIEluY2x1ZGVzIHN0YXJ0IGFuZCBlbmQgZGF0ZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RGF0ZXNCZXR3ZWVuKHN0YXJ0RGF0ZTogRGF0ZSwgZW5kRGF0ZTogRGF0ZSwgZmlsdGVyPzogRGF0ZUZpbHRlckZuPERhdGU+KTogRGF0ZVtdIHtcbiAgICAgICAgY29uc3QgY2xvbmVkU3RhcnREYXRlOiBEYXRlID0gbmV3IERhdGUoc3RhcnREYXRlKTtcbiAgICAgICAgY29uc3QgcmVzOiBEYXRlW10gPSBbXTtcbiAgICAgICAgd2hpbGUgKFxuICAgICAgICAgICAgY2xvbmVkU3RhcnREYXRlLmdldEZ1bGxZZWFyKCkgPCBlbmREYXRlLmdldEZ1bGxZZWFyKClcbiAgICAgICAgICAgIHx8IGNsb25lZFN0YXJ0RGF0ZS5nZXRNb250aCgpIDwgZW5kRGF0ZS5nZXRNb250aCgpXG4gICAgICAgICAgICB8fCBjbG9uZWRTdGFydERhdGUuZ2V0RGF0ZSgpIDw9IGVuZERhdGUuZ2V0RGF0ZSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmVzLnB1c2gobmV3IERhdGUoY2xvbmVkU3RhcnREYXRlKSk7XG4gICAgICAgICAgICBjbG9uZWRTdGFydERhdGUuc2V0VGltZShjbG9uZWRTdGFydERhdGUuZ2V0VGltZSgpICsgREFZX0lOX01TKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsdGVyID8gcmVzLmZpbHRlcihkID0+IGZpbHRlcihkKSkgOiByZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGFsbCB2YWxpZCB0aW1lcyBmb3IgdGhlIGRyb3Bkb3duIG9mIGEgZGF0ZXRpbWUgcHJvcGVydHkuXG4gICAgICogQHBhcmFtIHRpbWVzIC0gQWxsIGdpdmVuIHRpbWVzIHRvIGZpbHRlci5cbiAgICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIG9mIHRoZSBkYXRldGltZS5cbiAgICAgKiBAcGFyYW0gbWluIC0gVGhlIGZ1bmN0aW9uIHRoYXQgZGVmaW5lcyB0aGUgbWluaW11bSB0aW1lLlxuICAgICAqIEBwYXJhbSBtYXggLSBUaGUgZnVuY3Rpb24gdGhhdCBkZWZpbmVzIHRoZSBtYXhpbXVtIHRpbWUuXG4gICAgICogQHBhcmFtIGZpbHRlciAtIEEgZmlsdGVyIGZ1bmN0aW9uIHRvIGRvIG1vcmUgc3BlY2lmaWMgdGltZSBmaWx0ZXJpbmcuIFRoaXMgY291bGQgYmUgZS5nLiBUaGUgcmVtb3ZhbCBvZiBsdW5jaCBicmVha3MuXG4gICAgICogQHJldHVybnMgQWxsIHZhbGlkIGRyb3Bkb3duIHZhbHVlcyBmb3IgdGhlIGRhdGV0aW1lIHByb3BlcnR5LlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRWYWxpZFRpbWVzRm9yRHJvcGRvd24oXG4gICAgICAgIHRpbWVzOiBEcm9wZG93blZhbHVlPFRpbWUgfCB1bmRlZmluZWQ+W10sXG4gICAgICAgIGRhdGU/OiBEYXRlLFxuICAgICAgICBtaW4/OiAoZGF0ZT86IERhdGUpID0+IFRpbWUsXG4gICAgICAgIG1heD86IChkYXRlPzogRGF0ZSkgPT4gVGltZSxcbiAgICAgICAgZmlsdGVyPzogKCh0aW1lOiBUaW1lKSA9PiBib29sZWFuKSB8ICgoKSA9PiBib29sZWFuKVxuICAgICk6IERyb3Bkb3duVmFsdWU8VGltZSB8IHVuZGVmaW5lZD5bXSB7XG4gICAgICAgIGlmIChtaW4pIHtcbiAgICAgICAgICAgIGNvbnN0IG1pblRpbWU6IFRpbWUgPSBtaW4oZGF0ZSk7XG4gICAgICAgICAgICB0aW1lcyA9IHRpbWVzLmZpbHRlcih0ID0+ICF0LnZhbHVlXG4gICAgICAgICAgICAgICAgfHwgdC52YWx1ZS5ob3VycyA+IG1pblRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICB8fCAoXG4gICAgICAgICAgICAgICAgICAgIHQudmFsdWUuaG91cnMgPT09IG1pblRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICAgICAgJiYgdC52YWx1ZS5taW51dGVzID49IG1pblRpbWUubWludXRlc1xuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXgpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heFRpbWU6IFRpbWUgPSBtYXgoZGF0ZSk7XG4gICAgICAgICAgICB0aW1lcyA9IHRpbWVzLmZpbHRlcih0ID0+ICF0LnZhbHVlXG4gICAgICAgICAgICAgICAgfHwgdC52YWx1ZS5ob3VycyA8IG1heFRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICB8fCAoXG4gICAgICAgICAgICAgICAgICAgIHQudmFsdWUuaG91cnMgPT09IG1heFRpbWUuaG91cnNcbiAgICAgICAgICAgICAgICAgICAgJiYgdC52YWx1ZS5taW51dGVzIDw9IG1heFRpbWUubWludXRlc1xuICAgICAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICAgIHRpbWVzID0gdGltZXMuZmlsdGVyKHQgPT4gIXQudmFsdWUgfHwgZmlsdGVyKHQudmFsdWUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aW1lcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIHRpbWUgb2JqZWN0IGhhcyBwcm9jZXNzYWJsZSBob3VycyBhbmQgbWludXRlcyBwcm9wZXJ0aWVzLlxuICAgICAqIERvZXNuJ3QgY2hlY2sgY3VzdG9tIHZhbGlkYXRvcnMgbGlrZSBtaW4vbWF4IGZyb20gdGhlIG1ldGFkYXRhIGNvbmZpZ3VyYXRpb24uXG4gICAgICogQHBhcmFtIHRpbWUgLSBUaGUgdGltZSB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgdGltZSBvYmplY3QgaXMgdW5wcm9jZXNzYWJsZS5cbiAgICAgKi9cbiAgICBzdGF0aWMgdGltZUlzVW5wcm9jZXNzYWJsZSh0aW1lPzogVGltZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGltZT8uaG91cnMgPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICB8fCB0eXBlb2YgdGltZS5ob3VycyAhPT0gJ251bWJlcidcbiAgICAgICAgICAgIHx8IE51bWJlci5pc05hTih0aW1lLmhvdXJzKVxuICAgICAgICAgICAgfHwgdGltZS5taW51dGVzID09IHVuZGVmaW5lZFxuICAgICAgICAgICAgfHwgdHlwZW9mIHRpbWUubWludXRlcyAhPT0gJ251bWJlcidcbiAgICAgICAgICAgIHx8IE51bWJlci5pc05hTih0aW1lLm1pbnV0ZXMpO1xuICAgIH1cbn0iXX0=
|