@ngrx/data 11.0.0-rc.0 → 11.1.1

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 (149) hide show
  1. package/bundles/ngrx-data.umd.js +902 -4475
  2. package/bundles/ngrx-data.umd.js.map +1 -1
  3. package/bundles/ngrx-data.umd.min.js +15 -1
  4. package/bundles/ngrx-data.umd.min.js.map +1 -1
  5. package/esm2015/index.js +2 -7
  6. package/esm2015/ngrx-data.js +2 -7
  7. package/esm2015/public_api.js +2 -7
  8. package/esm2015/src/actions/entity-action-factory.js +6 -31
  9. package/esm2015/src/actions/entity-action-guard.js +23 -130
  10. package/esm2015/src/actions/entity-action-operators.js +11 -64
  11. package/esm2015/src/actions/entity-action.js +2 -68
  12. package/esm2015/src/actions/entity-cache-action.js +14 -125
  13. package/esm2015/src/actions/entity-cache-change-set.js +15 -126
  14. package/esm2015/src/actions/entity-op.js +70 -89
  15. package/esm2015/src/actions/merge-strategy.js +8 -16
  16. package/esm2015/src/actions/update-response-data.js +2 -36
  17. package/esm2015/src/dataservices/data-service-error.js +1 -34
  18. package/esm2015/src/dataservices/default-data-service-config.js +1 -41
  19. package/esm2015/src/dataservices/default-data.service.js +5 -163
  20. package/esm2015/src/dataservices/entity-cache-data.service.js +17 -103
  21. package/esm2015/src/dataservices/entity-data.service.js +5 -31
  22. package/esm2015/src/dataservices/http-url-generator.js +11 -97
  23. package/esm2015/src/dataservices/interfaces.js +2 -71
  24. package/esm2015/src/dataservices/persistence-result-handler.service.js +7 -66
  25. package/esm2015/src/dispatchers/entity-cache-dispatcher.js +40 -97
  26. package/esm2015/src/dispatchers/entity-commands.js +2 -247
  27. package/esm2015/src/dispatchers/entity-dispatcher-base.js +65 -287
  28. package/esm2015/src/dispatchers/entity-dispatcher-default-options.js +6 -48
  29. package/esm2015/src/dispatchers/entity-dispatcher-factory.js +2 -64
  30. package/esm2015/src/dispatchers/entity-dispatcher.js +1 -74
  31. package/esm2015/src/effects/entity-cache-effects.js +21 -135
  32. package/esm2015/src/effects/entity-effects-scheduler.js +2 -10
  33. package/esm2015/src/effects/entity-effects.js +18 -128
  34. package/esm2015/src/entity-data-without-effects.module.js +7 -79
  35. package/esm2015/src/entity-data.module.js +3 -25
  36. package/esm2015/src/entity-metadata/entity-definition.js +2 -42
  37. package/esm2015/src/entity-metadata/entity-definition.service.js +14 -52
  38. package/esm2015/src/entity-metadata/entity-filters.js +5 -33
  39. package/esm2015/src/entity-metadata/entity-metadata.js +1 -34
  40. package/esm2015/src/entity-services/entity-collection-service-base.js +56 -208
  41. package/esm2015/src/entity-services/entity-collection-service-elements-factory.js +3 -60
  42. package/esm2015/src/entity-services/entity-collection-service-factory.js +5 -20
  43. package/esm2015/src/entity-services/entity-collection-service.js +2 -53
  44. package/esm2015/src/entity-services/entity-services-base.js +18 -78
  45. package/esm2015/src/entity-services/entity-services-elements.js +9 -44
  46. package/esm2015/src/entity-services/entity-services.js +1 -70
  47. package/esm2015/src/index.js +1 -6
  48. package/esm2015/src/reducers/constants.js +1 -11
  49. package/esm2015/src/reducers/entity-cache-reducer.js +33 -175
  50. package/esm2015/src/reducers/entity-cache.js +2 -10
  51. package/esm2015/src/reducers/entity-change-tracker-base.js +115 -262
  52. package/esm2015/src/reducers/entity-change-tracker.js +2 -179
  53. package/esm2015/src/reducers/entity-collection-creator.js +5 -29
  54. package/esm2015/src/reducers/entity-collection-reducer-methods.js +44 -503
  55. package/esm2015/src/reducers/entity-collection-reducer-registry.js +8 -50
  56. package/esm2015/src/reducers/entity-collection-reducer.js +5 -34
  57. package/esm2015/src/reducers/entity-collection.js +9 -65
  58. package/esm2015/src/selectors/entity-cache-selector.js +1 -12
  59. package/esm2015/src/selectors/entity-selectors$.js +11 -137
  60. package/esm2015/src/selectors/entity-selectors.js +23 -262
  61. package/esm2015/src/utils/correlation-id-generator.js +4 -30
  62. package/esm2015/src/utils/default-logger.js +1 -21
  63. package/esm2015/src/utils/default-pluralizer.js +3 -24
  64. package/esm2015/src/utils/guid-fns.js +9 -41
  65. package/esm2015/src/utils/interfaces.js +1 -49
  66. package/esm2015/src/utils/utilities.js +6 -25
  67. package/fesm2015/ngrx-data.js +721 -4410
  68. package/fesm2015/ngrx-data.js.map +1 -1
  69. package/package.json +5 -5
  70. package/schematics-core/index.js +4 -1
  71. package/schematics-core/index.js.map +1 -1
  72. package/schematics-core/utility/ast-utils.js +127 -1
  73. package/schematics-core/utility/ast-utils.js.map +1 -1
  74. package/schematics-core/utility/config.js +1 -1
  75. package/schematics-core/utility/config.js.map +1 -1
  76. package/schematics-core/utility/find-component.js +101 -0
  77. package/schematics-core/utility/find-component.js.map +1 -0
  78. package/schematics-core/utility/libs-version.js +1 -1
  79. package/schematics-core/utility/libs-version.js.map +1 -1
  80. package/schematics-core/utility/project.js +4 -2
  81. package/schematics-core/utility/project.js.map +1 -1
  82. package/CHANGELOG.md +0 -3
  83. package/esm2015/index.ngsummary.json +0 -1
  84. package/esm2015/ngrx-data.ngsummary.json +0 -1
  85. package/esm2015/public_api.ngsummary.json +0 -1
  86. package/esm2015/src/actions/entity-action-factory.ngsummary.json +0 -1
  87. package/esm2015/src/actions/entity-action-guard.ngsummary.json +0 -1
  88. package/esm2015/src/actions/entity-action-operators.ngsummary.json +0 -1
  89. package/esm2015/src/actions/entity-action.ngsummary.json +0 -1
  90. package/esm2015/src/actions/entity-cache-action.ngsummary.json +0 -1
  91. package/esm2015/src/actions/entity-cache-change-set.ngsummary.json +0 -1
  92. package/esm2015/src/actions/entity-op.ngsummary.json +0 -1
  93. package/esm2015/src/actions/merge-strategy.ngsummary.json +0 -1
  94. package/esm2015/src/actions/update-response-data.ngsummary.json +0 -1
  95. package/esm2015/src/dataservices/data-service-error.ngsummary.json +0 -1
  96. package/esm2015/src/dataservices/default-data-service-config.ngsummary.json +0 -1
  97. package/esm2015/src/dataservices/default-data.service.ngsummary.json +0 -1
  98. package/esm2015/src/dataservices/entity-cache-data.service.ngsummary.json +0 -1
  99. package/esm2015/src/dataservices/entity-data.service.ngsummary.json +0 -1
  100. package/esm2015/src/dataservices/http-url-generator.ngsummary.json +0 -1
  101. package/esm2015/src/dataservices/interfaces.ngsummary.json +0 -1
  102. package/esm2015/src/dataservices/persistence-result-handler.service.ngsummary.json +0 -1
  103. package/esm2015/src/dispatchers/entity-cache-dispatcher.ngsummary.json +0 -1
  104. package/esm2015/src/dispatchers/entity-commands.ngsummary.json +0 -1
  105. package/esm2015/src/dispatchers/entity-dispatcher-base.ngsummary.json +0 -1
  106. package/esm2015/src/dispatchers/entity-dispatcher-default-options.ngsummary.json +0 -1
  107. package/esm2015/src/dispatchers/entity-dispatcher-factory.ngsummary.json +0 -1
  108. package/esm2015/src/dispatchers/entity-dispatcher.ngsummary.json +0 -1
  109. package/esm2015/src/effects/entity-cache-effects.ngsummary.json +0 -1
  110. package/esm2015/src/effects/entity-effects-scheduler.ngsummary.json +0 -1
  111. package/esm2015/src/effects/entity-effects.ngsummary.json +0 -1
  112. package/esm2015/src/entity-data-without-effects.module.ngfactory.js +0 -36
  113. package/esm2015/src/entity-data-without-effects.module.ngsummary.json +0 -1
  114. package/esm2015/src/entity-data.module.ngfactory.js +0 -48
  115. package/esm2015/src/entity-data.module.ngsummary.json +0 -1
  116. package/esm2015/src/entity-metadata/entity-definition.ngsummary.json +0 -1
  117. package/esm2015/src/entity-metadata/entity-definition.service.ngsummary.json +0 -1
  118. package/esm2015/src/entity-metadata/entity-filters.ngsummary.json +0 -1
  119. package/esm2015/src/entity-metadata/entity-metadata.ngsummary.json +0 -1
  120. package/esm2015/src/entity-services/entity-collection-service-base.ngsummary.json +0 -1
  121. package/esm2015/src/entity-services/entity-collection-service-elements-factory.ngsummary.json +0 -1
  122. package/esm2015/src/entity-services/entity-collection-service-factory.ngsummary.json +0 -1
  123. package/esm2015/src/entity-services/entity-collection-service.ngsummary.json +0 -1
  124. package/esm2015/src/entity-services/entity-services-base.ngsummary.json +0 -1
  125. package/esm2015/src/entity-services/entity-services-elements.ngsummary.json +0 -1
  126. package/esm2015/src/entity-services/entity-services.ngsummary.json +0 -1
  127. package/esm2015/src/index.ngsummary.json +0 -1
  128. package/esm2015/src/reducers/constants.ngsummary.json +0 -1
  129. package/esm2015/src/reducers/entity-cache-reducer.ngsummary.json +0 -1
  130. package/esm2015/src/reducers/entity-cache.ngsummary.json +0 -1
  131. package/esm2015/src/reducers/entity-change-tracker-base.ngsummary.json +0 -1
  132. package/esm2015/src/reducers/entity-change-tracker.ngsummary.json +0 -1
  133. package/esm2015/src/reducers/entity-collection-creator.ngsummary.json +0 -1
  134. package/esm2015/src/reducers/entity-collection-reducer-methods.ngsummary.json +0 -1
  135. package/esm2015/src/reducers/entity-collection-reducer-registry.ngsummary.json +0 -1
  136. package/esm2015/src/reducers/entity-collection-reducer.ngsummary.json +0 -1
  137. package/esm2015/src/reducers/entity-collection.ngsummary.json +0 -1
  138. package/esm2015/src/selectors/entity-cache-selector.ngsummary.json +0 -1
  139. package/esm2015/src/selectors/entity-selectors$.ngsummary.json +0 -1
  140. package/esm2015/src/selectors/entity-selectors.ngsummary.json +0 -1
  141. package/esm2015/src/utils/correlation-id-generator.ngsummary.json +0 -1
  142. package/esm2015/src/utils/default-logger.ngsummary.json +0 -1
  143. package/esm2015/src/utils/default-pluralizer.ngsummary.json +0 -1
  144. package/esm2015/src/utils/guid-fns.ngsummary.json +0 -1
  145. package/esm2015/src/utils/interfaces.ngsummary.json +0 -1
  146. package/esm2015/src/utils/utilities.ngsummary.json +0 -1
  147. package/schematics/ng-add/files/entity-metadata.ts.template +0 -10
  148. package/src/entity-data-without-effects.module.ngfactory.d.ts +0 -3
  149. package/src/entity-data.module.ngfactory.d.ts +0 -3
@@ -1,8 +1,3 @@
1
- /**
2
- * @fileoverview added by tsickle
3
- * Generated from: src/dispatchers/entity-dispatcher-base.ts
4
- * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
- */
6
1
  import { createSelector } from '@ngrx/store';
7
2
  import { of, throwError } from 'rxjs';
8
3
  import { filter, map, mergeMap, shareReplay, withLatestFrom, take, } from 'rxjs/operators';
@@ -13,22 +8,28 @@ import { EntityOp, OP_ERROR, OP_SUCCESS } from '../actions/entity-op';
13
8
  /**
14
9
  * Dispatches EntityCollection actions to their reducers and effects (default implementation).
15
10
  * All save commands rely on an Ngrx Effect such as `EntityEffects.persist$`.
16
- * @template T
17
11
  */
