@ethlete/query 4.2.0 → 4.2.2

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.
Files changed (68) hide show
  1. package/esm2022/lib/directives/infinity-query-trigger.directive.mjs +55 -0
  2. package/esm2022/lib/directives/infinity-query.directive.mjs +176 -0
  3. package/esm2022/lib/directives/query.directive.mjs +113 -0
  4. package/esm2022/lib/query-form/query-form.mjs +173 -0
  5. package/{esm2020 → esm2022}/lib/query-form/query-form.types.mjs +1 -1
  6. package/{fesm2020 → fesm2022}/ethlete-query.mjs +35 -19
  7. package/fesm2022/ethlete-query.mjs.map +1 -0
  8. package/lib/auth/bearer-auth-provider.d.ts +3 -3
  9. package/lib/directives/infinity-query-trigger.directive.d.ts +1 -1
  10. package/lib/directives/infinity-query.directive.d.ts +1 -1
  11. package/lib/directives/query.directive.d.ts +1 -1
  12. package/lib/query/query.utils.d.ts +12 -8
  13. package/lib/query-form/query-form.d.ts +11 -8
  14. package/lib/query-form/query-form.types.d.ts +4 -0
  15. package/package.json +8 -14
  16. package/esm2020/lib/directives/infinity-query-trigger.directive.mjs +0 -54
  17. package/esm2020/lib/directives/infinity-query.directive.mjs +0 -175
  18. package/esm2020/lib/directives/query.directive.mjs +0 -112
  19. package/esm2020/lib/query-form/query-form.mjs +0 -157
  20. package/fesm2015/ethlete-query.mjs +0 -2273
  21. package/fesm2015/ethlete-query.mjs.map +0 -1
  22. package/fesm2020/ethlete-query.mjs.map +0 -1
  23. /package/{esm2020 → esm2022}/ethlete-query.mjs +0 -0
  24. /package/{esm2020 → esm2022}/index.mjs +0 -0
  25. /package/{esm2020 → esm2022}/lib/auth/auth-provider.types.mjs +0 -0
  26. /package/{esm2020 → esm2022}/lib/auth/auth-provider.utils.mjs +0 -0
  27. /package/{esm2020 → esm2022}/lib/auth/basic-auth-provider.mjs +0 -0
  28. /package/{esm2020 → esm2022}/lib/auth/bearer-auth-provider.mjs +0 -0
  29. /package/{esm2020 → esm2022}/lib/auth/custom-header-auth-provider.mjs +0 -0
  30. /package/{esm2020 → esm2022}/lib/auth/index.mjs +0 -0
  31. /package/{esm2020 → esm2022}/lib/directives/index.mjs +0 -0
  32. /package/{esm2020 → esm2022}/lib/entity/entity-store.mjs +0 -0
  33. /package/{esm2020 → esm2022}/lib/entity/entity.types.mjs +0 -0
  34. /package/{esm2020 → esm2022}/lib/entity/entity.utils.mjs +0 -0
  35. /package/{esm2020 → esm2022}/lib/entity/index.mjs +0 -0
  36. /package/{esm2020 → esm2022}/lib/gql/gql.mjs +0 -0
  37. /package/{esm2020 → esm2022}/lib/gql/index.mjs +0 -0
  38. /package/{esm2020 → esm2022}/lib/infinite-query/index.mjs +0 -0
  39. /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.mjs +0 -0
  40. /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.types.mjs +0 -0
  41. /package/{esm2020 → esm2022}/lib/infinite-query/infinity-query.utils.mjs +0 -0
  42. /package/{esm2020 → esm2022}/lib/logger/index.mjs +0 -0
  43. /package/{esm2020 → esm2022}/lib/logger/logger.mjs +0 -0
  44. /package/{esm2020 → esm2022}/lib/query/index.mjs +0 -0
  45. /package/{esm2020 → esm2022}/lib/query/query.mjs +0 -0
  46. /package/{esm2020 → esm2022}/lib/query/query.types.mjs +0 -0
  47. /package/{esm2020 → esm2022}/lib/query/query.utils.mjs +0 -0
  48. /package/{esm2020 → esm2022}/lib/query-client/index.mjs +0 -0
  49. /package/{esm2020 → esm2022}/lib/query-client/query-client.mjs +0 -0
  50. /package/{esm2020 → esm2022}/lib/query-client/query-client.types.mjs +0 -0
  51. /package/{esm2020 → esm2022}/lib/query-client/query-client.utils.mjs +0 -0
  52. /package/{esm2020 → esm2022}/lib/query-creator/index.mjs +0 -0
  53. /package/{esm2020 → esm2022}/lib/query-creator/query-creator.mjs +0 -0
  54. /package/{esm2020 → esm2022}/lib/query-creator/query-creator.types.mjs +0 -0
  55. /package/{esm2020 → esm2022}/lib/query-form/index.mjs +0 -0
  56. /package/{esm2020 → esm2022}/lib/query-form/query-form.utils.mjs +0 -0
  57. /package/{esm2020 → esm2022}/lib/query-store/index.mjs +0 -0
  58. /package/{esm2020 → esm2022}/lib/query-store/query-store.mjs +0 -0
  59. /package/{esm2020 → esm2022}/lib/request/index.mjs +0 -0
  60. /package/{esm2020 → esm2022}/lib/request/request.mjs +0 -0
  61. /package/{esm2020 → esm2022}/lib/request/request.types.mjs +0 -0
  62. /package/{esm2020 → esm2022}/lib/request/request.util.mjs +0 -0
  63. /package/{esm2020 → esm2022}/lib/symfony/index.mjs +0 -0
  64. /package/{esm2020 → esm2022}/lib/symfony/symfony.types.mjs +0 -0
  65. /package/{esm2020 → esm2022}/lib/symfony/symfony.utils.mjs +0 -0
  66. /package/{esm2020 → esm2022}/lib/utils/deep-freeze.util.mjs +0 -0
  67. /package/{esm2020 → esm2022}/lib/utils/def.util.mjs +0 -0
  68. /package/{esm2020 → esm2022}/lib/utils/index.mjs +0 -0
