@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/reducers/entity-change-tracker-base.ts
4
- * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
- */
6
1
  import { ChangeType } from './entity-collection';
7
2
  import { defaultSelectId } from '../utils/utilities';
8
3
  import { MergeStrategy } from '../actions/merge-strategy';
@@ -11,13 +6,8 @@ import { MergeStrategy } from '../actions/merge-strategy';
11
6
  * methods for tracking, committing, and reverting/undoing unsaved entity changes.
12
7
  * Used by EntityCollectionReducerMethods which should call tracker methods BEFORE modifying the collection.
13
8
  * See EntityChangeTracker docs.
14
- * @template T
15
9
  */
16
10
  export class EntityChangeTrackerBase {
17
- /**
18
- * @param {?} adapter
19
- * @param {?} selectId
20
- */
21
11
  constructor(adapter, selectId) {
22
12
  this.adapter = adapter;
23
13
  this.selectId = selectId;
@@ -28,8 +18,7 @@ export class EntityChangeTrackerBase {
28
18
  /**
29
19
  * Commit all changes as when the collection has been completely reloaded from the server.
30
20
  * Harmless when there are no entity changes to commit.
31
- * @param {?} collection The entity collection
32
- * @return {?}
21
+ * @param collection The entity collection
33
22
  */
34
23
  commitAll(collection) {
35
24
  return Object.keys(collection.changeState).length === 0
@@ -39,27 +28,18 @@ export class EntityChangeTrackerBase {
39
28
  /**
40
29
  * Commit changes for the given entities as when they have been refreshed from the server.
41
30
  * Harmless when there are no entity changes to commit.
42
- * @param {?} entityOrIdList The entities to clear tracking or their ids.
43
- * @param {?} collection The entity collection
44
- * @return {?}
31
+ * @param entityOrIdList The entities to clear tracking or their ids.
32
+ * @param collection The entity collection
45
33
  */
46
34
  commitMany(entityOrIdList, collection) {
47
35
  if (entityOrIdList == null || entityOrIdList.length === 0) {
48
36
  return collection; // nothing to commit
49
37
  }
50
- /** @type {?} */
51
38
  let didMutate = false;
52
- /** @type {?} */
53
- const changeState = entityOrIdList.reduce((/**
54
- * @param {?} chgState
55
- * @param {?} entityOrId
56
- * @return {?}
57
- */
58
- (chgState, entityOrId) => {
59
- /** @type {?} */
39
+ const changeState = entityOrIdList.reduce((chgState, entityOrId) => {
60
40
  const id = typeof entityOrId === 'object'
61
41
  ? this.selectId(entityOrId)
62
- : ((/** @type {?} */ (entityOrId)));
42
+ : entityOrId;
63
43
  if (chgState[id]) {
64
44
  if (!didMutate) {
65
45
  chgState = Object.assign({}, chgState);
@@ -68,15 +48,14 @@ export class EntityChangeTrackerBase {
68
48
  delete chgState[id];
69
49
  }
70
50
  return chgState;
71
- }), collection.changeState);
51
+ }, collection.changeState);
72
52
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
73
53
  }
74
54
  /**
75
55
  * Commit changes for the given entity as when it have been refreshed from the server.
76
56
  * Harmless when no entity changes to commit.
77
- * @param {?} entityOrId The entity to clear tracking or its id.
78
- * @param {?} collection The entity collection
79
- * @return {?}
57
+ * @param entityOrId The entity to clear tracking or its id.
58
+ * @param collection The entity collection
80
59
  */
81
60
  commitOne(entityOrId, collection) {
82
61
  return entityOrId == null
@@ -87,10 +66,11 @@ export class EntityChangeTrackerBase {
87
66
  // #region merge query
88
67
  /**
89
68
  * Merge query results into the collection, adjusting the ChangeState per the mergeStrategy.
90
- * @param {?} entities Entities returned from querying the server.
91
- * @param {?} collection The entity collection
92
- * @param {?=} mergeStrategy
93
- * @return {?} The merged EntityCollection.
69
+ * @param entities Entities returned from querying the server.
70
+ * @param collection The entity collection
71
+ * @param [mergeStrategy] How to merge a queried entity when the corresponding entity in the collection has an unsaved change.
72
+ * Defaults to MergeStrategy.PreserveChanges.
73
+ * @returns The merged EntityCollection.
94
74
  */
95
75
  mergeQueryResults(entities, collection, mergeStrategy) {
96
76
  return this.mergeServerUpserts(entities, collection, MergeStrategy.PreserveChanges, mergeStrategy);
@@ -100,10 +80,11 @@ export class EntityChangeTrackerBase {
100
80
  /**
101
81
  * Merge result of saving new entities into the collection, adjusting the ChangeState per the mergeStrategy.
102
82
  * The default is MergeStrategy.OverwriteChanges.
103
- * @param {?} entities Entities returned from saving new entities to the server.
104
- * @param {?} collection The entity collection
105
- * @param {?=} mergeStrategy
106
- * @return {?} The merged EntityCollection.
83
+ * @param entities Entities returned from saving new entities to the server.
84
+ * @param collection The entity collection
85
+ * @param [mergeStrategy] How to merge a saved entity when the corresponding entity in the collection has an unsaved change.
86
+ * Defaults to MergeStrategy.OverwriteChanges.
87
+ * @returns The merged EntityCollection.
107
88
  */
108
89
  mergeSaveAdds(entities, collection, mergeStrategy) {
109
90
  return this.mergeServerUpserts(entities, collection, MergeStrategy.OverwriteChanges, mergeStrategy);
@@ -111,17 +92,17 @@ export class EntityChangeTrackerBase {
111
92
  /**
112
93
  * Merge successful result of deleting entities on the server that have the given primary keys
113
94
  * Clears the entity changeState for those keys unless the MergeStrategy is ignoreChanges.
114
- * @param {?} keys
115
- * @param {?} collection The entity collection
116
- * @param {?=} mergeStrategy
117
- * @return {?} The merged EntityCollection.
95
+ * @param entities keys primary keys of the entities to remove/delete.
96
+ * @param collection The entity collection
97
+ * @param [mergeStrategy] How to adjust change tracking when the corresponding entity in the collection has an unsaved change.
98
+ * Defaults to MergeStrategy.OverwriteChanges.
99
+ * @returns The merged EntityCollection.
118
100
  */
119
101
  mergeSaveDeletes(keys, collection, mergeStrategy) {
120
102
  mergeStrategy =
121
103
  mergeStrategy == null ? MergeStrategy.OverwriteChanges : mergeStrategy;
122
104
  // same logic for all non-ignore merge strategies: always clear (commit) the changes
123
- /** @type {?} */
124
- const deleteIds = (/** @type {?} */ (keys));
105
+ const deleteIds = keys; // make TypeScript happy
125
106
  collection =
126
107
  mergeStrategy === MergeStrategy.IgnoreChanges
127
108
  ? collection
@@ -131,38 +112,31 @@ export class EntityChangeTrackerBase {
131
112
  /**
132
113
  * Merge result of saving updated entities into the collection, adjusting the ChangeState per the mergeStrategy.
133
114
  * The default is MergeStrategy.OverwriteChanges.
134
- * @param {?} updateResponseData Entity response data returned from saving updated entities to the server.
135
- * @param {?} collection The entity collection
136
- * @param {?=} mergeStrategy
137
- * @param {?=} skipUnchanged
138
- * @return {?} The merged EntityCollection.
115
+ * @param updateResponseData Entity response data returned from saving updated entities to the server.
116
+ * @param collection The entity collection
117
+ * @param [mergeStrategy] How to merge a saved entity when the corresponding entity in the collection has an unsaved change.
118
+ * Defaults to MergeStrategy.OverwriteChanges.
119
+ * @param [skipUnchanged] True means skip update if server didn't change it. False by default.
120
+ * If the update was optimistic and the server didn't make more changes of its own
121
+ * then the updates are already in the collection and shouldn't make them again.
122
+ * @returns The merged EntityCollection.
139
123
  */
140
124
  mergeSaveUpdates(updateResponseData, collection, mergeStrategy, skipUnchanged = false) {
141
125
  if (updateResponseData == null || updateResponseData.length === 0) {
142
126
  return collection; // nothing to merge.
143
127
  }
144
- /** @type {?} */
145
128
  let didMutate = false;
146
- /** @type {?} */
147
129
  let changeState = collection.changeState;
148
130
  mergeStrategy =
149
131
  mergeStrategy == null ? MergeStrategy.OverwriteChanges : mergeStrategy;
150
- /** @type {?} */
151
132
  let updates;
152
133
  switch (mergeStrategy) {
153
134
  case MergeStrategy.IgnoreChanges:
154
135
  updates = filterChanged(updateResponseData);
155
136
  return this.adapter.updateMany(updates, collection);
156
137
  case MergeStrategy.OverwriteChanges:
157
- changeState = updateResponseData.reduce((/**
158
- * @param {?} chgState
159
- * @param {?} update
160
- * @return {?}
161
- */
162
- (chgState, update) => {
163
- /** @type {?} */
138
+ changeState = updateResponseData.reduce((chgState, update) => {
164
139
  const oldId = update.id;
165
- /** @type {?} */
166
140
  const change = chgState[oldId];
167
141
  if (change) {
168
142
  if (!didMutate) {
@@ -172,22 +146,14 @@ export class EntityChangeTrackerBase {
172
146
  delete chgState[oldId];
173
147
  }
174
148
  return chgState;
175
- }), collection.changeState);
149
+ }, collection.changeState);
176
150
  collection = didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
177
151
  updates = filterChanged(updateResponseData);
178
152
  return this.adapter.updateMany(updates, collection);
179
153
  case MergeStrategy.PreserveChanges: {
180
- /** @type {?} */
181
- const updateableEntities = (/** @type {?} */ ([]));
182
- changeState = updateResponseData.reduce((/**
183
- * @param {?} chgState
184
- * @param {?} update
185
- * @return {?}
186
- */
187
- (chgState, update) => {
188
- /** @type {?} */
154
+ const updateableEntities = [];
155
+ changeState = updateResponseData.reduce((chgState, update) => {
189
156
  const oldId = update.id;
190
- /** @type {?} */
191
157
  const change = chgState[oldId];
192
158
  if (change) {
193
159
  // Tracking a change so update original value but not the current value
@@ -195,24 +161,21 @@ export class EntityChangeTrackerBase {
195
161
  chgState = Object.assign({}, chgState);
196
162
  didMutate = true;
197
163
  }
198
- /** @type {?} */
199
- const newId = this.selectId((/** @type {?} */ (update.changes)));
200
- /** @type {?} */
164
+ const newId = this.selectId(update.changes);
201
165
  const oldChangeState = change;
202
166
  // If the server changed the id, register the new "originalValue" under the new id
203
167
  // and remove the change tracked under the old id.
204
168
  if (newId !== oldId) {
205
169
  delete chgState[oldId];
206
170
  }
207
- /** @type {?} */
208
- const newOrigValue = Object.assign(Object.assign({}, ((/** @type {?} */ ((/** @type {?} */ (oldChangeState)).originalValue)))), ((/** @type {?} */ (update.changes))));
209
- ((/** @type {?} */ (chgState)))[newId] = Object.assign(Object.assign({}, oldChangeState), { originalValue: newOrigValue });
171
+ const newOrigValue = Object.assign(Object.assign({}, oldChangeState.originalValue), update.changes);
172
+ chgState[newId] = Object.assign(Object.assign({}, oldChangeState), { originalValue: newOrigValue });
210
173
  }
211
174
  else {
212
175
  updateableEntities.push(update);
213
176
  }
214
177
  return chgState;
215
- }), collection.changeState);
178
+ }, collection.changeState);
216
179
  collection = didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
217
180
  updates = filterChanged(updateableEntities);
218
181
  return this.adapter.updateMany(updates, collection);
@@ -222,36 +185,28 @@ export class EntityChangeTrackerBase {
222
185
  * Conditionally keep only those updates that have additional server changes.
223
186
  * (e.g., for optimistic saves because they updates are already in the current collection)
224
187
  * Strip off the `changed` property.
225
- * \@responseData Entity response data from server.
188
+ * @responseData Entity response data from server.
226
189
  * May be an UpdateResponseData<T>, a subclass of Update<T> with a 'changed' flag.
227
- * @param {?} responseData
228
- * @return {?} Update<T> (without the changed flag)
190
+ * @returns Update<T> (without the changed flag)
229
191
  */
230
192
  function filterChanged(responseData) {
231
193
  if (skipUnchanged === true) {
232
194
  // keep only those updates that the server changed (knowable if is UpdateResponseData<T>)
233
- responseData = responseData.filter((/**
234
- * @param {?} r
235
- * @return {?}
236
- */
237
- (r) => r.changed === true));
195
+ responseData = responseData.filter((r) => r.changed === true);
238
196
  }
239
197
  // Strip unchanged property from responseData, leaving just the pure Update<T>
240
198
  // TODO: Remove? probably not necessary as the Update isn't stored and adapter will ignore `changed`.
241
- return responseData.map((/**
242
- * @param {?} r
243
- * @return {?}
244
- */
245
- (r) => ({ id: (/** @type {?} */ (r.id)), changes: r.changes })));
199
+ return responseData.map((r) => ({ id: r.id, changes: r.changes }));
246
200
  }
247
201
  }
248
202
  /**
249
203
  * Merge result of saving upserted entities into the collection, adjusting the ChangeState per the mergeStrategy.
250
204
  * The default is MergeStrategy.OverwriteChanges.
251
- * @param {?} entities Entities returned from saving upserts to the server.
252
- * @param {?} collection The entity collection
253
- * @param {?=} mergeStrategy
254
- * @return {?} The merged EntityCollection.
205
+ * @param entities Entities returned from saving upserts to the server.
206
+ * @param collection The entity collection
207
+ * @param [mergeStrategy] How to merge a saved entity when the corresponding entity in the collection has an unsaved change.
208
+ * Defaults to MergeStrategy.OverwriteChanges.
209
+ * @returns The merged EntityCollection.
255
210
  */
256
211
  mergeSaveUpserts(entities, collection, mergeStrategy) {
257
212
  return this.mergeServerUpserts(entities, collection, MergeStrategy.OverwriteChanges, mergeStrategy);
@@ -260,20 +215,16 @@ export class EntityChangeTrackerBase {
260
215
  // #region query & save helpers
261
216
  /**
262
217
  *
263
- * @private
264
- * @param {?} entities Entities to merge
265
- * @param {?} collection Collection into which entities are merged
266
- * @param {?} defaultMergeStrategy How to merge when action's MergeStrategy is unspecified
267
- * @param {?=} mergeStrategy
268
- * @return {?}
218
+ * @param entities Entities to merge
219
+ * @param collection Collection into which entities are merged
220
+ * @param defaultMergeStrategy How to merge when action's MergeStrategy is unspecified
221
+ * @param [mergeStrategy] The action's MergeStrategy
269
222
  */
270
223
  mergeServerUpserts(entities, collection, defaultMergeStrategy, mergeStrategy) {
271
224
  if (entities == null || entities.length === 0) {
272
225
  return collection; // nothing to merge.
273
226
  }
274
- /** @type {?} */
275
227
  let didMutate = false;
276
- /** @type {?} */
277
228
  let changeState = collection.changeState;
278
229
  mergeStrategy =
279
230
  mergeStrategy == null ? defaultMergeStrategy : mergeStrategy;
@@ -282,15 +233,8 @@ export class EntityChangeTrackerBase {
282
233
  return this.adapter.upsertMany(entities, collection);
283
234
  case MergeStrategy.OverwriteChanges:
284
235
  collection = this.adapter.upsertMany(entities, collection);
285
- changeState = entities.reduce((/**
286
- * @param {?} chgState
287
- * @param {?} entity
288
- * @return {?}
289
- */
290
- (chgState, entity) => {
291
- /** @type {?} */
236
+ changeState = entities.reduce((chgState, entity) => {
292
237
  const id = this.selectId(entity);
293
- /** @type {?} */
294
238
  const change = chgState[id];
295
239
  if (change) {
296
240
  if (!didMutate) {
@@ -300,24 +244,16 @@ export class EntityChangeTrackerBase {
300
244
  delete chgState[id];
301
245
  }
302
246
  return chgState;
303
- }), collection.changeState);
247
+ }, collection.changeState);
304
248
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
305
249
  case MergeStrategy.PreserveChanges: {
306
- /** @type {?} */
307
- const upsertEntities = (/** @type {?} */ ([]));
308
- changeState = entities.reduce((/**
309
- * @param {?} chgState
310
- * @param {?} entity
311
- * @return {?}
312
- */
313
- (chgState, entity) => {
314
- /** @type {?} */
250
+ const upsertEntities = [];
251
+ changeState = entities.reduce((chgState, entity) => {
315
252
  const id = this.selectId(entity);
316
- /** @type {?} */
317
253
  const change = chgState[id];
318
254
  if (change) {
319
255
  if (!didMutate) {
320
- chgState = Object.assign(Object.assign({}, chgState), { [id]: Object.assign(Object.assign({}, (/** @type {?} */ (chgState[id]))), { originalValue: entity }) });
256
+ chgState = Object.assign(Object.assign({}, chgState), { [id]: Object.assign(Object.assign({}, chgState[id]), { originalValue: entity }) });
321
257
  didMutate = true;
322
258
  }
323
259
  }
@@ -325,7 +261,7 @@ export class EntityChangeTrackerBase {
325
261
  upsertEntities.push(entity);
326
262
  }
327
263
  return chgState;
328
- }), collection.changeState);
264
+ }, collection.changeState);
329
265
  collection = this.adapter.upsertMany(upsertEntities, collection);
330
266
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
331
267
  }
@@ -336,10 +272,9 @@ export class EntityChangeTrackerBase {
336
272
  /**
337
273
  * Track multiple entities before adding them to the collection.
338
274
  * Does NOT add to the collection (the reducer's job).
339
- * @param {?} entities The entities to add. They must all have their ids.
340
- * @param {?} collection The entity collection
341
- * @param {?=} mergeStrategy
342
- * @return {?}
275
+ * @param entities The entities to add. They must all have their ids.
276
+ * @param collection The entity collection
277
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
343
278
  */
344
279
  trackAddMany(entities, collection, mergeStrategy) {
345
280
  if (mergeStrategy === MergeStrategy.IgnoreChanges ||
@@ -347,21 +282,12 @@ export class EntityChangeTrackerBase {
347
282
  entities.length === 0) {
348
283
  return collection; // nothing to track
349
284
  }
350
- /** @type {?} */
351
285
  let didMutate = false;
352
- /** @type {?} */
353
- const changeState = entities.reduce((/**
354
- * @param {?} chgState
355
- * @param {?} entity
356
- * @return {?}
357
- */
358
- (chgState, entity) => {
359
- /** @type {?} */
286
+ const changeState = entities.reduce((chgState, entity) => {
360
287
  const id = this.selectId(entity);
361
288
  if (id == null || id === '') {
362
289
  throw new Error(`${collection.entityName} entity add requires a key to be tracked`);
363
290
  }
364
- /** @type {?} */
365
291
  const trackedChange = chgState[id];
366
292
  if (!trackedChange) {
367
293
  if (!didMutate) {
@@ -371,16 +297,16 @@ export class EntityChangeTrackerBase {
371
297
  chgState[id] = { changeType: ChangeType.Added };
372
298
  }
373
299
  return chgState;
374
- }), collection.changeState);
300
+ }, collection.changeState);
375
301
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
376
302
  }
377
303
  /**
378
304
  * Track an entity before adding it to the collection.
379
305
  * Does NOT add to the collection (the reducer's job).
380
- * @param {?} entity The entity to add. It must have an id.
381
- * @param {?} collection The entity collection
382
- * @param {?=} mergeStrategy
383
- * @return {?}
306
+ * @param entity The entity to add. It must have an id.
307
+ * @param collection The entity collection
308
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
309
+ * If not specified, implementation supplies a default strategy.
384
310
  */
385
311
  trackAddOne(entity, collection, mergeStrategy) {
386
312
  return entity == null
@@ -390,10 +316,9 @@ export class EntityChangeTrackerBase {
390
316
  /**
391
317
  * Track multiple entities before removing them with the intention of deleting them on the server.
392
318
  * Does NOT remove from the collection (the reducer's job).
393
- * @param {?} keys The primary keys of the entities to delete.
394
- * @param {?} collection The entity collection
395
- * @param {?=} mergeStrategy
396
- * @return {?}
319
+ * @param keys The primary keys of the entities to delete.
320
+ * @param collection The entity collection
321
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
397
322
  */
398
323
  trackDeleteMany(keys, collection, mergeStrategy) {
399
324
  if (mergeStrategy === MergeStrategy.IgnoreChanges ||
@@ -401,21 +326,11 @@ export class EntityChangeTrackerBase {
401
326
  keys.length === 0) {
402
327
  return collection; // nothing to track
403
328
  }
404
- /** @type {?} */
405
329
  let didMutate = false;
406
- /** @type {?} */
407
330
  const entityMap = collection.entities;
408
- /** @type {?} */
409
- const changeState = keys.reduce((/**
410
- * @param {?} chgState
411
- * @param {?} id
412
- * @return {?}
413
- */
414
- (chgState, id) => {
415
- /** @type {?} */
331
+ const changeState = keys.reduce((chgState, id) => {
416
332
  const originalValue = entityMap[id];
417
333
  if (originalValue) {
418
- /** @type {?} */
419
334
  const trackedChange = chgState[id];
420
335
  if (trackedChange) {
421
336
  if (trackedChange.changeType === ChangeType.Added) {
@@ -438,25 +353,21 @@ export class EntityChangeTrackerBase {
438
353
  }
439
354
  }
440
355
  return chgState;
441
- /**
442
- * @return {?}
443
- */
444
356
  function cloneChgStateOnce() {
445
357
  if (!didMutate) {
446
358
  didMutate = true;
447
359
  chgState = Object.assign({}, chgState);
448
360
  }
449
361
  }
450
- }), collection.changeState);
362
+ }, collection.changeState);
451
363
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
452
364
  }
453
365
  /**
454
366
  * Track an entity before it is removed with the intention of deleting it on the server.
455
367
  * Does NOT remove from the collection (the reducer's job).
456
- * @param {?} key The primary key of the entity to delete.
457
- * @param {?} collection The entity collection
458
- * @param {?=} mergeStrategy
459
- * @return {?}
368
+ * @param key The primary key of the entity to delete.
369
+ * @param collection The entity collection
370
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
460
371
  */
461
372
  trackDeleteOne(key, collection, mergeStrategy) {
462
373
  return key == null
@@ -466,10 +377,9 @@ export class EntityChangeTrackerBase {
466
377
  /**
467
378
  * Track multiple entities before updating them in the collection.
468
379
  * Does NOT update the collection (the reducer's job).
469
- * @param {?} updates The entities to update.
470
- * @param {?} collection The entity collection
471
- * @param {?=} mergeStrategy
472
- * @return {?}
380
+ * @param updates The entities to update.
381
+ * @param collection The entity collection
382
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
473
383
  */
474
384
  trackUpdateMany(updates, collection, mergeStrategy) {
475
385
  if (mergeStrategy === MergeStrategy.IgnoreChanges ||
@@ -477,28 +387,18 @@ export class EntityChangeTrackerBase {
477
387
  updates.length === 0) {
478
388
  return collection; // nothing to track
479
389
  }
480
- /** @type {?} */
481
390
  let didMutate = false;
482
- /** @type {?} */
483
391
  const entityMap = collection.entities;
484
- /** @type {?} */
485
- const changeState = updates.reduce((/**
486
- * @param {?} chgState
487
- * @param {?} update
488
- * @return {?}
489
- */
490
- (chgState, update) => {
392
+ const changeState = updates.reduce((chgState, update) => {
491
393
  const { id, changes: entity } = update;
492
394
  if (id == null || id === '') {
493
395
  throw new Error(`${collection.entityName} entity update requires a key to be tracked`);
494
396
  }
495
- /** @type {?} */
496
397
  const originalValue = entityMap[id];
497
398
  // Only track if it is in the collection. Silently ignore if it is not.
498
399
  // @ngrx/entity adapter would also silently ignore.
499
400
  // Todo: should missing update entity really be reported as an error?
500
401
  if (originalValue) {
501
- /** @type {?} */
502
402
  const trackedChange = chgState[id];
503
403
  if (!trackedChange) {
504
404
  if (!didMutate) {
@@ -509,16 +409,15 @@ export class EntityChangeTrackerBase {
509
409
  }
510
410
  }
511
411
  return chgState;
512
- }), collection.changeState);
412
+ }, collection.changeState);
513
413
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
514
414
  }
515
415
  /**
516
416
  * Track an entity before updating it in the collection.
517
417
  * Does NOT update the collection (the reducer's job).
518
- * @param {?} update The entity to update.
519
- * @param {?} collection The entity collection
520
- * @param {?=} mergeStrategy
521
- * @return {?}
418
+ * @param update The entity to update.
419
+ * @param collection The entity collection
420
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
522
421
  */
523
422
  trackUpdateOne(update, collection, mergeStrategy) {
524
423
  return update == null
@@ -528,10 +427,9 @@ export class EntityChangeTrackerBase {
528
427
  /**
529
428
  * Track multiple entities before upserting (adding and updating) them to the collection.
530
429
  * Does NOT update the collection (the reducer's job).
531
- * @param {?} entities The entities to add or update. They must be complete entities with ids.
532
- * @param {?} collection The entity collection
533
- * @param {?=} mergeStrategy
534
- * @return {?}
430
+ * @param entities The entities to add or update. They must be complete entities with ids.
431
+ * @param collection The entity collection
432
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
535
433
  */
536
434
  trackUpsertMany(entities, collection, mergeStrategy) {
537
435
  if (mergeStrategy === MergeStrategy.IgnoreChanges ||
@@ -539,30 +437,19 @@ export class EntityChangeTrackerBase {
539
437
  entities.length === 0) {
540
438
  return collection; // nothing to track
541
439
  }
542
- /** @type {?} */
543
440
  let didMutate = false;
544
- /** @type {?} */
545
441
  const entityMap = collection.entities;
546
- /** @type {?} */
547
- const changeState = entities.reduce((/**
548
- * @param {?} chgState
549
- * @param {?} entity
550
- * @return {?}
551
- */
552
- (chgState, entity) => {
553
- /** @type {?} */
442
+ const changeState = entities.reduce((chgState, entity) => {
554
443
  const id = this.selectId(entity);
555
444
  if (id == null || id === '') {
556
445
  throw new Error(`${collection.entityName} entity upsert requires a key to be tracked`);
557
446
  }
558
- /** @type {?} */
559
447
  const trackedChange = chgState[id];
560
448
  if (!trackedChange) {
561
449
  if (!didMutate) {
562
450
  didMutate = true;
563
451
  chgState = Object.assign({}, chgState);
564
452
  }
565
- /** @type {?} */
566
453
  const originalValue = entityMap[id];
567
454
  chgState[id] =
568
455
  originalValue == null
@@ -570,16 +457,15 @@ export class EntityChangeTrackerBase {
570
457
  : { changeType: ChangeType.Updated, originalValue };
571
458
  }
572
459
  return chgState;
573
- }), collection.changeState);
460
+ }, collection.changeState);
574
461
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
575
462
  }
576
463
  /**
577
464
  * Track an entity before upsert (adding and updating) it to the collection.
578
465
  * Does NOT update the collection (the reducer's job).
579
- * @param {?} entity
580
- * @param {?} collection The entity collection
581
- * @param {?=} mergeStrategy
582
- * @return {?}
466
+ * @param entities The entity to add or update. It must be a complete entity with its id.
467
+ * @param collection The entity collection
468
+ * @param [mergeStrategy] Track by default. Don't track if is MergeStrategy.IgnoreChanges.
583
469
  */
584
470
  trackUpsertOne(entity, collection, mergeStrategy) {
585
471
  return entity == null
@@ -591,74 +477,55 @@ export class EntityChangeTrackerBase {
591
477
  /**
592
478
  * Revert the unsaved changes for all collection.
593
479
  * Harmless when there are no entity changes to undo.
594
- * @param {?} collection The entity collection
595
- * @return {?}
480
+ * @param collection The entity collection
596
481
  */
597
482
  undoAll(collection) {
598
- /** @type {?} */
599
483
  const ids = Object.keys(collection.changeState);
600
- const { remove, upsert } = ids.reduce((/**
601
- * @param {?} acc
602
- * @param {?} id
603
- * @return {?}
604
- */
605
- (acc, id) => {
606
- /** @type {?} */
607
- const changeState = (/** @type {?} */ (acc.chgState[id]));
484
+ const { remove, upsert } = ids.reduce((acc, id) => {
485
+ const changeState = acc.chgState[id];
608
486
  switch (changeState.changeType) {
609
487
  case ChangeType.Added:
610
488
  acc.remove.push(id);
611
489
  break;
612
490
  case ChangeType.Deleted:
613
- /** @type {?} */
614
- const removed = (/** @type {?} */ (changeState)).originalValue;
491
+ const removed = changeState.originalValue;
615
492
  if (removed) {
616
493
  acc.upsert.push(removed);
617
494
  }
618
495
  break;
619
496
  case ChangeType.Updated:
620
- acc.upsert.push((/** @type {?} */ ((/** @type {?} */ (changeState)).originalValue)));
497
+ acc.upsert.push(changeState.originalValue);
621
498
  break;
622
499
  }
623
500
  return acc;
624
- }),
501
+ },
625
502
  // entitiesToUndo
626
503
  {
627
- remove: (/** @type {?} */ ([])),
628
- upsert: (/** @type {?} */ ([])),
504
+ remove: [],
505
+ upsert: [],
629
506
  chgState: collection.changeState,
630
507
  });
631
- collection = this.adapter.removeMany((/** @type {?} */ (remove)), collection);
508
+ collection = this.adapter.removeMany(remove, collection);
632
509
  collection = this.adapter.upsertMany(upsert, collection);
633
510
  return Object.assign(Object.assign({}, collection), { changeState: {} });
634
511
  }
635
512
  /**
636
513
  * Revert the unsaved changes for the given entities.
637
514
  * Harmless when there are no entity changes to undo.
638
- * @param {?} entityOrIdList The entities to revert or their ids.
639
- * @param {?} collection The entity collection
640
- * @return {?}
515
+ * @param entityOrIdList The entities to revert or their ids.
516
+ * @param collection The entity collection
641
517
  */
642
518
  undoMany(entityOrIdList, collection) {
643
519
  if (entityOrIdList == null || entityOrIdList.length === 0) {
644
520
  return collection; // nothing to undo
645
521
  }
646
- /** @type {?} */
647
522
  let didMutate = false;
648
- const { changeState, remove, upsert } = entityOrIdList.reduce((/**
649
- * @param {?} acc
650
- * @param {?} entityOrId
651
- * @return {?}
652
- */
653
- (acc, entityOrId) => {
654
- /** @type {?} */
523
+ const { changeState, remove, upsert } = entityOrIdList.reduce((acc, entityOrId) => {
655
524
  let chgState = acc.changeState;
656
- /** @type {?} */
657
525
  const id = typeof entityOrId === 'object'
658
526
  ? this.selectId(entityOrId)
659
- : ((/** @type {?} */ (entityOrId)));
660
- /** @type {?} */
661
- const change = (/** @type {?} */ (chgState[id]));
527
+ : entityOrId;
528
+ const change = chgState[id];
662
529
  if (change) {
663
530
  if (!didMutate) {
664
531
  chgState = Object.assign({}, chgState);
@@ -671,35 +538,33 @@ export class EntityChangeTrackerBase {
671
538
  acc.remove.push(id);
672
539
  break;
673
540
  case ChangeType.Deleted:
674
- /** @type {?} */
675
- const removed = (/** @type {?} */ (change)).originalValue;
541
+ const removed = change.originalValue;
676
542
  if (removed) {
677
543
  acc.upsert.push(removed);
678
544
  }
679
545
  break;
680
546
  case ChangeType.Updated:
681
- acc.upsert.push((/** @type {?} */ ((/** @type {?} */ (change)).originalValue)));
547
+ acc.upsert.push(change.originalValue);
682
548
  break;
683
549
  }
684
550
  }
685
551
  return acc;
686
- }),
552
+ },
687
553
  // entitiesToUndo
688
554
  {
689
- remove: (/** @type {?} */ ([])),
690
- upsert: (/** @type {?} */ ([])),
555
+ remove: [],
556
+ upsert: [],
691
557
  changeState: collection.changeState,
692
558
  });
693
- collection = this.adapter.removeMany((/** @type {?} */ (remove)), collection);
559
+ collection = this.adapter.removeMany(remove, collection);
694
560
  collection = this.adapter.upsertMany(upsert, collection);
695
561
  return didMutate ? Object.assign(Object.assign({}, collection), { changeState }) : collection;
696
562
  }
697
563
  /**
698
564
  * Revert the unsaved changes for the given entity.
699
565
  * Harmless when there are no entity changes to undo.
700
- * @param {?} entityOrId The entity to revert or its id.
701
- * @param {?} collection The entity collection
702
- * @return {?}
566
+ * @param entityOrId The entity to revert or its id.
567
+ * @param collection The entity collection
703
568
  */
704
569
  undoOne(entityOrId, collection) {
705
570
  return entityOrId == null
@@ -707,16 +572,4 @@ export class EntityChangeTrackerBase {
707
572
  : this.undoMany([entityOrId], collection);
708
573
  }
709
574
  }
710
- if (false) {
711
- /**
712
- * @type {?}
713
- * @private
714
- */
715
- EntityChangeTrackerBase.prototype.adapter;
716
- /**
717
- * @type {?}
718
- * @private
719
- */
720
- EntityChangeTrackerBase.prototype.selectId;
721
- }
722
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWNoYW5nZS10cmFja2VyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vbW9kdWxlcy9kYXRhLyIsInNvdXJjZXMiOlsic3JjL3JlZHVjZXJzL2VudGl0eS1jaGFuZ2UtdHJhY2tlci1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBRUEsT0FBTyxFQUFFLFVBQVUsRUFBb0IsTUFBTSxxQkFBcUIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDJCQUEyQixDQUFDOzs7Ozs7OztBQVMxRCxNQUFNLE9BQU8sdUJBQXVCOzs7OztJQUNsQyxZQUNVLE9BQXlCLEVBQ3pCLFFBQXVCO1FBRHZCLFlBQU8sR0FBUCxPQUFPLENBQWtCO1FBQ3pCLGFBQVEsR0FBUixRQUFRLENBQWU7UUFFL0Isb0RBQW9EO1FBQ3BELElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxJQUFJLGVBQWUsQ0FBQztJQUM5QyxDQUFDOzs7Ozs7OztJQVFELFNBQVMsQ0FBQyxVQUErQjtRQUN2QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQ3JELENBQUMsQ0FBQyxVQUFVO1lBQ1osQ0FBQyxpQ0FBTSxVQUFVLEtBQUUsV0FBVyxFQUFFLEVBQUUsR0FBRSxDQUFDO0lBQ3pDLENBQUM7Ozs7Ozs7O0lBUUQsVUFBVSxDQUNSLGNBQXVDLEVBQ3ZDLFVBQStCO1FBRS9CLElBQUksY0FBYyxJQUFJLElBQUksSUFBSSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN6RCxPQUFPLFVBQVUsQ0FBQyxDQUFDLG9CQUFvQjtTQUN4Qzs7WUFDRyxTQUFTLEdBQUcsS0FBSzs7Y0FDZixXQUFXLEdBQUcsY0FBYyxDQUFDLE1BQU07Ozs7O1FBQUMsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFF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QUFVLENBQUMsbUJBQUEsTUFBTSxFQUFZLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckUsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN6RCxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlDQUFNLFVBQVUsS0FBRSxXQUFXLElBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUNqRSxDQUFDOzs7Ozs7OztJQVFELE9BQU8sQ0FDTCxVQUErQixFQUMvQixVQUErQjtRQUUvQixPQUFPLFVBQVUsSUFBSSxJQUFJO1lBQ3ZCLENBQUMsQ0FBQyxVQUFVO1lBQ1osQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUM5QyxDQUFDO0NBRUY7Ozs7OztJQXB0QkcsMENBQWlDOzs7OztJQUNqQywyQ0FBK0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnRpdHlBZGFwdGVyLCBJZFNlbGVjdG9yLCBVcGRhdGUgfSBmcm9tICdAbmdyeC9lbnRpdHknO1xuXG5pbXBvcnQgeyBDaGFuZ2VUeXBlLCBFbnRpdHlDb2xsZWN0aW9uIH0gZnJvbSAnLi9lbnRpdHktY29sbGVjdGlvbic7XG5pbXBvcnQgeyBkZWZhdWx0U2VsZWN0SWQgfSBmcm9tICcuLi91dGlscy91dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5Q2hhbmdlVHJhY2tlciB9IGZyb20gJy4vZW50aXR5LWNoYW5nZS10cmFja2VyJztcbmltcG9ydCB7IE1lcmdlU3RyYXRlZ3kgfSBmcm9tICcuLi9hY3Rpb25zL21lcmdlLXN0cmF0ZWd5JztcbmltcG9ydCB7IFVwZGF0ZVJlc3BvbnNlRGF0YSB9IGZyb20gJy4uL2FjdGlvbnMvdXBkYXRlLXJlc3BvbnNlLWRhdGEnO1xuXG4vKipcbiAqIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIEVudGl0eUNoYW5nZVRyYWNrZXIgd2l0aFxuICogbWV0aG9kcyBmb3IgdHJhY2tpbmcsIGNvbW1pdHRpbmcsIGFuZCByZXZlcnRpbmcvdW5kb2luZyB1bnNhdmVkIGVudGl0eSBjaGFuZ2VzLlxuICogVXNlZCBieSBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZHMgd2hpY2ggc2hvdWxkIGNhbGwgdHJhY2tlciBtZXRob2RzIEJFRk9SRSBtb2RpZnlpbmcgdGhlIGNvbGxlY3Rpb24uXG4gKiBTZWUgRW50aXR5Q2hhbmdlVHJhY2tlciBkb2NzLlxuICovXG5leHBvcnQgY2xhc3MgRW50aXR5Q2hhbmdlVHJhY2tlckJhc2U8VD4gaW1wbGVtZW50cyBFbnRpdHlDaGFuZ2VUcmFja2VyPFQ+IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhZGFwdGVyOiBFbnRpdHlBZGFwdGVyPFQ+LFxuICAgIHByaXZhdGUgc2VsZWN0SWQ6IElkU2VsZWN0b3I8VD5cbiAgKSB7XG4gICAgLyoqIEV4dHJhY3QgdGhlIHByaW1hcnkga2V5IChpZCk7IGRlZmF1bHQgdG8gYGlkYCAqL1xuICAgIHRoaXMuc2VsZWN0SWQgPSBzZWxlY3RJZCB8fCBkZWZhdWx0U2VsZWN0SWQ7XG4gIH1cblxuICAvLyAjcmVnaW9uIGNvbW1pdCBtZXRob2RzXG4gIC8qKlxuICAgKiBDb21taXQgYWxsIGNoYW5nZXMgYXMgd2hlbiB0aGUgY29sbGVjdGlvbiBoYXMgYmVlbiBjb21wbGV0ZWx5IHJlbG9hZGVkIGZyb20gdGhlIHNlcnZlci5cbiAgICogSGFybWxlc3Mgd2hlbiB0aGVyZSBhcmUgbm8gZW50aXR5IGNoYW5nZXMgdG8gY29tbWl0LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIGNvbW1pdEFsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpLmxlbmd0aCA9PT0gMFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGU6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogQ29tbWl0IGNoYW5nZXMgZm9yIHRoZSBnaXZlbiBlbnRpdGllcyBhcyB3aGVuIHRoZXkgaGF2ZSBiZWVuIHJlZnJlc2hlZCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIEhhcm1sZXNzIHdoZW4gdGhlcmUgYXJlIG5vIGVudGl0eSBjaGFuZ2VzIHRvIGNvbW1pdC5cbiAgICogQHBhcmFtIGVudGl0eU9ySWRMaXN0IFRoZSBlbnRpdGllcyB0byBjbGVhciB0cmFja2luZyBvciB0aGVpciBpZHMuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKi9cbiAgY29tbWl0TWFueShcbiAgICBlbnRpdHlPcklkTGlzdDogKG51bWJlciB8IHN0cmluZyB8IFQpW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAoZW50aXR5T3JJZExpc3QgPT0gbnVsbCB8fCBlbnRpdHlPcklkTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjb2xsZWN0aW9uOyAvLyBub3RoaW5nIHRvIGNvbW1pdFxuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgY29uc3QgY2hhbmdlU3RhdGUgPSBlbnRpdHlPcklkTGlzdC5yZWR1Y2UoKGNoZ1N0YXRlLCBlbnRpdHlPcklkKSA9PiB7XG4gICAgICBjb25zdCBpZCA9XG4gICAgICAgIHR5cGVvZiBlbnRpdHlPcklkID09PSAnb2JqZWN0J1xuICAgICAgICAgID8gdGhpcy5zZWxlY3RJZChlbnRpdHlPcklkKVxuICAgICAgICAgIDogKGVudGl0eU9ySWQgYXMgc3RyaW5nIHwgbnVtYmVyKTtcbiAgICAgIGlmIChjaGdTdGF0ZVtpZF0pIHtcbiAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSBjaGdTdGF0ZVtpZF07XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hnU3RhdGU7XG4gICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG5cbiAgICByZXR1cm4gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21taXQgY2hhbmdlcyBmb3IgdGhlIGdpdmVuIGVudGl0eSBhcyB3aGVuIGl0IGhhdmUgYmVlbiByZWZyZXNoZWQgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBIYXJtbGVzcyB3aGVuIG5vIGVudGl0eSBjaGFuZ2VzIHRvIGNvbW1pdC5cbiAgICogQHBhcmFtIGVudGl0eU9ySWQgVGhlIGVudGl0eSB0byBjbGVhciB0cmFja2luZyBvciBpdHMgaWQuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKi9cbiAgY29tbWl0T25lKFxuICAgIGVudGl0eU9ySWQ6IG51bWJlciB8IHN0cmluZyB8IFQsXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gZW50aXR5T3JJZCA9PSBudWxsXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogdGhpcy5jb21taXRNYW55KFtlbnRpdHlPcklkXSwgY29sbGVjdGlvbik7XG4gIH1cblxuICAvLyAjZW5kcmVnaW9uIGNvbW1pdCBtZXRob2RzXG5cbiAgLy8gI3JlZ2lvbiBtZXJnZSBxdWVyeVxuICAvKipcbiAgICogTWVyZ2UgcXVlcnkgcmVzdWx0cyBpbnRvIHRoZSBjb2xsZWN0aW9uLCBhZGp1c3RpbmcgdGhlIENoYW5nZVN0YXRlIHBlciB0aGUgbWVyZ2VTdHJhdGVneS5cbiAgICogQHBhcmFtIGVudGl0aWVzIEVudGl0aWVzIHJldHVybmVkIGZyb20gcXVlcnlpbmcgdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gSG93IHRvIG1lcmdlIGEgcXVlcmllZCBlbnRpdHkgd2hlbiB0aGUgY29ycmVzcG9uZGluZyBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gaGFzIGFuIHVuc2F2ZWQgY2hhbmdlLlxuICAgKiBEZWZhdWx0cyB0byBNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlcy5cbiAgICogQHJldHVybnMgVGhlIG1lcmdlZCBFbnRpdHlDb2xsZWN0aW9uLlxuICAgKi9cbiAgbWVyZ2VRdWVyeVJlc3VsdHMoXG4gICAgZW50aXRpZXM6IFRbXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLm1lcmdlU2VydmVyVXBzZXJ0cyhcbiAgICAgIGVudGl0aWVzLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIE1lcmdlU3RyYXRlZ3kuUHJlc2VydmVDaGFuZ2VzLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBtZXJnZSBxdWVyeSByZXN1bHRzXG5cbiAgLy8gI3JlZ2lvbiBtZXJnZSBzYXZlIHJlc3VsdHNcbiAgLyoqXG4gICAqIE1lcmdlIHJlc3VsdCBvZiBzYXZpbmcgbmV3IGVudGl0aWVzIGludG8gdGhlIGNvbGxlY3Rpb24sIGFkanVzdGluZyB0aGUgQ2hhbmdlU3RhdGUgcGVyIHRoZSBtZXJnZVN0cmF0ZWd5LlxuICAgKiBUaGUgZGVmYXVsdCBpcyBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBFbnRpdGllcyByZXR1cm5lZCBmcm9tIHNhdmluZyBuZXcgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gSG93IHRvIG1lcmdlIGEgc2F2ZWQgZW50aXR5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGhhcyBhbiB1bnNhdmVkIGNoYW5nZS5cbiAgICogRGVmYXVsdHMgdG8gTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcmV0dXJucyBUaGUgbWVyZ2VkIEVudGl0eUNvbGxlY3Rpb24uXG4gICAqL1xuICBtZXJnZVNhdmVBZGRzKFxuICAgIGVudGl0aWVzOiBUW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5tZXJnZVNlcnZlclVwc2VydHMoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMsXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZSBzdWNjZXNzZnVsIHJlc3VsdCBvZiBkZWxldGluZyBlbnRpdGllcyBvbiB0aGUgc2VydmVyIHRoYXQgaGF2ZSB0aGUgZ2l2ZW4gcHJpbWFyeSBrZXlzXG4gICAqIENsZWFycyB0aGUgZW50aXR5IGNoYW5nZVN0YXRlIGZvciB0aG9zZSBrZXlzIHVubGVzcyB0aGUgTWVyZ2VTdHJhdGVneSBpcyBpZ25vcmVDaGFuZ2VzLlxuICAgKiBAcGFyYW0gZW50aXRpZXMga2V5cyBwcmltYXJ5IGtleXMgb2YgdGhlIGVudGl0aWVzIHRvIHJlbW92ZS9kZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIEhvdyB0byBhZGp1c3QgY2hhbmdlIHRyYWNraW5nIHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGhhcyBhbiB1bnNhdmVkIGNoYW5nZS5cbiAgICogRGVmYXVsdHMgdG8gTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcmV0dXJucyBUaGUgbWVyZ2VkIEVudGl0eUNvbGxlY3Rpb24uXG4gICAqL1xuICBtZXJnZVNhdmVEZWxldGVzKFxuICAgIGtleXM6IChudW1iZXIgfCBzdHJpbmcpW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBtZXJnZVN0cmF0ZWd5ID1cbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT0gbnVsbCA/IE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcyA6IG1lcmdlU3RyYXRlZ3k7XG4gICAgLy8gc2FtZSBsb2dpYyBmb3IgYWxsIG5vbi1pZ25vcmUgbWVyZ2Ugc3RyYXRlZ2llczogYWx3YXlzIGNsZWFyIChjb21taXQpIHRoZSBjaGFuZ2VzXG4gICAgY29uc3QgZGVsZXRlSWRzID0ga2V5cyBhcyBzdHJpbmdbXTsgLy8gbWFrZSBUeXBlU2NyaXB0IGhhcHB5XG4gICAgY29sbGVjdGlvbiA9XG4gICAgICBtZXJnZVN0cmF0ZWd5ID09PSBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXNcbiAgICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICAgIDogdGhpcy5jb21taXRNYW55KGRlbGV0ZUlkcywgY29sbGVjdGlvbik7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZW1vdmVNYW55KGRlbGV0ZUlkcywgY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgcmVzdWx0IG9mIHNhdmluZyB1cGRhdGVkIGVudGl0aWVzIGludG8gdGhlIGNvbGxlY3Rpb24sIGFkanVzdGluZyB0aGUgQ2hhbmdlU3RhdGUgcGVyIHRoZSBtZXJnZVN0cmF0ZWd5LlxuICAgKiBUaGUgZGVmYXVsdCBpcyBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMuXG4gICAqIEBwYXJhbSB1cGRhdGVSZXNwb25zZURhdGEgRW50aXR5IHJlc3BvbnNlIGRhdGEgcmV0dXJuZWQgZnJvbSBzYXZpbmcgdXBkYXRlZCBlbnRpdGllcyB0byB0aGUgc2VydmVyLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBIb3cgdG8gbWVyZ2UgYSBzYXZlZCBlbnRpdHkgd2hlbiB0aGUgY29ycmVzcG9uZGluZyBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gaGFzIGFuIHVuc2F2ZWQgY2hhbmdlLlxuICAgKiBEZWZhdWx0cyB0byBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMuXG4gICAqIEBwYXJhbSBbc2tpcFVuY2hhbmdlZF0gVHJ1ZSBtZWFucyBza2lwIHVwZGF0ZSBpZiBzZXJ2ZXIgZGlkbid0IGNoYW5nZSBpdC4gRmFsc2UgYnkgZGVmYXVsdC5cbiAgICogSWYgdGhlIHVwZGF0ZSB3YXMgb3B0aW1pc3RpYyBhbmQgdGhlIHNlcnZlciBkaWRuJ3QgbWFrZSBtb3JlIGNoYW5nZXMgb2YgaXRzIG93blxuICAgKiB0aGVuIHRoZSB1cGRhdGVzIGFyZSBhbHJlYWR5IGluIHRoZSBjb2xsZWN0aW9uIGFuZCBzaG91bGRuJ3QgbWFrZSB0aGVtIGFnYWluLlxuICAgKiBAcmV0dXJucyBUaGUgbWVyZ2VkIEVudGl0eUNvbGxlY3Rpb24uXG4gICAqL1xuICBtZXJnZVNhdmVVcGRhdGVzKFxuICAgIHVwZGF0ZVJlc3BvbnNlRGF0YTogVXBkYXRlUmVzcG9uc2VEYXRhPFQ+W10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneSxcbiAgICBza2lwVW5jaGFuZ2VkID0gZmFsc2VcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKHVwZGF0ZVJlc3BvbnNlRGF0YSA9PSBudWxsIHx8IHVwZGF0ZVJlc3BvbnNlRGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjb2xsZWN0aW9uOyAvLyBub3RoaW5nIHRvIG1lcmdlLlxuICAgIH1cblxuICAgIGxldCBkaWRNdXRhdGUgPSBmYWxzZTtcbiAgICBsZXQgY2hhbmdlU3RhdGUgPSBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlO1xuICAgIG1lcmdlU3RyYXRlZ3kgPVxuICAgICAgbWVyZ2VTdHJhdGVneSA9PSBudWxsID8gTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzIDogbWVyZ2VTdHJhdGVneTtcbiAgICBsZXQgdXBkYXRlczogVXBkYXRlPFQ+W107XG5cbiAgICBzd2l0Y2ggKG1lcmdlU3RyYXRlZ3kpIHtcbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzOlxuICAgICAgICB1cGRhdGVzID0gZmlsdGVyQ2hhbmdlZCh1cGRhdGVSZXNwb25zZURhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU1hbnkodXBkYXRlcywgY29sbGVjdGlvbik7XG5cbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzOlxuICAgICAgICBjaGFuZ2VTdGF0ZSA9IHVwZGF0ZVJlc3BvbnNlRGF0YS5yZWR1Y2UoKGNoZ1N0YXRlLCB1cGRhdGUpID0+IHtcbiAgICAgICAgICBjb25zdCBvbGRJZCA9IHVwZGF0ZS5pZDtcbiAgICAgICAgICBjb25zdCBjaGFuZ2UgPSBjaGdTdGF0ZVtvbGRJZF07XG4gICAgICAgICAgaWYgKGNoYW5nZSkge1xuICAgICAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgY2hnU3RhdGVbb2xkSWRdO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gY2hnU3RhdGU7XG4gICAgICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuXG4gICAgICAgIGNvbGxlY3Rpb24gPSBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuXG4gICAgICAgIHVwZGF0ZXMgPSBmaWx0ZXJDaGFuZ2VkKHVwZGF0ZVJlc3BvbnNlRGF0YSk7XG4gICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlTWFueSh1cGRhdGVzLCBjb2xsZWN0aW9uKTtcblxuICAgICAgY2FzZSBNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlczoge1xuICAgICAgICBjb25zdCB1cGRhdGVhYmxlRW50aXRpZXMgPSBbXSBhcyBVcGRhdGVSZXNwb25zZURhdGE8VD5bXTtcbiAgICAgICAgY2hhbmdlU3RhdGUgPSB1cGRhdGVSZXNwb25zZURhdGEucmVkdWNlKChjaGdTdGF0ZSwgdXBkYXRlKSA9PiB7XG4gICAgICAgICAgY29uc3Qgb2xkSWQgPSB1cGRhdGUuaWQ7XG4gICAgICAgICAgY29uc3QgY2hhbmdlID0gY2hnU3RhdGVbb2xkSWRdO1xuICAgICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIC8vIFRyYWNraW5nIGEgY2hhbmdlIHNvIHVwZGF0ZSBvcmlnaW5hbCB2YWx1ZSBidXQgbm90IHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICAgICAgICBpZiAoIWRpZE11dGF0ZSkge1xuICAgICAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5ld0lkID0gdGhpcy5zZWxlY3RJZCh1cGRhdGUuY2hhbmdlcyBhcyBUKTtcbiAgICAgICAgICAgIGNvbnN0IG9sZENoYW5nZVN0YXRlID0gY2hhbmdlO1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNlcnZlciBjaGFuZ2VkIHRoZSBpZCwgcmVnaXN0ZXIgdGhlIG5ldyBcIm9yaWdpbmFsVmFsdWVcIiB1bmRlciB0aGUgbmV3IGlkXG4gICAgICAgICAgICAvLyBhbmQgcmVtb3ZlIHRoZSBjaGFuZ2UgdHJhY2tlZCB1bmRlciB0aGUgb2xkIGlkLlxuICAgICAgICAgICAgaWYgKG5ld0lkICE9PSBvbGRJZCkge1xuICAgICAgICAgICAgICBkZWxldGUgY2hnU3RhdGVbb2xkSWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmV3T3JpZ1ZhbHVlID0ge1xuICAgICAgICAgICAgICAuLi4ob2xkQ2hhbmdlU3RhdGUhLm9yaWdpbmFsVmFsdWUgYXMgYW55KSxcbiAgICAgICAgICAgICAgLi4uKHVwZGF0ZS5jaGFuZ2VzIGFzIGFueSksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgKGNoZ1N0YXRlIGFzIGFueSlbbmV3SWRdID0ge1xuICAgICAgICAgICAgICAuLi5vbGRDaGFuZ2VTdGF0ZSxcbiAgICAgICAgICAgICAgb3JpZ2luYWxWYWx1ZTogbmV3T3JpZ1ZhbHVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXBkYXRlYWJsZUVudGl0aWVzLnB1c2godXBkYXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgICAgICB9LCBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKTtcbiAgICAgICAgY29sbGVjdGlvbiA9IGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG5cbiAgICAgICAgdXBkYXRlcyA9IGZpbHRlckNoYW5nZWQodXBkYXRlYWJsZUVudGl0aWVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cGRhdGVNYW55KHVwZGF0ZXMsIGNvbGxlY3Rpb24pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbmRpdGlvbmFsbHkga2VlcCBvbmx5IHRob3NlIHVwZGF0ZXMgdGhhdCBoYXZlIGFkZGl0aW9uYWwgc2VydmVyIGNoYW5nZXMuXG4gICAgICogKGUuZy4sIGZvciBvcHRpbWlzdGljIHNhdmVzIGJlY2F1c2UgdGhleSB1cGRhdGVzIGFyZSBhbHJlYWR5IGluIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24pXG4gICAgICogU3RyaXAgb2ZmIHRoZSBgY2hhbmdlZGAgcHJvcGVydHkuXG4gICAgICogQHJlc3BvbnNlRGF0YSBFbnRpdHkgcmVzcG9uc2UgZGF0YSBmcm9tIHNlcnZlci5cbiAgICAgKiBNYXkgYmUgYW4gVXBkYXRlUmVzcG9uc2VEYXRhPFQ+LCBhIHN1YmNsYXNzIG9mIFVwZGF0ZTxUPiB3aXRoIGEgJ2NoYW5nZWQnIGZsYWcuXG4gICAgICogQHJldHVybnMgVXBkYXRlPFQ+ICh3aXRob3V0IHRoZSBjaGFuZ2VkIGZsYWcpXG4gICAgICovXG4gICAgZnVuY3Rpb24gZmlsdGVyQ2hhbmdlZChyZXNwb25zZURhdGE6IFVwZGF0ZVJlc3BvbnNlRGF0YTxUPltdKTogVXBkYXRlPFQ+W10ge1xuICAgICAgaWYgKHNraXBVbmNoYW5nZWQgPT09IHRydWUpIHtcbiAgICAgICAgLy8ga2VlcCBvbmx5IHRob3NlIHVwZGF0ZXMgdGhhdCB0aGUgc2VydmVyIGNoYW5nZWQgKGtub3dhYmxlIGlmIGlzIFVwZGF0ZVJlc3BvbnNlRGF0YTxUPilcbiAgICAgICAgcmVzcG9uc2VEYXRhID0gcmVzcG9uc2VEYXRhLmZpbHRlcigocikgPT4gci5jaGFuZ2VkID09PSB0cnVlKTtcbiAgICAgIH1cbiAgICAgIC8vIFN0cmlwIHVuY2hhbmdlZCBwcm9wZXJ0eSBmcm9tIHJlc3BvbnNlRGF0YSwgbGVhdmluZyBqdXN0IHRoZSBwdXJlIFVwZGF0ZTxUPlxuICAgICAgLy8gVE9ETzogUmVtb3ZlPyBwcm9iYWJseSBub3QgbmVjZXNzYXJ5IGFzIHRoZSBVcGRhdGUgaXNuJ3Qgc3RvcmVkIGFuZCBhZGFwdGVyIHdpbGwgaWdub3JlIGBjaGFuZ2VkYC5cbiAgICAgIHJldHVybiByZXNwb25zZURhdGEubWFwKChyKSA9PiAoeyBpZDogci5pZCBhcyBhbnksIGNoYW5nZXM6IHIuY2hhbmdlcyB9KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlIHJlc3VsdCBvZiBzYXZpbmcgdXBzZXJ0ZWQgZW50aXRpZXMgaW50byB0aGUgY29sbGVjdGlvbiwgYWRqdXN0aW5nIHRoZSBDaGFuZ2VTdGF0ZSBwZXIgdGhlIG1lcmdlU3RyYXRlZ3kuXG4gICAqIFRoZSBkZWZhdWx0IGlzIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcy5cbiAgICogQHBhcmFtIGVudGl0aWVzIEVudGl0aWVzIHJldHVybmVkIGZyb20gc2F2aW5nIHVwc2VydHMgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gSG93IHRvIG1lcmdlIGEgc2F2ZWQgZW50aXR5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGhhcyBhbiB1bnNhdmVkIGNoYW5nZS5cbiAgICogRGVmYXVsdHMgdG8gTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcmV0dXJucyBUaGUgbWVyZ2VkIEVudGl0eUNvbGxlY3Rpb24uXG4gICAqL1xuICBtZXJnZVNhdmVVcHNlcnRzKFxuICAgIGVudGl0aWVzOiBUW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5tZXJnZVNlcnZlclVwc2VydHMoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMsXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIG1lcmdlIHNhdmUgcmVzdWx0c1xuXG4gIC8vICNyZWdpb24gcXVlcnkgJiBzYXZlIGhlbHBlcnNcbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSBlbnRpdGllcyBFbnRpdGllcyB0byBtZXJnZVxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBDb2xsZWN0aW9uIGludG8gd2hpY2ggZW50aXRpZXMgYXJlIG1lcmdlZFxuICAgKiBAcGFyYW0gZGVmYXVsdE1lcmdlU3RyYXRlZ3kgSG93IHRvIG1lcmdlIHdoZW4gYWN0aW9uJ3MgTWVyZ2VTdHJhdGVneSBpcyB1bnNwZWNpZmllZFxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRoZSBhY3Rpb24ncyBNZXJnZVN0cmF0ZWd5XG4gICAqL1xuICBwcml2YXRlIG1lcmdlU2VydmVyVXBzZXJ0cyhcbiAgICBlbnRpdGllczogVFtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgZGVmYXVsdE1lcmdlU3RyYXRlZ3k6IE1lcmdlU3RyYXRlZ3ksXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKGVudGl0aWVzID09IG51bGwgfHwgZW50aXRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byBtZXJnZS5cbiAgICB9XG5cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgbGV0IGNoYW5nZVN0YXRlID0gY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZTtcbiAgICBtZXJnZVN0cmF0ZWd5ID1cbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT0gbnVsbCA/IGRlZmF1bHRNZXJnZVN0cmF0ZWd5IDogbWVyZ2VTdHJhdGVneTtcblxuICAgIHN3aXRjaCAobWVyZ2VTdHJhdGVneSkge1xuICAgICAgY2FzZSBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXM6XG4gICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueShlbnRpdGllcywgY29sbGVjdGlvbik7XG5cbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzOlxuICAgICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuXG4gICAgICAgIGNoYW5nZVN0YXRlID0gZW50aXRpZXMucmVkdWNlKChjaGdTdGF0ZSwgZW50aXR5KSA9PiB7XG4gICAgICAgICAgY29uc3QgaWQgPSB0aGlzLnNlbGVjdElkKGVudGl0eSk7XG4gICAgICAgICAgY29uc3QgY2hhbmdlID0gY2hnU3RhdGVbaWRdO1xuICAgICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGNoZ1N0YXRlW2lkXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgICAgICB9LCBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKTtcblxuICAgICAgICByZXR1cm4gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcblxuICAgICAgY2FzZSBNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlczoge1xuICAgICAgICBjb25zdCB1cHNlcnRFbnRpdGllcyA9IFtdIGFzIFRbXTtcbiAgICAgICAgY2hhbmdlU3RhdGUgPSBlbnRpdGllcy5yZWR1Y2UoKGNoZ1N0YXRlLCBlbnRpdHkpID0+IHtcbiAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuc2VsZWN0SWQoZW50aXR5KTtcbiAgICAgICAgICBjb25zdCBjaGFuZ2UgPSBjaGdTdGF0ZVtpZF07XG4gICAgICAgICAgaWYgKGNoYW5nZSkge1xuICAgICAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICAgICAgY2hnU3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgLi4uY2hnU3RhdGUsXG4gICAgICAgICAgICAgICAgW2lkXToge1xuICAgICAgICAgICAgICAgICAgLi4uY2hnU3RhdGVbaWRdISxcbiAgICAgICAgICAgICAgICAgIG9yaWdpbmFsVmFsdWU6IGVudGl0eSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1cHNlcnRFbnRpdGllcy5wdXNoKGVudGl0eSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBjaGdTdGF0ZTtcbiAgICAgICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG5cbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cHNlcnRNYW55KHVwc2VydEVudGl0aWVzLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vICNlbmRyZWdpb24gcXVlcnkgJiBzYXZlIGhlbHBlcnNcblxuICAvLyAjcmVnaW9uIHRyYWNrIG1ldGhvZHNcbiAgLyoqXG4gICAqIFRyYWNrIG11bHRpcGxlIGVudGl0aWVzIGJlZm9yZSBhZGRpbmcgdGhlbSB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogRG9lcyBOT1QgYWRkIHRvIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBUaGUgZW50aXRpZXMgdG8gYWRkLiBUaGV5IG11c3QgYWxsIGhhdmUgdGhlaXIgaWRzLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUcmFjayBieSBkZWZhdWx0LiBEb24ndCB0cmFjayBpZiBpcyBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMuXG4gICAqL1xuICB0cmFja0FkZE1hbnkoXG4gICAgZW50aXRpZXM6IFRbXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmIChcbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT09IE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcyB8fFxuICAgICAgZW50aXRpZXMgPT0gbnVsbCB8fFxuICAgICAgZW50aXRpZXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byB0cmFja1xuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgY29uc3QgY2hhbmdlU3RhdGUgPSBlbnRpdGllcy5yZWR1Y2UoKGNoZ1N0YXRlLCBlbnRpdHkpID0+IHtcbiAgICAgIGNvbnN0IGlkID0gdGhpcy5zZWxlY3RJZChlbnRpdHkpO1xuICAgICAgaWYgKGlkID09IG51bGwgfHwgaWQgPT09ICcnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgJHtjb2xsZWN0aW9uLmVudGl0eU5hbWV9IGVudGl0eSBhZGQgcmVxdWlyZXMgYSBrZXkgdG8gYmUgdHJhY2tlZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRyYWNrZWRDaGFuZ2UgPSBjaGdTdGF0ZVtpZF07XG5cbiAgICAgIGlmICghdHJhY2tlZENoYW5nZSkge1xuICAgICAgICBpZiAoIWRpZE11dGF0ZSkge1xuICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgIH1cbiAgICAgICAgY2hnU3RhdGVbaWRdID0geyBjaGFuZ2VUeXBlOiBDaGFuZ2VUeXBlLkFkZGVkIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hnU3RhdGU7XG4gICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG4gICAgcmV0dXJuIGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYW4gZW50aXR5IGJlZm9yZSBhZGRpbmcgaXQgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIERvZXMgTk9UIGFkZCB0byB0aGUgY29sbGVjdGlvbiAodGhlIHJlZHVjZXIncyBqb2IpLlxuICAgKiBAcGFyYW0gZW50aXR5IFRoZSBlbnRpdHkgdG8gYWRkLiBJdCBtdXN0IGhhdmUgYW4gaWQuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICogSWYgbm90IHNwZWNpZmllZCwgaW1wbGVtZW50YXRpb24gc3VwcGxpZXMgYSBkZWZhdWx0IHN0cmF0ZWd5LlxuICAgKi9cbiAgdHJhY2tBZGRPbmUoXG4gICAgZW50aXR5OiBULFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIGVudGl0eSA9PSBudWxsXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogdGhpcy50cmFja0FkZE1hbnkoW2VudGl0eV0sIGNvbGxlY3Rpb24sIG1lcmdlU3RyYXRlZ3kpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIG11bHRpcGxlIGVudGl0aWVzIGJlZm9yZSByZW1vdmluZyB0aGVtIHdpdGggdGhlIGludGVudGlvbiBvZiBkZWxldGluZyB0aGVtIG9uIHRoZSBzZXJ2ZXIuXG4gICAqIERvZXMgTk9UIHJlbW92ZSBmcm9tIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSBrZXlzIFRoZSBwcmltYXJ5IGtleXMgb2YgdGhlIGVudGl0aWVzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gVHJhY2sgYnkgZGVmYXVsdC4gRG9uJ3QgdHJhY2sgaWYgaXMgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzLlxuICAgKi9cbiAgdHJhY2tEZWxldGVNYW55KFxuICAgIGtleXM6IChudW1iZXIgfCBzdHJpbmcpW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAoXG4gICAgICBtZXJnZVN0cmF0ZWd5ID09PSBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMgfHxcbiAgICAgIGtleXMgPT0gbnVsbCB8fFxuICAgICAga2V5cy5sZW5ndGggPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiBjb2xsZWN0aW9uOyAvLyBub3RoaW5nIHRvIHRyYWNrXG4gICAgfVxuICAgIGxldCBkaWRNdXRhdGUgPSBmYWxzZTtcbiAgICBjb25zdCBlbnRpdHlNYXAgPSBjb2xsZWN0aW9uLmVudGl0aWVzO1xuICAgIGNvbnN0IGNoYW5nZVN0YXRlID0ga2V5cy5yZWR1Y2UoKGNoZ1N0YXRlLCBpZCkgPT4ge1xuICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IGVudGl0eU1hcFtpZF07XG4gICAgICBpZiAob3JpZ2luYWxWYWx1ZSkge1xuICAgICAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gY2hnU3RhdGVbaWRdO1xuICAgICAgICBpZiAodHJhY2tlZENoYW5nZSkge1xuICAgICAgICAgIGlmICh0cmFja2VkQ2hhbmdlLmNoYW5nZVR5cGUgPT09IENoYW5nZVR5cGUuQWRkZWQpIHtcbiAgICAgICAgICAgIC8vIFNwZWNpYWwgY2FzZTogc3RvcCB0cmFja2luZyBhbiBhZGRlZCBlbnRpdHkgdGhhdCB5b3UgZGVsZXRlXG4gICAgICAgICAgICAvLyBUaGUgY2FsbGVyIG11c3QgYWxzbyBkZXRlY3QgdGhpcywgcmVtb3ZlIGl0IGltbWVkaWF0ZWx5IGZyb20gdGhlIGNvbGxlY3Rpb25cbiAgICAgICAgICAgIC8vIGFuZCBza2lwIGF0dGVtcHQgdG8gZGVsZXRlIG9uIHRoZSBzZXJ2ZXIuXG4gICAgICAgICAgICBjbG9uZUNoZ1N0YXRlT25jZSgpO1xuICAgICAgICAgICAgZGVsZXRlIGNoZ1N0YXRlW2lkXTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRyYWNrZWRDaGFuZ2UuY2hhbmdlVHlwZSA9PT0gQ2hhbmdlVHlwZS5VcGRhdGVkKSB7XG4gICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2U6IHN3aXRjaCBjaGFuZ2UgdHlwZSBmcm9tIFVwZGF0ZWQgdG8gRGVsZXRlZC5cbiAgICAgICAgICAgIGNsb25lQ2hnU3RhdGVPbmNlKCk7XG4gICAgICAgICAgICB0cmFja2VkQ2hhbmdlLmNoYW5nZVR5cGUgPSBDaGFuZ2VUeXBlLkRlbGV0ZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFN0YXJ0IHRyYWNraW5nIHRoaXMgZW50aXR5XG4gICAgICAgICAgY2xvbmVDaGdTdGF0ZU9uY2UoKTtcbiAgICAgICAgICBjaGdTdGF0ZVtpZF0gPSB7IGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuRGVsZXRlZCwgb3JpZ2luYWxWYWx1ZSB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hnU3RhdGU7XG5cbiAgICAgIGZ1bmN0aW9uIGNsb25lQ2hnU3RhdGVPbmNlKCkge1xuICAgICAgICBpZiAoIWRpZE11dGF0ZSkge1xuICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKTtcblxuICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGFuIGVudGl0eSBiZWZvcmUgaXQgaXMgcmVtb3ZlZCB3aXRoIHRoZSBpbnRlbnRpb24gb2YgZGVsZXRpbmcgaXQgb24gdGhlIHNlcnZlci5cbiAgICogRG9lcyBOT1QgcmVtb3ZlIGZyb20gdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIGtleSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIGVudGl0eSB0byBkZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICovXG4gIHRyYWNrRGVsZXRlT25lKFxuICAgIGtleTogbnVtYmVyIHwgc3RyaW5nLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIGtleSA9PSBudWxsXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogdGhpcy50cmFja0RlbGV0ZU1hbnkoW2tleV0sIGNvbGxlY3Rpb24sIG1lcmdlU3RyYXRlZ3kpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIG11bHRpcGxlIGVudGl0aWVzIGJlZm9yZSB1cGRhdGluZyB0aGVtIGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBEb2VzIE5PVCB1cGRhdGUgdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIHVwZGF0ZXMgVGhlIGVudGl0aWVzIHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gVHJhY2sgYnkgZGVmYXVsdC4gRG9uJ3QgdHJhY2sgaWYgaXMgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzLlxuICAgKi9cbiAgdHJhY2tVcGRhdGVNYW55KFxuICAgIHVwZGF0ZXM6IFVwZGF0ZTxUPltdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKFxuICAgICAgbWVyZ2VTdHJhdGVneSA9PT0gTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzIHx8XG4gICAgICB1cGRhdGVzID09IG51bGwgfHxcbiAgICAgIHVwZGF0ZXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byB0cmFja1xuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgY29uc3QgZW50aXR5TWFwID0gY29sbGVjdGlvbi5lbnRpdGllcztcbiAgICBjb25zdCBjaGFuZ2VTdGF0ZSA9IHVwZGF0ZXMucmVkdWNlKChjaGdTdGF0ZSwgdXBkYXRlKSA9PiB7XG4gICAgICBjb25zdCB7IGlkLCBjaGFuZ2VzOiBlbnRpdHkgfSA9IHVwZGF0ZTtcbiAgICAgIGlmIChpZCA9PSBudWxsIHx8IGlkID09PSAnJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYCR7Y29sbGVjdGlvbi5lbnRpdHlOYW1lfSBlbnRpdHkgdXBkYXRlIHJlcXVpcmVzIGEga2V5IHRvIGJlIHRyYWNrZWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCBvcmlnaW5hbFZhbHVlID0gZW50aXR5TWFwW2lkXTtcbiAgICAgIC8vIE9ubHkgdHJhY2sgaWYgaXQgaXMgaW4gdGhlIGNvbGxlY3Rpb24uIFNpbGVudGx5IGlnbm9yZSBpZiBpdCBpcyBub3QuXG4gICAgICAvLyBAbmdyeC9lbnRpdHkgYWRhcHRlciB3b3VsZCBhbHNvIHNpbGVudGx5IGlnbm9yZS5cbiAgICAgIC8vIFRvZG86IHNob3VsZCBtaXNzaW5nIHVwZGF0ZSBlbnRpdHkgcmVhbGx5IGJlIHJlcG9ydGVkIGFzIGFuIGVycm9yP1xuICAgICAgaWYgKG9yaWdpbmFsVmFsdWUpIHtcbiAgICAgICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IGNoZ1N0YXRlW2lkXTtcbiAgICAgICAgaWYgKCF0cmFja2VkQ2hhbmdlKSB7XG4gICAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2hnU3RhdGVbaWRdID0geyBjaGFuZ2VUeXBlOiBDaGFuZ2VUeXBlLlVwZGF0ZWQsIG9yaWdpbmFsVmFsdWUgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGFuIGVudGl0eSBiZWZvcmUgdXBkYXRpbmcgaXQgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIERvZXMgTk9UIHVwZGF0ZSB0aGUgY29sbGVjdGlvbiAodGhlIHJlZHVjZXIncyBqb2IpLlxuICAgKiBAcGFyYW0gdXBkYXRlIFRoZSBlbnRpdHkgdG8gdXBkYXRlLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUcmFjayBieSBkZWZhdWx0LiBEb24ndCB0cmFjayBpZiBpcyBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMuXG4gICAqL1xuICB0cmFja1VwZGF0ZU9uZShcbiAgICB1cGRhdGU6IFVwZGF0ZTxUPixcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB1cGRhdGUgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMudHJhY2tVcGRhdGVNYW55KFt1cGRhdGVdLCBjb2xsZWN0aW9uLCBtZXJnZVN0cmF0ZWd5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBtdWx0aXBsZSBlbnRpdGllcyBiZWZvcmUgdXBzZXJ0aW5nIChhZGRpbmcgYW5kIHVwZGF0aW5nKSB0aGVtIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBEb2VzIE5PVCB1cGRhdGUgdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIGVudGl0aWVzIFRoZSBlbnRpdGllcyB0byBhZGQgb3IgdXBkYXRlLiBUaGV5IG11c3QgYmUgY29tcGxldGUgZW50aXRpZXMgd2l0aCBpZHMuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICovXG4gIHRyYWNrVXBzZXJ0TWFueShcbiAgICBlbnRpdGllczogVFtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKFxuICAgICAgbWVyZ2VTdHJhdGVneSA9PT0gTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzIHx8XG4gICAgICBlbnRpdGllcyA9PSBudWxsIHx8XG4gICAgICBlbnRpdGllcy5sZW5ndGggPT09IDBcbiAgICApIHtcbiAgICAgIHJldHVybiBjb2xsZWN0aW9uOyAvLyBub3RoaW5nIHRvIHRyYWNrXG4gICAgfVxuICAgIGxldCBkaWRNdXRhdGUgPSBmYWxzZTtcbiAgICBjb25zdCBlbnRpdHlNYXAgPSBjb2xsZWN0aW9uLmVudGl0aWVzO1xuICAgIGNvbnN0IGNoYW5nZVN0YXRlID0gZW50aXRpZXMucmVkdWNlKChjaGdTdGF0ZSwgZW50aXR5KSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMuc2VsZWN0SWQoZW50aXR5KTtcbiAgICAgIGlmIChpZCA9PSBudWxsIHx8IGlkID09PSAnJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYCR7Y29sbGVjdGlvbi5lbnRpdHlOYW1lfSBlbnRpdHkgdXBzZXJ0IHJlcXVpcmVzIGEga2V5IHRvIGJlIHRyYWNrZWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gY2hnU3RhdGVbaWRdO1xuXG4gICAgICBpZiAoIXRyYWNrZWRDaGFuZ2UpIHtcbiAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IGVudGl0eU1hcFtpZF07XG4gICAgICAgIGNoZ1N0YXRlW2lkXSA9XG4gICAgICAgICAgb3JpZ2luYWxWYWx1ZSA9PSBudWxsXG4gICAgICAgICAgICA/IHsgY2hhbmdlVHlwZTogQ2hhbmdlVHlwZS5BZGRlZCB9XG4gICAgICAgICAgICA6IHsgY2hhbmdlVHlwZTogQ2hhbmdlVHlwZS5VcGRhdGVkLCBvcmlnaW5hbFZhbHVlIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hnU3RhdGU7XG4gICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG4gICAgcmV0dXJuIGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYW4gZW50aXR5IGJlZm9yZSB1cHNlcnQgKGFkZGluZyBhbmQgdXBkYXRpbmcpIGl0IHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBEb2VzIE5PVCB1cGRhdGUgdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIGVudGl0aWVzIFRoZSBlbnRpdHkgdG8gYWRkIG9yIHVwZGF0ZS4gSXQgbXVzdCBiZSBhIGNvbXBsZXRlIGVudGl0eSB3aXRoIGl0cyBpZC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gVHJhY2sgYnkgZGVmYXVsdC4gRG9uJ3QgdHJhY2sgaWYgaXMgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzLlxuICAgKi9cbiAgdHJhY2tVcHNlcnRPbmUoXG4gICAgZW50aXR5OiBULFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIGVudGl0eSA9PSBudWxsXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogdGhpcy50cmFja1Vwc2VydE1hbnkoW2VudGl0eV0sIGNvbGxlY3Rpb24sIG1lcmdlU3RyYXRlZ3kpO1xuICB9XG4gIC8vICNlbmRyZWdpb24gdHJhY2sgbWV0aG9kc1xuXG4gIC8vICNyZWdpb24gdW5kbyBtZXRob2RzXG4gIC8qKlxuICAgKiBSZXZlcnQgdGhlIHVuc2F2ZWQgY2hhbmdlcyBmb3IgYWxsIGNvbGxlY3Rpb24uXG4gICAqIEhhcm1sZXNzIHdoZW4gdGhlcmUgYXJlIG5vIGVudGl0eSBjaGFuZ2VzIHRvIHVuZG8uXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKi9cbiAgdW5kb0FsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgaWRzID0gT2JqZWN0LmtleXMoY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG5cbiAgICBjb25zdCB7IHJlbW92ZSwgdXBzZXJ0IH0gPSBpZHMucmVkdWNlKFxuICAgICAgKGFjYywgaWQpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbmdlU3RhdGUgPSBhY2MuY2hnU3RhdGVbaWRdITtcbiAgICAgICAgc3dpdGNoIChjaGFuZ2VTdGF0ZS5jaGFuZ2VUeXBlKSB7XG4gICAgICAgICAgY2FzZSBDaGFuZ2VUeXBlLkFkZGVkOlxuICAgICAgICAgICAgYWNjLnJlbW92ZS5wdXNoKGlkKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgQ2hhbmdlVHlwZS5EZWxldGVkOlxuICAgICAgICAgICAgY29uc3QgcmVtb3ZlZCA9IGNoYW5nZVN0YXRlIS5vcmlnaW5hbFZhbHVlO1xuICAgICAgICAgICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgICAgICAgICAgYWNjLnVwc2VydC5wdXNoKHJlbW92ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBDaGFuZ2VUeXBlLlVwZGF0ZWQ6XG4gICAgICAgICAgICBhY2MudXBzZXJ0LnB1c2goY2hhbmdlU3RhdGUhLm9yaWdpbmFsVmFsdWUhKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgLy8gZW50aXRpZXNUb1VuZG9cbiAgICAgIHtcbiAgICAgICAgcmVtb3ZlOiBbXSBhcyAobnVtYmVyIHwgc3RyaW5nKVtdLFxuICAgICAgICB1cHNlcnQ6IFtdIGFzIFRbXSxcbiAgICAgICAgY2hnU3RhdGU6IGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUsXG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlTWFueShyZW1vdmUgYXMgc3RyaW5nW10sIGNvbGxlY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueSh1cHNlcnQsIGNvbGxlY3Rpb24pO1xuXG4gICAgcmV0dXJuIHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGU6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogUmV2ZXJ0IHRoZSB1bnNhdmVkIGNoYW5nZXMgZm9yIHRoZSBnaXZlbiBlbnRpdGllcy5cbiAgICogSGFybWxlc3Mgd2hlbiB0aGVyZSBhcmUgbm8gZW50aXR5IGNoYW5nZXMgdG8gdW5kby5cbiAgICogQHBhcmFtIGVudGl0eU9ySWRMaXN0IFRoZSBlbnRpdGllcyB0byByZXZlcnQgb3IgdGhlaXIgaWRzLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIHVuZG9NYW55KFxuICAgIGVudGl0eU9ySWRMaXN0OiAobnVtYmVyIHwgc3RyaW5nIHwgVClbXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmIChlbnRpdHlPcklkTGlzdCA9PSBudWxsIHx8IGVudGl0eU9ySWRMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247IC8vIG5vdGhpbmcgdG8gdW5kb1xuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG5cbiAgICBjb25zdCB7IGNoYW5nZVN0YXRlLCByZW1vdmUsIHVwc2VydCB9ID0gZW50aXR5T3JJZExpc3QucmVkdWNlKFxuICAgICAgKGFjYywgZW50aXR5T3JJZCkgPT4ge1xuICAgICAgICBsZXQgY2hnU3RhdGUgPSBhY2MuY2hhbmdlU3RhdGU7XG4gICAgICAgIGNvbnN0IGlkID1cbiAgICAgICAgICB0eXBlb2YgZW50aXR5T3JJZCA9PT0gJ29iamVjdCdcbiAgICAgICAgICAgID8gdGhpcy5zZWxlY3RJZChlbnRpdHlPcklkKVxuICAgICAgICAgICAgOiAoZW50aXR5T3JJZCBhcyBzdHJpbmcgfCBudW1iZXIpO1xuICAgICAgICBjb25zdCBjaGFuZ2UgPSBjaGdTdGF0ZVtpZF0hO1xuICAgICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVsZXRlIGNoZ1N0YXRlW2lkXTsgLy8gY2xlYXIgdHJhY2tpbmcgb2YgdGhpcyBlbnRpdHlcbiAgICAgICAgICBhY2MuY2hhbmdlU3RhdGUgPSBjaGdTdGF0ZTtcbiAgICAgICAgICBzd2l0Y2ggKGNoYW5nZS5jaGFuZ2VUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIENoYW5nZVR5cGUuQWRkZWQ6XG4gICAgICAgICAgICAgIGFjYy5yZW1vdmUucHVzaChpZCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBDaGFuZ2VUeXBlLkRlbGV0ZWQ6XG4gICAgICAgICAgICAgIGNvbnN0IHJlbW92ZWQgPSBjaGFuZ2UhLm9yaWdpbmFsVmFsdWU7XG4gICAgICAgICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgICAgICAgYWNjLnVwc2VydC5wdXNoKHJlbW92ZWQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBDaGFuZ2VUeXBlLlVwZGF0ZWQ6XG4gICAgICAgICAgICAgIGFjYy51cHNlcnQucHVzaChjaGFuZ2UhLm9yaWdpbmFsVmFsdWUhKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LFxuICAgICAgLy8gZW50aXRpZXNUb1VuZG9cbiAgICAgIHtcbiAgICAgICAgcmVtb3ZlOiBbXSBhcyAobnVtYmVyIHwgc3RyaW5nKVtdLFxuICAgICAgICB1cHNlcnQ6IFtdIGFzIFRbXSxcbiAgICAgICAgY2hhbmdlU3RhdGU6IGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUsXG4gICAgICB9XG4gICAgKTtcblxuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlTWFueShyZW1vdmUgYXMgc3RyaW5nW10sIGNvbGxlY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueSh1cHNlcnQsIGNvbGxlY3Rpb24pO1xuICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldmVydCB0aGUgdW5zYXZlZCBjaGFuZ2VzIGZvciB0aGUgZ2l2ZW4gZW50aXR5LlxuICAgKiBIYXJtbGVzcyB3aGVuIHRoZXJlIGFyZSBubyBlbnRpdHkgY2hhbmdlcyB0byB1bmRvLlxuICAgKiBAcGFyYW0gZW50aXR5T3JJZCBUaGUgZW50aXR5IHRvIHJldmVydCBvciBpdHMgaWQuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKi9cbiAgdW5kb09uZShcbiAgICBlbnRpdHlPcklkOiBudW1iZXIgfCBzdHJpbmcgfCBULFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIGVudGl0eU9ySWQgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMudW5kb01hbnkoW2VudGl0eU9ySWRdLCBjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHVuZG8gbWV0aG9kc1xufVxuIl19
575
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWNoYW5nZS10cmFja2VyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9tb2R1bGVzL2RhdGEvc3JjL3JlZHVjZXJzL2VudGl0eS1jaGFuZ2UtdHJhY2tlci1iYXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxVQUFVLEVBQW9CLE1BQU0scUJBQXFCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXJELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUcxRDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyx1QkFBdUI7SUFDbEMsWUFDVSxPQUF5QixFQUN6QixRQUF1QjtRQUR2QixZQUFPLEdBQVAsT0FBTyxDQUFrQjtRQUN6QixhQUFRLEdBQVIsUUFBUSxDQUFlO1FBRS9CLG9EQUFvRDtRQUNwRCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsSUFBSSxlQUFlLENBQUM7SUFDOUMsQ0FBQztJQUVELHlCQUF5QjtJQUN6Qjs7OztPQUlHO0lBQ0gsU0FBUyxDQUFDLFVBQStCO1FBQ3ZDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUM7WUFDckQsQ0FBQyxDQUFDLFVBQVU7WUFDWixDQUFDLGlDQUFNLFVBQVUsS0FBRSxXQUFXLEVBQUUsRUFBRSxHQUFFLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUNSLGNBQXVDLEVBQ3ZDLFVBQStCO1FBRS9CLElBQUksY0FBYyxJQUFJLElBQUksSUFBSSxjQUFjLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN6RCxPQUFPLFVBQVUsQ0FBQyxDQUFDLG9CQUFvQjtTQUN4QztRQUNELElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN0QixNQUFNLFdBQVcsR0FBRyxjQUFj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QixNQUFNLE9BQU8sR0FBRyxNQUFPLENBQUMsYUFBYSxDQUFDO3dCQUN0QyxJQUFJLE9BQU8sRUFBRTs0QkFDWCxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzt5QkFDMUI7d0JBQ0QsTUFBTTtvQkFDUixLQUFLLFVBQVUsQ0FBQyxPQUFPO3dCQUNyQixHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFPLENBQUMsYUFBYyxDQUFDLENBQUM7d0JBQ3hDLE1BQU07aUJBQ1Q7YUFDRjtZQUNELE9BQU8sR0FBRyxDQUFDO1FBQ2IsQ0FBQztRQUNELGlCQUFpQjtRQUNqQjtZQUNFLE1BQU0sRUFBRSxFQUF5QjtZQUNqQyxNQUFNLEVBQUUsRUFBUztZQUNqQixXQUFXLEVBQUUsVUFBVSxDQUFDLFdBQVc7U0FDcEMsQ0FDRixDQUFDO1FBRUYsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckUsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN6RCxPQUFPLFNBQVMsQ0FBQyxDQUFDLGlDQUFNLFVBQVUsS0FBRSxXQUFXLElBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQztJQUNqRSxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxPQUFPLENBQ0wsVUFBK0IsRUFDL0IsVUFBK0I7UUFFL0IsT0FBTyxVQUFVLElBQUksSUFBSTtZQUN2QixDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDOUMsQ0FBQztDQUVGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRW50aXR5QWRhcHRlciwgSWRTZWxlY3RvciwgVXBkYXRlIH0gZnJvbSAnQG5ncngvZW50aXR5JztcblxuaW1wb3J0IHsgQ2hhbmdlVHlwZSwgRW50aXR5Q29sbGVjdGlvbiB9IGZyb20gJy4vZW50aXR5LWNvbGxlY3Rpb24nO1xuaW1wb3J0IHsgZGVmYXVsdFNlbGVjdElkIH0gZnJvbSAnLi4vdXRpbHMvdXRpbGl0aWVzJztcbmltcG9ydCB7IEVudGl0eUNoYW5nZVRyYWNrZXIgfSBmcm9tICcuL2VudGl0eS1jaGFuZ2UtdHJhY2tlcic7XG5pbXBvcnQgeyBNZXJnZVN0cmF0ZWd5IH0gZnJvbSAnLi4vYWN0aW9ucy9tZXJnZS1zdHJhdGVneSc7XG5pbXBvcnQgeyBVcGRhdGVSZXNwb25zZURhdGEgfSBmcm9tICcuLi9hY3Rpb25zL3VwZGF0ZS1yZXNwb25zZS1kYXRhJztcblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZiBFbnRpdHlDaGFuZ2VUcmFja2VyIHdpdGhcbiAqIG1ldGhvZHMgZm9yIHRyYWNraW5nLCBjb21taXR0aW5nLCBhbmQgcmV2ZXJ0aW5nL3VuZG9pbmcgdW5zYXZlZCBlbnRpdHkgY2hhbmdlcy5cbiAqIFVzZWQgYnkgRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RzIHdoaWNoIHNob3VsZCBjYWxsIHRyYWNrZXIgbWV0aG9kcyBCRUZPUkUgbW9kaWZ5aW5nIHRoZSBjb2xsZWN0aW9uLlxuICogU2VlIEVudGl0eUNoYW5nZVRyYWNrZXIgZG9jcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudGl0eUNoYW5nZVRyYWNrZXJCYXNlPFQ+IGltcGxlbWVudHMgRW50aXR5Q2hhbmdlVHJhY2tlcjxUPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYWRhcHRlcjogRW50aXR5QWRhcHRlcjxUPixcbiAgICBwcml2YXRlIHNlbGVjdElkOiBJZFNlbGVjdG9yPFQ+XG4gICkge1xuICAgIC8qKiBFeHRyYWN0IHRoZSBwcmltYXJ5IGtleSAoaWQpOyBkZWZhdWx0IHRvIGBpZGAgKi9cbiAgICB0aGlzLnNlbGVjdElkID0gc2VsZWN0SWQgfHwgZGVmYXVsdFNlbGVjdElkO1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBjb21taXQgbWV0aG9kc1xuICAvKipcbiAgICogQ29tbWl0IGFsbCBjaGFuZ2VzIGFzIHdoZW4gdGhlIGNvbGxlY3Rpb24gaGFzIGJlZW4gY29tcGxldGVseSByZWxvYWRlZCBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIEhhcm1sZXNzIHdoZW4gdGhlcmUgYXJlIG5vIGVudGl0eSBjaGFuZ2VzIHRvIGNvbW1pdC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqL1xuICBjb21taXRBbGwoY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPik6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKS5sZW5ndGggPT09IDBcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbW1pdCBjaGFuZ2VzIGZvciB0aGUgZ2l2ZW4gZW50aXRpZXMgYXMgd2hlbiB0aGV5IGhhdmUgYmVlbiByZWZyZXNoZWQgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBIYXJtbGVzcyB3aGVuIHRoZXJlIGFyZSBubyBlbnRpdHkgY2hhbmdlcyB0byBjb21taXQuXG4gICAqIEBwYXJhbSBlbnRpdHlPcklkTGlzdCBUaGUgZW50aXRpZXMgdG8gY2xlYXIgdHJhY2tpbmcgb3IgdGhlaXIgaWRzLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIGNvbW1pdE1hbnkoXG4gICAgZW50aXR5T3JJZExpc3Q6IChudW1iZXIgfCBzdHJpbmcgfCBUKVtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKGVudGl0eU9ySWRMaXN0ID09IG51bGwgfHwgZW50aXR5T3JJZExpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byBjb21taXRcbiAgICB9XG4gICAgbGV0IGRpZE11dGF0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGNoYW5nZVN0YXRlID0gZW50aXR5T3JJZExpc3QucmVkdWNlKChjaGdTdGF0ZSwgZW50aXR5T3JJZCkgPT4ge1xuICAgICAgY29uc3QgaWQgPVxuICAgICAgICB0eXBlb2YgZW50aXR5T3JJZCA9PT0gJ29iamVjdCdcbiAgICAgICAgICA/IHRoaXMuc2VsZWN0SWQoZW50aXR5T3JJZClcbiAgICAgICAgICA6IChlbnRpdHlPcklkIGFzIHN0cmluZyB8IG51bWJlcik7XG4gICAgICBpZiAoY2hnU3RhdGVbaWRdKSB7XG4gICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgY2hnU3RhdGVbaWRdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuXG4gICAgcmV0dXJuIGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogQ29tbWl0IGNoYW5nZXMgZm9yIHRoZSBnaXZlbiBlbnRpdHkgYXMgd2hlbiBpdCBoYXZlIGJlZW4gcmVmcmVzaGVkIGZyb20gdGhlIHNlcnZlci5cbiAgICogSGFybWxlc3Mgd2hlbiBubyBlbnRpdHkgY2hhbmdlcyB0byBjb21taXQuXG4gICAqIEBwYXJhbSBlbnRpdHlPcklkIFRoZSBlbnRpdHkgdG8gY2xlYXIgdHJhY2tpbmcgb3IgaXRzIGlkLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIGNvbW1pdE9uZShcbiAgICBlbnRpdHlPcklkOiBudW1iZXIgfCBzdHJpbmcgfCBULFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIGVudGl0eU9ySWQgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMuY29tbWl0TWFueShbZW50aXR5T3JJZF0sIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvbiBjb21taXQgbWV0aG9kc1xuXG4gIC8vICNyZWdpb24gbWVyZ2UgcXVlcnlcbiAgLyoqXG4gICAqIE1lcmdlIHF1ZXJ5IHJlc3VsdHMgaW50byB0aGUgY29sbGVjdGlvbiwgYWRqdXN0aW5nIHRoZSBDaGFuZ2VTdGF0ZSBwZXIgdGhlIG1lcmdlU3RyYXRlZ3kuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBFbnRpdGllcyByZXR1cm5lZCBmcm9tIHF1ZXJ5aW5nIHRoZSBzZXJ2ZXIuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIEhvdyB0byBtZXJnZSBhIHF1ZXJpZWQgZW50aXR5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGhhcyBhbiB1bnNhdmVkIGNoYW5nZS5cbiAgICogRGVmYXVsdHMgdG8gTWVyZ2VTdHJhdGVneS5QcmVzZXJ2ZUNoYW5nZXMuXG4gICAqIEByZXR1cm5zIFRoZSBtZXJnZWQgRW50aXR5Q29sbGVjdGlvbi5cbiAgICovXG4gIG1lcmdlUXVlcnlSZXN1bHRzKFxuICAgIGVudGl0aWVzOiBUW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5tZXJnZVNlcnZlclVwc2VydHMoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlcyxcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICB9XG4gIC8vICNlbmRyZWdpb24gbWVyZ2UgcXVlcnkgcmVzdWx0c1xuXG4gIC8vICNyZWdpb24gbWVyZ2Ugc2F2ZSByZXN1bHRzXG4gIC8qKlxuICAgKiBNZXJnZSByZXN1bHQgb2Ygc2F2aW5nIG5ldyBlbnRpdGllcyBpbnRvIHRoZSBjb2xsZWN0aW9uLCBhZGp1c3RpbmcgdGhlIENoYW5nZVN0YXRlIHBlciB0aGUgbWVyZ2VTdHJhdGVneS5cbiAgICogVGhlIGRlZmF1bHQgaXMgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcGFyYW0gZW50aXRpZXMgRW50aXRpZXMgcmV0dXJuZWQgZnJvbSBzYXZpbmcgbmV3IGVudGl0aWVzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIEhvdyB0byBtZXJnZSBhIHNhdmVkIGVudGl0eSB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiBoYXMgYW4gdW5zYXZlZCBjaGFuZ2UuXG4gICAqIERlZmF1bHRzIHRvIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcy5cbiAgICogQHJldHVybnMgVGhlIG1lcmdlZCBFbnRpdHlDb2xsZWN0aW9uLlxuICAgKi9cbiAgbWVyZ2VTYXZlQWRkcyhcbiAgICBlbnRpdGllczogVFtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMubWVyZ2VTZXJ2ZXJVcHNlcnRzKFxuICAgICAgZW50aXRpZXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2Ugc3VjY2Vzc2Z1bCByZXN1bHQgb2YgZGVsZXRpbmcgZW50aXRpZXMgb24gdGhlIHNlcnZlciB0aGF0IGhhdmUgdGhlIGdpdmVuIHByaW1hcnkga2V5c1xuICAgKiBDbGVhcnMgdGhlIGVudGl0eSBjaGFuZ2VTdGF0ZSBmb3IgdGhvc2Uga2V5cyB1bmxlc3MgdGhlIE1lcmdlU3RyYXRlZ3kgaXMgaWdub3JlQ2hhbmdlcy5cbiAgICogQHBhcmFtIGVudGl0aWVzIGtleXMgcHJpbWFyeSBrZXlzIG9mIHRoZSBlbnRpdGllcyB0byByZW1vdmUvZGVsZXRlLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBIb3cgdG8gYWRqdXN0IGNoYW5nZSB0cmFja2luZyB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiBoYXMgYW4gdW5zYXZlZCBjaGFuZ2UuXG4gICAqIERlZmF1bHRzIHRvIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcy5cbiAgICogQHJldHVybnMgVGhlIG1lcmdlZCBFbnRpdHlDb2xsZWN0aW9uLlxuICAgKi9cbiAgbWVyZ2VTYXZlRGVsZXRlcyhcbiAgICBrZXlzOiAobnVtYmVyIHwgc3RyaW5nKVtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgbWVyZ2VTdHJhdGVneSA9XG4gICAgICBtZXJnZVN0cmF0ZWd5ID09IG51bGwgPyBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMgOiBtZXJnZVN0cmF0ZWd5O1xuICAgIC8vIHNhbWUgbG9naWMgZm9yIGFsbCBub24taWdub3JlIG1lcmdlIHN0cmF0ZWdpZXM6IGFsd2F5cyBjbGVhciAoY29tbWl0KSB0aGUgY2hhbmdlc1xuICAgIGNvbnN0IGRlbGV0ZUlkcyA9IGtleXMgYXMgc3RyaW5nW107IC8vIG1ha2UgVHlwZVNjcmlwdCBoYXBweVxuICAgIGNvbGxlY3Rpb24gPVxuICAgICAgbWVyZ2VTdHJhdGVneSA9PT0gTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzXG4gICAgICAgID8gY29sbGVjdGlvblxuICAgICAgICA6IHRoaXMuY29tbWl0TWFueShkZWxldGVJZHMsIGNvbGxlY3Rpb24pO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmVtb3ZlTWFueShkZWxldGVJZHMsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1lcmdlIHJlc3VsdCBvZiBzYXZpbmcgdXBkYXRlZCBlbnRpdGllcyBpbnRvIHRoZSBjb2xsZWN0aW9uLCBhZGp1c3RpbmcgdGhlIENoYW5nZVN0YXRlIHBlciB0aGUgbWVyZ2VTdHJhdGVneS5cbiAgICogVGhlIGRlZmF1bHQgaXMgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcGFyYW0gdXBkYXRlUmVzcG9uc2VEYXRhIEVudGl0eSByZXNwb25zZSBkYXRhIHJldHVybmVkIGZyb20gc2F2aW5nIHVwZGF0ZWQgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gSG93IHRvIG1lcmdlIGEgc2F2ZWQgZW50aXR5IHdoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIGhhcyBhbiB1bnNhdmVkIGNoYW5nZS5cbiAgICogRGVmYXVsdHMgdG8gTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLlxuICAgKiBAcGFyYW0gW3NraXBVbmNoYW5nZWRdIFRydWUgbWVhbnMgc2tpcCB1cGRhdGUgaWYgc2VydmVyIGRpZG4ndCBjaGFuZ2UgaXQuIEZhbHNlIGJ5IGRlZmF1bHQuXG4gICAqIElmIHRoZSB1cGRhdGUgd2FzIG9wdGltaXN0aWMgYW5kIHRoZSBzZXJ2ZXIgZGlkbid0IG1ha2UgbW9yZSBjaGFuZ2VzIG9mIGl0cyBvd25cbiAgICogdGhlbiB0aGUgdXBkYXRlcyBhcmUgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbiBhbmQgc2hvdWxkbid0IG1ha2UgdGhlbSBhZ2Fpbi5cbiAgICogQHJldHVybnMgVGhlIG1lcmdlZCBFbnRpdHlDb2xsZWN0aW9uLlxuICAgKi9cbiAgbWVyZ2VTYXZlVXBkYXRlcyhcbiAgICB1cGRhdGVSZXNwb25zZURhdGE6IFVwZGF0ZVJlc3BvbnNlRGF0YTxUPltdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3ksXG4gICAgc2tpcFVuY2hhbmdlZCA9IGZhbHNlXG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh1cGRhdGVSZXNwb25zZURhdGEgPT0gbnVsbCB8fCB1cGRhdGVSZXNwb25zZURhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byBtZXJnZS5cbiAgICB9XG5cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgbGV0IGNoYW5nZVN0YXRlID0gY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZTtcbiAgICBtZXJnZVN0cmF0ZWd5ID1cbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT0gbnVsbCA/IE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcyA6IG1lcmdlU3RyYXRlZ3k7XG4gICAgbGV0IHVwZGF0ZXM6IFVwZGF0ZTxUPltdO1xuXG4gICAgc3dpdGNoIChtZXJnZVN0cmF0ZWd5KSB7XG4gICAgICBjYXNlIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlczpcbiAgICAgICAgdXBkYXRlcyA9IGZpbHRlckNoYW5nZWQodXBkYXRlUmVzcG9uc2VEYXRhKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cGRhdGVNYW55KHVwZGF0ZXMsIGNvbGxlY3Rpb24pO1xuXG4gICAgICBjYXNlIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlczpcbiAgICAgICAgY2hhbmdlU3RhdGUgPSB1cGRhdGVSZXNwb25zZURhdGEucmVkdWNlKChjaGdTdGF0ZSwgdXBkYXRlKSA9PiB7XG4gICAgICAgICAgY29uc3Qgb2xkSWQgPSB1cGRhdGUuaWQ7XG4gICAgICAgICAgY29uc3QgY2hhbmdlID0gY2hnU3RhdGVbb2xkSWRdO1xuICAgICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGNoZ1N0YXRlW29sZElkXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgICAgICB9LCBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKTtcblxuICAgICAgICBjb2xsZWN0aW9uID0gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcblxuICAgICAgICB1cGRhdGVzID0gZmlsdGVyQ2hhbmdlZCh1cGRhdGVSZXNwb25zZURhdGEpO1xuICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU1hbnkodXBkYXRlcywgY29sbGVjdGlvbik7XG5cbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5QcmVzZXJ2ZUNoYW5nZXM6IHtcbiAgICAgICAgY29uc3QgdXBkYXRlYWJsZUVudGl0aWVzID0gW10gYXMgVXBkYXRlUmVzcG9uc2VEYXRhPFQ+W107XG4gICAgICAgIGNoYW5nZVN0YXRlID0gdXBkYXRlUmVzcG9uc2VEYXRhLnJlZHVjZSgoY2hnU3RhdGUsIHVwZGF0ZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG9sZElkID0gdXBkYXRlLmlkO1xuICAgICAgICAgIGNvbnN0IGNoYW5nZSA9IGNoZ1N0YXRlW29sZElkXTtcbiAgICAgICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgICAgICAvLyBUcmFja2luZyBhIGNoYW5nZSBzbyB1cGRhdGUgb3JpZ2luYWwgdmFsdWUgYnV0IG5vdCB0aGUgY3VycmVudCB2YWx1ZVxuICAgICAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuZXdJZCA9IHRoaXMuc2VsZWN0SWQodXBkYXRlLmNoYW5nZXMgYXMgVCk7XG4gICAgICAgICAgICBjb25zdCBvbGRDaGFuZ2VTdGF0ZSA9IGNoYW5nZTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBzZXJ2ZXIgY2hhbmdlZCB0aGUgaWQsIHJlZ2lzdGVyIHRoZSBuZXcgXCJvcmlnaW5hbFZhbHVlXCIgdW5kZXIgdGhlIG5ldyBpZFxuICAgICAgICAgICAgLy8gYW5kIHJlbW92ZSB0aGUgY2hhbmdlIHRyYWNrZWQgdW5kZXIgdGhlIG9sZCBpZC5cbiAgICAgICAgICAgIGlmIChuZXdJZCAhPT0gb2xkSWQpIHtcbiAgICAgICAgICAgICAgZGVsZXRlIGNoZ1N0YXRlW29sZElkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5ld09yaWdWYWx1ZSA9IHtcbiAgICAgICAgICAgICAgLi4uKG9sZENoYW5nZVN0YXRlIS5vcmlnaW5hbFZhbHVlIGFzIGFueSksXG4gICAgICAgICAgICAgIC4uLih1cGRhdGUuY2hhbmdlcyBhcyBhbnkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIChjaGdTdGF0ZSBhcyBhbnkpW25ld0lkXSA9IHtcbiAgICAgICAgICAgICAgLi4ub2xkQ2hhbmdlU3RhdGUsXG4gICAgICAgICAgICAgIG9yaWdpbmFsVmFsdWU6IG5ld09yaWdWYWx1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVwZGF0ZWFibGVFbnRpdGllcy5wdXNoKHVwZGF0ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBjaGdTdGF0ZTtcbiAgICAgICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG4gICAgICAgIGNvbGxlY3Rpb24gPSBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuXG4gICAgICAgIHVwZGF0ZXMgPSBmaWx0ZXJDaGFuZ2VkKHVwZGF0ZWFibGVFbnRpdGllcyk7XG4gICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlTWFueSh1cGRhdGVzLCBjb2xsZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb25kaXRpb25hbGx5IGtlZXAgb25seSB0aG9zZSB1cGRhdGVzIHRoYXQgaGF2ZSBhZGRpdGlvbmFsIHNlcnZlciBjaGFuZ2VzLlxuICAgICAqIChlLmcuLCBmb3Igb3B0aW1pc3RpYyBzYXZlcyBiZWNhdXNlIHRoZXkgdXBkYXRlcyBhcmUgYWxyZWFkeSBpbiB0aGUgY3VycmVudCBjb2xsZWN0aW9uKVxuICAgICAqIFN0cmlwIG9mZiB0aGUgYGNoYW5nZWRgIHByb3BlcnR5LlxuICAgICAqIEByZXNwb25zZURhdGEgRW50aXR5IHJlc3BvbnNlIGRhdGEgZnJvbSBzZXJ2ZXIuXG4gICAgICogTWF5IGJlIGFuIFVwZGF0ZVJlc3BvbnNlRGF0YTxUPiwgYSBzdWJjbGFzcyBvZiBVcGRhdGU8VD4gd2l0aCBhICdjaGFuZ2VkJyBmbGFnLlxuICAgICAqIEByZXR1cm5zIFVwZGF0ZTxUPiAod2l0aG91dCB0aGUgY2hhbmdlZCBmbGFnKVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGZpbHRlckNoYW5nZWQocmVzcG9uc2VEYXRhOiBVcGRhdGVSZXNwb25zZURhdGE8VD5bXSk6IFVwZGF0ZTxUPltdIHtcbiAgICAgIGlmIChza2lwVW5jaGFuZ2VkID09PSB0cnVlKSB7XG4gICAgICAgIC8vIGtlZXAgb25seSB0aG9zZSB1cGRhdGVzIHRoYXQgdGhlIHNlcnZlciBjaGFuZ2VkIChrbm93YWJsZSBpZiBpcyBVcGRhdGVSZXNwb25zZURhdGE8VD4pXG4gICAgICAgIHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlRGF0YS5maWx0ZXIoKHIpID0+IHIuY2hhbmdlZCA9PT0gdHJ1ZSk7XG4gICAgICB9XG4gICAgICAvLyBTdHJpcCB1bmNoYW5nZWQgcHJvcGVydHkgZnJvbSByZXNwb25zZURhdGEsIGxlYXZpbmcganVzdCB0aGUgcHVyZSBVcGRhdGU8VD5cbiAgICAgIC8vIFRPRE86IFJlbW92ZT8gcHJvYmFibHkgbm90IG5lY2Vzc2FyeSBhcyB0aGUgVXBkYXRlIGlzbid0IHN0b3JlZCBhbmQgYWRhcHRlciB3aWxsIGlnbm9yZSBgY2hhbmdlZGAuXG4gICAgICByZXR1cm4gcmVzcG9uc2VEYXRhLm1hcCgocikgPT4gKHsgaWQ6IHIuaWQgYXMgYW55LCBjaGFuZ2VzOiByLmNoYW5nZXMgfSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZSByZXN1bHQgb2Ygc2F2aW5nIHVwc2VydGVkIGVudGl0aWVzIGludG8gdGhlIGNvbGxlY3Rpb24sIGFkanVzdGluZyB0aGUgQ2hhbmdlU3RhdGUgcGVyIHRoZSBtZXJnZVN0cmF0ZWd5LlxuICAgKiBUaGUgZGVmYXVsdCBpcyBNZXJnZVN0cmF0ZWd5Lk92ZXJ3cml0ZUNoYW5nZXMuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBFbnRpdGllcyByZXR1cm5lZCBmcm9tIHNhdmluZyB1cHNlcnRzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIEhvdyB0byBtZXJnZSBhIHNhdmVkIGVudGl0eSB3aGVuIHRoZSBjb3JyZXNwb25kaW5nIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiBoYXMgYW4gdW5zYXZlZCBjaGFuZ2UuXG4gICAqIERlZmF1bHRzIHRvIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlcy5cbiAgICogQHJldHVybnMgVGhlIG1lcmdlZCBFbnRpdHlDb2xsZWN0aW9uLlxuICAgKi9cbiAgbWVyZ2VTYXZlVXBzZXJ0cyhcbiAgICBlbnRpdGllczogVFtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMubWVyZ2VTZXJ2ZXJVcHNlcnRzKFxuICAgICAgZW50aXRpZXMsXG4gICAgICBjb2xsZWN0aW9uLFxuICAgICAgTWVyZ2VTdHJhdGVneS5PdmVyd3JpdGVDaGFuZ2VzLFxuICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICk7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBtZXJnZSBzYXZlIHJlc3VsdHNcblxuICAvLyAjcmVnaW9uIHF1ZXJ5ICYgc2F2ZSBoZWxwZXJzXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gZW50aXRpZXMgRW50aXRpZXMgdG8gbWVyZ2VcbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gQ29sbGVjdGlvbiBpbnRvIHdoaWNoIGVudGl0aWVzIGFyZSBtZXJnZWRcbiAgICogQHBhcmFtIGRlZmF1bHRNZXJnZVN0cmF0ZWd5IEhvdyB0byBtZXJnZSB3aGVuIGFjdGlvbidzIE1lcmdlU3RyYXRlZ3kgaXMgdW5zcGVjaWZpZWRcbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUaGUgYWN0aW9uJ3MgTWVyZ2VTdHJhdGVneVxuICAgKi9cbiAgcHJpdmF0ZSBtZXJnZVNlcnZlclVwc2VydHMoXG4gICAgZW50aXRpZXM6IFRbXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGRlZmF1bHRNZXJnZVN0cmF0ZWd5OiBNZXJnZVN0cmF0ZWd5LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmIChlbnRpdGllcyA9PSBudWxsIHx8IGVudGl0aWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247IC8vIG5vdGhpbmcgdG8gbWVyZ2UuXG4gICAgfVxuXG4gICAgbGV0IGRpZE11dGF0ZSA9IGZhbHNlO1xuICAgIGxldCBjaGFuZ2VTdGF0ZSA9IGNvbGxlY3Rpb24uY2hhbmdlU3RhdGU7XG4gICAgbWVyZ2VTdHJhdGVneSA9XG4gICAgICBtZXJnZVN0cmF0ZWd5ID09IG51bGwgPyBkZWZhdWx0TWVyZ2VTdHJhdGVneSA6IG1lcmdlU3RyYXRlZ3k7XG5cbiAgICBzd2l0Y2ggKG1lcmdlU3RyYXRlZ3kpIHtcbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzOlxuICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuXG4gICAgICBjYXNlIE1lcmdlU3RyYXRlZ3kuT3ZlcndyaXRlQ2hhbmdlczpcbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cHNlcnRNYW55KGVudGl0aWVzLCBjb2xsZWN0aW9uKTtcblxuICAgICAgICBjaGFuZ2VTdGF0ZSA9IGVudGl0aWVzLnJlZHVjZSgoY2hnU3RhdGUsIGVudGl0eSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5zZWxlY3RJZChlbnRpdHkpO1xuICAgICAgICAgIGNvbnN0IGNoYW5nZSA9IGNoZ1N0YXRlW2lkXTtcbiAgICAgICAgICBpZiAoY2hhbmdlKSB7XG4gICAgICAgICAgICBpZiAoIWRpZE11dGF0ZSkge1xuICAgICAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBjaGdTdGF0ZVtpZF07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBjaGdTdGF0ZTtcbiAgICAgICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIGRpZE11dGF0ZSA/IHsgLi4uY29sbGVjdGlvbiwgY2hhbmdlU3RhdGUgfSA6IGNvbGxlY3Rpb247XG5cbiAgICAgIGNhc2UgTWVyZ2VTdHJhdGVneS5QcmVzZXJ2ZUNoYW5nZXM6IHtcbiAgICAgICAgY29uc3QgdXBzZXJ0RW50aXRpZXMgPSBbXSBhcyBUW107XG4gICAgICAgIGNoYW5nZVN0YXRlID0gZW50aXRpZXMucmVkdWNlKChjaGdTdGF0ZSwgZW50aXR5KSA9PiB7XG4gICAgICAgICAgY29uc3QgaWQgPSB0aGlzLnNlbGVjdElkKGVudGl0eSk7XG4gICAgICAgICAgY29uc3QgY2hhbmdlID0gY2hnU3RhdGVbaWRdO1xuICAgICAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgICAgIGNoZ1N0YXRlID0ge1xuICAgICAgICAgICAgICAgIC4uLmNoZ1N0YXRlLFxuICAgICAgICAgICAgICAgIFtpZF06IHtcbiAgICAgICAgICAgICAgICAgIC4uLmNoZ1N0YXRlW2lkXSEsXG4gICAgICAgICAgICAgICAgICBvcmlnaW5hbFZhbHVlOiBlbnRpdHksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXBzZXJ0RW50aXRpZXMucHVzaChlbnRpdHkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gY2hnU3RhdGU7XG4gICAgICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuXG4gICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueSh1cHNlcnRFbnRpdGllcywgY29sbGVjdGlvbik7XG4gICAgICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyAjZW5kcmVnaW9uIHF1ZXJ5ICYgc2F2ZSBoZWxwZXJzXG5cbiAgLy8gI3JlZ2lvbiB0cmFjayBtZXRob2RzXG4gIC8qKlxuICAgKiBUcmFjayBtdWx0aXBsZSBlbnRpdGllcyBiZWZvcmUgYWRkaW5nIHRoZW0gdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIERvZXMgTk9UIGFkZCB0byB0aGUgY29sbGVjdGlvbiAodGhlIHJlZHVjZXIncyBqb2IpLlxuICAgKiBAcGFyYW0gZW50aXRpZXMgVGhlIGVudGl0aWVzIHRvIGFkZC4gVGhleSBtdXN0IGFsbCBoYXZlIHRoZWlyIGlkcy5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gVHJhY2sgYnkgZGVmYXVsdC4gRG9uJ3QgdHJhY2sgaWYgaXMgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzLlxuICAgKi9cbiAgdHJhY2tBZGRNYW55KFxuICAgIGVudGl0aWVzOiBUW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAoXG4gICAgICBtZXJnZVN0cmF0ZWd5ID09PSBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMgfHxcbiAgICAgIGVudGl0aWVzID09IG51bGwgfHxcbiAgICAgIGVudGl0aWVzLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247IC8vIG5vdGhpbmcgdG8gdHJhY2tcbiAgICB9XG4gICAgbGV0IGRpZE11dGF0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGNoYW5nZVN0YXRlID0gZW50aXRpZXMucmVkdWNlKChjaGdTdGF0ZSwgZW50aXR5KSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMuc2VsZWN0SWQoZW50aXR5KTtcbiAgICAgIGlmIChpZCA9PSBudWxsIHx8IGlkID09PSAnJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYCR7Y29sbGVjdGlvbi5lbnRpdHlOYW1lfSBlbnRpdHkgYWRkIHJlcXVpcmVzIGEga2V5IHRvIGJlIHRyYWNrZWRgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCB0cmFja2VkQ2hhbmdlID0gY2hnU3RhdGVbaWRdO1xuXG4gICAgICBpZiAoIXRyYWNrZWRDaGFuZ2UpIHtcbiAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICB9XG4gICAgICAgIGNoZ1N0YXRlW2lkXSA9IHsgY2hhbmdlVHlwZTogQ2hhbmdlVHlwZS5BZGRlZCB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGFuIGVudGl0eSBiZWZvcmUgYWRkaW5nIGl0IHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBEb2VzIE5PVCBhZGQgdG8gdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIGVudGl0eSBUaGUgZW50aXR5IHRvIGFkZC4gSXQgbXVzdCBoYXZlIGFuIGlkLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUcmFjayBieSBkZWZhdWx0LiBEb24ndCB0cmFjayBpZiBpcyBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMuXG4gICAqIElmIG5vdCBzcGVjaWZpZWQsIGltcGxlbWVudGF0aW9uIHN1cHBsaWVzIGEgZGVmYXVsdCBzdHJhdGVneS5cbiAgICovXG4gIHRyYWNrQWRkT25lKFxuICAgIGVudGl0eTogVCxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiBlbnRpdHkgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMudHJhY2tBZGRNYW55KFtlbnRpdHldLCBjb2xsZWN0aW9uLCBtZXJnZVN0cmF0ZWd5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBtdWx0aXBsZSBlbnRpdGllcyBiZWZvcmUgcmVtb3ZpbmcgdGhlbSB3aXRoIHRoZSBpbnRlbnRpb24gb2YgZGVsZXRpbmcgdGhlbSBvbiB0aGUgc2VydmVyLlxuICAgKiBEb2VzIE5PVCByZW1vdmUgZnJvbSB0aGUgY29sbGVjdGlvbiAodGhlIHJlZHVjZXIncyBqb2IpLlxuICAgKiBAcGFyYW0ga2V5cyBUaGUgcHJpbWFyeSBrZXlzIG9mIHRoZSBlbnRpdGllcyB0byBkZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICovXG4gIHRyYWNrRGVsZXRlTWFueShcbiAgICBrZXlzOiAobnVtYmVyIHwgc3RyaW5nKVtdLFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgbWVyZ2VTdHJhdGVneT86IE1lcmdlU3RyYXRlZ3lcbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKFxuICAgICAgbWVyZ2VTdHJhdGVneSA9PT0gTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzIHx8XG4gICAgICBrZXlzID09IG51bGwgfHxcbiAgICAgIGtleXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byB0cmFja1xuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgY29uc3QgZW50aXR5TWFwID0gY29sbGVjdGlvbi5lbnRpdGllcztcbiAgICBjb25zdCBjaGFuZ2VTdGF0ZSA9IGtleXMucmVkdWNlKChjaGdTdGF0ZSwgaWQpID0+IHtcbiAgICAgIGNvbnN0IG9yaWdpbmFsVmFsdWUgPSBlbnRpdHlNYXBbaWRdO1xuICAgICAgaWYgKG9yaWdpbmFsVmFsdWUpIHtcbiAgICAgICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IGNoZ1N0YXRlW2lkXTtcbiAgICAgICAgaWYgKHRyYWNrZWRDaGFuZ2UpIHtcbiAgICAgICAgICBpZiAodHJhY2tlZENoYW5nZS5jaGFuZ2VUeXBlID09PSBDaGFuZ2VUeXBlLkFkZGVkKSB7XG4gICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2U6IHN0b3AgdHJhY2tpbmcgYW4gYWRkZWQgZW50aXR5IHRoYXQgeW91IGRlbGV0ZVxuICAgICAgICAgICAgLy8gVGhlIGNhbGxlciBtdXN0IGFsc28gZGV0ZWN0IHRoaXMsIHJlbW92ZSBpdCBpbW1lZGlhdGVseSBmcm9tIHRoZSBjb2xsZWN0aW9uXG4gICAgICAgICAgICAvLyBhbmQgc2tpcCBhdHRlbXB0IHRvIGRlbGV0ZSBvbiB0aGUgc2VydmVyLlxuICAgICAgICAgICAgY2xvbmVDaGdTdGF0ZU9uY2UoKTtcbiAgICAgICAgICAgIGRlbGV0ZSBjaGdTdGF0ZVtpZF07XG4gICAgICAgICAgfSBlbHNlIGlmICh0cmFja2VkQ2hhbmdlLmNoYW5nZVR5cGUgPT09IENoYW5nZVR5cGUuVXBkYXRlZCkge1xuICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlOiBzd2l0Y2ggY2hhbmdlIHR5cGUgZnJvbSBVcGRhdGVkIHRvIERlbGV0ZWQuXG4gICAgICAgICAgICBjbG9uZUNoZ1N0YXRlT25jZSgpO1xuICAgICAgICAgICAgdHJhY2tlZENoYW5nZS5jaGFuZ2VUeXBlID0gQ2hhbmdlVHlwZS5EZWxldGVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBTdGFydCB0cmFja2luZyB0aGlzIGVudGl0eVxuICAgICAgICAgIGNsb25lQ2hnU3RhdGVPbmNlKCk7XG4gICAgICAgICAgY2hnU3RhdGVbaWRdID0geyBjaGFuZ2VUeXBlOiBDaGFuZ2VUeXBlLkRlbGV0ZWQsIG9yaWdpbmFsVmFsdWUgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuXG4gICAgICBmdW5jdGlvbiBjbG9uZUNoZ1N0YXRlT25jZSgpIHtcbiAgICAgICAgaWYgKCFkaWRNdXRhdGUpIHtcbiAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgIGNoZ1N0YXRlID0geyAuLi5jaGdTdGF0ZSB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSwgY29sbGVjdGlvbi5jaGFuZ2VTdGF0ZSk7XG5cbiAgICByZXR1cm4gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBhbiBlbnRpdHkgYmVmb3JlIGl0IGlzIHJlbW92ZWQgd2l0aCB0aGUgaW50ZW50aW9uIG9mIGRlbGV0aW5nIGl0IG9uIHRoZSBzZXJ2ZXIuXG4gICAqIERvZXMgTk9UIHJlbW92ZSBmcm9tIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSBrZXkgVGhlIHByaW1hcnkga2V5IG9mIHRoZSBlbnRpdHkgdG8gZGVsZXRlLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUcmFjayBieSBkZWZhdWx0LiBEb24ndCB0cmFjayBpZiBpcyBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMuXG4gICAqL1xuICB0cmFja0RlbGV0ZU9uZShcbiAgICBrZXk6IG51bWJlciB8IHN0cmluZyxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiBrZXkgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMudHJhY2tEZWxldGVNYW55KFtrZXldLCBjb2xsZWN0aW9uLCBtZXJnZVN0cmF0ZWd5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBtdWx0aXBsZSBlbnRpdGllcyBiZWZvcmUgdXBkYXRpbmcgdGhlbSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogRG9lcyBOT1QgdXBkYXRlIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSB1cGRhdGVzIFRoZSBlbnRpdGllcyB0byB1cGRhdGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICovXG4gIHRyYWNrVXBkYXRlTWFueShcbiAgICB1cGRhdGVzOiBVcGRhdGU8VD5bXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmIChcbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT09IE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcyB8fFxuICAgICAgdXBkYXRlcyA9PSBudWxsIHx8XG4gICAgICB1cGRhdGVzLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247IC8vIG5vdGhpbmcgdG8gdHJhY2tcbiAgICB9XG4gICAgbGV0IGRpZE11dGF0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGVudGl0eU1hcCA9IGNvbGxlY3Rpb24uZW50aXRpZXM7XG4gICAgY29uc3QgY2hhbmdlU3RhdGUgPSB1cGRhdGVzLnJlZHVjZSgoY2hnU3RhdGUsIHVwZGF0ZSkgPT4ge1xuICAgICAgY29uc3QgeyBpZCwgY2hhbmdlczogZW50aXR5IH0gPSB1cGRhdGU7XG4gICAgICBpZiAoaWQgPT0gbnVsbCB8fCBpZCA9PT0gJycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGAke2NvbGxlY3Rpb24uZW50aXR5TmFtZX0gZW50aXR5IHVwZGF0ZSByZXF1aXJlcyBhIGtleSB0byBiZSB0cmFja2VkYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3JpZ2luYWxWYWx1ZSA9IGVudGl0eU1hcFtpZF07XG4gICAgICAvLyBPbmx5IHRyYWNrIGlmIGl0IGlzIGluIHRoZSBjb2xsZWN0aW9uLiBTaWxlbnRseSBpZ25vcmUgaWYgaXQgaXMgbm90LlxuICAgICAgLy8gQG5ncngvZW50aXR5IGFkYXB0ZXIgd291bGQgYWxzbyBzaWxlbnRseSBpZ25vcmUuXG4gICAgICAvLyBUb2RvOiBzaG91bGQgbWlzc2luZyB1cGRhdGUgZW50aXR5IHJlYWxseSBiZSByZXBvcnRlZCBhcyBhbiBlcnJvcj9cbiAgICAgIGlmIChvcmlnaW5hbFZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHRyYWNrZWRDaGFuZ2UgPSBjaGdTdGF0ZVtpZF07XG4gICAgICAgIGlmICghdHJhY2tlZENoYW5nZSkge1xuICAgICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgICBkaWRNdXRhdGUgPSB0cnVlO1xuICAgICAgICAgICAgY2hnU3RhdGUgPSB7IC4uLmNoZ1N0YXRlIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGNoZ1N0YXRlW2lkXSA9IHsgY2hhbmdlVHlwZTogQ2hhbmdlVHlwZS5VcGRhdGVkLCBvcmlnaW5hbFZhbHVlIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjaGdTdGF0ZTtcbiAgICB9LCBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlKTtcbiAgICByZXR1cm4gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBhbiBlbnRpdHkgYmVmb3JlIHVwZGF0aW5nIGl0IGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBEb2VzIE5PVCB1cGRhdGUgdGhlIGNvbGxlY3Rpb24gKHRoZSByZWR1Y2VyJ3Mgam9iKS5cbiAgICogQHBhcmFtIHVwZGF0ZSBUaGUgZW50aXR5IHRvIHVwZGF0ZS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqIEBwYXJhbSBbbWVyZ2VTdHJhdGVneV0gVHJhY2sgYnkgZGVmYXVsdC4gRG9uJ3QgdHJhY2sgaWYgaXMgTWVyZ2VTdHJhdGVneS5JZ25vcmVDaGFuZ2VzLlxuICAgKi9cbiAgdHJhY2tVcGRhdGVPbmUoXG4gICAgdXBkYXRlOiBVcGRhdGU8VD4sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBtZXJnZVN0cmF0ZWd5PzogTWVyZ2VTdHJhdGVneVxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdXBkYXRlID09IG51bGxcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB0aGlzLnRyYWNrVXBkYXRlTWFueShbdXBkYXRlXSwgY29sbGVjdGlvbiwgbWVyZ2VTdHJhdGVneSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgbXVsdGlwbGUgZW50aXRpZXMgYmVmb3JlIHVwc2VydGluZyAoYWRkaW5nIGFuZCB1cGRhdGluZykgdGhlbSB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogRG9lcyBOT1QgdXBkYXRlIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBUaGUgZW50aXRpZXMgdG8gYWRkIG9yIHVwZGF0ZS4gVGhleSBtdXN0IGJlIGNvbXBsZXRlIGVudGl0aWVzIHdpdGggaWRzLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICogQHBhcmFtIFttZXJnZVN0cmF0ZWd5XSBUcmFjayBieSBkZWZhdWx0LiBEb24ndCB0cmFjayBpZiBpcyBNZXJnZVN0cmF0ZWd5Lklnbm9yZUNoYW5nZXMuXG4gICAqL1xuICB0cmFja1Vwc2VydE1hbnkoXG4gICAgZW50aXRpZXM6IFRbXSxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmIChcbiAgICAgIG1lcmdlU3RyYXRlZ3kgPT09IE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcyB8fFxuICAgICAgZW50aXRpZXMgPT0gbnVsbCB8fFxuICAgICAgZW50aXRpZXMubGVuZ3RoID09PSAwXG4gICAgKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbjsgLy8gbm90aGluZyB0byB0cmFja1xuICAgIH1cbiAgICBsZXQgZGlkTXV0YXRlID0gZmFsc2U7XG4gICAgY29uc3QgZW50aXR5TWFwID0gY29sbGVjdGlvbi5lbnRpdGllcztcbiAgICBjb25zdCBjaGFuZ2VTdGF0ZSA9IGVudGl0aWVzLnJlZHVjZSgoY2hnU3RhdGUsIGVudGl0eSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLnNlbGVjdElkKGVudGl0eSk7XG4gICAgICBpZiAoaWQgPT0gbnVsbCB8fCBpZCA9PT0gJycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGAke2NvbGxlY3Rpb24uZW50aXR5TmFtZX0gZW50aXR5IHVwc2VydCByZXF1aXJlcyBhIGtleSB0byBiZSB0cmFja2VkYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgdHJhY2tlZENoYW5nZSA9IGNoZ1N0YXRlW2lkXTtcblxuICAgICAgaWYgKCF0cmFja2VkQ2hhbmdlKSB7XG4gICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgZGlkTXV0YXRlID0gdHJ1ZTtcbiAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG9yaWdpbmFsVmFsdWUgPSBlbnRpdHlNYXBbaWRdO1xuICAgICAgICBjaGdTdGF0ZVtpZF0gPVxuICAgICAgICAgIG9yaWdpbmFsVmFsdWUgPT0gbnVsbFxuICAgICAgICAgICAgPyB7IGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuQWRkZWQgfVxuICAgICAgICAgICAgOiB7IGNoYW5nZVR5cGU6IENoYW5nZVR5cGUuVXBkYXRlZCwgb3JpZ2luYWxWYWx1ZSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNoZ1N0YXRlO1xuICAgIH0sIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuICAgIHJldHVybiBkaWRNdXRhdGUgPyB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlIH0gOiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGFuIGVudGl0eSBiZWZvcmUgdXBzZXJ0IChhZGRpbmcgYW5kIHVwZGF0aW5nKSBpdCB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogRG9lcyBOT1QgdXBkYXRlIHRoZSBjb2xsZWN0aW9uICh0aGUgcmVkdWNlcidzIGpvYikuXG4gICAqIEBwYXJhbSBlbnRpdGllcyBUaGUgZW50aXR5IHRvIGFkZCBvciB1cGRhdGUuIEl0IG11c3QgYmUgYSBjb21wbGV0ZSBlbnRpdHkgd2l0aCBpdHMgaWQuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBlbnRpdHkgY29sbGVjdGlvblxuICAgKiBAcGFyYW0gW21lcmdlU3RyYXRlZ3ldIFRyYWNrIGJ5IGRlZmF1bHQuIERvbid0IHRyYWNrIGlmIGlzIE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcy5cbiAgICovXG4gIHRyYWNrVXBzZXJ0T25lKFxuICAgIGVudGl0eTogVCxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIG1lcmdlU3RyYXRlZ3k/OiBNZXJnZVN0cmF0ZWd5XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiBlbnRpdHkgPT0gbnVsbFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHRoaXMudHJhY2tVcHNlcnRNYW55KFtlbnRpdHldLCBjb2xsZWN0aW9uLCBtZXJnZVN0cmF0ZWd5KTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHRyYWNrIG1ldGhvZHNcblxuICAvLyAjcmVnaW9uIHVuZG8gbWV0aG9kc1xuICAvKipcbiAgICogUmV2ZXJ0IHRoZSB1bnNhdmVkIGNoYW5nZXMgZm9yIGFsbCBjb2xsZWN0aW9uLlxuICAgKiBIYXJtbGVzcyB3aGVuIHRoZXJlIGFyZSBubyBlbnRpdHkgY2hhbmdlcyB0byB1bmRvLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIHVuZG9BbGwoY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPik6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGlkcyA9IE9iamVjdC5rZXlzKGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUpO1xuXG4gICAgY29uc3QgeyByZW1vdmUsIHVwc2VydCB9ID0gaWRzLnJlZHVjZShcbiAgICAgIChhY2MsIGlkKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoYW5nZVN0YXRlID0gYWNjLmNoZ1N0YXRlW2lkXSE7XG4gICAgICAgIHN3aXRjaCAoY2hhbmdlU3RhdGUuY2hhbmdlVHlwZSkge1xuICAgICAgICAgIGNhc2UgQ2hhbmdlVHlwZS5BZGRlZDpcbiAgICAgICAgICAgIGFjYy5yZW1vdmUucHVzaChpZCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIENoYW5nZVR5cGUuRGVsZXRlZDpcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZWQgPSBjaGFuZ2VTdGF0ZSEub3JpZ2luYWxWYWx1ZTtcbiAgICAgICAgICAgIGlmIChyZW1vdmVkKSB7XG4gICAgICAgICAgICAgIGFjYy51cHNlcnQucHVzaChyZW1vdmVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgQ2hhbmdlVHlwZS5VcGRhdGVkOlxuICAgICAgICAgICAgYWNjLnVwc2VydC5wdXNoKGNoYW5nZVN0YXRlIS5vcmlnaW5hbFZhbHVlISk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIC8vIGVudGl0aWVzVG9VbmRvXG4gICAgICB7XG4gICAgICAgIHJlbW92ZTogW10gYXMgKG51bWJlciB8IHN0cmluZylbXSxcbiAgICAgICAgdXBzZXJ0OiBbXSBhcyBUW10sXG4gICAgICAgIGNoZ1N0YXRlOiBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlLFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkocmVtb3ZlIGFzIHN0cmluZ1tdLCBjb2xsZWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkodXBzZXJ0LCBjb2xsZWN0aW9uKTtcblxuICAgIHJldHVybiB7IC4uLmNvbGxlY3Rpb24sIGNoYW5nZVN0YXRlOiB7fSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldmVydCB0aGUgdW5zYXZlZCBjaGFuZ2VzIGZvciB0aGUgZ2l2ZW4gZW50aXRpZXMuXG4gICAqIEhhcm1sZXNzIHdoZW4gdGhlcmUgYXJlIG5vIGVudGl0eSBjaGFuZ2VzIHRvIHVuZG8uXG4gICAqIEBwYXJhbSBlbnRpdHlPcklkTGlzdCBUaGUgZW50aXRpZXMgdG8gcmV2ZXJ0IG9yIHRoZWlyIGlkcy5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGVudGl0eSBjb2xsZWN0aW9uXG4gICAqL1xuICB1bmRvTWFueShcbiAgICBlbnRpdHlPcklkTGlzdDogKG51bWJlciB8IHN0cmluZyB8IFQpW10sXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBpZiAoZW50aXR5T3JJZExpc3QgPT0gbnVsbCB8fCBlbnRpdHlPcklkTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBjb2xsZWN0aW9uOyAvLyBub3RoaW5nIHRvIHVuZG9cbiAgICB9XG4gICAgbGV0IGRpZE11dGF0ZSA9IGZhbHNlO1xuXG4gICAgY29uc3QgeyBjaGFuZ2VTdGF0ZSwgcmVtb3ZlLCB1cHNlcnQgfSA9IGVudGl0eU9ySWRMaXN0LnJlZHVjZShcbiAgICAgIChhY2MsIGVudGl0eU9ySWQpID0+IHtcbiAgICAgICAgbGV0IGNoZ1N0YXRlID0gYWNjLmNoYW5nZVN0YXRlO1xuICAgICAgICBjb25zdCBpZCA9XG4gICAgICAgICAgdHlwZW9mIGVudGl0eU9ySWQgPT09ICdvYmplY3QnXG4gICAgICAgICAgICA/IHRoaXMuc2VsZWN0SWQoZW50aXR5T3JJZClcbiAgICAgICAgICAgIDogKGVudGl0eU9ySWQgYXMgc3RyaW5nIHwgbnVtYmVyKTtcbiAgICAgICAgY29uc3QgY2hhbmdlID0gY2hnU3RhdGVbaWRdITtcbiAgICAgICAgaWYgKGNoYW5nZSkge1xuICAgICAgICAgIGlmICghZGlkTXV0YXRlKSB7XG4gICAgICAgICAgICBjaGdTdGF0ZSA9IHsgLi4uY2hnU3RhdGUgfTtcbiAgICAgICAgICAgIGRpZE11dGF0ZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlbGV0ZSBjaGdTdGF0ZVtpZF07IC8vIGNsZWFyIHRyYWNraW5nIG9mIHRoaXMgZW50aXR5XG4gICAgICAgICAgYWNjLmNoYW5nZVN0YXRlID0gY2hnU3RhdGU7XG4gICAgICAgICAgc3dpdGNoIChjaGFuZ2UuY2hhbmdlVHlwZSkge1xuICAgICAgICAgICAgY2FzZSBDaGFuZ2VUeXBlLkFkZGVkOlxuICAgICAgICAgICAgICBhY2MucmVtb3ZlLnB1c2goaWQpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgQ2hhbmdlVHlwZS5EZWxldGVkOlxuICAgICAgICAgICAgICBjb25zdCByZW1vdmVkID0gY2hhbmdlIS5vcmlnaW5hbFZhbHVlO1xuICAgICAgICAgICAgICBpZiAocmVtb3ZlZCkge1xuICAgICAgICAgICAgICAgIGFjYy51cHNlcnQucHVzaChyZW1vdmVkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgQ2hhbmdlVHlwZS5VcGRhdGVkOlxuICAgICAgICAgICAgICBhY2MudXBzZXJ0LnB1c2goY2hhbmdlIS5vcmlnaW5hbFZhbHVlISk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIC8vIGVudGl0aWVzVG9VbmRvXG4gICAgICB7XG4gICAgICAgIHJlbW92ZTogW10gYXMgKG51bWJlciB8IHN0cmluZylbXSxcbiAgICAgICAgdXBzZXJ0OiBbXSBhcyBUW10sXG4gICAgICAgIGNoYW5nZVN0YXRlOiBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlLFxuICAgICAgfVxuICAgICk7XG5cbiAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkocmVtb3ZlIGFzIHN0cmluZ1tdLCBjb2xsZWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkodXBzZXJ0LCBjb2xsZWN0aW9uKTtcbiAgICByZXR1cm4gZGlkTXV0YXRlID8geyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9IDogY29sbGVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZlcnQgdGhlIHVuc2F2ZWQgY2hhbmdlcyBmb3IgdGhlIGdpdmVuIGVudGl0eS5cbiAgICogSGFybWxlc3Mgd2hlbiB0aGVyZSBhcmUgbm8gZW50aXR5IGNoYW5nZXMgdG8gdW5kby5cbiAgICogQHBhcmFtIGVudGl0eU9ySWQgVGhlIGVudGl0eSB0byByZXZlcnQgb3IgaXRzIGlkLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgZW50aXR5IGNvbGxlY3Rpb25cbiAgICovXG4gIHVuZG9PbmUoXG4gICAgZW50aXR5T3JJZDogbnVtYmVyIHwgc3RyaW5nIHwgVCxcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiBlbnRpdHlPcklkID09IG51bGxcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB0aGlzLnVuZG9NYW55KFtlbnRpdHlPcklkXSwgY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiB1bmRvIG1ldGhvZHNcbn1cbiJdfQ==