@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.
- package/bundles/ngrx-data.umd.js +902 -4475
- package/bundles/ngrx-data.umd.js.map +1 -1
- package/bundles/ngrx-data.umd.min.js +15 -1
- package/bundles/ngrx-data.umd.min.js.map +1 -1
- package/esm2015/index.js +2 -7
- package/esm2015/ngrx-data.js +2 -7
- package/esm2015/public_api.js +2 -7
- package/esm2015/src/actions/entity-action-factory.js +6 -31
- package/esm2015/src/actions/entity-action-guard.js +23 -130
- package/esm2015/src/actions/entity-action-operators.js +11 -64
- package/esm2015/src/actions/entity-action.js +2 -68
- package/esm2015/src/actions/entity-cache-action.js +14 -125
- package/esm2015/src/actions/entity-cache-change-set.js +15 -126
- package/esm2015/src/actions/entity-op.js +70 -89
- package/esm2015/src/actions/merge-strategy.js +8 -16
- package/esm2015/src/actions/update-response-data.js +2 -36
- package/esm2015/src/dataservices/data-service-error.js +1 -34
- package/esm2015/src/dataservices/default-data-service-config.js +1 -41
- package/esm2015/src/dataservices/default-data.service.js +5 -163
- package/esm2015/src/dataservices/entity-cache-data.service.js +17 -103
- package/esm2015/src/dataservices/entity-data.service.js +5 -31
- package/esm2015/src/dataservices/http-url-generator.js +11 -97
- package/esm2015/src/dataservices/interfaces.js +2 -71
- package/esm2015/src/dataservices/persistence-result-handler.service.js +7 -66
- package/esm2015/src/dispatchers/entity-cache-dispatcher.js +40 -97
- package/esm2015/src/dispatchers/entity-commands.js +2 -247
- package/esm2015/src/dispatchers/entity-dispatcher-base.js +65 -287
- package/esm2015/src/dispatchers/entity-dispatcher-default-options.js +6 -48
- package/esm2015/src/dispatchers/entity-dispatcher-factory.js +2 -64
- package/esm2015/src/dispatchers/entity-dispatcher.js +1 -74
- package/esm2015/src/effects/entity-cache-effects.js +21 -135
- package/esm2015/src/effects/entity-effects-scheduler.js +2 -10
- package/esm2015/src/effects/entity-effects.js +18 -128
- package/esm2015/src/entity-data-without-effects.module.js +7 -79
- package/esm2015/src/entity-data.module.js +3 -25
- package/esm2015/src/entity-metadata/entity-definition.js +2 -42
- package/esm2015/src/entity-metadata/entity-definition.service.js +14 -52
- package/esm2015/src/entity-metadata/entity-filters.js +5 -33
- package/esm2015/src/entity-metadata/entity-metadata.js +1 -34
- package/esm2015/src/entity-services/entity-collection-service-base.js +56 -208
- package/esm2015/src/entity-services/entity-collection-service-elements-factory.js +3 -60
- package/esm2015/src/entity-services/entity-collection-service-factory.js +5 -20
- package/esm2015/src/entity-services/entity-collection-service.js +2 -53
- package/esm2015/src/entity-services/entity-services-base.js +18 -78
- package/esm2015/src/entity-services/entity-services-elements.js +9 -44
- package/esm2015/src/entity-services/entity-services.js +1 -70
- package/esm2015/src/index.js +1 -6
- package/esm2015/src/reducers/constants.js +1 -11
- package/esm2015/src/reducers/entity-cache-reducer.js +33 -175
- package/esm2015/src/reducers/entity-cache.js +2 -10
- package/esm2015/src/reducers/entity-change-tracker-base.js +115 -262
- package/esm2015/src/reducers/entity-change-tracker.js +2 -179
- package/esm2015/src/reducers/entity-collection-creator.js +5 -29
- package/esm2015/src/reducers/entity-collection-reducer-methods.js +44 -503
- package/esm2015/src/reducers/entity-collection-reducer-registry.js +8 -50
- package/esm2015/src/reducers/entity-collection-reducer.js +5 -34
- package/esm2015/src/reducers/entity-collection.js +9 -65
- package/esm2015/src/selectors/entity-cache-selector.js +1 -12
- package/esm2015/src/selectors/entity-selectors$.js +11 -137
- package/esm2015/src/selectors/entity-selectors.js +23 -262
- package/esm2015/src/utils/correlation-id-generator.js +4 -30
- package/esm2015/src/utils/default-logger.js +1 -21
- package/esm2015/src/utils/default-pluralizer.js +3 -24
- package/esm2015/src/utils/guid-fns.js +9 -41
- package/esm2015/src/utils/interfaces.js +1 -49
- package/esm2015/src/utils/utilities.js +6 -25
- package/fesm2015/ngrx-data.js +721 -4410
- package/fesm2015/ngrx-data.js.map +1 -1
- package/package.json +5 -5
- package/schematics-core/index.js +4 -1
- package/schematics-core/index.js.map +1 -1
- package/schematics-core/utility/ast-utils.js +127 -1
- package/schematics-core/utility/ast-utils.js.map +1 -1
- package/schematics-core/utility/config.js +1 -1
- package/schematics-core/utility/config.js.map +1 -1
- package/schematics-core/utility/find-component.js +101 -0
- package/schematics-core/utility/find-component.js.map +1 -0
- package/schematics-core/utility/libs-version.js +1 -1
- package/schematics-core/utility/libs-version.js.map +1 -1
- package/schematics-core/utility/project.js +4 -2
- package/schematics-core/utility/project.js.map +1 -1
- package/CHANGELOG.md +0 -3
- package/esm2015/index.ngsummary.json +0 -1
- package/esm2015/ngrx-data.ngsummary.json +0 -1
- package/esm2015/public_api.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-action-factory.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-action-guard.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-action-operators.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-action.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-cache-action.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-cache-change-set.ngsummary.json +0 -1
- package/esm2015/src/actions/entity-op.ngsummary.json +0 -1
- package/esm2015/src/actions/merge-strategy.ngsummary.json +0 -1
- package/esm2015/src/actions/update-response-data.ngsummary.json +0 -1
- package/esm2015/src/dataservices/data-service-error.ngsummary.json +0 -1
- package/esm2015/src/dataservices/default-data-service-config.ngsummary.json +0 -1
- package/esm2015/src/dataservices/default-data.service.ngsummary.json +0 -1
- package/esm2015/src/dataservices/entity-cache-data.service.ngsummary.json +0 -1
- package/esm2015/src/dataservices/entity-data.service.ngsummary.json +0 -1
- package/esm2015/src/dataservices/http-url-generator.ngsummary.json +0 -1
- package/esm2015/src/dataservices/interfaces.ngsummary.json +0 -1
- package/esm2015/src/dataservices/persistence-result-handler.service.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-cache-dispatcher.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-commands.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-dispatcher-base.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-dispatcher-default-options.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-dispatcher-factory.ngsummary.json +0 -1
- package/esm2015/src/dispatchers/entity-dispatcher.ngsummary.json +0 -1
- package/esm2015/src/effects/entity-cache-effects.ngsummary.json +0 -1
- package/esm2015/src/effects/entity-effects-scheduler.ngsummary.json +0 -1
- package/esm2015/src/effects/entity-effects.ngsummary.json +0 -1
- package/esm2015/src/entity-data-without-effects.module.ngfactory.js +0 -36
- package/esm2015/src/entity-data-without-effects.module.ngsummary.json +0 -1
- package/esm2015/src/entity-data.module.ngfactory.js +0 -48
- package/esm2015/src/entity-data.module.ngsummary.json +0 -1
- package/esm2015/src/entity-metadata/entity-definition.ngsummary.json +0 -1
- package/esm2015/src/entity-metadata/entity-definition.service.ngsummary.json +0 -1
- package/esm2015/src/entity-metadata/entity-filters.ngsummary.json +0 -1
- package/esm2015/src/entity-metadata/entity-metadata.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-collection-service-base.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-collection-service-elements-factory.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-collection-service-factory.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-collection-service.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-services-base.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-services-elements.ngsummary.json +0 -1
- package/esm2015/src/entity-services/entity-services.ngsummary.json +0 -1
- package/esm2015/src/index.ngsummary.json +0 -1
- package/esm2015/src/reducers/constants.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-cache-reducer.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-cache.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-change-tracker-base.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-change-tracker.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-collection-creator.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-collection-reducer-methods.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-collection-reducer-registry.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-collection-reducer.ngsummary.json +0 -1
- package/esm2015/src/reducers/entity-collection.ngsummary.json +0 -1
- package/esm2015/src/selectors/entity-cache-selector.ngsummary.json +0 -1
- package/esm2015/src/selectors/entity-selectors$.ngsummary.json +0 -1
- package/esm2015/src/selectors/entity-selectors.ngsummary.json +0 -1
- package/esm2015/src/utils/correlation-id-generator.ngsummary.json +0 -1
- package/esm2015/src/utils/default-logger.ngsummary.json +0 -1
- package/esm2015/src/utils/default-pluralizer.ngsummary.json +0 -1
- package/esm2015/src/utils/guid-fns.ngsummary.json +0 -1
- package/esm2015/src/utils/interfaces.ngsummary.json +0 -1
- package/esm2015/src/utils/utilities.ngsummary.json +0 -1
- package/schematics/ng-add/files/entity-metadata.ts.template +0 -10
- package/src/entity-data-without-effects.module.ngfactory.d.ts +0 -3
- 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-collection-reducer-methods.ts
|
|
4
|
-
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
|
|
5
|
-
*/
|
|
6
1
|
import { Injectable } from '@angular/core';
|
|
7
2
|
import { ChangeType, } from './entity-collection';
|
|
8
3
|
import { EntityChangeTrackerBase } from './entity-change-tracker-base';
|
|
@@ -11,23 +6,10 @@ import { EntityActionGuard } from '../actions/entity-action-guard';
|
|
|
11
6
|
import { EntityDefinitionService } from '../entity-metadata/entity-definition.service';
|
|
12
7
|
import { EntityOp } from '../actions/entity-op';
|
|
13
8
|
import { MergeStrategy } from '../actions/merge-strategy';
|
|
14
|
-
/**
|
|
15
|
-
* Map of {EntityOp} to reducer method for the operation.
|
|
16
|
-
* If an operation is missing, caller should return the collection for that reducer.
|
|
17
|
-
* @record
|
|
18
|
-
* @template T
|
|
19
|
-
*/
|
|
20
|
-
export function EntityCollectionReducerMethodMap() { }
|
|
21
9
|
/**
|
|
22
10
|
* Base implementation of reducer methods for an entity collection.
|
|
23
|
-
* @template T
|
|
24
11
|
*/
|
|
25
12
|
export class EntityCollectionReducerMethods {
|
|
26
|
-
/**
|
|
27
|
-
* @param {?} entityName
|
|
28
|
-
* @param {?} definition
|
|
29
|
-
* @param {?=} entityChangeTracker
|
|
30
|
-
*/
|
|
31
13
|
constructor(entityName, definition,
|
|
32
14
|
/*
|
|
33
15
|
* Track changes to entities since the last query or save
|
|
@@ -113,76 +95,34 @@ export class EntityCollectionReducerMethods {
|
|
|
113
95
|
entityChangeTracker ||
|
|
114
96
|
new EntityChangeTrackerBase(this.adapter, this.selectId);
|
|
115
97
|
}
|
|
116
|
-
/**
|
|
117
|
-
* Cancel a persistence operation
|
|
118
|
-
* @protected
|
|
119
|
-
* @param {?} collection
|
|
120
|
-
* @return {?}
|
|
121
|
-
*/
|
|
98
|
+
/** Cancel a persistence operation */
|
|
122
99
|
cancelPersist(collection) {
|
|
123
100
|
return this.setLoadingFalse(collection);
|
|
124
101
|
}
|
|
125
102
|
// #region query operations
|
|
126
|
-
/**
|
|
127
|
-
* @protected
|
|
128
|
-
* @param {?} collection
|
|
129
|
-
* @return {?}
|
|
130
|
-
*/
|
|
131
103
|
queryAll(collection) {
|
|
132
104
|
return this.setLoadingTrue(collection);
|
|
133
105
|
}
|
|
134
|
-
/**
|
|
135
|
-
* @protected
|
|
136
|
-
* @param {?} collection
|
|
137
|
-
* @param {?} action
|
|
138
|
-
* @return {?}
|
|
139
|
-
*/
|
|
140
106
|
queryAllError(collection, action) {
|
|
141
107
|
return this.setLoadingFalse(collection);
|
|
142
108
|
}
|
|
143
109
|
/**
|
|
144
110
|
* Merges query results per the MergeStrategy
|
|
145
111
|
* Sets loading flag to false and loaded flag to true.
|
|
146
|
-
* @protected
|
|
147
|
-
* @param {?} collection
|
|
148
|
-
* @param {?} action
|
|
149
|
-
* @return {?}
|
|
150
112
|
*/
|
|
151
113
|
queryAllSuccess(collection, action) {
|
|
152
|
-
/** @type {?} */
|
|
153
114
|
const data = this.extractData(action);
|
|
154
|
-
/** @type {?} */
|
|
155
115
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
156
116
|
return Object.assign(Object.assign({}, this.entityChangeTracker.mergeQueryResults(data, collection, mergeStrategy)), { loaded: true, loading: false });
|
|
157
117
|
}
|
|
158
|
-
/**
|
|
159
|
-
* @protected
|
|
160
|
-
* @param {?} collection
|
|
161
|
-
* @param {?} action
|
|
162
|
-
* @return {?}
|
|
163
|
-
*/
|
|
164
118
|
queryByKey(collection, action) {
|
|
165
119
|
return this.setLoadingTrue(collection);
|
|
166
120
|
}
|
|
167
|
-
/**
|
|
168
|
-
* @protected
|
|
169
|
-
* @param {?} collection
|
|
170
|
-
* @param {?} action
|
|
171
|
-
* @return {?}
|
|
172
|
-
*/
|
|
173
121
|
queryByKeyError(collection, action) {
|
|
174
122
|
return this.setLoadingFalse(collection);
|
|
175
123
|
}
|
|
176
|
-
/**
|
|
177
|
-
* @protected
|
|
178
|
-
* @param {?} collection
|
|
179
|
-
* @param {?} action
|
|
180
|
-
* @return {?}
|
|
181
|
-
*/
|
|
182
124
|
queryByKeySuccess(collection, action) {
|
|
183
|
-
/** @type {?} */
|
|
184
125
|
const data = this.extractData(action);
|
|
185
|
-
/** @type {?} */
|
|
186
126
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
187
127
|
collection =
|
|
188
128
|
data == null
|
|
@@ -190,20 +130,9 @@ export class EntityCollectionReducerMethods {
|
|
|
190
130
|
: this.entityChangeTracker.mergeQueryResults([data], collection, mergeStrategy);
|
|
191
131
|
return this.setLoadingFalse(collection);
|
|
192
132
|
}
|
|
193
|
-
/**
|
|
194
|
-
* @protected
|
|
195
|
-
* @param {?} collection
|
|
196
|
-
* @return {?}
|
|
197
|
-
*/
|
|
198
133
|
queryLoad(collection) {
|
|
199
134
|
return this.setLoadingTrue(collection);
|
|
200
135
|
}
|
|
201
|
-
/**
|
|
202
|
-
* @protected
|
|
203
|
-
* @param {?} collection
|
|
204
|
-
* @param {?} action
|
|
205
|
-
* @return {?}
|
|
206
|
-
*/
|
|
207
136
|
queryLoadError(collection, action) {
|
|
208
137
|
return this.setLoadingFalse(collection);
|
|
209
138
|
}
|
|
@@ -211,44 +140,19 @@ export class EntityCollectionReducerMethods {
|
|
|
211
140
|
* Replaces all entities in the collection
|
|
212
141
|
* Sets loaded flag to true, loading flag to false,
|
|
213
142
|
* and clears changeState for the entire collection.
|
|
214
|
-
* @protected
|
|
215
|
-
* @param {?} collection
|
|
216
|
-
* @param {?} action
|
|
217
|
-
* @return {?}
|
|
218
143
|
*/
|
|
219
144
|
queryLoadSuccess(collection, action) {
|
|
220
|
-
/** @type {?} */
|
|
221
145
|
const data = this.extractData(action);
|
|
222
146
|
return Object.assign(Object.assign({}, this.adapter.setAll(data, collection)), { loading: false, loaded: true, changeState: {} });
|
|
223
147
|
}
|
|
224
|
-
/**
|
|
225
|
-
* @protected
|
|
226
|
-
* @param {?} collection
|
|
227
|
-
* @param {?} action
|
|
228
|
-
* @return {?}
|
|
229
|
-
*/
|
|
230
148
|
queryMany(collection, action) {
|
|
231
149
|
return this.setLoadingTrue(collection);
|
|
232
150
|
}
|
|
233
|
-
/**
|
|
234
|
-
* @protected
|
|
235
|
-
* @param {?} collection
|
|
236
|
-
* @param {?} action
|
|
237
|
-
* @return {?}
|
|
238
|
-
*/
|
|
239
151
|
queryManyError(collection, action) {
|
|
240
152
|
return this.setLoadingFalse(collection);
|
|
241
153
|
}
|
|
242
|
-
/**
|
|
243
|
-
* @protected
|
|
244
|
-
* @param {?} collection
|
|
245
|
-
* @param {?} action
|
|
246
|
-
* @return {?}
|
|
247
|
-
*/
|
|
248
154
|
queryManySuccess(collection, action) {
|
|
249
|
-
/** @type {?} */
|
|
250
155
|
const data = this.extractData(action);
|
|
251
|
-
/** @type {?} */
|
|
252
156
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
253
157
|
return Object.assign(Object.assign({}, this.entityChangeTracker.mergeQueryResults(data, collection, mergeStrategy)), { loading: false });
|
|
254
158
|
}
|
|
@@ -259,19 +163,14 @@ export class EntityCollectionReducerMethods {
|
|
|
259
163
|
* Save multiple new entities.
|
|
260
164
|
* If saving pessimistically, delay adding to collection until server acknowledges success.
|
|
261
165
|
* If saving optimistically; add immediately.
|
|
262
|
-
* @
|
|
263
|
-
* @param
|
|
264
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
166
|
+
* @param collection The collection to which the entities should be added.
|
|
167
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
265
168
|
* and the data, which must be an array of entities.
|
|
266
169
|
* If saving optimistically, the entities must have their keys.
|
|
267
|
-
* @return {?}
|
|
268
170
|
*/
|
|
269
171
|
saveAddMany(collection, action) {
|
|
270
172
|
if (this.isOptimistic(action)) {
|
|
271
|
-
|
|
272
|
-
const entities = this.guard.mustBeEntities(action);
|
|
273
|
-
// ensure the entity has a PK
|
|
274
|
-
/** @type {?} */
|
|
173
|
+
const entities = this.guard.mustBeEntities(action); // ensure the entity has a PK
|
|
275
174
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
276
175
|
collection = this.entityChangeTracker.trackAddMany(entities, collection, mergeStrategy);
|
|
277
176
|
collection = this.adapter.addMany(entities, collection);
|
|
@@ -285,10 +184,6 @@ export class EntityCollectionReducerMethods {
|
|
|
285
184
|
* you may not have to compensate for the error.
|
|
286
185
|
* If saved optimistically, the unsaved entities are in the collection and
|
|
287
186
|
* you may need to compensate for the error.
|
|
288
|
-
* @protected
|
|
289
|
-
* @param {?} collection
|
|
290
|
-
* @param {?} action
|
|
291
|
-
* @return {?}
|
|
292
187
|
*/
|
|
293
188
|
saveAddManyError(collection, action) {
|
|
294
189
|
return this.setLoadingFalse(collection);
|
|
@@ -308,16 +203,10 @@ export class EntityCollectionReducerMethods {
|
|
|
308
203
|
* saveAddOneSuccess updates (not upserts) with the lone entity from the server.
|
|
309
204
|
* There is no effect if the entity is not already in cache.
|
|
310
205
|
* saveAddManySuccess will add an entity if it is not found in cache.
|
|
311
|
-
* @protected
|
|
312
|
-
* @param {?} collection
|
|
313
|
-
* @param {?} action
|
|
314
|
-
* @return {?}
|
|
315
206
|
*/
|
|
316
207
|
saveAddManySuccess(collection, action) {
|
|
317
208
|
// For pessimistic save, ensure the server generated the primary key if the client didn't send one.
|
|
318
|
-
/** @type {?} */
|
|
319
209
|
const entities = this.guard.mustBeEntities(action);
|
|
320
|
-
/** @type {?} */
|
|
321
210
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
322
211
|
if (this.isOptimistic(action)) {
|
|
323
212
|
collection = this.entityChangeTracker.mergeSaveUpserts(entities, collection, mergeStrategy);
|
|
@@ -333,19 +222,14 @@ export class EntityCollectionReducerMethods {
|
|
|
333
222
|
* Save a new entity.
|
|
334
223
|
* If saving pessimistically, delay adding to collection until server acknowledges success.
|
|
335
224
|
* If saving optimistically; add entity immediately.
|
|
336
|
-
* @
|
|
337
|
-
* @param
|
|
338
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
225
|
+
* @param collection The collection to which the entity should be added.
|
|
226
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
339
227
|
* and the data, which must be an entity.
|
|
340
228
|
* If saving optimistically, the entity must have a key.
|
|
341
|
-
* @return {?}
|
|
342
229
|
*/
|
|
343
230
|
saveAddOne(collection, action) {
|
|
344
231
|
if (this.isOptimistic(action)) {
|
|
345
|
-
|
|
346
|
-
const entity = this.guard.mustBeEntity(action);
|
|
347
|
-
// ensure the entity has a PK
|
|
348
|
-
/** @type {?} */
|
|
232
|
+
const entity = this.guard.mustBeEntity(action); // ensure the entity has a PK
|
|
349
233
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
350
234
|
collection = this.entityChangeTracker.trackAddOne(entity, collection, mergeStrategy);
|
|
351
235
|
collection = this.adapter.addOne(entity, collection);
|
|
@@ -359,10 +243,6 @@ export class EntityCollectionReducerMethods {
|
|
|
359
243
|
* you may not have to compensate for the error.
|
|
360
244
|
* If saved optimistically, the unsaved entity is in the collection and
|
|
361
245
|
* you may need to compensate for the error.
|
|
362
|
-
* @protected
|
|
363
|
-
* @param {?} collection
|
|
364
|
-
* @param {?} action
|
|
365
|
-
* @return {?}
|
|
366
246
|
*/
|
|
367
247
|
saveAddOneError(collection, action) {
|
|
368
248
|
return this.setLoadingFalse(collection);
|
|
@@ -375,19 +255,12 @@ export class EntityCollectionReducerMethods {
|
|
|
375
255
|
* Therefore, update the entity in the collection with the returned value (if any)
|
|
376
256
|
* Caution: in a race, this update could overwrite unsaved user changes.
|
|
377
257
|
* Use pessimistic add to avoid this risk.
|
|
378
|
-
* @protected
|
|
379
|
-
* @param {?} collection
|
|
380
|
-
* @param {?} action
|
|
381
|
-
* @return {?}
|
|
382
258
|
*/
|
|
383
259
|
saveAddOneSuccess(collection, action) {
|
|
384
260
|
// For pessimistic save, ensure the server generated the primary key if the client didn't send one.
|
|
385
|
-
/** @type {?} */
|
|
386
261
|
const entity = this.guard.mustBeEntity(action);
|
|
387
|
-
/** @type {?} */
|
|
388
262
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
389
263
|
if (this.isOptimistic(action)) {
|
|
390
|
-
/** @type {?} */
|
|
391
264
|
const update = this.toUpdate(entity);
|
|
392
265
|
// Always update the cache with added entity returned from server
|
|
393
266
|
collection = this.entityChangeTracker.mergeSaveUpdates([update], collection, mergeStrategy, false /*never skip*/);
|
|
@@ -408,27 +281,22 @@ export class EntityCollectionReducerMethods {
|
|
|
408
281
|
* and skip the server delete request.
|
|
409
282
|
* An optimistic save removes an existing entity from the collection immediately;
|
|
410
283
|
* a pessimistic save removes it after the server confirms successful delete.
|
|
411
|
-
* @
|
|
412
|
-
* @param
|
|
413
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
284
|
+
* @param collection Will remove the entity with this key from the collection.
|
|
285
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
414
286
|
* and the data, which must be a primary key or an entity with a key;
|
|
415
287
|
* this reducer extracts the key from the entity.
|
|
416
|
-
* @return {?}
|
|
417
288
|
*/
|
|
418
289
|
saveDeleteOne(collection, action) {
|
|
419
|
-
/** @type {?} */
|
|
420
290
|
const toDelete = this.extractData(action);
|
|
421
|
-
/** @type {?} */
|
|
422
291
|
const deleteId = typeof toDelete === 'object'
|
|
423
292
|
? this.selectId(toDelete)
|
|
424
|
-
:
|
|
425
|
-
/** @type {?} */
|
|
293
|
+
: toDelete;
|
|
426
294
|
const change = collection.changeState[deleteId];
|
|
427
295
|
// If entity is already tracked ...
|
|
428
296
|
if (change) {
|
|
429
297
|
if (change.changeType === ChangeType.Added) {
|
|
430
298
|
// Remove the added entity immediately and forget about its changes (via commit).
|
|
431
|
-
collection = this.adapter.removeOne(
|
|
299
|
+
collection = this.adapter.removeOne(deleteId, collection);
|
|
432
300
|
collection = this.entityChangeTracker.commitOne(deleteId, collection);
|
|
433
301
|
// Should not waste effort trying to delete on the server because it can't be there.
|
|
434
302
|
action.payload.skip = true;
|
|
@@ -440,10 +308,9 @@ export class EntityCollectionReducerMethods {
|
|
|
440
308
|
}
|
|
441
309
|
// If optimistic delete, track current state and remove immediately.
|
|
442
310
|
if (this.isOptimistic(action)) {
|
|
443
|
-
/** @type {?} */
|
|
444
311
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
445
312
|
collection = this.entityChangeTracker.trackDeleteOne(deleteId, collection, mergeStrategy);
|
|
446
|
-
collection = this.adapter.removeOne(
|
|
313
|
+
collection = this.adapter.removeOne(deleteId, collection);
|
|
447
314
|
}
|
|
448
315
|
return this.setLoadingTrue(collection);
|
|
449
316
|
}
|
|
@@ -454,10 +321,6 @@ export class EntityCollectionReducerMethods {
|
|
|
454
321
|
* you may not have to compensate for the error.
|
|
455
322
|
* If saved optimistically, the entity is not in the collection and
|
|
456
323
|
* you may need to compensate for the error.
|
|
457
|
-
* @protected
|
|
458
|
-
* @param {?} collection
|
|
459
|
-
* @param {?} action
|
|
460
|
-
* @return {?}
|
|
461
324
|
*/
|
|
462
325
|
saveDeleteOneError(collection, action) {
|
|
463
326
|
return this.setLoadingFalse(collection);
|
|
@@ -466,22 +329,16 @@ export class EntityCollectionReducerMethods {
|
|
|
466
329
|
* Successfully deleted entity on the server. The key of the deleted entity is in the action payload data.
|
|
467
330
|
* If saved pessimistically, if the entity is still in the collection it will be removed.
|
|
468
331
|
* If saved optimistically, the entity has already been removed from the collection.
|
|
469
|
-
* @protected
|
|
470
|
-
* @param {?} collection
|
|
471
|
-
* @param {?} action
|
|
472
|
-
* @return {?}
|
|
473
332
|
*/
|
|
474
333
|
saveDeleteOneSuccess(collection, action) {
|
|
475
|
-
/** @type {?} */
|
|
476
334
|
const deleteId = this.extractData(action);
|
|
477
335
|
if (this.isOptimistic(action)) {
|
|
478
|
-
/** @type {?} */
|
|
479
336
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
480
337
|
collection = this.entityChangeTracker.mergeSaveDeletes([deleteId], collection, mergeStrategy);
|
|
481
338
|
}
|
|
482
339
|
else {
|
|
483
340
|
// Pessimistic: ignore mergeStrategy. Remove entity from the collection and from change tracking.
|
|
484
|
-
collection = this.adapter.removeOne(
|
|
341
|
+
collection = this.adapter.removeOne(deleteId, collection);
|
|
485
342
|
collection = this.entityChangeTracker.commitOne(deleteId, collection);
|
|
486
343
|
}
|
|
487
344
|
return this.setLoadingFalse(collection);
|
|
@@ -495,32 +352,20 @@ export class EntityCollectionReducerMethods {
|
|
|
495
352
|
* Therefore, the server must be willing to ignore a delete request for an entity it cannot find.
|
|
496
353
|
* An optimistic save removes existing entities from the collection immediately;
|
|
497
354
|
* a pessimistic save removes them after the server confirms successful delete.
|
|
498
|
-
* @
|
|
499
|
-
* @param
|
|
500
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
355
|
+
* @param collection Removes entities from this collection.
|
|
356
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
501
357
|
* and the data, which must be an array of primary keys or entities with a key;
|
|
502
358
|
* this reducer extracts the key from the entity.
|
|
503
|
-
* @return {?}
|
|
504
359
|
*/
|
|
505
360
|
saveDeleteMany(collection, action) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
* @param {?} d
|
|
509
|
-
* @return {?}
|
|
510
|
-
*/
|
|
511
|
-
(d) => typeof d === 'object' ? this.selectId(d) : ((/** @type {?} */ (d)))));
|
|
512
|
-
deleteIds.forEach((/**
|
|
513
|
-
* @param {?} deleteId
|
|
514
|
-
* @return {?}
|
|
515
|
-
*/
|
|
516
|
-
(deleteId) => {
|
|
517
|
-
/** @type {?} */
|
|
361
|
+
const deleteIds = this.extractData(action).map((d) => typeof d === 'object' ? this.selectId(d) : d);
|
|
362
|
+
deleteIds.forEach((deleteId) => {
|
|
518
363
|
const change = collection.changeState[deleteId];
|
|
519
364
|
// If entity is already tracked ...
|
|
520
365
|
if (change) {
|
|
521
366
|
if (change.changeType === ChangeType.Added) {
|
|
522
367
|
// Remove the added entity immediately and forget about its changes (via commit).
|
|
523
|
-
collection = this.adapter.removeOne(
|
|
368
|
+
collection = this.adapter.removeOne(deleteId, collection);
|
|
524
369
|
collection = this.entityChangeTracker.commitOne(deleteId, collection);
|
|
525
370
|
// Should not waste effort trying to delete on the server because it can't be there.
|
|
526
371
|
action.payload.skip = true;
|
|
@@ -530,13 +375,12 @@ export class EntityCollectionReducerMethods {
|
|
|
530
375
|
collection = this.entityChangeTracker.trackDeleteOne(deleteId, collection);
|
|
531
376
|
}
|
|
532
377
|
}
|
|
533
|
-
})
|
|
378
|
+
});
|
|
534
379
|
// If optimistic delete, track current state and remove immediately.
|
|
535
380
|
if (this.isOptimistic(action)) {
|
|
536
|
-
/** @type {?} */
|
|
537
381
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
538
382
|
collection = this.entityChangeTracker.trackDeleteMany(deleteIds, collection, mergeStrategy);
|
|
539
|
-
collection = this.adapter.removeMany(
|
|
383
|
+
collection = this.adapter.removeMany(deleteIds, collection);
|
|
540
384
|
}
|
|
541
385
|
return this.setLoadingTrue(collection);
|
|
542
386
|
}
|
|
@@ -547,10 +391,6 @@ export class EntityCollectionReducerMethods {
|
|
|
547
391
|
* you may not have to compensate for the error.
|
|
548
392
|
* If saved optimistically, the entities are not in the collection and
|
|
549
393
|
* you may need to compensate for the error.
|
|
550
|
-
* @protected
|
|
551
|
-
* @param {?} collection
|
|
552
|
-
* @param {?} action
|
|
553
|
-
* @return {?}
|
|
554
394
|
*/
|
|
555
395
|
saveDeleteManyError(collection, action) {
|
|
556
396
|
return this.setLoadingFalse(collection);
|
|
@@ -559,22 +399,16 @@ export class EntityCollectionReducerMethods {
|
|
|
559
399
|
* Successfully deleted entities on the server. The keys of the deleted entities are in the action payload data.
|
|
560
400
|
* If saved pessimistically, entities that are still in the collection will be removed.
|
|
561
401
|
* If saved optimistically, the entities have already been removed from the collection.
|
|
562
|
-
* @protected
|
|
563
|
-
* @param {?} collection
|
|
564
|
-
* @param {?} action
|
|
565
|
-
* @return {?}
|
|
566
402
|
*/
|
|
567
403
|
saveDeleteManySuccess(collection, action) {
|
|
568
|
-
/** @type {?} */
|
|
569
404
|
const deleteIds = this.extractData(action);
|
|
570
405
|
if (this.isOptimistic(action)) {
|
|
571
|
-
/** @type {?} */
|
|
572
406
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
573
407
|
collection = this.entityChangeTracker.mergeSaveDeletes(deleteIds, collection, mergeStrategy);
|
|
574
408
|
}
|
|
575
409
|
else {
|
|
576
410
|
// Pessimistic: ignore mergeStrategy. Remove entity from the collection and from change tracking.
|
|
577
|
-
collection = this.adapter.removeMany(
|
|
411
|
+
collection = this.adapter.removeMany(deleteIds, collection);
|
|
578
412
|
collection = this.entityChangeTracker.commitMany(deleteIds, collection);
|
|
579
413
|
}
|
|
580
414
|
return this.setLoadingFalse(collection);
|
|
@@ -585,17 +419,13 @@ export class EntityCollectionReducerMethods {
|
|
|
585
419
|
* Save an update to an existing entity.
|
|
586
420
|
* If saving pessimistically, update the entity in the collection after the server confirms success.
|
|
587
421
|
* If saving optimistically, update the entity immediately, before the save request.
|
|
588
|
-
* @
|
|
589
|
-
* @param
|
|
590
|
-
* @param {?} action The action payload holds options, including if the save is optimistic,
|
|
422
|
+
* @param collection The collection to update
|
|
423
|
+
* @param action The action payload holds options, including if the save is optimistic,
|
|
591
424
|
* and the data which, must be an {Update<T>}
|
|
592
|
-
* @return {?}
|
|
593
425
|
*/
|
|
594
426
|
saveUpdateOne(collection, action) {
|
|
595
|
-
/** @type {?} */
|
|
596
427
|
const update = this.guard.mustBeUpdate(action);
|
|
597
428
|
if (this.isOptimistic(action)) {
|
|
598
|
-
/** @type {?} */
|
|
599
429
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
600
430
|
collection = this.entityChangeTracker.trackUpdateOne(update, collection, mergeStrategy);
|
|
601
431
|
collection = this.adapter.updateOne(update, collection);
|
|
@@ -609,10 +439,6 @@ export class EntityCollectionReducerMethods {
|
|
|
609
439
|
* you may not have to compensate for the error.
|
|
610
440
|
* If saved optimistically, the entity in the collection was updated
|
|
611
441
|
* and you may need to compensate for the error.
|
|
612
|
-
* @protected
|
|
613
|
-
* @param {?} collection
|
|
614
|
-
* @param {?} action
|
|
615
|
-
* @return {?}
|
|
616
442
|
*/
|
|
617
443
|
saveUpdateOneError(collection, action) {
|
|
618
444
|
return this.setLoadingFalse(collection);
|
|
@@ -625,20 +451,15 @@ export class EntityCollectionReducerMethods {
|
|
|
625
451
|
* Therefore, update the entity in the collection with the returned value (if any)
|
|
626
452
|
* Caution: in a race, this update could overwrite unsaved user changes.
|
|
627
453
|
* Use pessimistic update to avoid this risk.
|
|
628
|
-
* @
|
|
629
|
-
* @param
|
|
630
|
-
* @param {?} action The action payload holds options, including if the save is optimistic, and
|
|
454
|
+
* @param collection The collection to update
|
|
455
|
+
* @param action The action payload holds options, including if the save is optimistic, and
|
|
631
456
|
* the update data which, must be an UpdateResponse<T> that corresponds to the Update sent to the server.
|
|
632
457
|
* You must include an UpdateResponse even if the save was optimistic,
|
|
633
458
|
* to ensure that the change tracking is properly reset.
|
|
634
|
-
* @return {?}
|
|
635
459
|
*/
|
|
636
460
|
saveUpdateOneSuccess(collection, action) {
|
|
637
|
-
/** @type {?} */
|
|
638
461
|
const update = this.guard.mustBeUpdateResponse(action);
|
|
639
|
-
/** @type {?} */
|
|
640
462
|
const isOptimistic = this.isOptimistic(action);
|
|
641
|
-
/** @type {?} */
|
|
642
463
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
643
464
|
collection = this.entityChangeTracker.mergeSaveUpdates([update], collection, mergeStrategy, isOptimistic /*skip unchanged if optimistic */);
|
|
644
465
|
return this.setLoadingFalse(collection);
|
|
@@ -649,17 +470,13 @@ export class EntityCollectionReducerMethods {
|
|
|
649
470
|
* Save updated entities.
|
|
650
471
|
* If saving pessimistically, update the entities in the collection after the server confirms success.
|
|
651
472
|
* If saving optimistically, update the entities immediately, before the save request.
|
|
652
|
-
* @
|
|
653
|
-
* @param
|
|
654
|
-
* @param {?} action The action payload holds options, including if the save is optimistic,
|
|
473
|
+
* @param collection The collection to update
|
|
474
|
+
* @param action The action payload holds options, including if the save is optimistic,
|
|
655
475
|
* and the data which, must be an array of {Update<T>}.
|
|
656
|
-
* @return {?}
|
|
657
476
|
*/
|
|
658
477
|
saveUpdateMany(collection, action) {
|
|
659
|
-
/** @type {?} */
|
|
660
478
|
const updates = this.guard.mustBeUpdates(action);
|
|
661
479
|
if (this.isOptimistic(action)) {
|
|
662
|
-
/** @type {?} */
|
|
663
480
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
664
481
|
collection = this.entityChangeTracker.trackUpdateMany(updates, collection, mergeStrategy);
|
|
665
482
|
collection = this.adapter.updateMany(updates, collection);
|
|
@@ -673,10 +490,6 @@ export class EntityCollectionReducerMethods {
|
|
|
673
490
|
* you may not have to compensate for the error.
|
|
674
491
|
* If saved optimistically, the entities in the collection were updated
|
|
675
492
|
* and you may need to compensate for the error.
|
|
676
|
-
* @protected
|
|
677
|
-
* @param {?} collection
|
|
678
|
-
* @param {?} action
|
|
679
|
-
* @return {?}
|
|
680
493
|
*/
|
|
681
494
|
saveUpdateManyError(collection, action) {
|
|
682
495
|
return this.setLoadingFalse(collection);
|
|
@@ -689,20 +502,15 @@ export class EntityCollectionReducerMethods {
|
|
|
689
502
|
* Therefore, update the entity in the collection with the returned values (if any)
|
|
690
503
|
* Caution: in a race, this update could overwrite unsaved user changes.
|
|
691
504
|
* Use pessimistic update to avoid this risk.
|
|
692
|
-
* @
|
|
693
|
-
* @param
|
|
694
|
-
* @param {?} action The action payload holds options, including if the save is optimistic,
|
|
505
|
+
* @param collection The collection to update
|
|
506
|
+
* @param action The action payload holds options, including if the save is optimistic,
|
|
695
507
|
* and the data which, must be an array of UpdateResponse<T>.
|
|
696
508
|
* You must include an UpdateResponse for every Update sent to the server,
|
|
697
509
|
* even if the save was optimistic, to ensure that the change tracking is properly reset.
|
|
698
|
-
* @return {?}
|
|
699
510
|
*/
|
|
700
511
|
saveUpdateManySuccess(collection, action) {
|
|
701
|
-
/** @type {?} */
|
|
702
512
|
const updates = this.guard.mustBeUpdateResponses(action);
|
|
703
|
-
/** @type {?} */
|
|
704
513
|
const isOptimistic = this.isOptimistic(action);
|
|
705
|
-
/** @type {?} */
|
|
706
514
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
707
515
|
collection = this.entityChangeTracker.mergeSaveUpdates(updates, collection, mergeStrategy, false /* never skip */);
|
|
708
516
|
return this.setLoadingFalse(collection);
|
|
@@ -713,19 +521,14 @@ export class EntityCollectionReducerMethods {
|
|
|
713
521
|
* Save a new or existing entity.
|
|
714
522
|
* If saving pessimistically, delay adding to collection until server acknowledges success.
|
|
715
523
|
* If saving optimistically; add immediately.
|
|
716
|
-
* @
|
|
717
|
-
* @param
|
|
718
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
524
|
+
* @param collection The collection to which the entity should be upserted.
|
|
525
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
719
526
|
* and the data, which must be a whole entity.
|
|
720
527
|
* If saving optimistically, the entity must have its key.
|
|
721
|
-
* @return {?}
|
|
722
528
|
*/
|
|
723
529
|
saveUpsertOne(collection, action) {
|
|
724
530
|
if (this.isOptimistic(action)) {
|
|
725
|
-
|
|
726
|
-
const entity = this.guard.mustBeEntity(action);
|
|
727
|
-
// ensure the entity has a PK
|
|
728
|
-
/** @type {?} */
|
|
531
|
+
const entity = this.guard.mustBeEntity(action); // ensure the entity has a PK
|
|
729
532
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
730
533
|
collection = this.entityChangeTracker.trackUpsertOne(entity, collection, mergeStrategy);
|
|
731
534
|
collection = this.adapter.upsertOne(entity, collection);
|
|
@@ -739,10 +542,6 @@ export class EntityCollectionReducerMethods {
|
|
|
739
542
|
* you may not have to compensate for the error.
|
|
740
543
|
* If saved optimistically, the unsaved entities are in the collection and
|
|
741
544
|
* you may need to compensate for the error.
|
|
742
|
-
* @protected
|
|
743
|
-
* @param {?} collection
|
|
744
|
-
* @param {?} action
|
|
745
|
-
* @return {?}
|
|
746
545
|
*/
|
|
747
546
|
saveUpsertOneError(collection, action) {
|
|
748
547
|
return this.setLoadingFalse(collection);
|
|
@@ -755,16 +554,10 @@ export class EntityCollectionReducerMethods {
|
|
|
755
554
|
* Therefore, update the entities in the collection with the returned values (if any)
|
|
756
555
|
* Caution: in a race, this update could overwrite unsaved user changes.
|
|
757
556
|
* Use pessimistic add to avoid this risk.
|
|
758
|
-
* @protected
|
|
759
|
-
* @param {?} collection
|
|
760
|
-
* @param {?} action
|
|
761
|
-
* @return {?}
|
|
762
557
|
*/
|
|
763
558
|
saveUpsertOneSuccess(collection, action) {
|
|
764
559
|
// For pessimistic save, ensure the server generated the primary key if the client didn't send one.
|
|
765
|
-
/** @type {?} */
|
|
766
560
|
const entity = this.guard.mustBeEntity(action);
|
|
767
|
-
/** @type {?} */
|
|
768
561
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
769
562
|
// Always update the cache with upserted entities returned from server
|
|
770
563
|
collection = this.entityChangeTracker.mergeSaveUpserts([entity], collection, mergeStrategy);
|
|
@@ -776,19 +569,14 @@ export class EntityCollectionReducerMethods {
|
|
|
776
569
|
* Save multiple new or existing entities.
|
|
777
570
|
* If saving pessimistically, delay adding to collection until server acknowledges success.
|
|
778
571
|
* If saving optimistically; add immediately.
|
|
779
|
-
* @
|
|
780
|
-
* @param
|
|
781
|
-
* @param {?} action The action payload holds options, including whether the save is optimistic,
|
|
572
|
+
* @param collection The collection to which the entities should be upserted.
|
|
573
|
+
* @param action The action payload holds options, including whether the save is optimistic,
|
|
782
574
|
* and the data, which must be an array of whole entities.
|
|
783
575
|
* If saving optimistically, the entities must have their keys.
|
|
784
|
-
* @return {?}
|
|
785
576
|
*/
|
|
786
577
|
saveUpsertMany(collection, action) {
|
|
787
578
|
if (this.isOptimistic(action)) {
|
|
788
|
-
|
|
789
|
-
const entities = this.guard.mustBeEntities(action);
|
|
790
|
-
// ensure the entity has a PK
|
|
791
|
-
/** @type {?} */
|
|
579
|
+
const entities = this.guard.mustBeEntities(action); // ensure the entity has a PK
|
|
792
580
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
793
581
|
collection = this.entityChangeTracker.trackUpsertMany(entities, collection, mergeStrategy);
|
|
794
582
|
collection = this.adapter.upsertMany(entities, collection);
|
|
@@ -802,10 +590,6 @@ export class EntityCollectionReducerMethods {
|
|
|
802
590
|
* you may not have to compensate for the error.
|
|
803
591
|
* If saved optimistically, the unsaved entities are in the collection and
|
|
804
592
|
* you may need to compensate for the error.
|
|
805
|
-
* @protected
|
|
806
|
-
* @param {?} collection
|
|
807
|
-
* @param {?} action
|
|
808
|
-
* @return {?}
|
|
809
593
|
*/
|
|
810
594
|
saveUpsertManyError(collection, action) {
|
|
811
595
|
return this.setLoadingFalse(collection);
|
|
@@ -818,16 +602,10 @@ export class EntityCollectionReducerMethods {
|
|
|
818
602
|
* Therefore, update the entities in the collection with the returned values (if any)
|
|
819
603
|
* Caution: in a race, this update could overwrite unsaved user changes.
|
|
820
604
|
* Use pessimistic add to avoid this risk.
|
|
821
|
-
* @protected
|
|
822
|
-
* @param {?} collection
|
|
823
|
-
* @param {?} action
|
|
824
|
-
* @return {?}
|
|
825
605
|
*/
|
|
826
606
|
saveUpsertManySuccess(collection, action) {
|
|
827
607
|
// For pessimistic save, ensure the server generated the primary key if the client didn't send one.
|
|
828
|
-
/** @type {?} */
|
|
829
608
|
const entities = this.guard.mustBeEntities(action);
|
|
830
|
-
/** @type {?} */
|
|
831
609
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
832
610
|
// Always update the cache with upserted entities returned from server
|
|
833
611
|
collection = this.entityChangeTracker.mergeSaveUpserts(entities, collection, mergeStrategy);
|
|
@@ -840,206 +618,90 @@ export class EntityCollectionReducerMethods {
|
|
|
840
618
|
* Replaces all entities in the collection
|
|
841
619
|
* Sets loaded flag to true.
|
|
842
620
|
* Merges query results, preserving unsaved changes
|
|
843
|
-
* @protected
|
|
844
|
-
* @param {?} collection
|
|
845
|
-
* @param {?} action
|
|
846
|
-
* @return {?}
|
|
847
621
|
*/
|
|
848
622
|
addAll(collection, action) {
|
|
849
|
-
/** @type {?} */
|
|
850
623
|
const entities = this.guard.mustBeEntities(action);
|
|
851
624
|
return Object.assign(Object.assign({}, this.adapter.setAll(entities, collection)), { loading: false, loaded: true, changeState: {} });
|
|
852
625
|
}
|
|
853
|
-
/**
|
|
854
|
-
* @protected
|
|
855
|
-
* @param {?} collection
|
|
856
|
-
* @param {?} action
|
|
857
|
-
* @return {?}
|
|
858
|
-
*/
|
|
859
626
|
addMany(collection, action) {
|
|
860
|
-
/** @type {?} */
|
|
861
627
|
const entities = this.guard.mustBeEntities(action);
|
|
862
|
-
/** @type {?} */
|
|
863
628
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
864
629
|
collection = this.entityChangeTracker.trackAddMany(entities, collection, mergeStrategy);
|
|
865
630
|
return this.adapter.addMany(entities, collection);
|
|
866
631
|
}
|
|
867
|
-
/**
|
|
868
|
-
* @protected
|
|
869
|
-
* @param {?} collection
|
|
870
|
-
* @param {?} action
|
|
871
|
-
* @return {?}
|
|
872
|
-
*/
|
|
873
632
|
addOne(collection, action) {
|
|
874
|
-
/** @type {?} */
|
|
875
633
|
const entity = this.guard.mustBeEntity(action);
|
|
876
|
-
/** @type {?} */
|
|
877
634
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
878
635
|
collection = this.entityChangeTracker.trackAddOne(entity, collection, mergeStrategy);
|
|
879
636
|
return this.adapter.addOne(entity, collection);
|
|
880
637
|
}
|
|
881
|
-
/**
|
|
882
|
-
* @protected
|
|
883
|
-
* @param {?} collection
|
|
884
|
-
* @param {?} action
|
|
885
|
-
* @return {?}
|
|
886
|
-
*/
|
|
887
638
|
removeMany(collection, action) {
|
|
888
639
|
// payload must be entity keys
|
|
889
|
-
|
|
890
|
-
const keys = (/** @type {?} */ (this.guard.mustBeKeys(action)));
|
|
891
|
-
/** @type {?} */
|
|
640
|
+
const keys = this.guard.mustBeKeys(action);
|
|
892
641
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
893
642
|
collection = this.entityChangeTracker.trackDeleteMany(keys, collection, mergeStrategy);
|
|
894
643
|
return this.adapter.removeMany(keys, collection);
|
|
895
644
|
}
|
|
896
|
-
/**
|
|
897
|
-
* @protected
|
|
898
|
-
* @param {?} collection
|
|
899
|
-
* @param {?} action
|
|
900
|
-
* @return {?}
|
|
901
|
-
*/
|
|
902
645
|
removeOne(collection, action) {
|
|
903
646
|
// payload must be entity key
|
|
904
|
-
|
|
905
|
-
const key = (/** @type {?} */ (this.guard.mustBeKey(action)));
|
|
906
|
-
/** @type {?} */
|
|
647
|
+
const key = this.guard.mustBeKey(action);
|
|
907
648
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
908
649
|
collection = this.entityChangeTracker.trackDeleteOne(key, collection, mergeStrategy);
|
|
909
650
|
return this.adapter.removeOne(key, collection);
|
|
910
651
|
}
|
|
911
|
-
/**
|
|
912
|
-
* @protected
|
|
913
|
-
* @param {?} collection
|
|
914
|
-
* @param {?} action
|
|
915
|
-
* @return {?}
|
|
916
|
-
*/
|
|
917
652
|
removeAll(collection, action) {
|
|
918
653
|
return Object.assign(Object.assign({}, this.adapter.removeAll(collection)), { loaded: false, loading: false, changeState: {} });
|
|
919
654
|
}
|
|
920
|
-
/**
|
|
921
|
-
* @protected
|
|
922
|
-
* @param {?} collection
|
|
923
|
-
* @param {?} action
|
|
924
|
-
* @return {?}
|
|
925
|
-
*/
|
|
926
655
|
updateMany(collection, action) {
|
|
927
656
|
// payload must be an array of `Updates<T>`, not entities
|
|
928
|
-
/** @type {?} */
|
|
929
657
|
const updates = this.guard.mustBeUpdates(action);
|
|
930
|
-
/** @type {?} */
|
|
931
658
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
932
659
|
collection = this.entityChangeTracker.trackUpdateMany(updates, collection, mergeStrategy);
|
|
933
660
|
return this.adapter.updateMany(updates, collection);
|
|
934
661
|
}
|
|
935
|
-
/**
|
|
936
|
-
* @protected
|
|
937
|
-
* @param {?} collection
|
|
938
|
-
* @param {?} action
|
|
939
|
-
* @return {?}
|
|
940
|
-
*/
|
|
941
662
|
updateOne(collection, action) {
|
|
942
663
|
// payload must be an `Update<T>`, not an entity
|
|
943
|
-
/** @type {?} */
|
|
944
664
|
const update = this.guard.mustBeUpdate(action);
|
|
945
|
-
/** @type {?} */
|
|
946
665
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
947
666
|
collection = this.entityChangeTracker.trackUpdateOne(update, collection, mergeStrategy);
|
|
948
667
|
return this.adapter.updateOne(update, collection);
|
|
949
668
|
}
|
|
950
|
-
/**
|
|
951
|
-
* @protected
|
|
952
|
-
* @param {?} collection
|
|
953
|
-
* @param {?} action
|
|
954
|
-
* @return {?}
|
|
955
|
-
*/
|
|
956
669
|
upsertMany(collection, action) {
|
|
957
670
|
// <v6: payload must be an array of `Updates<T>`, not entities
|
|
958
671
|
// v6+: payload must be an array of T
|
|
959
|
-
/** @type {?} */
|
|
960
672
|
const entities = this.guard.mustBeEntities(action);
|
|
961
|
-
/** @type {?} */
|
|
962
673
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
963
674
|
collection = this.entityChangeTracker.trackUpsertMany(entities, collection, mergeStrategy);
|
|
964
675
|
return this.adapter.upsertMany(entities, collection);
|
|
965
676
|
}
|
|
966
|
-
/**
|
|
967
|
-
* @protected
|
|
968
|
-
* @param {?} collection
|
|
969
|
-
* @param {?} action
|
|
970
|
-
* @return {?}
|
|
971
|
-
*/
|
|
972
677
|
upsertOne(collection, action) {
|
|
973
678
|
// <v6: payload must be an `Update<T>`, not an entity
|
|
974
679
|
// v6+: payload must be a T
|
|
975
|
-
/** @type {?} */
|
|
976
680
|
const entity = this.guard.mustBeEntity(action);
|
|
977
|
-
/** @type {?} */
|
|
978
681
|
const mergeStrategy = this.extractMergeStrategy(action);
|
|
979
682
|
collection = this.entityChangeTracker.trackUpsertOne(entity, collection, mergeStrategy);
|
|
980
683
|
return this.adapter.upsertOne(entity, collection);
|
|
981
684
|
}
|
|
982
|
-
/**
|
|
983
|
-
* @protected
|
|
984
|
-
* @param {?} collection
|
|
985
|
-
* @return {?}
|
|
986
|
-
*/
|
|
987
685
|
commitAll(collection) {
|
|
988
686
|
return this.entityChangeTracker.commitAll(collection);
|
|
989
687
|
}
|
|
990
|
-
/**
|
|
991
|
-
* @protected
|
|
992
|
-
* @param {?} collection
|
|
993
|
-
* @param {?} action
|
|
994
|
-
* @return {?}
|
|
995
|
-
*/
|
|
996
688
|
commitMany(collection, action) {
|
|
997
689
|
return this.entityChangeTracker.commitMany(this.extractData(action), collection);
|
|
998
690
|
}
|
|
999
|
-
/**
|
|
1000
|
-
* @protected
|
|
1001
|
-
* @param {?} collection
|
|
1002
|
-
* @param {?} action
|
|
1003
|
-
* @return {?}
|
|
1004
|
-
*/
|
|
1005
691
|
commitOne(collection, action) {
|
|
1006
692
|
return this.entityChangeTracker.commitOne(this.extractData(action), collection);
|
|
1007
693
|
}
|
|
1008
|
-
/**
|
|
1009
|
-
* @protected
|
|
1010
|
-
* @param {?} collection
|
|
1011
|
-
* @return {?}
|
|
1012
|
-
*/
|
|
1013
694
|
undoAll(collection) {
|
|
1014
695
|
return this.entityChangeTracker.undoAll(collection);
|
|
1015
696
|
}
|
|
1016
|
-
/**
|
|
1017
|
-
* @protected
|
|
1018
|
-
* @param {?} collection
|
|
1019
|
-
* @param {?} action
|
|
1020
|
-
* @return {?}
|
|
1021
|
-
*/
|
|
1022
697
|
undoMany(collection, action) {
|
|
1023
698
|
return this.entityChangeTracker.undoMany(this.extractData(action), collection);
|
|
1024
699
|
}
|
|
1025
|
-
/**
|
|
1026
|
-
* @protected
|
|
1027
|
-
* @param {?} collection
|
|
1028
|
-
* @param {?} action
|
|
1029
|
-
* @return {?}
|
|
1030
|
-
*/
|
|
1031
700
|
undoOne(collection, action) {
|
|
1032
701
|
return this.entityChangeTracker.undoOne(this.extractData(action), collection);
|
|
1033
702
|
}
|
|
1034
|
-
/**
|
|
1035
|
-
* Dangerous: Completely replace the collection's ChangeState. Use rarely and wisely.
|
|
1036
|
-
* @protected
|
|
1037
|
-
* @param {?} collection
|
|
1038
|
-
* @param {?} action
|
|
1039
|
-
* @return {?}
|
|
1040
|
-
*/
|
|
703
|
+
/** Dangerous: Completely replace the collection's ChangeState. Use rarely and wisely. */
|
|
1041
704
|
setChangeState(collection, action) {
|
|
1042
|
-
/** @type {?} */
|
|
1043
705
|
const changeState = this.extractData(action);
|
|
1044
706
|
return collection.changeState === changeState
|
|
1045
707
|
? collection
|
|
@@ -1049,74 +711,33 @@ export class EntityCollectionReducerMethods {
|
|
|
1049
711
|
* Dangerous: Completely replace the collection.
|
|
1050
712
|
* Primarily for testing and rehydration from local storage.
|
|
1051
713
|
* Use rarely and wisely.
|
|
1052
|
-
* @protected
|
|
1053
|
-
* @param {?} collection
|
|
1054
|
-
* @param {?} action
|
|
1055
|
-
* @return {?}
|
|
1056
714
|
*/
|
|
1057
715
|
setCollection(collection, action) {
|
|
1058
|
-
/** @type {?} */
|
|
1059
716
|
const newCollection = this.extractData(action);
|
|
1060
717
|
return collection === newCollection ? collection : newCollection;
|
|
1061
718
|
}
|
|
1062
|
-
/**
|
|
1063
|
-
* @protected
|
|
1064
|
-
* @param {?} collection
|
|
1065
|
-
* @param {?} action
|
|
1066
|
-
* @return {?}
|
|
1067
|
-
*/
|
|
1068
719
|
setFilter(collection, action) {
|
|
1069
|
-
/** @type {?} */
|
|
1070
720
|
const filter = this.extractData(action);
|
|
1071
721
|
return collection.filter === filter
|
|
1072
722
|
? collection
|
|
1073
723
|
: Object.assign(Object.assign({}, collection), { filter });
|
|
1074
724
|
}
|
|
1075
|
-
/**
|
|
1076
|
-
* @protected
|
|
1077
|
-
* @param {?} collection
|
|
1078
|
-
* @param {?} action
|
|
1079
|
-
* @return {?}
|
|
1080
|
-
*/
|
|
1081
725
|
setLoaded(collection, action) {
|
|
1082
|
-
/** @type {?} */
|
|
1083
726
|
const loaded = this.extractData(action) === true || false;
|
|
1084
727
|
return collection.loaded === loaded
|
|
1085
728
|
? collection
|
|
1086
729
|
: Object.assign(Object.assign({}, collection), { loaded });
|
|
1087
730
|
}
|
|
1088
|
-
/**
|
|
1089
|
-
* @protected
|
|
1090
|
-
* @param {?} collection
|
|
1091
|
-
* @param {?} action
|
|
1092
|
-
* @return {?}
|
|
1093
|
-
*/
|
|
1094
731
|
setLoading(collection, action) {
|
|
1095
732
|
return this.setLoadingFlag(collection, this.extractData(action));
|
|
1096
733
|
}
|
|
1097
|
-
/**
|
|
1098
|
-
* @protected
|
|
1099
|
-
* @param {?} collection
|
|
1100
|
-
* @return {?}
|
|
1101
|
-
*/
|
|
1102
734
|
setLoadingFalse(collection) {
|
|
1103
735
|
return this.setLoadingFlag(collection, false);
|
|
1104
736
|
}
|
|
1105
|
-
/**
|
|
1106
|
-
* @protected
|
|
1107
|
-
* @param {?} collection
|
|
1108
|
-
* @return {?}
|
|
1109
|
-
*/
|
|
1110
737
|
setLoadingTrue(collection) {
|
|
1111
738
|
return this.setLoadingFlag(collection, true);
|
|
1112
739
|
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Set the collection's loading flag
|
|
1115
|
-
* @protected
|
|
1116
|
-
* @param {?} collection
|
|
1117
|
-
* @param {?} loading
|
|
1118
|
-
* @return {?}
|
|
1119
|
-
*/
|
|
740
|
+
/** Set the collection's loading flag */
|
|
1120
741
|
setLoadingFlag(collection, loading) {
|
|
1121
742
|
loading = loading === true ? true : false;
|
|
1122
743
|
return collection.loading === loading
|
|
@@ -1125,104 +746,31 @@ export class EntityCollectionReducerMethods {
|
|
|
1125
746
|
}
|
|
1126
747
|
// #endregion Cache-only operations
|
|
1127
748
|
// #region helpers
|
|
1128
|
-
/**
|
|
1129
|
-
* Safely extract data from the EntityAction payload
|
|
1130
|
-
* @protected
|
|
1131
|
-
* @template D
|
|
1132
|
-
* @param {?} action
|
|
1133
|
-
* @return {?}
|
|
1134
|
-
*/
|
|
749
|
+
/** Safely extract data from the EntityAction payload */
|
|
1135
750
|
extractData(action) {
|
|
1136
|
-
return (
|
|
751
|
+
return (action.payload && action.payload.data);
|
|
1137
752
|
}
|
|
1138
|
-
/**
|
|
1139
|
-
* Safely extract MergeStrategy from EntityAction. Set to IgnoreChanges if collection itself is not tracked.
|
|
1140
|
-
* @protected
|
|
1141
|
-
* @param {?} action
|
|
1142
|
-
* @return {?}
|
|
1143
|
-
*/
|
|
753
|
+
/** Safely extract MergeStrategy from EntityAction. Set to IgnoreChanges if collection itself is not tracked. */
|
|
1144
754
|
extractMergeStrategy(action) {
|
|
1145
755
|
// If not tracking this collection, always ignore changes
|
|
1146
756
|
return this.isChangeTracking
|
|
1147
757
|
? action.payload && action.payload.mergeStrategy
|
|
1148
758
|
: MergeStrategy.IgnoreChanges;
|
|
1149
759
|
}
|
|
1150
|
-
/**
|
|
1151
|
-
* @protected
|
|
1152
|
-
* @param {?} action
|
|
1153
|
-
* @return {?}
|
|
1154
|
-
*/
|
|
1155
760
|
isOptimistic(action) {
|
|
1156
761
|
return action.payload && action.payload.isOptimistic === true;
|
|
1157
762
|
}
|
|
1158
763
|
}
|
|
1159
|
-
if (false) {
|
|
1160
|
-
/**
|
|
1161
|
-
* @type {?}
|
|
1162
|
-
* @protected
|
|
1163
|
-
*/
|
|
1164
|
-
EntityCollectionReducerMethods.prototype.adapter;
|
|
1165
|
-
/**
|
|
1166
|
-
* @type {?}
|
|
1167
|
-
* @protected
|
|
1168
|
-
*/
|
|
1169
|
-
EntityCollectionReducerMethods.prototype.guard;
|
|
1170
|
-
/**
|
|
1171
|
-
* True if this collection tracks unsaved changes
|
|
1172
|
-
* @type {?}
|
|
1173
|
-
* @protected
|
|
1174
|
-
*/
|
|
1175
|
-
EntityCollectionReducerMethods.prototype.isChangeTracking;
|
|
1176
|
-
/**
|
|
1177
|
-
* Extract the primary key (id); default to `id`
|
|
1178
|
-
* @type {?}
|
|
1179
|
-
*/
|
|
1180
|
-
EntityCollectionReducerMethods.prototype.selectId;
|
|
1181
|
-
/**
|
|
1182
|
-
* Track changes to entities since the last query or save
|
|
1183
|
-
* Can revert some or all of those changes
|
|
1184
|
-
* @type {?}
|
|
1185
|
-
*/
|
|
1186
|
-
EntityCollectionReducerMethods.prototype.entityChangeTracker;
|
|
1187
|
-
/**
|
|
1188
|
-
* Convert an entity (or partial entity) into the `Update<T>` object
|
|
1189
|
-
* `id`: the primary key and
|
|
1190
|
-
* `changes`: the entity (or partial entity of changes).
|
|
1191
|
-
* @type {?}
|
|
1192
|
-
* @protected
|
|
1193
|
-
*/
|
|
1194
|
-
EntityCollectionReducerMethods.prototype.toUpdate;
|
|
1195
|
-
/**
|
|
1196
|
-
* Dictionary of the {EntityCollectionReducerMethods} for this entity type,
|
|
1197
|
-
* keyed by the {EntityOp}
|
|
1198
|
-
* @type {?}
|
|
1199
|
-
*/
|
|
1200
|
-
EntityCollectionReducerMethods.prototype.methods;
|
|
1201
|
-
/** @type {?} */
|
|
1202
|
-
EntityCollectionReducerMethods.prototype.entityName;
|
|
1203
|
-
/** @type {?} */
|
|
1204
|
-
EntityCollectionReducerMethods.prototype.definition;
|
|
1205
|
-
}
|
|
1206
764
|
/**
|
|
1207
765
|
* Creates {EntityCollectionReducerMethods} for a given entity type.
|
|
1208
766
|
*/
|
|
1209
767
|
export class EntityCollectionReducerMethodsFactory {
|
|
1210
|
-
/**
|
|
1211
|
-
* @param {?} entityDefinitionService
|
|
1212
|
-
*/
|
|
1213
768
|
constructor(entityDefinitionService) {
|
|
1214
769
|
this.entityDefinitionService = entityDefinitionService;
|
|
1215
770
|
}
|
|
1216
|
-
/**
|
|
1217
|
-
* Create the {EntityCollectionReducerMethods} for the named entity type
|
|
1218
|
-
* @template T
|
|
1219
|
-
* @param {?} entityName
|
|
1220
|
-
* @return {?}
|
|
1221
|
-
*/
|
|
771
|
+
/** Create the {EntityCollectionReducerMethods} for the named entity type */
|
|
1222
772
|
create(entityName) {
|
|
1223
|
-
/** @type {?} */
|
|
1224
773
|
const definition = this.entityDefinitionService.getDefinition(entityName);
|
|
1225
|
-
/** @type {?} */
|
|
1226
774
|
const methodsClass = new EntityCollectionReducerMethods(entityName, definition);
|
|
1227
775
|
return methodsClass.methods;
|
|
1228
776
|
}
|
|
@@ -1234,11 +782,4 @@ EntityCollectionReducerMethodsFactory.decorators = [
|
|
|
1234
782
|
EntityCollectionReducerMethodsFactory.ctorParameters = () => [
|
|
1235
783
|
{ type: EntityDefinitionService }
|
|
1236
784
|
];
|
|
1237
|
-
if (false) {
|
|
1238
|
-
/**
|
|
1239
|
-
* @type {?}
|
|
1240
|
-
* @private
|
|
1241
|
-
*/
|
|
1242
|
-
EntityCollectionReducerMethodsFactory.prototype.entityDefinitionService;
|
|
1243
|
-
}
|
|
1244
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWNvbGxlY3Rpb24tcmVkdWNlci1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uLy4uL21vZHVsZXMvZGF0YS8iLCJzb3VyY2VzIjpbInNyYy9yZWR1Y2Vycy9lbnRpdHktY29sbGVjdGlvbi1yZWR1Y2VyLW1ldGhvZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFFTCxVQUFVLEdBRVgsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHbkUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7Ozs7OztBQU8xRCxzREFLQzs7Ozs7QUFLRCxNQUFNLE9BQU8sOEJBQThCOzs7Ozs7SUErR3pDLFlBQ1MsVUFBa0IsRUFDbEIsVUFBK0I7SUFDdEM7OztPQUdHO0lBQ0gsbUJBQTRDO1FBTnJDLGVBQVUsR0FBVixVQUFVLENBQVE7UUFDbEIsZUFBVSxHQUFWLFVBQVUsQ0FBcUI7Ozs7O1FBdkYvQixZQUFPLEdBQXdDO1lBQ3RELENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUV4RCxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDOUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFD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QUksQ0FBQyxJQUFJLENBQUM7Ozs7O1lBUXhFLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMxQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDbEQsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRWhELENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNsRCxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFaEQsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2xELENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUVoRCxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDaEQsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxD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R1Msb0JBQW9CLENBQUMsTUFBb0I7UUFDakQseURBQXlEO1FBQ3pELE9BQU8sSUFBSSxDQUFDLGdCQUFnQjtZQUMxQixDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWE7WUFDaEQsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUM7SUFDbEMsQ0FBQzs7Ozs7O0lBRVMsWUFBWSxDQUFDLE1BQW9CO1FBQ3pDLE9BQU8sTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUM7SUFDaEUsQ0FBQztDQUdGOzs7Ozs7SUFscUNDLGlEQUFvQzs7Ozs7SUFDcEMsK0NBQXNDOzs7Ozs7SUFFdEMsMERBQW9DOzs7OztJQUdwQyxrREFBd0I7Ozs7OztJQU14Qiw2REFBNEM7Ozs7Ozs7O0lBTzVDLGtEQUFzRDs7Ozs7O0lBTXRELGlEQW1GRTs7SUFHQSxvREFBeUI7O0lBQ3pCLG9EQUFzQzs7Ozs7QUF3akMxQyxNQUFNLE9BQU8scUNBQXFDOzs7O0lBQ2hELFlBQW9CLHVCQUFnRDtRQUFoRCw0QkFBdUIsR0FBdkIsdUJBQXVCLENBQXlCO0lBQUcsQ0FBQzs7Ozs7OztJQUd4RSxNQUFNLENBQUksVUFBa0I7O2NBQ3BCLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUMzRCxVQUFVLENBQ1g7O2NBQ0ssWUFBWSxHQUFHLElBQUksOEJBQThCLENBQ3JELFVBQVUsRUFDVixVQUFVLENBQ1g7UUFFRCxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUM7SUFDOUIsQ0FBQzs7O1lBZkYsVUFBVTs7OztZQTNyQ0YsdUJBQXVCOzs7Ozs7O0lBNnJDbEIsd0VBQXdEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRW50aXR5QWRhcHRlciwgSWRTZWxlY3RvciwgVXBkYXRlIH0gZnJvbSAnQG5ncngvZW50aXR5JztcbmltcG9ydCB7XG4gIENoYW5nZVN0YXRlTWFwLFxuICBDaGFuZ2VUeXBlLFxuICBFbnRpdHlDb2xsZWN0aW9uLFxufSBmcm9tICcuL2VudGl0eS1jb2xsZWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUNoYW5nZVRyYWNrZXJCYXNlIH0gZnJvbSAnLi9lbnRpdHktY2hhbmdlLXRyYWNrZXItYmFzZSc7XG5pbXBvcnQgeyB0b1VwZGF0ZUZhY3RvcnkgfSBmcm9tICcuLi91dGlscy91dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5QWN0aW9uIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3IgfSBmcm9tICcuLi9kYXRhc2VydmljZXMvZGF0YS1zZXJ2aWNlLWVycm9yJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbkd1YXJkIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uLWd1YXJkJztcbmltcG9ydCB7IEVudGl0eUNoYW5nZVRyYWNrZXIgfSBmcm9tICcuL2VudGl0eS1jaGFuZ2UtdHJhY2tlcic7XG5pbXBvcnQgeyBFbnRpdHlEZWZpbml0aW9uIH0gZnJvbSAnLi4vZW50aXR5LW1ldGFkYXRhL2VudGl0eS1kZWZpbml0aW9uJztcbmltcG9ydCB7IEVudGl0eURlZmluaXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vZW50aXR5LW1ldGFkYXRhL2VudGl0eS1kZWZpbml0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgRW50aXR5T3AgfSBmcm9tICcuLi9hY3Rpb25zL2VudGl0eS1vcCc7XG5pbXBvcnQgeyBNZXJnZVN0cmF0ZWd5IH0gZnJvbSAnLi4vYWN0aW9ucy9tZXJnZS1zdHJhdGVneSc7XG5pbXBvcnQgeyBVcGRhdGVSZXNwb25zZURhdGEgfSBmcm9tICcuLi9hY3Rpb25zL3VwZGF0ZS1yZXNwb25zZS1kYXRhJztcblxuLyoqXG4gKiBNYXAgb2Yge0VudGl0eU9wfSB0byByZWR1Y2VyIG1ldGhvZCBmb3IgdGhlIG9wZXJhdGlvbi5cbiAqIElmIGFuIG9wZXJhdGlvbiBpcyBtaXNzaW5nLCBjYWxsZXIgc2hvdWxkIHJldHVybiB0aGUgY29sbGVjdGlvbiBmb3IgdGhhdCByZWR1Y2VyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kTWFwPFQ+IHtcbiAgW21ldGhvZDogc3RyaW5nXTogKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb25cbiAgKSA9PiBFbnRpdHlDb2xsZWN0aW9uPFQ+O1xufVxuXG4vKipcbiAqIEJhc2UgaW1wbGVtZW50YXRpb24gb2YgcmVkdWNlciBtZXRob2RzIGZvciBhbiBlbnRpdHkgY29sbGVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kczxUPiB7XG4gIHByb3RlY3RlZCBhZGFwdGVyOiBFbnRpdHlBZGFwdGVyPFQ+O1xuICBwcm90ZWN0ZWQgZ3VhcmQ6IEVudGl0eUFjdGlvbkd1YXJkPFQ+O1xuICAvKiogVHJ1ZSBpZiB0aGlzIGNvbGxlY3Rpb24gdHJhY2tzIHVuc2F2ZWQgY2hhbmdlcyAqL1xuICBwcm90ZWN0ZWQgaXNDaGFuZ2VUcmFja2luZzogYm9vbGVhbjtcblxuICAvKiogRXh0cmFjdCB0aGUgcHJpbWFyeSBrZXkgKGlkKTsgZGVmYXVsdCB0byBgaWRgICovXG4gIHNlbGVjdElkOiBJZFNlbGVjdG9yPFQ+O1xuXG4gIC8qKlxuICAgKiBUcmFjayBjaGFuZ2VzIHRvIGVudGl0aWVzIHNpbmNlIHRoZSBsYXN0IHF1ZXJ5IG9yIHNhdmVcbiAgICogQ2FuIHJldmVydCBzb21lIG9yIGFsbCBvZiB0aG9zZSBjaGFuZ2VzXG4gICAqL1xuICBlbnRpdHlDaGFuZ2VUcmFja2VyOiBFbnRpdHlDaGFuZ2VUcmFja2VyPFQ+O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkpIGludG8gdGhlIGBVcGRhdGU8VD5gIG9iamVjdFxuICAgKiBgaWRgOiB0aGUgcHJpbWFyeSBrZXkgYW5kXG4gICAqIGBjaGFuZ2VzYDogdGhlIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkgb2YgY2hhbmdlcykuXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9VcGRhdGU6IChlbnRpdHk6IFBhcnRpYWw8VD4pID0+IFVwZGF0ZTxUPjtcblxuICAvKipcbiAgICogRGljdGlvbmFyeSBvZiB0aGUge0VudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc30gZm9yIHRoaXMgZW50aXR5IHR5cGUsXG4gICAqIGtleWVkIGJ5IHRoZSB7RW50aXR5T3B9XG4gICAqL1xuICByZWFkb25seSBtZXRob2RzOiBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZE1hcDxUPiA9IHtcbiAgICBbRW50aXR5T3AuQ0FOQ0VMX1BFUlNJU1RdOiB0aGlzLmNhbmNlbFBlcnNpc3QuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5RVUVSWV9BTExdOiB0aGlzLnF1ZXJ5QWxsLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0FMTF9FUlJPUl06IHRoaXMucXVlcnlBbGxFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9BTExfU1VDQ0VTU106IHRoaXMucXVlcnlBbGxTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuUVVFUllfQllfS0VZXTogdGhpcy5xdWVyeUJ5S2V5LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0JZX0tFWV9FUlJPUl06IHRoaXMucXVlcnlCeUtleUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0JZX0tFWV9TVUNDRVNTXTogdGhpcy5xdWVyeUJ5S2V5U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlFVRVJZX0xPQURdOiB0aGlzLnF1ZXJ5TG9hZC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9MT0FEX0VSUk9SXTogdGhpcy5xdWVyeUxvYWRFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9MT0FEX1NVQ0NFU1NdOiB0aGlzLnF1ZXJ5TG9hZFN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5RVUVSWV9NQU5ZXTogdGhpcy5xdWVyeU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTUFOWV9FUlJPUl06IHRoaXMucXVlcnlNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTUFOWV9TVUNDRVNTXTogdGhpcy5xdWVyeU1hbnlTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9BRERfTUFOWV06IHRoaXMuc2F2ZUFkZE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9BRERfTUFOWV9FUlJPUl06IHRoaXMuc2F2ZUFkZE1hbnlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9NQU5ZX1NVQ0NFU1NdOiB0aGlzLnNhdmVBZGRNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfQUREX09ORV06IHRoaXMuc2F2ZUFkZE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9PTkVfRVJST1JdOiB0aGlzLnNhdmVBZGRPbmVFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9PTkVfU1VDQ0VTU106IHRoaXMuc2F2ZUFkZE9uZVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9NQU5ZXTogdGhpcy5zYXZlRGVsZXRlTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9NQU5ZX0VSUk9SXTogdGhpcy5zYXZlRGVsZXRlTWFueUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX01BTllfU1VDQ0VTU106IHRoaXMuc2F2ZURlbGV0ZU1hbnlTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9ERUxFVEVfT05FXTogdGhpcy5zYXZlRGVsZXRlT25lLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX09ORV9FUlJPUl06IHRoaXMuc2F2ZURlbGV0ZU9uZUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX09ORV9TVUNDRVNTXTogdGhpcy5zYXZlRGVsZXRlT25lU3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX01BTlldOiB0aGlzLnNhdmVVcGRhdGVNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX01BTllfRVJST1JdOiB0aGlzLnNhdmVVcGRhdGVNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfTUFOWV9TVUNDRVNTXTogdGhpcy5zYXZlVXBkYXRlTWFueVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX1VQREFURV9PTkVdOiB0aGlzLnNhdmVVcGRhdGVPbmUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfT05FX0VSUk9SXTogdGhpcy5zYXZlVXBkYXRlT25lRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfT05FX1NVQ0NFU1NdOiB0aGlzLnNhdmVVcGRhdGVPbmVTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfTUFOWV06IHRoaXMuc2F2ZVVwc2VydE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfTUFOWV9FUlJPUl06IHRoaXMuc2F2ZVVwc2VydE1hbnlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9NQU5ZX1NVQ0NFU1NdOiB0aGlzLnNhdmVVcHNlcnRNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfVVBTRVJUX09ORV06IHRoaXMuc2F2ZVVwc2VydE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkVfRVJST1JdOiB0aGlzLnNhdmVVcHNlcnRPbmVFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkVfU1VDQ0VTU106IHRoaXMuc2F2ZVVwc2VydE9uZVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIC8vIERvIG5vdGhpbmcgb24gc2F2ZSBlcnJvcnMgZXhjZXB0IHR1cm4gdGhlIGxvYWRpbmcgZmxhZyBvZmYuXG4gICAgLy8gU2VlIHRoZSBDaGFuZ2VUcmFja2VyTWV0YVJlZHVjZXJzXG4gICAgLy8gT3IgdGhlIGFwcCBjb3VsZCBsaXN0ZW4gZm9yIHRob3NlIGVycm9ycyBhbmQgZG8gc29tZXRoaW5nXG5cbiAgICAvLy8gY2FjaGUgb25seSBvcGVyYXRpb25zIC8vL1xuXG4gICAgW0VudGl0eU9wLkFERF9BTExdOiB0aGlzLmFkZEFsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5BRERfTUFOWV06IHRoaXMuYWRkTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5BRERfT05FXTogdGhpcy5hZGRPbmUuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5SRU1PVkVfQUxMXTogdGhpcy5yZW1vdmVBbGwuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUkVNT1ZFX01BTlldOiB0aGlzLnJlbW92ZU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUkVNT1ZFX09ORV06IHRoaXMucmVtb3ZlT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuVVBEQVRFX01BTlldOiB0aGlzLnVwZGF0ZU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVVBEQVRFX09ORV06IHRoaXMudXBkYXRlT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuVVBTRVJUX01BTlldOiB0aGlzLnVwc2VydE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVVBTRVJUX09ORV06IHRoaXMudXBzZXJ0T25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuQ09NTUlUX0FMTF06IHRoaXMuY29tbWl0QWxsLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLkNPTU1JVF9NQU5ZXTogdGhpcy5jb21taXRNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLkNPTU1JVF9PTkVdOiB0aGlzLmNvbW1pdE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5VTkRPX0FMTF06IHRoaXMudW5kb0FsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5VTkRPX01BTlldOiB0aGlzLnVuZG9NYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlVORE9fT05FXTogdGhpcy51bmRvT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0VUX0NIQU5HRV9TVEFURV06IHRoaXMuc2V0Q2hhbmdlU3RhdGUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0VUX0NPTExFQ1RJT05dOiB0aGlzLnNldENvbGxlY3Rpb24uYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0VUX0ZJTFRFUl06IHRoaXMuc2V0RmlsdGVyLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNFVF9MT0FERURdOiB0aGlzLnNldExvYWRlZC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TRVRfTE9BRElOR106IHRoaXMuc2V0TG9hZGluZy5iaW5kKHRoaXMpLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgcHVibGljIGRlZmluaXRpb246IEVudGl0eURlZmluaXRpb248VD4sXG4gICAgLypcbiAgICAgKiBUcmFjayBjaGFuZ2VzIHRvIGVudGl0aWVzIHNpbmNlIHRoZSBsYXN0IHF1ZXJ5IG9yIHNhdmVcbiAgICAgKiBDYW4gcmV2ZXJ0IHNvbWUgb3IgYWxsIG9mIHRob3NlIGNoYW5nZXNcbiAgICAgKi9cbiAgICBlbnRpdHlDaGFuZ2VUcmFja2VyPzogRW50aXR5Q2hhbmdlVHJhY2tlcjxUPlxuICApIHtcbiAgICB0aGlzLmFkYXB0ZXIgPSBkZWZpbml0aW9uLmVudGl0eUFkYXB0ZXI7XG4gICAgdGhpcy5pc0NoYW5nZVRyYWNraW5nID0gZGVmaW5pdGlvbi5ub0NoYW5nZVRyYWNraW5nICE9PSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0SWQgPSBkZWZpbml0aW9uLnNlbGVjdElkO1xuXG4gICAgdGhpcy5ndWFyZCA9IG5ldyBFbnRpdHlBY3Rpb25HdWFyZChlbnRpdHlOYW1lLCB0aGlzLnNlbGVjdElkKTtcbiAgICB0aGlzLnRvVXBkYXRlID0gdG9VcGRhdGVGYWN0b3J5KHRoaXMuc2VsZWN0SWQpO1xuXG4gICAgdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyID1cbiAgICAgIGVudGl0eUNoYW5nZVRyYWNrZXIgfHxcbiAgICAgIG5ldyBFbnRpdHlDaGFuZ2VUcmFja2VyQmFzZTxUPih0aGlzLmFkYXB0ZXIsIHRoaXMuc2VsZWN0SWQpO1xuICB9XG5cbiAgLyoqIENhbmNlbCBhIHBlcnNpc3RlbmNlIG9wZXJhdGlvbiAqL1xuICBwcm90ZWN0ZWQgY2FuY2VsUGVyc2lzdChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8vICNyZWdpb24gcXVlcnkgb3BlcmF0aW9uc1xuXG4gIHByb3RlY3RlZCBxdWVyeUFsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlBbGxFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgcXVlcnkgcmVzdWx0cyBwZXIgdGhlIE1lcmdlU3RyYXRlZ3lcbiAgICogU2V0cyBsb2FkaW5nIGZsYWcgdG8gZmFsc2UgYW5kIGxvYWRlZCBmbGFnIHRvIHRydWUuXG4gICAqL1xuICBwcm90ZWN0ZWQgcXVlcnlBbGxTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKSxcbiAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlCeUtleShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlciB8IHN0cmluZz5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlCeUtleUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5QnlLZXlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPVxuICAgICAgZGF0YSA9PSBudWxsXG4gICAgICAgID8gY29sbGVjdGlvblxuICAgICAgICA6IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgICAgIFtkYXRhXSxcbiAgICAgICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlMb2FkKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4pOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeUxvYWRFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICogU2V0cyBsb2FkZWQgZmxhZyB0byB0cnVlLCBsb2FkaW5nIGZsYWcgdG8gZmFsc2UsXG4gICAqIGFuZCBjbGVhcnMgY2hhbmdlU3RhdGUgZm9yIHRoZSBlbnRpcmUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBxdWVyeUxvYWRTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmFkYXB0ZXIuc2V0QWxsKGRhdGEsIGNvbGxlY3Rpb24pLFxuICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICBjaGFuZ2VTdGF0ZToge30sXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvblxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKSxcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBxdWVyeSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBzYXZlIG9wZXJhdGlvbnNcblxuICAvLyAjcmVnaW9uIHNhdmVBZGRNYW55XG4gIC8qKlxuICAgKiBTYXZlIG11bHRpcGxlIG5ldyBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgZGVsYXkgYWRkaW5nIHRvIGNvbGxlY3Rpb24gdW50aWwgc2VydmVyIGFja25vd2xlZGdlcyBzdWNjZXNzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHk7IGFkZCBpbW1lZGlhdGVseS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gd2hpY2ggdGhlIGVudGl0aWVzIHNob3VsZCBiZSBhZGRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGFycmF5IG9mIGVudGl0aWVzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBtdXN0IGhhdmUgdGhlaXIga2V5cy5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkTWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdGllcyhhY3Rpb24pOyAvLyBlbnN1cmUgdGhlIGVudGl0eSBoYXMgYSBQS1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tBZGRNYW55KFxuICAgICAgICBlbnRpdGllcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIuYWRkTWFueShlbnRpdGllcywgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc2F2ZSBuZXcgZW50aXRpZXMgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBuZXcgZW50aXRpZXMgYXJlIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgdW5zYXZlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVBZGRNYW55XG5cbiAgLy8gI3JlZ2lvbiBzYXZlQWRkT25lXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgbmV3IGVudGl0aWVzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgYWRkIHRoZSBlbnRpdGllcyBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgYWRkZWQgZW50aXRpZXMgYXJlIGFscmVhZHkgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKSxcbiAgICogYW5kIG1heSBldmVuIHJldHVybiBhZGRpdGlvbmFsIG5ldyBlbnRpdGllcy5cbiAgICogVGhlcmVmb3JlLCB1cHNlcnQgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIGFkZCB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqIE5vdGU6IHNhdmVBZGRNYW55U3VjY2VzcyBkaWZmZXJzIGZyb20gc2F2ZUFkZE9uZVN1Y2Nlc3Mgd2hlbiBvcHRpbWlzdGljLlxuICAgKiBzYXZlQWRkT25lU3VjY2VzcyB1cGRhdGVzIChub3QgdXBzZXJ0cykgd2l0aCB0aGUgbG9uZSBlbnRpdHkgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBUaGVyZSBpcyBubyBlZmZlY3QgaWYgdGhlIGVudGl0eSBpcyBub3QgYWxyZWFkeSBpbiBjYWNoZS5cbiAgICogc2F2ZUFkZE1hbnlTdWNjZXNzIHdpbGwgYWRkIGFuIGVudGl0eSBpZiBpdCBpcyBub3QgZm91bmQgaW4gY2FjaGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApIHtcbiAgICAvLyBGb3IgcGVzc2ltaXN0aWMgc2F2ZSwgZW5zdXJlIHRoZSBzZXJ2ZXIgZ2VuZXJhdGVkIHRoZSBwcmltYXJ5IGtleSBpZiB0aGUgY2xpZW50IGRpZG4ndCBzZW5kIG9uZS5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICAgIGVudGl0aWVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZUFkZHMoXG4gICAgICAgIGVudGl0aWVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlQWRkTWFueVxuXG4gIC8vICNyZWdpb24gc2F2ZUFkZE9uZVxuICAvKipcbiAgICogU2F2ZSBhIG5ldyBlbnRpdHkuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIGRlbGF5IGFkZGluZyB0byBjb2xsZWN0aW9uIHVudGlsIHNlcnZlciBhY2tub3dsZWRnZXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5OyBhZGQgZW50aXR5IGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB3aGljaCB0aGUgZW50aXR5IHNob3VsZCBiZSBhZGRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IG11c3QgaGF2ZSBhIGtleS5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7IC8vIGVuc3VyZSB0aGUgZW50aXR5IGhhcyBhIFBLXG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0FkZE9uZShcbiAgICAgICAgZW50aXR5LFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5hZGRPbmUoZW50aXR5LCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBzYXZlIGEgbmV3IGVudGl0eSBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgaXMgbm90IGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSB1bnNhdmVkIGVudGl0eSBpcyBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkT25lRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIGEgbmV3IGVudGl0eSB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGFkZCB0aGUgZW50aXR5IGZyb20gdGhlIHNlcnZlciB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBhZGRlZCBlbnRpdHkgaXMgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCB0aGUgcmV0dXJuZWQgdmFsdWUgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVBZGRPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCB1cGRhdGU6IFVwZGF0ZVJlc3BvbnNlRGF0YTxUPiA9IHRoaXMudG9VcGRhdGUoZW50aXR5KTtcbiAgICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggYWRkZWQgZW50aXR5IHJldHVybmVkIGZyb20gc2VydmVyXG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwZGF0ZXMoXG4gICAgICAgIFt1cGRhdGVdLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5LFxuICAgICAgICBmYWxzZSAvKm5ldmVyIHNraXAqL1xuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVBZGRzKFxuICAgICAgICBbZW50aXR5XSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZUFkZE9uZVxuXG4gIC8vICNyZWdpb24gc2F2ZUFkZE1hbnlcbiAgLy8gVE9ETyBNQU5ZXG4gIC8vICNlbmRyZWdpb24gc2F2ZUFkZE1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVEZWxldGVPbmVcbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBlbnRpdHkgZnJvbSB0aGUgc2VydmVyIGJ5IGtleSBhbmQgcmVtb3ZlIGl0IGZyb20gdGhlIGNvbGxlY3Rpb24gKGlmIHByZXNlbnQpLlxuICAgKiBJZiB0aGUgZW50aXR5IGlzIGFuIHVuc2F2ZWQgbmV3IGVudGl0eSwgcmVtb3ZlIGl0IGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHlcbiAgICogYW5kIHNraXAgdGhlIHNlcnZlciBkZWxldGUgcmVxdWVzdC5cbiAgICogQW4gb3B0aW1pc3RpYyBzYXZlIHJlbW92ZXMgYW4gZXhpc3RpbmcgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHk7XG4gICAqIGEgcGVzc2ltaXN0aWMgc2F2ZSByZW1vdmVzIGl0IGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzc2Z1bCBkZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFdpbGwgcmVtb3ZlIHRoZSBlbnRpdHkgd2l0aCB0aGlzIGtleSBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgd2hldGhlciB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEsIHdoaWNoIG11c3QgYmUgYSBwcmltYXJ5IGtleSBvciBhbiBlbnRpdHkgd2l0aCBhIGtleTtcbiAgICogdGhpcyByZWR1Y2VyIGV4dHJhY3RzIHRoZSBrZXkgZnJvbSB0aGUgZW50aXR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVEZWxldGVPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxudW1iZXIgfCBzdHJpbmcgfCBUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB0b0RlbGV0ZSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBkZWxldGVJZCA9XG4gICAgICB0eXBlb2YgdG9EZWxldGUgPT09ICdvYmplY3QnXG4gICAgICAgID8gdGhpcy5zZWxlY3RJZCh0b0RlbGV0ZSlcbiAgICAgICAgOiAodG9EZWxldGUgYXMgc3RyaW5nIHwgbnVtYmVyKTtcbiAgICBjb25zdCBjaGFuZ2UgPSBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlW2RlbGV0ZUlkXTtcbiAgICAvLyBJZiBlbnRpdHkgaXMgYWxyZWFkeSB0cmFja2VkIC4uLlxuICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgIGlmIChjaGFuZ2UuY2hhbmdlVHlwZSA9PT0gQ2hhbmdlVHlwZS5BZGRlZCkge1xuICAgICAgICAvLyBSZW1vdmUgdGhlIGFkZGVkIGVudGl0eSBpbW1lZGlhdGVseSBhbmQgZm9yZ2V0IGFib3V0IGl0cyBjaGFuZ2VzICh2aWEgY29tbWl0KS5cbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVPbmUoZGVsZXRlSWQgYXMgc3RyaW5nLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoZGVsZXRlSWQsIGNvbGxlY3Rpb24pO1xuICAgICAgICAvLyBTaG91bGQgbm90IHdhc3RlIGVmZm9ydCB0cnlpbmcgdG8gZGVsZXRlIG9uIHRoZSBzZXJ2ZXIgYmVjYXVzZSBpdCBjYW4ndCBiZSB0aGVyZS5cbiAgICAgICAgYWN0aW9uLnBheWxvYWQuc2tpcCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZS10cmFjayBpdCBhcyBhIGRlbGV0ZSwgZXZlbiBpZiB0cmFja2luZyBpcyB0dXJuZWQgb2ZmIGZvciB0aGlzIGNhbGwuXG4gICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVPbmUoXG4gICAgICAgICAgZGVsZXRlSWQsXG4gICAgICAgICAgY29sbGVjdGlvblxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG9wdGltaXN0aWMgZGVsZXRlLCB0cmFjayBjdXJyZW50IHN0YXRlIGFuZCByZW1vdmUgaW1tZWRpYXRlbHkuXG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlT25lKFxuICAgICAgICBkZWxldGVJZCxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBkZWxldGUgdGhlIGVudGl0eSBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0eSBjb3VsZCBzdGlsbCBiZSBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlT25lRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgZW50aXR5IG9uIHRoZSBzZXJ2ZXIuIFRoZSBrZXkgb2YgdGhlIGRlbGV0ZWQgZW50aXR5IGlzIGluIHRoZSBhY3Rpb24gcGF5bG9hZCBkYXRhLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGlmIHRoZSBlbnRpdHkgaXMgc3RpbGwgaW4gdGhlIGNvbGxlY3Rpb24gaXQgd2lsbCBiZSByZW1vdmVkLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0eSBoYXMgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlT25lU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlciB8IHN0cmluZz5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGVsZXRlSWQgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZURlbGV0ZXMoXG4gICAgICAgIFtkZWxldGVJZF0sXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFBlc3NpbWlzdGljOiBpZ25vcmUgbWVyZ2VTdHJhdGVneS4gUmVtb3ZlIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uIGFuZCBmcm9tIGNoYW5nZSB0cmFja2luZy5cbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE9uZShkZWxldGVJZCwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVEZWxldGVPbmVcblxuICAvLyAjcmVnaW9uIHNhdmVEZWxldGVNYW55XG4gIC8qKlxuICAgKiBEZWxldGUgbXVsdGlwbGUgZW50aXRpZXMgZnJvbSB0aGUgc2VydmVyIGJ5IGtleSBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgY29sbGVjdGlvbiAoaWYgcHJlc2VudCkuXG4gICAqIFJlbW92ZXMgdW5zYXZlZCBuZXcgZW50aXRpZXMgZnJvbSB0aGUgY29sbGVjdGlvbiBpbW1lZGlhdGVseVxuICAgKiBidXQgdGhlIGlkIGlzIHN0aWxsIHNlbnQgdG8gdGhlIHNlcnZlciBmb3IgZGVsZXRpb24gZXZlbiB0aG91Z2ggdGhlIHNlcnZlciB3aWxsIG5vdCBmaW5kIHRoYXQgZW50aXR5LlxuICAgKiBUaGVyZWZvcmUsIHRoZSBzZXJ2ZXIgbXVzdCBiZSB3aWxsaW5nIHRvIGlnbm9yZSBhIGRlbGV0ZSByZXF1ZXN0IGZvciBhbiBlbnRpdHkgaXQgY2Fubm90IGZpbmQuXG4gICAqIEFuIG9wdGltaXN0aWMgc2F2ZSByZW1vdmVzIGV4aXN0aW5nIGVudGl0aWVzIGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHk7XG4gICAqIGEgcGVzc2ltaXN0aWMgc2F2ZSByZW1vdmVzIHRoZW0gYWZ0ZXIgdGhlIHNlcnZlciBjb25maXJtcyBzdWNjZXNzZnVsIGRlbGV0ZS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gUmVtb3ZlcyBlbnRpdGllcyBmcm9tIHRoaXMgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGFycmF5IG9mIHByaW1hcnkga2V5cyBvciBlbnRpdGllcyB3aXRoIGEga2V5O1xuICAgKiB0aGlzIHJlZHVjZXIgZXh0cmFjdHMgdGhlIGtleSBmcm9tIHRoZSBlbnRpdHkuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjwobnVtYmVyIHwgc3RyaW5nIHwgVClbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGVsZXRlSWRzID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLm1hcCgoZCkgPT5cbiAgICAgIHR5cGVvZiBkID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0SWQoZCkgOiAoZCBhcyBzdHJpbmcgfCBudW1iZXIpXG4gICAgKTtcbiAgICBkZWxldGVJZHMuZm9yRWFjaCgoZGVsZXRlSWQpID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZSA9IGNvbGxlY3Rpb24uY2hhbmdlU3RhdGVbZGVsZXRlSWRdO1xuICAgICAgLy8gSWYgZW50aXR5IGlzIGFscmVhZHkgdHJhY2tlZCAuLi5cbiAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgaWYgKGNoYW5nZS5jaGFuZ2VUeXBlID09PSBDaGFuZ2VUeXBlLkFkZGVkKSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIHRoZSBhZGRlZCBlbnRpdHkgaW1tZWRpYXRlbHkgYW5kIGZvcmdldCBhYm91dCBpdHMgY2hhbmdlcyAodmlhIGNvbW1pdCkuXG4gICAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVPbmUoZGVsZXRlSWQgYXMgc3RyaW5nLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE9uZShkZWxldGVJZCwgY29sbGVjdGlvbik7XG4gICAgICAgICAgLy8gU2hvdWxkIG5vdCB3YXN0ZSBlZmZvcnQgdHJ5aW5nIHRvIGRlbGV0ZSBvbiB0aGUgc2VydmVyIGJlY2F1c2UgaXQgY2FuJ3QgYmUgdGhlcmUuXG4gICAgICAgICAgYWN0aW9uLnBheWxvYWQuc2tpcCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmUtdHJhY2sgaXQgYXMgYSBkZWxldGUsIGV2ZW4gaWYgdHJhY2tpbmcgaXMgdHVybmVkIG9mZiBmb3IgdGhpcyBjYWxsLlxuICAgICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVPbmUoXG4gICAgICAgICAgICBkZWxldGVJZCxcbiAgICAgICAgICAgIGNvbGxlY3Rpb25cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gSWYgb3B0aW1pc3RpYyBkZWxldGUsIHRyYWNrIGN1cnJlbnQgc3RhdGUgYW5kIHJlbW92ZSBpbW1lZGlhdGVseS5cbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVNYW55KFxuICAgICAgICBkZWxldGVJZHMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkoZGVsZXRlSWRzIGFzIHN0cmluZ1tdLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBkZWxldGUgdGhlIGVudGl0aWVzIG9uIHRoZSBzZXJ2ZXIgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgY291bGQgc3RpbGwgYmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGFyZSBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgZGVsZXRlZCBlbnRpdGllcyBvbiB0aGUgc2VydmVyLiBUaGUga2V5cyBvZiB0aGUgZGVsZXRlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGFjdGlvbiBwYXlsb2FkIGRhdGEuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgZW50aXRpZXMgdGhhdCBhcmUgc3RpbGwgaW4gdGhlIGNvbGxlY3Rpb24gd2lsbCBiZSByZW1vdmVkLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGhhdmUgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlTWFueVN1Y2Nlc3MoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjwobnVtYmVyIHwgc3RyaW5nKVtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkZWxldGVJZHMgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZURlbGV0ZXMoXG4gICAgICAgIGRlbGV0ZUlkcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUGVzc2ltaXN0aWM6IGlnbm9yZSBtZXJnZVN0cmF0ZWd5LiBSZW1vdmUgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb24gYW5kIGZyb20gY2hhbmdlIHRyYWNraW5nLlxuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVNYW55KGRlbGV0ZUlkcyBhcyBzdHJpbmdbXSwgY29sbGVjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE1hbnkoZGVsZXRlSWRzLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZURlbGV0ZU1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVVcGRhdGVPbmVcbiAgLyoqXG4gICAqIFNhdmUgYW4gdXBkYXRlIHRvIGFuIGV4aXN0aW5nIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gYWZ0ZXIgdGhlIHNlcnZlciBjb25maXJtcyBzdWNjZXNzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHVwZGF0ZSB0aGUgZW50aXR5IGltbWVkaWF0ZWx5LCBiZWZvcmUgdGhlIHNhdmUgcmVxdWVzdC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyBpZiB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4ge1VwZGF0ZTxUPn1cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBkYXRlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlPFQ+PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU9uZShcbiAgICAgICAgdXBkYXRlLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cGRhdGVPbmUodXBkYXRlLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byB1cGRhdGUgdGhlIGVudGl0eSBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiBpcyBpbiB0aGUgcHJlLXNhdmUgc3RhdGVcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdhcyB1cGRhdGVkXG4gICAqIGFuZCB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVPbmVFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgdGhlIHVwZGF0ZWQgZW50aXR5IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCBkYXRhIGZyb20gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgd2FzIGFscmVhZHkgdXBkYXRlZCBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCB0aGUgcmV0dXJuZWQgdmFsdWUgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyB1cGRhdGUgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB1cGRhdGVcbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIGlmIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsIGFuZFxuICAgKiB0aGUgdXBkYXRlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4gVXBkYXRlUmVzcG9uc2U8VD4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgVXBkYXRlIHNlbnQgdG8gdGhlIHNlcnZlci5cbiAgICogWW91IG11c3QgaW5jbHVkZSBhbiBVcGRhdGVSZXNwb25zZSBldmVuIGlmIHRoZSBzYXZlIHdhcyBvcHRpbWlzdGljLFxuICAgKiB0byBlbnN1cmUgdGhhdCB0aGUgY2hhbmdlIHRyYWNraW5nIGlzIHByb3Blcmx5IHJlc2V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlUmVzcG9uc2VEYXRhPFQ+PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZVJlc3BvbnNlKGFjdGlvbik7XG4gICAgY29uc3QgaXNPcHRpbWlzdGljID0gdGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VTYXZlVXBkYXRlcyhcbiAgICAgIFt1cGRhdGVdLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3ksXG4gICAgICBpc09wdGltaXN0aWMgLypza2lwIHVuY2hhbmdlZCBpZiBvcHRpbWlzdGljICovXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBkYXRlT25lXG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBkYXRlTWFueVxuICAvKipcbiAgICogU2F2ZSB1cGRhdGVkIGVudGl0aWVzLlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCB1cGRhdGUgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB1cGRhdGUgdGhlIGVudGl0aWVzIGltbWVkaWF0ZWx5LCBiZWZvcmUgdGhlIHNhdmUgcmVxdWVzdC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyBpZiB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4gYXJyYXkgb2Yge1VwZGF0ZTxUPn0uXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwZGF0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD5bXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdXBkYXRlcyA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlcyhhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU1hbnkoXG4gICAgICAgIHVwZGF0ZXMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwZGF0ZU1hbnkodXBkYXRlcywgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gdXBkYXRlIGVudGl0aWVzIG9uIHRoZSBzZXJ2ZXIgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gYXJlIGluIHRoZSBwcmUtc2F2ZSBzdGF0ZVxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3ZXJlIHVwZGF0ZWRcbiAgICogYW5kIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwZGF0ZU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgdGhlIHVwZGF0ZWQgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2lsbCBiZSB1cGRhdGVkIHdpdGggZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2VyZSBhbHJlYWR5IHVwZGF0ZWQuXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKVxuICAgKiBUaGVyZWZvcmUsIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIHVwZGF0ZSB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgaWYgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhIHdoaWNoLCBtdXN0IGJlIGFuIGFycmF5IG9mIFVwZGF0ZVJlc3BvbnNlPFQ+LlxuICAgKiBZb3UgbXVzdCBpbmNsdWRlIGFuIFVwZGF0ZVJlc3BvbnNlIGZvciBldmVyeSBVcGRhdGUgc2VudCB0byB0aGUgc2VydmVyLFxuICAgKiBldmVuIGlmIHRoZSBzYXZlIHdhcyBvcHRpbWlzdGljLCB0byBlbnN1cmUgdGhhdCB0aGUgY2hhbmdlIHRyYWNraW5nIGlzIHByb3Blcmx5IHJlc2V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVNYW55U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFVwZGF0ZVJlc3BvbnNlRGF0YTxUPltdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGVzID0gdGhpcy5ndWFyZC5tdXN0QmVVcGRhdGVSZXNwb25zZXMoYWN0aW9uKTtcbiAgICBjb25zdCBpc09wdGltaXN0aWMgPSB0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcGRhdGVzKFxuICAgICAgdXBkYXRlcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5LFxuICAgICAgZmFsc2UgLyogbmV2ZXIgc2tpcCAqL1xuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZVVwZGF0ZU1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVVcHNlcnRPbmVcbiAgLyoqXG4gICAqIFNhdmUgYSBuZXcgb3IgZXhpc3RpbmcgZW50aXR5LlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCBkZWxheSBhZGRpbmcgdG8gY29sbGVjdGlvbiB1bnRpbCBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHN1Y2Nlc3MuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseTsgYWRkIGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB3aGljaCB0aGUgZW50aXR5IHNob3VsZCBiZSB1cHNlcnRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGEgd2hvbGUgZW50aXR5LlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgbXVzdCBoYXZlIGl0cyBrZXkuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pOyAvLyBlbnN1cmUgdGhlIGVudGl0eSBoYXMgYSBQS1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcHNlcnRPbmUoXG4gICAgICAgIGVudGl0eSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lKGVudGl0eSwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc2F2ZSBuZXcgb3IgZXhpc3RpbmcgZW50aXR5IGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgbmV3IG9yIHVwZGF0ZWQgZW50aXR5IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgdW5zYXZlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE9uZUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Y2Nlc3NmdWxseSBzYXZlZCBuZXcgb3IgZXhpc3RpbmcgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBhZGQgdGhlIGVudGl0aWVzIGZyb20gdGhlIHNlcnZlciB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBhZGRlZCBlbnRpdGllcyBhcmUgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSByZXR1cm5lZCB2YWx1ZXMgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggdXBzZXJ0ZWQgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSBzZXJ2ZXJcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICBbZW50aXR5XSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBzZXJ0T25lXG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBzZXJ0TWFueVxuICAvKipcbiAgICogU2F2ZSBtdWx0aXBsZSBuZXcgb3IgZXhpc3RpbmcgZW50aXRpZXMuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIGRlbGF5IGFkZGluZyB0byBjb2xsZWN0aW9uIHVudGlsIHNlcnZlciBhY2tub3dsZWRnZXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5OyBhZGQgaW1tZWRpYXRlbHkuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHdoaWNoIHRoZSBlbnRpdGllcyBzaG91bGQgYmUgdXBzZXJ0ZWQuXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhbiBhcnJheSBvZiB3aG9sZSBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgbXVzdCBoYXZlIHRoZWlyIGtleXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTsgLy8gZW5zdXJlIHRoZSBlbnRpdHkgaGFzIGEgUEtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBzZXJ0TWFueShcbiAgICAgICAgZW50aXRpZXMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHNhdmUgbmV3IG9yIGV4aXN0aW5nIGVudGl0aWVzIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgbmV3IGVudGl0aWVzIGFyZSBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIHVuc2F2ZWQgZW50aXRpZXMgYXJlIGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIG5ldyBvciBleGlzdGluZyBlbnRpdGllcyB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGFkZCB0aGUgZW50aXRpZXMgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGFkZGVkIGVudGl0aWVzIGFyZSBhbHJlYWR5IGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBIb3dldmVyLCB0aGUgc2VydmVyIG1pZ2h0IGhhdmUgc2V0IG9yIG1vZGlmaWVkIG90aGVyIGZpZWxkcyAoZS5nLCBjb25jdXJyZW5jeSBmaWVsZClcbiAgICogVGhlcmVmb3JlLCB1cGRhdGUgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIGFkZCB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApIHtcbiAgICAvLyBGb3IgcGVzc2ltaXN0aWMgc2F2ZSwgZW5zdXJlIHRoZSBzZXJ2ZXIgZ2VuZXJhdGVkIHRoZSBwcmltYXJ5IGtleSBpZiB0aGUgY2xpZW50IGRpZG4ndCBzZW5kIG9uZS5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggdXBzZXJ0ZWQgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSBzZXJ2ZXJcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBzZXJ0TWFueVxuXG4gIC8vICNlbmRyZWdpb24gc2F2ZSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBjYWNoZS1vbmx5IG9wZXJhdGlvbnNcblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uXG4gICAqIFNldHMgbG9hZGVkIGZsYWcgdG8gdHJ1ZS5cbiAgICogTWVyZ2VzIHF1ZXJ5IHJlc3VsdHMsIHByZXNlcnZpbmcgdW5zYXZlZCBjaGFuZ2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgYWRkQWxsKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5hZGFwdGVyLnNldEFsbChlbnRpdGllcywgY29sbGVjdGlvbiksXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgIGNoYW5nZVN0YXRlOiB7fSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFkZE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdGllcyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0FkZE1hbnkoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFkZE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFkZE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrQWRkT25lKFxuICAgICAgZW50aXR5LFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuYWRkT25lKGVudGl0eSwgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlTWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlcltdIHwgc3RyaW5nW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIHBheWxvYWQgbXVzdCBiZSBlbnRpdHkga2V5c1xuICAgIGNvbnN0IGtleXMgPSB0aGlzLmd1YXJkLm11c3RCZUtleXMoYWN0aW9uKSBhcyBzdHJpbmdbXTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVNYW55KFxuICAgICAga2V5cyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkoa2V5cywgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248bnVtYmVyIHwgc3RyaW5nPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICAvLyBwYXlsb2FkIG11c3QgYmUgZW50aXR5IGtleVxuICAgIGNvbnN0IGtleSA9IHRoaXMuZ3VhcmQubXVzdEJlS2V5KGFjdGlvbikgYXMgc3RyaW5nO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0RlbGV0ZU9uZShcbiAgICAgIGtleSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJlbW92ZU9uZShrZXksIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlbW92ZUFsbChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmFkYXB0ZXIucmVtb3ZlQWxsKGNvbGxlY3Rpb24pLFxuICAgICAgbG9hZGVkOiBmYWxzZSwgLy8gT25seSBSRU1PVkVfQUxMIHNldHMgbG9hZGVkIHRvIGZhbHNlXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgIGNoYW5nZVN0YXRlOiB7fSwgLy8gQXNzdW1lIGNsZWFyaW5nIHRoZSBjb2xsZWN0aW9uIGFuZCBub3QgdHJ5aW5nIHRvIGRlbGV0ZSBhbGwgZW50aXRpZXNcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD5bXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gcGF5bG9hZCBtdXN0IGJlIGFuIGFycmF5IG9mIGBVcGRhdGVzPFQ+YCwgbm90IGVudGl0aWVzXG4gICAgY29uc3QgdXBkYXRlcyA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlcyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU1hbnkoXG4gICAgICB1cGRhdGVzLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlTWFueSh1cGRhdGVzLCBjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIHBheWxvYWQgbXVzdCBiZSBhbiBgVXBkYXRlPFQ+YCwgbm90IGFuIGVudGl0eVxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBkYXRlT25lKFxuICAgICAgdXBkYXRlLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlT25lKHVwZGF0ZSwgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBzZXJ0TWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gPHY2OiBwYXlsb2FkIG11c3QgYmUgYW4gYXJyYXkgb2YgYFVwZGF0ZXM8VD5gLCBub3QgZW50aXRpZXNcbiAgICAvLyB2Nis6IHBheWxvYWQgbXVzdCBiZSBhbiBhcnJheSBvZiBUXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBzZXJ0TWFueShcbiAgICAgIGVudGl0aWVzLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueShlbnRpdGllcywgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBzZXJ0T25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gPHY2OiBwYXlsb2FkIG11c3QgYmUgYW4gYFVwZGF0ZTxUPmAsIG5vdCBhbiBlbnRpdHlcbiAgICAvLyB2Nis6IHBheWxvYWQgbXVzdCBiZSBhIFRcbiAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1Vwc2VydE9uZShcbiAgICAgIGVudGl0eSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE9uZShlbnRpdHksIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbW1pdEFsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRBbGwoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tbWl0TWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRNYW55KFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tbWl0T25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoXG4gICAgICB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbiksXG4gICAgICBjb2xsZWN0aW9uXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1bmRvQWxsKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4pIHtcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnVuZG9BbGwoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdW5kb01hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICkge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudW5kb01hbnkoXG4gICAgICB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbiksXG4gICAgICBjb2xsZWN0aW9uXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1bmRvT25lKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+KSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci51bmRvT25lKFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICAvKiogRGFuZ2Vyb3VzOiBDb21wbGV0ZWx5IHJlcGxhY2UgdGhlIGNvbGxlY3Rpb24ncyBDaGFuZ2VTdGF0ZS4gVXNlIHJhcmVseSBhbmQgd2lzZWx5LiAqL1xuICBwcm90ZWN0ZWQgc2V0Q2hhbmdlU3RhdGUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxDaGFuZ2VTdGF0ZU1hcDxUPj5cbiAgKSB7XG4gICAgY29uc3QgY2hhbmdlU3RhdGUgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUgPT09IGNoYW5nZVN0YXRlXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogeyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIERhbmdlcm91czogQ29tcGxldGVseSByZXBsYWNlIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBQcmltYXJpbHkgZm9yIHRlc3RpbmcgYW5kIHJlaHlkcmF0aW9uIGZyb20gbG9jYWwgc3RvcmFnZS5cbiAgICogVXNlIHJhcmVseSBhbmQgd2lzZWx5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldENvbGxlY3Rpb24oXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlDb2xsZWN0aW9uPFQ+PlxuICApIHtcbiAgICBjb25zdCBuZXdDb2xsZWN0aW9uID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uID09PSBuZXdDb2xsZWN0aW9uID8gY29sbGVjdGlvbiA6IG5ld0NvbGxlY3Rpb247XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0RmlsdGVyKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248YW55PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24uZmlsdGVyID09PSBmaWx0ZXJcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB7IC4uLmNvbGxlY3Rpb24sIGZpbHRlciB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRlZChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPGJvb2xlYW4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSA9PT0gdHJ1ZSB8fCBmYWxzZTtcbiAgICByZXR1cm4gY29sbGVjdGlvbi5sb2FkZWQgPT09IGxvYWRlZFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgbG9hZGVkIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0TG9hZGluZyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPGJvb2xlYW4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGbGFnKGNvbGxlY3Rpb24sIHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0TG9hZGluZ0ZhbHNlKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZsYWcoY29sbGVjdGlvbiwgZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRpbmdUcnVlKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZsYWcoY29sbGVjdGlvbiwgdHJ1ZSk7XG4gIH1cblxuICAvKiogU2V0IHRoZSBjb2xsZWN0aW9uJ3MgbG9hZGluZyBmbGFnICovXG4gIHByb3RlY3RlZCBzZXRMb2FkaW5nRmxhZyhjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LCBsb2FkaW5nOiBib29sZWFuKSB7XG4gICAgbG9hZGluZyA9IGxvYWRpbmcgPT09IHRydWUgPyB0cnVlIDogZmFsc2U7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24ubG9hZGluZyA9PT0gbG9hZGluZ1xuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgbG9hZGluZyB9O1xuICB9XG4gIC8vICNlbmRyZWdpb24gQ2FjaGUtb25seSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBoZWxwZXJzXG4gIC8qKiBTYWZlbHkgZXh0cmFjdCBkYXRhIGZyb20gdGhlIEVudGl0eUFjdGlvbiBwYXlsb2FkICovXG4gIHByb3RlY3RlZCBleHRyYWN0RGF0YTxEID0gYW55PihhY3Rpb246IEVudGl0eUFjdGlvbjxEPik6IEQge1xuICAgIHJldHVybiAoYWN0aW9uLnBheWxvYWQgJiYgYWN0aW9uLnBheWxvYWQuZGF0YSkgYXMgRDtcbiAgfVxuXG4gIC8qKiBTYWZlbHkgZXh0cmFjdCBNZXJnZVN0cmF0ZWd5IGZyb20gRW50aXR5QWN0aW9uLiBTZXQgdG8gSWdub3JlQ2hhbmdlcyBpZiBjb2xsZWN0aW9uIGl0c2VsZiBpcyBub3QgdHJhY2tlZC4gKi9cbiAgcHJvdGVjdGVkIGV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbjogRW50aXR5QWN0aW9uKSB7XG4gICAgLy8gSWYgbm90IHRyYWNraW5nIHRoaXMgY29sbGVjdGlvbiwgYWx3YXlzIGlnbm9yZSBjaGFuZ2VzXG4gICAgcmV0dXJuIHRoaXMuaXNDaGFuZ2VUcmFja2luZ1xuICAgICAgPyBhY3Rpb24ucGF5bG9hZCAmJiBhY3Rpb24ucGF5bG9hZC5tZXJnZVN0cmF0ZWd5XG4gICAgICA6IE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcztcbiAgfVxuXG4gIHByb3RlY3RlZCBpc09wdGltaXN0aWMoYWN0aW9uOiBFbnRpdHlBY3Rpb24pIHtcbiAgICByZXR1cm4gYWN0aW9uLnBheWxvYWQgJiYgYWN0aW9uLnBheWxvYWQuaXNPcHRpbWlzdGljID09PSB0cnVlO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvbiBoZWxwZXJzXG59XG5cbi8qKlxuICogQ3JlYXRlcyB7RW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RzfSBmb3IgYSBnaXZlbiBlbnRpdHkgdHlwZS5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc0ZhY3Rvcnkge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVudGl0eURlZmluaXRpb25TZXJ2aWNlOiBFbnRpdHlEZWZpbml0aW9uU2VydmljZSkge31cblxuICAvKiogQ3JlYXRlIHRoZSAge0VudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc30gZm9yIHRoZSBuYW1lZCBlbnRpdHkgdHlwZSAqL1xuICBjcmVhdGU8VD4oZW50aXR5TmFtZTogc3RyaW5nKTogRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RNYXA8VD4ge1xuICAgIGNvbnN0IGRlZmluaXRpb24gPSB0aGlzLmVudGl0eURlZmluaXRpb25TZXJ2aWNlLmdldERlZmluaXRpb248VD4oXG4gICAgICBlbnRpdHlOYW1lXG4gICAgKTtcbiAgICBjb25zdCBtZXRob2RzQ2xhc3MgPSBuZXcgRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RzKFxuICAgICAgZW50aXR5TmFtZSxcbiAgICAgIGRlZmluaXRpb25cbiAgICApO1xuXG4gICAgcmV0dXJuIG1ldGhvZHNDbGFzcy5tZXRob2RzO1xuICB9XG59XG4iXX0=
|
|
785
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWNvbGxlY3Rpb24tcmVkdWNlci1tZXRob2RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbW9kdWxlcy9kYXRhL3NyYy9yZWR1Y2Vycy9lbnRpdHktY29sbGVjdGlvbi1yZWR1Y2VyLW1ldGhvZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUUzQyxPQUFPLEVBRUwsVUFBVSxHQUVYLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3JELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR25FLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFjMUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sOEJBQThCO0lBK0d6QyxZQUNTLFVBQWtCLEVBQ2xCLFVBQStCO0lBQ3RDOzs7T0FHRztJQUNILG1CQUE0QztRQU5yQyxlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2xCLGVBQVUsR0FBVixVQUFVLENBQXFCO1FBM0Z4Qzs7O1dBR0c7UUFDTSxZQUFPLEdBQXdDO1lBQ3RELENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUV4RCxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDOUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3pELENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTdELENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNuRCxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUM5RCxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRWxFLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMzRCxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRS9ELENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMzRCxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRS9ELENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNyRCxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2hFLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFcEUsQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ25ELENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzlELENBQUMsUUFBUSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFbEUsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0QsQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN0RSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTFFLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN6RCxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3BFLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFeEUsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0QsQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN0RSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTFFLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN6RCxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3BFLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFeEUsQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDM0QsQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN0RSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTFFLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN6RCxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3BFLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFDLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFeEUsOERBQThEO1lBQzlELG9DQUFvQztZQUNwQyw0REFBNEQ7WUFFNUQsNkJBQTZCO1lBRTdCLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMxQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRTFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDbEQsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBRWhELENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNsRCxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFFaEQsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2xELENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUVoRCxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDaEQsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2xELENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzlDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUU1QyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUMzRCxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDeEQsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ2hELENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNoRCxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDbkQsQ0FBQztRQVdBLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUN4QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixLQUFLLElBQUksQ0FBQztRQUM3RCxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUM7UUFFcEMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRS9DLElBQUksQ0FBQyxtQkFBbUI7WUFDdEIsbUJBQW1CO2dCQUNuQixJQUFJLHVCQUF1QixDQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxxQ0FBcUM7SUFDM0IsYUFBYSxDQUNyQixVQUErQjtRQUUvQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVELDJCQUEyQjtJQUVqQixRQUFRLENBQUMsVUFBK0I7UUFDaEQsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFUyxhQUFhLENBQ3JCLFVBQStCLEVBQy9CLE1BQWtEO1FBRWxELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ08sZUFBZSxDQUN2QixVQUErQixFQUMvQixNQUF5QjtRQUV6QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCx1Q0FDSyxJQUFJLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLENBQzNDLElBQUksRUFDSixVQUFVLEVBQ1YsYUFBYSxDQUNkLEtBQ0QsTUFBTSxFQUFFLElBQUksRUFDWixPQUFPLEVBQUUsS0FBSyxJQUNkO0lBQ0osQ0FBQztJQUVTLFVBQVUsQ0FDbEIsVUFBK0IsRUFDL0IsTUFBcUM7UUFFckMsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFUyxlQUFlLENBQ3ZCLFVBQStCLEVBQy9CLE1BQWtEO1FBRWxELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRVMsaUJBQWlCLENBQ3pCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELFVBQVU7WUFDUixJQUFJLElBQUksSUFBSTtnQkFDVixDQUFDLENBQUMsVUFBVTtnQkFDWixDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGlCQUFpQixDQUN4QyxDQUFDLElBQUksQ0FBQyxFQUNOLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztRQUNSLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRVMsU0FBUyxDQUFDLFVBQStCO1FBQ2pELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRVMsY0FBYyxDQUN0QixVQUErQixFQUMvQixNQUFrRDtRQUVsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxnQkFBZ0IsQ0FDeEIsVUFBK0IsRUFDL0IsTUFBeUI7UUFFekIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN0Qyx1Q0FDSyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEtBQ3hDLE9BQU8sRUFBRSxLQUFLLEVBQ2QsTUFBTSxFQUFFLElBQUksRUFDWixXQUFXLEVBQUUsRUFBRSxJQUNmO0lBQ0osQ0FBQztJQUVTLFNBQVMsQ0FDakIsVUFBK0IsRUFDL0IsTUFBb0I7UUFFcEIsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFUyxjQUFjLENBQ3RCLFVBQStCLEVBQy9CLE1BQWtEO1FBRWxELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRVMsZ0JBQWdCLENBQ3hCLFVBQStCLEVBQy9CLE1BQXlCO1FBRXpCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELHVDQUNLLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FDM0MsSUFBSSxFQUNKLFVBQVUsRUFDVixhQUFhLENBQ2QsS0FDRCxPQUFPLEVBQUUsS0FBSyxJQUNkO0lBQ0osQ0FBQztJQUNELDhCQUE4QjtJQUU5QiwwQkFBMEI7SUFFMUIsc0JBQXNCO0lBQ3RCOzs7Ozs7OztPQVFHO0lBQ08sV0FBVyxDQUNuQixVQUErQixFQUMvQixNQUF5QjtRQUV6QixJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDN0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyw2QkFBNkI7WUFDakYsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUNoRCxRQUFRLEVBQ1IsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztTQUN6RDtRQUNELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLGdCQUFnQixDQUN4QixVQUErQixFQUMvQixNQUFrRDtRQUVsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELHlCQUF5QjtJQUV6QixxQkFBcUI7SUFDckI7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNPLGtCQUFrQixDQUMxQixVQUErQixFQUMvQixNQUF5QjtRQUV6QixtR0FBbUc7UUFDbkcsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM3QixVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUNwRCxRQUFRLEVBQ1IsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1NBQ0g7YUFBTTtZQUNMLFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUNqRCxRQUFRLEVBQ1IsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1NBQ0g7UUFDRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELHlCQUF5QjtJQUV6QixxQkFBcUI7SUFDckI7Ozs7Ozs7O09BUUc7SUFDTyxVQUFVLENBQ2xCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM3QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLDZCQUE2QjtZQUM3RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQy9DLE1BQU0sRUFDTixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ3REO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ08sZUFBZSxDQUN2QixVQUErQixFQUMvQixNQUFrRDtRQUVsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ08saUJBQWlCLENBQ3pCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLG1HQUFtRztRQUNuRyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sTUFBTSxHQUEwQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzVELGlFQUFpRTtZQUNqRSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUNwRCxDQUFDLE1BQU0sQ0FBQyxFQUNSLFVBQVUsRUFDVixhQUFhLEVBQ2IsS0FBSyxDQUFDLGNBQWMsQ0FDckIsQ0FBQztTQUNIO2FBQU07WUFDTCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FDakQsQ0FBQyxNQUFNLENBQUMsRUFDUixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7U0FDSDtRQUNELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0Qsd0JBQXdCO0lBRXhCLHNCQUFzQjtJQUN0QixZQUFZO0lBQ1oseUJBQXlCO0lBRXpCLHdCQUF3QjtJQUN4Qjs7Ozs7Ozs7OztPQVVHO0lBQ08sYUFBYSxDQUNyQixVQUErQixFQUMvQixNQUF5QztRQUV6QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUNaLE9BQU8sUUFBUSxLQUFLLFFBQVE7WUFDMUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1lBQ3pCLENBQUMsQ0FBRSxRQUE0QixDQUFDO1FBQ3BDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEQsbUNBQW1DO1FBQ25DLElBQUksTUFBTSxFQUFFO1lBQ1YsSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLFVBQVUsQ0FBQyxLQUFLLEVBQUU7Z0JBQzFDLGlGQUFpRjtnQkFDakYsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBQ3BFLFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztnQkFDdEUsb0ZBQW9GO2dCQUNwRixNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7YUFDNUI7aUJBQU07Z0JBQ0wseUVBQXlFO2dCQUN6RSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsQ0FDbEQsUUFBUSxFQUNSLFVBQVUsQ0FDWCxDQUFDO2FBQ0g7U0FDRjtRQUVELG9FQUFvRTtRQUNwRSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDN0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUNsRCxRQUFRLEVBQ1IsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDckU7UUFFRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTyxrQkFBa0IsQ0FDMUIsVUFBK0IsRUFDL0IsTUFBa0Q7UUFFbEQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sb0JBQW9CLENBQzVCLFVBQStCLEVBQy9CLE1BQXFDO1FBRXJDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUNwRCxDQUFDLFFBQVEsQ0FBQyxFQUNWLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztTQUNIO2FBQU07WUFDTCxpR0FBaUc7WUFDakcsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQWtCLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDcEUsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ3ZFO1FBQ0QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFDRCwyQkFBMkI7SUFFM0IseUJBQXlCO0lBQ3pCOzs7Ozs7Ozs7OztPQVdHO0lBQ08sY0FBYyxDQUN0QixVQUErQixFQUMvQixNQUE2QztRQUU3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ25ELE9BQU8sQ0FBQyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBcUIsQ0FDbEUsQ0FBQztRQUNGLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUM3QixNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2hELG1DQUFtQztZQUNuQyxJQUFJLE1BQU0sRUFBRTtnQkFDVixJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssVUFBVSxDQUFDLEtBQUssRUFBRTtvQkFDMUMsaUZBQWlGO29CQUNqRixVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBa0IsRUFBRSxVQUFVLENBQUMsQ0FBQztvQkFDcEUsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO29CQUN0RSxvRkFBb0Y7b0JBQ3BGLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztpQkFDNUI7cUJBQU07b0JBQ0wseUVBQXlFO29CQUN6RSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsQ0FDbEQsUUFBUSxFQUNSLFVBQVUsQ0FDWCxDQUFDO2lCQUNIO2FBQ0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILG9FQUFvRTtRQUNwRSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDN0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUNuRCxTQUFTLEVBQ1QsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQXFCLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDekU7UUFDRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTyxtQkFBbUIsQ0FDM0IsVUFBK0IsRUFDL0IsTUFBa0Q7UUFFbEQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08scUJBQXFCLENBQzdCLFVBQStCLEVBQy9CLE1BQXlDO1FBRXpDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0MsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUNwRCxTQUFTLEVBQ1QsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1NBQ0g7YUFBTTtZQUNMLGlHQUFpRztZQUNqRyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsU0FBcUIsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUN4RSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDekU7UUFDRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELDRCQUE0QjtJQUU1Qix3QkFBd0I7SUFDeEI7Ozs7Ozs7T0FPRztJQUNPLGFBQWEsQ0FDckIsVUFBK0IsRUFDL0IsTUFBK0I7UUFFL0IsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0MsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQzdCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsQ0FDbEQsTUFBTSxFQUNOLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztZQUNGLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDekQ7UUFDRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTyxrQkFBa0IsQ0FDMUIsVUFBK0IsRUFDL0IsTUFBa0Q7UUFFbEQsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ08sb0JBQW9CLENBQzVCLFVBQStCLEVBQy9CLE1BQTJDO1FBRTNDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FDcEQsQ0FBQyxNQUFNLENBQUMsRUFDUixVQUFVLEVBQ1YsYUFBYSxFQUNiLFlBQVksQ0FBQyxpQ0FBaUMsQ0FDL0MsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsMkJBQTJCO0lBRTNCLHlCQUF5QjtJQUN6Qjs7Ozs7OztPQU9HO0lBQ08sY0FBYyxDQUN0QixVQUErQixFQUMvQixNQUFpQztRQUVqQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDN0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUNuRCxPQUFPLEVBQ1AsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1lBQ0YsVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsQ0FBQztTQUMzRDtRQUNELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNPLG1CQUFtQixDQUMzQixVQUErQixFQUMvQixNQUFrRDtRQUVsRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDTyxxQkFBcUIsQ0FDN0IsVUFBK0IsRUFDL0IsTUFBNkM7UUFFN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUNwRCxPQUFPLEVBQ1AsVUFBVSxFQUNWLGFBQWEsRUFDYixLQUFLLENBQUMsZ0JBQWdCLENBQ3ZCLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELDRCQUE0QjtJQUU1Qix3QkFBd0I7SUFDeEI7Ozs7Ozs7O09BUUc7SUFDTyxhQUFhLENBQ3JCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM3QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLDZCQUE2QjtZQUM3RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLENBQ2xELE1BQU0sRUFDTixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQ3pEO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ08sa0JBQWtCLENBQzFCLFVBQStCLEVBQy9CLE1BQWtEO1FBRWxELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxvQkFBb0IsQ0FDNUIsVUFBK0IsRUFDL0IsTUFBdUI7UUFFdkIsbUdBQW1HO1FBQ25HLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxzRUFBc0U7UUFDdEUsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FDcEQsQ0FBQyxNQUFNLENBQUMsRUFDUixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUNELDJCQUEyQjtJQUUzQix5QkFBeUI7SUFDekI7Ozs7Ozs7O09BUUc7SUFDTyxjQUFjLENBQ3RCLFVBQStCLEVBQy9CLE1BQXlCO1FBRXpCLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM3QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLDZCQUE2QjtZQUNqRixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQ25ELFFBQVEsRUFDUixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7WUFDRixVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1NBQzVEO1FBQ0QsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ08sbUJBQW1CLENBQzNCLFVBQStCLEVBQy9CLE1BQWtEO1FBRWxELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxxQkFBcUIsQ0FDN0IsVUFBK0IsRUFDL0IsTUFBeUI7UUFFekIsbUdBQW1HO1FBQ25HLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxzRUFBc0U7UUFDdEUsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FDcEQsUUFBUSxFQUNSLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsNEJBQTRCO0lBRTVCLDZCQUE2QjtJQUU3QixnQ0FBZ0M7SUFFaEM7Ozs7T0FJRztJQUNPLE1BQU0sQ0FDZCxVQUErQixFQUMvQixNQUF5QjtRQUV6QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRCx1Q0FDSyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEtBQzVDLE9BQU8sRUFBRSxLQUFLLEVBQ2QsTUFBTSxFQUFFLElBQUksRUFDWixXQUFXLEVBQUUsRUFBRSxJQUNmO0lBQ0osQ0FBQztJQUVTLE9BQU8sQ0FDZixVQUErQixFQUMvQixNQUF5QjtRQUV6QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNuRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQ2hELFFBQVEsRUFDUixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRVMsTUFBTSxDQUNkLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsQ0FDL0MsTUFBTSxFQUNOLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxVQUFVLENBQ2xCLFVBQStCLEVBQy9CLE1BQXlDO1FBRXpDLDhCQUE4QjtRQUM5QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQWEsQ0FBQztRQUN2RCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLENBQ25ELElBQUksRUFDSixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRVMsU0FBUyxDQUNqQixVQUErQixFQUMvQixNQUFxQztRQUVyQyw2QkFBNkI7UUFDN0IsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFXLENBQUM7UUFDbkQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUNsRCxHQUFHLEVBQ0gsVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVTLFNBQVMsQ0FDakIsVUFBK0IsRUFDL0IsTUFBdUI7UUFFdkIsdUNBQ0ssSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQ3JDLE1BQU0sRUFBRSxLQUFLLEVBQ2IsT0FBTyxFQUFFLEtBQUssRUFDZCxXQUFXLEVBQUUsRUFBRSxJQUNmO0lBQ0osQ0FBQztJQUVTLFVBQVUsQ0FDbEIsVUFBK0IsRUFDL0IsTUFBaUM7UUFFakMseURBQXlEO1FBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsQ0FDbkQsT0FBTyxFQUNQLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFUyxTQUFTLENBQ2pCLFVBQStCLEVBQy9CLE1BQStCO1FBRS9CLGdEQUFnRDtRQUNoRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLENBQ2xELE1BQU0sRUFDTixVQUFVLEVBQ1YsYUFBYSxDQUNkLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRVMsVUFBVSxDQUNsQixVQUErQixFQUMvQixNQUF5QjtRQUV6Qiw4REFBOEQ7UUFDOUQscUNBQXFDO1FBQ3JDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsQ0FDbkQsUUFBUSxFQUNSLFVBQVUsRUFDVixhQUFhLENBQ2QsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFUyxTQUFTLENBQ2pCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLHFEQUFxRDtRQUNyRCwyQkFBMkI7UUFDM0IsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDL0MsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3hELFVBQVUsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxDQUNsRCxNQUFNLEVBQ04sVUFBVSxFQUNWLGFBQWEsQ0FDZCxDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVTLFNBQVMsQ0FBQyxVQUErQjtRQUNqRCxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVTLFVBQVUsQ0FDbEIsVUFBK0IsRUFDL0IsTUFBeUI7UUFFekIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUN4QyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUN4QixVQUFVLENBQ1gsQ0FBQztJQUNKLENBQUM7SUFFUyxTQUFTLENBQ2pCLFVBQStCLEVBQy9CLE1BQXVCO1FBRXZCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsQ0FDdkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFDeEIsVUFBVSxDQUNYLENBQUM7SUFDSixDQUFDO0lBRVMsT0FBTyxDQUFDLFVBQStCO1FBQy9DLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRVMsUUFBUSxDQUNoQixVQUErQixFQUMvQixNQUF5QjtRQUV6QixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLENBQ3RDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQ3hCLFVBQVUsQ0FDWCxDQUFDO0lBQ0osQ0FBQztJQUVTLE9BQU8sQ0FBQyxVQUErQixFQUFFLE1BQXVCO1FBQ3hFLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sQ0FDckMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFDeEIsVUFBVSxDQUNYLENBQUM7SUFDSixDQUFDO0lBRUQseUZBQXlGO0lBQy9FLGNBQWMsQ0FDdEIsVUFBK0IsRUFDL0IsTUFBdUM7UUFFdkMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QyxPQUFPLFVBQVUsQ0FBQyxXQUFXLEtBQUssV0FBVztZQUMzQyxDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsaUNBQU0sVUFBVSxLQUFFLFdBQVcsR0FBRSxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sYUFBYSxDQUNyQixVQUErQixFQUMvQixNQUF5QztRQUV6QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLE9BQU8sVUFBVSxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUM7SUFDbkUsQ0FBQztJQUVTLFNBQVMsQ0FDakIsVUFBK0IsRUFDL0IsTUFBeUI7UUFFekIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4QyxPQUFPLFVBQVUsQ0FBQyxNQUFNLEtBQUssTUFBTTtZQUNqQyxDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsaUNBQU0sVUFBVSxLQUFFLE1BQU0sR0FBRSxDQUFDO0lBQ2hDLENBQUM7SUFFUyxTQUFTLENBQ2pCLFVBQStCLEVBQy9CLE1BQTZCO1FBRTdCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLEtBQUssQ0FBQztRQUMxRCxPQUFPLFVBQVUsQ0FBQyxNQUFNLEtBQUssTUFBTTtZQUNqQyxDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsaUNBQU0sVUFBVSxLQUFFLE1BQU0sR0FBRSxDQUFDO0lBQ2hDLENBQUM7SUFFUyxVQUFVLENBQ2xCLFVBQStCLEVBQy9CLE1BQTZCO1FBRTdCLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFUyxlQUFlLENBQ3ZCLFVBQStCO1FBRS9CLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVTLGNBQWMsQ0FDdEIsVUFBK0I7UUFFL0IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsd0NBQXdDO0lBQzlCLGNBQWMsQ0FBQyxVQUErQixFQUFFLE9BQWdCO1FBQ3hFLE9BQU8sR0FBRyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUMxQyxPQUFPLFVBQVUsQ0FBQyxPQUFPLEtBQUssT0FBTztZQUNuQyxDQUFDLENBQUMsVUFBVTtZQUNaLENBQUMsaUNBQU0sVUFBVSxLQUFFLE9BQU8sR0FBRSxDQUFDO0lBQ2pDLENBQUM7SUFDRCxtQ0FBbUM7SUFFbkMsa0JBQWtCO0lBQ2xCLHdEQUF3RDtJQUM5QyxXQUFXLENBQVUsTUFBdUI7UUFDcEQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQU0sQ0FBQztJQUN0RCxDQUFDO0lBRUQsZ0hBQWdIO0lBQ3RHLG9CQUFvQixDQUFDLE1BQW9CO1FBQ2pELHlEQUF5RDtRQUN6RCxPQUFPLElBQUksQ0FBQyxnQkFBZ0I7WUFDMUIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhO1lBQ2hELENBQUMsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO0lBQ2xDLENBQUM7SUFFUyxZQUFZLENBQUMsTUFBb0I7UUFDekMsT0FBTyxNQUFNLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQztJQUNoRSxDQUFDO0NBR0Y7QUFFRDs7R0FFRztBQUVILE1BQU0sT0FBTyxxQ0FBcUM7SUFDaEQsWUFBb0IsdUJBQWdEO1FBQWhELDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7SUFBRyxDQUFDO0lBRXhFLDZFQUE2RTtJQUM3RSxNQUFNLENBQUksVUFBa0I7UUFDMUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FDM0QsVUFBVSxDQUNYLENBQUM7UUFDRixNQUFNLFlBQVksR0FBRyxJQUFJLDhCQUE4QixDQUNyRCxVQUFVLEVBQ1YsVUFBVSxDQUNYLENBQUM7UUFFRixPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUM7SUFDOUIsQ0FBQzs7O1lBZkYsVUFBVTs7OztZQTNyQ0YsdUJBQXVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRW50aXR5QWRhcHRlciwgSWRTZWxlY3RvciwgVXBkYXRlIH0gZnJvbSAnQG5ncngvZW50aXR5JztcbmltcG9ydCB7XG4gIENoYW5nZVN0YXRlTWFwLFxuICBDaGFuZ2VUeXBlLFxuICBFbnRpdHlDb2xsZWN0aW9uLFxufSBmcm9tICcuL2VudGl0eS1jb2xsZWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUNoYW5nZVRyYWNrZXJCYXNlIH0gZnJvbSAnLi9lbnRpdHktY2hhbmdlLXRyYWNrZXItYmFzZSc7XG5pbXBvcnQgeyB0b1VwZGF0ZUZhY3RvcnkgfSBmcm9tICcuLi91dGlscy91dGlsaXRpZXMnO1xuaW1wb3J0IHsgRW50aXR5QWN0aW9uIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3IgfSBmcm9tICcuLi9kYXRhc2VydmljZXMvZGF0YS1zZXJ2aWNlLWVycm9yJztcbmltcG9ydCB7IEVudGl0eUFjdGlvbkd1YXJkIH0gZnJvbSAnLi4vYWN0aW9ucy9lbnRpdHktYWN0aW9uLWd1YXJkJztcbmltcG9ydCB7IEVudGl0eUNoYW5nZVRyYWNrZXIgfSBmcm9tICcuL2VudGl0eS1jaGFuZ2UtdHJhY2tlcic7XG5pbXBvcnQgeyBFbnRpdHlEZWZpbml0aW9uIH0gZnJvbSAnLi4vZW50aXR5LW1ldGFkYXRhL2VudGl0eS1kZWZpbml0aW9uJztcbmltcG9ydCB7IEVudGl0eURlZmluaXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vZW50aXR5LW1ldGFkYXRhL2VudGl0eS1kZWZpbml0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgRW50aXR5T3AgfSBmcm9tICcuLi9hY3Rpb25zL2VudGl0eS1vcCc7XG5pbXBvcnQgeyBNZXJnZVN0cmF0ZWd5IH0gZnJvbSAnLi4vYWN0aW9ucy9tZXJnZS1zdHJhdGVneSc7XG5pbXBvcnQgeyBVcGRhdGVSZXNwb25zZURhdGEgfSBmcm9tICcuLi9hY3Rpb25zL3VwZGF0ZS1yZXNwb25zZS1kYXRhJztcblxuLyoqXG4gKiBNYXAgb2Yge0VudGl0eU9wfSB0byByZWR1Y2VyIG1ldGhvZCBmb3IgdGhlIG9wZXJhdGlvbi5cbiAqIElmIGFuIG9wZXJhdGlvbiBpcyBtaXNzaW5nLCBjYWxsZXIgc2hvdWxkIHJldHVybiB0aGUgY29sbGVjdGlvbiBmb3IgdGhhdCByZWR1Y2VyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kTWFwPFQ+IHtcbiAgW21ldGhvZDogc3RyaW5nXTogKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb25cbiAgKSA9PiBFbnRpdHlDb2xsZWN0aW9uPFQ+O1xufVxuXG4vKipcbiAqIEJhc2UgaW1wbGVtZW50YXRpb24gb2YgcmVkdWNlciBtZXRob2RzIGZvciBhbiBlbnRpdHkgY29sbGVjdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kczxUPiB7XG4gIHByb3RlY3RlZCBhZGFwdGVyOiBFbnRpdHlBZGFwdGVyPFQ+O1xuICBwcm90ZWN0ZWQgZ3VhcmQ6IEVudGl0eUFjdGlvbkd1YXJkPFQ+O1xuICAvKiogVHJ1ZSBpZiB0aGlzIGNvbGxlY3Rpb24gdHJhY2tzIHVuc2F2ZWQgY2hhbmdlcyAqL1xuICBwcm90ZWN0ZWQgaXNDaGFuZ2VUcmFja2luZzogYm9vbGVhbjtcblxuICAvKiogRXh0cmFjdCB0aGUgcHJpbWFyeSBrZXkgKGlkKTsgZGVmYXVsdCB0byBgaWRgICovXG4gIHNlbGVjdElkOiBJZFNlbGVjdG9yPFQ+O1xuXG4gIC8qKlxuICAgKiBUcmFjayBjaGFuZ2VzIHRvIGVudGl0aWVzIHNpbmNlIHRoZSBsYXN0IHF1ZXJ5IG9yIHNhdmVcbiAgICogQ2FuIHJldmVydCBzb21lIG9yIGFsbCBvZiB0aG9zZSBjaGFuZ2VzXG4gICAqL1xuICBlbnRpdHlDaGFuZ2VUcmFja2VyOiBFbnRpdHlDaGFuZ2VUcmFja2VyPFQ+O1xuXG4gIC8qKlxuICAgKiBDb252ZXJ0IGFuIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkpIGludG8gdGhlIGBVcGRhdGU8VD5gIG9iamVjdFxuICAgKiBgaWRgOiB0aGUgcHJpbWFyeSBrZXkgYW5kXG4gICAqIGBjaGFuZ2VzYDogdGhlIGVudGl0eSAob3IgcGFydGlhbCBlbnRpdHkgb2YgY2hhbmdlcykuXG4gICAqL1xuICBwcm90ZWN0ZWQgdG9VcGRhdGU6IChlbnRpdHk6IFBhcnRpYWw8VD4pID0+IFVwZGF0ZTxUPjtcblxuICAvKipcbiAgICogRGljdGlvbmFyeSBvZiB0aGUge0VudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc30gZm9yIHRoaXMgZW50aXR5IHR5cGUsXG4gICAqIGtleWVkIGJ5IHRoZSB7RW50aXR5T3B9XG4gICAqL1xuICByZWFkb25seSBtZXRob2RzOiBFbnRpdHlDb2xsZWN0aW9uUmVkdWNlck1ldGhvZE1hcDxUPiA9IHtcbiAgICBbRW50aXR5T3AuQ0FOQ0VMX1BFUlNJU1RdOiB0aGlzLmNhbmNlbFBlcnNpc3QuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5RVUVSWV9BTExdOiB0aGlzLnF1ZXJ5QWxsLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0FMTF9FUlJPUl06IHRoaXMucXVlcnlBbGxFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9BTExfU1VDQ0VTU106IHRoaXMucXVlcnlBbGxTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuUVVFUllfQllfS0VZXTogdGhpcy5xdWVyeUJ5S2V5LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0JZX0tFWV9FUlJPUl06IHRoaXMucXVlcnlCeUtleUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlFVRVJZX0JZX0tFWV9TVUNDRVNTXTogdGhpcy5xdWVyeUJ5S2V5U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlFVRVJZX0xPQURdOiB0aGlzLnF1ZXJ5TG9hZC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9MT0FEX0VSUk9SXTogdGhpcy5xdWVyeUxvYWRFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5RVUVSWV9MT0FEX1NVQ0NFU1NdOiB0aGlzLnF1ZXJ5TG9hZFN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5RVUVSWV9NQU5ZXTogdGhpcy5xdWVyeU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTUFOWV9FUlJPUl06IHRoaXMucXVlcnlNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUVVFUllfTUFOWV9TVUNDRVNTXTogdGhpcy5xdWVyeU1hbnlTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9BRERfTUFOWV06IHRoaXMuc2F2ZUFkZE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9BRERfTUFOWV9FUlJPUl06IHRoaXMuc2F2ZUFkZE1hbnlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9NQU5ZX1NVQ0NFU1NdOiB0aGlzLnNhdmVBZGRNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfQUREX09ORV06IHRoaXMuc2F2ZUFkZE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9PTkVfRVJST1JdOiB0aGlzLnNhdmVBZGRPbmVFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0FERF9PTkVfU1VDQ0VTU106IHRoaXMuc2F2ZUFkZE9uZVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9NQU5ZXTogdGhpcy5zYXZlRGVsZXRlTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX0RFTEVURV9NQU5ZX0VSUk9SXTogdGhpcy5zYXZlRGVsZXRlTWFueUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX01BTllfU1VDQ0VTU106IHRoaXMuc2F2ZURlbGV0ZU1hbnlTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9ERUxFVEVfT05FXTogdGhpcy5zYXZlRGVsZXRlT25lLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX09ORV9FUlJPUl06IHRoaXMuc2F2ZURlbGV0ZU9uZUVycm9yLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfREVMRVRFX09ORV9TVUNDRVNTXTogdGhpcy5zYXZlRGVsZXRlT25lU3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX01BTlldOiB0aGlzLnNhdmVVcGRhdGVNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNBVkVfVVBEQVRFX01BTllfRVJST1JdOiB0aGlzLnNhdmVVcGRhdGVNYW55RXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfTUFOWV9TVUNDRVNTXTogdGhpcy5zYXZlVXBkYXRlTWFueVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5TQVZFX1VQREFURV9PTkVdOiB0aGlzLnNhdmVVcGRhdGVPbmUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfT05FX0VSUk9SXTogdGhpcy5zYXZlVXBkYXRlT25lRXJyb3IuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUERBVEVfT05FX1NVQ0NFU1NdOiB0aGlzLnNhdmVVcGRhdGVPbmVTdWNjZXNzLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfTUFOWV06IHRoaXMuc2F2ZVVwc2VydE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0FWRV9VUFNFUlRfTUFOWV9FUlJPUl06IHRoaXMuc2F2ZVVwc2VydE1hbnlFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9NQU5ZX1NVQ0NFU1NdOiB0aGlzLnNhdmVVcHNlcnRNYW55U3VjY2Vzcy5iaW5kKHRoaXMpLFxuXG4gICAgW0VudGl0eU9wLlNBVkVfVVBTRVJUX09ORV06IHRoaXMuc2F2ZVVwc2VydE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkVfRVJST1JdOiB0aGlzLnNhdmVVcHNlcnRPbmVFcnJvci5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TQVZFX1VQU0VSVF9PTkVfU1VDQ0VTU106IHRoaXMuc2F2ZVVwc2VydE9uZVN1Y2Nlc3MuYmluZCh0aGlzKSxcblxuICAgIC8vIERvIG5vdGhpbmcgb24gc2F2ZSBlcnJvcnMgZXhjZXB0IHR1cm4gdGhlIGxvYWRpbmcgZmxhZyBvZmYuXG4gICAgLy8gU2VlIHRoZSBDaGFuZ2VUcmFja2VyTWV0YVJlZHVjZXJzXG4gICAgLy8gT3IgdGhlIGFwcCBjb3VsZCBsaXN0ZW4gZm9yIHRob3NlIGVycm9ycyBhbmQgZG8gc29tZXRoaW5nXG5cbiAgICAvLy8gY2FjaGUgb25seSBvcGVyYXRpb25zIC8vL1xuXG4gICAgW0VudGl0eU9wLkFERF9BTExdOiB0aGlzLmFkZEFsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5BRERfTUFOWV06IHRoaXMuYWRkTWFueS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5BRERfT05FXTogdGhpcy5hZGRPbmUuYmluZCh0aGlzKSxcblxuICAgIFtFbnRpdHlPcC5SRU1PVkVfQUxMXTogdGhpcy5yZW1vdmVBbGwuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUkVNT1ZFX01BTlldOiB0aGlzLnJlbW92ZU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuUkVNT1ZFX09ORV06IHRoaXMucmVtb3ZlT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuVVBEQVRFX01BTlldOiB0aGlzLnVwZGF0ZU1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVVBEQVRFX09ORV06IHRoaXMudXBkYXRlT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuVVBTRVJUX01BTlldOiB0aGlzLnVwc2VydE1hbnkuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuVVBTRVJUX09ORV06IHRoaXMudXBzZXJ0T25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuQ09NTUlUX0FMTF06IHRoaXMuY29tbWl0QWxsLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLkNPTU1JVF9NQU5ZXTogdGhpcy5jb21taXRNYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLkNPTU1JVF9PTkVdOiB0aGlzLmNvbW1pdE9uZS5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5VTkRPX0FMTF06IHRoaXMudW5kb0FsbC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5VTkRPX01BTlldOiB0aGlzLnVuZG9NYW55LmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlVORE9fT05FXTogdGhpcy51bmRvT25lLmJpbmQodGhpcyksXG5cbiAgICBbRW50aXR5T3AuU0VUX0NIQU5HRV9TVEFURV06IHRoaXMuc2V0Q2hhbmdlU3RhdGUuYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0VUX0NPTExFQ1RJT05dOiB0aGlzLnNldENvbGxlY3Rpb24uYmluZCh0aGlzKSxcbiAgICBbRW50aXR5T3AuU0VUX0ZJTFRFUl06IHRoaXMuc2V0RmlsdGVyLmJpbmQodGhpcyksXG4gICAgW0VudGl0eU9wLlNFVF9MT0FERURdOiB0aGlzLnNldExvYWRlZC5iaW5kKHRoaXMpLFxuICAgIFtFbnRpdHlPcC5TRVRfTE9BRElOR106IHRoaXMuc2V0TG9hZGluZy5iaW5kKHRoaXMpLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgcHVibGljIGRlZmluaXRpb246IEVudGl0eURlZmluaXRpb248VD4sXG4gICAgLypcbiAgICAgKiBUcmFjayBjaGFuZ2VzIHRvIGVudGl0aWVzIHNpbmNlIHRoZSBsYXN0IHF1ZXJ5IG9yIHNhdmVcbiAgICAgKiBDYW4gcmV2ZXJ0IHNvbWUgb3IgYWxsIG9mIHRob3NlIGNoYW5nZXNcbiAgICAgKi9cbiAgICBlbnRpdHlDaGFuZ2VUcmFja2VyPzogRW50aXR5Q2hhbmdlVHJhY2tlcjxUPlxuICApIHtcbiAgICB0aGlzLmFkYXB0ZXIgPSBkZWZpbml0aW9uLmVudGl0eUFkYXB0ZXI7XG4gICAgdGhpcy5pc0NoYW5nZVRyYWNraW5nID0gZGVmaW5pdGlvbi5ub0NoYW5nZVRyYWNraW5nICE9PSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0SWQgPSBkZWZpbml0aW9uLnNlbGVjdElkO1xuXG4gICAgdGhpcy5ndWFyZCA9IG5ldyBFbnRpdHlBY3Rpb25HdWFyZChlbnRpdHlOYW1lLCB0aGlzLnNlbGVjdElkKTtcbiAgICB0aGlzLnRvVXBkYXRlID0gdG9VcGRhdGVGYWN0b3J5KHRoaXMuc2VsZWN0SWQpO1xuXG4gICAgdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyID1cbiAgICAgIGVudGl0eUNoYW5nZVRyYWNrZXIgfHxcbiAgICAgIG5ldyBFbnRpdHlDaGFuZ2VUcmFja2VyQmFzZTxUPih0aGlzLmFkYXB0ZXIsIHRoaXMuc2VsZWN0SWQpO1xuICB9XG5cbiAgLyoqIENhbmNlbCBhIHBlcnNpc3RlbmNlIG9wZXJhdGlvbiAqL1xuICBwcm90ZWN0ZWQgY2FuY2VsUGVyc2lzdChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8vICNyZWdpb24gcXVlcnkgb3BlcmF0aW9uc1xuXG4gIHByb3RlY3RlZCBxdWVyeUFsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlBbGxFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZXMgcXVlcnkgcmVzdWx0cyBwZXIgdGhlIE1lcmdlU3RyYXRlZ3lcbiAgICogU2V0cyBsb2FkaW5nIGZsYWcgdG8gZmFsc2UgYW5kIGxvYWRlZCBmbGFnIHRvIHRydWUuXG4gICAqL1xuICBwcm90ZWN0ZWQgcXVlcnlBbGxTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKSxcbiAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlCeUtleShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlciB8IHN0cmluZz5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlCeUtleUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHF1ZXJ5QnlLZXlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPVxuICAgICAgZGF0YSA9PSBudWxsXG4gICAgICAgID8gY29sbGVjdGlvblxuICAgICAgICA6IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgICAgIFtkYXRhXSxcbiAgICAgICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcXVlcnlMb2FkKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4pOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeUxvYWRFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb25cbiAgICogU2V0cyBsb2FkZWQgZmxhZyB0byB0cnVlLCBsb2FkaW5nIGZsYWcgdG8gZmFsc2UsXG4gICAqIGFuZCBjbGVhcnMgY2hhbmdlU3RhdGUgZm9yIHRoZSBlbnRpcmUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBxdWVyeUxvYWRTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmFkYXB0ZXIuc2V0QWxsKGRhdGEsIGNvbGxlY3Rpb24pLFxuICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICBjaGFuZ2VTdGF0ZToge30sXG4gICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvblxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVF1ZXJ5UmVzdWx0cyhcbiAgICAgICAgZGF0YSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKSxcbiAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBxdWVyeSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBzYXZlIG9wZXJhdGlvbnNcblxuICAvLyAjcmVnaW9uIHNhdmVBZGRNYW55XG4gIC8qKlxuICAgKiBTYXZlIG11bHRpcGxlIG5ldyBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgZGVsYXkgYWRkaW5nIHRvIGNvbGxlY3Rpb24gdW50aWwgc2VydmVyIGFja25vd2xlZGdlcyBzdWNjZXNzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHk7IGFkZCBpbW1lZGlhdGVseS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gd2hpY2ggdGhlIGVudGl0aWVzIHNob3VsZCBiZSBhZGRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGFycmF5IG9mIGVudGl0aWVzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBtdXN0IGhhdmUgdGhlaXIga2V5cy5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkTWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdGllcyhhY3Rpb24pOyAvLyBlbnN1cmUgdGhlIGVudGl0eSBoYXMgYSBQS1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tBZGRNYW55KFxuICAgICAgICBlbnRpdGllcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIuYWRkTWFueShlbnRpdGllcywgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc2F2ZSBuZXcgZW50aXRpZXMgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBuZXcgZW50aXRpZXMgYXJlIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgdW5zYXZlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVBZGRNYW55XG5cbiAgLy8gI3JlZ2lvbiBzYXZlQWRkT25lXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgbmV3IGVudGl0aWVzIHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgYWRkIHRoZSBlbnRpdGllcyBmcm9tIHRoZSBzZXJ2ZXIgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgYWRkZWQgZW50aXRpZXMgYXJlIGFscmVhZHkgaW4gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKSxcbiAgICogYW5kIG1heSBldmVuIHJldHVybiBhZGRpdGlvbmFsIG5ldyBlbnRpdGllcy5cbiAgICogVGhlcmVmb3JlLCB1cHNlcnQgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIGFkZCB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqIE5vdGU6IHNhdmVBZGRNYW55U3VjY2VzcyBkaWZmZXJzIGZyb20gc2F2ZUFkZE9uZVN1Y2Nlc3Mgd2hlbiBvcHRpbWlzdGljLlxuICAgKiBzYXZlQWRkT25lU3VjY2VzcyB1cGRhdGVzIChub3QgdXBzZXJ0cykgd2l0aCB0aGUgbG9uZSBlbnRpdHkgZnJvbSB0aGUgc2VydmVyLlxuICAgKiBUaGVyZSBpcyBubyBlZmZlY3QgaWYgdGhlIGVudGl0eSBpcyBub3QgYWxyZWFkeSBpbiBjYWNoZS5cbiAgICogc2F2ZUFkZE1hbnlTdWNjZXNzIHdpbGwgYWRkIGFuIGVudGl0eSBpZiBpdCBpcyBub3QgZm91bmQgaW4gY2FjaGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZUFkZE1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApIHtcbiAgICAvLyBGb3IgcGVzc2ltaXN0aWMgc2F2ZSwgZW5zdXJlIHRoZSBzZXJ2ZXIgZ2VuZXJhdGVkIHRoZSBwcmltYXJ5IGtleSBpZiB0aGUgY2xpZW50IGRpZG4ndCBzZW5kIG9uZS5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICAgIGVudGl0aWVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZUFkZHMoXG4gICAgICAgIGVudGl0aWVzLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlQWRkTWFueVxuXG4gIC8vICNyZWdpb24gc2F2ZUFkZE9uZVxuICAvKipcbiAgICogU2F2ZSBhIG5ldyBlbnRpdHkuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIGRlbGF5IGFkZGluZyB0byBjb2xsZWN0aW9uIHVudGlsIHNlcnZlciBhY2tub3dsZWRnZXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5OyBhZGQgZW50aXR5IGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB3aGljaCB0aGUgZW50aXR5IHNob3VsZCBiZSBhZGRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IG11c3QgaGF2ZSBhIGtleS5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7IC8vIGVuc3VyZSB0aGUgZW50aXR5IGhhcyBhIFBLXG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0FkZE9uZShcbiAgICAgICAgZW50aXR5LFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5hZGRPbmUoZW50aXR5LCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBzYXZlIGEgbmV3IGVudGl0eSBmYWlsZWQgb3IgdGltZWQtb3V0LlxuICAgKiBBY3Rpb24gaG9sZHMgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgaXMgbm90IGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSB1bnNhdmVkIGVudGl0eSBpcyBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlQWRkT25lRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIGEgbmV3IGVudGl0eSB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGFkZCB0aGUgZW50aXR5IGZyb20gdGhlIHNlcnZlciB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBhZGRlZCBlbnRpdHkgaXMgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCB0aGUgcmV0dXJuZWQgdmFsdWUgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVBZGRPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCB1cGRhdGU6IFVwZGF0ZVJlc3BvbnNlRGF0YTxUPiA9IHRoaXMudG9VcGRhdGUoZW50aXR5KTtcbiAgICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggYWRkZWQgZW50aXR5IHJldHVybmVkIGZyb20gc2VydmVyXG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwZGF0ZXMoXG4gICAgICAgIFt1cGRhdGVdLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5LFxuICAgICAgICBmYWxzZSAvKm5ldmVyIHNraXAqL1xuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVBZGRzKFxuICAgICAgICBbZW50aXR5XSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZUFkZE9uZVxuXG4gIC8vICNyZWdpb24gc2F2ZUFkZE1hbnlcbiAgLy8gVE9ETyBNQU5ZXG4gIC8vICNlbmRyZWdpb24gc2F2ZUFkZE1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVEZWxldGVPbmVcbiAgLyoqXG4gICAqIERlbGV0ZSBhbiBlbnRpdHkgZnJvbSB0aGUgc2VydmVyIGJ5IGtleSBhbmQgcmVtb3ZlIGl0IGZyb20gdGhlIGNvbGxlY3Rpb24gKGlmIHByZXNlbnQpLlxuICAgKiBJZiB0aGUgZW50aXR5IGlzIGFuIHVuc2F2ZWQgbmV3IGVudGl0eSwgcmVtb3ZlIGl0IGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHlcbiAgICogYW5kIHNraXAgdGhlIHNlcnZlciBkZWxldGUgcmVxdWVzdC5cbiAgICogQW4gb3B0aW1pc3RpYyBzYXZlIHJlbW92ZXMgYW4gZXhpc3RpbmcgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHk7XG4gICAqIGEgcGVzc2ltaXN0aWMgc2F2ZSByZW1vdmVzIGl0IGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzc2Z1bCBkZWxldGUuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFdpbGwgcmVtb3ZlIHRoZSBlbnRpdHkgd2l0aCB0aGlzIGtleSBmcm9tIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgd2hldGhlciB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEsIHdoaWNoIG11c3QgYmUgYSBwcmltYXJ5IGtleSBvciBhbiBlbnRpdHkgd2l0aCBhIGtleTtcbiAgICogdGhpcyByZWR1Y2VyIGV4dHJhY3RzIHRoZSBrZXkgZnJvbSB0aGUgZW50aXR5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVEZWxldGVPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxudW1iZXIgfCBzdHJpbmcgfCBUPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB0b0RlbGV0ZSA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKTtcbiAgICBjb25zdCBkZWxldGVJZCA9XG4gICAgICB0eXBlb2YgdG9EZWxldGUgPT09ICdvYmplY3QnXG4gICAgICAgID8gdGhpcy5zZWxlY3RJZCh0b0RlbGV0ZSlcbiAgICAgICAgOiAodG9EZWxldGUgYXMgc3RyaW5nIHwgbnVtYmVyKTtcbiAgICBjb25zdCBjaGFuZ2UgPSBjb2xsZWN0aW9uLmNoYW5nZVN0YXRlW2RlbGV0ZUlkXTtcbiAgICAvLyBJZiBlbnRpdHkgaXMgYWxyZWFkeSB0cmFja2VkIC4uLlxuICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgIGlmIChjaGFuZ2UuY2hhbmdlVHlwZSA9PT0gQ2hhbmdlVHlwZS5BZGRlZCkge1xuICAgICAgICAvLyBSZW1vdmUgdGhlIGFkZGVkIGVudGl0eSBpbW1lZGlhdGVseSBhbmQgZm9yZ2V0IGFib3V0IGl0cyBjaGFuZ2VzICh2aWEgY29tbWl0KS5cbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVPbmUoZGVsZXRlSWQgYXMgc3RyaW5nLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoZGVsZXRlSWQsIGNvbGxlY3Rpb24pO1xuICAgICAgICAvLyBTaG91bGQgbm90IHdhc3RlIGVmZm9ydCB0cnlpbmcgdG8gZGVsZXRlIG9uIHRoZSBzZXJ2ZXIgYmVjYXVzZSBpdCBjYW4ndCBiZSB0aGVyZS5cbiAgICAgICAgYWN0aW9uLnBheWxvYWQuc2tpcCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZS10cmFjayBpdCBhcyBhIGRlbGV0ZSwgZXZlbiBpZiB0cmFja2luZyBpcyB0dXJuZWQgb2ZmIGZvciB0aGlzIGNhbGwuXG4gICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVPbmUoXG4gICAgICAgICAgZGVsZXRlSWQsXG4gICAgICAgICAgY29sbGVjdGlvblxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG9wdGltaXN0aWMgZGVsZXRlLCB0cmFjayBjdXJyZW50IHN0YXRlIGFuZCByZW1vdmUgaW1tZWRpYXRlbHkuXG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrRGVsZXRlT25lKFxuICAgICAgICBkZWxldGVJZCxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBkZWxldGUgdGhlIGVudGl0eSBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0eSBjb3VsZCBzdGlsbCBiZSBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlT25lRXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgZW50aXR5IG9uIHRoZSBzZXJ2ZXIuIFRoZSBrZXkgb2YgdGhlIGRlbGV0ZWQgZW50aXR5IGlzIGluIHRoZSBhY3Rpb24gcGF5bG9hZCBkYXRhLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGlmIHRoZSBlbnRpdHkgaXMgc3RpbGwgaW4gdGhlIGNvbGxlY3Rpb24gaXQgd2lsbCBiZSByZW1vdmVkLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0eSBoYXMgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlT25lU3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlciB8IHN0cmluZz5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGVsZXRlSWQgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZURlbGV0ZXMoXG4gICAgICAgIFtkZWxldGVJZF0sXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFBlc3NpbWlzdGljOiBpZ25vcmUgbWVyZ2VTdHJhdGVneS4gUmVtb3ZlIGVudGl0eSBmcm9tIHRoZSBjb2xsZWN0aW9uIGFuZCBmcm9tIGNoYW5nZSB0cmFja2luZy5cbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIucmVtb3ZlT25lKGRlbGV0ZUlkIGFzIHN0cmluZywgY29sbGVjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE9uZShkZWxldGVJZCwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuICAvLyAjZW5kcmVnaW9uIHNhdmVEZWxldGVPbmVcblxuICAvLyAjcmVnaW9uIHNhdmVEZWxldGVNYW55XG4gIC8qKlxuICAgKiBEZWxldGUgbXVsdGlwbGUgZW50aXRpZXMgZnJvbSB0aGUgc2VydmVyIGJ5IGtleSBhbmQgcmVtb3ZlIHRoZW0gZnJvbSB0aGUgY29sbGVjdGlvbiAoaWYgcHJlc2VudCkuXG4gICAqIFJlbW92ZXMgdW5zYXZlZCBuZXcgZW50aXRpZXMgZnJvbSB0aGUgY29sbGVjdGlvbiBpbW1lZGlhdGVseVxuICAgKiBidXQgdGhlIGlkIGlzIHN0aWxsIHNlbnQgdG8gdGhlIHNlcnZlciBmb3IgZGVsZXRpb24gZXZlbiB0aG91Z2ggdGhlIHNlcnZlciB3aWxsIG5vdCBmaW5kIHRoYXQgZW50aXR5LlxuICAgKiBUaGVyZWZvcmUsIHRoZSBzZXJ2ZXIgbXVzdCBiZSB3aWxsaW5nIHRvIGlnbm9yZSBhIGRlbGV0ZSByZXF1ZXN0IGZvciBhbiBlbnRpdHkgaXQgY2Fubm90IGZpbmQuXG4gICAqIEFuIG9wdGltaXN0aWMgc2F2ZSByZW1vdmVzIGV4aXN0aW5nIGVudGl0aWVzIGZyb20gdGhlIGNvbGxlY3Rpb24gaW1tZWRpYXRlbHk7XG4gICAqIGEgcGVzc2ltaXN0aWMgc2F2ZSByZW1vdmVzIHRoZW0gYWZ0ZXIgdGhlIHNlcnZlciBjb25maXJtcyBzdWNjZXNzZnVsIGRlbGV0ZS5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gUmVtb3ZlcyBlbnRpdGllcyBmcm9tIHRoaXMgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGFuIGFycmF5IG9mIHByaW1hcnkga2V5cyBvciBlbnRpdGllcyB3aXRoIGEga2V5O1xuICAgKiB0aGlzIHJlZHVjZXIgZXh0cmFjdHMgdGhlIGtleSBmcm9tIHRoZSBlbnRpdHkuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjwobnVtYmVyIHwgc3RyaW5nIHwgVClbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgZGVsZXRlSWRzID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLm1hcCgoZCkgPT5cbiAgICAgIHR5cGVvZiBkID09PSAnb2JqZWN0JyA/IHRoaXMuc2VsZWN0SWQoZCkgOiAoZCBhcyBzdHJpbmcgfCBudW1iZXIpXG4gICAgKTtcbiAgICBkZWxldGVJZHMuZm9yRWFjaCgoZGVsZXRlSWQpID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZSA9IGNvbGxlY3Rpb24uY2hhbmdlU3RhdGVbZGVsZXRlSWRdO1xuICAgICAgLy8gSWYgZW50aXR5IGlzIGFscmVhZHkgdHJhY2tlZCAuLi5cbiAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgaWYgKGNoYW5nZS5jaGFuZ2VUeXBlID09PSBDaGFuZ2VUeXBlLkFkZGVkKSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIHRoZSBhZGRlZCBlbnRpdHkgaW1tZWRpYXRlbHkgYW5kIGZvcmdldCBhYm91dCBpdHMgY2hhbmdlcyAodmlhIGNvbW1pdCkuXG4gICAgICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVPbmUoZGVsZXRlSWQgYXMgc3RyaW5nLCBjb2xsZWN0aW9uKTtcbiAgICAgICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE9uZShkZWxldGVJZCwgY29sbGVjdGlvbik7XG4gICAgICAgICAgLy8gU2hvdWxkIG5vdCB3YXN0ZSBlZmZvcnQgdHJ5aW5nIHRvIGRlbGV0ZSBvbiB0aGUgc2VydmVyIGJlY2F1c2UgaXQgY2FuJ3QgYmUgdGhlcmUuXG4gICAgICAgICAgYWN0aW9uLnBheWxvYWQuc2tpcCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmUtdHJhY2sgaXQgYXMgYSBkZWxldGUsIGV2ZW4gaWYgdHJhY2tpbmcgaXMgdHVybmVkIG9mZiBmb3IgdGhpcyBjYWxsLlxuICAgICAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVPbmUoXG4gICAgICAgICAgICBkZWxldGVJZCxcbiAgICAgICAgICAgIGNvbGxlY3Rpb25cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gSWYgb3B0aW1pc3RpYyBkZWxldGUsIHRyYWNrIGN1cnJlbnQgc3RhdGUgYW5kIHJlbW92ZSBpbW1lZGlhdGVseS5cbiAgICBpZiAodGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKSkge1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVNYW55KFxuICAgICAgICBkZWxldGVJZHMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkoZGVsZXRlSWRzIGFzIHN0cmluZ1tdLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byBkZWxldGUgdGhlIGVudGl0aWVzIG9uIHRoZSBzZXJ2ZXIgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgY291bGQgc3RpbGwgYmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGFyZSBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZURlbGV0ZU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgZGVsZXRlZCBlbnRpdGllcyBvbiB0aGUgc2VydmVyLiBUaGUga2V5cyBvZiB0aGUgZGVsZXRlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGFjdGlvbiBwYXlsb2FkIGRhdGEuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgZW50aXRpZXMgdGhhdCBhcmUgc3RpbGwgaW4gdGhlIGNvbGxlY3Rpb24gd2lsbCBiZSByZW1vdmVkLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGVudGl0aWVzIGhhdmUgYWxyZWFkeSBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY29sbGVjdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlRGVsZXRlTWFueVN1Y2Nlc3MoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjwobnVtYmVyIHwgc3RyaW5nKVtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBkZWxldGVJZHMgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgaWYgKHRoaXMuaXNPcHRpbWlzdGljKGFjdGlvbikpIHtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZURlbGV0ZXMoXG4gICAgICAgIGRlbGV0ZUlkcyxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUGVzc2ltaXN0aWM6IGlnbm9yZSBtZXJnZVN0cmF0ZWd5LiBSZW1vdmUgZW50aXR5IGZyb20gdGhlIGNvbGxlY3Rpb24gYW5kIGZyb20gY2hhbmdlIHRyYWNraW5nLlxuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci5yZW1vdmVNYW55KGRlbGV0ZUlkcyBhcyBzdHJpbmdbXSwgY29sbGVjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLmNvbW1pdE1hbnkoZGVsZXRlSWRzLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZURlbGV0ZU1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVVcGRhdGVPbmVcbiAgLyoqXG4gICAqIFNhdmUgYW4gdXBkYXRlIHRvIGFuIGV4aXN0aW5nIGVudGl0eS5cbiAgICogSWYgc2F2aW5nIHBlc3NpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gYWZ0ZXIgdGhlIHNlcnZlciBjb25maXJtcyBzdWNjZXNzLlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHVwZGF0ZSB0aGUgZW50aXR5IGltbWVkaWF0ZWx5LCBiZWZvcmUgdGhlIHNhdmUgcmVxdWVzdC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyBpZiB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4ge1VwZGF0ZTxUPn1cbiAgICovXG4gIHByb3RlY3RlZCBzYXZlVXBkYXRlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlPFQ+PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZShhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU9uZShcbiAgICAgICAgdXBkYXRlLFxuICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgICApO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuYWRhcHRlci51cGRhdGVPbmUodXBkYXRlLCBjb2xsZWN0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ1RydWUoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQXR0ZW1wdCB0byB1cGRhdGUgdGhlIGVudGl0eSBvbiB0aGUgc2VydmVyIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdGhlIGVudGl0eSBpbiB0aGUgY29sbGVjdGlvbiBpcyBpbiB0aGUgcHJlLXNhdmUgc3RhdGVcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdhcyB1cGRhdGVkXG4gICAqIGFuZCB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVPbmVFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgdGhlIHVwZGF0ZWQgZW50aXR5IHRvIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCBkYXRhIGZyb20gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgd2FzIGFscmVhZHkgdXBkYXRlZCBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdHkgaW4gdGhlIGNvbGxlY3Rpb24gd2l0aCB0aGUgcmV0dXJuZWQgdmFsdWUgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyB1cGRhdGUgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB1cGRhdGVcbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIGlmIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsIGFuZFxuICAgKiB0aGUgdXBkYXRlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4gVXBkYXRlUmVzcG9uc2U8VD4gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgVXBkYXRlIHNlbnQgdG8gdGhlIHNlcnZlci5cbiAgICogWW91IG11c3QgaW5jbHVkZSBhbiBVcGRhdGVSZXNwb25zZSBldmVuIGlmIHRoZSBzYXZlIHdhcyBvcHRpbWlzdGljLFxuICAgKiB0byBlbnN1cmUgdGhhdCB0aGUgY2hhbmdlIHRyYWNraW5nIGlzIHByb3Blcmx5IHJlc2V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VXBkYXRlUmVzcG9uc2VEYXRhPFQ+PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLmd1YXJkLm11c3RCZVVwZGF0ZVJlc3BvbnNlKGFjdGlvbik7XG4gICAgY29uc3QgaXNPcHRpbWlzdGljID0gdGhpcy5pc09wdGltaXN0aWMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIubWVyZ2VTYXZlVXBkYXRlcyhcbiAgICAgIFt1cGRhdGVdLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3ksXG4gICAgICBpc09wdGltaXN0aWMgLypza2lwIHVuY2hhbmdlZCBpZiBvcHRpbWlzdGljICovXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBkYXRlT25lXG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBkYXRlTWFueVxuICAvKipcbiAgICogU2F2ZSB1cGRhdGVkIGVudGl0aWVzLlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCB1cGRhdGUgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIGFmdGVyIHRoZSBzZXJ2ZXIgY29uZmlybXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB1cGRhdGUgdGhlIGVudGl0aWVzIGltbWVkaWF0ZWx5LCBiZWZvcmUgdGhlIHNhdmUgcmVxdWVzdC5cbiAgICogQHBhcmFtIGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gdXBkYXRlXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyBpZiB0aGUgc2F2ZSBpcyBvcHRpbWlzdGljLFxuICAgKiBhbmQgdGhlIGRhdGEgd2hpY2gsIG11c3QgYmUgYW4gYXJyYXkgb2Yge1VwZGF0ZTxUPn0uXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwZGF0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD5bXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgY29uc3QgdXBkYXRlcyA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlcyhhY3Rpb24pO1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU1hbnkoXG4gICAgICAgIHVwZGF0ZXMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwZGF0ZU1hbnkodXBkYXRlcywgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gdXBkYXRlIGVudGl0aWVzIG9uIHRoZSBzZXJ2ZXIgZmFpbGVkIG9yIHRpbWVkLW91dC5cbiAgICogQWN0aW9uIGhvbGRzIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gYXJlIGluIHRoZSBwcmUtc2F2ZSBzdGF0ZVxuICAgKiB5b3UgbWF5IG5vdCBoYXZlIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBlcnJvci5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3ZXJlIHVwZGF0ZWRcbiAgICogYW5kIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwZGF0ZU1hbnlFcnJvcihcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPEVudGl0eUFjdGlvbkRhdGFTZXJ2aWNlRXJyb3I+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGYWxzZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWNjZXNzZnVsbHkgc2F2ZWQgdGhlIHVwZGF0ZWQgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2lsbCBiZSB1cGRhdGVkIHdpdGggZGF0YSBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgaW4gdGhlIGNvbGxlY3Rpb24gd2VyZSBhbHJlYWR5IHVwZGF0ZWQuXG4gICAqIEhvd2V2ZXIsIHRoZSBzZXJ2ZXIgbWlnaHQgaGF2ZSBzZXQgb3IgbW9kaWZpZWQgb3RoZXIgZmllbGRzIChlLmcsIGNvbmN1cnJlbmN5IGZpZWxkKVxuICAgKiBUaGVyZWZvcmUsIHVwZGF0ZSB0aGUgZW50aXR5IGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIHVwZGF0ZSB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0gYWN0aW9uIFRoZSBhY3Rpb24gcGF5bG9hZCBob2xkcyBvcHRpb25zLCBpbmNsdWRpbmcgaWYgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhIHdoaWNoLCBtdXN0IGJlIGFuIGFycmF5IG9mIFVwZGF0ZVJlc3BvbnNlPFQ+LlxuICAgKiBZb3UgbXVzdCBpbmNsdWRlIGFuIFVwZGF0ZVJlc3BvbnNlIGZvciBldmVyeSBVcGRhdGUgc2VudCB0byB0aGUgc2VydmVyLFxuICAgKiBldmVuIGlmIHRoZSBzYXZlIHdhcyBvcHRpbWlzdGljLCB0byBlbnN1cmUgdGhhdCB0aGUgY2hhbmdlIHRyYWNraW5nIGlzIHByb3Blcmx5IHJlc2V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcGRhdGVNYW55U3VjY2VzcyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFVwZGF0ZVJlc3BvbnNlRGF0YTxUPltdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCB1cGRhdGVzID0gdGhpcy5ndWFyZC5tdXN0QmVVcGRhdGVSZXNwb25zZXMoYWN0aW9uKTtcbiAgICBjb25zdCBpc09wdGltaXN0aWMgPSB0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5tZXJnZVNhdmVVcGRhdGVzKFxuICAgICAgdXBkYXRlcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5LFxuICAgICAgZmFsc2UgLyogbmV2ZXIgc2tpcCAqL1xuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG4gIC8vICNlbmRyZWdpb24gc2F2ZVVwZGF0ZU1hbnlcblxuICAvLyAjcmVnaW9uIHNhdmVVcHNlcnRPbmVcbiAgLyoqXG4gICAqIFNhdmUgYSBuZXcgb3IgZXhpc3RpbmcgZW50aXR5LlxuICAgKiBJZiBzYXZpbmcgcGVzc2ltaXN0aWNhbGx5LCBkZWxheSBhZGRpbmcgdG8gY29sbGVjdGlvbiB1bnRpbCBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHN1Y2Nlc3MuXG4gICAqIElmIHNhdmluZyBvcHRpbWlzdGljYWxseTsgYWRkIGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byB3aGljaCB0aGUgZW50aXR5IHNob3VsZCBiZSB1cHNlcnRlZC5cbiAgICogQHBhcmFtIGFjdGlvbiBUaGUgYWN0aW9uIHBheWxvYWQgaG9sZHMgb3B0aW9ucywgaW5jbHVkaW5nIHdoZXRoZXIgdGhlIHNhdmUgaXMgb3B0aW1pc3RpYyxcbiAgICogYW5kIHRoZSBkYXRhLCB3aGljaCBtdXN0IGJlIGEgd2hvbGUgZW50aXR5LlxuICAgKiBJZiBzYXZpbmcgb3B0aW1pc3RpY2FsbHksIHRoZSBlbnRpdHkgbXVzdCBoYXZlIGl0cyBrZXkuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pOyAvLyBlbnN1cmUgdGhlIGVudGl0eSBoYXMgYSBQS1xuICAgICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tVcHNlcnRPbmUoXG4gICAgICAgIGVudGl0eSxcbiAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgbWVyZ2VTdHJhdGVneVxuICAgICAgKTtcbiAgICAgIGNvbGxlY3Rpb24gPSB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lKGVudGl0eSwgY29sbGVjdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdUcnVlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGVtcHQgdG8gc2F2ZSBuZXcgb3IgZXhpc3RpbmcgZW50aXR5IGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgbmV3IG9yIHVwZGF0ZWQgZW50aXR5IGlzIG5vdCBpbiB0aGUgY29sbGVjdGlvbiBhbmRcbiAgICogeW91IG1heSBub3QgaGF2ZSB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIG9wdGltaXN0aWNhbGx5LCB0aGUgdW5zYXZlZCBlbnRpdGllcyBhcmUgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbmVlZCB0byBjb21wZW5zYXRlIGZvciB0aGUgZXJyb3IuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE9uZUVycm9yKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248RW50aXR5QWN0aW9uRGF0YVNlcnZpY2VFcnJvcj5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZhbHNlKGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1Y2Nlc3NmdWxseSBzYXZlZCBuZXcgb3IgZXhpc3RpbmcgZW50aXRpZXMgdG8gdGhlIHNlcnZlci5cbiAgICogSWYgc2F2ZWQgcGVzc2ltaXN0aWNhbGx5LCBhZGQgdGhlIGVudGl0aWVzIGZyb20gdGhlIHNlcnZlciB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogSWYgc2F2ZWQgb3B0aW1pc3RpY2FsbHksIHRoZSBhZGRlZCBlbnRpdGllcyBhcmUgYWxyZWFkeSBpbiB0aGUgY29sbGVjdGlvbi5cbiAgICogSG93ZXZlciwgdGhlIHNlcnZlciBtaWdodCBoYXZlIHNldCBvciBtb2RpZmllZCBvdGhlciBmaWVsZHMgKGUuZywgY29uY3VycmVuY3kgZmllbGQpXG4gICAqIFRoZXJlZm9yZSwgdXBkYXRlIHRoZSBlbnRpdGllcyBpbiB0aGUgY29sbGVjdGlvbiB3aXRoIHRoZSByZXR1cm5lZCB2YWx1ZXMgKGlmIGFueSlcbiAgICogQ2F1dGlvbjogaW4gYSByYWNlLCB0aGlzIHVwZGF0ZSBjb3VsZCBvdmVyd3JpdGUgdW5zYXZlZCB1c2VyIGNoYW5nZXMuXG4gICAqIFVzZSBwZXNzaW1pc3RpYyBhZGQgdG8gYXZvaWQgdGhpcyByaXNrLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRPbmVTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgLy8gRm9yIHBlc3NpbWlzdGljIHNhdmUsIGVuc3VyZSB0aGUgc2VydmVyIGdlbmVyYXRlZCB0aGUgcHJpbWFyeSBrZXkgaWYgdGhlIGNsaWVudCBkaWRuJ3Qgc2VuZCBvbmUuXG4gICAgY29uc3QgZW50aXR5ID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdHkoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggdXBzZXJ0ZWQgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSBzZXJ2ZXJcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICBbZW50aXR5XSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBzZXJ0T25lXG5cbiAgLy8gI3JlZ2lvbiBzYXZlVXBzZXJ0TWFueVxuICAvKipcbiAgICogU2F2ZSBtdWx0aXBsZSBuZXcgb3IgZXhpc3RpbmcgZW50aXRpZXMuXG4gICAqIElmIHNhdmluZyBwZXNzaW1pc3RpY2FsbHksIGRlbGF5IGFkZGluZyB0byBjb2xsZWN0aW9uIHVudGlsIHNlcnZlciBhY2tub3dsZWRnZXMgc3VjY2Vzcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5OyBhZGQgaW1tZWRpYXRlbHkuXG4gICAqIEBwYXJhbSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIHdoaWNoIHRoZSBlbnRpdGllcyBzaG91bGQgYmUgdXBzZXJ0ZWQuXG4gICAqIEBwYXJhbSBhY3Rpb24gVGhlIGFjdGlvbiBwYXlsb2FkIGhvbGRzIG9wdGlvbnMsIGluY2x1ZGluZyB3aGV0aGVyIHRoZSBzYXZlIGlzIG9wdGltaXN0aWMsXG4gICAqIGFuZCB0aGUgZGF0YSwgd2hpY2ggbXVzdCBiZSBhbiBhcnJheSBvZiB3aG9sZSBlbnRpdGllcy5cbiAgICogSWYgc2F2aW5nIG9wdGltaXN0aWNhbGx5LCB0aGUgZW50aXRpZXMgbXVzdCBoYXZlIHRoZWlyIGtleXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGlmICh0aGlzLmlzT3B0aW1pc3RpYyhhY3Rpb24pKSB7XG4gICAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTsgLy8gZW5zdXJlIHRoZSBlbnRpdHkgaGFzIGEgUEtcbiAgICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBzZXJ0TWFueShcbiAgICAgICAgZW50aXRpZXMsXG4gICAgICAgIGNvbGxlY3Rpb24sXG4gICAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICAgICk7XG4gICAgICBjb2xsZWN0aW9uID0gdGhpcy5hZGFwdGVyLnVwc2VydE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nVHJ1ZShjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRlbXB0IHRvIHNhdmUgbmV3IG9yIGV4aXN0aW5nIGVudGl0aWVzIGZhaWxlZCBvciB0aW1lZC1vdXQuXG4gICAqIEFjdGlvbiBob2xkcyB0aGUgZXJyb3IuXG4gICAqIElmIHNhdmVkIHBlc3NpbWlzdGljYWxseSwgbmV3IGVudGl0aWVzIGFyZSBub3QgaW4gdGhlIGNvbGxlY3Rpb24gYW5kXG4gICAqIHlvdSBtYXkgbm90IGhhdmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIHVuc2F2ZWQgZW50aXRpZXMgYXJlIGluIHRoZSBjb2xsZWN0aW9uIGFuZFxuICAgKiB5b3UgbWF5IG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgdGhlIGVycm9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNhdmVVcHNlcnRNYW55RXJyb3IoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlBY3Rpb25EYXRhU2VydmljZUVycm9yPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogU3VjY2Vzc2Z1bGx5IHNhdmVkIG5ldyBvciBleGlzdGluZyBlbnRpdGllcyB0byB0aGUgc2VydmVyLlxuICAgKiBJZiBzYXZlZCBwZXNzaW1pc3RpY2FsbHksIGFkZCB0aGUgZW50aXRpZXMgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBJZiBzYXZlZCBvcHRpbWlzdGljYWxseSwgdGhlIGFkZGVkIGVudGl0aWVzIGFyZSBhbHJlYWR5IGluIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBIb3dldmVyLCB0aGUgc2VydmVyIG1pZ2h0IGhhdmUgc2V0IG9yIG1vZGlmaWVkIG90aGVyIGZpZWxkcyAoZS5nLCBjb25jdXJyZW5jeSBmaWVsZClcbiAgICogVGhlcmVmb3JlLCB1cGRhdGUgdGhlIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uIHdpdGggdGhlIHJldHVybmVkIHZhbHVlcyAoaWYgYW55KVxuICAgKiBDYXV0aW9uOiBpbiBhIHJhY2UsIHRoaXMgdXBkYXRlIGNvdWxkIG92ZXJ3cml0ZSB1bnNhdmVkIHVzZXIgY2hhbmdlcy5cbiAgICogVXNlIHBlc3NpbWlzdGljIGFkZCB0byBhdm9pZCB0aGlzIHJpc2suXG4gICAqL1xuICBwcm90ZWN0ZWQgc2F2ZVVwc2VydE1hbnlTdWNjZXNzKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApIHtcbiAgICAvLyBGb3IgcGVzc2ltaXN0aWMgc2F2ZSwgZW5zdXJlIHRoZSBzZXJ2ZXIgZ2VuZXJhdGVkIHRoZSBwcmltYXJ5IGtleSBpZiB0aGUgY2xpZW50IGRpZG4ndCBzZW5kIG9uZS5cbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIC8vIEFsd2F5cyB1cGRhdGUgdGhlIGNhY2hlIHdpdGggdXBzZXJ0ZWQgZW50aXRpZXMgcmV0dXJuZWQgZnJvbSBzZXJ2ZXJcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLm1lcmdlU2F2ZVVwc2VydHMoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXRMb2FkaW5nRmFsc2UoY29sbGVjdGlvbik7XG4gIH1cbiAgLy8gI2VuZHJlZ2lvbiBzYXZlVXBzZXJ0TWFueVxuXG4gIC8vICNlbmRyZWdpb24gc2F2ZSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBjYWNoZS1vbmx5IG9wZXJhdGlvbnNcblxuICAvKipcbiAgICogUmVwbGFjZXMgYWxsIGVudGl0aWVzIGluIHRoZSBjb2xsZWN0aW9uXG4gICAqIFNldHMgbG9hZGVkIGZsYWcgdG8gdHJ1ZS5cbiAgICogTWVyZ2VzIHF1ZXJ5IHJlc3VsdHMsIHByZXNlcnZpbmcgdW5zYXZlZCBjaGFuZ2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgYWRkQWxsKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VFtdPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBlbnRpdGllcyA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXRpZXMoYWN0aW9uKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5hZGFwdGVyLnNldEFsbChlbnRpdGllcywgY29sbGVjdGlvbiksXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgIGNoYW5nZVN0YXRlOiB7fSxcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFkZE1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGVudGl0aWVzID0gdGhpcy5ndWFyZC5tdXN0QmVFbnRpdGllcyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0FkZE1hbnkoXG4gICAgICBlbnRpdGllcyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFkZE1hbnkoZW50aXRpZXMsIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFkZE9uZShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZ3VhcmQubXVzdEJlRW50aXR5KGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrQWRkT25lKFxuICAgICAgZW50aXR5LFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuYWRkT25lKGVudGl0eSwgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlTWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPG51bWJlcltdIHwgc3RyaW5nW10+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIHBheWxvYWQgbXVzdCBiZSBlbnRpdHkga2V5c1xuICAgIGNvbnN0IGtleXMgPSB0aGlzLmd1YXJkLm11c3RCZUtleXMoYWN0aW9uKSBhcyBzdHJpbmdbXTtcbiAgICBjb25zdCBtZXJnZVN0cmF0ZWd5ID0gdGhpcy5leHRyYWN0TWVyZ2VTdHJhdGVneShhY3Rpb24pO1xuICAgIGNvbGxlY3Rpb24gPSB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudHJhY2tEZWxldGVNYW55KFxuICAgICAga2V5cyxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJlbW92ZU1hbnkoa2V5cywgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlT25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248bnVtYmVyIHwgc3RyaW5nPlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICAvLyBwYXlsb2FkIG11c3QgYmUgZW50aXR5IGtleVxuICAgIGNvbnN0IGtleSA9IHRoaXMuZ3VhcmQubXVzdEJlS2V5KGFjdGlvbikgYXMgc3RyaW5nO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja0RlbGV0ZU9uZShcbiAgICAgIGtleSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJlbW92ZU9uZShrZXksIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlbW92ZUFsbChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmFkYXB0ZXIucmVtb3ZlQWxsKGNvbGxlY3Rpb24pLFxuICAgICAgbG9hZGVkOiBmYWxzZSwgLy8gT25seSBSRU1PVkVfQUxMIHNldHMgbG9hZGVkIHRvIGZhbHNlXG4gICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgIGNoYW5nZVN0YXRlOiB7fSwgLy8gQXNzdW1lIGNsZWFyaW5nIHRoZSBjb2xsZWN0aW9uIGFuZCBub3QgdHJ5aW5nIHRvIGRlbGV0ZSBhbGwgZW50aXRpZXNcbiAgICB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZU1hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD5bXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gcGF5bG9hZCBtdXN0IGJlIGFuIGFycmF5IG9mIGBVcGRhdGVzPFQ+YCwgbm90IGVudGl0aWVzXG4gICAgY29uc3QgdXBkYXRlcyA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlcyhhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1VwZGF0ZU1hbnkoXG4gICAgICB1cGRhdGVzLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlTWFueSh1cGRhdGVzLCBjb2xsZWN0aW9uKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVPbmUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxVcGRhdGU8VD4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIC8vIHBheWxvYWQgbXVzdCBiZSBhbiBgVXBkYXRlPFQ+YCwgbm90IGFuIGVudGl0eVxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMuZ3VhcmQubXVzdEJlVXBkYXRlKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBkYXRlT25lKFxuICAgICAgdXBkYXRlLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBkYXRlT25lKHVwZGF0ZSwgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBzZXJ0TWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gPHY2OiBwYXlsb2FkIG11c3QgYmUgYW4gYXJyYXkgb2YgYFVwZGF0ZXM8VD5gLCBub3QgZW50aXRpZXNcbiAgICAvLyB2Nis6IHBheWxvYWQgbXVzdCBiZSBhbiBhcnJheSBvZiBUXG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0aWVzKGFjdGlvbik7XG4gICAgY29uc3QgbWVyZ2VTdHJhdGVneSA9IHRoaXMuZXh0cmFjdE1lcmdlU3RyYXRlZ3koYWN0aW9uKTtcbiAgICBjb2xsZWN0aW9uID0gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnRyYWNrVXBzZXJ0TWFueShcbiAgICAgIGVudGl0aWVzLFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIG1lcmdlU3RyYXRlZ3lcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0TWFueShlbnRpdGllcywgY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdXBzZXJ0T25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgLy8gPHY2OiBwYXlsb2FkIG11c3QgYmUgYW4gYFVwZGF0ZTxUPmAsIG5vdCBhbiBlbnRpdHlcbiAgICAvLyB2Nis6IHBheWxvYWQgbXVzdCBiZSBhIFRcbiAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmd1YXJkLm11c3RCZUVudGl0eShhY3Rpb24pO1xuICAgIGNvbnN0IG1lcmdlU3RyYXRlZ3kgPSB0aGlzLmV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbik7XG4gICAgY29sbGVjdGlvbiA9IHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci50cmFja1Vwc2VydE9uZShcbiAgICAgIGVudGl0eSxcbiAgICAgIGNvbGxlY3Rpb24sXG4gICAgICBtZXJnZVN0cmF0ZWd5XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwc2VydE9uZShlbnRpdHksIGNvbGxlY3Rpb24pO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbW1pdEFsbChjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+KSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRBbGwoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tbWl0TWFueShcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPFRbXT5cbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRNYW55KFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tbWl0T25lKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248VD5cbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci5jb21taXRPbmUoXG4gICAgICB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbiksXG4gICAgICBjb2xsZWN0aW9uXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1bmRvQWxsKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4pIHtcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlDaGFuZ2VUcmFja2VyLnVuZG9BbGwoY29sbGVjdGlvbik7XG4gIH1cblxuICBwcm90ZWN0ZWQgdW5kb01hbnkoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxUW10+XG4gICkge1xuICAgIHJldHVybiB0aGlzLmVudGl0eUNoYW5nZVRyYWNrZXIudW5kb01hbnkoXG4gICAgICB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbiksXG4gICAgICBjb2xsZWN0aW9uXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1bmRvT25lKGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sIGFjdGlvbjogRW50aXR5QWN0aW9uPFQ+KSB7XG4gICAgcmV0dXJuIHRoaXMuZW50aXR5Q2hhbmdlVHJhY2tlci51bmRvT25lKFxuICAgICAgdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pLFxuICAgICAgY29sbGVjdGlvblxuICAgICk7XG4gIH1cblxuICAvKiogRGFuZ2Vyb3VzOiBDb21wbGV0ZWx5IHJlcGxhY2UgdGhlIGNvbGxlY3Rpb24ncyBDaGFuZ2VTdGF0ZS4gVXNlIHJhcmVseSBhbmQgd2lzZWx5LiAqL1xuICBwcm90ZWN0ZWQgc2V0Q2hhbmdlU3RhdGUoXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxDaGFuZ2VTdGF0ZU1hcDxUPj5cbiAgKSB7XG4gICAgY29uc3QgY2hhbmdlU3RhdGUgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24uY2hhbmdlU3RhdGUgPT09IGNoYW5nZVN0YXRlXG4gICAgICA/IGNvbGxlY3Rpb25cbiAgICAgIDogeyAuLi5jb2xsZWN0aW9uLCBjaGFuZ2VTdGF0ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIERhbmdlcm91czogQ29tcGxldGVseSByZXBsYWNlIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBQcmltYXJpbHkgZm9yIHRlc3RpbmcgYW5kIHJlaHlkcmF0aW9uIGZyb20gbG9jYWwgc3RvcmFnZS5cbiAgICogVXNlIHJhcmVseSBhbmQgd2lzZWx5LlxuICAgKi9cbiAgcHJvdGVjdGVkIHNldENvbGxlY3Rpb24oXG4gICAgY29sbGVjdGlvbjogRW50aXR5Q29sbGVjdGlvbjxUPixcbiAgICBhY3Rpb246IEVudGl0eUFjdGlvbjxFbnRpdHlDb2xsZWN0aW9uPFQ+PlxuICApIHtcbiAgICBjb25zdCBuZXdDb2xsZWN0aW9uID0gdGhpcy5leHRyYWN0RGF0YShhY3Rpb24pO1xuICAgIHJldHVybiBjb2xsZWN0aW9uID09PSBuZXdDb2xsZWN0aW9uID8gY29sbGVjdGlvbiA6IG5ld0NvbGxlY3Rpb247XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0RmlsdGVyKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD4sXG4gICAgYWN0aW9uOiBFbnRpdHlBY3Rpb248YW55PlxuICApOiBFbnRpdHlDb2xsZWN0aW9uPFQ+IHtcbiAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmV4dHJhY3REYXRhKGFjdGlvbik7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24uZmlsdGVyID09PSBmaWx0ZXJcbiAgICAgID8gY29sbGVjdGlvblxuICAgICAgOiB7IC4uLmNvbGxlY3Rpb24sIGZpbHRlciB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRlZChcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPGJvb2xlYW4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSA9PT0gdHJ1ZSB8fCBmYWxzZTtcbiAgICByZXR1cm4gY29sbGVjdGlvbi5sb2FkZWQgPT09IGxvYWRlZFxuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgbG9hZGVkIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0TG9hZGluZyhcbiAgICBjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LFxuICAgIGFjdGlvbjogRW50aXR5QWN0aW9uPGJvb2xlYW4+XG4gICk6IEVudGl0eUNvbGxlY3Rpb248VD4ge1xuICAgIHJldHVybiB0aGlzLnNldExvYWRpbmdGbGFnKGNvbGxlY3Rpb24sIHRoaXMuZXh0cmFjdERhdGEoYWN0aW9uKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0TG9hZGluZ0ZhbHNlKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZsYWcoY29sbGVjdGlvbiwgZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNldExvYWRpbmdUcnVlKFxuICAgIGNvbGxlY3Rpb246IEVudGl0eUNvbGxlY3Rpb248VD5cbiAgKTogRW50aXR5Q29sbGVjdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuc2V0TG9hZGluZ0ZsYWcoY29sbGVjdGlvbiwgdHJ1ZSk7XG4gIH1cblxuICAvKiogU2V0IHRoZSBjb2xsZWN0aW9uJ3MgbG9hZGluZyBmbGFnICovXG4gIHByb3RlY3RlZCBzZXRMb2FkaW5nRmxhZyhjb2xsZWN0aW9uOiBFbnRpdHlDb2xsZWN0aW9uPFQ+LCBsb2FkaW5nOiBib29sZWFuKSB7XG4gICAgbG9hZGluZyA9IGxvYWRpbmcgPT09IHRydWUgPyB0cnVlIDogZmFsc2U7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24ubG9hZGluZyA9PT0gbG9hZGluZ1xuICAgICAgPyBjb2xsZWN0aW9uXG4gICAgICA6IHsgLi4uY29sbGVjdGlvbiwgbG9hZGluZyB9O1xuICB9XG4gIC8vICNlbmRyZWdpb24gQ2FjaGUtb25seSBvcGVyYXRpb25zXG5cbiAgLy8gI3JlZ2lvbiBoZWxwZXJzXG4gIC8qKiBTYWZlbHkgZXh0cmFjdCBkYXRhIGZyb20gdGhlIEVudGl0eUFjdGlvbiBwYXlsb2FkICovXG4gIHByb3RlY3RlZCBleHRyYWN0RGF0YTxEID0gYW55PihhY3Rpb246IEVudGl0eUFjdGlvbjxEPik6IEQge1xuICAgIHJldHVybiAoYWN0aW9uLnBheWxvYWQgJiYgYWN0aW9uLnBheWxvYWQuZGF0YSkgYXMgRDtcbiAgfVxuXG4gIC8qKiBTYWZlbHkgZXh0cmFjdCBNZXJnZVN0cmF0ZWd5IGZyb20gRW50aXR5QWN0aW9uLiBTZXQgdG8gSWdub3JlQ2hhbmdlcyBpZiBjb2xsZWN0aW9uIGl0c2VsZiBpcyBub3QgdHJhY2tlZC4gKi9cbiAgcHJvdGVjdGVkIGV4dHJhY3RNZXJnZVN0cmF0ZWd5KGFjdGlvbjogRW50aXR5QWN0aW9uKSB7XG4gICAgLy8gSWYgbm90IHRyYWNraW5nIHRoaXMgY29sbGVjdGlvbiwgYWx3YXlzIGlnbm9yZSBjaGFuZ2VzXG4gICAgcmV0dXJuIHRoaXMuaXNDaGFuZ2VUcmFja2luZ1xuICAgICAgPyBhY3Rpb24ucGF5bG9hZCAmJiBhY3Rpb24ucGF5bG9hZC5tZXJnZVN0cmF0ZWd5XG4gICAgICA6IE1lcmdlU3RyYXRlZ3kuSWdub3JlQ2hhbmdlcztcbiAgfVxuXG4gIHByb3RlY3RlZCBpc09wdGltaXN0aWMoYWN0aW9uOiBFbnRpdHlBY3Rpb24pIHtcbiAgICByZXR1cm4gYWN0aW9uLnBheWxvYWQgJiYgYWN0aW9uLnBheWxvYWQuaXNPcHRpbWlzdGljID09PSB0cnVlO1xuICB9XG5cbiAgLy8gI2VuZHJlZ2lvbiBoZWxwZXJzXG59XG5cbi8qKlxuICogQ3JlYXRlcyB7RW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RzfSBmb3IgYSBnaXZlbiBlbnRpdHkgdHlwZS5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEVudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc0ZhY3Rvcnkge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVudGl0eURlZmluaXRpb25TZXJ2aWNlOiBFbnRpdHlEZWZpbml0aW9uU2VydmljZSkge31cblxuICAvKiogQ3JlYXRlIHRoZSAge0VudGl0eUNvbGxlY3Rpb25SZWR1Y2VyTWV0aG9kc30gZm9yIHRoZSBuYW1lZCBlbnRpdHkgdHlwZSAqL1xuICBjcmVhdGU8VD4oZW50aXR5TmFtZTogc3RyaW5nKTogRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RNYXA8VD4ge1xuICAgIGNvbnN0IGRlZmluaXRpb24gPSB0aGlzLmVudGl0eURlZmluaXRpb25TZXJ2aWNlLmdldERlZmluaXRpb248VD4oXG4gICAgICBlbnRpdHlOYW1lXG4gICAgKTtcbiAgICBjb25zdCBtZXRob2RzQ2xhc3MgPSBuZXcgRW50aXR5Q29sbGVjdGlvblJlZHVjZXJNZXRob2RzKFxuICAgICAgZW50aXR5TmFtZSxcbiAgICAgIGRlZmluaXRpb25cbiAgICApO1xuXG4gICAgcmV0dXJuIG1ldGhvZHNDbGFzcy5tZXRob2RzO1xuICB9XG59XG4iXX0=
|