@@ -1,157 +0,0 @@
1
- import { inject, isDevMode } from '@angular/core';
2
- import { FormGroup } from '@angular/forms';
3
- import { ActivatedRoute, Router } from '@angular/router';
4
- import { clone, equal } from '@ethlete/core';
5
- import { combineLatest, concat, debounceTime, distinctUntilChanged, filter, map, pairwise, startWith, take, tap, } from 'rxjs';
6
- export class QueryField {
7
- get control() {
8
- return this.data.control;
9
- }
10
- constructor(data) {
11
- this.data = data;
12
- this.changes$ = this._setupChangesObservable();
13
- this._currentDebounceTimeout = null;
14
- }
15
- setValue(value, options) {
16
- if (this._currentDebounceTimeout !== null) {
17
- clearTimeout(this._currentDebounceTimeout);
18
- }
19
- if (this.data.debounce && !options?.skipDebounce) {
20
- this._currentDebounceTimeout = window.setTimeout(() => {
21
- this.control.setValue(value);
22
- }, this.data.debounce);
23
- }
24
- else {
25
- this.control.setValue(value);
26
- }
27
- }
28
- _setupChangesObservable() {
29
- const obs = this.control.valueChanges.pipe(startWith(this.control.value));
30
- if (!this.data.debounce) {
31
- return obs;
32
- }
33
- // The initial value should get emitted immediately
34
- // concat switches to the debounced observable after the first observable is completed
35
- return concat(obs.pipe(take(1)), this.control.valueChanges.pipe(debounceTime(this.data.debounce)));
36
- }
37
- }
38
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
- export class QueryForm {
40
- constructor(_fields) {
41
- this._fields = _fields;
42
- this._router = inject(Router, { optional: true });
43
- this._activatedRoute = inject(ActivatedRoute, { optional: true });
44
- this._defaultValues = this._extractDefaultValues();
45
- this.form = this._setupFormGroup();
46
- }
47
- observe(options) {
48
- return combineLatest(Object.values(this._fields).map((field) => field.changes$)).pipe(map(() => this.form.getRawValue()), distinctUntilChanged((a, b) => equal(a, b)), tap((values) => {
49
- if (options?.syncViaUrlQueryParams !== false) {
50
- this._syncViaUrlQueryParams(values);
51
- }
52
- }), pairwise(), startWith([null, this.form.getRawValue()]), map(([previousValue, currentValue]) => ({ previousValue, currentValue })), map(({ previousValue, currentValue }) => {
53
- let didResetValues = false;
54
- for (const formFieldKey in this._fields) {
55
- const resets = this._fields[formFieldKey].data.isResetBy;
56
- if (!resets)
57
- continue;
58
- const resetConditionKeys = Array.isArray(resets) ? resets : [resets];
59
- for (const resetConditionKey of resetConditionKeys) {
60
- if (!(resetConditionKey in this._fields)) {
61
- if (isDevMode()) {
62
- console.warn(`The field "${resetConditionKey}" is not defined in the QueryForm. Is it a typo?`, this);
63
- }
64
- continue;
65
- }
66
- if (previousValue &&
67
- currentValue &&
68
- !equal(previousValue[resetConditionKey], currentValue[resetConditionKey])) {
69
- const defaultValueForKeyToReset = this._defaultValues[formFieldKey];
70
- const currentValueForKeyToReset = currentValue[formFieldKey];
71
- if (equal(defaultValueForKeyToReset, currentValueForKeyToReset)) {
72
- continue;
73
- }
74
- this.form.controls[formFieldKey].setValue(defaultValueForKeyToReset);
75
- didResetValues = true;
76
- break;
77
- }
78
- }
79
- }
80
- return (didResetValues || {
81
- previousValue,
82
- currentValue,
83
- });
84
- }), filter((value) => value !== true));
85
- }
86
- setFormValueFromUrlQueryParams(options) {
87
- if (!this._activatedRoute) {
88
- throw new Error('Cannot set form value from url query params without ActivatedRoute');
89
- }
90
- const queryParams = this._activatedRoute.snapshot.queryParams;
91
- for (const [key, field] of Object.entries(this._fields)) {
92
- const value = queryParams[key];
93
- // We only check using == because the value types can be different (e.g. "1" and 1)
94
- if (value === undefined || value == field.control.value) {
95
- continue;
96
- }
97
- const deserializedValue = field.data.queryParamToValueTransformFn?.(value) ?? value;
98
- field.setValue(deserializedValue, { skipDebounce: options?.skipDebounce ?? true });
99
- }
100
- }
101
- updateFormOnUrlQueryParamsChange() {
102
- if (!this._activatedRoute) {
103
- throw new Error('Cannot update form on url query params change without ActivatedRoute');
104
- }
105
- return this._activatedRoute.queryParams.pipe(tap(() => this.setFormValueFromUrlQueryParams()));
106
- }
107
- _getDefaultValue(key) {
108
- return this._defaultValues[key] ?? null;
109
- }
110
- _isDefaultValue(key, value) {
111
- const normalizedValue = Array.isArray(value) ? JSON.stringify(value) : value;
112
- return this._getDefaultValue(key) === normalizedValue;
113
- }
114
- _setupFormGroup() {
115
- const group = new FormGroup({});
116
- for (const [key, field] of Object.entries(this._fields)) {
117
- group.addControl(key, field.control);
118
- }
119
- return group;
120
- }
121
- _extractDefaultValues() {
122
- const defaultValues = {};
123
- for (const [key, field] of Object.entries(this._fields)) {
124
- const value = field.control.value;
125
- if (value === null || value === undefined) {
126
- continue;
127
- }
128
- if (Array.isArray(value)) {
129
- defaultValues[key] = JSON.stringify(value);
130
- }
131
- else {
132
- defaultValues[key] = value;
133
- }
134
- }
135
- return defaultValues;
136
- }
137
- _syncViaUrlQueryParams(values) {
138
- if (!this._router || !this._activatedRoute) {
139
- return;
140
- }
141
- const queryParams = { ...clone(this._activatedRoute.snapshot.queryParams) };
142
- for (const [key, value] of Object.entries(values)) {
143
- if (this._isDefaultValue(key, value) || this._fields[key].data.appendToUrl === false) {
144
- delete queryParams[key];
145
- }
146
- else {
147
- queryParams[key] = this._fields[key].data.valueToQueryParamTransformFn
148
- ? this._fields[key].data.valueToQueryParamTransformFn?.(value)
149
- : value;
150
- }
151
- }
152
- this._router.navigate([], {
153
- queryParams,
154
- });
155
- }
156
- }
157
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnktZm9ybS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvcXVlcnkvc3JjL2xpYi9xdWVyeS1mb3JtL3F1ZXJ5LWZvcm0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDekQsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUVMLGFBQWEsRUFDYixNQUFNLEVBQ04sWUFBWSxFQUNaLG9CQUFvQixFQUNwQixNQUFNLEVBQ04sR0FBRyxFQUNILFFBQVEsRUFDUixTQUFTLEVBQ1QsSUFBSSxFQUNKLEdBQUcsR0FDSixNQUFNLE1BQU0sQ0FBQztBQUdkLE1BQU0sT0FBTyxVQUFVO0lBR3JCLElBQUksT0FBTztRQUNULE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQUlELFlBQW1CLElBQTBCO1FBQTFCLFNBQUksR0FBSixJQUFJLENBQXNCO1FBUjdDLGFBQVEsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQU1sQyw0QkFBdUIsR0FBa0IsSUFBSSxDQUFDO0lBRU4sQ0FBQztJQUVqRCxRQUFRLENBQUMsS0FBZSxFQUFFLE9BQW9DO1FBQzVELElBQUksSUFBSSxDQUFDLHVCQUF1QixLQUFLLElBQUksRUFBRTtZQUN6QyxZQUFZLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7U0FDNUM7UUFFRCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRTtZQUNoRCxJQUFJLENBQUMs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Q0FBQyxHQUFHLEtBQUssQ0FBQzthQUM1QjtTQUNGO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVPLHNCQUFzQixDQUFDLE1BQStCO1FBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUMxQyxPQUFPO1NBQ1I7UUFFRCxNQUFNLFdBQVcsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFFNUUsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDakQsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEtBQUssS0FBSyxFQUFFO2dCQUNwRixPQUFPLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUN6QjtpQkFBTTtnQkFDTCxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCO29CQUNwRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsQ0FBQyxLQUFLLENBQUM7b0JBQzlELENBQUMsQ0FBQyxLQUFLLENBQUM7YUFDWDtTQUNGO1FBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFO1lBQ3hCLFdBQVc7U0FDWixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIGlzRGV2TW9kZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjbG9uZSwgZXF1YWwgfSBmcm9tICdAZXRobGV0ZS9jb3JlJztcbmltcG9ydCB7XG4gIE9ic2VydmFibGUsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGNvbmNhdCxcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBtYXAsXG4gIHBhaXJ3aXNlLFxuICBzdGFydFdpdGgsXG4gIHRha2UsXG4gIHRhcCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBRdWVyeUZpZWxkT3B0aW9ucywgUXVlcnlGb3JtR3JvdXAsIFF1ZXJ5Rm9ybU9ic2VydmVPcHRpb25zLCBRdWVyeUZvcm1WYWx1ZSB9IGZyb20gJy4vcXVlcnktZm9ybS50eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBRdWVyeUZpZWxkPFQ+IHtcbiAgY2hhbmdlcyQgPSB0aGlzLl9zZXR1cENoYW5nZXNPYnNlcnZhYmxlKCk7XG5cbiAgZ2V0IGNvbnRyb2woKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YS5jb250cm9sO1xuICB9XG5cbiAgcHJpdmF0ZSBfY3VycmVudERlYm91bmNlVGltZW91dDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHVibGljIGRhdGE6IFF1ZXJ5RmllbGRPcHRpb25zPFQ+KSB7fVxuXG4gIHNldFZhbHVlKHZhbHVlOiBUIHwgbnVsbCwgb3B0aW9ucz86IHsgc2tpcERlYm91bmNlPzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnREZWJvdW5jZVRpbWVvdXQgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9jdXJyZW50RGVib3VuY2VUaW1lb3V0KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kYXRhLmRlYm91bmNlICYmICFvcHRpb25zPy5za2lwRGVib3VuY2UpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnREZWJvdW5jZVRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuY29udHJvbC5zZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICB9LCB0aGlzLmRhdGEuZGVib3VuY2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRyb2wuc2V0VmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3NldHVwQ2hhbmdlc09ic2VydmFibGUoKSB7XG4gICAgY29uc3Qgb2JzID0gdGhpcy5jb250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKHN0YXJ0V2l0aCh0aGlzLmNvbnRyb2wudmFsdWUpKTtcblxuICAgIGlmICghdGhpcy5kYXRhLmRlYm91bmNlKSB7XG4gICAgICByZXR1cm4gb2JzO1xuICAgIH1cblxuICAgIC8vIFRoZSBpbml0aWFsIHZhbHVlIHNob3VsZCBnZXQgZW1pdHRlZCBpbW1lZGlhdGVseVxuICAgIC8vIGNvbmNhdCBzd2l0Y2hlcyB0byB0aGUgZGVib3VuY2VkIG9ic2VydmFibGUgYWZ0ZXIgdGhlIGZpcnN0IG9ic2VydmFibGUgaXMgY29tcGxldGVkXG4gICAgcmV0dXJuIGNvbmNhdChvYnMucGlwZSh0YWtlKDEpKSwgdGhpcy5jb250cm9sLnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZSh0aGlzLmRhdGEuZGVib3VuY2UpKSk7XG4gIH1cbn1cblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmV4cG9ydCBjbGFzcyBRdWVyeUZvcm08VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIFF1ZXJ5RmllbGQ8YW55Pj4+IHtcbiAgcHJpdmF0ZSBfcm91dGVyID0gaW5qZWN0KFJvdXRlciwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSBfYWN0aXZhdGVkUm91dGUgPSBpbmplY3QoQWN0aXZhdGVkUm91dGUsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgX2RlZmF1bHRWYWx1ZXMgPSB0aGlzLl9leHRyYWN0RGVmYXVsdFZhbHVlcygpO1xuXG4gIGZvcm0gPSB0aGlzLl9zZXR1cEZvcm1Hcm91cCgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2ZpZWxkczogVCkge31cblxuICBvYnNlcnZlKG9wdGlvbnM/OiBRdWVyeUZvcm1PYnNlcnZlT3B0aW9ucykge1xuICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KE9iamVjdC52YWx1ZXModGhpcy5fZmllbGRzKS5tYXAoKGZpZWxkKSA9PiBmaWVsZC5jaGFuZ2VzJCkpLnBpcGUoXG4gICAgICBtYXAoKCkgPT4gdGhpcy5mb3JtLmdldFJhd1ZhbHVlKCkpLFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKGEsIGIpID0+IGVxdWFsKGEsIGIpKSxcbiAgICAgIHRhcCgodmFsdWVzKSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zPy5zeW5jVmlhVXJsUXVlcnlQYXJhbXMgIT09IGZhbHNlKSB7XG4gICAgICAgICAgdGhpcy5fc3luY1ZpYVVybFF1ZXJ5UGFyYW1zKHZhbHVlcyk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgcGFpcndpc2UoKSxcbiAgICAgIHN0YXJ0V2l0aChbbnVsbCwgdGhpcy5mb3JtLmdldFJhd1ZhbHVlKCldIGFzIGNvbnN0KSxcbiAgICAgIG1hcCgoW3ByZXZpb3VzVmFsdWUsIGN1cnJlbnRWYWx1ZV0pID0+ICh7IHByZXZpb3VzVmFsdWUsIGN1cnJlbnRWYWx1ZSB9KSksXG4gICAgICBtYXAoKHsgcHJldmlvdXNWYWx1ZSwgY3VycmVudFZhbHVlIH0pID0+IHtcbiAgICAgICAgbGV0IGRpZFJlc2V0VmFsdWVzID0gZmFsc2U7XG5cbiAgICAgICAgZm9yIChjb25zdCBmb3JtRmllbGRLZXkgaW4gdGhpcy5fZmllbGRzKSB7XG4gICAgICAgICAgY29uc3QgcmVzZXRzID0gdGhpcy5fZmllbGRzW2Zvcm1GaWVsZEtleV0uZGF0YS5pc1Jlc2V0Qnk7XG5cbiAgICAgICAgICBpZiAoIXJlc2V0cykgY29udGludWU7XG5cbiAgICAgICAgICBjb25zdCByZXNldENvbmRpdGlvbktleXMgPSBBcnJheS5pc0FycmF5KHJlc2V0cykgPyByZXNldHMgOiBbcmVzZXRzXTtcblxuICAgICAgICAgIGZvciAoY29uc3QgcmVzZXRDb25kaXRpb25LZXkgb2YgcmVzZXRDb25kaXRpb25LZXlzKSB7XG4gICAgICAgICAgICBpZiAoIShyZXNldENvbmRpdGlvbktleSBpbiB0aGlzLl9maWVsZHMpKSB7XG4gICAgICAgICAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgVGhlIGZpZWxkIFwiJHtyZXNldENvbmRpdGlvbktleX1cIiBpcyBub3QgZGVmaW5lZCBpbiB0aGUgUXVlcnlGb3JtLiBJcyBpdCBhIHR5cG8/YCwgdGhpcyk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBwcmV2aW91c1ZhbHVlICYmXG4gICAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSAmJlxuICAgICAgICAgICAgICAhZXF1YWwocHJldmlvdXNWYWx1ZVtyZXNldENvbmRpdGlvbktleV0sIGN1cnJlbnRWYWx1ZVtyZXNldENvbmRpdGlvbktleV0pXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlRm9yS2V5VG9SZXNldCA9IHRoaXMuX2RlZmF1bHRWYWx1ZXNbZm9ybUZpZWxkS2V5XTtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudFZhbHVlRm9yS2V5VG9SZXNldCA9IGN1cnJlbnRWYWx1ZVtmb3JtRmllbGRLZXldO1xuXG4gICAgICAgICAgICAgIGlmIChlcXVhbChkZWZhdWx0VmFsdWVGb3JLZXlUb1Jlc2V0LCBjdXJyZW50VmFsdWVGb3JLZXlUb1Jlc2V0KSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdGhpcy5mb3JtLmNvbnRyb2xzW2Zvcm1GaWVsZEtleV0uc2V0VmFsdWUoZGVmYXVsdFZhbHVlRm9yS2V5VG9SZXNldCk7XG5cbiAgICAgICAgICAgICAgZGlkUmVzZXRWYWx1ZXMgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgZGlkUmVzZXRWYWx1ZXMgfHwge1xuICAgICAgICAgICAgcHJldmlvdXNWYWx1ZSxcbiAgICAgICAgICAgIGN1cnJlbnRWYWx1ZSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9KSxcbiAgICAgIGZpbHRlcigodmFsdWUpID0+IHZhbHVlICE9PSB0cnVlKSwgLy8gRmlsdGVyIG91dCBldmVudHMgdGhhdCBvbmx5IHJlc2V0IHZhbHVlc1xuICAgICAgLy8gVGhpcyB0eXBlIGNhc3QgaXMgbmVlZGVkIHNpbmNlIG5nLXBhY2thZ3Igd2lsbCBicmVhayB0aGUgdHlwZSBpbmZlcmVuY2Ugb3RoZXJ3aXNlLlxuICAgICkgYXMgT2JzZXJ2YWJsZTx7XG4gICAgICBwcmV2aW91c1ZhbHVlOiBRdWVyeUZvcm1WYWx1ZTxUPjtcbiAgICAgIGN1cnJlbnRWYWx1ZTogUXVlcnlGb3JtVmFsdWU8VD47XG4gICAgfT47XG4gIH1cblxuICBzZXRGb3JtVmFsdWVGcm9tVXJsUXVlcnlQYXJhbXMob3B0aW9ucz86IHsgc2tpcERlYm91bmNlPzogYm9vbGVhbiB9KSB7XG4gICAgaWYgKCF0aGlzLl9hY3RpdmF0ZWRSb3V0ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3Qgc2V0IGZvcm0gdmFsdWUgZnJvbSB1cmwgcXVlcnkgcGFyYW1zIHdpdGhvdXQgQWN0aXZhdGVkUm91dGUnKTtcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeVBhcmFtcyA9IHRoaXMuX2FjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBmaWVsZF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5fZmllbGRzKSkge1xuICAgICAgY29uc3QgdmFsdWUgPSBxdWVyeVBhcmFtc1trZXldO1xuXG4gICAgICAvLyBXZSBvbmx5IGNoZWNrIHVzaW5nID09IGJlY2F1c2UgdGhlIHZhbHVlIHR5cGVzIGNhbiBiZSBkaWZmZXJlbnQgKGUuZy4gXCIxXCIgYW5kIDEpXG4gICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PSBmaWVsZC5jb250cm9sLnZhbHVlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXNlcmlhbGl6ZWRWYWx1ZSA9IGZpZWxkLmRhdGEucXVlcnlQYXJhbVRvVmFsdWVUcmFuc2Zvcm1Gbj8uKHZhbHVlKSA/PyB2YWx1ZTtcblxuICAgICAgZmllbGQuc2V0VmFsdWUoZGVzZXJpYWxpemVkVmFsdWUsIHsgc2tpcERlYm91bmNlOiBvcHRpb25zPy5za2lwRGVib3VuY2UgPz8gdHJ1ZSB9KTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVGb3JtT25VcmxRdWVyeVBhcmFtc0NoYW5nZSgpIHtcbiAgICBpZiAoIXRoaXMuX2FjdGl2YXRlZFJvdXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCB1cGRhdGUgZm9ybSBvbiB1cmwgcXVlcnkgcGFyYW1zIGNoYW5nZSB3aXRob3V0IEFjdGl2YXRlZFJvdXRlJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2YXRlZFJvdXRlLnF1ZXJ5UGFyYW1zLnBpcGUodGFwKCgpID0+IHRoaXMuc2V0Rm9ybVZhbHVlRnJvbVVybFF1ZXJ5UGFyYW1zKCkpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldERlZmF1bHRWYWx1ZShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9kZWZhdWx0VmFsdWVzW2tleV0gPz8gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX2lzRGVmYXVsdFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gSlNPTi5zdHJpbmdpZnkodmFsdWUpIDogdmFsdWU7XG5cbiAgICByZXR1cm4gdGhpcy5fZ2V0RGVmYXVsdFZhbHVlKGtleSkgPT09IG5vcm1hbGl6ZWRWYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgX3NldHVwRm9ybUdyb3VwKCkge1xuICAgIGNvbnN0IGdyb3VwID0gbmV3IEZvcm1Hcm91cCh7fSBhcyBRdWVyeUZvcm1Hcm91cDxUPik7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIGZpZWxkXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLl9maWVsZHMpKSB7XG4gICAgICBncm91cC5hZGRDb250cm9sKGtleSwgZmllbGQuY29udHJvbCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdyb3VwO1xuICB9XG5cbiAgcHJpdmF0ZSBfZXh0cmFjdERlZmF1bHRWYWx1ZXMoKSB7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgZmllbGRdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuX2ZpZWxkcykpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gZmllbGQuY29udHJvbC52YWx1ZTtcblxuICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICBkZWZhdWx0VmFsdWVzW2tleV0gPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWZhdWx0VmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZGVmYXVsdFZhbHVlcztcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNWaWFVcmxRdWVyeVBhcmFtcyh2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSB7XG4gICAgaWYgKCF0aGlzLl9yb3V0ZXIgfHwgIXRoaXMuX2FjdGl2YXRlZFJvdXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnlQYXJhbXMgPSB7IC4uLmNsb25lKHRoaXMuX2FjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnF1ZXJ5UGFyYW1zKSB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModmFsdWVzKSkge1xuICAgICAgaWYgKHRoaXMuX2lzRGVmYXVsdFZhbHVlKGtleSwgdmFsdWUpIHx8IHRoaXMuX2ZpZWxkc1trZXldLmRhdGEuYXBwZW5kVG9VcmwgPT09IGZhbHNlKSB7XG4gICAgICAgIGRlbGV0ZSBxdWVyeVBhcmFtc1trZXldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnlQYXJhbXNba2V5XSA9IHRoaXMuX2ZpZWxkc1trZXldLmRhdGEudmFsdWVUb1F1ZXJ5UGFyYW1UcmFuc2Zvcm1GblxuICAgICAgICAgID8gdGhpcy5fZmllbGRzW2tleV0uZGF0YS52YWx1ZVRvUXVlcnlQYXJhbVRyYW5zZm9ybUZuPy4odmFsdWUpXG4gICAgICAgICAgOiB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUoW10sIHtcbiAgICAgIHF1ZXJ5UGFyYW1zLFxuICAgIH0pO1xuICB9XG59XG4iXX0=