18
12
  export class EntityDispatcherBase {
13
+ constructor(
14
+ /** Name of the entity type for which entities are dispatched */
15
+ entityName,
16
+ /** Creates an {EntityAction} */
17
+ entityActionFactory,
18
+ /** The store, scoped to the EntityCache */
19
+ store,
20
+ /** Returns the primary key (id) of this entity */
21
+ selectId = defaultSelectId,
19
22
  /**
20
- * @param {?} entityName
21
- * @param {?} entityActionFactory
22
- * @param {?} store
23
- * @param {?=} selectId
24
- * @param {?=} defaultDispatcherOptions
25
- * @param {?=} reducedActions$
26
- * @param {?=} entityCacheSelector
27
- * @param {?=} correlationIdGenerator
23
+ * Dispatcher options configure dispatcher behavior such as
24
+ * whether add is optimistic or pessimistic by default.
28
25
  */
29
- constructor(entityName, entityActionFactory, store, selectId = defaultSelectId, defaultDispatcherOptions, reducedActions$,
26
+ defaultDispatcherOptions,
27
+ /** Actions scanned by the store after it processed them with reducers. */
28
+ reducedActions$,
30
29
  /** Store selector for the EntityCache */
31
- entityCacheSelector, correlationIdGenerator) {
30
+ entityCacheSelector,
31
+ /** Generates correlation ids for query and save methods */
32
+ correlationIdGenerator) {
32
33
  this.entityName = entityName;
33
34
  this.entityActionFactory = entityActionFactory;
34
35
  this.store = store;
@@ -38,21 +39,15 @@ export class EntityDispatcherBase {
38
39
  this.correlationIdGenerator = correlationIdGenerator;
39
40
  this.guard = new EntityActionGuard(entityName, selectId);
40
41
  this.toUpdate = toUpdateFactory(selectId);
41
- /** @type {?} */
42
- const collectionSelector = createSelector(entityCacheSelector, (/**
43
- * @param {?} cache
44
- * @return {?}
45
- */
46
- (cache) => (/** @type {?} */ (cache[entityName]))));
42
+ const collectionSelector = createSelector(entityCacheSelector, (cache) => cache[entityName]);
47
43
  this.entityCollection$ = store.select(collectionSelector);
48
44
  }
49
45
  /**
50
46
  * Create an {EntityAction} for this entity type.
51
- * @template P
52
- * @param {?} entityOp {EntityOp} the entity operation
53
- * @param {?=} data
54
- * @param {?=} options
55
- * @return {?} the EntityAction
47
+ * @param entityOp {EntityOp} the entity operation
48
+ * @param [data] the action data
49
+ * @param [options] additional options
50
+ * @returns the EntityAction
56
51
  */
57
52
  createEntityAction(entityOp, data, options) {
58
53
  return this.entityActionFactory.create(Object.assign({ entityName: this.entityName, entityOp,
@@ -61,22 +56,20 @@ export class EntityDispatcherBase {
61
56
  /**
62
57
  * Create an {EntityAction} for this entity type and
63
58
  * dispatch it immediately to the store.
64
- * @template P
65
- * @param {?} op {EntityOp} the entity operation
66
- * @param {?=} data
67
- * @param {?=} options
68
- * @return {?} the dispatched EntityAction
59
+ * @param op {EntityOp} the entity operation
60
+ * @param [data] the action data
61
+ * @param [options] additional options
62
+ * @returns the dispatched EntityAction
69
63
  */
70
64
  createAndDispatch(op, data, options) {
71
- /** @type {?} */
72
65
  const action = this.createEntityAction(op, data, options);
73
66
  this.dispatch(action);
74
67
  return action;
75
68
  }
76
69
  /**
77
70
  * Dispatch an Action to the store.
78
- * @param {?} action the Action
79
- * @return {?} the dispatched Action
71
+ * @param action the Action
72
+ * @returns the dispatched Action
80
73
  */
81
74
  dispatch(action) {
82
75
  this.store.dispatch(action);
@@ -85,15 +78,13 @@ export class EntityDispatcherBase {
85
78
  // #region Query and save operations
86
79
  /**
87
80
  * Dispatch action to save a new entity to remote storage.
88
- * @param {?} entity entity to add, which may omit its key if pessimistic and the server creates the key;
81
+ * @param entity entity to add, which may omit its key if pessimistic and the server creates the key;
89
82
  * must have a key if optimistic save.
90
- * @param {?=} options
91
- * @return {?} A terminating Observable of the entity
83
+ * @returns A terminating Observable of the entity
92
84
  * after server reports successful save or the save error.
93
85
  */
94
86
  add(entity, options) {
95
87
  options = this.setSaveEntityActionOptions(options, this.defaultDispatcherOptions.optimisticAdd);
96
- /** @type {?} */
97
88
  const action = this.createEntityAction(EntityOp.SAVE_ADD_ONE, entity, options);
98
89
  if (options.isOptimistic) {
99
90
  this.guard.mustBeEntity(action);
@@ -102,20 +93,14 @@ export class EntityDispatcherBase {
102
93
  return this.getResponseData$(options.correlationId).pipe(
103
94
  // Use the returned entity data's id to get the entity from the collection
104
95
  // as it might be different from the entity returned from the server.
105
- withLatestFrom(this.entityCollection$), map((/**
106
- * @param {?} __0
107
- * @return {?}
108
- */
109
- ([e, collection]) => (/** @type {?} */ (collection.entities[this.selectId(e)])))), shareReplay(1));
96
+ withLatestFrom(this.entityCollection$), map(([e, collection]) => collection.entities[this.selectId(e)]), shareReplay(1));
110
97
  }
111
98
  /**
112
99
  * Dispatch action to cancel the persistence operation (query or save).
113
100
  * Will cause save observable to error with a PersistenceCancel error.
114
101
  * Caller is responsible for undoing changes in cache from pending optimistic save
115
- * @param {?} correlationId The correlation id for the corresponding EntityAction
116
- * @param {?=} reason
117
- * @param {?=} options
118
- * @return {?}
102
+ * @param correlationId The correlation id for the corresponding EntityAction
103
+ * @param [reason] explains why canceled and by whom.
119
104
  */
120
105
  cancel(correlationId, reason, options) {
121
106
  if (!correlationId) {
@@ -123,129 +108,86 @@ export class EntityDispatcherBase {
123
108
  }
124
109
  this.createAndDispatch(EntityOp.CANCEL_PERSIST, reason, { correlationId });
125
110
  }
126
- /**
127
- * @param {?} arg
128
- * @param {?=} options
129
- * @return {?}
130
- */
131
111
  delete(arg, options) {
132
112
  options = this.setSaveEntityActionOptions(options, this.defaultDispatcherOptions.optimisticDelete);
133
- /** @type {?} */
134
113
  const key = this.getKey(arg);
135
- /** @type {?} */
136
114
  const action = this.createEntityAction(EntityOp.SAVE_DELETE_ONE, key, options);
137
115
  this.guard.mustBeKey(action);
138
116
  this.dispatch(action);
139
- return this.getResponseData$(options.correlationId).pipe(map((/**
140
- * @return {?}
141
- */
142
- () => key)), shareReplay(1));
117
+ return this.getResponseData$(options.correlationId).pipe(map(() => key), shareReplay(1));
143
118
  }
144
119
  /**
145
120
  * Dispatch action to query remote storage for all entities and
146
121
  * merge the queried entities into the cached collection.
147
- * @see load()
148
- * @param {?=} options
149
- * @return {?} A terminating Observable of the queried entities that are in the collection
122
+ * @returns A terminating Observable of the queried entities that are in the collection
150
123
  * after server reports success query or the query error.
124
+ * @see load()
151
125
  */
152
126
  getAll(options) {
153
127
  options = this.setQueryEntityActionOptions(options);
154
- /** @type {?} */
155
128
  const action = this.createEntityAction(EntityOp.QUERY_ALL, null, options);
156
129
  this.dispatch(action);
157
130
  return this.getResponseData$(options.correlationId).pipe(
158
131
  // Use the returned entity ids to get the entities from the collection
159
132
  // as they might be different from the entities returned from the server
160
133
  // because of unsaved changes (deletes or updates).
161
- withLatestFrom(this.entityCollection$), map((/**
162
- * @param {?} __0
163
- * @return {?}
164
- */
165
- ([entities, collection]) => entities.reduce((/**
166
- * @param {?} acc
167
- * @param {?} e
168
- * @return {?}
169
- */
170
- (acc, e) => {
171
- /** @type {?} */
134
+ withLatestFrom(this.entityCollection$), map(([entities, collection]) => entities.reduce((acc, e) => {
172
135
  const entity = collection.entities[this.selectId(e)];
173
136
  if (entity) {
174
137
  acc.push(entity); // only return an entity found in the collection
175
138
  }
176
139
  return acc;
177
- }), (/** @type {?} */ ([]))))), shareReplay(1));
140
+ }, [])), shareReplay(1));
178
141
  }
179
142
  /**
180
143
  * Dispatch action to query remote storage for the entity with this primary key.
181
144
  * If the server returns an entity,
182
145
  * merge it into the cached collection.
183
- * @param {?} key
184
- * @param {?=} options
185
- * @return {?} A terminating Observable of the collection
146
+ * @returns A terminating Observable of the collection
186
147
  * after server reports successful query or the query error.
187
148
  */
188
149
  getByKey(key, options) {
189
150
  options = this.setQueryEntityActionOptions(options);
190
- /** @type {?} */
191
151
  const action = this.createEntityAction(EntityOp.QUERY_BY_KEY, key, options);
192
152
  this.dispatch(action);
193
153
  return this.getResponseData$(options.correlationId).pipe(
194
154
  // Use the returned entity data's id to get the entity from the collection
195
155
  // as it might be different from the entity returned from the server.
196
- withLatestFrom(this.entityCollection$), map((/**
197
- * @param {?} __0
198
- * @return {?}
199
- */
200
- ([entity, collection]) => (/** @type {?} */ (collection.entities[this.selectId(entity)])))), shareReplay(1));
156
+ withLatestFrom(this.entityCollection$), map(([entity, collection]) => collection.entities[this.selectId(entity)]), shareReplay(1));
201
157
  }
202
158
  /**
203
159
  * Dispatch action to query remote storage for the entities that satisfy a query expressed
204
160
  * with either a query parameter map or an HTTP URL query string,
205
161
  * and merge the results into the cached collection.
206
- * @param {?} queryParams the query in a form understood by the server
207
- * @param {?=} options
208
- * @return {?} A terminating Observable of the queried entities
162
+ * @param queryParams the query in a form understood by the server
163
+ * @returns A terminating Observable of the queried entities
209
164
  * after server reports successful query or the query error.
210
165
  */
211
166
  getWithQuery(queryParams, options) {
212
167
  options = this.setQueryEntityActionOptions(options);
213
- /** @type {?} */
214
168
  const action = this.createEntityAction(EntityOp.QUERY_MANY, queryParams, options);
215
169
  this.dispatch(action);
216
170
  return this.getResponseData$(options.correlationId).pipe(
217
171
  // Use the returned entity ids to get the entities from the collection
218
172
  // as they might be different from the entities returned from the server
219
173
  // because of unsaved changes (deletes or updates).
220
- withLatestFrom(this.entityCollection$), map((/**
221
- * @param {?} __0
222
- * @return {?}
223
- */
224
- ([entities, collection]) => entities.reduce((/**
225
- * @param {?} acc
226
- * @param {?} e
227
- * @return {?}
228
- */
229
- (acc, e) => {
230
- /** @type {?} */
174
+ withLatestFrom(this.entityCollection$), map(([entities, collection]) => entities.reduce((acc, e) => {
231
175
  const entity = collection.entities[this.selectId(e)];
232
176
  if (entity) {
233
177
  acc.push(entity); // only return an entity found in the collection
234
178
  }
235
179
  return acc;
236
- }), (/** @type {?} */ ([]))))), shareReplay(1));
180
+ }, [])), shareReplay(1));
237
181
  }
238
182
  /**
239
183
  * Dispatch action to query remote storage for all entities and
240
184
  * completely replace the cached collection with the queried entities.
241
- * @see getAll
242
- * @param {?=} options
243
- * @return {?} A terminating Observable of the entities in the collection
185
+ * @returns A terminating Observable of the entities in the collection
244
186
  * after server reports successful query or the query error.
187
+ * @see getAll
245
188
  */
246
189
  load(options) {
247
190
  options = this.setQueryEntityActionOptions(options);
248
- /** @type {?} */
249
191
  const action = this.createEntityAction(EntityOp.QUERY_LOAD, null, options);
250
192
  this.dispatch(action);
251
193
  return this.getResponseData$(options.correlationId).pipe(shareReplay(1));
@@ -254,18 +196,15 @@ export class EntityDispatcherBase {
254
196
  * Dispatch action to save the updated entity (or partial entity) in remote storage.
255
197
  * The update entity may be partial (but must have its key)
256
198
  * in which case it patches the existing entity.
257
- * @param {?} entity update entity, which might be a partial of T but must at least have its key.
258
- * @param {?=} options
259
- * @return {?} A terminating Observable of the updated entity
199
+ * @param entity update entity, which might be a partial of T but must at least have its key.
200
+ * @returns A terminating Observable of the updated entity
260
201
  * after server reports successful save or the save error.
261
202
  */
262
203
  update(entity, options) {
263
204
  // update entity might be a partial of T but must at least have its key.
264
205
  // pass the Update<T> structure as the payload
265
- /** @type {?} */
266
206
  const update = this.toUpdate(entity);
267
207
  options = this.setSaveEntityActionOptions(options, this.defaultDispatcherOptions.optimisticUpdate);
268
- /** @type {?} */
269
208
  const action = this.createEntityAction(EntityOp.SAVE_UPDATE_ONE, update, options);
270
209
  if (options.isOptimistic) {
271
210
  this.guard.mustBeUpdate(action);
@@ -275,28 +214,18 @@ export class EntityDispatcherBase {
275
214
  // Use the update entity data id to get the entity from the collection
276
215
  // as might be different from the entity returned from the server
277
216
  // because the id changed or there are unsaved changes.
278
- map((/**
279
- * @param {?} updateData
280
- * @return {?}
281
- */
282
- (updateData) => updateData.changes)), withLatestFrom(this.entityCollection$), map((/**
283
- * @param {?} __0
284
- * @return {?}
285
- */
286
- ([e, collection]) => (/** @type {?} */ (collection.entities[this.selectId((/** @type {?} */ (e)))])))), shareReplay(1));
217
+ map((updateData) => updateData.changes), withLatestFrom(this.entityCollection$), map(([e, collection]) => collection.entities[this.selectId(e)]), shareReplay(1));
287
218
  }
288
219
  /**
289
220
  * Dispatch action to save a new or existing entity to remote storage.
290
221
  * Only dispatch this action if your server supports upsert.
291
- * @param {?} entity entity to add, which may omit its key if pessimistic and the server creates the key;
222
+ * @param entity entity to add, which may omit its key if pessimistic and the server creates the key;
292
223
  * must have a key if optimistic save.
293
- * @param {?=} options
294
- * @return {?} A terminating Observable of the entity
224
+ * @returns A terminating Observable of the entity
295
225
  * after server reports successful save or the save error.
296
226
  */
297
227
  upsert(entity, options) {
298
228
  options = this.setSaveEntityActionOptions(options, this.defaultDispatcherOptions.optimisticUpsert);
299
- /** @type {?} */
300
229
  const action = this.createEntityAction(EntityOp.SAVE_UPSERT_ONE, entity, options);
301
230
  if (options.isOptimistic) {
302
231
  this.guard.mustBeEntity(action);
@@ -305,11 +234,7 @@ export class EntityDispatcherBase {
305
234
  return this.getResponseData$(options.correlationId).pipe(
306
235
  // Use the returned entity data's id to get the entity from the collection
307
236
  // as it might be different from the entity returned from the server.
308
- withLatestFrom(this.entityCollection$), map((/**
309
- * @param {?} __0
310
- * @return {?}
311
- */
312
- ([e, collection]) => (/** @type {?} */ (collection.entities[this.selectId(e)])))), shareReplay(1));
237
+ withLatestFrom(this.entityCollection$), map(([e, collection]) => collection.entities[this.selectId(e)]), shareReplay(1));
313
238
  }
314
239
  // #endregion Query and save operations
315
240
  // #region Cache-only operations that do not update remote storage
@@ -321,9 +246,6 @@ export class EntityDispatcherBase {
321
246
  /**
322
247
  * Replace all entities in the cached collection.
323
248
  * Does not save to remote storage.
324
- * @param {?} entities
325
- * @param {?=} options
326
- * @return {?}
327
249
  */
328
250
  addAllToCache(entities, options) {
329
251
  this.createAndDispatch(EntityOp.ADD_ALL, entities, options);
@@ -332,9 +254,6 @@ export class EntityDispatcherBase {
332
254
  * Add a new entity directly to the cache.
333
255
  * Does not save to remote storage.
334
256
  * Ignored if an entity with the same primary key is already in cache.
335
- * @param {?} entity
336
- * @param {?=} options
337
- * @return {?}
338
257
  */
339
258
  addOneToCache(entity, options) {
340
259
  this.createAndDispatch(EntityOp.ADD_ONE, entity, options);
@@ -343,46 +262,24 @@ export class EntityDispatcherBase {
343
262
  * Add multiple new entities directly to the cache.
344
263
  * Does not save to remote storage.
345
264
  * Entities with primary keys already in cache are ignored.
346
- * @param {?} entities
347
- * @param {?=} options
348
- * @return {?}
349
265
  */
350
266
  addManyToCache(entities, options) {
351
267
  this.createAndDispatch(EntityOp.ADD_MANY, entities, options);
352
268
  }
353
- /**
354
- * Clear the cached entity collection
355
- * @param {?=} options
356
- * @return {?}
357
- */
269
+ /** Clear the cached entity collection */
358
270
  clearCache(options) {
359
271
  this.createAndDispatch(EntityOp.REMOVE_ALL, undefined, options);
360
272
  }
361
- /**
362
- * @param {?} arg
363
- * @param {?=} options
364
- * @return {?}
365
- */
366
273
  removeOneFromCache(arg, options) {
367
274
  this.createAndDispatch(EntityOp.REMOVE_ONE, this.getKey(arg), options);
368
275
  }
369
- /**
370
- * @param {?} args
371
- * @param {?=} options
372
- * @return {?}
373
- */
374
276
  removeManyFromCache(args, options) {
375
277
  if (!args || args.length === 0) {
376
278
  return;
377
279
  }
378
- /** @type {?} */
379
280
  const keys = typeof args[0] === 'object'
380
281
  ? // if array[0] is a key, assume they're all keys
381
- ((/** @type {?} */ (args))).map((/**
382
- * @param {?} arg
383
- * @return {?}
384
- */
385
- (arg) => this.getKey(arg)))
282
+ args.map((arg) => this.getKey(arg))
386
283
  : args;
387
284
  this.createAndDispatch(EntityOp.REMOVE_MANY, keys, options);
388
285
  }
@@ -392,14 +289,10 @@ export class EntityDispatcherBase {
392
289
  * Ignored if an entity with matching primary key is not in cache.
393
290
  * The update entity may be partial (but must have its key)
394
291
  * in which case it patches the existing entity.
395
- * @param {?} entity
396
- * @param {?=} options
397
- * @return {?}
398
292
  */
399
293
  updateOneInCache(entity, options) {
400
294
  // update entity might be a partial of T but must at least have its key.
401
295
  // pass the Update<T> structure as the payload
402
- /** @type {?} */
403
296
  const update = this.toUpdate(entity);
404
297
  this.createAndDispatch(EntityOp.UPDATE_ONE, update, options);
405
298
  }
@@ -409,20 +302,12 @@ export class EntityDispatcherBase {
409
302
  * Entities whose primary keys are not in cache are ignored.
410
303
  * Update entities may be partial but must at least have their keys.
411
304
  * such partial entities patch their cached counterparts.
412
- * @param {?} entities
413
- * @param {?=} options
414
- * @return {?}
415
305
  */
416
306
  updateManyInCache(entities, options) {
417
307
  if (!entities || entities.length === 0) {
418
308
  return;
419
309
  }
420
- /** @type {?} */
421
- const updates = entities.map((/**
422
- * @param {?} entity
423
- * @return {?}
424
- */
425
- (entity) => this.toUpdate(entity)));
310
+ const updates = entities.map((entity) => this.toUpdate(entity));
426
311
  this.createAndDispatch(EntityOp.UPDATE_MANY, updates, options);
427
312
  }
428
313
  /**
@@ -430,9 +315,6 @@ export class EntityDispatcherBase {
430
315
  * Does not save to remote storage.
431
316
  * Upsert entity might be a partial of T but must at least have its key.
432
317
  * Pass the Update<T> structure as the payload
433
- * @param {?} entity
434
- * @param {?=} options
435
- * @return {?}
436
318
  */
437
319
  upsertOneInCache(entity, options) {
438
320
  this.createAndDispatch(EntityOp.UPSERT_ONE, entity, options);
@@ -440,9 +322,6 @@ export class EntityDispatcherBase {
440
322
  /**
441
323
  * Add or update multiple cached entities directly.
442
324
  * Does not save to remote storage.
443
- * @param {?} entities
444
- * @param {?=} options
445
- * @return {?}
446
325
  */
447
326
  upsertManyInCache(entities, options) {
448
327
  if (!entities || entities.length === 0) {
@@ -453,49 +332,31 @@ export class EntityDispatcherBase {
453
332
  /**
454
333
  * Set the pattern that the collection's filter applies
455
334
  * when using the `filteredEntities` selector.
456
- * @param {?} pattern
457
- * @return {?}
458
335
  */
459
336
  setFilter(pattern) {
460
337
  this.createAndDispatch(EntityOp.SET_FILTER, pattern);
461
338
  }
462
- /**
463
- * Set the loaded flag
464
- * @param {?} isLoaded
465
- * @return {?}
466
- */
339
+ /** Set the loaded flag */
467
340
  setLoaded(isLoaded) {
468
341
  this.createAndDispatch(EntityOp.SET_LOADED, !!isLoaded);
469
342
  }
470
- /**
471
- * Set the loading flag
472
- * @param {?} isLoading
473
- * @return {?}
474
- */
343
+ /** Set the loading flag */
475
344
  setLoading(isLoading) {
476
345
  this.createAndDispatch(EntityOp.SET_LOADING, !!isLoading);
477
346
  }
478
347
  // #endregion Cache-only operations that do not update remote storage
479
348
  // #region private helpers
480
- /**
481
- * Get key from entity (unless arg is already a key)
482
- * @private
483
- * @param {?} arg
484
- * @return {?}
485
- */
349
+ /** Get key from entity (unless arg is already a key) */
486
350
  getKey(arg) {
487
351
  return typeof arg === 'object'
488
352
  ? this.selectId(arg)
489
- : ((/** @type {?} */ (arg)));
353
+ : arg;
490
354
  }
491
355
  /**
492
356
  * Return Observable of data from the server-success EntityAction with
493
357
  * the given Correlation Id, after that action was processed by the ngrx store.
494
358
  * or else put the server error on the Observable error channel.
495
- * @private
496
- * @template D
497
- * @param {?} crid The correlationId for both the save and response actions.
498
- * @return {?}
359
+ * @param crid The correlationId for both the save and response actions.
499
360
  */
500
361
  getResponseData$(crid) {
501
362
  /**
@@ -503,121 +364,38 @@ export class EntityDispatcherBase {
503
364
  * because the response action might have been dispatched to the store
504
365
  * before caller had a chance to subscribe.
505
366
  */
506
- return this.reducedActions$.pipe(filter((/**
507
- * @param {?} act
508
- * @return {?}
509
- */
510
- (act) => !!act.payload)), filter((/**
511
- * @param {?} act
512
- * @return {?}
513
- */
514
- (act) => {
367
+ return this.reducedActions$.pipe(filter((act) => !!act.payload), filter((act) => {
515
368
  const { correlationId, entityName, entityOp } = act.payload;
516
369
  return (entityName === this.entityName &&
517
370
  correlationId === crid &&
518
371
  (entityOp.endsWith(OP_SUCCESS) ||
519
372
  entityOp.endsWith(OP_ERROR) ||
520
373
  entityOp === EntityOp.CANCEL_PERSIST));
521
- })), take(1), mergeMap((/**
522
- * @param {?} act
523
- * @return {?}
524
- */
525
- (act) => {
374
+ }), take(1), mergeMap((act) => {
526
375
  const { entityOp } = act.payload;
527
376
  return entityOp === EntityOp.CANCEL_PERSIST
528
377
  ? throwError(new PersistanceCanceled(act.payload.data))
529
378
  : entityOp.endsWith(OP_SUCCESS)
530
- ? of((/** @type {?} */ (act.payload.data)))
379
+ ? of(act.payload.data)
531
380
  : throwError(act.payload.data.error);
532
- })));
381
+ }));
533
382
  }
534
- /**
535
- * @private
536
- * @param {?=} options
537
- * @return {?}
538
- */
539
383
  setQueryEntityActionOptions(options) {
540
384
  options = options || {};
541
- /** @type {?} */
542
385
  const correlationId = options.correlationId == null
543
386
  ? this.correlationIdGenerator.next()
544
387
  : options.correlationId;
545
388
  return Object.assign(Object.assign({}, options), { correlationId });
546
389
  }
547
- /**
548
- * @private
549
- * @param {?=} options
550
- * @param {?=} defaultOptimism
551
- * @return {?}
552
- */
553
390
  setSaveEntityActionOptions(options, defaultOptimism) {
554
391
  options = options || {};
555
- /** @type {?} */
556
392
  const correlationId = options.correlationId == null
557
393
  ? this.correlationIdGenerator.next()
558
394
  : options.correlationId;
559
- /** @type {?} */
560
395
  const isOptimistic = options.isOptimistic == null
561
396
  ? defaultOptimism || false
562
397
  : options.isOptimistic === true;
563
398
  return Object.assign(Object.assign({}, options), { correlationId, isOptimistic });
564
399
  }
565
400
  }
566
- if (false) {
567
- /**
568
- * Utility class with methods to validate EntityAction payloads.
569
- * @type {?}
570
- */
571
- EntityDispatcherBase.prototype.guard;
572
- /**
573
- * @type {?}
574
- * @private
575
- */
576
- EntityDispatcherBase.prototype.entityCollection$;
577
- /**
578
- * Convert an entity (or partial entity) into the `Update<T>` object
579
- * `update...` and `upsert...` methods take `Update<T>` args
580
- * @type {?}
581
- */
582
- EntityDispatcherBase.prototype.toUpdate;
583
- /**
584
- * Name of the entity type for which entities are dispatched
585
- * @type {?}
586
- */
587
- EntityDispatcherBase.prototype.entityName;
588
- /**
589
- * Creates an {EntityAction}
590
- * @type {?}
591
- */
592
- EntityDispatcherBase.prototype.entityActionFactory;
593
- /**
594
- * The store, scoped to the EntityCache
595
- * @type {?}
596
- */
597
- EntityDispatcherBase.prototype.store;
598
- /**
599
- * Returns the primary key (id) of this entity
600
- * @type {?}
601
- */
602
- EntityDispatcherBase.prototype.selectId;
603
- /**
604
- * Dispatcher options configure dispatcher behavior such as
605
- * whether add is optimistic or pessimistic by default.
606
- * @type {?}
607
- * @private
608
- */
609
- EntityDispatcherBase.prototype.defaultDispatcherOptions;
610
- /**
611
- * Actions scanned by the store after it processed them with reducers.
612
- * @type {?}
613
- * @private
614
- */
615
- EntityDispatcherBase.prototype.reducedActions$;
616
- /**
617
- * Generates correlation ids for query and save methods
618
- * @type {?}
619
- * @private
620
- */
621
- EntityDispatcherBase.prototype.correlationIdGenerator;
622
- }
623
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWRpc3BhdGNoZXItYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLi8uLi9tb2R1bGVzL2RhdGEvIiwic291cmNlcyI6WyJzcmMvZGlzcGF0Y2hlcnMvZW50aXR5LWRpc3BhdGNoZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBVSxjQUFjLEVBQVMsTUFBTSxhQUFhLENBQUM7QUFHNUQsT0FBTyxFQUFjLEVBQUUsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEQsT0FBTyxFQUNMLE1BQU0sRUFDTixHQUFHLEVBQ0gsUUFBUSxFQUNSLFdBQVcsRUFDWCxjQUFjLEVBQ2QsSUFBSSxHQUNMLE1BQU0sZ0JBQWdCLENBQUM7QUFHeEIsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUd0RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUtuRSxPQUFPLEVBQW9CLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFNUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7OztBQVN0RSxNQUFNLE9BQU8sb0JBQW9COzs7Ozs7Ozs7OztJQVkvQixZQUVTLFVBQWtCLEVBRWxCLG1CQUF3QyxFQUV4QyxLQUF5QixFQUV6QixXQUEwQixlQUFlLEVBS3hDLHdCQUF3RCxFQUV4RCxlQUFtQztJQUMzQyx5Q0FBeUM7SUFDekMsbUJBQXdDLEVBRWhDLHNCQUE4QztRQWpCL0MsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUVsQix3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBRXhDLFVBQUssR0FBTCxLQUFLLENBQW9CO1FBRXpCLGFBQVEsR0FBUixRQUFRLENBQWlDO1FBS3hDLDZCQUF3QixHQUF4Qix3QkFBd0IsQ0FBZ0M7UUFFeEQsb0JBQWUsR0FBZixlQUFlLENBQW9CO1FB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ZXNDb250ZW50IjpbImltcG9ydCB7IEFjdGlvbiwgY3JlYXRlU2VsZWN0b3IsIFN0b3JlIH0gZnJvbSAnQG5ncngvc3RvcmUnO1xuaW1wb3J0IHsgSWRTZWxlY3RvciwgVXBkYXRlIH0gZnJvbSAnQG5ncngvZW50aXR5JztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YsIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGZpbHRlcixcbiAgbWFwLFxuICBtZXJnZU1hcCxcbiAgc2hhcmVSZXBsYXksXG4gIHdpdGhMYXRlc3RGcm9tLFxuICB0YWtlLFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IENvcnJlbGF0aW9uSWRHZW5lcmF0b3IgfSBmcm9tICcuLi91dGlscy9jb3JyZWxhdGlvbi1pZC1nZW5lcmF0b3InO1xuaW1wb3J0IHsgZGVmYXVsdFNlbGVjdElkLCB0b1VwZGF0ZUZhY3RvcnkgfSBmcm9tICcuLi91dGlscy91dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5QWN0aW9uLCBFbnRpdHlBY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbkZhY3RvcnkgfSBmcm9tICcuLi9hY3Rpb25zL2VudGl0eS1hY3Rpb24tZmFjdG9yeSc7XG5pbXBvcnQgeyBFbnRpdHlBY3Rpb25HdWFyZCB9IGZyb20gJy4uL2FjdGlvbnMvZW50aXR5LWFjdGlvbi1ndWFyZCc7XG5pbXBvcnQgeyBFbnRpdHlDYWNoZSB9IGZyb20gJy4uL3JlZHVjZXJzL2VudGl0eS1jYWNoZSc7XG5pbXBvcnQgeyBFbnRpdHlDYWNoZVNlbGVjdG9yIH0gZnJvbSAnLi4vc2VsZWN0b3JzL2VudGl0eS1jYWNoZS1zZWxlY3Rvcic7XG5pbXBvcnQgeyBFbnRpdHlDb2xsZWN0aW9uIH0gZnJvbSAnLi4vcmVkdWNlcnMvZW50aXR5LWNvbGxlY3Rpb24nO1xuaW1wb3J0IHsgRW50aXR5Q29tbWFuZHMgfSBmcm9tICcuL2VudGl0eS1jb21tYW5kcyc7XG5pbXBvcnQgeyBFbnRpdHlEaXNwYXRjaGVyLCBQZXJzaXN0YW5jZUNhbmNlbGVkIH0gZnJvbSAnLi9lbnRpdHktZGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBFbnRpdHlEaXNwYXRjaGVyRGVmYXVsdE9wdGlvbnMgfSBmcm9tICcuL2VudGl0eS1kaXNwYXRjaGVyLWRlZmF1bHQtb3B0aW9ucyc7XG5pbXBvcnQgeyBFbnRpdHlPcCwgT1BfRVJST1IsIE9QX1NVQ0NFU1MgfSBmcm9tICcuLi9hY3Rpb25zL2VudGl0eS1vcCc7XG5pbXBvcnQgeyBNZXJnZVN0cmF0ZWd5IH0gZnJvbSAnLi4vYWN0aW9ucy9tZXJnZS1zdHJhdGVneSc7XG5pbXBvcnQgeyBRdWVyeVBhcmFtcyB9IGZyb20gJy4uL2RhdGFzZXJ2aWNlcy9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFVwZGF0ZVJlc3BvbnNlRGF0YSB9IGZyb20gJy4uL2FjdGlvbnMvdXBkYXRlLXJlc3BvbnNlLWRhdGEnO1xuXG4vKipcbiAqIERpc3BhdGNoZXMgRW50aXR5Q29sbGVjdGlvbiBhY3Rpb25zIHRvIHRoZWlyIHJlZHVjZXJzIGFuZCBlZmZlY3RzIChkZWZhdWx0IGltcGxlbWVudGF0aW9uKS5cbiAqIEFsbCBzYXZlIGNvbW1hbmRzIHJlbHkgb24gYW4gTmdyeCBFZmZlY3Qgc3VjaCBhcyBgRW50aXR5RWZmZWN0cy5wZXJzaXN0JGAuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbnRpdHlEaXNwYXRjaGVyQmFzZTxUPiBpbXBsZW1lbnRzIEVudGl0eURpc3BhdGNoZXI8VD4ge1xuICAvKiogVXRpbGl0eSBjbGFzcyB3aXRoIG1ldGhvZHMgdG8gdmFsaWRhdGUgRW50aXR5QWN0aW9uIHBheWxvYWRzLiovXG4gIGd1YXJkOiBFbnRpdHlBY3Rpb25HdWFyZDxUPjtcblxuICBwcml2YXRlIGVudGl0eUNvbGxlY3Rpb24kOiBPYnNlcnZhYmxlPEVudGl0eUNvbGxlY3Rpb248VD4+O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkpIGludG8gdGhlIGBVcGRhdGU8VD5gIG9iamVjdFxuICAgKiBgdXBkYXRlLi4uYCBhbmQgYHVwc2VydC4uLmAgbWV0aG9kcyB0YWtlIGBVcGRhdGU8VD5gIGFyZ3NcbiAgICovXG4gIHRvVXBkYXRlOiAoZW50aXR5OiBQYXJ0aWFsPFQ+KSA9PiBVcGRhdGU8VD47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLyoqIE5hbWUgb2YgdGhlIGVudGl0eSB0eXBlIGZvciB3aGljaCBlbnRpdGllcyBhcmUgZGlzcGF0Y2hlZCAqL1xuICAgIHB1YmxpYyBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgLyoqIENyZWF0ZXMgYW4ge0VudGl0eUFjdGlvbn0gKi9cbiAgICBwdWJsaWMgZW50aXR5QWN0aW9uRmFjdG9yeTogRW50aXR5QWN0aW9uRmFjdG9yeSxcbiAgICAvKiogVGhlIHN0b3JlLCBzY29wZWQgdG8gdGhlIEVudGl0eUNhY2hlICovXG4gICAgcHVibGljIHN0b3JlOiBTdG9yZTxFbnRpdHlDYWNoZT4sXG4gICAgLyoqIFJldHVybnMgdGhlIHByaW1hcnkga2V5IChpZCkgb2YgdGhpcyBlbnRpdHkgKi9cbiAgICBwdWJsaWMgc2VsZWN0SWQ6IElkU2VsZWN0b3I8VD4gPSBkZWZhdWx0U2VsZWN0SWQsXG4gICAgLyoqXG4gICAgICogRGlzcGF0Y2hlciBvcHRpb25zIGNvbmZpZ3VyZSBkaXNwYXRjaGVyIGJlaGF2aW9yIHN1Y2ggYXNcbiAgICAgKiB3aGV0aGVyIGFkZCBpcyBvcHRpbWlzdGljIG9yIHBlc3NpbWlzdGljIGJ5IGRlZmF1bHQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBkZWZhdWx0RGlzcGF0Y2hlck9wdGlvbnM6IEVudGl0eURpc3BhdGNoZXJEZWZhdWx0T3B0aW9ucyxcbiAgICAvKiogQWN0aW9ucyBzY2FubmVkIGJ5IHRoZSBzdG9yZSBhZnRlciBpdCBwcm9jZXNzZWQgdGhlbSB3aXRoIHJlZHVjZXJzLiAqL1xuICAgIHByaXZhdGUgcmVkdWNlZEFjdGlvbnMkOiBPYnNlcnZhYmxlPEFjdGlvbj4sXG4gICAgLyoqIFN0b3JlIHNlbGVjdG9yIGZvciB0aGUgRW50aXR5Q2FjaGUgKi9cbiAgICBlbnRpdHlDYWNoZVNlbGVjdG9yOiBFbnRpdHlDYWNoZVNlbGVjdG9yLFxuICAgIC8qKiBHZW5lcmF0ZXMgY29ycmVsYXRpb24gaWRzIGZvciBxdWVyeSBhbmQgc2F2ZSBtZXRob2RzICovXG4gICAgcHJpdmF0ZSBjb3JyZWxhdGlvbklkR2VuZXJhdG9yOiBDb3JyZWxhdGlvbklkR2VuZXJhdG9yXG4gICkge1xuICAgIHRoaXMuZ3VhcmQgPSBuZXcgRW50aXR5QWN0aW9uR3VhcmQoZW50aXR5TmFtZSwgc2VsZWN0SWQpO1xuICAgIHRoaXMudG9VcGRhdGUgPSB0b1VwZGF0ZUZhY3Rvcnk8VD4oc2VsZWN0SWQpO1xuXG4gICAgY29uc3QgY29sbGVjdGlvblNlbGVjdG9yID0gY3JlYXRlU2VsZWN0b3IoXG4gICAgICBlbnRpdHlDYWNoZVNlbGVjdG9yLFxuICAgICAgKGNhY2hlKSA9PiBjYWNoZVtlbnRpdHlOYW1lXSBhcyBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICAgKTtcbiAgICB0aGlzLmVudGl0eUNvbGxlY3Rpb24kID0gc3RvcmUuc2VsZWN0KGNvbGxlY3Rpb25TZWxlY3Rvcik7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIHtFbnRpdHlBY3Rpb259IGZvciB0aGlzIGVudGl0eSB0eXBlLlxuICAgKiBAcGFyYW0gZW50aXR5T3Age0VudGl0eU9wfSB0aGUgZW50aXR5IG9wZXJhdGlvblxuICAgKiBAcGFyYW0gW2RhdGFdIHRoZSBhY3Rpb24gZGF0YVxuICAgKiBAcGFyYW0gW29wdGlvbnNdIGFkZGl0aW9uYWwgb3B0aW9uc1xuICAgKiBAcmV0dXJucyB0aGUgRW50aXR5QWN0aW9uXG4gICAqL1xuICBjcmVhdGVFbnRpdHlBY3Rpb248UCA9IGFueT4oXG4gICAgZW50aXR5T3A6IEVudGl0eU9wLFxuICAgIGRhdGE/OiBQLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IEVudGl0eUFjdGlvbjxQPiB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5QWN0aW9uRmFjdG9yeS5jcmVhdGUoe1xuICAgICAgZW50aXR5TmFtZTogdGhpcy5lbnRpdHlOYW1lLFxuICAgICAgZW50aXR5T3AsXG4gICAgICBkYXRhLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4ge0VudGl0eUFjdGlvbn0gZm9yIHRoaXMgZW50aXR5IHR5cGUgYW5kXG4gICAqIGRpc3BhdGNoIGl0IGltbWVkaWF0ZWx5IHRvIHRoZSBzdG9yZS5cbiAgICogQHBhcmFtIG9wIHtFbnRpdHlPcH0gdGhlIGVudGl0eSBvcGVyYXRpb25cbiAgICogQHBhcmFtIFtkYXRhXSB0aGUgYWN0aW9uIGRhdGFcbiAgICogQHBhcmFtIFtvcHRpb25zXSBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgICogQHJldHVybnMgdGhlIGRpc3BhdGNoZWQgRW50aXR5QWN0aW9uXG4gICAqL1xuICBjcmVhdGVBbmREaXNwYXRjaDxQID0gYW55PihcbiAgICBvcDogRW50aXR5T3AsXG4gICAgZGF0YT86IFAsXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogRW50aXR5QWN0aW9uPFA+IHtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihvcCwgZGF0YSwgb3B0aW9ucyk7XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiBhY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYW4gQWN0aW9uIHRvIHRoZSBzdG9yZS5cbiAgICogQHBhcmFtIGFjdGlvbiB0aGUgQWN0aW9uXG4gICAqIEByZXR1cm5zIHRoZSBkaXNwYXRjaGVkIEFjdGlvblxuICAgKi9cbiAgZGlzcGF0Y2goYWN0aW9uOiBBY3Rpb24pOiBBY3Rpb24ge1xuICAgIHRoaXMuc3RvcmUuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gYWN0aW9uO1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBRdWVyeSBhbmQgc2F2ZSBvcGVyYXRpb25zXG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBzYXZlIGEgbmV3IGVudGl0eSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICogQHBhcmFtIGVudGl0eSBlbnRpdHkgdG8gYWRkLCB3aGljaCBtYXkgb21pdCBpdHMga2V5IGlmIHBlc3NpbWlzdGljIGFuZCB0aGUgc2VydmVyIGNyZWF0ZXMgdGhlIGtleTtcbiAgICogbXVzdCBoYXZlIGEga2V5IGlmIG9wdGltaXN0aWMgc2F2ZS5cbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBlbnRpdHlcbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2Vzc2Z1bCBzYXZlIG9yIHRoZSBzYXZlIGVycm9yLlxuICAgKi9cbiAgYWRkKGVudGl0eTogVCwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICBvcHRpb25zID0gdGhpcy5zZXRTYXZlRW50aXR5QWN0aW9uT3B0aW9ucyhcbiAgICAgIG9wdGlvbnMsXG4gICAgICB0aGlzLmRlZmF1bHREaXNwYXRjaGVyT3B0aW9ucy5vcHRpbWlzdGljQWRkXG4gICAgKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihcbiAgICAgIEVudGl0eU9wLlNBVkVfQUREX09ORSxcbiAgICAgIGVudGl0eSxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuICAgIGlmIChvcHRpb25zLmlzT3B0aW1pc3RpYykge1xuICAgICAgdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICB9XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8VD4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgLy8gVXNlIHRoZSByZXR1cm5lZCBlbnRpdHkgZGF0YSdzIGlkIHRvIGdldCB0aGUgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb25cbiAgICAgIC8vIGFzIGl0IG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBlbnRpdHkgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyLlxuICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5lbnRpdHlDb2xsZWN0aW9uJCksXG4gICAgICBtYXAoKFtlLCBjb2xsZWN0aW9uXSkgPT4gY29sbGVjdGlvbi5lbnRpdGllc1t0aGlzLnNlbGVjdElkKGUpXSEpLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBjYW5jZWwgdGhlIHBlcnNpc3RlbmNlIG9wZXJhdGlvbiAocXVlcnkgb3Igc2F2ZSkuXG4gICAqIFdpbGwgY2F1c2Ugc2F2ZSBvYnNlcnZhYmxlIHRvIGVycm9yIHdpdGggYSBQZXJzaXN0ZW5jZUNhbmNlbCBlcnJvci5cbiAgICogQ2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciB1bmRvaW5nIGNoYW5nZXMgaW4gY2FjaGUgZnJvbSBwZW5kaW5nIG9wdGltaXN0aWMgc2F2ZVxuICAgKiBAcGFyYW0gY29ycmVsYXRpb25JZCBUaGUgY29ycmVsYXRpb24gaWQgZm9yIHRoZSBjb3JyZXNwb25kaW5nIEVudGl0eUFjdGlvblxuICAgKiBAcGFyYW0gW3JlYXNvbl0gZXhwbGFpbnMgd2h5IGNhbmNlbGVkIGFuZCBieSB3aG9tLlxuICAgKi9cbiAgY2FuY2VsKFxuICAgIGNvcnJlbGF0aW9uSWQ6IGFueSxcbiAgICByZWFzb24/OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogdm9pZCB7XG4gICAgaWYgKCFjb3JyZWxhdGlvbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgY29ycmVsYXRpb25JZCcpO1xuICAgIH1cbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLkNBTkNFTF9QRVJTSVNULCByZWFzb24sIHsgY29ycmVsYXRpb25JZCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gZGVsZXRlIGVudGl0eSBmcm9tIHJlbW90ZSBzdG9yYWdlIGJ5IGtleS5cbiAgICogQHBhcmFtIGtleSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIGVudGl0eSB0byByZW1vdmVcbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBkZWxldGVkIGtleVxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzZnVsIHNhdmUgb3IgdGhlIHNhdmUgZXJyb3IuXG4gICAqL1xuICBkZWxldGUoZW50aXR5OiBULCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IE9ic2VydmFibGU8bnVtYmVyIHwgc3RyaW5nPjtcblxuICAvKipcbiAgICogRGlzcGF0Y2ggYWN0aW9uIHRvIGRlbGV0ZSBlbnRpdHkgZnJvbSByZW1vdGUgc3RvcmFnZSBieSBrZXkuXG4gICAqIEBwYXJhbSBrZXkgVGhlIGVudGl0eSB0byBkZWxldGVcbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBkZWxldGVkIGtleVxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzZnVsIHNhdmUgb3IgdGhlIHNhdmUgZXJyb3IuXG4gICAqL1xuICBkZWxldGUoXG4gICAga2V5OiBudW1iZXIgfCBzdHJpbmcsXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogT2JzZXJ2YWJsZTxudW1iZXIgfCBzdHJpbmc+O1xuICBkZWxldGUoXG4gICAgYXJnOiBudW1iZXIgfCBzdHJpbmcgfCBULFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IE9ic2VydmFibGU8bnVtYmVyIHwgc3RyaW5nPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0U2F2ZUVudGl0eUFjdGlvbk9wdGlvbnMoXG4gICAgICBvcHRpb25zLFxuICAgICAgdGhpcy5kZWZhdWx0RGlzcGF0Y2hlck9wdGlvbnMub3B0aW1pc3RpY0RlbGV0ZVxuICAgICk7XG4gICAgY29uc3Qga2V5ID0gdGhpcy5nZXRLZXkoYXJnKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihcbiAgICAgIEVudGl0eU9wLlNBVkVfREVMRVRFX09ORSxcbiAgICAgIGtleSxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuICAgIHRoaXMuZ3VhcmQubXVzdEJlS2V5KGFjdGlvbik7XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8bnVtYmVyIHwgc3RyaW5nPihvcHRpb25zLmNvcnJlbGF0aW9uSWQpLnBpcGUoXG4gICAgICBtYXAoKCkgPT4ga2V5KSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gcXVlcnkgcmVtb3RlIHN0b3JhZ2UgZm9yIGFsbCBlbnRpdGllcyBhbmRcbiAgICogbWVyZ2UgdGhlIHF1ZXJpZWQgZW50aXRpZXMgaW50byB0aGUgY2FjaGVkIGNvbGxlY3Rpb24uXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgcXVlcmllZCBlbnRpdGllcyB0aGF0IGFyZSBpbiB0aGUgY29sbGVjdGlvblxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzIHF1ZXJ5IG9yIHRoZSBxdWVyeSBlcnJvci5cbiAgICogQHNlZSBsb2FkKClcbiAgICovXG4gIGdldEFsbChvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IE9ic2VydmFibGU8VFtdPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0UXVlcnlFbnRpdHlBY3Rpb25PcHRpb25zKG9wdGlvbnMpO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKEVudGl0eU9wLlFVRVJZX0FMTCwgbnVsbCwgb3B0aW9ucyk7XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8VFtdPihvcHRpb25zLmNvcnJlbGF0aW9uSWQpLnBpcGUoXG4gICAgICAvLyBVc2UgdGhlIHJldHVybmVkIGVudGl0eSBpZHMgdG8gZ2V0IHRoZSBlbnRpdGllcyBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAgICAvLyBhcyB0aGV5IG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBlbnRpdGllcyByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAgIC8vIGJlY2F1c2Ugb2YgdW5zYXZlZCBjaGFuZ2VzIChkZWxldGVzIG9yIHVwZGF0ZXMpLlxuICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5lbnRpdHlDb2xsZWN0aW9uJCksXG4gICAgICBtYXAoKFtlbnRpdGllcywgY29sbGVjdGlvbl0pID0+XG4gICAgICAgIGVudGl0aWVzLnJlZHVjZSgoYWNjLCBlKSA9PiB7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gY29sbGVjdGlvbi5lbnRpdGllc1t0aGlzLnNlbGVjdElkKGUpXTtcbiAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICBhY2MucHVzaChlbnRpdHkpOyAvLyBvbmx5IHJldHVybiBhbiBlbnRpdHkgZm91bmQgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwgW10gYXMgVFtdKVxuICAgICAgKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gcXVlcnkgcmVtb3RlIHN0b3JhZ2UgZm9yIHRoZSBlbnRpdHkgd2l0aCB0aGlzIHByaW1hcnkga2V5LlxuICAgKiBJZiB0aGUgc2VydmVyIHJldHVybnMgYW4gZW50aXR5LFxuICAgKiBtZXJnZSBpdCBpbnRvIHRoZSBjYWNoZWQgY29sbGVjdGlvbi5cbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBjb2xsZWN0aW9uXG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgcXVlcnkgb3IgdGhlIHF1ZXJ5IGVycm9yLlxuICAgKi9cbiAgZ2V0QnlLZXkoa2V5OiBhbnksIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0UXVlcnlFbnRpdHlBY3Rpb25PcHRpb25zKG9wdGlvbnMpO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKEVudGl0eU9wLlFVRVJZX0JZX0tFWSwga2V5LCBvcHRpb25zKTtcbiAgICB0aGlzLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVzcG9uc2VEYXRhJDxUPihvcHRpb25zLmNvcnJlbGF0aW9uSWQpLnBpcGUoXG4gICAgICAvLyBVc2UgdGhlIHJldHVybmVkIGVudGl0eSBkYXRhJ3MgaWQgdG8gZ2V0IHRoZSBlbnRpdHkgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgICAgLy8gYXMgaXQgbWlnaHQgYmUgZGlmZmVyZW50IGZyb20gdGhlIGVudGl0eSByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmVudGl0eUNvbGxlY3Rpb24kKSxcbiAgICAgIG1hcChcbiAgICAgICAgKFtlbnRpdHksIGNvbGxlY3Rpb25dKSA9PiBjb2xsZWN0aW9uLmVudGl0aWVzW3RoaXMuc2VsZWN0SWQoZW50aXR5KV0hXG4gICAgICApLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBxdWVyeSByZW1vdGUgc3RvcmFnZSBmb3IgdGhlIGVudGl0aWVzIHRoYXQgc2F0aXNmeSBhIHF1ZXJ5IGV4cHJlc3NlZFxuICAgKiB3aXRoIGVpdGhlciBhIHF1ZXJ5IHBhcmFtZXRlciBtYXAgb3IgYW4gSFRUUCBVUkwgcXVlcnkgc3RyaW5nLFxuICAgKiBhbmQgbWVyZ2UgdGhlIHJlc3VsdHMgaW50byB0aGUgY2FjaGVkIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSBxdWVyeVBhcmFtcyB0aGUgcXVlcnkgaW4gYSBmb3JtIHVuZGVyc3Rvb2QgYnkgdGhlIHNlcnZlclxuICAgKiBAcmV0dXJucyBBIHRlcm1pbmF0aW5nIE9ic2VydmFibGUgb2YgdGhlIHF1ZXJpZWQgZW50aXRpZXNcbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2Vzc2Z1bCBxdWVyeSBvciB0aGUgcXVlcnkgZXJyb3IuXG4gICAqL1xuICBnZXRXaXRoUXVlcnkoXG4gICAgcXVlcnlQYXJhbXM6IFF1ZXJ5UGFyYW1zIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IE9ic2VydmFibGU8VFtdPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0UXVlcnlFbnRpdHlBY3Rpb25PcHRpb25zKG9wdGlvbnMpO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKFxuICAgICAgRW50aXR5T3AuUVVFUllfTUFOWSxcbiAgICAgIHF1ZXJ5UGFyYW1zLFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8VFtdPihvcHRpb25zLmNvcnJlbGF0aW9uSWQpLnBpcGUoXG4gICAgICAvLyBVc2UgdGhlIHJldHVybmVkIGVudGl0eSBpZHMgdG8gZ2V0IHRoZSBlbnRpdGllcyBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAgICAvLyBhcyB0aGV5IG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBlbnRpdGllcyByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAgIC8vIGJlY2F1c2Ugb2YgdW5zYXZlZCBjaGFuZ2VzIChkZWxldGVzIG9yIHVwZGF0ZXMpLlxuICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5lbnRpdHlDb2xsZWN0aW9uJCksXG4gICAgICBtYXAoKFtlbnRpdGllcywgY29sbGVjdGlvbl0pID0+XG4gICAgICAgIGVudGl0aWVzLnJlZHVjZSgoYWNjLCBlKSA9PiB7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gY29sbGVjdGlvbi5lbnRpdGllc1t0aGlzLnNlbGVjdElkKGUpXTtcbiAgICAgICAgICBpZiAoZW50aXR5KSB7XG4gICAgICAgICAgICBhY2MucHVzaChlbnRpdHkpOyAvLyBvbmx5IHJldHVybiBhbiBlbnRpdHkgZm91bmQgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgfSwgW10gYXMgVFtdKVxuICAgICAgKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gcXVlcnkgcmVtb3RlIHN0b3JhZ2UgZm9yIGFsbCBlbnRpdGllcyBhbmRcbiAgICogY29tcGxldGVseSByZXBsYWNlIHRoZSBjYWNoZWQgY29sbGVjdGlvbiB3aXRoIHRoZSBxdWVyaWVkIGVudGl0aWVzLlxuICAgKiBAcmV0dXJucyBBIHRlcm1pbmF0aW5nIE9ic2VydmFibGUgb2YgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uXG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgcXVlcnkgb3IgdGhlIHF1ZXJ5IGVycm9yLlxuICAgKiBAc2VlIGdldEFsbFxuICAgKi9cbiAgbG9hZChvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IE9ic2VydmFibGU8VFtdPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0UXVlcnlFbnRpdHlBY3Rpb25PcHRpb25zKG9wdGlvbnMpO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKEVudGl0eU9wLlFVRVJZX0xPQUQsIG51bGwsIG9wdGlvbnMpO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPFRbXT4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBzYXZlIHRoZSB1cGRhdGVkIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkpIGluIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBUaGUgdXBkYXRlIGVudGl0eSBtYXkgYmUgcGFydGlhbCAoYnV0IG11c3QgaGF2ZSBpdHMga2V5KVxuICAgKiBpbiB3aGljaCBjYXNlIGl0IHBhdGNoZXMgdGhlIGV4aXN0aW5nIGVudGl0eS5cbiAgICogQHBhcmFtIGVudGl0eSB1cGRhdGUgZW50aXR5LCB3aGljaCBtaWdodCBiZSBhIHBhcnRpYWwgb2YgVCBidXQgbXVzdCBhdCBsZWFzdCBoYXZlIGl0cyBrZXkuXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgdXBkYXRlZCBlbnRpdHlcbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2Vzc2Z1bCBzYXZlIG9yIHRoZSBzYXZlIGVycm9yLlxuICAgKi9cbiAgdXBkYXRlKGVudGl0eTogUGFydGlhbDxUPiwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPFQ+IHtcbiAgICAvLyB1cGRhdGUgZW50aXR5IG1pZ2h0IGJlIGEgcGFydGlhbCBvZiBUIGJ1dCBtdXN0IGF0IGxlYXN0IGhhdmUgaXRzIGtleS5cbiAgICAvLyBwYXNzIHRoZSBVcGRhdGU8VD4gc3RydWN0dXJlIGFzIHRoZSBwYXlsb2FkXG4gICAgY29uc3QgdXBkYXRlID0gdGhpcy50b1VwZGF0ZShlbnRpdHkpO1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFNhdmVFbnRpdHlBY3Rpb25PcHRpb25zKFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHRoaXMuZGVmYXVsdERpc3BhdGNoZXJPcHRpb25zLm9wdGltaXN0aWNVcGRhdGVcbiAgICApO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKFxuICAgICAgRW50aXR5T3AuU0FWRV9VUERBVEVfT05FLFxuICAgICAgdXBkYXRlLFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gICAgaWYgKG9wdGlvbnMuaXNPcHRpbWlzdGljKSB7XG4gICAgICB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZShhY3Rpb24pO1xuICAgIH1cbiAgICB0aGlzLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVzcG9uc2VEYXRhJDxVcGRhdGVSZXNwb25zZURhdGE8VD4+KFxuICAgICAgb3B0aW9ucy5jb3JyZWxhdGlvbklkXG4gICAgKS5waXBlKFxuICAgICAgLy8gVXNlIHRoZSB1cGRhdGUgZW50aXR5IGRhdGEgaWQgdG8gZ2V0IHRoZSBlbnRpdHkgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgICAgLy8gYXMgbWlnaHQgYmUgZGlmZmVyZW50IGZyb20gdGhlIGVudGl0eSByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXJcbiAgICAgIC8vIGJlY2F1c2UgdGhlIGlkIGNoYW5nZWQgb3IgdGhlcmUgYXJlIHVuc2F2ZWQgY2hhbmdlcy5cbiAgICAgIG1hcCgodXBkYXRlRGF0YSkgPT4gdXBkYXRlRGF0YS5jaGFuZ2VzKSxcbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuZW50aXR5Q29sbGVjdGlvbiQpLFxuICAgICAgbWFwKChbZSwgY29sbGVjdGlvbl0pID0+IGNvbGxlY3Rpb24uZW50aXRpZXNbdGhpcy5zZWxlY3RJZChlIGFzIFQpXSEpLFxuICAgICAgc2hhcmVSZXBsYXkoMSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBzYXZlIGEgbmV3IG9yIGV4aXN0aW5nIGVudGl0eSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICogT25seSBkaXNwYXRjaCB0aGlzIGFjdGlvbiBpZiB5b3VyIHNlcnZlciBzdXBwb3J0cyB1cHNlcnQuXG4gICAqIEBwYXJhbSBlbnRpdHkgZW50aXR5IHRvIGFkZCwgd2hpY2ggbWF5IG9taXQgaXRzIGtleSBpZiBwZXNzaW1pc3RpYyBhbmQgdGhlIHNlcnZlciBjcmVhdGVzIHRoZSBrZXk7XG4gICAqIG11c3QgaGF2ZSBhIGtleSBpZiBvcHRpbWlzdGljIHNhdmUuXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgZW50aXR5XG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgc2F2ZSBvciB0aGUgc2F2ZSBlcnJvci5cbiAgICovXG4gIHVwc2VydChlbnRpdHk6IFQsIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0U2F2ZUVudGl0eUFjdGlvbk9wdGlvbnMoXG4gICAgICBvcHRpb25zLFxuICAgICAgdGhpcy5kZWZhdWx0RGlzcGF0Y2hlck9wdGlvbnMub3B0aW1pc3RpY1Vwc2VydFxuICAgICk7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5jcmVhdGVFbnRpdHlBY3Rpb24oXG4gICAgICBFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkUsXG4gICAgICBlbnRpdHksXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICBpZiAob3B0aW9ucy5pc09wdGltaXN0aWMpIHtcbiAgICAgIHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgfVxuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPFQ+KG9wdGlvbnMuY29ycmVsYXRpb25JZCkucGlwZShcbiAgICAgIC8vIFVzZSB0aGUgcmV0dXJuZWQgZW50aXR5IGRhdGEncyBpZCB0byBnZXQgdGhlIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAgICAvLyBhcyBpdCBtaWdodCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgZW50aXR5IHJldHVybmVkIGZyb20gdGhlIHNlcnZlci5cbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuZW50aXR5Q29sbGVjdGlvbiQpLFxuICAgICAgbWFwKChbZSwgY29sbGVjdGlvbl0pID0+IGNvbGxlY3Rpb24uZW50aXRpZXNbdGhpcy5zZWxlY3RJZChlKV0hKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIFF1ZXJ5IGFuZCBzYXZlIG9wZXJhdGlvbnNcblxuICAvLyAjcmVnaW9uIENhY2hlLW9ubHkgb3BlcmF0aW9ucyB0aGF0IGRvIG5vdCB1cGRhdGUgcmVtb3RlIHN0b3JhZ2VcblxuICAvLyBVbmd1YXJkZWQgZm9yIHBlcmZvcm1hbmNlLlxuICAvLyBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlcjxUPiBydW5zIGEgZ3VhcmQgKHdoaWNoIHRocm93cylcbiAgLy8gRGV2ZWxvcGVyIHNob3VsZCB1bmRlcnN0YW5kIGNhY2hlLW9ubHkgbWV0aG9kcyB3ZWxsIGVub3VnaFxuICAvLyB0byBjYWxsIHRoZW0gd2l0aCB0aGUgcHJvcGVyIGVudGl0aWVzLlxuICAvLyBNYXkgcmVjb25zaWRlciBhbmQgYWRkIGd1YXJkcyBpbiBmdXR1cmUuXG5cbiAgLyoqXG4gICAqIFJlcGxhY2UgYWxsIGVudGl0aWVzIGluIHRoZSBjYWNoZWQgY29sbGVjdGlvbi5cbiAgICogRG9lcyBub3Qgc2F2ZSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICovXG4gIGFkZEFsbFRvQ2FjaGUoZW50aXRpZXM6IFRbXSwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLkFERF9BTEwsIGVudGl0aWVzLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBuZXcgZW50aXR5IGRpcmVjdGx5IHRvIHRoZSBjYWNoZS5cbiAgICogRG9lcyBub3Qgc2F2ZSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICogSWdub3JlZCBpZiBhbiBlbnRpdHkgd2l0aCB0aGUgc2FtZSBwcmltYXJ5IGtleSBpcyBhbHJlYWR5IGluIGNhY2hlLlxuICAgKi9cbiAgYWRkT25lVG9DYWNoZShlbnRpdHk6IFQsIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5BRERfT05FLCBlbnRpdHksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBtdWx0aXBsZSBuZXcgZW50aXRpZXMgZGlyZWN0bHkgdG8gdGhlIGNhY2hlLlxuICAgKiBEb2VzIG5vdCBzYXZlIHRvIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBFbnRpdGllcyB3aXRoIHByaW1hcnkga2V5cyBhbHJlYWR5IGluIGNhY2hlIGFyZSBpZ25vcmVkLlxuICAgKi9cbiAgYWRkTWFueVRvQ2FjaGUoZW50aXRpZXM6IFRbXSwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiB2b2lkIHtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLkFERF9NQU5ZLCBlbnRpdGllcywgb3B0aW9ucyk7XG4gIH1cblxuICAvKiogQ2xlYXIgdGhlIGNhY2hlZCBlbnRpdHkgY29sbGVjdGlvbiAqL1xuICBjbGVhckNhY2hlKG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5SRU1PVkVfQUxMLCB1bmRlZmluZWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBlbnRpdHkgZGlyZWN0bHkgZnJvbSB0aGUgY2FjaGUuXG4gICAqIERvZXMgbm90IGRlbGV0ZSB0aGF0IGVudGl0eSBmcm9tIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBAcGFyYW0gZW50aXR5IFRoZSBlbnRpdHkgdG8gcmVtb3ZlXG4gICAqL1xuICByZW1vdmVPbmVGcm9tQ2FjaGUoZW50aXR5OiBULCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhbiBlbnRpdHkgZGlyZWN0bHkgZnJvbSB0aGUgY2FjaGUuXG4gICAqIERvZXMgbm90IGRlbGV0ZSB0aGF0IGVudGl0eSBmcm9tIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBwcmltYXJ5IGtleSBvZiB0aGUgZW50aXR5IHRvIHJlbW92ZVxuICAgKi9cbiAgcmVtb3ZlT25lRnJvbUNhY2hlKGtleTogbnVtYmVyIHwgc3RyaW5nLCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQ7XG4gIHJlbW92ZU9uZUZyb21DYWNoZShcbiAgICBhcmc6IChudW1iZXIgfCBzdHJpbmcpIHwgVCxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiB2b2lkIHtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlJFTU9WRV9PTkUsIHRoaXMuZ2V0S2V5KGFyZyksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBtdWx0aXBsZSBlbnRpdGllcyBkaXJlY3RseSBmcm9tIHRoZSBjYWNoZS5cbiAgICogRG9lcyBub3QgZGVsZXRlIHRoZXNlIGVudGl0aWVzIGZyb20gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSBlbnRpdHkgVGhlIGVudGl0aWVzIHRvIHJlbW92ZVxuICAgKi9cbiAgcmVtb3ZlTWFueUZyb21DYWNoZShlbnRpdGllczogVFtdLCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBtdWx0aXBsZSBlbnRpdGllcyBkaXJlY3RseSBmcm9tIHRoZSBjYWNoZS5cbiAgICogRG9lcyBub3QgZGVsZXRlIHRoZXNlIGVudGl0aWVzIGZyb20gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSBrZXlzIFRoZSBwcmltYXJ5IGtleXMgb2YgdGhlIGVudGl0aWVzIHRvIHJlbW92ZVxuICAgKi9cbiAgcmVtb3ZlTWFueUZyb21DYWNoZShcbiAgICBrZXlzOiAobnVtYmVyIHwgc3RyaW5nKVtdLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IHZvaWQ7XG4gIHJlbW92ZU1hbnlGcm9tQ2FjaGUoXG4gICAgYXJnczogKG51bWJlciB8IHN0cmluZylbXSB8IFRbXSxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiB2b2lkIHtcbiAgICBpZiAoIWFyZ3MgfHwgYXJncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qga2V5cyA9XG4gICAgICB0eXBlb2YgYXJnc1swXSA9PT0gJ29iamVjdCdcbiAgICAgICAgPyAvLyBpZiBhcnJheVswXSBpcyBhIGtleSwgYXNzdW1lIHRoZXkncmUgYWxsIGtleXNcbiAgICAgICAgICAoPFRbXT5hcmdzKS5tYXAoKGFyZykgPT4gdGhpcy5nZXRLZXkoYXJnKSlcbiAgICAgICAgOiBhcmdzO1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuUkVNT1ZFX01BTlksIGtleXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBhIGNhY2hlZCBlbnRpdHkgZGlyZWN0bHkuXG4gICAqIERvZXMgbm90IHVwZGF0ZSB0aGF0IGVudGl0eSBpbiByZW1vdGUgc3RvcmFnZS5cbiAgICogSWdub3JlZCBpZiBhbiBlbnRpdHkgd2l0aCBtYXRjaGluZyBwcmltYXJ5IGtleSBpcyBub3QgaW4gY2FjaGUuXG4gICAqIFRoZSB1cGRhdGUgZW50aXR5IG1heSBiZSBwYXJ0aWFsIChidXQgbXVzdCBoYXZlIGl0cyBrZXkpXG4gICAqIGluIHdoaWNoIGNhc2UgaXQgcGF0Y2hlcyB0aGUgZXhpc3RpbmcgZW50aXR5LlxuICAgKi9cbiAgdXBkYXRlT25lSW5DYWNoZShlbnRpdHk6IFBhcnRpYWw8VD4sIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgLy8gdXBkYXRlIGVudGl0eSBtaWdodCBiZSBhIHBhcnRpYWwgb2YgVCBidXQgbXVzdCBhdCBsZWFzdCBoYXZlIGl0cyBrZXkuXG4gICAgLy8gcGFzcyB0aGUgVXBkYXRlPFQ+IHN0cnVjdHVyZSBhcyB0aGUgcGF5bG9hZFxuICAgIGNvbnN0IHVwZGF0ZTogVXBkYXRlPFQ+ID0gdGhpcy50b1VwZGF0ZShlbnRpdHkpO1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuVVBEQVRFX09ORSwgdXBkYXRlLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgbXVsdGlwbGUgY2FjaGVkIGVudGl0aWVzIGRpcmVjdGx5LlxuICAgKiBEb2VzIG5vdCB1cGRhdGUgdGhlc2UgZW50aXRpZXMgaW4gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIEVudGl0aWVzIHdob3NlIHByaW1hcnkga2V5cyBhcmUgbm90IGluIGNhY2hlIGFyZSBpZ25vcmVkLlxuICAgKiBVcGRhdGUgZW50aXRpZXMgbWF5IGJlIHBhcnRpYWwgYnV0IG11c3QgYXQgbGVhc3QgaGF2ZSB0aGVpciBrZXlzLlxuICAgKiBzdWNoIHBhcnRpYWwgZW50aXRpZXMgcGF0Y2ggdGhlaXIgY2FjaGVkIGNvdW50ZXJwYXJ0cy5cbiAgICovXG4gIHVwZGF0ZU1hbnlJbkNhY2hlKFxuICAgIGVudGl0aWVzOiBQYXJ0aWFsPFQ+W10sXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogdm9pZCB7XG4gICAgaWYgKCFlbnRpdGllcyB8fCBlbnRpdGllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdXBkYXRlczogVXBkYXRlPFQ+W10gPSBlbnRpdGllcy5tYXAoKGVudGl0eSkgPT5cbiAgICAgIHRoaXMudG9VcGRhdGUoZW50aXR5KVxuICAgICk7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5VUERBVEVfTUFOWSwgdXBkYXRlcywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIG9yIHVwZGF0ZSBhIG5ldyBlbnRpdHkgZGlyZWN0bHkgdG8gdGhlIGNhY2hlLlxuICAgKiBEb2VzIG5vdCBzYXZlIHRvIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBVcHNlcnQgZW50aXR5IG1pZ2h0IGJlIGEgcGFydGlhbCBvZiBUIGJ1dCBtdXN0IGF0IGxlYXN0IGhhdmUgaXRzIGtleS5cbiAgICogUGFzcyB0aGUgVXBkYXRlPFQ+IHN0cnVjdHVyZSBhcyB0aGUgcGF5bG9hZFxuICAgKi9cbiAgdXBzZXJ0T25lSW5DYWNoZShlbnRpdHk6IFBhcnRpYWw8VD4sIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5VUFNFUlRfT05FLCBlbnRpdHksIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBvciB1cGRhdGUgbXVsdGlwbGUgY2FjaGVkIGVudGl0aWVzIGRpcmVjdGx5LlxuICAgKiBEb2VzIG5vdCBzYXZlIHRvIHJlbW90ZSBzdG9yYWdlLlxuICAgKi9cbiAgdXBzZXJ0TWFueUluQ2FjaGUoXG4gICAgZW50aXRpZXM6IFBhcnRpYWw8VD5bXSxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiB2b2lkIHtcbiAgICBpZiAoIWVudGl0aWVzIHx8IGVudGl0aWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlVQU0VSVF9NQU5ZLCBlbnRpdGllcywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBwYXR0ZXJuIHRoYXQgdGhlIGNvbGxlY3Rpb24ncyBmaWx0ZXIgYXBwbGllc1xuICAgKiB3aGVuIHVzaW5nIHRoZSBgZmlsdGVyZWRFbnRpdGllc2Agc2VsZWN0b3IuXG4gICAqL1xuICBzZXRGaWx0ZXIocGF0dGVybjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5TRVRfRklMVEVSLCBwYXR0ZXJuKTtcbiAgfVxuXG4gIC8qKiBTZXQgdGhlIGxvYWRlZCBmbGFnICovXG4gIHNldExvYWRlZChpc0xvYWRlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuU0VUX0xPQURFRCwgISFpc0xvYWRlZCk7XG4gIH1cblxuICAvKiogU2V0IHRoZSBsb2FkaW5nIGZsYWcgKi9cbiAgc2V0TG9hZGluZyhpc0xvYWRpbmc6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlNFVF9MT0FESU5HLCAhIWlzTG9hZGluZyk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBDYWNoZS1vbmx5IG9wZXJhdGlvbnMgdGhhdCBkbyBub3QgdXBkYXRlIHJlbW90ZSBzdG9yYWdlXG5cbiAgLy8gI3JlZ2lvbiBwcml2YXRlIGhlbHBlcnNcblxuICAvKiogR2V0IGtleSBmcm9tIGVudGl0eSAodW5sZXNzIGFyZyBpcyBhbHJlYWR5IGEga2V5KSAqL1xuICBwcml2YXRlIGdldEtleShhcmc6IG51bWJlciB8IHN0cmluZyB8IFQpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAgID8gdGhpcy5zZWxlY3RJZChhcmcpXG4gICAgICA6IChhcmcgYXMgbnVtYmVyIHwgc3RyaW5nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gT2JzZXJ2YWJsZSBvZiBkYXRhIGZyb20gdGhlIHNlcnZlci1zdWNjZXNzIEVudGl0eUFjdGlvbiB3aXRoXG4gICAqIHRoZSBnaXZlbiBDb3JyZWxhdGlvbiBJZCwgYWZ0ZXIgdGhhdCBhY3Rpb24gd2FzIHByb2Nlc3NlZCBieSB0aGUgbmdyeCBzdG9yZS5cbiAgICogb3IgZWxzZSBwdXQgdGhlIHNlcnZlciBlcnJvciBvbiB0aGUgT2JzZXJ2YWJsZSBlcnJvciBjaGFubmVsLlxuICAgKiBAcGFyYW0gY3JpZCBUaGUgY29ycmVsYXRpb25JZCBmb3IgYm90aCB0aGUgc2F2ZSBhbmQgcmVzcG9uc2UgYWN0aW9ucy5cbiAgICovXG4gIHByaXZhdGUgZ2V0UmVzcG9uc2VEYXRhJDxEID0gYW55PihjcmlkOiBhbnkpOiBPYnNlcnZhYmxlPEQ+IHtcbiAgICAvKipcbiAgICAgKiByZWR1Y2VkQWN0aW9ucyQgbXVzdCBiZSByZXBsYXkgb2JzZXJ2YWJsZSBvZiB0aGUgbW9zdCByZWNlbnQgYWN0aW9uIHJlZHVjZWQgYnkgdGhlIHN0b3JlLlxuICAgICAqIGJlY2F1c2UgdGhlIHJlc3BvbnNlIGFjdGlvbiBtaWdodCBoYXZlIGJlZW4gZGlzcGF0Y2hlZCB0byB0aGUgc3RvcmVcbiAgICAgKiBiZWZvcmUgY2FsbGVyIGhhZCBhIGNoYW5jZSB0byBzdWJzY3JpYmUuXG4gICAgICovXG4gICAgcmV0dXJuIHRoaXMucmVkdWNlZEFjdGlvbnMkLnBpcGUoXG4gICAgICBmaWx0ZXIoKGFjdDogYW55KSA9PiAhIWFjdC5wYXlsb2FkKSxcbiAgICAgIGZpbHRlcigoYWN0OiBFbnRpdHlBY3Rpb24pID0+IHtcbiAgICAgICAgY29uc3QgeyBjb3JyZWxhdGlvbklkLCBlbnRpdHlOYW1lLCBlbnRpdHlPcCB9ID0gYWN0LnBheWxvYWQ7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgZW50aXR5TmFtZSA9PT0gdGhpcy5lbnRpdHlOYW1lICYmXG4gICAgICAgICAgY29ycmVsYXRpb25JZCA9PT0gY3JpZCAmJlxuICAgICAgICAgIChlbnRpdHlPcC5lbmRzV2l0aChPUF9TVUNDRVNTKSB8fFxuICAgICAgICAgICAgZW50aXR5T3AuZW5kc1dpdGgoT1BfRVJST1IpIHx8XG4gICAgICAgICAgICBlbnRpdHlPcCA9PT0gRW50aXR5T3AuQ0FOQ0VMX1BFUlNJU1QpXG4gICAgICAgICk7XG4gICAgICB9KSxcbiAgICAgIHRha2UoMSksXG4gICAgICBtZXJnZU1hcCgoYWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5T3AgfSA9IGFjdC5wYXlsb2FkO1xuICAgICAgICByZXR1cm4gZW50aXR5T3AgPT09IEVudGl0eU9wLkNBTkNFTF9QRVJTSVNUXG4gICAgICAgICAgPyB0aHJvd0Vycm9yKG5ldyBQZXJzaXN0YW5jZUNhbmNlbGVkKGFjdC5wYXlsb2FkLmRhdGEpKVxuICAgICAgICAgIDogZW50aXR5T3AuZW5kc1dpdGgoT1BfU1VDQ0VTUylcbiAgICAgICAgICA/IG9mKGFjdC5wYXlsb2FkLmRhdGEgYXMgRClcbiAgICAgICAgICA6IHRocm93RXJyb3IoYWN0LnBheWxvYWQuZGF0YS5lcnJvcik7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHNldFF1ZXJ5RW50aXR5QWN0aW9uT3B0aW9ucyhcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiBFbnRpdHlBY3Rpb25PcHRpb25zIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBjb25zdCBjb3JyZWxhdGlvbklkID1cbiAgICAgIG9wdGlvbnMuY29ycmVsYXRpb25JZCA9PSBudWxsXG4gICAgICAgID8gdGhpcy5jb3JyZWxhdGlvbklkR2VuZXJhdG9yLm5leHQoKVxuICAgICAgICA6IG9wdGlvbnMuY29ycmVsYXRpb25JZDtcbiAgICByZXR1cm4geyAuLi5vcHRpb25zLCBjb3JyZWxhdGlvbklkIH07XG4gIH1cblxuICBwcml2YXRlIHNldFNhdmVFbnRpdHlBY3Rpb25PcHRpb25zKFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zLFxuICAgIGRlZmF1bHRPcHRpbWlzbT86IGJvb2xlYW5cbiAgKTogRW50aXR5QWN0aW9uT3B0aW9ucyB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgY29uc3QgY29ycmVsYXRpb25JZCA9XG4gICAgICBvcHRpb25zLmNvcnJlbGF0aW9uSWQgPT0gbnVsbFxuICAgICAgICA/IHRoaXMuY29ycmVsYXRpb25JZEdlbmVyYXRvci5uZXh0KClcbiAgICAgICAgOiBvcHRpb25zLmNvcnJlbGF0aW9uSWQ7XG4gICAgY29uc3QgaXNPcHRpbWlzdGljID1cbiAgICAgIG9wdGlvbnMuaXNPcHRpbWlzdGljID09IG51bGxcbiAgICAgICAgPyBkZWZhdWx0T3B0aW1pc20gfHwgZmFsc2VcbiAgICAgICAgOiBvcHRpb25zLmlzT3B0aW1pc3RpYyA9PT0gdHJ1ZTtcbiAgICByZXR1cm4geyAuLi5vcHRpb25zLCBjb3JyZWxhdGlvbklkLCBpc09wdGltaXN0aWMgfTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHByaXZhdGUgaGVscGVyc1xufVxuIl19
401
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWRpc3BhdGNoZXItYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL21vZHVsZXMvZGF0YS9zcmMvZGlzcGF0Y2hlcnMvZW50aXR5LWRpc3BhdGNoZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVUsY0FBYyxFQUFTLE1BQU0sYUFBYSxDQUFDO0FBRzVELE9BQU8sRUFBYyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ2xELE9BQU8sRUFDTCxNQUFNLEVBQ04sR0FBRyxFQUNILFFBQVEsRUFDUixXQUFXLEVBQ1gsY0FBYyxFQUNkLElBQUksR0FDTCxNQUFNLGdCQUFnQixDQUFDO0FBR3hCLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHdEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFLbkUsT0FBTyxFQUFvQixtQkFBbUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBS3RFOzs7R0FHRztBQUNILE1BQU0sT0FBTyxvQkFBb0I7SUFZL0I7SUFDRSxnRUFBZ0U7SUFDekQsVUFBa0I7SUFDekIsZ0NBQWdDO0lBQ3pCLG1CQUF3QztJQUMvQywyQ0FBMkM7SUFDcEMsS0FBeUI7SUFDaEMsa0RBQWtEO0lBQzNDLFdBQTBCLGVBQWU7SUFDaEQ7OztPQUdHO0lBQ0ssd0JBQXdEO0lBQ2hFLDBFQUEwRTtJQUNsRSxlQUFtQztJQUMzQyx5Q0FBeUM7SUFDekMsbUJBQXdDO0lBQ3hDLDJEQUEyRDtJQUNuRCxzQkFBOEM7UUFqQi9DLGVBQVUsR0FBVixVQUFVLENBQVE7UUFFbEIsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUV4QyxVQUFLLEdBQUwsS0FBSyxDQUFvQjtR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QyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQzVCLE1BQU0sWUFBWSxHQUNoQixPQUFPLENBQUMsWUFBWSxJQUFJLElBQUk7WUFDMUIsQ0FBQyxDQUFDLGVBQWUsSUFBSSxLQUFLO1lBQzFCLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQztRQUNwQyx1Q0FBWSxPQUFPLEtBQUUsYUFBYSxFQUFFLFlBQVksSUFBRztJQUNyRCxDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY3Rpb24sIGNyZWF0ZVNlbGVjdG9yLCBTdG9yZSB9IGZyb20gJ0BuZ3J4L3N0b3JlJztcbmltcG9ydCB7IElkU2VsZWN0b3IsIFVwZGF0ZSB9IGZyb20gJ0BuZ3J4L2VudGl0eSc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIG1hcCxcbiAgbWVyZ2VNYXAsXG4gIHNoYXJlUmVwbGF5LFxuICB3aXRoTGF0ZXN0RnJvbSxcbiAgdGFrZSxcbn0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBDb3JyZWxhdGlvbklkR2VuZXJhdG9yIH0gZnJvbSAnLi4vdXRpbHMvY29ycmVsYXRpb24taWQtZ2VuZXJhdG9yJztcbmltcG9ydCB7IGRlZmF1bHRTZWxlY3RJZCwgdG9VcGRhdGVGYWN0b3J5IH0gZnJvbSAnLi4vdXRpbHMvdXRpbGl0aWVzJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbiwgRW50aXR5QWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL2FjdGlvbnMvZW50aXR5LWFjdGlvbic7XG5pbXBvcnQgeyBFbnRpdHlBY3Rpb25GYWN0b3J5IH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uLWZhY3RvcnknO1xuaW1wb3J0IHsgRW50aXR5QWN0aW9uR3VhcmQgfSBmcm9tICcuLi9hY3Rpb25zL2VudGl0eS1hY3Rpb24tZ3VhcmQnO1xuaW1wb3J0IHsgRW50aXR5Q2FjaGUgfSBmcm9tICcuLi9yZWR1Y2Vycy9lbnRpdHktY2FjaGUnO1xuaW1wb3J0IHsgRW50aXR5Q2FjaGVTZWxlY3RvciB9IGZyb20gJy4uL3NlbGVjdG9ycy9lbnRpdHktY2FjaGUtc2VsZWN0b3InO1xuaW1wb3J0IHsgRW50aXR5Q29sbGVjdGlvbiB9IGZyb20gJy4uL3JlZHVjZXJzL2VudGl0eS1jb2xsZWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUNvbW1hbmRzIH0gZnJvbSAnLi9lbnRpdHktY29tbWFuZHMnO1xuaW1wb3J0IHsgRW50aXR5RGlzcGF0Y2hlciwgUGVyc2lzdGFuY2VDYW5jZWxlZCB9IGZyb20gJy4vZW50aXR5LWRpc3BhdGNoZXInO1xuaW1wb3J0IHsgRW50aXR5RGlzcGF0Y2hlckRlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi9lbnRpdHktZGlzcGF0Y2hlci1kZWZhdWx0LW9wdGlvbnMnO1xuaW1wb3J0IHsgRW50aXR5T3AsIE9QX0VSUk9SLCBPUF9TVUNDRVNTIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktb3AnO1xuaW1wb3J0IHsgTWVyZ2VTdHJhdGVneSB9IGZyb20gJy4uL2FjdGlvbnMvbWVyZ2Utc3RyYXRlZ3knO1xuaW1wb3J0IHsgUXVlcnlQYXJhbXMgfSBmcm9tICcuLi9kYXRhc2VydmljZXMvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBVcGRhdGVSZXNwb25zZURhdGEgfSBmcm9tICcuLi9hY3Rpb25zL3VwZGF0ZS1yZXNwb25zZS1kYXRhJztcblxuLyoqXG4gKiBEaXNwYXRjaGVzIEVudGl0eUNvbGxlY3Rpb24gYWN0aW9ucyB0byB0aGVpciByZWR1Y2VycyBhbmQgZWZmZWN0cyAoZGVmYXVsdCBpbXBsZW1lbnRhdGlvbikuXG4gKiBBbGwgc2F2ZSBjb21tYW5kcyByZWx5IG9uIGFuIE5ncnggRWZmZWN0IHN1Y2ggYXMgYEVudGl0eUVmZmVjdHMucGVyc2lzdCRgLlxuICovXG5leHBvcnQgY2xhc3MgRW50aXR5RGlzcGF0Y2hlckJhc2U8VD4gaW1wbGVtZW50cyBFbnRpdHlEaXNwYXRjaGVyPFQ+IHtcbiAgLyoqIFV0aWxpdHkgY2xhc3Mgd2l0aCBtZXRob2RzIHRvIHZhbGlkYXRlIEVudGl0eUFjdGlvbiBwYXlsb2Fkcy4qL1xuICBndWFyZDogRW50aXR5QWN0aW9uR3VhcmQ8VD47XG5cbiAgcHJpdmF0ZSBlbnRpdHlDb2xsZWN0aW9uJDogT2JzZXJ2YWJsZTxFbnRpdHlDb2xsZWN0aW9uPFQ+PjtcblxuICAvKipcbiAgICogQ29udmVydCBhbiBlbnRpdHkgKG9yIHBhcnRpYWwgZW50aXR5KSBpbnRvIHRoZSBgVXBkYXRlPFQ+YCBvYmplY3RcbiAgICogYHVwZGF0ZS4uLmAgYW5kIGB1cHNlcnQuLi5gIG1ldGhvZHMgdGFrZSBgVXBkYXRlPFQ+YCBhcmdzXG4gICAqL1xuICB0b1VwZGF0ZTogKGVudGl0eTogUGFydGlhbDxUPikgPT4gVXBkYXRlPFQ+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKiBOYW1lIG9mIHRoZSBlbnRpdHkgdHlwZSBmb3Igd2hpY2ggZW50aXRpZXMgYXJlIGRpc3BhdGNoZWQgKi9cbiAgICBwdWJsaWMgZW50aXR5TmFtZTogc3RyaW5nLFxuICAgIC8qKiBDcmVhdGVzIGFuIHtFbnRpdHlBY3Rpb259ICovXG4gICAgcHVibGljIGVudGl0eUFjdGlvbkZhY3Rvcnk6IEVudGl0eUFjdGlvbkZhY3RvcnksXG4gICAgLyoqIFRoZSBzdG9yZSwgc2NvcGVkIHRvIHRoZSBFbnRpdHlDYWNoZSAqL1xuICAgIHB1YmxpYyBzdG9yZTogU3RvcmU8RW50aXR5Q2FjaGU+LFxuICAgIC8qKiBSZXR1cm5zIHRoZSBwcmltYXJ5IGtleSAoaWQpIG9mIHRoaXMgZW50aXR5ICovXG4gICAgcHVibGljIHNlbGVjdElkOiBJZFNlbGVjdG9yPFQ+ID0gZGVmYXVsdFNlbGVjdElkLFxuICAgIC8qKlxuICAgICAqIERpc3BhdGNoZXIgb3B0aW9ucyBjb25maWd1cmUgZGlzcGF0Y2hlciBiZWhhdmlvciBzdWNoIGFzXG4gICAgICogd2hldGhlciBhZGQgaXMgb3B0aW1pc3RpYyBvciBwZXNzaW1pc3RpYyBieSBkZWZhdWx0LlxuICAgICAqL1xuICAgIHByaXZhdGUgZGVmYXVsdERpc3BhdGNoZXJPcHRpb25zOiBFbnRpdHlEaXNwYXRjaGVyRGVmYXVsdE9wdGlvbnMsXG4gICAgLyoqIEFjdGlvbnMgc2Nhbm5lZCBieSB0aGUgc3RvcmUgYWZ0ZXIgaXQgcHJvY2Vzc2VkIHRoZW0gd2l0aCByZWR1Y2Vycy4gKi9cbiAgICBwcml2YXRlIHJlZHVjZWRBY3Rpb25zJDogT2JzZXJ2YWJsZTxBY3Rpb24+LFxuICAgIC8qKiBTdG9yZSBzZWxlY3RvciBmb3IgdGhlIEVudGl0eUNhY2hlICovXG4gICAgZW50aXR5Q2FjaGVTZWxlY3RvcjogRW50aXR5Q2FjaGVTZWxlY3RvcixcbiAgICAvKiogR2VuZXJhdGVzIGNvcnJlbGF0aW9uIGlkcyBmb3IgcXVlcnkgYW5kIHNhdmUgbWV0aG9kcyAqL1xuICAgIHByaXZhdGUgY29ycmVsYXRpb25JZEdlbmVyYXRvcjogQ29ycmVsYXRpb25JZEdlbmVyYXRvclxuICApIHtcbiAgICB0aGlzLmd1YXJkID0gbmV3IEVudGl0eUFjdGlvbkd1YXJkKGVudGl0eU5hbWUsIHNlbGVjdElkKTtcbiAgICB0aGlzLnRvVXBkYXRlID0gdG9VcGRhdGVGYWN0b3J5PFQ+KHNlbGVjdElkKTtcblxuICAgIGNvbnN0IGNvbGxlY3Rpb25TZWxlY3RvciA9IGNyZWF0ZVNlbGVjdG9yKFxuICAgICAgZW50aXR5Q2FjaGVTZWxlY3RvcixcbiAgICAgIChjYWNoZSkgPT4gY2FjaGVbZW50aXR5TmFtZV0gYXMgRW50aXR5Q29sbGVjdGlvbjxUPlxuICAgICk7XG4gICAgdGhpcy5lbnRpdHlDb2xsZWN0aW9uJCA9IHN0b3JlLnNlbGVjdChjb2xsZWN0aW9uU2VsZWN0b3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiB7RW50aXR5QWN0aW9ufSBmb3IgdGhpcyBlbnRpdHkgdHlwZS5cbiAgICogQHBhcmFtIGVudGl0eU9wIHtFbnRpdHlPcH0gdGhlIGVudGl0eSBvcGVyYXRpb25cbiAgICogQHBhcmFtIFtkYXRhXSB0aGUgYWN0aW9uIGRhdGFcbiAgICogQHBhcmFtIFtvcHRpb25zXSBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgICogQHJldHVybnMgdGhlIEVudGl0eUFjdGlvblxuICAgKi9cbiAgY3JlYXRlRW50aXR5QWN0aW9uPFAgPSBhbnk+KFxuICAgIGVudGl0eU9wOiBFbnRpdHlPcCxcbiAgICBkYXRhPzogUCxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiBFbnRpdHlBY3Rpb248UD4ge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUFjdGlvbkZhY3RvcnkuY3JlYXRlKHtcbiAgICAgIGVudGl0eU5hbWU6IHRoaXMuZW50aXR5TmFtZSxcbiAgICAgIGVudGl0eU9wLFxuICAgICAgZGF0YSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIHtFbnRpdHlBY3Rpb259IGZvciB0aGlzIGVudGl0eSB0eXBlIGFuZFxuICAgKiBkaXNwYXRjaCBpdCBpbW1lZGlhdGVseSB0byB0aGUgc3RvcmUuXG4gICAqIEBwYXJhbSBvcCB7RW50aXR5T3B9IHRoZSBlbnRpdHkgb3BlcmF0aW9uXG4gICAqIEBwYXJhbSBbZGF0YV0gdGhlIGFjdGlvbiBkYXRhXG4gICAqIEBwYXJhbSBbb3B0aW9uc10gYWRkaXRpb25hbCBvcHRpb25zXG4gICAqIEByZXR1cm5zIHRoZSBkaXNwYXRjaGVkIEVudGl0eUFjdGlvblxuICAgKi9cbiAgY3JlYXRlQW5kRGlzcGF0Y2g8UCA9IGFueT4oXG4gICAgb3A6IEVudGl0eU9wLFxuICAgIGRhdGE/OiBQLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IEVudGl0eUFjdGlvbjxQPiB7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5jcmVhdGVFbnRpdHlBY3Rpb24ob3AsIGRhdGEsIG9wdGlvbnMpO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gYWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFuIEFjdGlvbiB0byB0aGUgc3RvcmUuXG4gICAqIEBwYXJhbSBhY3Rpb24gdGhlIEFjdGlvblxuICAgKiBAcmV0dXJucyB0aGUgZGlzcGF0Y2hlZCBBY3Rpb25cbiAgICovXG4gIGRpc3BhdGNoKGFjdGlvbjogQWN0aW9uKTogQWN0aW9uIHtcbiAgICB0aGlzLnN0b3JlLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgcmV0dXJuIGFjdGlvbjtcbiAgfVxuXG4gIC8vICNyZWdpb24gUXVlcnkgYW5kIHNhdmUgb3BlcmF0aW9uc1xuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gc2F2ZSBhIG5ldyBlbnRpdHkgdG8gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSBlbnRpdHkgZW50aXR5IHRvIGFkZCwgd2hpY2ggbWF5IG9taXQgaXRzIGtleSBpZiBwZXNzaW1pc3RpYyBhbmQgdGhlIHNlcnZlciBjcmVhdGVzIHRoZSBrZXk7XG4gICAqIG11c3QgaGF2ZSBhIGtleSBpZiBvcHRpbWlzdGljIHNhdmUuXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgZW50aXR5XG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgc2F2ZSBvciB0aGUgc2F2ZSBlcnJvci5cbiAgICovXG4gIGFkZChlbnRpdHk6IFQsIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgb3B0aW9ucyA9IHRoaXMuc2V0U2F2ZUVudGl0eUFjdGlvbk9wdGlvbnMoXG4gICAgICBvcHRpb25zLFxuICAgICAgdGhpcy5kZWZhdWx0RGlzcGF0Y2hlck9wdGlvbnMub3B0aW1pc3RpY0FkZFxuICAgICk7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5jcmVhdGVFbnRpdHlBY3Rpb24oXG4gICAgICBFbnRpdHlPcC5TQVZFX0FERF9PTkUsXG4gICAgICBlbnRpdHksXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICBpZiAob3B0aW9ucy5pc09wdGltaXN0aWMpIHtcbiAgICAgIHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgfVxuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPFQ+KG9wdGlvbnMuY29ycmVsYXRpb25JZCkucGlwZShcbiAgICAgIC8vIFVzZSB0aGUgcmV0dXJuZWQgZW50aXR5IGRhdGEncyBpZCB0byBnZXQgdGhlIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAgICAvLyBhcyBpdCBtaWdodCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgZW50aXR5IHJldHVybmVkIGZyb20gdGhlIHNlcnZlci5cbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuZW50aXR5Q29sbGVjdGlvbiQpLFxuICAgICAgbWFwKChbZSwgY29sbGVjdGlvbl0pID0+IGNvbGxlY3Rpb24uZW50aXRpZXNbdGhpcy5zZWxlY3RJZChlKV0hKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gY2FuY2VsIHRoZSBwZXJzaXN0ZW5jZSBvcGVyYXRpb24gKHF1ZXJ5IG9yIHNhdmUpLlxuICAgKiBXaWxsIGNhdXNlIHNhdmUgb2JzZXJ2YWJsZSB0byBlcnJvciB3aXRoIGEgUGVyc2lzdGVuY2VDYW5jZWwgZXJyb3IuXG4gICAqIENhbGxlciBpcyByZXNwb25zaWJsZSBmb3IgdW5kb2luZyBjaGFuZ2VzIGluIGNhY2hlIGZyb20gcGVuZGluZyBvcHRpbWlzdGljIHNhdmVcbiAgICogQHBhcmFtIGNvcnJlbGF0aW9uSWQgVGhlIGNvcnJlbGF0aW9uIGlkIGZvciB0aGUgY29ycmVzcG9uZGluZyBFbnRpdHlBY3Rpb25cbiAgICogQHBhcmFtIFtyZWFzb25dIGV4cGxhaW5zIHdoeSBjYW5jZWxlZCBhbmQgYnkgd2hvbS5cbiAgICovXG4gIGNhbmNlbChcbiAgICBjb3JyZWxhdGlvbklkOiBhbnksXG4gICAgcmVhc29uPzogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IHZvaWQge1xuICAgIGlmICghY29ycmVsYXRpb25JZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGNvcnJlbGF0aW9uSWQnKTtcbiAgICB9XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5DQU5DRUxfUEVSU0lTVCwgcmVhc29uLCB7IGNvcnJlbGF0aW9uSWQgfSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYWN0aW9uIHRvIGRlbGV0ZSBlbnRpdHkgZnJvbSByZW1vdGUgc3RvcmFnZSBieSBrZXkuXG4gICAqIEBwYXJhbSBrZXkgVGhlIHByaW1hcnkga2V5IG9mIHRoZSBlbnRpdHkgdG8gcmVtb3ZlXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgZGVsZXRlZCBrZXlcbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2Vzc2Z1bCBzYXZlIG9yIHRoZSBzYXZlIGVycm9yLlxuICAgKi9cbiAgZGVsZXRlKGVudGl0eTogVCwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPG51bWJlciB8IHN0cmluZz47XG5cbiAgLyoqXG4gICAqIERpc3BhdGNoIGFjdGlvbiB0byBkZWxldGUgZW50aXR5IGZyb20gcmVtb3RlIHN0b3JhZ2UgYnkga2V5LlxuICAgKiBAcGFyYW0ga2V5IFRoZSBlbnRpdHkgdG8gZGVsZXRlXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgZGVsZXRlZCBrZXlcbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2Vzc2Z1bCBzYXZlIG9yIHRoZSBzYXZlIGVycm9yLlxuICAgKi9cbiAgZGVsZXRlKFxuICAgIGtleTogbnVtYmVyIHwgc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IE9ic2VydmFibGU8bnVtYmVyIHwgc3RyaW5nPjtcbiAgZGVsZXRlKFxuICAgIGFyZzogbnVtYmVyIHwgc3RyaW5nIHwgVCxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiBPYnNlcnZhYmxlPG51bWJlciB8IHN0cmluZz4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFNhdmVFbnRpdHlBY3Rpb25PcHRpb25zKFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHRoaXMuZGVmYXVsdERpc3BhdGNoZXJPcHRpb25zLm9wdGltaXN0aWNEZWxldGVcbiAgICApO1xuICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0S2V5KGFyZyk7XG4gICAgY29uc3QgYWN0aW9uID0gdGhpcy5jcmVhdGVFbnRpdHlBY3Rpb24oXG4gICAgICBFbnRpdHlPcC5TQVZFX0RFTEVURV9PTkUsXG4gICAgICBrZXksXG4gICAgICBvcHRpb25zXG4gICAgKTtcbiAgICB0aGlzLmd1YXJkLm11c3RCZUtleShhY3Rpb24pO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPG51bWJlciB8IHN0cmluZz4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgbWFwKCgpID0+IGtleSksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYWN0aW9uIHRvIHF1ZXJ5IHJlbW90ZSBzdG9yYWdlIGZvciBhbGwgZW50aXRpZXMgYW5kXG4gICAqIG1lcmdlIHRoZSBxdWVyaWVkIGVudGl0aWVzIGludG8gdGhlIGNhY2hlZCBjb2xsZWN0aW9uLlxuICAgKiBAcmV0dXJucyBBIHRlcm1pbmF0aW5nIE9ic2VydmFibGUgb2YgdGhlIHF1ZXJpZWQgZW50aXRpZXMgdGhhdCBhcmUgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICogYWZ0ZXIgc2VydmVyIHJlcG9ydHMgc3VjY2VzcyBxdWVyeSBvciB0aGUgcXVlcnkgZXJyb3IuXG4gICAqIEBzZWUgbG9hZCgpXG4gICAqL1xuICBnZXRBbGwob3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPFRbXT4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFF1ZXJ5RW50aXR5QWN0aW9uT3B0aW9ucyhvcHRpb25zKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihFbnRpdHlPcC5RVUVSWV9BTEwsIG51bGwsIG9wdGlvbnMpO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPFRbXT4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgLy8gVXNlIHRoZSByZXR1cm5lZCBlbnRpdHkgaWRzIHRvIGdldCB0aGUgZW50aXRpZXMgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgICAgLy8gYXMgdGhleSBtaWdodCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gICAgICAvLyBiZWNhdXNlIG9mIHVuc2F2ZWQgY2hhbmdlcyAoZGVsZXRlcyBvciB1cGRhdGVzKS5cbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuZW50aXR5Q29sbGVjdGlvbiQpLFxuICAgICAgbWFwKChbZW50aXRpZXMsIGNvbGxlY3Rpb25dKSA9PlxuICAgICAgICBlbnRpdGllcy5yZWR1Y2UoKGFjYywgZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IGNvbGxlY3Rpb24uZW50aXRpZXNbdGhpcy5zZWxlY3RJZChlKV07XG4gICAgICAgICAgaWYgKGVudGl0eSkge1xuICAgICAgICAgICAgYWNjLnB1c2goZW50aXR5KTsgLy8gb25seSByZXR1cm4gYW4gZW50aXR5IGZvdW5kIGluIHRoZSBjb2xsZWN0aW9uXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIFtdIGFzIFRbXSlcbiAgICAgICksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYWN0aW9uIHRvIHF1ZXJ5IHJlbW90ZSBzdG9yYWdlIGZvciB0aGUgZW50aXR5IHdpdGggdGhpcyBwcmltYXJ5IGtleS5cbiAgICogSWYgdGhlIHNlcnZlciByZXR1cm5zIGFuIGVudGl0eSxcbiAgICogbWVyZ2UgaXQgaW50byB0aGUgY2FjaGVkIGNvbGxlY3Rpb24uXG4gICAqIEByZXR1cm5zIEEgdGVybWluYXRpbmcgT2JzZXJ2YWJsZSBvZiB0aGUgY29sbGVjdGlvblxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzZnVsIHF1ZXJ5IG9yIHRoZSBxdWVyeSBlcnJvci5cbiAgICovXG4gIGdldEJ5S2V5KGtleTogYW55LCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IE9ic2VydmFibGU8VD4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFF1ZXJ5RW50aXR5QWN0aW9uT3B0aW9ucyhvcHRpb25zKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihFbnRpdHlPcC5RVUVSWV9CWV9LRVksIGtleSwgb3B0aW9ucyk7XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8VD4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgLy8gVXNlIHRoZSByZXR1cm5lZCBlbnRpdHkgZGF0YSdzIGlkIHRvIGdldCB0aGUgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb25cbiAgICAgIC8vIGFzIGl0IG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBlbnRpdHkgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyLlxuICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5lbnRpdHlDb2xsZWN0aW9uJCksXG4gICAgICBtYXAoXG4gICAgICAgIChbZW50aXR5LCBjb2xsZWN0aW9uXSkgPT4gY29sbGVjdGlvbi5lbnRpdGllc1t0aGlzLnNlbGVjdElkKGVudGl0eSldIVxuICAgICAgKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gcXVlcnkgcmVtb3RlIHN0b3JhZ2UgZm9yIHRoZSBlbnRpdGllcyB0aGF0IHNhdGlzZnkgYSBxdWVyeSBleHByZXNzZWRcbiAgICogd2l0aCBlaXRoZXIgYSBxdWVyeSBwYXJhbWV0ZXIgbWFwIG9yIGFuIEhUVFAgVVJMIHF1ZXJ5IHN0cmluZyxcbiAgICogYW5kIG1lcmdlIHRoZSByZXN1bHRzIGludG8gdGhlIGNhY2hlZCBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0gcXVlcnlQYXJhbXMgdGhlIHF1ZXJ5IGluIGEgZm9ybSB1bmRlcnN0b29kIGJ5IHRoZSBzZXJ2ZXJcbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBxdWVyaWVkIGVudGl0aWVzXG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgcXVlcnkgb3IgdGhlIHF1ZXJ5IGVycm9yLlxuICAgKi9cbiAgZ2V0V2l0aFF1ZXJ5KFxuICAgIHF1ZXJ5UGFyYW1zOiBRdWVyeVBhcmFtcyB8IHN0cmluZyxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiBPYnNlcnZhYmxlPFRbXT4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFF1ZXJ5RW50aXR5QWN0aW9uT3B0aW9ucyhvcHRpb25zKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihcbiAgICAgIEVudGl0eU9wLlFVRVJZX01BTlksXG4gICAgICBxdWVyeVBhcmFtcyxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbiAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zZURhdGEkPFRbXT4ob3B0aW9ucy5jb3JyZWxhdGlvbklkKS5waXBlKFxuICAgICAgLy8gVXNlIHRoZSByZXR1cm5lZCBlbnRpdHkgaWRzIHRvIGdldCB0aGUgZW50aXRpZXMgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgICAgLy8gYXMgdGhleSBtaWdodCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gICAgICAvLyBiZWNhdXNlIG9mIHVuc2F2ZWQgY2hhbmdlcyAoZGVsZXRlcyBvciB1cGRhdGVzKS5cbiAgICAgIHdpdGhMYXRlc3RGcm9tKHRoaXMuZW50aXR5Q29sbGVjdGlvbiQpLFxuICAgICAgbWFwKChbZW50aXRpZXMsIGNvbGxlY3Rpb25dKSA9PlxuICAgICAgICBlbnRpdGllcy5yZWR1Y2UoKGFjYywgZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IGNvbGxlY3Rpb24uZW50aXRpZXNbdGhpcy5zZWxlY3RJZChlKV07XG4gICAgICAgICAgaWYgKGVudGl0eSkge1xuICAgICAgICAgICAgYWNjLnB1c2goZW50aXR5KTsgLy8gb25seSByZXR1cm4gYW4gZW50aXR5IGZvdW5kIGluIHRoZSBjb2xsZWN0aW9uXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgIH0sIFtdIGFzIFRbXSlcbiAgICAgICksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2ggYWN0aW9uIHRvIHF1ZXJ5IHJlbW90ZSBzdG9yYWdlIGZvciBhbGwgZW50aXRpZXMgYW5kXG4gICAqIGNvbXBsZXRlbHkgcmVwbGFjZSB0aGUgY2FjaGVkIGNvbGxlY3Rpb24gd2l0aCB0aGUgcXVlcmllZCBlbnRpdGllcy5cbiAgICogQHJldHVybnMgQSB0ZXJtaW5hdGluZyBPYnNlcnZhYmxlIG9mIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvblxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzZnVsIHF1ZXJ5IG9yIHRoZSBxdWVyeSBlcnJvci5cbiAgICogQHNlZSBnZXRBbGxcbiAgICovXG4gIGxvYWQob3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPFRbXT4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFF1ZXJ5RW50aXR5QWN0aW9uT3B0aW9ucyhvcHRpb25zKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihFbnRpdHlPcC5RVUVSWV9MT0FELCBudWxsLCBvcHRpb25zKTtcbiAgICB0aGlzLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVzcG9uc2VEYXRhJDxUW10+KG9wdGlvbnMuY29ycmVsYXRpb25JZCkucGlwZShcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gc2F2ZSB0aGUgdXBkYXRlZCBlbnRpdHkgKG9yIHBhcnRpYWwgZW50aXR5KSBpbiByZW1vdGUgc3RvcmFnZS5cbiAgICogVGhlIHVwZGF0ZSBlbnRpdHkgbWF5IGJlIHBhcnRpYWwgKGJ1dCBtdXN0IGhhdmUgaXRzIGtleSlcbiAgICogaW4gd2hpY2ggY2FzZSBpdCBwYXRjaGVzIHRoZSBleGlzdGluZyBlbnRpdHkuXG4gICAqIEBwYXJhbSBlbnRpdHkgdXBkYXRlIGVudGl0eSwgd2hpY2ggbWlnaHQgYmUgYSBwYXJ0aWFsIG9mIFQgYnV0IG11c3QgYXQgbGVhc3QgaGF2ZSBpdHMga2V5LlxuICAgKiBAcmV0dXJucyBBIHRlcm1pbmF0aW5nIE9ic2VydmFibGUgb2YgdGhlIHVwZGF0ZWQgZW50aXR5XG4gICAqIGFmdGVyIHNlcnZlciByZXBvcnRzIHN1Y2Nlc3NmdWwgc2F2ZSBvciB0aGUgc2F2ZSBlcnJvci5cbiAgICovXG4gIHVwZGF0ZShlbnRpdHk6IFBhcnRpYWw8VD4sIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogT2JzZXJ2YWJsZTxUPiB7XG4gICAgLy8gdXBkYXRlIGVudGl0eSBtaWdodCBiZSBhIHBhcnRpYWwgb2YgVCBidXQgbXVzdCBhdCBsZWFzdCBoYXZlIGl0cyBrZXkuXG4gICAgLy8gcGFzcyB0aGUgVXBkYXRlPFQ+IHN0cnVjdHVyZSBhcyB0aGUgcGF5bG9hZFxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMudG9VcGRhdGUoZW50aXR5KTtcbiAgICBvcHRpb25zID0gdGhpcy5zZXRTYXZlRW50aXR5QWN0aW9uT3B0aW9ucyhcbiAgICAgIG9wdGlvbnMsXG4gICAgICB0aGlzLmRlZmF1bHREaXNwYXRjaGVyT3B0aW9ucy5vcHRpbWlzdGljVXBkYXRlXG4gICAgKTtcbiAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNyZWF0ZUVudGl0eUFjdGlvbihcbiAgICAgIEVudGl0eU9wLlNBVkVfVVBEQVRFX09ORSxcbiAgICAgIHVwZGF0ZSxcbiAgICAgIG9wdGlvbnNcbiAgICApO1xuICAgIGlmIChvcHRpb25zLmlzT3B0aW1pc3RpYykge1xuICAgICAgdGhpcy5ndWFyZC5tdXN0QmVVcGRhdGUoYWN0aW9uKTtcbiAgICB9XG4gICAgdGhpcy5kaXNwYXRjaChhY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmdldFJlc3BvbnNlRGF0YSQ8VXBkYXRlUmVzcG9uc2VEYXRhPFQ+PihcbiAgICAgIG9wdGlvbnMuY29ycmVsYXRpb25JZFxuICAgICkucGlwZShcbiAgICAgIC8vIFVzZSB0aGUgdXBkYXRlIGVudGl0eSBkYXRhIGlkIHRvIGdldCB0aGUgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb25cbiAgICAgIC8vIGFzIG1pZ2h0IGJlIGRpZmZlcmVudCBmcm9tIHRoZSBlbnRpdHkgcmV0dXJuZWQgZnJvbSB0aGUgc2VydmVyXG4gICAgICAvLyBiZWNhdXNlIHRoZSBpZCBjaGFuZ2VkIG9yIHRoZXJlIGFyZSB1bnNhdmVkIGNoYW5nZXMuXG4gICAgICBtYXAoKHVwZGF0ZURhdGEpID0+IHVwZGF0ZURhdGEuY2hhbmdlcyksXG4gICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmVudGl0eUNvbGxlY3Rpb24kKSxcbiAgICAgIG1hcCgoW2UsIGNvbGxlY3Rpb25dKSA9PiBjb2xsZWN0aW9uLmVudGl0aWVzW3RoaXMuc2VsZWN0SWQoZSBhcyBUKV0hKSxcbiAgICAgIHNoYXJlUmVwbGF5KDEpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNwYXRjaCBhY3Rpb24gdG8gc2F2ZSBhIG5ldyBvciBleGlzdGluZyBlbnRpdHkgdG8gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIE9ubHkgZGlzcGF0Y2ggdGhpcyBhY3Rpb24gaWYgeW91ciBzZXJ2ZXIgc3VwcG9ydHMgdXBzZXJ0LlxuICAgKiBAcGFyYW0gZW50aXR5IGVudGl0eSB0byBhZGQsIHdoaWNoIG1heSBvbWl0IGl0cyBrZXkgaWYgcGVzc2ltaXN0aWMgYW5kIHRoZSBzZXJ2ZXIgY3JlYXRlcyB0aGUga2V5O1xuICAgKiBtdXN0IGhhdmUgYSBrZXkgaWYgb3B0aW1pc3RpYyBzYXZlLlxuICAgKiBAcmV0dXJucyBBIHRlcm1pbmF0aW5nIE9ic2VydmFibGUgb2YgdGhlIGVudGl0eVxuICAgKiBhZnRlciBzZXJ2ZXIgcmVwb3J0cyBzdWNjZXNzZnVsIHNhdmUgb3IgdGhlIHNhdmUgZXJyb3IuXG4gICAqL1xuICB1cHNlcnQoZW50aXR5OiBULCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IE9ic2VydmFibGU8VD4ge1xuICAgIG9wdGlvbnMgPSB0aGlzLnNldFNhdmVFbnRpdHlBY3Rpb25PcHRpb25zKFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHRoaXMuZGVmYXVsdERpc3BhdGNoZXJPcHRpb25zLm9wdGltaXN0aWNVcHNlcnRcbiAgICApO1xuICAgIGNvbnN0IGFjdGlvbiA9IHRoaXMuY3JlYXRlRW50aXR5QWN0aW9uKFxuICAgICAgRW50aXR5T3AuU0FWRV9VUFNFUlRfT05FLFxuICAgICAgZW50aXR5LFxuICAgICAgb3B0aW9uc1xuICAgICk7XG4gICAgaWYgKG9wdGlvbnMuaXNPcHRpbWlzdGljKSB7XG4gICAgICB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pO1xuICAgIH1cbiAgICB0aGlzLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVzcG9uc2VEYXRhJDxUPihvcHRpb25zLmNvcnJlbGF0aW9uSWQpLnBpcGUoXG4gICAgICAvLyBVc2UgdGhlIHJldHVybmVkIGVudGl0eSBkYXRhJ3MgaWQgdG8gZ2V0IHRoZSBlbnRpdHkgZnJvbSB0aGUgY29sbGVjdGlvblxuICAgICAgLy8gYXMgaXQgbWlnaHQgYmUgZGlmZmVyZW50IGZyb20gdGhlIGVudGl0eSByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICB3aXRoTGF0ZXN0RnJvbSh0aGlzLmVudGl0eUNvbGxlY3Rpb24kKSxcbiAgICAgIG1hcCgoW2UsIGNvbGxlY3Rpb25dKSA9PiBjb2xsZWN0aW9uLmVudGl0aWVzW3RoaXMuc2VsZWN0SWQoZSldISksXG4gICAgICBzaGFyZVJlcGxheSgxKVxuICAgICk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBRdWVyeSBhbmQgc2F2ZSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBDYWNoZS1vbmx5IG9wZXJhdGlvbnMgdGhhdCBkbyBub3QgdXBkYXRlIHJlbW90ZSBzdG9yYWdlXG5cbiAgLy8gVW5ndWFyZGVkIGZvciBwZXJmb3JtYW5jZS5cbiAgLy8gRW50aXR5Q29sbGVjdGlvblJlZHVjZXI8VD4gcnVucyBhIGd1YXJkICh3aGljaCB0aHJvd3MpXG4gIC8vIERldmVsb3BlciBzaG91bGQgdW5kZXJzdGFuZCBjYWNoZS1vbmx5IG1ldGhvZHMgd2VsbCBlbm91Z2hcbiAgLy8gdG8gY2FsbCB0aGVtIHdpdGggdGhlIHByb3BlciBlbnRpdGllcy5cbiAgLy8gTWF5IHJlY29uc2lkZXIgYW5kIGFkZCBndWFyZHMgaW4gZnV0dXJlLlxuXG4gIC8qKlxuICAgKiBSZXBsYWNlIGFsbCBlbnRpdGllcyBpbiB0aGUgY2FjaGVkIGNvbGxlY3Rpb24uXG4gICAqIERvZXMgbm90IHNhdmUgdG8gcmVtb3RlIHN0b3JhZ2UuXG4gICAqL1xuICBhZGRBbGxUb0NhY2hlKGVudGl0aWVzOiBUW10sIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5BRERfQUxMLCBlbnRpdGllcywgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgbmV3IGVudGl0eSBkaXJlY3RseSB0byB0aGUgY2FjaGUuXG4gICAqIERvZXMgbm90IHNhdmUgdG8gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIElnbm9yZWQgaWYgYW4gZW50aXR5IHdpdGggdGhlIHNhbWUgcHJpbWFyeSBrZXkgaXMgYWxyZWFkeSBpbiBjYWNoZS5cbiAgICovXG4gIGFkZE9uZVRvQ2FjaGUoZW50aXR5OiBULCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuQUREX09ORSwgZW50aXR5LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgbXVsdGlwbGUgbmV3IGVudGl0aWVzIGRpcmVjdGx5IHRvIHRoZSBjYWNoZS5cbiAgICogRG9lcyBub3Qgc2F2ZSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICogRW50aXRpZXMgd2l0aCBwcmltYXJ5IGtleXMgYWxyZWFkeSBpbiBjYWNoZSBhcmUgaWdub3JlZC5cbiAgICovXG4gIGFkZE1hbnlUb0NhY2hlKGVudGl0aWVzOiBUW10sIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5BRERfTUFOWSwgZW50aXRpZXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqIENsZWFyIHRoZSBjYWNoZWQgZW50aXR5IGNvbGxlY3Rpb24gKi9cbiAgY2xlYXJDYWNoZShvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuUkVNT1ZFX0FMTCwgdW5kZWZpbmVkLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYW4gZW50aXR5IGRpcmVjdGx5IGZyb20gdGhlIGNhY2hlLlxuICAgKiBEb2VzIG5vdCBkZWxldGUgdGhhdCBlbnRpdHkgZnJvbSByZW1vdGUgc3RvcmFnZS5cbiAgICogQHBhcmFtIGVudGl0eSBUaGUgZW50aXR5IHRvIHJlbW92ZVxuICAgKi9cbiAgcmVtb3ZlT25lRnJvbUNhY2hlKGVudGl0eTogVCwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBSZW1vdmUgYW4gZW50aXR5IGRpcmVjdGx5IGZyb20gdGhlIGNhY2hlLlxuICAgKiBEb2VzIG5vdCBkZWxldGUgdGhhdCBlbnRpdHkgZnJvbSByZW1vdGUgc3RvcmFnZS5cbiAgICogQHBhcmFtIGtleSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIGVudGl0eSB0byByZW1vdmVcbiAgICovXG4gIHJlbW92ZU9uZUZyb21DYWNoZShrZXk6IG51bWJlciB8IHN0cmluZywgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiB2b2lkO1xuICByZW1vdmVPbmVGcm9tQ2FjaGUoXG4gICAgYXJnOiAobnVtYmVyIHwgc3RyaW5nKSB8IFQsXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5SRU1PVkVfT05FLCB0aGlzLmdldEtleShhcmcpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgbXVsdGlwbGUgZW50aXRpZXMgZGlyZWN0bHkgZnJvbSB0aGUgY2FjaGUuXG4gICAqIERvZXMgbm90IGRlbGV0ZSB0aGVzZSBlbnRpdGllcyBmcm9tIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBAcGFyYW0gZW50aXR5IFRoZSBlbnRpdGllcyB0byByZW1vdmVcbiAgICovXG4gIHJlbW92ZU1hbnlGcm9tQ2FjaGUoZW50aXRpZXM6IFRbXSwgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnMpOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBSZW1vdmUgbXVsdGlwbGUgZW50aXRpZXMgZGlyZWN0bHkgZnJvbSB0aGUgY2FjaGUuXG4gICAqIERvZXMgbm90IGRlbGV0ZSB0aGVzZSBlbnRpdGllcyBmcm9tIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBAcGFyYW0ga2V5cyBUaGUgcHJpbWFyeSBrZXlzIG9mIHRoZSBlbnRpdGllcyB0byByZW1vdmVcbiAgICovXG4gIHJlbW92ZU1hbnlGcm9tQ2FjaGUoXG4gICAga2V5czogKG51bWJlciB8IHN0cmluZylbXSxcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9uc1xuICApOiB2b2lkO1xuICByZW1vdmVNYW55RnJvbUNhY2hlKFxuICAgIGFyZ3M6IChudW1iZXIgfCBzdHJpbmcpW10gfCBUW10sXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogdm9pZCB7XG4gICAgaWYgKCFhcmdzIHx8IGFyZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGtleXMgPVxuICAgICAgdHlwZW9mIGFyZ3NbMF0gPT09ICdvYmplY3QnXG4gICAgICAgID8gLy8gaWYgYXJyYXlbMF0gaXMgYSBrZXksIGFzc3VtZSB0aGV5J3JlIGFsbCBrZXlzXG4gICAgICAgICAgKDxUW10+YXJncykubWFwKChhcmcpID0+IHRoaXMuZ2V0S2V5KGFyZykpXG4gICAgICAgIDogYXJncztcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlJFTU9WRV9NQU5ZLCBrZXlzLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgYSBjYWNoZWQgZW50aXR5IGRpcmVjdGx5LlxuICAgKiBEb2VzIG5vdCB1cGRhdGUgdGhhdCBlbnRpdHkgaW4gcmVtb3RlIHN0b3JhZ2UuXG4gICAqIElnbm9yZWQgaWYgYW4gZW50aXR5IHdpdGggbWF0Y2hpbmcgcHJpbWFyeSBrZXkgaXMgbm90IGluIGNhY2hlLlxuICAgKiBUaGUgdXBkYXRlIGVudGl0eSBtYXkgYmUgcGFydGlhbCAoYnV0IG11c3QgaGF2ZSBpdHMga2V5KVxuICAgKiBpbiB3aGljaCBjYXNlIGl0IHBhdGNoZXMgdGhlIGV4aXN0aW5nIGVudGl0eS5cbiAgICovXG4gIHVwZGF0ZU9uZUluQ2FjaGUoZW50aXR5OiBQYXJ0aWFsPFQ+LCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgIC8vIHVwZGF0ZSBlbnRpdHkgbWlnaHQgYmUgYSBwYXJ0aWFsIG9mIFQgYnV0IG11c3QgYXQgbGVhc3QgaGF2ZSBpdHMga2V5LlxuICAgIC8vIHBhc3MgdGhlIFVwZGF0ZTxUPiBzdHJ1Y3R1cmUgYXMgdGhlIHBheWxvYWRcbiAgICBjb25zdCB1cGRhdGU6IFVwZGF0ZTxUPiA9IHRoaXMudG9VcGRhdGUoZW50aXR5KTtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlVQREFURV9PTkUsIHVwZGF0ZSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIG11bHRpcGxlIGNhY2hlZCBlbnRpdGllcyBkaXJlY3RseS5cbiAgICogRG9lcyBub3QgdXBkYXRlIHRoZXNlIGVudGl0aWVzIGluIHJlbW90ZSBzdG9yYWdlLlxuICAgKiBFbnRpdGllcyB3aG9zZSBwcmltYXJ5IGtleXMgYXJlIG5vdCBpbiBjYWNoZSBhcmUgaWdub3JlZC5cbiAgICogVXBkYXRlIGVudGl0aWVzIG1heSBiZSBwYXJ0aWFsIGJ1dCBtdXN0IGF0IGxlYXN0IGhhdmUgdGhlaXIga2V5cy5cbiAgICogc3VjaCBwYXJ0aWFsIGVudGl0aWVzIHBhdGNoIHRoZWlyIGNhY2hlZCBjb3VudGVycGFydHMuXG4gICAqL1xuICB1cGRhdGVNYW55SW5DYWNoZShcbiAgICBlbnRpdGllczogUGFydGlhbDxUPltdLFxuICAgIG9wdGlvbnM/OiBFbnRpdHlBY3Rpb25PcHRpb25zXG4gICk6IHZvaWQge1xuICAgIGlmICghZW50aXRpZXMgfHwgZW50aXRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZXM6IFVwZGF0ZTxUPltdID0gZW50aXRpZXMubWFwKChlbnRpdHkpID0+XG4gICAgICB0aGlzLnRvVXBkYXRlKGVudGl0eSlcbiAgICApO1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuVVBEQVRFX01BTlksIHVwZGF0ZXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBvciB1cGRhdGUgYSBuZXcgZW50aXR5IGRpcmVjdGx5IHRvIHRoZSBjYWNoZS5cbiAgICogRG9lcyBub3Qgc2F2ZSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICogVXBzZXJ0IGVudGl0eSBtaWdodCBiZSBhIHBhcnRpYWwgb2YgVCBidXQgbXVzdCBhdCBsZWFzdCBoYXZlIGl0cyBrZXkuXG4gICAqIFBhc3MgdGhlIFVwZGF0ZTxUPiBzdHJ1Y3R1cmUgYXMgdGhlIHBheWxvYWRcbiAgICovXG4gIHVwc2VydE9uZUluQ2FjaGUoZW50aXR5OiBQYXJ0aWFsPFQ+LCBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuVVBTRVJUX09ORSwgZW50aXR5LCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgb3IgdXBkYXRlIG11bHRpcGxlIGNhY2hlZCBlbnRpdGllcyBkaXJlY3RseS5cbiAgICogRG9lcyBub3Qgc2F2ZSB0byByZW1vdGUgc3RvcmFnZS5cbiAgICovXG4gIHVwc2VydE1hbnlJbkNhY2hlKFxuICAgIGVudGl0aWVzOiBQYXJ0aWFsPFQ+W10sXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogdm9pZCB7XG4gICAgaWYgKCFlbnRpdGllcyB8fCBlbnRpdGllcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5VUFNFUlRfTUFOWSwgZW50aXRpZXMsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgcGF0dGVybiB0aGF0IHRoZSBjb2xsZWN0aW9uJ3MgZmlsdGVyIGFwcGxpZXNcbiAgICogd2hlbiB1c2luZyB0aGUgYGZpbHRlcmVkRW50aXRpZXNgIHNlbGVjdG9yLlxuICAgKi9cbiAgc2V0RmlsdGVyKHBhdHRlcm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQW5kRGlzcGF0Y2goRW50aXR5T3AuU0VUX0ZJTFRFUiwgcGF0dGVybik7XG4gIH1cblxuICAvKiogU2V0IHRoZSBsb2FkZWQgZmxhZyAqL1xuICBzZXRMb2FkZWQoaXNMb2FkZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNyZWF0ZUFuZERpc3BhdGNoKEVudGl0eU9wLlNFVF9MT0FERUQsICEhaXNMb2FkZWQpO1xuICB9XG5cbiAgLyoqIFNldCB0aGUgbG9hZGluZyBmbGFnICovXG4gIHNldExvYWRpbmcoaXNMb2FkaW5nOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5jcmVhdGVBbmREaXNwYXRjaChFbnRpdHlPcC5TRVRfTE9BRElORywgISFpc0xvYWRpbmcpO1xuICB9XG4gIC8vICNlbmRyZWdpb24gQ2FjaGUtb25seSBvcGVyYXRpb25zIHRoYXQgZG8gbm90IHVwZGF0ZSByZW1vdGUgc3RvcmFnZVxuXG4gIC8vICNyZWdpb24gcHJpdmF0ZSBoZWxwZXJzXG5cbiAgLyoqIEdldCBrZXkgZnJvbSBlbnRpdHkgKHVubGVzcyBhcmcgaXMgYWxyZWFkeSBhIGtleSkgKi9cbiAgcHJpdmF0ZSBnZXRLZXkoYXJnOiBudW1iZXIgfCBzdHJpbmcgfCBUKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnXG4gICAgICA/IHRoaXMuc2VsZWN0SWQoYXJnKVxuICAgICAgOiAoYXJnIGFzIG51bWJlciB8IHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIE9ic2VydmFibGUgb2YgZGF0YSBmcm9tIHRoZSBzZXJ2ZXItc3VjY2VzcyBFbnRpdHlBY3Rpb24gd2l0aFxuICAgKiB0aGUgZ2l2ZW4gQ29ycmVsYXRpb24gSWQsIGFmdGVyIHRoYXQgYWN0aW9uIHdhcyBwcm9jZXNzZWQgYnkgdGhlIG5ncnggc3RvcmUuXG4gICAqIG9yIGVsc2UgcHV0IHRoZSBzZXJ2ZXIgZXJyb3Igb24gdGhlIE9ic2VydmFibGUgZXJyb3IgY2hhbm5lbC5cbiAgICogQHBhcmFtIGNyaWQgVGhlIGNvcnJlbGF0aW9uSWQgZm9yIGJvdGggdGhlIHNhdmUgYW5kIHJlc3BvbnNlIGFjdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIGdldFJlc3BvbnNlRGF0YSQ8RCA9IGFueT4oY3JpZDogYW55KTogT2JzZXJ2YWJsZTxEPiB7XG4gICAgLyoqXG4gICAgICogcmVkdWNlZEFjdGlvbnMkIG11c3QgYmUgcmVwbGF5IG9ic2VydmFibGUgb2YgdGhlIG1vc3QgcmVjZW50IGFjdGlvbiByZWR1Y2VkIGJ5IHRoZSBzdG9yZS5cbiAgICAgKiBiZWNhdXNlIHRoZSByZXNwb25zZSBhY3Rpb24gbWlnaHQgaGF2ZSBiZWVuIGRpc3BhdGNoZWQgdG8gdGhlIHN0b3JlXG4gICAgICogYmVmb3JlIGNhbGxlciBoYWQgYSBjaGFuY2UgdG8gc3Vic2NyaWJlLlxuICAgICAqL1xuICAgIHJldHVybiB0aGlzLnJlZHVjZWRBY3Rpb25zJC5waXBlKFxuICAgICAgZmlsdGVyKChhY3Q6IGFueSkgPT4gISFhY3QucGF5bG9hZCksXG4gICAgICBmaWx0ZXIoKGFjdDogRW50aXR5QWN0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY29ycmVsYXRpb25JZCwgZW50aXR5TmFtZSwgZW50aXR5T3AgfSA9IGFjdC5wYXlsb2FkO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIGVudGl0eU5hbWUgPT09IHRoaXMuZW50aXR5TmFtZSAmJlxuICAgICAgICAgIGNvcnJlbGF0aW9uSWQgPT09IGNyaWQgJiZcbiAgICAgICAgICAoZW50aXR5T3AuZW5kc1dpdGgoT1BfU1VDQ0VTUykgfHxcbiAgICAgICAgICAgIGVudGl0eU9wLmVuZHNXaXRoKE9QX0VSUk9SKSB8fFxuICAgICAgICAgICAgZW50aXR5T3AgPT09IEVudGl0eU9wLkNBTkNFTF9QRVJTSVNUKVxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgICB0YWtlKDEpLFxuICAgICAgbWVyZ2VNYXAoKGFjdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eU9wIH0gPSBhY3QucGF5bG9hZDtcbiAgICAgICAgcmV0dXJuIGVudGl0eU9wID09PSBFbnRpdHlPcC5DQU5DRUxfUEVSU0lTVFxuICAgICAgICAgID8gdGhyb3dFcnJvcihuZXcgUGVyc2lzdGFuY2VDYW5jZWxlZChhY3QucGF5bG9hZC5kYXRhKSlcbiAgICAgICAgICA6IGVudGl0eU9wLmVuZHNXaXRoKE9QX1NVQ0NFU1MpXG4gICAgICAgICAgPyBvZihhY3QucGF5bG9hZC5kYXRhIGFzIEQpXG4gICAgICAgICAgOiB0aHJvd0Vycm9yKGFjdC5wYXlsb2FkLmRhdGEuZXJyb3IpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRRdWVyeUVudGl0eUFjdGlvbk9wdGlvbnMoXG4gICAgb3B0aW9ucz86IEVudGl0eUFjdGlvbk9wdGlvbnNcbiAgKTogRW50aXR5QWN0aW9uT3B0aW9ucyB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgY29uc3QgY29ycmVsYXRpb25JZCA9XG4gICAgICBvcHRpb25zLmNvcnJlbGF0aW9uSWQgPT0gbnVsbFxuICAgICAgICA/IHRoaXMuY29ycmVsYXRpb25JZEdlbmVyYXRvci5uZXh0KClcbiAgICAgICAgOiBvcHRpb25zLmNvcnJlbGF0aW9uSWQ7XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgY29ycmVsYXRpb25JZCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTYXZlRW50aXR5QWN0aW9uT3B0aW9ucyhcbiAgICBvcHRpb25zPzogRW50aXR5QWN0aW9uT3B0aW9ucyxcbiAgICBkZWZhdWx0T3B0aW1pc20/OiBib29sZWFuXG4gICk6IEVudGl0eUFjdGlvbk9wdGlvbnMge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgIGNvbnN0IGNvcnJlbGF0aW9uSWQgPVxuICAgICAgb3B0aW9ucy5jb3JyZWxhdGlvbklkID09IG51bGxcbiAgICAgICAgPyB0aGlzLmNvcnJlbGF0aW9uSWRHZW5lcmF0b3IubmV4dCgpXG4gICAgICAgIDogb3B0aW9ucy5jb3JyZWxhdGlvbklkO1xuICAgIGNvbnN0IGlzT3B0aW1pc3RpYyA9XG4gICAgICBvcHRpb25zLmlzT3B0aW1pc3RpYyA9PSBudWxsXG4gICAgICAgID8gZGVmYXVsdE9wdGltaXNtIHx8IGZhbHNlXG4gICAgICAgIDogb3B0aW9ucy5pc09wdGltaXN0aWMgPT09IHRydWU7XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgY29ycmVsYXRpb25JZCwgaXNPcHRpbWlzdGljIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBwcml2YXRlIGhlbHBlcnNcbn1cbiJdfQ==