@decaf-ts/core 0.3.37 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +0 -0
- package/README.md +37 -243
- package/dist/core.cjs +2361 -0
- package/dist/core.esm.cjs +2307 -0
- package/lib/esm/identity/decorators.d.ts +1 -1
- package/lib/esm/identity/decorators.js +1 -2
- package/lib/esm/identity/index.d.ts +0 -0
- package/lib/esm/identity/index.js +1 -2
- package/lib/esm/identity/utils.d.ts +0 -0
- package/lib/esm/identity/utils.js +1 -2
- package/lib/esm/index.d.ts +1 -1
- package/lib/esm/index.js +2 -3
- package/lib/esm/interfaces/Builder.d.ts +0 -0
- package/lib/esm/interfaces/Builder.js +1 -2
- package/lib/esm/interfaces/Executor.d.ts +0 -0
- package/lib/esm/interfaces/Executor.js +1 -2
- package/lib/esm/interfaces/Observable.d.ts +0 -0
- package/lib/esm/interfaces/Observable.js +1 -2
- package/lib/esm/interfaces/Observer.d.ts +0 -0
- package/lib/esm/interfaces/Observer.js +1 -2
- package/lib/esm/interfaces/Paginatable.d.ts +0 -0
- package/lib/esm/interfaces/Paginatable.js +1 -2
- package/lib/esm/interfaces/Queriable.d.ts +0 -0
- package/lib/esm/interfaces/Queriable.js +1 -2
- package/lib/esm/interfaces/RawExecutor.d.ts +0 -0
- package/lib/esm/interfaces/RawExecutor.js +1 -2
- package/lib/esm/interfaces/SequenceOptions.d.ts +0 -0
- package/lib/esm/interfaces/SequenceOptions.js +1 -2
- package/lib/esm/interfaces/index.d.ts +0 -0
- package/lib/esm/interfaces/index.js +1 -2
- package/lib/esm/model/BaseModel.d.ts +0 -0
- package/lib/esm/model/BaseModel.js +1 -2
- package/lib/esm/model/IdentifiedBaseModel.d.ts +0 -0
- package/lib/esm/model/IdentifiedBaseModel.js +1 -2
- package/lib/esm/model/User.d.ts +2 -1
- package/lib/esm/model/User.js +1 -2
- package/lib/esm/model/construction.d.ts +1 -1
- package/lib/esm/model/construction.js +1 -2
- package/lib/esm/model/decorators.d.ts +0 -0
- package/lib/esm/model/decorators.js +1 -2
- package/lib/esm/model/index.d.ts +0 -0
- package/lib/esm/model/index.js +1 -2
- package/lib/esm/model/types.d.ts +0 -0
- package/lib/esm/model/types.js +1 -2
- package/lib/esm/persistence/Adapter.d.ts +0 -0
- package/lib/esm/persistence/Adapter.js +1 -2
- package/lib/esm/persistence/Sequence.d.ts +0 -0
- package/lib/esm/persistence/Sequence.js +1 -2
- package/lib/esm/persistence/constants.d.ts +0 -0
- package/lib/esm/persistence/constants.js +1 -2
- package/lib/esm/persistence/decorators.d.ts +0 -0
- package/lib/esm/persistence/decorators.js +1 -2
- package/lib/esm/persistence/errors.d.ts +0 -0
- package/lib/esm/persistence/errors.js +1 -2
- package/lib/esm/persistence/index.d.ts +0 -0
- package/lib/esm/persistence/index.js +1 -2
- package/lib/esm/query/Clause.d.ts +0 -0
- package/lib/esm/query/Clause.js +1 -2
- package/lib/esm/query/ClauseFactory.d.ts +0 -0
- package/lib/esm/query/ClauseFactory.js +1 -2
- package/lib/esm/query/Condition.d.ts +0 -0
- package/lib/esm/query/Condition.js +1 -2
- package/lib/esm/query/Paginator.d.ts +0 -0
- package/lib/esm/query/Paginator.js +1 -2
- package/lib/esm/query/Query.d.ts +0 -0
- package/lib/esm/query/Query.js +1 -2
- package/lib/esm/query/Statement.d.ts +2 -1
- package/lib/esm/query/Statement.js +1 -2
- package/lib/esm/query/clauses/FromClause.d.ts +0 -0
- package/lib/esm/query/clauses/FromClause.js +1 -2
- package/lib/esm/query/clauses/GroupByClause.d.ts +0 -0
- package/lib/esm/query/clauses/GroupByClause.js +1 -2
- package/lib/esm/query/clauses/InsertClause.d.ts +0 -0
- package/lib/esm/query/clauses/InsertClause.js +1 -2
- package/lib/esm/query/clauses/LimitClause.d.ts +0 -0
- package/lib/esm/query/clauses/LimitClause.js +1 -2
- package/lib/esm/query/clauses/OffsetClause.d.ts +0 -0
- package/lib/esm/query/clauses/OffsetClause.js +1 -2
- package/lib/esm/query/clauses/OrderByClause.d.ts +0 -0
- package/lib/esm/query/clauses/OrderByClause.js +1 -2
- package/lib/esm/query/clauses/SelectClause.d.ts +0 -0
- package/lib/esm/query/clauses/SelectClause.js +1 -2
- package/lib/esm/query/clauses/SelectorBasedClause.d.ts +0 -0
- package/lib/esm/query/clauses/SelectorBasedClause.js +1 -2
- package/lib/esm/query/clauses/ValuesClause.d.ts +0 -0
- package/lib/esm/query/clauses/ValuesClause.js +1 -2
- package/lib/esm/query/clauses/WhereClause.d.ts +0 -0
- package/lib/esm/query/clauses/WhereClause.js +71 -0
- package/lib/esm/query/clauses/index.d.ts +0 -0
- package/lib/esm/query/clauses/index.js +11 -0
- package/lib/esm/query/constants.d.ts +0 -0
- package/lib/esm/query/constants.js +1 -2
- package/lib/esm/query/errors.d.ts +0 -0
- package/lib/esm/query/errors.js +1 -2
- package/lib/esm/query/index.d.ts +0 -0
- package/lib/esm/query/index.js +1 -2
- package/lib/esm/query/options.d.ts +0 -0
- package/lib/esm/query/options.js +1 -2
- package/lib/esm/query/selectors.d.ts +0 -0
- package/lib/esm/query/selectors.js +1 -2
- package/lib/esm/query/types.d.ts +0 -0
- package/lib/esm/query/types.js +1 -2
- package/lib/esm/repository/Context.d.ts +0 -0
- package/lib/esm/repository/Context.js +1 -2
- package/lib/esm/repository/Repository.d.ts +0 -0
- package/lib/esm/repository/Repository.js +1 -2
- package/lib/esm/repository/constants.d.ts +0 -0
- package/lib/esm/repository/constants.js +1 -2
- package/lib/esm/repository/decorators.d.ts +0 -0
- package/lib/esm/repository/decorators.js +1 -2
- package/lib/esm/repository/errors.d.ts +0 -0
- package/lib/esm/repository/errors.js +1 -2
- package/lib/esm/repository/index.d.ts +0 -0
- package/lib/esm/repository/index.js +1 -2
- package/lib/esm/repository/injectables.d.ts +0 -0
- package/lib/esm/repository/injectables.js +1 -2
- package/lib/esm/repository/types.d.ts +0 -0
- package/lib/esm/repository/types.js +1 -2
- package/lib/esm/repository/utils.d.ts +0 -0
- package/lib/esm/repository/utils.js +1 -2
- package/lib/esm/validators/ClauseSequenceValidator.d.ts +3 -3
- package/lib/esm/validators/ClauseSequenceValidator.js +8 -9
- package/lib/esm/validators/decorators.d.ts +0 -0
- package/lib/esm/validators/decorators.js +1 -2
- package/lib/esm/validators/index.d.ts +0 -0
- package/lib/esm/validators/index.js +1 -2
- package/lib/identity/decorators.cjs +1 -0
- package/lib/identity/decorators.d.ts +1 -1
- package/lib/identity/index.cjs +1 -0
- package/lib/identity/index.d.ts +0 -0
- package/lib/identity/utils.cjs +1 -0
- package/lib/identity/utils.d.ts +0 -0
- package/lib/index.cjs +2 -1
- package/lib/index.d.ts +1 -1
- package/lib/interfaces/Builder.cjs +1 -0
- package/lib/interfaces/Builder.d.ts +0 -0
- package/lib/interfaces/Executor.cjs +1 -0
- package/lib/interfaces/Executor.d.ts +0 -0
- package/lib/interfaces/Observable.cjs +1 -0
- package/lib/interfaces/Observable.d.ts +0 -0
- package/lib/interfaces/Observer.cjs +1 -0
- package/lib/interfaces/Observer.d.ts +0 -0
- package/lib/interfaces/Paginatable.cjs +1 -0
- package/lib/interfaces/Paginatable.d.ts +0 -0
- package/lib/interfaces/Queriable.cjs +1 -0
- package/lib/interfaces/Queriable.d.ts +0 -0
- package/lib/interfaces/RawExecutor.cjs +1 -0
- package/lib/interfaces/RawExecutor.d.ts +0 -0
- package/lib/interfaces/SequenceOptions.cjs +1 -0
- package/lib/interfaces/SequenceOptions.d.ts +0 -0
- package/lib/interfaces/index.cjs +1 -0
- package/lib/interfaces/index.d.ts +0 -0
- package/lib/model/BaseModel.cjs +1 -0
- package/lib/model/BaseModel.d.ts +0 -0
- package/lib/model/IdentifiedBaseModel.cjs +1 -0
- package/lib/model/IdentifiedBaseModel.d.ts +0 -0
- package/lib/model/User.cjs +1 -0
- package/lib/model/User.d.ts +2 -1
- package/lib/model/construction.cjs +1 -0
- package/lib/model/construction.d.ts +1 -1
- package/lib/model/decorators.cjs +1 -0
- package/lib/model/decorators.d.ts +0 -0
- package/lib/model/index.cjs +1 -0
- package/lib/model/index.d.ts +0 -0
- package/lib/model/types.cjs +1 -0
- package/lib/model/types.d.ts +0 -0
- package/lib/persistence/Adapter.cjs +1 -0
- package/lib/persistence/Adapter.d.ts +0 -0
- package/lib/persistence/Sequence.cjs +1 -0
- package/lib/persistence/Sequence.d.ts +0 -0
- package/lib/persistence/constants.cjs +1 -0
- package/lib/persistence/constants.d.ts +0 -0
- package/lib/persistence/decorators.cjs +1 -0
- package/lib/persistence/decorators.d.ts +0 -0
- package/lib/persistence/errors.cjs +1 -0
- package/lib/persistence/errors.d.ts +0 -0
- package/lib/persistence/index.cjs +1 -0
- package/lib/persistence/index.d.ts +0 -0
- package/lib/query/Clause.cjs +1 -0
- package/lib/query/Clause.d.ts +0 -0
- package/lib/query/ClauseFactory.cjs +1 -0
- package/lib/query/ClauseFactory.d.ts +0 -0
- package/lib/query/Condition.cjs +1 -0
- package/lib/query/Condition.d.ts +0 -0
- package/lib/query/Paginator.cjs +1 -0
- package/lib/query/Paginator.d.ts +0 -0
- package/lib/query/Query.cjs +1 -0
- package/lib/query/Query.d.ts +0 -0
- package/lib/query/Statement.cjs +1 -0
- package/lib/query/Statement.d.ts +2 -1
- package/lib/query/clauses/FromClause.cjs +1 -0
- package/lib/query/clauses/FromClause.d.ts +0 -0
- package/lib/query/clauses/GroupByClause.cjs +1 -0
- package/lib/query/clauses/GroupByClause.d.ts +0 -0
- package/lib/query/clauses/InsertClause.cjs +1 -0
- package/lib/query/clauses/InsertClause.d.ts +0 -0
- package/lib/query/clauses/LimitClause.cjs +1 -0
- package/lib/query/clauses/LimitClause.d.ts +0 -0
- package/lib/query/clauses/OffsetClause.cjs +1 -0
- package/lib/query/clauses/OffsetClause.d.ts +0 -0
- package/lib/query/clauses/OrderByClause.cjs +1 -0
- package/lib/query/clauses/OrderByClause.d.ts +0 -0
- package/lib/query/clauses/SelectClause.cjs +1 -0
- package/lib/query/clauses/SelectClause.d.ts +0 -0
- package/lib/query/clauses/SelectorBasedClause.cjs +1 -0
- package/lib/query/clauses/SelectorBasedClause.d.ts +0 -0
- package/lib/query/clauses/ValuesClause.cjs +1 -0
- package/lib/query/clauses/ValuesClause.d.ts +0 -0
- package/lib/query/clauses/WhereClause.cjs +1 -0
- package/lib/query/clauses/WhereClause.d.ts +0 -0
- package/lib/query/clauses/index.cjs +1 -0
- package/lib/query/clauses/index.d.ts +0 -0
- package/lib/query/constants.cjs +1 -0
- package/lib/query/constants.d.ts +0 -0
- package/lib/query/errors.cjs +1 -0
- package/lib/query/errors.d.ts +0 -0
- package/lib/query/index.cjs +1 -0
- package/lib/query/index.d.ts +0 -0
- package/lib/query/options.cjs +1 -0
- package/lib/query/options.d.ts +0 -0
- package/lib/query/selectors.cjs +1 -0
- package/lib/query/selectors.d.ts +0 -0
- package/lib/query/types.cjs +1 -0
- package/lib/query/types.d.ts +0 -0
- package/lib/repository/Context.cjs +1 -0
- package/lib/repository/Context.d.ts +0 -0
- package/lib/repository/Repository.cjs +1 -0
- package/lib/repository/Repository.d.ts +0 -0
- package/lib/repository/constants.cjs +1 -0
- package/lib/repository/constants.d.ts +0 -0
- package/lib/repository/decorators.cjs +1 -0
- package/lib/repository/decorators.d.ts +0 -0
- package/lib/repository/errors.cjs +1 -0
- package/lib/repository/errors.d.ts +0 -0
- package/lib/repository/index.cjs +1 -0
- package/lib/repository/index.d.ts +0 -0
- package/lib/repository/injectables.cjs +1 -0
- package/lib/repository/injectables.d.ts +0 -0
- package/lib/repository/types.cjs +1 -0
- package/lib/repository/types.d.ts +0 -0
- package/lib/repository/utils.cjs +1 -0
- package/lib/repository/utils.d.ts +0 -0
- package/lib/validators/ClauseSequenceValidator.cjs +8 -7
- package/lib/validators/ClauseSequenceValidator.d.ts +3 -3
- package/lib/validators/decorators.cjs +1 -0
- package/lib/validators/decorators.d.ts +0 -0
- package/lib/validators/index.cjs +1 -0
- package/lib/validators/index.d.ts +0 -0
- package/package.json +36 -38
- package/dist/core.bundle.min.js +0 -2
- package/dist/core.bundle.min.js.LICENSE.txt +0 -14
- package/dist/esm/core.bundle.min.esm.js +0 -2
- package/dist/esm/core.bundle.min.esm.js.LICENSE.txt +0 -14
- package/dist/lib/identity/decorators.d.ts +0 -24
- package/dist/lib/identity/index.d.ts +0 -2
- package/dist/lib/identity/utils.d.ts +0 -3
- package/dist/lib/index.d.ts +0 -25
- package/dist/lib/interfaces/Builder.d.ts +0 -16
- package/dist/lib/interfaces/Executor.d.ts +0 -19
- package/dist/lib/interfaces/Observable.d.ts +0 -31
- package/dist/lib/interfaces/Observer.d.ts +0 -16
- package/dist/lib/interfaces/Paginatable.d.ts +0 -4
- package/dist/lib/interfaces/Queriable.d.ts +0 -6
- package/dist/lib/interfaces/RawExecutor.d.ts +0 -20
- package/dist/lib/interfaces/SequenceOptions.d.ts +0 -19
- package/dist/lib/interfaces/index.d.ts +0 -7
- package/dist/lib/model/BaseModel.d.ts +0 -6
- package/dist/lib/model/IdentifiedBaseModel.d.ts +0 -7
- package/dist/lib/model/User.d.ts +0 -8
- package/dist/lib/model/construction.d.ts +0 -15
- package/dist/lib/model/decorators.d.ts +0 -75
- package/dist/lib/model/index.d.ts +0 -4
- package/dist/lib/model/types.d.ts +0 -6
- package/dist/lib/persistence/Adapter.d.ts +0 -86
- package/dist/lib/persistence/Sequence.d.ts +0 -22
- package/dist/lib/persistence/constants.d.ts +0 -22
- package/dist/lib/persistence/decorators.d.ts +0 -1
- package/dist/lib/persistence/errors.d.ts +0 -7
- package/dist/lib/persistence/index.d.ts +0 -5
- package/dist/lib/query/Clause.d.ts +0 -50
- package/dist/lib/query/ClauseFactory.d.ts +0 -71
- package/dist/lib/query/Condition.d.ts +0 -75
- package/dist/lib/query/Paginator.d.ts +0 -22
- package/dist/lib/query/Query.d.ts +0 -43
- package/dist/lib/query/Statement.d.ts +0 -55
- package/dist/lib/query/clauses/FromClause.d.ts +0 -45
- package/dist/lib/query/clauses/GroupByClause.d.ts +0 -21
- package/dist/lib/query/clauses/InsertClause.d.ts +0 -37
- package/dist/lib/query/clauses/LimitClause.d.ts +0 -29
- package/dist/lib/query/clauses/OffsetClause.d.ts +0 -21
- package/dist/lib/query/clauses/OrderByClause.d.ts +0 -37
- package/dist/lib/query/clauses/SelectClause.d.ts +0 -47
- package/dist/lib/query/clauses/SelectorBasedClause.d.ts +0 -25
- package/dist/lib/query/clauses/ValuesClause.d.ts +0 -21
- package/dist/lib/query/clauses/WhereClause.d.ts +0 -46
- package/dist/lib/query/clauses/index.d.ts +0 -10
- package/dist/lib/query/constants.d.ts +0 -79
- package/dist/lib/query/errors.d.ts +0 -7
- package/dist/lib/query/index.d.ts +0 -12
- package/dist/lib/query/options.d.ts +0 -372
- package/dist/lib/query/selectors.d.ts +0 -38
- package/dist/lib/query/types.d.ts +0 -2
- package/dist/lib/repository/Context.d.ts +0 -10
- package/dist/lib/repository/Repository.d.ts +0 -70
- package/dist/lib/repository/constants.d.ts +0 -25
- package/dist/lib/repository/decorators.d.ts +0 -2
- package/dist/lib/repository/errors.d.ts +0 -12
- package/dist/lib/repository/index.d.ts +0 -8
- package/dist/lib/repository/injectables.d.ts +0 -5
- package/dist/lib/repository/types.d.ts +0 -15
- package/dist/lib/repository/utils.d.ts +0 -3
- package/dist/lib/validators/ClauseSequenceValidator.d.ts +0 -28
- package/dist/lib/validators/decorators.d.ts +0 -10
- package/dist/lib/validators/index.d.ts +0 -2
@@ -0,0 +1,2307 @@
|
|
1
|
+
import { Context as Context$1, BaseError, InternalError, NotFoundError, DBKeys, Repository as Repository$1, wrapMethodWithContext, OperationKeys, enforceDBDecorators, ValidationError, findPrimaryKey, ConflictError, onCreateUpdate, onCreate, onUpdate, onDelete, afterAny, readonly, timestamp, DBOperations } from '@decaf-ts/db-decorators';
|
2
|
+
import { inject, injectable, InjectableRegistryImp, Injectables } from '@decaf-ts/injectable-decorators';
|
3
|
+
import { apply, metadata, Reflection, isEqual } from '@decaf-ts/reflection';
|
4
|
+
import { Model, sf, required, Validation, ValidationKeys, propMetadata, prop, type, list, model, DEFAULT_ERROR_MESSAGES, validator, Validator, minlength, stringFormat } from '@decaf-ts/decorator-validation';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @summary defines order directions when sorting
|
8
|
+
*
|
9
|
+
* @constant OrderDirection
|
10
|
+
*
|
11
|
+
* @category Query
|
12
|
+
*/
|
13
|
+
var OrderDirection;
|
14
|
+
(function (OrderDirection) {
|
15
|
+
/**
|
16
|
+
* @summary Defines the sort order as ascending
|
17
|
+
* @prop ASC
|
18
|
+
*/
|
19
|
+
OrderDirection["ASC"] = "asc";
|
20
|
+
/**
|
21
|
+
* @summary Defines the sort order as descending
|
22
|
+
* @property {string} DSC
|
23
|
+
*/
|
24
|
+
OrderDirection["DSC"] = "desc";
|
25
|
+
})(OrderDirection || (OrderDirection = {}));
|
26
|
+
var Cascade;
|
27
|
+
(function (Cascade) {
|
28
|
+
Cascade["CASCADE"] = "cascade";
|
29
|
+
Cascade["NONE"] = "none";
|
30
|
+
})(Cascade || (Cascade = {}));
|
31
|
+
const DefaultCascade = {
|
32
|
+
update: Cascade.CASCADE,
|
33
|
+
delete: Cascade.NONE,
|
34
|
+
};
|
35
|
+
|
36
|
+
class Context extends Context$1 {
|
37
|
+
constructor(operation, model, parent) {
|
38
|
+
super(operation, model, parent);
|
39
|
+
}
|
40
|
+
get timestamp() {
|
41
|
+
if (!this._timestamp)
|
42
|
+
this._timestamp = new Date();
|
43
|
+
return this._timestamp;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
var PersistenceKeys;
|
48
|
+
(function (PersistenceKeys) {
|
49
|
+
PersistenceKeys["INDEX"] = "index";
|
50
|
+
PersistenceKeys["UNIQUE"] = "unique";
|
51
|
+
PersistenceKeys["ADAPTER"] = "adapter";
|
52
|
+
PersistenceKeys["INJECTABLE"] = "decaf_{0}_adapter_for_{1}";
|
53
|
+
PersistenceKeys["TABLE"] = "table";
|
54
|
+
PersistenceKeys["COLUMN"] = "column";
|
55
|
+
PersistenceKeys["METADATA"] = "__metadata";
|
56
|
+
PersistenceKeys["RELATIONS"] = "__relations";
|
57
|
+
PersistenceKeys["CLAUSE_SEQUENCE"] = "clause-sequence";
|
58
|
+
// Ownership
|
59
|
+
PersistenceKeys["CREATED_BY"] = "ownership.created-by";
|
60
|
+
PersistenceKeys["UPDATED_BY"] = "ownership.updated-by";
|
61
|
+
// Relations
|
62
|
+
PersistenceKeys["ONE_TO_ONE"] = "relations.one-to-one";
|
63
|
+
PersistenceKeys["ONE_TO_MANY"] = "relations.one-to-many";
|
64
|
+
PersistenceKeys["MANY_TO_ONE"] = "relations.many-to-one";
|
65
|
+
PersistenceKeys["POPULATE"] = "populate";
|
66
|
+
})(PersistenceKeys || (PersistenceKeys = {}));
|
67
|
+
var Roles;
|
68
|
+
(function (Roles) {
|
69
|
+
Roles["ADMIN"] = "admin";
|
70
|
+
Roles["WRITER"] = "writer";
|
71
|
+
Roles["READER"] = "reader";
|
72
|
+
})(Roles || (Roles = {}));
|
73
|
+
|
74
|
+
var Operator;
|
75
|
+
(function (Operator) {
|
76
|
+
Operator["EQUAL"] = "EQUAL";
|
77
|
+
Operator["DIFFERENT"] = "DIFFERENT";
|
78
|
+
Operator["BIGGER"] = "BIGGER";
|
79
|
+
Operator["BIGGER_EQ"] = "BIGGER_EQ";
|
80
|
+
Operator["SMALLER"] = "SMALLER";
|
81
|
+
Operator["SMALLER_EQ"] = "SMALLER_EQ";
|
82
|
+
// BETWEEN = "BETWEEN",
|
83
|
+
Operator["NOT"] = "NOT";
|
84
|
+
Operator["IN"] = "IN";
|
85
|
+
// IS = "IS",
|
86
|
+
Operator["REGEXP"] = "REGEXP";
|
87
|
+
})(Operator || (Operator = {}));
|
88
|
+
var GroupOperator;
|
89
|
+
(function (GroupOperator) {
|
90
|
+
GroupOperator["AND"] = "AND";
|
91
|
+
GroupOperator["OR"] = "OR";
|
92
|
+
})(GroupOperator || (GroupOperator = {}));
|
93
|
+
var Const;
|
94
|
+
(function (Const) {
|
95
|
+
Const["NULL"] = "NULL";
|
96
|
+
Const["FULL_RECORD"] = "*";
|
97
|
+
})(Const || (Const = {}));
|
98
|
+
/**
|
99
|
+
* @summary Defines execution order of Clauses in statements as defined in SQL.
|
100
|
+
*
|
101
|
+
* @description sub priorities where defined to better organize clauses within statements, eg From and Join Clauses
|
102
|
+
*
|
103
|
+
* @const Priority
|
104
|
+
*
|
105
|
+
* @category Clauses
|
106
|
+
* @subcategory Constants
|
107
|
+
*/
|
108
|
+
var Priority;
|
109
|
+
(function (Priority) {
|
110
|
+
/**
|
111
|
+
* @summary Defines the priority for the FROM Clause
|
112
|
+
* @description From Clause in SELECT Statements.
|
113
|
+
* Values Clause in INSERT Statements
|
114
|
+
*
|
115
|
+
* @prop FROM
|
116
|
+
*/
|
117
|
+
Priority[Priority["FROM"] = 1] = "FROM";
|
118
|
+
/**
|
119
|
+
* @summary Defines the priority for the JOIN Clause
|
120
|
+
*
|
121
|
+
* @property {number} JOIN
|
122
|
+
*/
|
123
|
+
Priority[Priority["JOIN"] = 1.1] = "JOIN";
|
124
|
+
/**
|
125
|
+
* Where Clause
|
126
|
+
*/
|
127
|
+
Priority[Priority["WHERE"] = 2] = "WHERE";
|
128
|
+
/**
|
129
|
+
* Group By Clause
|
130
|
+
*/
|
131
|
+
Priority[Priority["GROUP_BY"] = 3] = "GROUP_BY";
|
132
|
+
/**
|
133
|
+
* Having Clause
|
134
|
+
*/
|
135
|
+
Priority[Priority["HAVING"] = 4] = "HAVING";
|
136
|
+
/**
|
137
|
+
* Select Clause in SELECT Statements
|
138
|
+
* Insert Clause in INSERT Statements
|
139
|
+
*/
|
140
|
+
Priority[Priority["SELECT"] = 5] = "SELECT";
|
141
|
+
/**
|
142
|
+
* Order By Clause
|
143
|
+
*/
|
144
|
+
Priority[Priority["ORDER_BY"] = 6] = "ORDER_BY";
|
145
|
+
/**
|
146
|
+
* Limit Clause
|
147
|
+
*/
|
148
|
+
Priority[Priority["LIMIT"] = 7] = "LIMIT";
|
149
|
+
/**
|
150
|
+
* Offset Clause
|
151
|
+
*/
|
152
|
+
Priority[Priority["OFFSET"] = 7.1] = "OFFSET";
|
153
|
+
})(Priority || (Priority = {}));
|
154
|
+
const MandatoryPriorities = [Priority.FROM, Priority.SELECT];
|
155
|
+
var StatementType;
|
156
|
+
(function (StatementType) {
|
157
|
+
StatementType["QUERY"] = "query";
|
158
|
+
StatementType["TRANSACTION"] = "transaction";
|
159
|
+
})(StatementType || (StatementType = {}));
|
160
|
+
|
161
|
+
/**
|
162
|
+
* @summary Helper Class to build queries
|
163
|
+
*
|
164
|
+
* @param {Database} db
|
165
|
+
*
|
166
|
+
* @class Query
|
167
|
+
*
|
168
|
+
* @category Query
|
169
|
+
*/
|
170
|
+
class Query {
|
171
|
+
constructor(adapter) {
|
172
|
+
this.adapter = adapter;
|
173
|
+
}
|
174
|
+
/**
|
175
|
+
* @summary Creates a Select Clause
|
176
|
+
* @param {SelectSelector} [selector]
|
177
|
+
*/
|
178
|
+
select(selector = Const.FULL_RECORD) {
|
179
|
+
return this.adapter.Clauses.select(selector);
|
180
|
+
}
|
181
|
+
/**
|
182
|
+
* @summary Creates a Min Clause
|
183
|
+
* @param {SelectSelector} selector
|
184
|
+
*/
|
185
|
+
min(selector) {
|
186
|
+
return this.select().min(selector);
|
187
|
+
}
|
188
|
+
/**
|
189
|
+
* @summary Creates a Max Clause
|
190
|
+
* @param {SelectSelector} selector
|
191
|
+
*/
|
192
|
+
max(selector) {
|
193
|
+
return this.select().max(selector);
|
194
|
+
}
|
195
|
+
/**
|
196
|
+
* @summary Creates a Distinct Clause
|
197
|
+
* @param {SelectSelector} selector
|
198
|
+
*/
|
199
|
+
distinct(selector) {
|
200
|
+
return this.select().distinct(selector);
|
201
|
+
}
|
202
|
+
/**
|
203
|
+
* @summary Creates a Count Clause
|
204
|
+
* @param {SelectSelector} selector
|
205
|
+
*/
|
206
|
+
count(selector) {
|
207
|
+
return this.select().count(selector);
|
208
|
+
}
|
209
|
+
insert() {
|
210
|
+
return this.adapter.Clauses.insert();
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
class ConnectionError extends BaseError {
|
215
|
+
constructor(msg) {
|
216
|
+
super(ConnectionError.name, msg);
|
217
|
+
}
|
218
|
+
}
|
219
|
+
class UnsupportedError extends BaseError {
|
220
|
+
constructor(msg) {
|
221
|
+
super(UnsupportedError.name, msg);
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
/**
|
226
|
+
* @summary Abstract Decaf-ts Persistence Adapter Class
|
227
|
+
* @description Offers the base implementation for all Adapter Classes
|
228
|
+
* and manages them various registered {@link Adapter}s
|
229
|
+
*
|
230
|
+
* @typedef Y the underlying persistence object type
|
231
|
+
* @typedef Q The query object the adapter uses
|
232
|
+
*
|
233
|
+
* @param {Y} native the underlying persistence object
|
234
|
+
* @param {string} flavour the under witch the persistence adapter should be stored
|
235
|
+
*
|
236
|
+
* @class Adapter
|
237
|
+
* @implements RawExecutor
|
238
|
+
* @implements Observable
|
239
|
+
*/
|
240
|
+
class Adapter {
|
241
|
+
static { this._cache = {}; }
|
242
|
+
get native() {
|
243
|
+
return this._native;
|
244
|
+
}
|
245
|
+
repository() {
|
246
|
+
return Repository;
|
247
|
+
}
|
248
|
+
constructor(native, flavour) {
|
249
|
+
this.flavour = flavour;
|
250
|
+
this._observers = [];
|
251
|
+
if (this.flavour in Adapter._cache)
|
252
|
+
throw new InternalError(`Persistence adapter flavour ${this.flavour} already registered`);
|
253
|
+
this._native = native;
|
254
|
+
Adapter._cache[this.flavour] = this;
|
255
|
+
}
|
256
|
+
Query() {
|
257
|
+
return new Query(this);
|
258
|
+
}
|
259
|
+
isReserved(attr) {
|
260
|
+
return !attr;
|
261
|
+
}
|
262
|
+
async context(operation, model) {
|
263
|
+
let user;
|
264
|
+
try {
|
265
|
+
user = await this.user();
|
266
|
+
}
|
267
|
+
catch (e) {
|
268
|
+
if (!(e instanceof UnsupportedError))
|
269
|
+
throw e;
|
270
|
+
}
|
271
|
+
const c = new (class extends Context {
|
272
|
+
constructor(operation, model, parent) {
|
273
|
+
super(operation, model, parent);
|
274
|
+
}
|
275
|
+
get user() {
|
276
|
+
if (!user)
|
277
|
+
throw new UnsupportedError("Adapter does not support user identification");
|
278
|
+
return user;
|
279
|
+
}
|
280
|
+
})(operation, model);
|
281
|
+
return c;
|
282
|
+
}
|
283
|
+
prepare(model, pk) {
|
284
|
+
const result = Object.entries(model).reduce((accum, [key, val]) => {
|
285
|
+
// if (key === pk) return accum;
|
286
|
+
const mappedProp = Repository.column(model, key);
|
287
|
+
if (this.isReserved(mappedProp))
|
288
|
+
throw new InternalError(`Property name ${mappedProp} is reserved`);
|
289
|
+
accum[mappedProp] = val;
|
290
|
+
return accum;
|
291
|
+
}, {});
|
292
|
+
if (model[PersistenceKeys.METADATA])
|
293
|
+
Object.defineProperty(result, PersistenceKeys.METADATA, {
|
294
|
+
enumerable: false,
|
295
|
+
writable: false,
|
296
|
+
configurable: true,
|
297
|
+
value: model[PersistenceKeys.METADATA],
|
298
|
+
});
|
299
|
+
return {
|
300
|
+
record: result,
|
301
|
+
id: model[pk],
|
302
|
+
};
|
303
|
+
}
|
304
|
+
revert(obj, clazz, pk, id) {
|
305
|
+
const ob = {};
|
306
|
+
ob[pk] = id;
|
307
|
+
const m = (typeof clazz === "string" ? Model.build(ob, clazz) : new clazz(ob));
|
308
|
+
const metadata = obj[PersistenceKeys.METADATA];
|
309
|
+
const result = Object.keys(m).reduce((accum, key) => {
|
310
|
+
if (key === pk)
|
311
|
+
return accum;
|
312
|
+
accum[key] = obj[Repository.column(accum, key)];
|
313
|
+
return accum;
|
314
|
+
}, m);
|
315
|
+
if (metadata)
|
316
|
+
Object.defineProperty(result, PersistenceKeys.METADATA, {
|
317
|
+
enumerable: false,
|
318
|
+
configurable: false,
|
319
|
+
writable: false,
|
320
|
+
value: metadata,
|
321
|
+
});
|
322
|
+
return result;
|
323
|
+
}
|
324
|
+
async createAll(tableName, id, model, ...args) {
|
325
|
+
if (id.length !== model.length)
|
326
|
+
throw new InternalError("Ids and models must have the same length");
|
327
|
+
return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...args)));
|
328
|
+
}
|
329
|
+
async readAll(tableName, id, ...args) {
|
330
|
+
return Promise.all(id.map((i) => this.read(tableName, i, ...args)));
|
331
|
+
}
|
332
|
+
async updateAll(tableName, id, model, ...args) {
|
333
|
+
if (id.length !== model.length)
|
334
|
+
throw new InternalError("Ids and models must have the same length");
|
335
|
+
return Promise.all(id.map((i, count) => this.update(tableName, i, model[count], ...args)));
|
336
|
+
}
|
337
|
+
async deleteAll(tableName, id, ...args) {
|
338
|
+
return Promise.all(id.map((i) => this.delete(tableName, i, ...args)));
|
339
|
+
}
|
340
|
+
/**
|
341
|
+
* @summary Registers an {@link Observer}
|
342
|
+
* @param {Observer} observer
|
343
|
+
*
|
344
|
+
* @see {Observable#observe}
|
345
|
+
*/
|
346
|
+
observe(observer) {
|
347
|
+
const index = this._observers.indexOf(observer);
|
348
|
+
if (index !== -1)
|
349
|
+
throw new InternalError("Observer already registered");
|
350
|
+
this._observers.push(observer);
|
351
|
+
}
|
352
|
+
/**
|
353
|
+
* @summary Unregisters an {@link Observer}
|
354
|
+
* @param {Observer} observer
|
355
|
+
*
|
356
|
+
* @see {Observable#unObserve}
|
357
|
+
*/
|
358
|
+
unObserve(observer) {
|
359
|
+
const index = this._observers.indexOf(observer);
|
360
|
+
if (index === -1)
|
361
|
+
throw new InternalError("Failed to find Observer");
|
362
|
+
this._observers.splice(index, 1);
|
363
|
+
}
|
364
|
+
/**
|
365
|
+
* @summary calls all registered {@link Observer}s to update themselves
|
366
|
+
* @param {any[]} [args] optional arguments to be passed to the {@link Observer#refresh} method
|
367
|
+
*/
|
368
|
+
async updateObservers(...args) {
|
369
|
+
const results = await Promise.allSettled(this._observers.map((o) => o.refresh(...args)));
|
370
|
+
results.forEach((result, i) => {
|
371
|
+
if (result.status === "rejected")
|
372
|
+
console.warn(`Failed to update observable ${this._observers[i]}: ${result.reason}`);
|
373
|
+
});
|
374
|
+
}
|
375
|
+
static get current() {
|
376
|
+
return this._current;
|
377
|
+
}
|
378
|
+
static get(flavour) {
|
379
|
+
if (flavour in this._cache)
|
380
|
+
return this._cache[flavour];
|
381
|
+
throw new InternalError(`No Adapter registered under ${flavour}.`);
|
382
|
+
}
|
383
|
+
static setCurrent(flavour) {
|
384
|
+
const adapter = Adapter.get(flavour);
|
385
|
+
if (!adapter)
|
386
|
+
throw new NotFoundError(`No persistence flavour ${flavour} registered`);
|
387
|
+
this._current = adapter;
|
388
|
+
}
|
389
|
+
static key(key) {
|
390
|
+
return Repository.key(key);
|
391
|
+
}
|
392
|
+
static models(flavour) {
|
393
|
+
try {
|
394
|
+
const registry = Model.getRegistry();
|
395
|
+
const cache = registry.cache;
|
396
|
+
const managedModels = Object.values(cache)
|
397
|
+
.map((m) => {
|
398
|
+
let f = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), m);
|
399
|
+
if (f && f === flavour)
|
400
|
+
return m;
|
401
|
+
if (!f) {
|
402
|
+
const repo = Reflect.getMetadata(Repository.key(DBKeys.REPOSITORY), m);
|
403
|
+
if (!repo)
|
404
|
+
return;
|
405
|
+
const repository = Repository.forModel(m);
|
406
|
+
f = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), repository);
|
407
|
+
return f;
|
408
|
+
}
|
409
|
+
})
|
410
|
+
.filter((m) => !!m);
|
411
|
+
return managedModels;
|
412
|
+
}
|
413
|
+
catch (e) {
|
414
|
+
throw new InternalError(e);
|
415
|
+
}
|
416
|
+
}
|
417
|
+
}
|
418
|
+
|
419
|
+
function getTableName(model) {
|
420
|
+
const metadata = Reflect.getMetadata(Adapter.key(PersistenceKeys.TABLE), model instanceof Model ? model.constructor : model);
|
421
|
+
if (metadata) {
|
422
|
+
return metadata;
|
423
|
+
}
|
424
|
+
if (model instanceof Model) {
|
425
|
+
return model.constructor.name;
|
426
|
+
}
|
427
|
+
return model.name;
|
428
|
+
}
|
429
|
+
function sequenceNameForModel(model, ...args) {
|
430
|
+
return [getTableName(model), ...args].join("_");
|
431
|
+
}
|
432
|
+
|
433
|
+
class Sequence {
|
434
|
+
constructor(options) {
|
435
|
+
this.options = options;
|
436
|
+
}
|
437
|
+
static pk(model) {
|
438
|
+
return sequenceNameForModel(model, "pk");
|
439
|
+
}
|
440
|
+
}
|
441
|
+
|
442
|
+
function uses(flavour) {
|
443
|
+
return apply(metadata(Adapter.key(PersistenceKeys.ADAPTER), flavour));
|
444
|
+
}
|
445
|
+
|
446
|
+
class Repository extends Repository$1 {
|
447
|
+
static { this._cache = {}; }
|
448
|
+
get adapter() {
|
449
|
+
if (!this._adapter)
|
450
|
+
throw new InternalError(`No adapter found for this repository. did you use the @uses decorator or pass it in the constructor?`);
|
451
|
+
return this._adapter;
|
452
|
+
}
|
453
|
+
get tableName() {
|
454
|
+
if (!this._tableName)
|
455
|
+
this._tableName = Repository.table(this.class);
|
456
|
+
return this._tableName;
|
457
|
+
}
|
458
|
+
constructor(adapter, clazz) {
|
459
|
+
super(clazz);
|
460
|
+
this.observers = [];
|
461
|
+
if (adapter)
|
462
|
+
this._adapter = adapter;
|
463
|
+
if (clazz) {
|
464
|
+
Repository.register(clazz, this);
|
465
|
+
if (adapter) {
|
466
|
+
const flavour = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), clazz);
|
467
|
+
if (flavour && flavour !== adapter.flavour)
|
468
|
+
throw new InternalError("Incompatible flavours");
|
469
|
+
uses(adapter.flavour)(clazz);
|
470
|
+
}
|
471
|
+
}
|
472
|
+
[this.createAll, this.readAll, this.updateAll, this.deleteAll].forEach((m) => {
|
473
|
+
const name = m.name;
|
474
|
+
wrapMethodWithContext(this, this[name + "Prefix"], m, this[name + "Suffix"]);
|
475
|
+
});
|
476
|
+
}
|
477
|
+
async createPrefix(model, ...args) {
|
478
|
+
const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args, this.adapter);
|
479
|
+
model = new this.class(model);
|
480
|
+
await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.CREATE, OperationKeys.ON);
|
481
|
+
const errors = model.hasErrors();
|
482
|
+
if (errors)
|
483
|
+
throw new ValidationError(errors.toString());
|
484
|
+
return [model, ...contextArgs.args];
|
485
|
+
}
|
486
|
+
async create(model, ...args) {
|
487
|
+
// eslint-disable-next-line prefer-const
|
488
|
+
let { record, id } = this.adapter.prepare(model, this.pk);
|
489
|
+
record = await this.adapter.create(this.tableName, id, record, ...args);
|
490
|
+
return this.adapter.revert(record, this.class, this.pk, id);
|
491
|
+
}
|
492
|
+
async createAll(models, ...args) {
|
493
|
+
if (!models.length)
|
494
|
+
return models;
|
495
|
+
const prepared = models.map((m) => this.adapter.prepare(m, this.pk));
|
496
|
+
const ids = prepared.map((p) => p.id);
|
497
|
+
let records = prepared.map((p) => p.record);
|
498
|
+
records = await this.adapter.createAll(this.tableName, ids, records, ...args);
|
499
|
+
return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, ids[i]));
|
500
|
+
}
|
501
|
+
async createAllPrefix(models, ...args) {
|
502
|
+
const contextArgs = await Context.args(OperationKeys.CREATE, this.class, args, this.adapter);
|
503
|
+
if (!models.length)
|
504
|
+
return [models, ...contextArgs.args];
|
505
|
+
const opts = Repository.getSequenceOptions(models[0]);
|
506
|
+
let ids = [];
|
507
|
+
if (opts.type) {
|
508
|
+
if (!opts.name)
|
509
|
+
opts.name = Sequence.pk(models[0]);
|
510
|
+
ids = await (await this.adapter.Sequence(opts)).range(models.length);
|
511
|
+
}
|
512
|
+
models = await Promise.all(models.map(async (m, i) => {
|
513
|
+
m = new this.class(m);
|
514
|
+
m[this.pk] = ids[i];
|
515
|
+
await enforceDBDecorators(this, contextArgs.context, m, OperationKeys.CREATE, OperationKeys.ON);
|
516
|
+
return m;
|
517
|
+
}));
|
518
|
+
const errors = models
|
519
|
+
.map((m) => m.hasErrors())
|
520
|
+
.reduce((accum, e, i) => {
|
521
|
+
if (e)
|
522
|
+
accum =
|
523
|
+
typeof accum === "string"
|
524
|
+
? accum + `\n - ${i}: ${e.toString()}`
|
525
|
+
: ` - ${i}: ${e.toString()}`;
|
526
|
+
return accum;
|
527
|
+
}, undefined);
|
528
|
+
if (errors)
|
529
|
+
throw new ValidationError(errors);
|
530
|
+
return [models, ...contextArgs.args];
|
531
|
+
}
|
532
|
+
async readPrefix(key, ...args) {
|
533
|
+
const contextArgs = await Context.args(OperationKeys.READ, this.class, args, this.adapter);
|
534
|
+
const model = new this.class();
|
535
|
+
model[this.pk] = key;
|
536
|
+
await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.READ, OperationKeys.ON);
|
537
|
+
return [key, ...contextArgs.args];
|
538
|
+
}
|
539
|
+
async read(id, ...args) {
|
540
|
+
const m = await this.adapter.read(this.tableName, id, ...args);
|
541
|
+
return this.adapter.revert(m, this.class, this.pk, id);
|
542
|
+
}
|
543
|
+
async readAllPrefix(keys, ...args) {
|
544
|
+
const contextArgs = await Context.args(OperationKeys.READ, this.class, args, this.adapter);
|
545
|
+
await Promise.all(keys.map(async (k) => {
|
546
|
+
const m = new this.class();
|
547
|
+
m[this.pk] = k;
|
548
|
+
return enforceDBDecorators(this, contextArgs.context, m, OperationKeys.READ, OperationKeys.ON);
|
549
|
+
}));
|
550
|
+
return [keys, ...contextArgs.args];
|
551
|
+
}
|
552
|
+
async readAll(keys, ...args) {
|
553
|
+
const records = await this.adapter.readAll(this.tableName, keys, ...args);
|
554
|
+
return records.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
|
555
|
+
}
|
556
|
+
async update(model, ...args) {
|
557
|
+
// eslint-disable-next-line prefer-const
|
558
|
+
let { record, id } = this.adapter.prepare(model, this.pk);
|
559
|
+
record = await this.adapter.update(this.tableName, id, record, ...args);
|
560
|
+
return this.adapter.revert(record, this.class, this.pk, id);
|
561
|
+
}
|
562
|
+
async updatePrefix(model, ...args) {
|
563
|
+
const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args, this.adapter);
|
564
|
+
const pk = model[this.pk];
|
565
|
+
if (!pk)
|
566
|
+
throw new InternalError(`No value for the Id is defined under the property ${this.pk}`);
|
567
|
+
const oldModel = await this.read(pk, ...contextArgs.args);
|
568
|
+
model = this.merge(oldModel, model);
|
569
|
+
await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.UPDATE, OperationKeys.ON, oldModel);
|
570
|
+
const errors = model.hasErrors(oldModel, ...Repository.relations(this.class));
|
571
|
+
if (errors)
|
572
|
+
throw new ValidationError(errors.toString());
|
573
|
+
if (Repository.getMetadata(oldModel)) {
|
574
|
+
if (!Repository.getMetadata(model))
|
575
|
+
Repository.setMetadata(model, Repository.getMetadata(oldModel));
|
576
|
+
}
|
577
|
+
return [model, ...contextArgs.args];
|
578
|
+
}
|
579
|
+
async updateAll(models, ...args) {
|
580
|
+
const records = models.map((m) => this.adapter.prepare(m, this.pk));
|
581
|
+
const updated = await this.adapter.updateAll(this.tableName, records.map((r) => r.id), records.map((r) => r.record), ...args);
|
582
|
+
return updated.map((u, i) => this.adapter.revert(u, this.class, this.pk, records[i].id));
|
583
|
+
}
|
584
|
+
async updateAllPrefix(models, ...args) {
|
585
|
+
const contextArgs = await Context.args(OperationKeys.UPDATE, this.class, args, this.adapter);
|
586
|
+
const ids = models.map((m) => {
|
587
|
+
const id = m[this.pk];
|
588
|
+
if (!id)
|
589
|
+
throw new InternalError("missing id on update operation");
|
590
|
+
return id;
|
591
|
+
});
|
592
|
+
const oldModels = await this.readAll(ids, ...contextArgs.args);
|
593
|
+
models = models.map((m, i) => {
|
594
|
+
m = this.merge(oldModels[i], m);
|
595
|
+
if (Repository.getMetadata(oldModels[i])) {
|
596
|
+
if (!Repository.getMetadata(m))
|
597
|
+
Repository.setMetadata(m, Repository.getMetadata(oldModels[i]));
|
598
|
+
}
|
599
|
+
return m;
|
600
|
+
});
|
601
|
+
await Promise.all(models.map((m, i) => enforceDBDecorators(this, contextArgs.context, m, OperationKeys.UPDATE, OperationKeys.ON, oldModels[i])));
|
602
|
+
const errors = models
|
603
|
+
.map((m, i) => m.hasErrors(oldModels[i], m))
|
604
|
+
.reduce((accum, e, i) => {
|
605
|
+
if (e)
|
606
|
+
accum =
|
607
|
+
typeof accum === "string"
|
608
|
+
? accum + `\n - ${i}: ${e.toString()}`
|
609
|
+
: ` - ${i}: ${e.toString()}`;
|
610
|
+
return accum;
|
611
|
+
}, undefined);
|
612
|
+
if (errors)
|
613
|
+
throw new ValidationError(errors);
|
614
|
+
models.forEach((m, i) => {
|
615
|
+
if (Repository.getMetadata(oldModels[i])) {
|
616
|
+
if (!Repository.getMetadata(m))
|
617
|
+
Repository.setMetadata(m, Repository.getMetadata(oldModels[i]));
|
618
|
+
}
|
619
|
+
});
|
620
|
+
return [models, ...contextArgs.args];
|
621
|
+
}
|
622
|
+
async deletePrefix(key, ...args) {
|
623
|
+
const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args, this.adapter);
|
624
|
+
const model = await this.read(key, ...contextArgs.args);
|
625
|
+
await enforceDBDecorators(this, contextArgs.context, model, OperationKeys.DELETE, OperationKeys.ON);
|
626
|
+
return [key, ...contextArgs.args];
|
627
|
+
}
|
628
|
+
async delete(id, ...args) {
|
629
|
+
const m = await this.adapter.delete(this.tableName, id, ...args);
|
630
|
+
return this.adapter.revert(m, this.class, this.pk, id);
|
631
|
+
}
|
632
|
+
async deleteAllPrefix(keys, ...args) {
|
633
|
+
const contextArgs = await Context.args(OperationKeys.DELETE, this.class, args, this.adapter);
|
634
|
+
const models = await this.readAll(keys, ...contextArgs.args);
|
635
|
+
await Promise.all(models.map(async (m) => {
|
636
|
+
return enforceDBDecorators(this, contextArgs.context, m, OperationKeys.DELETE, OperationKeys.ON);
|
637
|
+
}));
|
638
|
+
return [keys, ...contextArgs.args];
|
639
|
+
}
|
640
|
+
async deleteAll(keys, ...args) {
|
641
|
+
const results = await this.adapter.deleteAll(this.tableName, keys, ...args);
|
642
|
+
return results.map((r, i) => this.adapter.revert(r, this.class, this.pk, keys[i]));
|
643
|
+
}
|
644
|
+
select(selector) {
|
645
|
+
return new Query(this.adapter).select(selector).from(this.class);
|
646
|
+
}
|
647
|
+
async query(condition, orderBy, order = OrderDirection.ASC, limit, skip) {
|
648
|
+
const sort = [orderBy, order];
|
649
|
+
const query = this.select().where(condition).orderBy(sort);
|
650
|
+
if (limit)
|
651
|
+
query.limit(limit);
|
652
|
+
if (skip)
|
653
|
+
query.offset(skip);
|
654
|
+
return query.execute();
|
655
|
+
}
|
656
|
+
/**
|
657
|
+
* @summary Registers an {@link Observer}
|
658
|
+
* @param {Observer} observer
|
659
|
+
*
|
660
|
+
* @see {Observable#observe}
|
661
|
+
*/
|
662
|
+
observe(observer) {
|
663
|
+
const index = this.observers.indexOf(observer);
|
664
|
+
if (index !== -1)
|
665
|
+
throw new InternalError("Observer already registered");
|
666
|
+
this.observers.push(observer);
|
667
|
+
}
|
668
|
+
/**
|
669
|
+
* @summary Unregisters an {@link Observer}
|
670
|
+
* @param {Observer} observer
|
671
|
+
*
|
672
|
+
* @see {Observable#unObserve}
|
673
|
+
*/
|
674
|
+
unObserve(observer) {
|
675
|
+
const index = this.observers.indexOf(observer);
|
676
|
+
if (index === -1)
|
677
|
+
throw new InternalError("Failed to find Observer");
|
678
|
+
this.observers.splice(index, 1);
|
679
|
+
}
|
680
|
+
/**
|
681
|
+
* @summary calls all registered {@link Observer}s to update themselves
|
682
|
+
* @param {any[]} [args] optional arguments to be passed to the {@link Observer#refresh} method
|
683
|
+
*/
|
684
|
+
async updateObservers(...args) {
|
685
|
+
const results = await Promise.allSettled(this.observers.map((o) => o.refresh(...args)));
|
686
|
+
results.forEach((result, i) => {
|
687
|
+
if (result.status === "rejected")
|
688
|
+
console.warn(`Failed to update observable ${this.observers[i]}: ${result.reason}`);
|
689
|
+
});
|
690
|
+
}
|
691
|
+
static forModel(model, defaultFlavour) {
|
692
|
+
let repo;
|
693
|
+
try {
|
694
|
+
repo = this.get(model);
|
695
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
696
|
+
}
|
697
|
+
catch (e) {
|
698
|
+
repo = undefined;
|
699
|
+
}
|
700
|
+
if (repo instanceof Repository)
|
701
|
+
return repo;
|
702
|
+
const flavour = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), model) ||
|
703
|
+
(repo &&
|
704
|
+
Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), repo)) ||
|
705
|
+
defaultFlavour;
|
706
|
+
const adapter = flavour
|
707
|
+
? Adapter.get(flavour)
|
708
|
+
: undefined;
|
709
|
+
if (!adapter)
|
710
|
+
throw new InternalError(`No registered persistence adapter found flavour ${flavour}`);
|
711
|
+
repo = repo || adapter.repository();
|
712
|
+
return new repo(adapter, model);
|
713
|
+
}
|
714
|
+
static get(model) {
|
715
|
+
const name = Repository.table(model);
|
716
|
+
if (name in this._cache)
|
717
|
+
return this._cache[name];
|
718
|
+
throw new InternalError(`Could not find repository registered under ${name}`);
|
719
|
+
}
|
720
|
+
static register(model, repo) {
|
721
|
+
const name = Repository.table(model);
|
722
|
+
if (name in this._cache)
|
723
|
+
throw new InternalError(`${name} already registered as a repository`);
|
724
|
+
this._cache[name] = repo;
|
725
|
+
}
|
726
|
+
static setMetadata(model, metadata) {
|
727
|
+
Object.defineProperty(model, PersistenceKeys.METADATA, {
|
728
|
+
enumerable: false,
|
729
|
+
configurable: true,
|
730
|
+
writable: false,
|
731
|
+
value: metadata,
|
732
|
+
});
|
733
|
+
}
|
734
|
+
static getMetadata(model) {
|
735
|
+
const descriptor = Object.getOwnPropertyDescriptor(model, PersistenceKeys.METADATA);
|
736
|
+
return descriptor ? descriptor.value : undefined;
|
737
|
+
}
|
738
|
+
static removeMetadata(model) {
|
739
|
+
const descriptor = Object.getOwnPropertyDescriptor(model, PersistenceKeys.METADATA);
|
740
|
+
if (descriptor)
|
741
|
+
delete model[PersistenceKeys.METADATA];
|
742
|
+
}
|
743
|
+
static getSequenceOptions(model) {
|
744
|
+
const pk = findPrimaryKey(model).id;
|
745
|
+
const metadata = Reflect.getMetadata(Repository.key(DBKeys.ID), model, pk);
|
746
|
+
if (!metadata)
|
747
|
+
throw new InternalError("No sequence options defined for model. did you use the @pk decorator?");
|
748
|
+
return metadata;
|
749
|
+
}
|
750
|
+
static indexes(model) {
|
751
|
+
const indexDecorators = Reflection.getAllPropertyDecorators(model instanceof Model ? model : new model(), DBKeys.REFLECT);
|
752
|
+
return Object.entries(indexDecorators || {}).reduce((accum, [k, val]) => {
|
753
|
+
const decs = val.filter((v) => v.key.startsWith(PersistenceKeys.INDEX));
|
754
|
+
if (decs && decs.length) {
|
755
|
+
for (const dec of decs) {
|
756
|
+
const { key, props } = dec;
|
757
|
+
accum[k] = accum[k] || {};
|
758
|
+
accum[k][key] = props;
|
759
|
+
}
|
760
|
+
}
|
761
|
+
return accum;
|
762
|
+
}, {});
|
763
|
+
}
|
764
|
+
static relations(model) {
|
765
|
+
const result = [];
|
766
|
+
let prototype = model instanceof Model
|
767
|
+
? Object.getPrototypeOf(model)
|
768
|
+
: model.prototype;
|
769
|
+
while (prototype != null) {
|
770
|
+
const props = prototype[PersistenceKeys.RELATIONS];
|
771
|
+
if (props) {
|
772
|
+
result.push(...props);
|
773
|
+
}
|
774
|
+
prototype = Object.getPrototypeOf(prototype);
|
775
|
+
}
|
776
|
+
return result;
|
777
|
+
}
|
778
|
+
static table(model) {
|
779
|
+
return getTableName(model);
|
780
|
+
}
|
781
|
+
static column(model, attribute) {
|
782
|
+
const metadata = Reflect.getMetadata(Adapter.key(PersistenceKeys.COLUMN), model, attribute);
|
783
|
+
return metadata ? metadata : attribute;
|
784
|
+
}
|
785
|
+
}
|
786
|
+
|
787
|
+
function repository(model, nameOverride) {
|
788
|
+
return ((original, propertyKey) => {
|
789
|
+
if (propertyKey) {
|
790
|
+
return inject(nameOverride || model.name)(original, propertyKey);
|
791
|
+
}
|
792
|
+
metadata(Repository.key(DBKeys.REPOSITORY), nameOverride || original.name)(model);
|
793
|
+
Repository.register(model, original);
|
794
|
+
return injectable(nameOverride || original.name, true, (instance) => {
|
795
|
+
Object.defineProperty(instance, DBKeys.CLASS, {
|
796
|
+
enumerable: false,
|
797
|
+
configurable: false,
|
798
|
+
writable: false,
|
799
|
+
value: model,
|
800
|
+
});
|
801
|
+
})(original);
|
802
|
+
});
|
803
|
+
}
|
804
|
+
|
805
|
+
/**
|
806
|
+
* @summary Represents a failure in observer communication
|
807
|
+
*
|
808
|
+
* @param {string} msg the error message
|
809
|
+
*
|
810
|
+
* @class ObserverError
|
811
|
+
* @extends BaseError
|
812
|
+
*/
|
813
|
+
class ObserverError extends BaseError {
|
814
|
+
constructor(msg) {
|
815
|
+
super(ObserverError.name, msg);
|
816
|
+
}
|
817
|
+
}
|
818
|
+
|
819
|
+
function generateInjectableNameForRepository(model, flavour) {
|
820
|
+
if (!flavour) {
|
821
|
+
const key = Adapter.key(PersistenceKeys.ADAPTER);
|
822
|
+
flavour = Reflect.getMetadata(key, model instanceof Model ? model.constructor : model);
|
823
|
+
if (!flavour)
|
824
|
+
throw new InternalError(`Could not retrieve flavour from model ${model instanceof Model ? model.constructor.name : model.name}`);
|
825
|
+
}
|
826
|
+
return sf(PersistenceKeys.INJECTABLE, flavour, Repository.table(model));
|
827
|
+
}
|
828
|
+
|
829
|
+
class InjectablesRegistry extends InjectableRegistryImp {
|
830
|
+
constructor() {
|
831
|
+
super();
|
832
|
+
}
|
833
|
+
get(name) {
|
834
|
+
let injectable = super.get(name);
|
835
|
+
if (!injectable)
|
836
|
+
try {
|
837
|
+
const m = Model.get(name);
|
838
|
+
if (m)
|
839
|
+
injectable = Repository.forModel(m);
|
840
|
+
if (injectable) {
|
841
|
+
if (injectable instanceof Repository)
|
842
|
+
return injectable;
|
843
|
+
const flavour = Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), injectable.constructor) ||
|
844
|
+
Reflect.getMetadata(Adapter.key(PersistenceKeys.ADAPTER), m);
|
845
|
+
Injectables.register(injectable, generateInjectableNameForRepository(m, flavour));
|
846
|
+
}
|
847
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
848
|
+
}
|
849
|
+
catch (e) {
|
850
|
+
return undefined;
|
851
|
+
}
|
852
|
+
return injectable;
|
853
|
+
}
|
854
|
+
}
|
855
|
+
|
856
|
+
const DefaultSequenceOptions = {
|
857
|
+
type: "Number",
|
858
|
+
startWith: 0,
|
859
|
+
incrementBy: 1,
|
860
|
+
cycle: false,
|
861
|
+
};
|
862
|
+
const NumericSequence = {
|
863
|
+
type: "Number",
|
864
|
+
startWith: 0,
|
865
|
+
incrementBy: 1,
|
866
|
+
cycle: false,
|
867
|
+
};
|
868
|
+
const BigIntSequence = {
|
869
|
+
type: "BigInt",
|
870
|
+
startWith: 0,
|
871
|
+
incrementBy: 1,
|
872
|
+
cycle: false,
|
873
|
+
};
|
874
|
+
|
875
|
+
/******************************************************************************
|
876
|
+
Copyright (c) Microsoft Corporation.
|
877
|
+
|
878
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
879
|
+
purpose with or without fee is hereby granted.
|
880
|
+
|
881
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
882
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
883
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
884
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
885
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
886
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
887
|
+
PERFORMANCE OF THIS SOFTWARE.
|
888
|
+
***************************************************************************** */
|
889
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
890
|
+
|
891
|
+
|
892
|
+
function __decorate(decorators, target, key, desc) {
|
893
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
894
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
895
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
896
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
897
|
+
}
|
898
|
+
|
899
|
+
function __metadata(metadataKey, metadataValue) {
|
900
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
901
|
+
}
|
902
|
+
|
903
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
904
|
+
var e = new Error(message);
|
905
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
906
|
+
};
|
907
|
+
|
908
|
+
class QueryError extends BaseError {
|
909
|
+
constructor(msg) {
|
910
|
+
super(QueryError.name, msg);
|
911
|
+
}
|
912
|
+
}
|
913
|
+
class PagingError extends BaseError {
|
914
|
+
constructor(msg) {
|
915
|
+
super(PagingError.name, msg);
|
916
|
+
}
|
917
|
+
}
|
918
|
+
|
919
|
+
/**
|
920
|
+
* @summary Condition Class
|
921
|
+
* @description Represents a logical condition
|
922
|
+
*
|
923
|
+
* @param {string | Condition} attr1
|
924
|
+
* @param {Operator | GroupOperator} operator
|
925
|
+
* @param {string | Condition} comparison
|
926
|
+
*
|
927
|
+
* @class Condition
|
928
|
+
* @implements Executor
|
929
|
+
*
|
930
|
+
* @category Query
|
931
|
+
* @subcategory Conditions
|
932
|
+
*/
|
933
|
+
class Condition extends Model {
|
934
|
+
constructor(attr1, operator, comparison) {
|
935
|
+
super();
|
936
|
+
this.attr1 = undefined;
|
937
|
+
this.operator = undefined;
|
938
|
+
this.comparison = undefined;
|
939
|
+
this.attr1 = attr1;
|
940
|
+
this.operator = operator;
|
941
|
+
this.comparison = comparison;
|
942
|
+
}
|
943
|
+
/**
|
944
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
|
945
|
+
* @param {Condition} condition
|
946
|
+
*/
|
947
|
+
and(condition) {
|
948
|
+
return Condition.and(this, condition);
|
949
|
+
}
|
950
|
+
/**
|
951
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
|
952
|
+
* @param {Condition} condition
|
953
|
+
*/
|
954
|
+
or(condition) {
|
955
|
+
return Condition.or(this, condition);
|
956
|
+
}
|
957
|
+
/**
|
958
|
+
* @summary excludes a valut from the result
|
959
|
+
* @param val
|
960
|
+
*/
|
961
|
+
not(val) {
|
962
|
+
return new Condition(this, Operator.NOT, val);
|
963
|
+
}
|
964
|
+
/**
|
965
|
+
* @inheritDoc
|
966
|
+
*/
|
967
|
+
hasErrors(...exceptions) {
|
968
|
+
const errors = super.hasErrors(...exceptions);
|
969
|
+
if (errors)
|
970
|
+
return errors;
|
971
|
+
if (typeof this.attr1 === "string") {
|
972
|
+
if (this.comparison instanceof Condition)
|
973
|
+
return {
|
974
|
+
comparison: {
|
975
|
+
condition: "Both sides of the comparison must be of the same type",
|
976
|
+
},
|
977
|
+
};
|
978
|
+
if (Object.values(Operator).indexOf(this.operator) === -1)
|
979
|
+
return {
|
980
|
+
operator: {
|
981
|
+
condition: sf("Invalid operator {0}", this.operator),
|
982
|
+
},
|
983
|
+
};
|
984
|
+
}
|
985
|
+
if (this.attr1 instanceof Condition) {
|
986
|
+
if (!(this.comparison instanceof Condition) &&
|
987
|
+
this.operator !== Operator.NOT)
|
988
|
+
return {
|
989
|
+
comparison: {
|
990
|
+
condition: sf("Invalid operator {0}", this.operator),
|
991
|
+
},
|
992
|
+
};
|
993
|
+
if (Object.values(GroupOperator).indexOf(this.operator) ===
|
994
|
+
-1 &&
|
995
|
+
this.operator !== Operator.NOT)
|
996
|
+
return {
|
997
|
+
operator: {
|
998
|
+
condition: sf("Invalid operator {0}", this.operator),
|
999
|
+
},
|
1000
|
+
};
|
1001
|
+
// if (this.operator !== Operator.NOT && typeof this.attr1.attr1 !== "string")
|
1002
|
+
// return {
|
1003
|
+
// attr1: {
|
1004
|
+
// condition: stringFormat("Parent condition attribute must be a string")
|
1005
|
+
// }
|
1006
|
+
// } as ModelErrorDefinition
|
1007
|
+
}
|
1008
|
+
}
|
1009
|
+
/**
|
1010
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#AND} operation
|
1011
|
+
* @param {Condition} condition1
|
1012
|
+
* @param {Condition} condition2
|
1013
|
+
*/
|
1014
|
+
static and(condition1, condition2) {
|
1015
|
+
return Condition.group(condition1, GroupOperator.AND, condition2);
|
1016
|
+
}
|
1017
|
+
/**
|
1018
|
+
* @summary Joins 2 {@link Condition}s on an {@link Operator#OR} operation
|
1019
|
+
* @param {Condition} condition1
|
1020
|
+
* @param {Condition} condition2
|
1021
|
+
*/
|
1022
|
+
static or(condition1, condition2) {
|
1023
|
+
return Condition.group(condition1, GroupOperator.OR, condition2);
|
1024
|
+
}
|
1025
|
+
/**
|
1026
|
+
* @summary Groups 2 {@link Condition}s by the specified {@link GroupOperator}
|
1027
|
+
* @param {Condition} condition1
|
1028
|
+
* @param {GroupOperator} operator
|
1029
|
+
* @param {Condition} condition2
|
1030
|
+
*/
|
1031
|
+
static group(condition1, operator, condition2) {
|
1032
|
+
return new Condition(condition1, operator, condition2);
|
1033
|
+
}
|
1034
|
+
static attribute(attr) {
|
1035
|
+
return new Condition.Builder().attribute(attr);
|
1036
|
+
}
|
1037
|
+
/**
|
1038
|
+
* @summary Condition Builder Class
|
1039
|
+
* @description provides a simple API to build {@link Condition}s
|
1040
|
+
*
|
1041
|
+
* @class ConditionBuilder
|
1042
|
+
* @implements Builder
|
1043
|
+
* @implements AttributeOption
|
1044
|
+
*
|
1045
|
+
* @category Query
|
1046
|
+
* @subcategory Conditions
|
1047
|
+
*/
|
1048
|
+
static { this.Builder = class ConditionBuilder {
|
1049
|
+
constructor() {
|
1050
|
+
this.attr1 = undefined;
|
1051
|
+
this.operator = undefined;
|
1052
|
+
this.comparison = undefined;
|
1053
|
+
}
|
1054
|
+
/**
|
1055
|
+
* @inheritDoc
|
1056
|
+
*/
|
1057
|
+
attribute(attr) {
|
1058
|
+
this.attr1 = attr;
|
1059
|
+
return this;
|
1060
|
+
}
|
1061
|
+
/**
|
1062
|
+
* @summary Creates an Equality Comparison
|
1063
|
+
* @param {any} val
|
1064
|
+
*/
|
1065
|
+
eq(val) {
|
1066
|
+
return this.setOp(Operator.EQUAL, val);
|
1067
|
+
}
|
1068
|
+
/**
|
1069
|
+
* @summary Creates a Different Comparison
|
1070
|
+
* @param {any} val
|
1071
|
+
*/
|
1072
|
+
dif(val) {
|
1073
|
+
return this.setOp(Operator.DIFFERENT, val);
|
1074
|
+
}
|
1075
|
+
/**
|
1076
|
+
* @summary Creates a Greater Than Comparison
|
1077
|
+
* @param {any} val
|
1078
|
+
*/
|
1079
|
+
gt(val) {
|
1080
|
+
return this.setOp(Operator.BIGGER, val);
|
1081
|
+
}
|
1082
|
+
/**
|
1083
|
+
* @summary Creates a Lower Than Comparison
|
1084
|
+
* @param {any} val
|
1085
|
+
*/
|
1086
|
+
lt(val) {
|
1087
|
+
return this.setOp(Operator.SMALLER, val);
|
1088
|
+
}
|
1089
|
+
/**
|
1090
|
+
* @summary Creates a Greater or Equal to Comparison
|
1091
|
+
* @param {any} val
|
1092
|
+
*/
|
1093
|
+
gte(val) {
|
1094
|
+
return this.setOp(Operator.BIGGER_EQ, val);
|
1095
|
+
}
|
1096
|
+
/**
|
1097
|
+
* @summary Creates a Lower or Equal to Comparison
|
1098
|
+
* @param {any} val
|
1099
|
+
*/
|
1100
|
+
lte(val) {
|
1101
|
+
return this.setOp(Operator.SMALLER_EQ, val);
|
1102
|
+
}
|
1103
|
+
in(arr) {
|
1104
|
+
return this.setOp(Operator.IN, arr);
|
1105
|
+
}
|
1106
|
+
/**
|
1107
|
+
* @summary Creates a Regexpo Comparison
|
1108
|
+
* @param {any} val
|
1109
|
+
*/
|
1110
|
+
regexp(val) {
|
1111
|
+
return this.setOp(Operator.REGEXP, new RegExp(val).source);
|
1112
|
+
}
|
1113
|
+
/**
|
1114
|
+
* @summary Creates an {@link Operator} based Comparison
|
1115
|
+
* @param {Operator} op
|
1116
|
+
* @param {any} val
|
1117
|
+
*/
|
1118
|
+
setOp(op, val) {
|
1119
|
+
this.operator = op;
|
1120
|
+
this.comparison = val;
|
1121
|
+
return this.build();
|
1122
|
+
}
|
1123
|
+
/**
|
1124
|
+
* @summary Builds the Database Object
|
1125
|
+
* @throws {QueryError} if it fails to build the {@link Condition}
|
1126
|
+
* @private
|
1127
|
+
*/
|
1128
|
+
build() {
|
1129
|
+
try {
|
1130
|
+
return new Condition(this.attr1, this.operator, this.comparison);
|
1131
|
+
}
|
1132
|
+
catch (e) {
|
1133
|
+
throw new QueryError(e);
|
1134
|
+
}
|
1135
|
+
}
|
1136
|
+
}; }
|
1137
|
+
static get builder() {
|
1138
|
+
return new Condition.Builder();
|
1139
|
+
}
|
1140
|
+
}
|
1141
|
+
__decorate([
|
1142
|
+
required(),
|
1143
|
+
__metadata("design:type", Object)
|
1144
|
+
], Condition.prototype, "attr1", void 0);
|
1145
|
+
__decorate([
|
1146
|
+
required(),
|
1147
|
+
__metadata("design:type", String)
|
1148
|
+
], Condition.prototype, "operator", void 0);
|
1149
|
+
__decorate([
|
1150
|
+
required(),
|
1151
|
+
__metadata("design:type", Object)
|
1152
|
+
], Condition.prototype, "comparison", void 0);
|
1153
|
+
|
1154
|
+
async function createOrUpdate(model, context, repository) {
|
1155
|
+
if (!repository) {
|
1156
|
+
const constructor = Model.get(model.constructor.name);
|
1157
|
+
if (!constructor)
|
1158
|
+
throw new InternalError(`Could not find model ${model.constructor.name}`);
|
1159
|
+
repository = Repository.forModel(constructor);
|
1160
|
+
}
|
1161
|
+
if (typeof model[repository.pk] === "undefined")
|
1162
|
+
return repository.create(model, context);
|
1163
|
+
else {
|
1164
|
+
try {
|
1165
|
+
return repository.update(model, context);
|
1166
|
+
}
|
1167
|
+
catch (e) {
|
1168
|
+
if (!(e instanceof NotFoundError))
|
1169
|
+
throw e;
|
1170
|
+
return repository.create(model, context);
|
1171
|
+
}
|
1172
|
+
}
|
1173
|
+
}
|
1174
|
+
async function oneToOneOnCreate(context, data, key, model) {
|
1175
|
+
const propertyValue = model[key];
|
1176
|
+
if (!propertyValue)
|
1177
|
+
return;
|
1178
|
+
if (typeof propertyValue !== "object") {
|
1179
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1180
|
+
const read = await innerRepo.read(propertyValue);
|
1181
|
+
await cacheModelForPopulate(context, model, key, propertyValue, read);
|
1182
|
+
model[key] = propertyValue;
|
1183
|
+
return;
|
1184
|
+
}
|
1185
|
+
const constructor = Model.get(data.class);
|
1186
|
+
if (!constructor)
|
1187
|
+
throw new InternalError(`Could not find model ${data.class}`);
|
1188
|
+
const repo = Repository.forModel(constructor);
|
1189
|
+
const created = await repo.create(propertyValue);
|
1190
|
+
const pk = findPrimaryKey(created).id;
|
1191
|
+
await cacheModelForPopulate(context, model, key, created[pk], created);
|
1192
|
+
model[key] = created[pk];
|
1193
|
+
}
|
1194
|
+
async function oneToOneOnUpdate(context, data, key, model) {
|
1195
|
+
const propertyValue = model[key];
|
1196
|
+
if (!propertyValue)
|
1197
|
+
return;
|
1198
|
+
if (data.cascade.update !== Cascade.CASCADE)
|
1199
|
+
return;
|
1200
|
+
if (typeof propertyValue !== "object") {
|
1201
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1202
|
+
const read = await innerRepo.read(propertyValue);
|
1203
|
+
await cacheModelForPopulate(context, model, key, propertyValue, read);
|
1204
|
+
model[key] = propertyValue;
|
1205
|
+
return;
|
1206
|
+
}
|
1207
|
+
const updated = await createOrUpdate(model[key], context);
|
1208
|
+
const pk = findPrimaryKey(updated).id;
|
1209
|
+
await cacheModelForPopulate(context, model, key, updated[pk], updated);
|
1210
|
+
model[key] = updated[pk];
|
1211
|
+
}
|
1212
|
+
async function oneToOneOnDelete(context, data, key, model) {
|
1213
|
+
const propertyValue = model[key];
|
1214
|
+
if (!propertyValue)
|
1215
|
+
return;
|
1216
|
+
if (data.cascade.update !== Cascade.CASCADE)
|
1217
|
+
return;
|
1218
|
+
const innerRepo = repositoryFromTypeMetadata(model, key);
|
1219
|
+
let deleted;
|
1220
|
+
if (!(propertyValue instanceof Model))
|
1221
|
+
deleted = await innerRepo.delete(model[key], context);
|
1222
|
+
else
|
1223
|
+
deleted = await innerRepo.delete(model[key][innerRepo.pk], context);
|
1224
|
+
await cacheModelForPopulate(context, model, key, deleted[innerRepo.pk], deleted);
|
1225
|
+
}
|
1226
|
+
async function oneToManyOnCreate(context, data, key, model) {
|
1227
|
+
const propertyValues = model[key];
|
1228
|
+
if (!propertyValues || !propertyValues.length)
|
1229
|
+
return;
|
1230
|
+
const arrayType = typeof propertyValues[0];
|
1231
|
+
if (!propertyValues.every((item) => typeof item === arrayType))
|
1232
|
+
throw new InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
|
1233
|
+
const uniqueValues = new Set([...propertyValues]);
|
1234
|
+
if (arrayType !== "object") {
|
1235
|
+
const repo = repositoryFromTypeMetadata(model, key);
|
1236
|
+
for (const id of uniqueValues) {
|
1237
|
+
const read = await repo.read(id);
|
1238
|
+
await cacheModelForPopulate(context, model, key, id, read);
|
1239
|
+
}
|
1240
|
+
model[key] = [...uniqueValues];
|
1241
|
+
return;
|
1242
|
+
}
|
1243
|
+
const pkName = findPrimaryKey(propertyValues[0]).id;
|
1244
|
+
const result = new Set();
|
1245
|
+
for (const m of propertyValues) {
|
1246
|
+
const record = await createOrUpdate(m, context);
|
1247
|
+
await cacheModelForPopulate(context, model, key, record[pkName], record);
|
1248
|
+
result.add(record[pkName]);
|
1249
|
+
}
|
1250
|
+
model[key] = [...result];
|
1251
|
+
}
|
1252
|
+
async function oneToManyOnUpdate(context, data, key, model) {
|
1253
|
+
const { cascade } = data;
|
1254
|
+
if (cascade.update !== Cascade.CASCADE)
|
1255
|
+
return;
|
1256
|
+
return oneToManyOnCreate.call(this, context, data, key, model);
|
1257
|
+
}
|
1258
|
+
async function oneToManyOnDelete(context, data, key, model) {
|
1259
|
+
if (data.cascade.delete !== Cascade.CASCADE)
|
1260
|
+
return;
|
1261
|
+
const values = model[key];
|
1262
|
+
if (!values || !values.length)
|
1263
|
+
return;
|
1264
|
+
const arrayType = typeof values[0];
|
1265
|
+
const areAllSameType = values.every((item) => typeof item === arrayType);
|
1266
|
+
if (!areAllSameType)
|
1267
|
+
throw new InternalError(`Invalid operation. All elements of property ${key} must match the same type.`);
|
1268
|
+
const isInstantiated = arrayType === "object";
|
1269
|
+
const repo = isInstantiated
|
1270
|
+
? Repository.forModel(values[0])
|
1271
|
+
: repositoryFromTypeMetadata(model, key);
|
1272
|
+
const uniqueValues = new Set([
|
1273
|
+
...(isInstantiated
|
1274
|
+
? values.map((v) => v[repo.pk])
|
1275
|
+
: values),
|
1276
|
+
]);
|
1277
|
+
for (const id of uniqueValues.values()) {
|
1278
|
+
const deleted = await repo.delete(id, context);
|
1279
|
+
await cacheModelForPopulate(context, model, key, id, deleted);
|
1280
|
+
}
|
1281
|
+
model[key] = [...uniqueValues];
|
1282
|
+
}
|
1283
|
+
function getPopulateKey(tableName, fieldName, id) {
|
1284
|
+
return [PersistenceKeys.POPULATE, tableName, fieldName, id].join(".");
|
1285
|
+
}
|
1286
|
+
async function cacheModelForPopulate(context, parentModel, propertyKey, pkValue, cacheValue) {
|
1287
|
+
const cacheKey = getPopulateKey(parentModel.constructor.name, propertyKey, pkValue);
|
1288
|
+
return context.put(cacheKey, cacheValue);
|
1289
|
+
}
|
1290
|
+
async function populate(context, data, key, model) {
|
1291
|
+
if (!data.populate)
|
1292
|
+
return;
|
1293
|
+
const nested = model[key];
|
1294
|
+
const isArr = Array.isArray(nested);
|
1295
|
+
if (typeof nested === "undefined" || (isArr && nested.length === 0))
|
1296
|
+
return;
|
1297
|
+
async function fetchPopulateValues(c, model, propName, propKeyValues) {
|
1298
|
+
let cacheKey;
|
1299
|
+
let val;
|
1300
|
+
const results = [];
|
1301
|
+
for (const proKeyValue of propKeyValues) {
|
1302
|
+
cacheKey = getPopulateKey(model.constructor.name, propName, proKeyValue);
|
1303
|
+
try {
|
1304
|
+
val = await c.get(cacheKey);
|
1305
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
1306
|
+
}
|
1307
|
+
catch (e) {
|
1308
|
+
const repo = repositoryFromTypeMetadata(model, propName);
|
1309
|
+
if (!repo)
|
1310
|
+
throw new InternalError("Could not find repo");
|
1311
|
+
val = await repo.read(proKeyValue);
|
1312
|
+
}
|
1313
|
+
results.push(val);
|
1314
|
+
}
|
1315
|
+
return results;
|
1316
|
+
}
|
1317
|
+
const res = await fetchPopulateValues(context, model, key, isArr ? nested : [nested]);
|
1318
|
+
model[key] = isArr ? res : res[0];
|
1319
|
+
}
|
1320
|
+
const commomTypes = [
|
1321
|
+
"array",
|
1322
|
+
"string",
|
1323
|
+
"number",
|
1324
|
+
"boolean",
|
1325
|
+
"symbol",
|
1326
|
+
"function",
|
1327
|
+
"object",
|
1328
|
+
"undefined",
|
1329
|
+
"null",
|
1330
|
+
"bigint",
|
1331
|
+
];
|
1332
|
+
function repositoryFromTypeMetadata(model, propertyKey) {
|
1333
|
+
const types = Reflect.getMetadata(Validation.key(Array.isArray(model[propertyKey])
|
1334
|
+
? ValidationKeys.LIST
|
1335
|
+
: ValidationKeys.TYPE), model, propertyKey);
|
1336
|
+
const customTypes = Array.isArray(model[propertyKey])
|
1337
|
+
? types.class
|
1338
|
+
: types.customTypes;
|
1339
|
+
if (!types || !customTypes)
|
1340
|
+
throw new InternalError(`Failed to find types decorators for property ${propertyKey}`);
|
1341
|
+
const allowedTypes = Array.isArray(customTypes)
|
1342
|
+
? [...customTypes]
|
1343
|
+
: [customTypes];
|
1344
|
+
const constructorName = allowedTypes.find((t) => !commomTypes.includes(`${t}`.toLowerCase()));
|
1345
|
+
if (!constructorName)
|
1346
|
+
throw new InternalError(`Property key ${propertyKey} does not have a valid constructor type`);
|
1347
|
+
const constructor = Model.get(constructorName);
|
1348
|
+
if (!constructor)
|
1349
|
+
throw new InternalError(`No registered model found for ${constructorName}`);
|
1350
|
+
return Repository.forModel(constructor);
|
1351
|
+
}
|
1352
|
+
|
1353
|
+
function table(tableName) {
|
1354
|
+
return metadata(Adapter.key(PersistenceKeys.TABLE), tableName);
|
1355
|
+
}
|
1356
|
+
function column(columnName) {
|
1357
|
+
return propMetadata(Adapter.key(PersistenceKeys.COLUMN), columnName);
|
1358
|
+
}
|
1359
|
+
/**
|
1360
|
+
* @summary Index Decorator
|
1361
|
+
* @description properties decorated will the index in the
|
1362
|
+
* DB for performance in queries
|
1363
|
+
*
|
1364
|
+
* @param {OrderDirection[]} [directions]
|
1365
|
+
* @param {string[]} [compositions]
|
1366
|
+
*
|
1367
|
+
* @function index
|
1368
|
+
*/
|
1369
|
+
function index(directions, compositions) {
|
1370
|
+
return propMetadata(Repository.key(`${PersistenceKeys.INDEX}${compositions && compositions.length ? `.${compositions.join(".")}` : ""}`), {
|
1371
|
+
directions: directions,
|
1372
|
+
compositions: compositions,
|
1373
|
+
});
|
1374
|
+
}
|
1375
|
+
async function uniqueOnCreateUpdate(context, data, key, model) {
|
1376
|
+
if (!model[key])
|
1377
|
+
return;
|
1378
|
+
const existing = await this.select()
|
1379
|
+
.where(Condition.attribute(key).eq(model[key]))
|
1380
|
+
.execute();
|
1381
|
+
if (existing.length)
|
1382
|
+
throw new ConflictError(`model already exists with property ${key} equal to ${JSON.stringify(model[key], undefined, 2)}`);
|
1383
|
+
}
|
1384
|
+
/**
|
1385
|
+
* @summary Unique Decorator
|
1386
|
+
* @description Tags a property as unique.
|
1387
|
+
* No other elements in that table can have the same property value
|
1388
|
+
*
|
1389
|
+
* @function unique
|
1390
|
+
*
|
1391
|
+
* @memberOf module:wallet-db.Decorators
|
1392
|
+
*/
|
1393
|
+
function unique() {
|
1394
|
+
return apply(onCreateUpdate(uniqueOnCreateUpdate), propMetadata(Repository.key(PersistenceKeys.UNIQUE), {}));
|
1395
|
+
}
|
1396
|
+
async function createdByOnCreateUpdate(context, data, key, model) {
|
1397
|
+
const user = context.user;
|
1398
|
+
if (!user)
|
1399
|
+
throw new UnsupportedError("This adapter does not support user identification");
|
1400
|
+
model[key] = user.id;
|
1401
|
+
}
|
1402
|
+
function createdBy() {
|
1403
|
+
return apply(onCreate(createdByOnCreateUpdate), propMetadata(Repository.key(PersistenceKeys.CREATED_BY), {}));
|
1404
|
+
}
|
1405
|
+
function updatedBy() {
|
1406
|
+
return apply(onCreateUpdate(createdByOnCreateUpdate), propMetadata(Repository.key(PersistenceKeys.CREATED_BY), {}));
|
1407
|
+
}
|
1408
|
+
/**
|
1409
|
+
* @summary One To One relation Decorators
|
1410
|
+
*
|
1411
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1412
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1413
|
+
* @param {boolean} populate If true, replaces the specified key in the document with the corresponding record from the database
|
1414
|
+
*
|
1415
|
+
* @function onToOne
|
1416
|
+
*
|
1417
|
+
* @memberOf module:wallet-db.Decorators
|
1418
|
+
*
|
1419
|
+
* @see oneToMany
|
1420
|
+
* @see manyToOne
|
1421
|
+
*/
|
1422
|
+
function oneToOne(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
|
1423
|
+
Model.register(clazz);
|
1424
|
+
const metadata = {
|
1425
|
+
class: clazz.name,
|
1426
|
+
cascade: cascadeOptions,
|
1427
|
+
populate: populate$1,
|
1428
|
+
};
|
1429
|
+
return apply(prop(PersistenceKeys.RELATIONS), type([clazz.name, String.name, Number.name, BigInt.name]), onCreate(oneToOneOnCreate, metadata), onUpdate(oneToOneOnUpdate, metadata), onDelete(oneToOneOnDelete, metadata), afterAny(populate, metadata), propMetadata(Repository.key(PersistenceKeys.ONE_TO_ONE), metadata));
|
1430
|
+
}
|
1431
|
+
/**
|
1432
|
+
* @summary One To Many relation Decorators
|
1433
|
+
*
|
1434
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1435
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1436
|
+
*
|
1437
|
+
* @function oneToMany
|
1438
|
+
*
|
1439
|
+
* @memberOf module:wallet-db.Decorators
|
1440
|
+
*
|
1441
|
+
* @see oneToOne
|
1442
|
+
* @see manyToOne
|
1443
|
+
*/
|
1444
|
+
function oneToMany(clazz, cascadeOptions = DefaultCascade, populate$1 = true) {
|
1445
|
+
Model.register(clazz);
|
1446
|
+
const metadata = {
|
1447
|
+
class: clazz.name,
|
1448
|
+
cascade: cascadeOptions,
|
1449
|
+
populate: populate$1,
|
1450
|
+
};
|
1451
|
+
return apply(prop(PersistenceKeys.RELATIONS),
|
1452
|
+
// @ts-expect-error purposeful override
|
1453
|
+
list([clazz, String, Number, BigInt]), onCreate(oneToManyOnCreate, metadata), onUpdate(oneToManyOnUpdate, metadata), onDelete(oneToManyOnDelete, metadata), afterAny(populate, metadata), propMetadata(Repository.key(PersistenceKeys.ONE_TO_MANY), metadata));
|
1454
|
+
}
|
1455
|
+
/**
|
1456
|
+
* @summary Many To One relation Decorators
|
1457
|
+
*
|
1458
|
+
* @param {Constructor<any>} clazz the {@link Sequence} to use. Defaults to {@link NoneSequence}
|
1459
|
+
* @param {CascadeMetadata} [cascadeOptions]
|
1460
|
+
*
|
1461
|
+
* @function manyToOne
|
1462
|
+
*
|
1463
|
+
* @memberOf module:wallet-db.Decorators
|
1464
|
+
*
|
1465
|
+
* @see oneToMany
|
1466
|
+
* @see oneToOne
|
1467
|
+
*/
|
1468
|
+
function manyToOne(clazz, cascadeOptions = DefaultCascade, populate = true) {
|
1469
|
+
Model.register(clazz);
|
1470
|
+
const metadata = {
|
1471
|
+
class: clazz.name,
|
1472
|
+
cascade: cascadeOptions,
|
1473
|
+
populate: populate,
|
1474
|
+
};
|
1475
|
+
return apply(prop(PersistenceKeys.RELATIONS), type([clazz.name, String.name, Number.name, BigInt.name]),
|
1476
|
+
// onCreate(oneToManyOnCreate, metadata),
|
1477
|
+
// onUpdate(oneToManyOnUpdate, metadata),
|
1478
|
+
// onDelete(oneToManyOnDelete, metadata),
|
1479
|
+
// afterAll(populate, metadata),
|
1480
|
+
propMetadata(Repository.key(PersistenceKeys.MANY_TO_ONE), metadata));
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
/**
|
1484
|
+
* @summary Primary Key Decorator
|
1485
|
+
* @description Marks the property as the {@link Model}s primary key.
|
1486
|
+
* Also marks the property as {@link unique} as {@required} and ensures the index is created properly according to the provided {@link Sequence}
|
1487
|
+
*
|
1488
|
+
*
|
1489
|
+
*
|
1490
|
+
* @function pk
|
1491
|
+
*
|
1492
|
+
* @memberOf module:wallet-db.Decorators
|
1493
|
+
*
|
1494
|
+
* @see unique
|
1495
|
+
* @see required
|
1496
|
+
* @see on
|
1497
|
+
* @param data
|
1498
|
+
* @param key
|
1499
|
+
* @param model
|
1500
|
+
*/
|
1501
|
+
async function pkOnCreate(context, data, key, model) {
|
1502
|
+
if (!data.type || model[key]) {
|
1503
|
+
return;
|
1504
|
+
}
|
1505
|
+
const setPrimaryKeyValue = function (target, propertyKey, value) {
|
1506
|
+
Object.defineProperty(target, propertyKey, {
|
1507
|
+
enumerable: true,
|
1508
|
+
writable: false,
|
1509
|
+
configurable: true,
|
1510
|
+
value: value,
|
1511
|
+
});
|
1512
|
+
};
|
1513
|
+
if (!data.name)
|
1514
|
+
data.name = sequenceNameForModel(model, "pk");
|
1515
|
+
let sequence;
|
1516
|
+
try {
|
1517
|
+
sequence = await this.adapter.Sequence(data);
|
1518
|
+
}
|
1519
|
+
catch (e) {
|
1520
|
+
throw new InternalError(`Failed to instantiate Sequence ${data.name}: ${e}`);
|
1521
|
+
}
|
1522
|
+
const next = await sequence.next();
|
1523
|
+
setPrimaryKeyValue(model, key, next);
|
1524
|
+
}
|
1525
|
+
function pk(opts = DefaultSequenceOptions) {
|
1526
|
+
opts = Object.assign({}, DefaultSequenceOptions, opts);
|
1527
|
+
return apply(index([OrderDirection.ASC, OrderDirection.DSC]), required(), readonly(),
|
1528
|
+
// type([String.name, Number.name, BigInt.name]),
|
1529
|
+
propMetadata(Repository.key(DBKeys.ID), opts), onCreate(pkOnCreate, opts));
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
class BaseModel extends Model {
|
1533
|
+
constructor(arg) {
|
1534
|
+
super(arg);
|
1535
|
+
}
|
1536
|
+
}
|
1537
|
+
__decorate([
|
1538
|
+
timestamp(DBOperations.CREATE),
|
1539
|
+
__metadata("design:type", Date)
|
1540
|
+
], BaseModel.prototype, "createdOn", void 0);
|
1541
|
+
__decorate([
|
1542
|
+
timestamp(),
|
1543
|
+
__metadata("design:type", Date)
|
1544
|
+
], BaseModel.prototype, "updatedOn", void 0);
|
1545
|
+
|
1546
|
+
let User = class User extends Model {
|
1547
|
+
constructor(arg) {
|
1548
|
+
super(arg);
|
1549
|
+
}
|
1550
|
+
};
|
1551
|
+
__decorate([
|
1552
|
+
pk(),
|
1553
|
+
__metadata("design:type", String)
|
1554
|
+
], User.prototype, "id", void 0);
|
1555
|
+
__decorate([
|
1556
|
+
list([String]),
|
1557
|
+
__metadata("design:type", Array)
|
1558
|
+
], User.prototype, "roles", void 0);
|
1559
|
+
__decorate([
|
1560
|
+
list([String]),
|
1561
|
+
__metadata("design:type", Array)
|
1562
|
+
], User.prototype, "affiliations", void 0);
|
1563
|
+
User = __decorate([
|
1564
|
+
model(),
|
1565
|
+
__metadata("design:paramtypes", [Object])
|
1566
|
+
], User);
|
1567
|
+
|
1568
|
+
Object.defineProperty(DEFAULT_ERROR_MESSAGES, PersistenceKeys.CLAUSE_SEQUENCE, {
|
1569
|
+
value: "Invalid clause sequence: {0}",
|
1570
|
+
});
|
1571
|
+
Object.defineProperty(ValidationKeys, "CLAUSE_SEQUENCE", {
|
1572
|
+
value: PersistenceKeys.CLAUSE_SEQUENCE,
|
1573
|
+
});
|
1574
|
+
/**
|
1575
|
+
*
|
1576
|
+
* @param {string} [message]
|
1577
|
+
*
|
1578
|
+
* @function clauseSequence
|
1579
|
+
*
|
1580
|
+
* @category Decorators
|
1581
|
+
* @subcategory Validation
|
1582
|
+
*/
|
1583
|
+
function clauseSequence(message) {
|
1584
|
+
return propMetadata(Validation.key(ValidationKeys.REQUIRED), {
|
1585
|
+
message: message ||
|
1586
|
+
DEFAULT_ERROR_MESSAGES[PersistenceKeys.CLAUSE_SEQUENCE],
|
1587
|
+
});
|
1588
|
+
}
|
1589
|
+
|
1590
|
+
/**
|
1591
|
+
* @summary Validates a {@link Sequence}'s {@link Clause}s
|
1592
|
+
*
|
1593
|
+
* @param {string} [message]
|
1594
|
+
*
|
1595
|
+
* @class ClauseSequenceValidator
|
1596
|
+
* @extends Validator
|
1597
|
+
*
|
1598
|
+
* @category Validation
|
1599
|
+
* @subcategory Validators
|
1600
|
+
*/
|
1601
|
+
let ClauseSequenceValidator = class ClauseSequenceValidator extends Validator {
|
1602
|
+
constructor(message = DEFAULT_ERROR_MESSAGES[PersistenceKeys.CLAUSE_SEQUENCE]) {
|
1603
|
+
super(message);
|
1604
|
+
}
|
1605
|
+
validateSequence(clauses, message) {
|
1606
|
+
return MandatoryPriorities.every((p) => !!clauses.find((c) => c.getPriority() === p))
|
1607
|
+
? undefined
|
1608
|
+
: this.getMessage(sf(message || this.message, "Missing required Clause Priorities"));
|
1609
|
+
}
|
1610
|
+
/**
|
1611
|
+
* @summary Verifies the model for errors
|
1612
|
+
* @param {string} value
|
1613
|
+
* @param {ValidatorOptions} [options]
|
1614
|
+
*
|
1615
|
+
* @return Errors
|
1616
|
+
*
|
1617
|
+
* @override
|
1618
|
+
*
|
1619
|
+
* @see Validator
|
1620
|
+
*/
|
1621
|
+
hasErrors(value, options) {
|
1622
|
+
try {
|
1623
|
+
if (!value ||
|
1624
|
+
!Array.isArray(value) ||
|
1625
|
+
!value.length ||
|
1626
|
+
!value.every((e) => e instanceof Clause))
|
1627
|
+
return this.getMessage(sf((options || {}).message || this.message, "No or invalid Clauses found"));
|
1628
|
+
const clauses = value;
|
1629
|
+
const clauseErrors = clauses.reduce((accum, c) => {
|
1630
|
+
const errs = c.hasErrors();
|
1631
|
+
if (errs)
|
1632
|
+
if (accum)
|
1633
|
+
accum += sf("\nClause {0}: {1}", c.constructor.name, errs.toString());
|
1634
|
+
else
|
1635
|
+
accum = sf("Clause {0}: {1}", c.constructor.name, errs.toString());
|
1636
|
+
return accum;
|
1637
|
+
}, undefined);
|
1638
|
+
if (clauseErrors)
|
1639
|
+
return this.getMessage(sf((options || {}).message || this.message, clauseErrors.toString()));
|
1640
|
+
const verifyPriority = () => {
|
1641
|
+
const priorities = clauses.map((c) => c.getPriority());
|
1642
|
+
const allUnique = new Set(priorities).size === priorities.length;
|
1643
|
+
if (!allUnique)
|
1644
|
+
return "Not all clauses have unique priorities";
|
1645
|
+
const sorted = priorities.sort((a, b) => {
|
1646
|
+
return b - a;
|
1647
|
+
});
|
1648
|
+
return isEqual(priorities, sorted)
|
1649
|
+
? true
|
1650
|
+
: "Clauses are not properly sorted";
|
1651
|
+
};
|
1652
|
+
const priorityCheck = verifyPriority();
|
1653
|
+
if (priorityCheck !== true)
|
1654
|
+
return this.getMessage(sf((options || {}).message || this.message, "Invalid prioritization"));
|
1655
|
+
const sequenceCheck = this.validateSequence(clauses, (options || {}).message);
|
1656
|
+
if (sequenceCheck)
|
1657
|
+
return this.getMessage(sf((options || {}).message || this.message, "Invalid sequence"));
|
1658
|
+
}
|
1659
|
+
catch (e) {
|
1660
|
+
throw new QueryError(sf("Failed to verify clause sequence {0}: {1}", value, e));
|
1661
|
+
}
|
1662
|
+
}
|
1663
|
+
};
|
1664
|
+
ClauseSequenceValidator = __decorate([
|
1665
|
+
validator(PersistenceKeys.CLAUSE_SEQUENCE),
|
1666
|
+
__metadata("design:paramtypes", [String])
|
1667
|
+
], ClauseSequenceValidator);
|
1668
|
+
|
1669
|
+
/**
|
1670
|
+
* @summary Statement Class
|
1671
|
+
* @description holds all the clauses until they can be processed
|
1672
|
+
*
|
1673
|
+
* @param {ModelArg} [statement]
|
1674
|
+
*
|
1675
|
+
* @class Statement
|
1676
|
+
* @extends Model
|
1677
|
+
* @implements Executor
|
1678
|
+
* @implements RawExecutor
|
1679
|
+
*
|
1680
|
+
* @category Query
|
1681
|
+
*/
|
1682
|
+
class Statement extends Model {
|
1683
|
+
constructor(db) {
|
1684
|
+
super();
|
1685
|
+
this.clauses = undefined;
|
1686
|
+
this.target = undefined;
|
1687
|
+
this.fullRecord = false;
|
1688
|
+
this.type = undefined;
|
1689
|
+
this.adapter = db;
|
1690
|
+
}
|
1691
|
+
build() {
|
1692
|
+
if (!this.clauses)
|
1693
|
+
throw new QueryError(sf("Failed to build Statement:\n{0}", "No Clauses"));
|
1694
|
+
this.clauses.sort((c1, c2) => {
|
1695
|
+
return c1.getPriority() - c2.getPriority();
|
1696
|
+
});
|
1697
|
+
const errors = this.hasErrors();
|
1698
|
+
if (errors)
|
1699
|
+
throw new QueryError(sf("Poorly built statement: {0}", errors.toString()));
|
1700
|
+
let query;
|
1701
|
+
try {
|
1702
|
+
const iterator = function (clauses, previous = {}) {
|
1703
|
+
const c = clauses.shift();
|
1704
|
+
if (!c)
|
1705
|
+
return previous;
|
1706
|
+
const results = c.build(previous);
|
1707
|
+
return iterator(clauses, results);
|
1708
|
+
};
|
1709
|
+
query = iterator(new Array(...this.clauses));
|
1710
|
+
}
|
1711
|
+
catch (e) {
|
1712
|
+
throw new QueryError(e);
|
1713
|
+
}
|
1714
|
+
return query;
|
1715
|
+
}
|
1716
|
+
/**
|
1717
|
+
* @inheritDoc
|
1718
|
+
*/
|
1719
|
+
async execute() {
|
1720
|
+
try {
|
1721
|
+
const query = this.build();
|
1722
|
+
return this.raw(query);
|
1723
|
+
}
|
1724
|
+
catch (e) {
|
1725
|
+
throw new InternalError(e);
|
1726
|
+
}
|
1727
|
+
}
|
1728
|
+
async raw(rawInput, ...args) {
|
1729
|
+
const results = await this.adapter.raw(rawInput, true, ...args);
|
1730
|
+
if (!this.fullRecord)
|
1731
|
+
return results;
|
1732
|
+
if (!this.target)
|
1733
|
+
throw new InternalError("No target defined in statement. should never happen");
|
1734
|
+
const pkAttr = findPrimaryKey(new this.target()).id;
|
1735
|
+
const processor = function recordProcessor(r) {
|
1736
|
+
const id = r[pkAttr];
|
1737
|
+
return this.adapter.revert(r, this.target, pkAttr, id);
|
1738
|
+
}.bind(this);
|
1739
|
+
if (Array.isArray(results))
|
1740
|
+
return results.map(processor);
|
1741
|
+
return processor(results);
|
1742
|
+
}
|
1743
|
+
/**
|
1744
|
+
* @inheritDoc
|
1745
|
+
*/
|
1746
|
+
hasErrors(...exceptions) {
|
1747
|
+
const errors = super.hasErrors(...exceptions);
|
1748
|
+
if (errors)
|
1749
|
+
return errors;
|
1750
|
+
for (const i in this.clauses) {
|
1751
|
+
const err = this.clauses[i].hasErrors();
|
1752
|
+
if (err)
|
1753
|
+
return err;
|
1754
|
+
}
|
1755
|
+
}
|
1756
|
+
/**
|
1757
|
+
* @summary Adds a clause to the Statement
|
1758
|
+
* @param {Clause} clause
|
1759
|
+
*/
|
1760
|
+
addClause(clause) {
|
1761
|
+
if (!this.clauses)
|
1762
|
+
this.clauses = [];
|
1763
|
+
const priority = clause.getPriority();
|
1764
|
+
const currentPriority = this.clauses
|
1765
|
+
.map((c, i) => ({ index: i, clause: c }))
|
1766
|
+
.find((c) => c.clause.getPriority() === priority);
|
1767
|
+
if (currentPriority) {
|
1768
|
+
this.clauses[currentPriority.index] = clause;
|
1769
|
+
}
|
1770
|
+
this.clauses.push(clause);
|
1771
|
+
}
|
1772
|
+
getAdapter() {
|
1773
|
+
return this.adapter;
|
1774
|
+
}
|
1775
|
+
/**
|
1776
|
+
* @summary Defines the output class (when existing)
|
1777
|
+
* @param {Constructor} clazz
|
1778
|
+
*/
|
1779
|
+
setTarget(clazz) {
|
1780
|
+
if (this.target)
|
1781
|
+
throw new QueryError(sf("Output class already defined to {0}", this.target.name));
|
1782
|
+
this.target = clazz;
|
1783
|
+
}
|
1784
|
+
getTarget() {
|
1785
|
+
if (!this.target)
|
1786
|
+
throw new InternalError("No target defined for statement");
|
1787
|
+
return this.target;
|
1788
|
+
}
|
1789
|
+
setFullRecord() {
|
1790
|
+
this.fullRecord = true;
|
1791
|
+
}
|
1792
|
+
setMode(type) {
|
1793
|
+
this.type = type;
|
1794
|
+
}
|
1795
|
+
}
|
1796
|
+
__decorate([
|
1797
|
+
required(),
|
1798
|
+
minlength(MandatoryPriorities.length),
|
1799
|
+
clauseSequence(),
|
1800
|
+
__metadata("design:type", Array)
|
1801
|
+
], Statement.prototype, "clauses", void 0);
|
1802
|
+
__decorate([
|
1803
|
+
required(),
|
1804
|
+
type(["object"]),
|
1805
|
+
__metadata("design:type", Adapter)
|
1806
|
+
], Statement.prototype, "adapter", void 0);
|
1807
|
+
__decorate([
|
1808
|
+
required(),
|
1809
|
+
__metadata("design:type", Object)
|
1810
|
+
], Statement.prototype, "target", void 0);
|
1811
|
+
__decorate([
|
1812
|
+
required(),
|
1813
|
+
__metadata("design:type", String)
|
1814
|
+
], Statement.prototype, "type", void 0);
|
1815
|
+
|
1816
|
+
/**
|
1817
|
+
*/
|
1818
|
+
/**
|
1819
|
+
* @summary Clause Class
|
1820
|
+
* @description Represents a Clause in a {@link Statement}
|
1821
|
+
*
|
1822
|
+
* @typedef Q Represents que query object the persistence adapter uses
|
1823
|
+
*
|
1824
|
+
* @param {ModelArg<Clause<Q>>} [clause]
|
1825
|
+
*
|
1826
|
+
* @class Clause
|
1827
|
+
* @extends Model
|
1828
|
+
* @implements Executor
|
1829
|
+
* @implements QueryBuilder
|
1830
|
+
* @abstract
|
1831
|
+
*
|
1832
|
+
* @category Query
|
1833
|
+
* @subcategory Clauses
|
1834
|
+
*/
|
1835
|
+
class Clause extends Model {
|
1836
|
+
constructor(clause) {
|
1837
|
+
super();
|
1838
|
+
this.priority = clause?.priority;
|
1839
|
+
this.statement = clause?.statement;
|
1840
|
+
if (!this.statement || !this.priority)
|
1841
|
+
throw new QueryError("Missing statement or priority. Should be impossible");
|
1842
|
+
this.statement.addClause(this);
|
1843
|
+
}
|
1844
|
+
get adapter() {
|
1845
|
+
return this.statement.getAdapter();
|
1846
|
+
}
|
1847
|
+
get Clauses() {
|
1848
|
+
return this.statement.getAdapter().Clauses;
|
1849
|
+
}
|
1850
|
+
/**
|
1851
|
+
* @summary return the priority of the clause
|
1852
|
+
* @see Priority
|
1853
|
+
*/
|
1854
|
+
getPriority() {
|
1855
|
+
return this.priority;
|
1856
|
+
}
|
1857
|
+
/**
|
1858
|
+
* @inheritDoc
|
1859
|
+
* @abstract
|
1860
|
+
*/
|
1861
|
+
async execute() {
|
1862
|
+
return this.statement.execute();
|
1863
|
+
}
|
1864
|
+
/**
|
1865
|
+
* @inheritDoc
|
1866
|
+
* @abstract
|
1867
|
+
*/
|
1868
|
+
async paginate(size) {
|
1869
|
+
return this.statement.paginate(size);
|
1870
|
+
}
|
1871
|
+
toString() {
|
1872
|
+
return this.constructor.name;
|
1873
|
+
}
|
1874
|
+
}
|
1875
|
+
__decorate([
|
1876
|
+
required(),
|
1877
|
+
__metadata("design:type", Number)
|
1878
|
+
], Clause.prototype, "priority", void 0);
|
1879
|
+
__decorate([
|
1880
|
+
required(),
|
1881
|
+
type("object"),
|
1882
|
+
__metadata("design:type", Statement)
|
1883
|
+
], Clause.prototype, "statement", void 0);
|
1884
|
+
|
1885
|
+
/**
|
1886
|
+
* @summary The base Selector based clause
|
1887
|
+
*
|
1888
|
+
* @param {ClauseArg} [clause]
|
1889
|
+
*
|
1890
|
+
* @class SelectorBasedClause
|
1891
|
+
* @extends Clause
|
1892
|
+
* @abstract
|
1893
|
+
*
|
1894
|
+
* @category Query
|
1895
|
+
* @subcategory Clauses
|
1896
|
+
*/
|
1897
|
+
class SelectorBasedClause extends Clause {
|
1898
|
+
constructor(clause) {
|
1899
|
+
super(clause);
|
1900
|
+
/**
|
1901
|
+
* @summary Stores the selector
|
1902
|
+
*
|
1903
|
+
* @prop selector
|
1904
|
+
* @protected
|
1905
|
+
*/
|
1906
|
+
this.selector = undefined;
|
1907
|
+
this.selector = clause.selector;
|
1908
|
+
}
|
1909
|
+
toString() {
|
1910
|
+
return this.constructor.name + `[${this.selector}]`;
|
1911
|
+
}
|
1912
|
+
}
|
1913
|
+
__decorate([
|
1914
|
+
required(),
|
1915
|
+
__metadata("design:type", Object)
|
1916
|
+
], SelectorBasedClause.prototype, "selector", void 0);
|
1917
|
+
|
1918
|
+
/**
|
1919
|
+
* @summary The FROM clause
|
1920
|
+
*
|
1921
|
+
* @param {ModelArg} [clause]
|
1922
|
+
*
|
1923
|
+
* @class FromClause
|
1924
|
+
* @extends SelectorBasedClause
|
1925
|
+
* @implements WhereOption
|
1926
|
+
*
|
1927
|
+
* @category Query
|
1928
|
+
* @subcategory Clauses
|
1929
|
+
*/
|
1930
|
+
class FromClause extends SelectorBasedClause {
|
1931
|
+
constructor(clause) {
|
1932
|
+
super(Object.assign({}, clause, { priority: Priority.FROM }));
|
1933
|
+
this.selector =
|
1934
|
+
typeof this.selector === "string"
|
1935
|
+
? Model.get(this.selector)
|
1936
|
+
: this.selector;
|
1937
|
+
if (!this.selector)
|
1938
|
+
throw new QueryError(stringFormat("Could not find selector model: {0}"));
|
1939
|
+
this.statement.setTarget(this.selector);
|
1940
|
+
}
|
1941
|
+
/**
|
1942
|
+
* @inheritDoc
|
1943
|
+
*/
|
1944
|
+
where(condition) {
|
1945
|
+
return this.Clauses.where(this.statement, condition);
|
1946
|
+
}
|
1947
|
+
/**
|
1948
|
+
* @inheritDoc
|
1949
|
+
*/
|
1950
|
+
orderBy(...selector) {
|
1951
|
+
return this.Clauses.orderBy(this.statement, selector);
|
1952
|
+
}
|
1953
|
+
/**
|
1954
|
+
* @inheritDoc
|
1955
|
+
*/
|
1956
|
+
groupBy(selector) {
|
1957
|
+
return this.Clauses.groupBy(this.statement, selector);
|
1958
|
+
}
|
1959
|
+
/**
|
1960
|
+
* @inheritDoc
|
1961
|
+
*/
|
1962
|
+
limit(selector) {
|
1963
|
+
return this.Clauses.limit(this.statement, selector);
|
1964
|
+
}
|
1965
|
+
/**
|
1966
|
+
* @inheritDoc
|
1967
|
+
*/
|
1968
|
+
offset(selector) {
|
1969
|
+
return this.Clauses.offset(this.statement, selector);
|
1970
|
+
}
|
1971
|
+
}
|
1972
|
+
|
1973
|
+
/**
|
1974
|
+
* @summary The GROUP BY clause
|
1975
|
+
*
|
1976
|
+
* @param {ClauseArg} [clause]
|
1977
|
+
*
|
1978
|
+
* @class GroupByClause
|
1979
|
+
* @extends SelectorBasedClause
|
1980
|
+
*
|
1981
|
+
* @category Query
|
1982
|
+
* @subcategory Clauses
|
1983
|
+
*/
|
1984
|
+
class GroupByClause extends SelectorBasedClause {
|
1985
|
+
constructor(clause) {
|
1986
|
+
super(Object.assign({}, clause, { priority: Priority.GROUP_BY }));
|
1987
|
+
}
|
1988
|
+
}
|
1989
|
+
|
1990
|
+
/**
|
1991
|
+
* @summary The INSERT/INTO clause
|
1992
|
+
*
|
1993
|
+
* @param {ClauseArg} [clause]
|
1994
|
+
*
|
1995
|
+
* @class FromClause
|
1996
|
+
* @extends Clause
|
1997
|
+
* @implements IntoOption
|
1998
|
+
*
|
1999
|
+
* @category Query
|
2000
|
+
* @subcategory Clauses
|
2001
|
+
*/
|
2002
|
+
class InsertClause extends Clause {
|
2003
|
+
constructor(clause) {
|
2004
|
+
super(Object.assign({}, clause, { priority: Priority.SELECT }));
|
2005
|
+
this.table = undefined;
|
2006
|
+
}
|
2007
|
+
/**
|
2008
|
+
* @inheritDoc
|
2009
|
+
*/
|
2010
|
+
into(table) {
|
2011
|
+
this.table = table.name; // TODO get mapped name
|
2012
|
+
this.statement.setTarget(table);
|
2013
|
+
return this;
|
2014
|
+
}
|
2015
|
+
/**
|
2016
|
+
* @inheritDoc
|
2017
|
+
*/
|
2018
|
+
values(...models) {
|
2019
|
+
return this.Clauses.values(this.statement, models);
|
2020
|
+
}
|
2021
|
+
/**
|
2022
|
+
* @inheritDoc
|
2023
|
+
*/
|
2024
|
+
where(condition) {
|
2025
|
+
return this.Clauses.where(this.statement, condition);
|
2026
|
+
}
|
2027
|
+
}
|
2028
|
+
__decorate([
|
2029
|
+
required(),
|
2030
|
+
__metadata("design:type", String)
|
2031
|
+
], InsertClause.prototype, "table", void 0);
|
2032
|
+
|
2033
|
+
/**
|
2034
|
+
* @summary Limit Clause
|
2035
|
+
* @description Limits the results
|
2036
|
+
*
|
2037
|
+
* @param {ClauseArg} [clause]
|
2038
|
+
*
|
2039
|
+
* @class LimitClause
|
2040
|
+
* @extends SelectorBasedClause<T>
|
2041
|
+
* @implements OffsetOption<T>
|
2042
|
+
*
|
2043
|
+
* @category Query
|
2044
|
+
* @subcategory Clauses
|
2045
|
+
*/
|
2046
|
+
class LimitClause extends SelectorBasedClause {
|
2047
|
+
constructor(clause) {
|
2048
|
+
super(Object.assign({}, clause, { priority: Priority.GROUP_BY }));
|
2049
|
+
}
|
2050
|
+
/**
|
2051
|
+
* @inheritDoc
|
2052
|
+
*/
|
2053
|
+
offset(selector) {
|
2054
|
+
return this.Clauses.offset(this.statement, selector);
|
2055
|
+
}
|
2056
|
+
}
|
2057
|
+
|
2058
|
+
/**
|
2059
|
+
* @summary The OFFSET clause
|
2060
|
+
*
|
2061
|
+
* @param {ClauseArg} [clause]
|
2062
|
+
*
|
2063
|
+
* @class FromClause
|
2064
|
+
* @extends SelectorBasedClause
|
2065
|
+
*
|
2066
|
+
* @category Query
|
2067
|
+
* @subcategory Clauses
|
2068
|
+
*/
|
2069
|
+
class OffsetClause extends SelectorBasedClause {
|
2070
|
+
constructor(clause) {
|
2071
|
+
super(Object.assign({}, clause, { priority: Priority.GROUP_BY }));
|
2072
|
+
}
|
2073
|
+
}
|
2074
|
+
|
2075
|
+
/**
|
2076
|
+
* @summary The ORDER BY clause
|
2077
|
+
*
|
2078
|
+
* @param {ClauseArg} [clause]
|
2079
|
+
*
|
2080
|
+
* @class OrderByClause
|
2081
|
+
* @extends SelectorBasedClause
|
2082
|
+
* @implements LimitOption
|
2083
|
+
* @implements OffsetOption
|
2084
|
+
*
|
2085
|
+
* @category Query
|
2086
|
+
* @subcategory Clauses
|
2087
|
+
*/
|
2088
|
+
class OrderByClause extends SelectorBasedClause {
|
2089
|
+
constructor(clause) {
|
2090
|
+
super(Object.assign({}, clause, { priority: Priority.ORDER_BY }));
|
2091
|
+
}
|
2092
|
+
/**
|
2093
|
+
* @inheritDoc
|
2094
|
+
*/
|
2095
|
+
groupBy(selector) {
|
2096
|
+
return this.Clauses.groupBy(this.statement, selector);
|
2097
|
+
}
|
2098
|
+
/**
|
2099
|
+
* @inheritDoc
|
2100
|
+
*/
|
2101
|
+
limit(selector) {
|
2102
|
+
return this.Clauses.limit(this.statement, selector);
|
2103
|
+
}
|
2104
|
+
/**
|
2105
|
+
* @inheritDoc
|
2106
|
+
*/
|
2107
|
+
offset(selector) {
|
2108
|
+
return this.Clauses.offset(this.statement, selector);
|
2109
|
+
}
|
2110
|
+
}
|
2111
|
+
|
2112
|
+
/**
|
2113
|
+
* @summary The SELECT clause
|
2114
|
+
*
|
2115
|
+
* @param {ClauseArg} [clause]
|
2116
|
+
*
|
2117
|
+
* @class SelectClause
|
2118
|
+
* @extends SelectorBasedClause
|
2119
|
+
* @implements SelectOption
|
2120
|
+
*
|
2121
|
+
* @category Query
|
2122
|
+
* @subcategory Clauses
|
2123
|
+
*/
|
2124
|
+
class SelectClause extends SelectorBasedClause {
|
2125
|
+
constructor(clause) {
|
2126
|
+
super(Object.assign({}, clause, { priority: Priority.SELECT }));
|
2127
|
+
this.isDistinct = false;
|
2128
|
+
this.isCount = false;
|
2129
|
+
this.isMax = false;
|
2130
|
+
this.isMin = false;
|
2131
|
+
if (this.selector === Const.FULL_RECORD)
|
2132
|
+
this.statement.setFullRecord();
|
2133
|
+
this.statement.setMode(StatementType.QUERY);
|
2134
|
+
}
|
2135
|
+
/**
|
2136
|
+
* @inheritDoc
|
2137
|
+
*/
|
2138
|
+
distinct(selector) {
|
2139
|
+
this.isDistinct = true;
|
2140
|
+
this.selector = selector;
|
2141
|
+
return this;
|
2142
|
+
}
|
2143
|
+
/**
|
2144
|
+
* @inheritDoc
|
2145
|
+
*/
|
2146
|
+
count(selector) {
|
2147
|
+
this.selector = selector;
|
2148
|
+
return this;
|
2149
|
+
}
|
2150
|
+
/**
|
2151
|
+
* @inheritDoc
|
2152
|
+
*/
|
2153
|
+
min(selector) {
|
2154
|
+
this.selector = selector;
|
2155
|
+
return this;
|
2156
|
+
}
|
2157
|
+
/**
|
2158
|
+
* @inheritDoc
|
2159
|
+
*/
|
2160
|
+
max(selector) {
|
2161
|
+
this.selector = selector;
|
2162
|
+
return this;
|
2163
|
+
}
|
2164
|
+
/**
|
2165
|
+
* @inheritDoc
|
2166
|
+
*/
|
2167
|
+
from(tableName) {
|
2168
|
+
return this.Clauses.from(this.statement, tableName);
|
2169
|
+
}
|
2170
|
+
}
|
2171
|
+
|
2172
|
+
/**
|
2173
|
+
* @summary The VALUES clause
|
2174
|
+
*
|
2175
|
+
* @param {ClauseArg} [clause]
|
2176
|
+
*
|
2177
|
+
* @class ValuesClause
|
2178
|
+
* @extends Clause
|
2179
|
+
*
|
2180
|
+
* @category Query
|
2181
|
+
* @subcategory Clauses
|
2182
|
+
*/
|
2183
|
+
class ValuesClause extends Clause {
|
2184
|
+
constructor(clause) {
|
2185
|
+
super(Object.assign({}, clause, { priority: Priority.FROM }));
|
2186
|
+
this.models = undefined;
|
2187
|
+
this.models = clause?.models;
|
2188
|
+
}
|
2189
|
+
}
|
2190
|
+
__decorate([
|
2191
|
+
required(),
|
2192
|
+
type(Array.name),
|
2193
|
+
__metadata("design:type", Array)
|
2194
|
+
], ValuesClause.prototype, "models", void 0);
|
2195
|
+
|
2196
|
+
/**
|
2197
|
+
* @summary The WHERE clause
|
2198
|
+
*
|
2199
|
+
* @param {ClauseArg} [clause]
|
2200
|
+
*
|
2201
|
+
* @class WhereClause
|
2202
|
+
* @extends Clause
|
2203
|
+
* @implements OrderAndGroupOption
|
2204
|
+
*
|
2205
|
+
* @category Query
|
2206
|
+
* @subcategory Clauses
|
2207
|
+
*/
|
2208
|
+
class WhereClause extends Clause {
|
2209
|
+
constructor(clause) {
|
2210
|
+
super(Object.assign({}, clause, { priority: Priority.WHERE }));
|
2211
|
+
this.condition = undefined;
|
2212
|
+
this.condition = clause?.condition;
|
2213
|
+
}
|
2214
|
+
/**
|
2215
|
+
* @inheritDoc
|
2216
|
+
*/
|
2217
|
+
orderBy(...selector) {
|
2218
|
+
return this.Clauses.orderBy(this.statement, selector);
|
2219
|
+
}
|
2220
|
+
/**
|
2221
|
+
* @inheritDoc
|
2222
|
+
*/
|
2223
|
+
groupBy(selector) {
|
2224
|
+
return this.Clauses.groupBy(this.statement, selector);
|
2225
|
+
}
|
2226
|
+
/**
|
2227
|
+
* @inheritDoc
|
2228
|
+
*/
|
2229
|
+
limit(selector) {
|
2230
|
+
return this.Clauses.limit(this.statement, selector);
|
2231
|
+
}
|
2232
|
+
/**
|
2233
|
+
* @inheritDoc
|
2234
|
+
*/
|
2235
|
+
offset(selector) {
|
2236
|
+
return this.Clauses.offset(this.statement, selector);
|
2237
|
+
}
|
2238
|
+
/**
|
2239
|
+
* @inheritDoc
|
2240
|
+
*/
|
2241
|
+
hasErrors(...exceptions) {
|
2242
|
+
const errors = super.hasErrors(...exceptions);
|
2243
|
+
if (errors)
|
2244
|
+
return errors;
|
2245
|
+
return this.condition.hasErrors();
|
2246
|
+
}
|
2247
|
+
}
|
2248
|
+
__decorate([
|
2249
|
+
required(),
|
2250
|
+
type("Condition"),
|
2251
|
+
__metadata("design:type", Condition)
|
2252
|
+
], WhereClause.prototype, "condition", void 0);
|
2253
|
+
|
2254
|
+
class ClauseFactory {
|
2255
|
+
constructor(adapter) {
|
2256
|
+
this.adapter = adapter;
|
2257
|
+
}
|
2258
|
+
}
|
2259
|
+
|
2260
|
+
class Paginator {
|
2261
|
+
get current() {
|
2262
|
+
return this._currentPage;
|
2263
|
+
}
|
2264
|
+
get total() {
|
2265
|
+
return this._totalPages;
|
2266
|
+
}
|
2267
|
+
get count() {
|
2268
|
+
return this._recordCount;
|
2269
|
+
}
|
2270
|
+
get statement() {
|
2271
|
+
if (!this._statement)
|
2272
|
+
this._statement = this.prepare(this._rawStatement);
|
2273
|
+
return this._statement;
|
2274
|
+
}
|
2275
|
+
get adapter() {
|
2276
|
+
return this.stat.getAdapter();
|
2277
|
+
}
|
2278
|
+
constructor(stat, size, _rawStatement) {
|
2279
|
+
this.stat = stat;
|
2280
|
+
this.size = size;
|
2281
|
+
this._rawStatement = _rawStatement;
|
2282
|
+
}
|
2283
|
+
async next() {
|
2284
|
+
return this.page(this.current + 1);
|
2285
|
+
}
|
2286
|
+
async previous() {
|
2287
|
+
return this.page(this.current - 1);
|
2288
|
+
}
|
2289
|
+
validatePage(page) {
|
2290
|
+
if (page < 1 || !Number.isInteger(page))
|
2291
|
+
throw new PagingError("page number cannot be under 1 and must be an integer");
|
2292
|
+
if (page > this._totalPages)
|
2293
|
+
throw new PagingError("page number cannot be under 1 and must be an integer");
|
2294
|
+
}
|
2295
|
+
}
|
2296
|
+
|
2297
|
+
Injectables.setRegistry(new InjectablesRegistry());
|
2298
|
+
/**
|
2299
|
+
* @summary stores the current package version
|
2300
|
+
* @description this is how you should document a constant
|
2301
|
+
* @const VERSION
|
2302
|
+
* @memberOf module:ts-workspace
|
2303
|
+
*/
|
2304
|
+
const VERSION = "0.4.0";
|
2305
|
+
|
2306
|
+
export { Adapter, BaseModel, BigIntSequence, Cascade, Clause, ClauseFactory, ClauseSequenceValidator, Condition, ConnectionError, Const, Context, DefaultCascade, DefaultSequenceOptions, FromClause, GroupByClause, GroupOperator, InjectablesRegistry, InsertClause, LimitClause, MandatoryPriorities, NumericSequence, ObserverError, OffsetClause, Operator, OrderByClause, OrderDirection, Paginator, PagingError, PersistenceKeys, Priority, Query, QueryError, Repository, Roles, SelectClause, SelectorBasedClause, Sequence, Statement, StatementType, UnsupportedError, User, VERSION, ValuesClause, WhereClause, clauseSequence, column, createdBy, createdByOnCreateUpdate, generateInjectableNameForRepository, getTableName, index, manyToOne, oneToMany, oneToOne, pk, pkOnCreate, repository, sequenceNameForModel, table, unique, uniqueOnCreateUpdate, updatedBy, uses };
|
2307
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5lc20uY2pzIiwic291cmNlcyI6WyIuLi9zcmMvcmVwb3NpdG9yeS9jb25zdGFudHMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9Db250ZXh0LnRzIiwiLi4vc3JjL3BlcnNpc3RlbmNlL2NvbnN0YW50cy50cyIsIi4uL3NyYy9xdWVyeS9jb25zdGFudHMudHMiLCIuLi9zcmMvcXVlcnkvUXVlcnkudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvZXJyb3JzLnRzIiwiLi4vc3JjL3BlcnNpc3RlbmNlL0FkYXB0ZXIudHMiLCIuLi9zcmMvaWRlbnRpdHkvdXRpbHMudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvU2VxdWVuY2UudHMiLCIuLi9zcmMvcGVyc2lzdGVuY2UvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L1JlcG9zaXRvcnkudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvZXJyb3JzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvdXRpbHMudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9pbmplY3RhYmxlcy50cyIsIi4uL3NyYy9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9ucy50cyIsIi4uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanMiLCIuLi9zcmMvcXVlcnkvZXJyb3JzLnRzIiwiLi4vc3JjL3F1ZXJ5L0NvbmRpdGlvbi50cyIsIi4uL3NyYy9tb2RlbC9jb25zdHJ1Y3Rpb24udHMiLCIuLi9zcmMvbW9kZWwvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9pZGVudGl0eS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL0Jhc2VNb2RlbC50cyIsIi4uL3NyYy9tb2RlbC9Vc2VyLnRzIiwiLi4vc3JjL3ZhbGlkYXRvcnMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy92YWxpZGF0b3JzL0NsYXVzZVNlcXVlbmNlVmFsaWRhdG9yLnRzIiwiLi4vc3JjL3F1ZXJ5L1N0YXRlbWVudC50cyIsIi4uL3NyYy9xdWVyeS9DbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9TZWxlY3RvckJhc2VkQ2xhdXNlLnRzIiwiLi4vc3JjL3F1ZXJ5L2NsYXVzZXMvRnJvbUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL0dyb3VwQnlDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9JbnNlcnRDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9MaW1pdENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL09mZnNldENsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9jbGF1c2VzL09yZGVyQnlDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9TZWxlY3RDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9WYWx1ZXNDbGF1c2UudHMiLCIuLi9zcmMvcXVlcnkvY2xhdXNlcy9XaGVyZUNsYXVzZS50cyIsIi4uL3NyYy9xdWVyeS9DbGF1c2VGYWN0b3J5LnRzIiwiLi4vc3JjL3F1ZXJ5L1BhZ2luYXRvci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDYXNjYWRlTWV0YWRhdGEgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IGRlZmluZXMgb3JkZXIgZGlyZWN0aW9ucyB3aGVuIHNvcnRpbmdcbiAqXG4gKiBAY29uc3RhbnQgT3JkZXJEaXJlY3Rpb25cbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqL1xuZXhwb3J0IGVudW0gT3JkZXJEaXJlY3Rpb24ge1xuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgc29ydCBvcmRlciBhcyBhc2NlbmRpbmdcbiAgICogQHByb3AgQVNDXG4gICAqL1xuICBBU0MgPSBcImFzY1wiLFxuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgc29ydCBvcmRlciBhcyBkZXNjZW5kaW5nXG4gICAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEU0NcbiAgICovXG4gIERTQyA9IFwiZGVzY1wiLFxufVxuXG5leHBvcnQgZW51bSBDYXNjYWRlIHtcbiAgQ0FTQ0FERSA9IFwiY2FzY2FkZVwiLFxuICBOT05FID0gXCJub25lXCIsXG59XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0Q2FzY2FkZTogQ2FzY2FkZU1ldGFkYXRhID0ge1xuICB1cGRhdGU6IENhc2NhZGUuQ0FTQ0FERSxcbiAgZGVsZXRlOiBDYXNjYWRlLk5PTkUsXG59O1xuIiwiaW1wb3J0IHsgQ29udGV4dCBhcyBDdHggfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFVzZXIgfSBmcm9tIFwiLi4vbW9kZWxcIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvbnRleHQ8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgVSBleHRlbmRzIFVzZXIgPSBVc2VyLFxuPiBleHRlbmRzIEN0eDxNPiB7XG4gIHByb3RlY3RlZCBfdGltZXN0YW1wITogRGF0ZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzLFxuICAgIG1vZGVsPzogQ29uc3RydWN0b3I8TT4sXG4gICAgcGFyZW50PzogQ29udGV4dDxhbnksIGFueT5cbiAgKSB7XG4gICAgc3VwZXIob3BlcmF0aW9uLCBtb2RlbCwgcGFyZW50KTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldCB0aW1lc3RhbXAoKSB7XG4gICAgaWYgKCF0aGlzLl90aW1lc3RhbXApIHRoaXMuX3RpbWVzdGFtcCA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIHRoaXMuX3RpbWVzdGFtcDtcbiAgfVxuXG4gIGFic3RyYWN0IGdldCB1c2VyKCk6IFUgfCB1bmRlZmluZWQ7XG59XG4iLCJleHBvcnQgZW51bSBQZXJzaXN0ZW5jZUtleXMge1xuICBJTkRFWCA9IFwiaW5kZXhcIixcbiAgVU5JUVVFID0gXCJ1bmlxdWVcIixcbiAgQURBUFRFUiA9IFwiYWRhcHRlclwiLFxuICBJTkpFQ1RBQkxFID0gXCJkZWNhZl97MH1fYWRhcHRlcl9mb3JfezF9XCIsXG4gIFRBQkxFID0gXCJ0YWJsZVwiLFxuICBDT0xVTU4gPSBcImNvbHVtblwiLFxuICBNRVRBREFUQSA9IFwiX19tZXRhZGF0YVwiLFxuICBSRUxBVElPTlMgPSBcIl9fcmVsYXRpb25zXCIsXG4gIENMQVVTRV9TRVFVRU5DRSA9IFwiY2xhdXNlLXNlcXVlbmNlXCIsXG4gIC8vIE93bmVyc2hpcFxuICBDUkVBVEVEX0JZID0gXCJvd25lcnNoaXAuY3JlYXRlZC1ieVwiLFxuICBVUERBVEVEX0JZID0gXCJvd25lcnNoaXAudXBkYXRlZC1ieVwiLFxuICAvLyBSZWxhdGlvbnNcbiAgT05FX1RPX09ORSA9IFwicmVsYXRpb25zLm9uZS10by1vbmVcIixcbiAgT05FX1RPX01BTlkgPSBcInJlbGF0aW9ucy5vbmUtdG8tbWFueVwiLFxuICBNQU5ZX1RPX09ORSA9IFwicmVsYXRpb25zLm1hbnktdG8tb25lXCIsXG4gIFBPUFVMQVRFID0gXCJwb3B1bGF0ZVwiLFxufVxuXG5leHBvcnQgZW51bSBSb2xlcyB7XG4gIEFETUlOID0gXCJhZG1pblwiLFxuICBXUklURVIgPSBcIndyaXRlclwiLFxuICBSRUFERVIgPSBcInJlYWRlclwiLFxufVxuIiwiZXhwb3J0IGVudW0gT3BlcmF0b3Ige1xuICBFUVVBTCA9IFwiRVFVQUxcIixcbiAgRElGRkVSRU5UID0gXCJESUZGRVJFTlRcIixcbiAgQklHR0VSID0gXCJCSUdHRVJcIixcbiAgQklHR0VSX0VRID0gXCJCSUdHRVJfRVFcIixcbiAgU01BTExFUiA9IFwiU01BTExFUlwiLFxuICBTTUFMTEVSX0VRID0gXCJTTUFMTEVSX0VRXCIsXG4gIC8vIEJFVFdFRU4gPSBcIkJFVFdFRU5cIixcbiAgTk9UID0gXCJOT1RcIixcbiAgSU4gPSBcIklOXCIsXG4gIC8vIElTID0gXCJJU1wiLFxuICBSRUdFWFAgPSBcIlJFR0VYUFwiLFxufVxuXG5leHBvcnQgZW51bSBHcm91cE9wZXJhdG9yIHtcbiAgQU5EID0gXCJBTkRcIixcbiAgT1IgPSBcIk9SXCIsXG59XG5cbmV4cG9ydCBlbnVtIENvbnN0IHtcbiAgTlVMTCA9IFwiTlVMTFwiLFxuICBGVUxMX1JFQ09SRCA9IFwiKlwiLFxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgZXhlY3V0aW9uIG9yZGVyIG9mIENsYXVzZXMgaW4gc3RhdGVtZW50cyBhcyBkZWZpbmVkIGluIFNRTC5cbiAqXG4gKiBAZGVzY3JpcHRpb24gc3ViIHByaW9yaXRpZXMgd2hlcmUgZGVmaW5lZCB0byBiZXR0ZXIgb3JnYW5pemUgY2xhdXNlcyB3aXRoaW4gc3RhdGVtZW50cywgZWcgRnJvbSBhbmQgSm9pbiBDbGF1c2VzXG4gKlxuICogQGNvbnN0IFByaW9yaXR5XG4gKlxuICogQGNhdGVnb3J5IENsYXVzZXNcbiAqIEBzdWJjYXRlZ29yeSBDb25zdGFudHNcbiAqL1xuZXhwb3J0IGVudW0gUHJpb3JpdHkge1xuICAvKipcbiAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgcHJpb3JpdHkgZm9yIHRoZSBGUk9NIENsYXVzZVxuICAgKiBAZGVzY3JpcHRpb24gRnJvbSBDbGF1c2UgaW4gU0VMRUNUIFN0YXRlbWVudHMuXG4gICAqIFZhbHVlcyBDbGF1c2UgaW4gSU5TRVJUIFN0YXRlbWVudHNcbiAgICpcbiAgICogQHByb3AgRlJPTVxuICAgKi9cbiAgRlJPTSA9IDEsXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBEZWZpbmVzIHRoZSBwcmlvcml0eSBmb3IgdGhlIEpPSU4gQ2xhdXNlXG4gICAqXG4gICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBKT0lOXG4gICAqL1xuICBKT0lOID0gMS4xLFxuICAvKipcbiAgICogV2hlcmUgQ2xhdXNlXG4gICAqL1xuICBXSEVSRSA9IDIsXG4gIC8qKlxuICAgKiBHcm91cCBCeSBDbGF1c2VcbiAgICovXG4gIEdST1VQX0JZID0gMyxcbiAgLyoqXG4gICAqIEhhdmluZyBDbGF1c2VcbiAgICovXG4gIEhBVklORyA9IDQsXG4gIC8qKlxuICAgKiBTZWxlY3QgQ2xhdXNlIGluIFNFTEVDVCBTdGF0ZW1lbnRzXG4gICAqIEluc2VydCBDbGF1c2UgaW4gSU5TRVJUIFN0YXRlbWVudHNcbiAgICovXG4gIFNFTEVDVCA9IDUsXG4gIC8qKlxuICAgKiBPcmRlciBCeSBDbGF1c2VcbiAgICovXG4gIE9SREVSX0JZID0gNixcbiAgLyoqXG4gICAqIExpbWl0IENsYXVzZVxuICAgKi9cbiAgTElNSVQgPSA3LFxuICAvKipcbiAgICogT2Zmc2V0IENsYXVzZVxuICAgKi9cbiAgT0ZGU0VUID0gNy4xLFxufVxuXG5leHBvcnQgY29uc3QgTWFuZGF0b3J5UHJpb3JpdGllcyA9IFtQcmlvcml0eS5GUk9NLCBQcmlvcml0eS5TRUxFQ1RdO1xuXG5leHBvcnQgZW51bSBTdGF0ZW1lbnRUeXBlIHtcbiAgUVVFUlkgPSBcInF1ZXJ5XCIsXG4gIFRSQU5TQUNUSU9OID0gXCJ0cmFuc2FjdGlvblwiLFxufVxuIiwiaW1wb3J0IHtcbiAgQ291bnRPcHRpb24sXG4gIERpc3RpbmN0T3B0aW9uLFxuICBJbnNlcnRPcHRpb24sXG4gIE1heE9wdGlvbixcbiAgTWluT3B0aW9uLFxuICBTZWxlY3RPcHRpb24sXG59IGZyb20gXCIuL29wdGlvbnNcIjtcbmltcG9ydCB7IFNlbGVjdFNlbGVjdG9yIH0gZnJvbSBcIi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5pbXBvcnQgeyBDb25zdCB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSGVscGVyIENsYXNzIHRvIGJ1aWxkIHF1ZXJpZXNcbiAqXG4gKiBAcGFyYW0ge0RhdGFiYXNlfSBkYlxuICpcbiAqIEBjbGFzcyBRdWVyeVxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICovXG5leHBvcnQgY2xhc3MgUXVlcnk8USwgTSBleHRlbmRzIE1vZGVsPiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYWRhcHRlcjogQWRhcHRlcjxhbnksIFE+KSB7fVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgU2VsZWN0IENsYXVzZVxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBbc2VsZWN0b3JdXG4gICAqL1xuICBzZWxlY3Qoc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yID0gQ29uc3QuRlVMTF9SRUNPUkQpOiBTZWxlY3RPcHRpb248TT4ge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuQ2xhdXNlcy5zZWxlY3Q8TT4oc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgTWluIENsYXVzZVxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgbWluKHNlbGVjdG9yOiBTZWxlY3RTZWxlY3Rvcik6IE1pbk9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KCkubWluKHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIE1heCBDbGF1c2VcbiAgICogQHBhcmFtIHtTZWxlY3RTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIG1heChzZWxlY3RvcjogU2VsZWN0U2VsZWN0b3IpOiBNYXhPcHRpb248TT4ge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdCgpLm1heChzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBEaXN0aW5jdCBDbGF1c2VcbiAgICogQHBhcmFtIHtTZWxlY3RTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGRpc3RpbmN0KHNlbGVjdG9yOiBTZWxlY3RTZWxlY3Rvcik6IERpc3RpbmN0T3B0aW9uPE0+IHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QoKS5kaXN0aW5jdChzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBDb3VudCBDbGF1c2VcbiAgICogQHBhcmFtIHtTZWxlY3RTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGNvdW50KHNlbGVjdG9yPzogU2VsZWN0U2VsZWN0b3IpOiBDb3VudE9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KCkuY291bnQoc2VsZWN0b3IpO1xuICB9XG5cbiAgaW5zZXJ0KCk6IEluc2VydE9wdGlvbjxNPiB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5DbGF1c2VzLmluc2VydDxNPigpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihDb25uZWN0aW9uRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVW5zdXBwb3J0ZWRFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihVbnN1cHBvcnRlZEVycm9yLm5hbWUsIG1zZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEJhc2VFcnJvcixcbiAgREJLZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBOb3RGb3VuZEVycm9yLFxuICBDb250ZXh0LFxuICBPcGVyYXRpb25LZXlzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvT2JzZXJ2ZXJcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxDb25zdHJ1Y3RvcixcbiAgTW9kZWxSZWdpc3RyeSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvU2VxdWVuY2VPcHRpb25zXCI7XG5pbXBvcnQgeyBSYXdFeGVjdXRvciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL1Jhd0V4ZWN1dG9yXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBRdWVyeSB9IGZyb20gXCIuLi9xdWVyeS9RdWVyeVwiO1xuaW1wb3J0IHsgU3RhdGVtZW50IH0gZnJvbSBcIi4uL3F1ZXJ5L1N0YXRlbWVudFwiO1xuaW1wb3J0IHsgQ2xhdXNlRmFjdG9yeSB9IGZyb20gXCIuLi9xdWVyeS9DbGF1c2VGYWN0b3J5XCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcXVlcnkvQ29uZGl0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgU2VxdWVuY2UgfSBmcm9tIFwiLi9TZXF1ZW5jZVwiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCIuLi9tb2RlbC9Vc2VyXCI7XG5pbXBvcnQgeyBDb250ZXh0IGFzIEN0eCB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L0NvbnRleHRcIjtcbmltcG9ydCB7IFVuc3VwcG9ydGVkRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBBYnN0cmFjdCBEZWNhZi10cyBQZXJzaXN0ZW5jZSBBZGFwdGVyIENsYXNzXG4gKiBAZGVzY3JpcHRpb24gT2ZmZXJzIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uIGZvciBhbGwgQWRhcHRlciBDbGFzc2VzXG4gKiBhbmQgbWFuYWdlcyB0aGVtIHZhcmlvdXMgcmVnaXN0ZXJlZCB7QGxpbmsgQWRhcHRlcn1zXG4gKlxuICogQHR5cGVkZWYgWSB0aGUgdW5kZXJseWluZyBwZXJzaXN0ZW5jZSBvYmplY3QgdHlwZVxuICogQHR5cGVkZWYgUSBUaGUgcXVlcnkgb2JqZWN0IHRoZSBhZGFwdGVyIHVzZXNcbiAqXG4gKiBAcGFyYW0ge1l9IG5hdGl2ZSB0aGUgdW5kZXJseWluZyBwZXJzaXN0ZW5jZSBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIHRoZSB1bmRlciB3aXRjaCB0aGUgcGVyc2lzdGVuY2UgYWRhcHRlciBzaG91bGQgYmUgc3RvcmVkXG4gKlxuICogQGNsYXNzIEFkYXB0ZXJcbiAqIEBpbXBsZW1lbnRzIFJhd0V4ZWN1dG9yXG4gKiBAaW1wbGVtZW50cyBPYnNlcnZhYmxlXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBZGFwdGVyPFksIFE+IGltcGxlbWVudHMgUmF3RXhlY3V0b3I8UT4sIE9ic2VydmFibGUge1xuICBwcml2YXRlIHN0YXRpYyBfY3VycmVudDogQWRhcHRlcjxhbnksIGFueT47XG4gIHByaXZhdGUgc3RhdGljIF9jYWNoZTogUmVjb3JkPHN0cmluZywgQWRhcHRlcjxhbnksIGFueT4+ID0ge307XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9vYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbmF0aXZlOiBZO1xuXG4gIGdldCBuYXRpdmUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX25hdGl2ZTtcbiAgfVxuXG4gIHJlcG9zaXRvcnk8TSBleHRlbmRzIE1vZGVsPigpOiBDb25zdHJ1Y3RvcjxSZXBvc2l0b3J5PE0sIFEsIEFkYXB0ZXI8WSwgUT4+PiB7XG4gICAgcmV0dXJuIFJlcG9zaXRvcnk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgbmF0aXZlOiBZLFxuICAgIHJlYWRvbmx5IGZsYXZvdXI6IHN0cmluZ1xuICApIHtcbiAgICBpZiAodGhpcy5mbGF2b3VyIGluIEFkYXB0ZXIuX2NhY2hlKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBQZXJzaXN0ZW5jZSBhZGFwdGVyIGZsYXZvdXIgJHt0aGlzLmZsYXZvdXJ9IGFscmVhZHkgcmVnaXN0ZXJlZGBcbiAgICAgICk7XG4gICAgdGhpcy5fbmF0aXZlID0gbmF0aXZlO1xuICAgIEFkYXB0ZXIuX2NhY2hlW3RoaXMuZmxhdm91cl0gPSB0aGlzO1xuICB9XG5cbiAgUXVlcnk8TSBleHRlbmRzIE1vZGVsPigpOiBRdWVyeTxRLCBNPiB7XG4gICAgcmV0dXJuIG5ldyBRdWVyeSh0aGlzKTtcbiAgfVxuXG4gIGFic3RyYWN0IHBhcnNlQ29uZGl0aW9uKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogUTtcblxuICBhYnN0cmFjdCBnZXQgU3RhdGVtZW50KCk6IFN0YXRlbWVudDxRPjtcblxuICBhYnN0cmFjdCBnZXQgQ2xhdXNlcygpOiBDbGF1c2VGYWN0b3J5PFksIFE+O1xuXG4gIHByb3RlY3RlZCBpc1Jlc2VydmVkKGF0dHI6IHN0cmluZykge1xuICAgIHJldHVybiAhYXR0cjtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUVycm9yKGVycjogRXJyb3IpOiBCYXNlRXJyb3I7XG5cbiAgYWJzdHJhY3QgaW5pdGlhbGl6ZSguLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD47XG5cbiAgYWJzdHJhY3QgU2VxdWVuY2Uob3B0aW9uczogU2VxdWVuY2VPcHRpb25zKTogUHJvbWlzZTxTZXF1ZW5jZT47XG5cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHVzZXIoKTogUHJvbWlzZTxVc2VyIHwgdW5kZWZpbmVkPjtcblxuICBhc3luYyBjb250ZXh0PE0gZXh0ZW5kcyBNb2RlbCwgQyBleHRlbmRzIENvbnRleHQ8TT4+KFxuICAgIG9wZXJhdGlvbjpcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5DUkVBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gICAgICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPlxuICApOiBQcm9taXNlPEM+IHtcbiAgICBsZXQgdXNlcjogVXNlciB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgdXNlciA9IGF3YWl0IHRoaXMudXNlcigpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIFVuc3VwcG9ydGVkRXJyb3IpKSB0aHJvdyBlO1xuICAgIH1cblxuICAgIGNvbnN0IGM6IEMgPSBuZXcgKGNsYXNzIGV4dGVuZHMgQ3R4PE0+IHtcbiAgICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgICAgIG1vZGVsPzogQ29uc3RydWN0b3I8TT4sXG4gICAgICAgIHBhcmVudD86IEN0eDxhbnksIGFueT5cbiAgICAgICkge1xuICAgICAgICBzdXBlcihvcGVyYXRpb24sIG1vZGVsLCBwYXJlbnQpO1xuICAgICAgfVxuXG4gICAgICBnZXQgdXNlcigpOiBVc2VyIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKCF1c2VyKVxuICAgICAgICAgIHRocm93IG5ldyBVbnN1cHBvcnRlZEVycm9yKFxuICAgICAgICAgICAgXCJBZGFwdGVyIGRvZXMgbm90IHN1cHBvcnQgdXNlciBpZGVudGlmaWNhdGlvblwiXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHVzZXI7XG4gICAgICB9XG4gICAgfSkob3BlcmF0aW9uLCBtb2RlbCkgYXMgdW5rbm93biBhcyBDO1xuXG4gICAgcmV0dXJuIGM7XG4gIH1cblxuICBwcmVwYXJlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IE0sXG4gICAgcGs6IHN0cmluZyB8IG51bWJlclxuICApOiB7XG4gICAgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIGlkOiBzdHJpbmc7XG4gIH0ge1xuICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5lbnRyaWVzKG1vZGVsKS5yZWR1Y2UoXG4gICAgICAoYWNjdW06IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgLy8gaWYgKGtleSA9PT0gcGspIHJldHVybiBhY2N1bTtcbiAgICAgICAgY29uc3QgbWFwcGVkUHJvcCA9IFJlcG9zaXRvcnkuY29sdW1uKG1vZGVsLCBrZXkpO1xuICAgICAgICBpZiAodGhpcy5pc1Jlc2VydmVkKG1hcHBlZFByb3ApKVxuICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBQcm9wZXJ0eSBuYW1lICR7bWFwcGVkUHJvcH0gaXMgcmVzZXJ2ZWRgKTtcbiAgICAgICAgYWNjdW1bbWFwcGVkUHJvcF0gPSB2YWw7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sXG4gICAgICB7fVxuICAgICk7XG4gICAgaWYgKChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV0pXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogKG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXSxcbiAgICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICByZWNvcmQ6IHJlc3VsdCxcbiAgICAgIGlkOiAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcGtdLFxuICAgIH07XG4gIH1cblxuICByZXZlcnQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgY2xheno6IHN0cmluZyB8IENvbnN0cnVjdG9yPE0+LFxuICAgIHBrOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludFxuICApOiBNIHtcbiAgICBjb25zdCBvYjogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIG9iW3BrXSA9IGlkO1xuICAgIGNvbnN0IG0gPSAoXG4gICAgICB0eXBlb2YgY2xhenogPT09IFwic3RyaW5nXCIgPyBNb2RlbC5idWlsZChvYiwgY2xhenopIDogbmV3IGNsYXp6KG9iKVxuICAgICkgYXMgTTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IG9ialtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdO1xuICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5rZXlzKG0pLnJlZHVjZSgoYWNjdW06IE0sIGtleSkgPT4ge1xuICAgICAgaWYgKGtleSA9PT0gcGspIHJldHVybiBhY2N1bTtcbiAgICAgIChhY2N1bSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldID0gb2JqW1JlcG9zaXRvcnkuY29sdW1uKGFjY3VtLCBrZXkpXTtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBtKTtcbiAgICBpZiAobWV0YWRhdGEpXG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocmVzdWx0LCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgdmFsdWU6IG1ldGFkYXRhLFxuICAgICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGFic3RyYWN0IGNyZWF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYXN5bmMgY3JlYXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiAoc3RyaW5nIHwgbnVtYmVyKVtdLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoaWQubGVuZ3RoICE9PSBtb2RlbC5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgaWQubWFwKChpLCBjb3VudCkgPT4gdGhpcy5jcmVhdGUodGFibGVOYW1lLCBpLCBtb2RlbFtjb3VudF0sIC4uLmFyZ3MpKVxuICAgICk7XG4gIH1cblxuICBhYnN0cmFjdCByZWFkKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PjtcblxuICBhc3luYyByZWFkQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiAoc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50KVtdLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGlkLm1hcCgoaSkgPT4gdGhpcy5yZWFkKHRhYmxlTmFtZSwgaSwgLi4uYXJncykpKTtcbiAgfVxuXG4gIGFic3RyYWN0IHVwZGF0ZShcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj47XG5cbiAgYXN5bmMgdXBkYXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoaWQubGVuZ3RoICE9PSBtb2RlbC5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgaWQubWFwKChpLCBjb3VudCkgPT4gdGhpcy51cGRhdGUodGFibGVOYW1lLCBpLCBtb2RlbFtjb3VudF0sIC4uLmFyZ3MpKVxuICAgICk7XG4gIH1cblxuICBhYnN0cmFjdCBkZWxldGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG4gIGFzeW5jIGRlbGV0ZUFsbChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIHJldHVybiBQcm9taXNlLmFsbChpZC5tYXAoKGkpID0+IHRoaXMuZGVsZXRlKHRhYmxlTmFtZSwgaSwgLi4uYXJncykpKTtcbiAgfVxuXG4gIGFic3RyYWN0IHJhdzxSPihyYXdJbnB1dDogUSwgcHJvY2VzczogYm9vbGVhbiwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFI+O1xuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgYW4ge0BsaW5rIE9ic2VydmVyfVxuICAgKiBAcGFyYW0ge09ic2VydmVyfSBvYnNlcnZlclxuICAgKlxuICAgKiBAc2VlIHtPYnNlcnZhYmxlI29ic2VydmV9XG4gICAqL1xuICBvYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fb2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiT2JzZXJ2ZXIgYWxyZWFkeSByZWdpc3RlcmVkXCIpO1xuICAgIHRoaXMuX29ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBVbnJlZ2lzdGVycyBhbiB7QGxpbmsgT2JzZXJ2ZXJ9XG4gICAqIEBwYXJhbSB7T2JzZXJ2ZXJ9IG9ic2VydmVyXG4gICAqXG4gICAqIEBzZWUge09ic2VydmFibGUjdW5PYnNlcnZlfVxuICAgKi9cbiAgdW5PYnNlcnZlKG9ic2VydmVyOiBPYnNlcnZlcik6IHZvaWQge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fb2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiRmFpbGVkIHRvIGZpbmQgT2JzZXJ2ZXJcIik7XG4gICAgdGhpcy5fb2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgY2FsbHMgYWxsIHJlZ2lzdGVyZWQge0BsaW5rIE9ic2VydmVyfXMgdG8gdXBkYXRlIHRoZW1zZWx2ZXNcbiAgICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gdGhlIHtAbGluayBPYnNlcnZlciNyZWZyZXNofSBtZXRob2RcbiAgICovXG4gIGFzeW5jIHVwZGF0ZU9ic2VydmVycyguLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICB0aGlzLl9vYnNlcnZlcnMubWFwKChvKSA9PiBvLnJlZnJlc2goLi4uYXJncykpXG4gICAgKTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCwgaSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIilcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBGYWlsZWQgdG8gdXBkYXRlIG9ic2VydmFibGUgJHt0aGlzLl9vYnNlcnZlcnNbaV19OiAke3Jlc3VsdC5yZWFzb259YFxuICAgICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBjdXJyZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50O1xuICB9XG5cbiAgc3RhdGljIGdldDxZLCBRPihmbGF2b3VyOiBhbnkpOiBBZGFwdGVyPFksIFE+IHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoZmxhdm91ciBpbiB0aGlzLl9jYWNoZSkgcmV0dXJuIHRoaXMuX2NhY2hlW2ZsYXZvdXJdO1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyBBZGFwdGVyIHJlZ2lzdGVyZWQgdW5kZXIgJHtmbGF2b3VyfS5gKTtcbiAgfVxuXG4gIHN0YXRpYyBzZXRDdXJyZW50KGZsYXZvdXI6IHN0cmluZykge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBBZGFwdGVyLmdldChmbGF2b3VyKTtcbiAgICBpZiAoIWFkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgTm8gcGVyc2lzdGVuY2UgZmxhdm91ciAke2ZsYXZvdXJ9IHJlZ2lzdGVyZWRgKTtcbiAgICB0aGlzLl9jdXJyZW50ID0gYWRhcHRlcjtcbiAgfVxuXG4gIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gUmVwb3NpdG9yeS5rZXkoa2V5KTtcbiAgfVxuXG4gIHN0YXRpYyBtb2RlbHM8TSBleHRlbmRzIE1vZGVsPihmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVnaXN0cnkgPSAoTW9kZWwgYXMgYW55KS5nZXRSZWdpc3RyeSgpIGFzIE1vZGVsUmVnaXN0cnk8YW55PjtcbiAgICAgIGNvbnN0IGNhY2hlID0gKFxuICAgICAgICByZWdpc3RyeSBhcyB1bmtub3duIGFzIHsgY2FjaGU6IFJlY29yZDxzdHJpbmcsIE1vZGVsQ29uc3RydWN0b3I8YW55Pj4gfVxuICAgICAgKS5jYWNoZTtcbiAgICAgIGNvbnN0IG1hbmFnZWRNb2RlbHM6IE1vZGVsQ29uc3RydWN0b3I8YW55PltdID0gT2JqZWN0LnZhbHVlcyhjYWNoZSlcbiAgICAgICAgLm1hcCgobTogTW9kZWxDb25zdHJ1Y3RvcjxNPikgPT4ge1xuICAgICAgICAgIGxldCBmID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZiAmJiBmID09PSBmbGF2b3VyKSByZXR1cm4gbTtcbiAgICAgICAgICBpZiAoIWYpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlcG8gPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuUkVQT1NJVE9SWSksXG4gICAgICAgICAgICAgIG0gYXMgTW9kZWxDb25zdHJ1Y3Rvcjxhbnk+XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKCFyZXBvKSByZXR1cm47XG4gICAgICAgICAgICBjb25zdCByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChtKTtcblxuICAgICAgICAgICAgZiA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgcmVwb3NpdG9yeVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiBmO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmZpbHRlcigobSkgPT4gISFtKTtcbiAgICAgIHJldHVybiBtYW5hZ2VkTW9kZWxzO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRhYmxlTmFtZTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5UQUJMRSksXG4gICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yIDogbW9kZWxcbiAgKTtcbiAgaWYgKG1ldGFkYXRhKSB7XG4gICAgcmV0dXJuIG1ldGFkYXRhO1xuICB9XG4gIGlmIChtb2RlbCBpbnN0YW5jZW9mIE1vZGVsKSB7XG4gICAgcmV0dXJuIG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gIH1cbiAgcmV0dXJuIG1vZGVsLm5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXF1ZW5jZU5hbWVGb3JNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+LFxuICAuLi5hcmdzOiBzdHJpbmdbXVxuKSB7XG4gIHJldHVybiBbZ2V0VGFibGVOYW1lKG1vZGVsKSwgLi4uYXJnc10uam9pbihcIl9cIik7XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IFNlcXVlbmNlXG4gKlxuICogQGludGVyZmFjZSBTZXF1ZW5jZVxuICpcbiAqIEBjYXRlZ29yeSBTZXF1ZW5jZXNcbiAqL1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgc2VxdWVuY2VOYW1lRm9yTW9kZWwgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IFNlcXVlbmNlT3B0aW9ucyB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU2VxdWVuY2Uge1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocHJvdGVjdGVkIHJlYWRvbmx5IG9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucykge31cblxuICAvKipcbiAgICogQHN1bW1hcnkgZ2VuZXJhdGVzIHRoZSBuZXh0IHZhbHVlIGluIHRoZSBzZXF1ZW5jZVxuICAgKlxuICAgKiBAbWV0aG9kXG4gICAqL1xuICBhYnN0cmFjdCBuZXh0KCk6IFByb21pc2U8c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50PjtcbiAgYWJzdHJhY3QgY3VycmVudCgpOiBQcm9taXNlPHN0cmluZyB8IG51bWJlciB8IGJpZ2ludD47XG4gIGFic3RyYWN0IHJhbmdlKGNvdW50OiBudW1iZXIpOiBQcm9taXNlPChudW1iZXIgfCBzdHJpbmcgfCBiaWdpbnQpW10+O1xuXG4gIHN0YXRpYyBwazxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgICByZXR1cm4gc2VxdWVuY2VOYW1lRm9yTW9kZWwobW9kZWwsIFwicGtcIik7XG4gIH1cbn1cbiIsImltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4vQWRhcHRlclwiO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlcyhmbGF2b3VyOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGFwcGx5KG1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgZmxhdm91cikpO1xufVxuIiwiaW1wb3J0IHtcbiAgREJLZXlzLFxuICBlbmZvcmNlREJEZWNvcmF0b3JzLFxuICBmaW5kUHJpbWFyeUtleSxcbiAgSW50ZXJuYWxFcnJvcixcbiAgSVJlcG9zaXRvcnksXG4gIE9wZXJhdGlvbktleXMsXG4gIFJlcG9zaXRvcnkgYXMgUmVwLFxuICBWYWxpZGF0aW9uRXJyb3IsXG4gIHdyYXBNZXRob2RXaXRoQ29udGV4dCxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvT2JzZXJ2YWJsZVwiO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9PYnNlcnZlclwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBRdWVyeSB9IGZyb20gXCIuLi9xdWVyeS9RdWVyeVwiO1xuaW1wb3J0IHsgT3JkZXJEaXJlY3Rpb24gfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFNlcXVlbmNlT3B0aW9ucyB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuaW1wb3J0IHsgUXVlcmlhYmxlIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvUXVlcmlhYmxlXCI7XG5pbXBvcnQgeyBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBJbmRleE1ldGFkYXRhIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFNlcXVlbmNlIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL1NlcXVlbmNlXCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcXVlcnkvQ29uZGl0aW9uXCI7XG5pbXBvcnQgeyBXaGVyZU9wdGlvbiB9IGZyb20gXCIuLi9xdWVyeS9vcHRpb25zXCI7XG5pbXBvcnQgeyBPcmRlckJ5U2VsZWN0b3IsIFNlbGVjdFNlbGVjdG9yIH0gZnJvbSBcIi4uL3F1ZXJ5L3NlbGVjdG9yc1wiO1xuaW1wb3J0IHsgZ2V0VGFibGVOYW1lIH0gZnJvbSBcIi4uL2lkZW50aXR5L3V0aWxzXCI7XG5pbXBvcnQgeyB1c2VzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5cbmV4cG9ydCB0eXBlIFJlcG88XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUSA9IGFueSxcbiAgQSBleHRlbmRzIEFkYXB0ZXI8YW55LCBRPiA9IEFkYXB0ZXI8YW55LCBRPixcbj4gPSBSZXBvc2l0b3J5PE0sIFEsIEE+O1xuXG5leHBvcnQgY2xhc3MgUmVwb3NpdG9yeTxNIGV4dGVuZHMgTW9kZWwsIFEsIEEgZXh0ZW5kcyBBZGFwdGVyPGFueSwgUT4+XG4gIGV4dGVuZHMgUmVwPE0+XG4gIGltcGxlbWVudHMgT2JzZXJ2YWJsZSwgUXVlcmlhYmxlLCBJUmVwb3NpdG9yeTxNPlxue1xuICBwcml2YXRlIHN0YXRpYyBfY2FjaGU6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgQ29uc3RydWN0b3I8UmVwbzxNb2RlbD4+IHwgUmVwbzxNb2RlbD5cbiAgPiA9IHt9O1xuXG4gIHByb3RlY3RlZCBvYnNlcnZlcnM6IE9ic2VydmVyW10gPSBbXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9hZGFwdGVyITogQTtcbiAgcHJpdmF0ZSBfdGFibGVOYW1lITogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCBnZXQgYWRhcHRlcigpOiBBIHtcbiAgICBpZiAoIXRoaXMuX2FkYXB0ZXIpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIGFkYXB0ZXIgZm91bmQgZm9yIHRoaXMgcmVwb3NpdG9yeS4gZGlkIHlvdSB1c2UgdGhlIEB1c2VzIGRlY29yYXRvciBvciBwYXNzIGl0IGluIHRoZSBjb25zdHJ1Y3Rvcj9gXG4gICAgICApO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGVyO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgaWYgKCF0aGlzLl90YWJsZU5hbWUpIHRoaXMuX3RhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUodGhpcy5jbGFzcyk7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmxlTmFtZTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI/OiBBLCBjbGF6ej86IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgc3VwZXIoY2xhenopO1xuICAgIGlmIChhZGFwdGVyKSB0aGlzLl9hZGFwdGVyID0gYWRhcHRlcjtcbiAgICBpZiAoY2xhenopIHtcbiAgICAgIFJlcG9zaXRvcnkucmVnaXN0ZXIoY2xhenosIHRoaXMpO1xuICAgICAgaWYgKGFkYXB0ZXIpIHtcbiAgICAgICAgY29uc3QgZmxhdm91ciA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgIGNsYXp6XG4gICAgICAgICk7XG4gICAgICAgIGlmIChmbGF2b3VyICYmIGZsYXZvdXIgIT09IGFkYXB0ZXIuZmxhdm91cilcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkluY29tcGF0aWJsZSBmbGF2b3Vyc1wiKTtcbiAgICAgICAgdXNlcyhhZGFwdGVyLmZsYXZvdXIpKGNsYXp6KTtcbiAgICAgIH1cbiAgICB9XG4gICAgW3RoaXMuY3JlYXRlQWxsLCB0aGlzLnJlYWRBbGwsIHRoaXMudXBkYXRlQWxsLCB0aGlzLmRlbGV0ZUFsbF0uZm9yRWFjaChcbiAgICAgIChtKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBtLm5hbWU7XG4gICAgICAgIHdyYXBNZXRob2RXaXRoQ29udGV4dChcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgICh0aGlzIGFzIGFueSlbbmFtZSArIFwiUHJlZml4XCJdLFxuICAgICAgICAgIG0sXG4gICAgICAgICAgKHRoaXMgYXMgYW55KVtuYW1lICsgXCJTdWZmaXhcIl1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZVByZWZpeChcbiAgICBtb2RlbDogTSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFtNLCAuLi5hbnlbXV0+IHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIG1vZGVsID0gbmV3IHRoaXMuY2xhc3MobW9kZWwpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycygpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLnRvU3RyaW5nKCkpO1xuXG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBhc3luYyBjcmVhdGUobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCB7IHJlY29yZCwgaWQgfSA9IHRoaXMuYWRhcHRlci5wcmVwYXJlKG1vZGVsLCB0aGlzLnBrKTtcbiAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuY3JlYXRlKHRoaXMudGFibGVOYW1lLCBpZCwgcmVjb3JkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydDxNPihyZWNvcmQsIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUFsbChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIGlmICghbW9kZWxzLmxlbmd0aCkgcmV0dXJuIG1vZGVscztcbiAgICBjb25zdCBwcmVwYXJlZCA9IG1vZGVscy5tYXAoKG0pID0+IHRoaXMuYWRhcHRlci5wcmVwYXJlKG0sIHRoaXMucGspKTtcbiAgICBjb25zdCBpZHMgPSBwcmVwYXJlZC5tYXAoKHApID0+IHAuaWQpO1xuICAgIGxldCByZWNvcmRzID0gcHJlcGFyZWQubWFwKChwKSA9PiBwLnJlY29yZCk7XG4gICAgcmVjb3JkcyA9IGF3YWl0IHRoaXMuYWRhcHRlci5jcmVhdGVBbGwoXG4gICAgICB0aGlzLnRhYmxlTmFtZSxcbiAgICAgIGlkcyBhcyAoc3RyaW5nIHwgbnVtYmVyKVtdLFxuICAgICAgcmVjb3JkcyxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIHJldHVybiByZWNvcmRzLm1hcCgociwgaSkgPT5cbiAgICAgIHRoaXMuYWRhcHRlci5yZXZlcnQociwgdGhpcy5jbGFzcywgdGhpcy5waywgaWRzW2ldIGFzIHN0cmluZyB8IG51bWJlcilcbiAgICApO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZUFsbFByZWZpeChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGlmICghbW9kZWxzLmxlbmd0aCkgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICAgIGNvbnN0IG9wdHMgPSBSZXBvc2l0b3J5LmdldFNlcXVlbmNlT3B0aW9ucyhtb2RlbHNbMF0pO1xuICAgIGxldCBpZHM6IChzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQgfCB1bmRlZmluZWQpW10gPSBbXTtcbiAgICBpZiAob3B0cy50eXBlKSB7XG4gICAgICBpZiAoIW9wdHMubmFtZSkgb3B0cy5uYW1lID0gU2VxdWVuY2UucGsobW9kZWxzWzBdKTtcbiAgICAgIGlkcyA9IGF3YWl0IChhd2FpdCB0aGlzLmFkYXB0ZXIuU2VxdWVuY2Uob3B0cykpLnJhbmdlKG1vZGVscy5sZW5ndGgpO1xuICAgIH1cblxuICAgIG1vZGVscyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcChhc3luYyAobSwgaSkgPT4ge1xuICAgICAgICBtID0gbmV3IHRoaXMuY2xhc3MobSk7XG4gICAgICAgIChtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3RoaXMucGtdID0gaWRzW2ldO1xuICAgICAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtKSA9PiBtLmhhc0Vycm9ycygpKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZSlcbiAgICAgICAgICBhY2N1bSA9XG4gICAgICAgICAgICB0eXBlb2YgYWNjdW0gPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgPyBhY2N1bSArIGBcXG4gLSAke2l9OiAke2UudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgIDogYCAtICR7aX06ICR7ZS50b1N0cmluZygpfWA7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMpO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZWFkUHJlZml4KGtleTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGNvbnN0IG1vZGVsOiBNID0gbmV3IHRoaXMuY2xhc3MoKTtcbiAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbdGhpcy5wa10gPSBrZXk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBhc3luYyByZWFkKGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPiB7XG4gICAgY29uc3QgbSA9IGF3YWl0IHRoaXMuYWRhcHRlci5yZWFkKHRoaXMudGFibGVOYW1lLCBpZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5yZXZlcnQ8TT4obSwgdGhpcy5jbGFzcywgdGhpcy5waywgaWQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRBbGxQcmVmaXgoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGtleXMubWFwKGFzeW5jIChrKSA9PiB7XG4gICAgICAgIGNvbnN0IG0gPSBuZXcgdGhpcy5jbGFzcygpO1xuICAgICAgICAobSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVt0aGlzLnBrXSA9IGs7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFtrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIHJlYWRBbGwoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHJlY29yZHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmVhZEFsbCh0aGlzLnRhYmxlTmFtZSwga2V5cywgLi4uYXJncyk7XG4gICAgcmV0dXJuIHJlY29yZHMubWFwKChyLCBpKSA9PlxuICAgICAgdGhpcy5hZGFwdGVyLnJldmVydChyLCB0aGlzLmNsYXNzLCB0aGlzLnBrLCBrZXlzW2ldKVxuICAgICk7XG4gIH1cblxuICBhc3luYyB1cGRhdGUobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPiB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgIGxldCB7IHJlY29yZCwgaWQgfSA9IHRoaXMuYWRhcHRlci5wcmVwYXJlKG1vZGVsLCB0aGlzLnBrKTtcbiAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmFkYXB0ZXIudXBkYXRlKHRoaXMudGFibGVOYW1lLCBpZCwgcmVjb3JkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydDxNPihyZWNvcmQsIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVQcmVmaXgoXG4gICAgbW9kZWw6IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxbTSwgLi4uYXJnczogYW55W11dPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyXG4gICAgKTtcbiAgICBjb25zdCBwayA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVt0aGlzLnBrXTtcbiAgICBpZiAoIXBrKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wa31gXG4gICAgICApO1xuICAgIGNvbnN0IG9sZE1vZGVsID0gYXdhaXQgdGhpcy5yZWFkKHBrLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBtb2RlbCA9IHRoaXMubWVyZ2Uob2xkTW9kZWwsIG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgIG9sZE1vZGVsXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycyhcbiAgICAgIG9sZE1vZGVsLFxuICAgICAgLi4uUmVwb3NpdG9yeS5yZWxhdGlvbnModGhpcy5jbGFzcylcbiAgICApO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLnRvU3RyaW5nKCkpO1xuICAgIGlmIChSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsKSkge1xuICAgICAgaWYgKCFSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG1vZGVsKSlcbiAgICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtb2RlbCwgUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbCkpO1xuICAgIH1cbiAgICByZXR1cm4gW21vZGVsLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUFsbChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHJlY29yZHMgPSBtb2RlbHMubWFwKChtKSA9PiB0aGlzLmFkYXB0ZXIucHJlcGFyZShtLCB0aGlzLnBrKSk7XG4gICAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IHRoaXMuYWRhcHRlci51cGRhdGVBbGwoXG4gICAgICB0aGlzLnRhYmxlTmFtZSxcbiAgICAgIHJlY29yZHMubWFwKChyKSA9PiByLmlkKSxcbiAgICAgIHJlY29yZHMubWFwKChyKSA9PiByLnJlY29yZCksXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICByZXR1cm4gdXBkYXRlZC5tYXAoKHUsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHUsIHRoaXMuY2xhc3MsIHRoaXMucGssIHJlY29yZHNbaV0uaWQpXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVBbGxQcmVmaXgobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxhbnlbXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJncyxcbiAgICAgIHRoaXMuYWRhcHRlclxuICAgICk7XG4gICAgY29uc3QgaWRzID0gbW9kZWxzLm1hcCgobSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSAobSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVt0aGlzLnBrXTtcbiAgICAgIGlmICghaWQpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwibWlzc2luZyBpZCBvbiB1cGRhdGUgb3BlcmF0aW9uXCIpO1xuICAgICAgcmV0dXJuIGlkO1xuICAgIH0pO1xuICAgIGNvbnN0IG9sZE1vZGVscyA9IGF3YWl0IHRoaXMucmVhZEFsbChpZHMsIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIG1vZGVscyA9IG1vZGVscy5tYXAoKG0sIGkpID0+IHtcbiAgICAgIG0gPSB0aGlzLm1lcmdlKG9sZE1vZGVsc1tpXSwgbSk7XG4gICAgICBpZiAoUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShvbGRNb2RlbHNbaV0pKSB7XG4gICAgICAgIGlmICghUmVwb3NpdG9yeS5nZXRNZXRhZGF0YShtKSlcbiAgICAgICAgICBSZXBvc2l0b3J5LnNldE1ldGFkYXRhKG0sIFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0sIGkpID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgICAgICBvbGRNb2RlbHNbaV1cbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbHNcbiAgICAgIC5tYXAoKG0sIGkpID0+IG0uaGFzRXJyb3JzKG9sZE1vZGVsc1tpXSwgbSkpXG4gICAgICAucmVkdWNlKChhY2N1bTogc3RyaW5nIHwgdW5kZWZpbmVkLCBlLCBpKSA9PiB7XG4gICAgICAgIGlmIChlKVxuICAgICAgICAgIGFjY3VtID1cbiAgICAgICAgICAgIHR5cGVvZiBhY2N1bSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgICA/IGFjY3VtICsgYFxcbiAtICR7aX06ICR7ZS50b1N0cmluZygpfWBcbiAgICAgICAgICAgICAgOiBgIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YDtcbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSwgdW5kZWZpbmVkKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycyk7XG5cbiAgICBtb2RlbHMuZm9yRWFjaCgobSwgaSkgPT4ge1xuICAgICAgaWYgKFJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEob2xkTW9kZWxzW2ldKSkge1xuICAgICAgICBpZiAoIVJlcG9zaXRvcnkuZ2V0TWV0YWRhdGEobSkpXG4gICAgICAgICAgUmVwb3NpdG9yeS5zZXRNZXRhZGF0YShtLCBSZXBvc2l0b3J5LmdldE1ldGFkYXRhKG9sZE1vZGVsc1tpXSkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBkZWxldGVQcmVmaXgoa2V5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzLFxuICAgICAgdGhpcy5hZGFwdGVyXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBhc3luYyBkZWxldGUoaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICBjb25zdCBtID0gYXdhaXQgdGhpcy5hZGFwdGVyLmRlbGV0ZSh0aGlzLnRhYmxlTmFtZSwgaWQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucmV2ZXJ0PE0+KG0sIHRoaXMuY2xhc3MsIHRoaXMucGssIGlkKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBkZWxldGVBbGxQcmVmaXgoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3MsXG4gICAgICB0aGlzLmFkYXB0ZXJcbiAgICApO1xuICAgIGNvbnN0IG1vZGVscyA9IGF3YWl0IHRoaXMucmVhZEFsbChrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgcmV0dXJuIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBba2V5cywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBhc3luYyBkZWxldGVBbGwoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuZGVsZXRlQWxsKHRoaXMudGFibGVOYW1lLCBrZXlzLCAuLi5hcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0cy5tYXAoKHIsIGkpID0+XG4gICAgICB0aGlzLmFkYXB0ZXIucmV2ZXJ0KHIsIHRoaXMuY2xhc3MsIHRoaXMucGssIGtleXNbaV0pXG4gICAgKTtcbiAgfVxuXG4gIHNlbGVjdChzZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yKTogV2hlcmVPcHRpb24ge1xuICAgIHJldHVybiBuZXcgUXVlcnk8USwgTT4odGhpcy5hZGFwdGVyKS5zZWxlY3Qoc2VsZWN0b3IpLmZyb20odGhpcy5jbGFzcyk7XG4gIH1cblxuICBhc3luYyBxdWVyeTxWPihcbiAgICBjb25kaXRpb246IENvbmRpdGlvbixcbiAgICBvcmRlckJ5OiBzdHJpbmcsXG4gICAgb3JkZXI6IE9yZGVyRGlyZWN0aW9uID0gT3JkZXJEaXJlY3Rpb24uQVNDLFxuICAgIGxpbWl0PzogbnVtYmVyLFxuICAgIHNraXA/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxWPiB7XG4gICAgY29uc3Qgc29ydDogT3JkZXJCeVNlbGVjdG9yID0gW29yZGVyQnkgYXMgc3RyaW5nLCBvcmRlciBhcyBPcmRlckRpcmVjdGlvbl07XG4gICAgY29uc3QgcXVlcnkgPSB0aGlzLnNlbGVjdCgpLndoZXJlKGNvbmRpdGlvbikub3JkZXJCeShzb3J0KTtcbiAgICBpZiAobGltaXQpIHF1ZXJ5LmxpbWl0KGxpbWl0KTtcbiAgICBpZiAoc2tpcCkgcXVlcnkub2Zmc2V0KHNraXApO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlPFY+KCk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgUmVnaXN0ZXJzIGFuIHtAbGluayBPYnNlcnZlcn1cbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICpcbiAgICogQHNlZSB7T2JzZXJ2YWJsZSNvYnNlcnZlfVxuICAgKi9cbiAgb2JzZXJ2ZShvYnNlcnZlcjogT2JzZXJ2ZXIpOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXIpO1xuICAgIGlmIChpbmRleCAhPT0gLTEpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiT2JzZXJ2ZXIgYWxyZWFkeSByZWdpc3RlcmVkXCIpO1xuICAgIHRoaXMub2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFVucmVnaXN0ZXJzIGFuIHtAbGluayBPYnNlcnZlcn1cbiAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXJcbiAgICpcbiAgICogQHNlZSB7T2JzZXJ2YWJsZSN1bk9ic2VydmV9XG4gICAqL1xuICB1bk9ic2VydmUob2JzZXJ2ZXI6IE9ic2VydmVyKTogdm9pZCB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLm9ic2VydmVycy5pbmRleE9mKG9ic2VydmVyKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkZhaWxlZCB0byBmaW5kIE9ic2VydmVyXCIpO1xuICAgIHRoaXMub2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgY2FsbHMgYWxsIHJlZ2lzdGVyZWQge0BsaW5rIE9ic2VydmVyfXMgdG8gdXBkYXRlIHRoZW1zZWx2ZXNcbiAgICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gdGhlIHtAbGluayBPYnNlcnZlciNyZWZyZXNofSBtZXRob2RcbiAgICovXG4gIGFzeW5jIHVwZGF0ZU9ic2VydmVycyguLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoXG4gICAgICB0aGlzLm9ic2VydmVycy5tYXAoKG8pID0+IG8ucmVmcmVzaCguLi5hcmdzKSlcbiAgICApO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKVxuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYEZhaWxlZCB0byB1cGRhdGUgb2JzZXJ2YWJsZSAke3RoaXMub2JzZXJ2ZXJzW2ldfTogJHtyZXN1bHQucmVhc29ufWBcbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBmb3JNb2RlbDxNIGV4dGVuZHMgTW9kZWwsIFIgZXh0ZW5kcyBSZXBvPE0+PihcbiAgICBtb2RlbDogQ29uc3RydWN0b3I8TT4sXG4gICAgZGVmYXVsdEZsYXZvdXI/OiBzdHJpbmdcbiAgKTogUiB7XG4gICAgbGV0IHJlcG86IFIgfCBDb25zdHJ1Y3RvcjxSPiB8IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgcmVwbyA9IHRoaXMuZ2V0KG1vZGVsKSBhcyBDb25zdHJ1Y3RvcjxSPiB8IFI7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICByZXBvID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChyZXBvIGluc3RhbmNlb2YgUmVwb3NpdG9yeSkgcmV0dXJuIHJlcG8gYXMgUjtcblxuICAgIGNvbnN0IGZsYXZvdXI6IHN0cmluZyB8IHVuZGVmaW5lZCA9XG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgbW9kZWwpIHx8XG4gICAgICAocmVwbyAmJlxuICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSwgcmVwbykpIHx8XG4gICAgICBkZWZhdWx0Rmxhdm91cjtcbiAgICBjb25zdCBhZGFwdGVyOiBBZGFwdGVyPGFueSwgYW55PiB8IHVuZGVmaW5lZCA9IGZsYXZvdXJcbiAgICAgID8gQWRhcHRlci5nZXQoZmxhdm91cilcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKCFhZGFwdGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyByZWdpc3RlcmVkIHBlcnNpc3RlbmNlIGFkYXB0ZXIgZm91bmQgZmxhdm91ciAke2ZsYXZvdXJ9YFxuICAgICAgKTtcblxuICAgIHJlcG8gPSByZXBvIHx8IChhZGFwdGVyLnJlcG9zaXRvcnkoKSBhcyBDb25zdHJ1Y3RvcjxSPik7XG4gICAgcmV0dXJuIG5ldyByZXBvKGFkYXB0ZXIsIG1vZGVsKSBhcyBSO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+XG4gICk6IENvbnN0cnVjdG9yPFJlcG88TT4+IHwgUmVwbzxNPiB7XG4gICAgY29uc3QgbmFtZSA9IFJlcG9zaXRvcnkudGFibGUobW9kZWwpO1xuICAgIGlmIChuYW1lIGluIHRoaXMuX2NhY2hlKVxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlW25hbWVdIGFzIENvbnN0cnVjdG9yPFJlcG88TT4+IHwgUmVwbzxNPjtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBDb3VsZCBub3QgZmluZCByZXBvc2l0b3J5IHJlZ2lzdGVyZWQgdW5kZXIgJHtuYW1lfWBcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIHJlZ2lzdGVyPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIHJlcG86IENvbnN0cnVjdG9yPFJlcG88TT4+IHwgUmVwbzxNPlxuICApIHtcbiAgICBjb25zdCBuYW1lID0gUmVwb3NpdG9yeS50YWJsZShtb2RlbCk7XG4gICAgaWYgKG5hbWUgaW4gdGhpcy5fY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgJHtuYW1lfSBhbHJlYWR5IHJlZ2lzdGVyZWQgYXMgYSByZXBvc2l0b3J5YCk7XG4gICAgdGhpcy5fY2FjaGVbbmFtZV0gPSByZXBvO1xuICB9XG5cbiAgc3RhdGljIHNldE1ldGFkYXRhPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0sIG1ldGFkYXRhOiBhbnkpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kZWwsIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQSwge1xuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICB2YWx1ZTogbWV0YWRhdGEsXG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgZ2V0TWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSkge1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuICAgICAgbW9kZWwsXG4gICAgICBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFcbiAgICApO1xuICAgIHJldHVybiBkZXNjcmlwdG9yID8gZGVzY3JpcHRvci52YWx1ZSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHN0YXRpYyByZW1vdmVNZXRhZGF0YTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoXG4gICAgICBtb2RlbCxcbiAgICAgIFBlcnNpc3RlbmNlS2V5cy5NRVRBREFUQVxuICAgICk7XG4gICAgaWYgKGRlc2NyaXB0b3IpIGRlbGV0ZSAobW9kZWwgYXMgYW55KVtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdO1xuICB9XG5cbiAgc3RhdGljIGdldFNlcXVlbmNlT3B0aW9uczxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gICAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleShtb2RlbCkuaWQ7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5JRCksIG1vZGVsLCBwayk7XG4gICAgaWYgKCFtZXRhZGF0YSlcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBcIk5vIHNlcXVlbmNlIG9wdGlvbnMgZGVmaW5lZCBmb3IgbW9kZWwuIGRpZCB5b3UgdXNlIHRoZSBAcGsgZGVjb3JhdG9yP1wiXG4gICAgICApO1xuICAgIHJldHVybiBtZXRhZGF0YSBhcyBTZXF1ZW5jZU9wdGlvbnM7XG4gIH1cblxuICBzdGF0aWMgaW5kZXhlczxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNIHwgQ29uc3RydWN0b3I8TT4pIHtcbiAgICBjb25zdCBpbmRleERlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIG1vZGVsIGluc3RhbmNlb2YgTW9kZWwgPyBtb2RlbCA6IG5ldyBtb2RlbCgpLFxuICAgICAgREJLZXlzLlJFRkxFQ1RcbiAgICApO1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhpbmRleERlY29yYXRvcnMgfHwge30pLnJlZHVjZShcbiAgICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgSW5kZXhNZXRhZGF0YT4+LCBbaywgdmFsXSkgPT4ge1xuICAgICAgICBjb25zdCBkZWNzID0gdmFsLmZpbHRlcigodikgPT4gdi5rZXkuc3RhcnRzV2l0aChQZXJzaXN0ZW5jZUtleXMuSU5ERVgpKTtcbiAgICAgICAgaWYgKGRlY3MgJiYgZGVjcy5sZW5ndGgpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGRlYyBvZiBkZWNzKSB7XG4gICAgICAgICAgICBjb25zdCB7IGtleSwgcHJvcHMgfSA9IGRlYztcbiAgICAgICAgICAgIGFjY3VtW2tdID0gYWNjdW1ba10gfHwge307XG4gICAgICAgICAgICBhY2N1bVtrXVtrZXldID0gcHJvcHMgYXMgSW5kZXhNZXRhZGF0YTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgfSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHN0YXRpYyByZWxhdGlvbnM8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGxldCBwcm90b3R5cGUgPVxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbFxuICAgICAgICA/IE9iamVjdC5nZXRQcm90b3R5cGVPZihtb2RlbClcbiAgICAgICAgOiAobW9kZWwgYXMgYW55KS5wcm90b3R5cGU7XG4gICAgd2hpbGUgKHByb3RvdHlwZSAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwcm9wczogc3RyaW5nW10gPSBwcm90b3R5cGVbUGVyc2lzdGVuY2VLZXlzLlJFTEFUSU9OU107XG4gICAgICBpZiAocHJvcHMpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4ucHJvcHMpO1xuICAgICAgfVxuICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBzdGF0aWMgdGFibGU8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSB8IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgcmV0dXJuIGdldFRhYmxlTmFtZShtb2RlbCk7XG4gIH1cblxuICBzdGF0aWMgY29sdW1uPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0sIGF0dHJpYnV0ZTogc3RyaW5nKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTiksXG4gICAgICBtb2RlbCxcbiAgICAgIGF0dHJpYnV0ZVxuICAgICk7XG4gICAgcmV0dXJuIG1ldGFkYXRhID8gbWV0YWRhdGEgOiBhdHRyaWJ1dGU7XG4gIH1cbn1cbiIsImltcG9ydCB7IGluamVjdCwgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjYWYtdHMvaW5qZWN0YWJsZS1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBEQktleXMsIElSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuL1JlcG9zaXRvcnlcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcG9zaXRvcnk8VCBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IENvbnN0cnVjdG9yPFQ+LFxuICBuYW1lT3ZlcnJpZGU/OiBzdHJpbmdcbik6IGFueSB7XG4gIHJldHVybiAoKG9yaWdpbmFsOiBhbnksIHByb3BlcnR5S2V5PzogYW55KSA9PiB7XG4gICAgaWYgKHByb3BlcnR5S2V5KSB7XG4gICAgICByZXR1cm4gaW5qZWN0KG5hbWVPdmVycmlkZSB8fCBtb2RlbC5uYW1lKShvcmlnaW5hbCwgcHJvcGVydHlLZXkpO1xuICAgIH1cblxuICAgIG1ldGFkYXRhKFxuICAgICAgUmVwb3NpdG9yeS5rZXkoREJLZXlzLlJFUE9TSVRPUlkpLFxuICAgICAgbmFtZU92ZXJyaWRlIHx8IG9yaWdpbmFsLm5hbWVcbiAgICApKG1vZGVsKTtcbiAgICBSZXBvc2l0b3J5LnJlZ2lzdGVyKG1vZGVsLCBvcmlnaW5hbCk7XG4gICAgcmV0dXJuIGluamVjdGFibGUoXG4gICAgICBuYW1lT3ZlcnJpZGUgfHwgb3JpZ2luYWwubmFtZSxcbiAgICAgIHRydWUsXG4gICAgICAoaW5zdGFuY2U6IElSZXBvc2l0b3J5PFQ+KSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbnN0YW5jZSwgREJLZXlzLkNMQVNTLCB7XG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgdmFsdWU6IG1vZGVsLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApKG9yaWdpbmFsKTtcbiAgfSkgYXMgYW55O1xufVxuIiwiaW1wb3J0IHsgQmFzZUVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGZhaWx1cmUgaW4gb2JzZXJ2ZXIgY29tbXVuaWNhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgT2JzZXJ2ZXJFcnJvclxuICogQGV4dGVuZHMgQmFzZUVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBPYnNlcnZlckVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKE9ic2VydmVyRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9BZGFwdGVyXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeTxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogQ29uc3RydWN0b3I8VD4gfCBULFxuICBmbGF2b3VyPzogc3RyaW5nXG4pIHtcbiAgaWYgKCFmbGF2b3VyKSB7XG4gICAgY29uc3Qga2V5ID0gQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpO1xuICAgIGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAga2V5LFxuICAgICAgbW9kZWwgaW5zdGFuY2VvZiBNb2RlbCA/IG1vZGVsLmNvbnN0cnVjdG9yIDogbW9kZWxcbiAgICApO1xuICAgIGlmICghZmxhdm91cilcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IHJldHJpZXZlIGZsYXZvdXIgZnJvbSBtb2RlbCAke21vZGVsIGluc3RhbmNlb2YgTW9kZWwgPyBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lIDogbW9kZWwubmFtZX1gXG4gICAgICApO1xuICB9XG4gIHJldHVybiBzZihQZXJzaXN0ZW5jZUtleXMuSU5KRUNUQUJMRSwgZmxhdm91ciwgUmVwb3NpdG9yeS50YWJsZShtb2RlbCkpO1xufVxuIiwiaW1wb3J0IHtcbiAgSW5qZWN0YWJsZVJlZ2lzdHJ5SW1wLFxuICBJbmplY3RhYmxlcyxcbn0gZnJvbSBcIkBkZWNhZi10cy9pbmplY3RhYmxlLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBNb2RlbCwgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IGdlbmVyYXRlSW5qZWN0YWJsZU5hbWVGb3JSZXBvc2l0b3J5IH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvQWRhcHRlclwiO1xuXG5leHBvcnQgY2xhc3MgSW5qZWN0YWJsZXNSZWdpc3RyeSBleHRlbmRzIEluamVjdGFibGVSZWdpc3RyeUltcCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQ8VD4obmFtZTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGluamVjdGFibGUgPSBzdXBlci5nZXQobmFtZSk7XG4gICAgaWYgKCFpbmplY3RhYmxlKVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgbSA9IE1vZGVsLmdldChuYW1lKTtcbiAgICAgICAgaWYgKG0pIGluamVjdGFibGUgPSBSZXBvc2l0b3J5LmZvck1vZGVsKG0pO1xuICAgICAgICBpZiAoaW5qZWN0YWJsZSkge1xuICAgICAgICAgIGlmIChpbmplY3RhYmxlIGluc3RhbmNlb2YgUmVwb3NpdG9yeSkgcmV0dXJuIGluamVjdGFibGUgYXMgVDtcbiAgICAgICAgICBjb25zdCBmbGF2b3VyID1cbiAgICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgICAgIEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5BREFQVEVSKSxcbiAgICAgICAgICAgICAgaW5qZWN0YWJsZS5jb25zdHJ1Y3RvclxuICAgICAgICAgICAgKSB8fFxuICAgICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICAgICAgQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkFEQVBURVIpLFxuICAgICAgICAgICAgICBtIGFzIE1vZGVsQ29uc3RydWN0b3I8YW55PlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBJbmplY3RhYmxlcy5yZWdpc3RlcihcbiAgICAgICAgICAgIGluamVjdGFibGUsXG4gICAgICAgICAgICBnZW5lcmF0ZUluamVjdGFibGVOYW1lRm9yUmVwb3NpdG9yeShcbiAgICAgICAgICAgICAgbSBhcyBNb2RlbENvbnN0cnVjdG9yPGFueT4sXG4gICAgICAgICAgICAgIGZsYXZvdXJcbiAgICAgICAgICAgIClcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIHJldHVybiBpbmplY3RhYmxlIGFzIFQgfCB1bmRlZmluZWQ7XG4gIH1cbn1cbiIsIi8qKlxuICogQHR5cGVkZWYgU2VxdWVuY2VPcHRpb25zXG4gKlxuICogQHByb3Age3N0cmluZyB8IG51bWJlcn0gW3N0YXJ0aW5nVmFsdWVdIGRlZmluZXMgdGhlIHN0YXJ0aW5nIHZhbHVlIHdoZW4gc2VxdWVuY2UgZG9lc3Qgbm90IGV4aXN0XG4gKlxuICogQGNhdGVnb3J5IFNlcXVlbmNlc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlcXVlbmNlT3B0aW9ucyB7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIHR5cGU6IFwiTnVtYmVyXCIgfCBcIkJpZ0ludFwiIHwgdW5kZWZpbmVkO1xuICBzdGFydFdpdGg6IG51bWJlcjtcbiAgaW5jcmVtZW50Qnk6IG51bWJlcjtcbiAgbWluVmFsdWU/OiBudW1iZXI7XG4gIG1heFZhbHVlPzogbnVtYmVyO1xuICBjeWNsZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IERlZmF1bHRTZXF1ZW5jZU9wdGlvbnM6IFNlcXVlbmNlT3B0aW9ucyA9IHtcbiAgdHlwZTogXCJOdW1iZXJcIixcbiAgc3RhcnRXaXRoOiAwLFxuICBpbmNyZW1lbnRCeTogMSxcbiAgY3ljbGU6IGZhbHNlLFxufTtcblxuZXhwb3J0IGNvbnN0IE51bWVyaWNTZXF1ZW5jZTogU2VxdWVuY2VPcHRpb25zID0ge1xuICB0eXBlOiBcIk51bWJlclwiLFxuICBzdGFydFdpdGg6IDAsXG4gIGluY3JlbWVudEJ5OiAxLFxuICBjeWNsZTogZmFsc2UsXG59O1xuXG5leHBvcnQgY29uc3QgQmlnSW50U2VxdWVuY2U6IFNlcXVlbmNlT3B0aW9ucyA9IHtcbiAgdHlwZTogXCJCaWdJbnRcIixcbiAgc3RhcnRXaXRoOiAwLFxuICBpbmNyZW1lbnRCeTogMSxcbiAgY3ljbGU6IGZhbHNlLFxufTtcbiIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSwgU3VwcHJlc3NlZEVycm9yLCBTeW1ib2wsIEl0ZXJhdG9yICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnVuc2hpZnQoXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnID0gT2JqZWN0LmNyZWF0ZSgodHlwZW9mIEl0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKTtcclxuICAgIHJldHVybiBnLm5leHQgPSB2ZXJiKDApLCBnW1widGhyb3dcIl0gPSB2ZXJiKDEpLCBnW1wicmV0dXJuXCJdID0gdmVyYigyKSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgQXN5bmNJdGVyYXRvciA9PT0gXCJmdW5jdGlvblwiID8gQXN5bmNJdGVyYXRvciA6IE9iamVjdCkucHJvdG90eXBlKSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiLCBhd2FpdFJldHVybiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIGF3YWl0UmV0dXJuKGYpIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUodikudGhlbihmLCByZWplY3QpOyB9OyB9XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaWYgKGdbbl0pIHsgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgaWYgKGYpIGlbbl0gPSBmKGlbbl0pOyB9IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG52YXIgb3duS2V5cyA9IGZ1bmN0aW9uKG8pIHtcclxuICAgIG93bktleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB8fCBmdW5jdGlvbiAobykge1xyXG4gICAgICAgIHZhciBhciA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIGsgaW4gbykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBrKSkgYXJbYXIubGVuZ3RoXSA9IGs7XHJcbiAgICAgICAgcmV0dXJuIGFyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBvd25LZXlzKG8pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgPSBvd25LZXlzKG1vZCksIGkgPSAwOyBpIDwgay5sZW5ndGg7IGkrKykgaWYgKGtbaV0gIT09IFwiZGVmYXVsdFwiKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGtbaV0pO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hZGREaXNwb3NhYmxlUmVzb3VyY2UoZW52LCB2YWx1ZSwgYXN5bmMpIHtcclxuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdm9pZCAwKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZC5cIik7XHJcbiAgICAgICAgdmFyIGRpc3Bvc2UsIGlubmVyO1xyXG4gICAgICAgIGlmIChhc3luYykge1xyXG4gICAgICAgICAgICBpZiAoIVN5bWJvbC5hc3luY0Rpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNEaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5hc3luY0Rpc3Bvc2VdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZGlzcG9zZSA9PT0gdm9pZCAwKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmRpc3Bvc2UpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuZGlzcG9zZSBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICAgICAgICAgIGRpc3Bvc2UgPSB2YWx1ZVtTeW1ib2wuZGlzcG9zZV07XHJcbiAgICAgICAgICAgIGlmIChhc3luYykgaW5uZXIgPSBkaXNwb3NlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBub3QgZGlzcG9zYWJsZS5cIik7XHJcbiAgICAgICAgaWYgKGlubmVyKSBkaXNwb3NlID0gZnVuY3Rpb24oKSB7IHRyeSB7IGlubmVyLmNhbGwodGhpcyk7IH0gY2F0Y2ggKGUpIHsgcmV0dXJuIFByb21pc2UucmVqZWN0KGUpOyB9IH07XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyB2YWx1ZTogdmFsdWUsIGRpc3Bvc2U6IGRpc3Bvc2UsIGFzeW5jOiBhc3luYyB9KTtcclxuICAgIH1cclxuICAgIGVsc2UgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgZW52LnN0YWNrLnB1c2goeyBhc3luYzogdHJ1ZSB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB2YWx1ZTtcclxuXHJcbn1cclxuXHJcbnZhciBfU3VwcHJlc3NlZEVycm9yID0gdHlwZW9mIFN1cHByZXNzZWRFcnJvciA9PT0gXCJmdW5jdGlvblwiID8gU3VwcHJlc3NlZEVycm9yIDogZnVuY3Rpb24gKGVycm9yLCBzdXBwcmVzc2VkLCBtZXNzYWdlKSB7XHJcbiAgICB2YXIgZSA9IG5ldyBFcnJvcihtZXNzYWdlKTtcclxuICAgIHJldHVybiBlLm5hbWUgPSBcIlN1cHByZXNzZWRFcnJvclwiLCBlLmVycm9yID0gZXJyb3IsIGUuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kaXNwb3NlUmVzb3VyY2VzKGVudikge1xyXG4gICAgZnVuY3Rpb24gZmFpbChlKSB7XHJcbiAgICAgICAgZW52LmVycm9yID0gZW52Lmhhc0Vycm9yID8gbmV3IF9TdXBwcmVzc2VkRXJyb3IoZSwgZW52LmVycm9yLCBcIkFuIGVycm9yIHdhcyBzdXBwcmVzc2VkIGR1cmluZyBkaXNwb3NhbC5cIikgOiBlO1xyXG4gICAgICAgIGVudi5oYXNFcnJvciA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB2YXIgciwgcyA9IDA7XHJcbiAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgIHdoaWxlIChyID0gZW52LnN0YWNrLnBvcCgpKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXIuYXN5bmMgJiYgcyA9PT0gMSkgcmV0dXJuIHMgPSAwLCBlbnYuc3RhY2sucHVzaChyKSwgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihuZXh0KTtcclxuICAgICAgICAgICAgICAgIGlmIChyLmRpc3Bvc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gci5kaXNwb3NlLmNhbGwoci52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHIuYXN5bmMpIHJldHVybiBzIHw9IDIsIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLnRoZW4obmV4dCwgZnVuY3Rpb24oZSkgeyBmYWlsKGUpOyByZXR1cm4gbmV4dCgpOyB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgcyB8PSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBmYWlsKGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzID09PSAxKSByZXR1cm4gZW52Lmhhc0Vycm9yID8gUHJvbWlzZS5yZWplY3QoZW52LmVycm9yKSA6IFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgIGlmIChlbnYuaGFzRXJyb3IpIHRocm93IGVudi5lcnJvcjtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXh0KCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbihwYXRoLCBwcmVzZXJ2ZUpzeCkge1xyXG4gICAgaWYgKHR5cGVvZiBwYXRoID09PSBcInN0cmluZ1wiICYmIC9eXFwuXFwuP1xcLy8udGVzdChwYXRoKSkge1xyXG4gICAgICAgIHJldHVybiBwYXRoLnJlcGxhY2UoL1xcLih0c3gpJHwoKD86XFwuZCk/KSgoPzpcXC5bXi4vXSs/KT8pXFwuKFtjbV0/KXRzJC9pLCBmdW5jdGlvbiAobSwgdHN4LCBkLCBleHQsIGNtKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0c3ggPyBwcmVzZXJ2ZUpzeCA/IFwiLmpzeFwiIDogXCIuanNcIiA6IGQgJiYgKCFleHQgfHwgIWNtKSA/IG0gOiAoZCArIGV4dCArIFwiLlwiICsgY20udG9Mb3dlckNhc2UoKSArIFwianNcIik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGF0aDtcclxufVxyXG5cclxuZXhwb3J0IGRlZmF1bHQge1xyXG4gICAgX19leHRlbmRzOiBfX2V4dGVuZHMsXHJcbiAgICBfX2Fzc2lnbjogX19hc3NpZ24sXHJcbiAgICBfX3Jlc3Q6IF9fcmVzdCxcclxuICAgIF9fZGVjb3JhdGU6IF9fZGVjb3JhdGUsXHJcbiAgICBfX3BhcmFtOiBfX3BhcmFtLFxyXG4gICAgX19lc0RlY29yYXRlOiBfX2VzRGVjb3JhdGUsXHJcbiAgICBfX3J1bkluaXRpYWxpemVyczogX19ydW5Jbml0aWFsaXplcnMsXHJcbiAgICBfX3Byb3BLZXk6IF9fcHJvcEtleSxcclxuICAgIF9fc2V0RnVuY3Rpb25OYW1lOiBfX3NldEZ1bmN0aW9uTmFtZSxcclxuICAgIF9fbWV0YWRhdGE6IF9fbWV0YWRhdGEsXHJcbiAgICBfX2F3YWl0ZXI6IF9fYXdhaXRlcixcclxuICAgIF9fZ2VuZXJhdG9yOiBfX2dlbmVyYXRvcixcclxuICAgIF9fY3JlYXRlQmluZGluZzogX19jcmVhdGVCaW5kaW5nLFxyXG4gICAgX19leHBvcnRTdGFyOiBfX2V4cG9ydFN0YXIsXHJcbiAgICBfX3ZhbHVlczogX192YWx1ZXMsXHJcbiAgICBfX3JlYWQ6IF9fcmVhZCxcclxuICAgIF9fc3ByZWFkOiBfX3NwcmVhZCxcclxuICAgIF9fc3ByZWFkQXJyYXlzOiBfX3NwcmVhZEFycmF5cyxcclxuICAgIF9fc3ByZWFkQXJyYXk6IF9fc3ByZWFkQXJyYXksXHJcbiAgICBfX2F3YWl0OiBfX2F3YWl0LFxyXG4gICAgX19hc3luY0dlbmVyYXRvcjogX19hc3luY0dlbmVyYXRvcixcclxuICAgIF9fYXN5bmNEZWxlZ2F0b3I6IF9fYXN5bmNEZWxlZ2F0b3IsXHJcbiAgICBfX2FzeW5jVmFsdWVzOiBfX2FzeW5jVmFsdWVzLFxyXG4gICAgX19tYWtlVGVtcGxhdGVPYmplY3Q6IF9fbWFrZVRlbXBsYXRlT2JqZWN0LFxyXG4gICAgX19pbXBvcnRTdGFyOiBfX2ltcG9ydFN0YXIsXHJcbiAgICBfX2ltcG9ydERlZmF1bHQ6IF9faW1wb3J0RGVmYXVsdCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRHZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRHZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0OiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEluOiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4sXHJcbiAgICBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZTogX19hZGREaXNwb3NhYmxlUmVzb3VyY2UsXHJcbiAgICBfX2Rpc3Bvc2VSZXNvdXJjZXM6IF9fZGlzcG9zZVJlc291cmNlcyxcclxuICAgIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uOiBfX3Jld3JpdGVSZWxhdGl2ZUltcG9ydEV4dGVuc2lvbixcclxufTtcclxuIiwiaW1wb3J0IHsgQmFzZUVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCBjbGFzcyBRdWVyeUVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFF1ZXJ5RXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFnaW5nRXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoUGFnaW5nRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQXR0cmlidXRlT3B0aW9uLCBDb25kaXRpb25CdWlsZGVyT3B0aW9uIH0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgTW9kZWwsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICByZXF1aXJlZCxcbiAgc2YsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEdyb3VwT3BlcmF0b3IsIE9wZXJhdG9yIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBRdWVyeUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQ29uZGl0aW9uIENsYXNzXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyBhIGxvZ2ljYWwgY29uZGl0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmcgfCBDb25kaXRpb259IGF0dHIxXG4gKiBAcGFyYW0ge09wZXJhdG9yIHwgR3JvdXBPcGVyYXRvcn0gb3BlcmF0b3JcbiAqIEBwYXJhbSB7c3RyaW5nIHwgQ29uZGl0aW9ufSBjb21wYXJpc29uXG4gKlxuICogQGNsYXNzIENvbmRpdGlvblxuICogQGltcGxlbWVudHMgRXhlY3V0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDb25kaXRpb25zXG4gKi9cblxuZXhwb3J0IGNsYXNzIENvbmRpdGlvbiBleHRlbmRzIE1vZGVsIHtcbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIGF0dHIxPzogc3RyaW5nIHwgQ29uZGl0aW9uID0gdW5kZWZpbmVkO1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgb3BlcmF0b3I/OiBPcGVyYXRvciB8IEdyb3VwT3BlcmF0b3IgPSB1bmRlZmluZWQ7XG4gIEByZXF1aXJlZCgpXG4gIHByb3RlY3RlZCBjb21wYXJpc29uPzogYW55ID0gdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgYXR0cjE6IHN0cmluZyB8IENvbmRpdGlvbixcbiAgICBvcGVyYXRvcjogT3BlcmF0b3IgfCBHcm91cE9wZXJhdG9yLFxuICAgIGNvbXBhcmlzb246IGFueVxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYXR0cjEgPSBhdHRyMTtcbiAgICB0aGlzLm9wZXJhdG9yID0gb3BlcmF0b3I7XG4gICAgdGhpcy5jb21wYXJpc29uID0gY29tcGFyaXNvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBKb2lucyAyIHtAbGluayBDb25kaXRpb259cyBvbiBhbiB7QGxpbmsgT3BlcmF0b3IjQU5EfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvblxuICAgKi9cbiAgYW5kKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogQ29uZGl0aW9uIHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLmFuZCh0aGlzLCBjb25kaXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNPUn0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb25cbiAgICovXG4gIG9yKGNvbmRpdGlvbjogQ29uZGl0aW9uKTogQ29uZGl0aW9uIHtcbiAgICByZXR1cm4gQ29uZGl0aW9uLm9yKHRoaXMsIGNvbmRpdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgZXhjbHVkZXMgYSB2YWx1dCBmcm9tIHRoZSByZXN1bHRcbiAgICogQHBhcmFtIHZhbFxuICAgKi9cbiAgbm90KHZhbDogYW55KTogQ29uZGl0aW9uIHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbih0aGlzLCBPcGVyYXRvci5OT1QsIHZhbCk7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGhhc0Vycm9ycyguLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlcnJvcnMgPSBzdXBlci5oYXNFcnJvcnMoLi4uZXhjZXB0aW9ucyk7XG4gICAgaWYgKGVycm9ycykgcmV0dXJuIGVycm9ycztcblxuICAgIGlmICh0eXBlb2YgdGhpcy5hdHRyMSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgaWYgKHRoaXMuY29tcGFyaXNvbiBpbnN0YW5jZW9mIENvbmRpdGlvbilcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb21wYXJpc29uOiB7XG4gICAgICAgICAgICBjb25kaXRpb246IFwiQm90aCBzaWRlcyBvZiB0aGUgY29tcGFyaXNvbiBtdXN0IGJlIG9mIHRoZSBzYW1lIHR5cGVcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9IGFzIE1vZGVsRXJyb3JEZWZpbml0aW9uO1xuICAgICAgaWYgKE9iamVjdC52YWx1ZXMoT3BlcmF0b3IpLmluZGV4T2YodGhpcy5vcGVyYXRvciBhcyBPcGVyYXRvcikgPT09IC0xKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG9wZXJhdG9yOiB7XG4gICAgICAgICAgICBjb25kaXRpb246IHNmKFwiSW52YWxpZCBvcGVyYXRvciB7MH1cIiwgdGhpcy5vcGVyYXRvciBhcyBzdHJpbmcpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0gYXMgTW9kZWxFcnJvckRlZmluaXRpb247XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXR0cjEgaW5zdGFuY2VvZiBDb25kaXRpb24pIHtcbiAgICAgIGlmIChcbiAgICAgICAgISh0aGlzLmNvbXBhcmlzb24gaW5zdGFuY2VvZiBDb25kaXRpb24pICYmXG4gICAgICAgIHRoaXMub3BlcmF0b3IgIT09IE9wZXJhdG9yLk5PVFxuICAgICAgKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbXBhcmlzb246IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogc2YoXCJJbnZhbGlkIG9wZXJhdG9yIHswfVwiLCB0aGlzLm9wZXJhdG9yIGFzIHN0cmluZyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvbjtcbiAgICAgIGlmIChcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhHcm91cE9wZXJhdG9yKS5pbmRleE9mKHRoaXMub3BlcmF0b3IgYXMgR3JvdXBPcGVyYXRvcikgPT09XG4gICAgICAgICAgLTEgJiZcbiAgICAgICAgdGhpcy5vcGVyYXRvciAhPT0gT3BlcmF0b3IuTk9UXG4gICAgICApXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3BlcmF0b3I6IHtcbiAgICAgICAgICAgIGNvbmRpdGlvbjogc2YoXCJJbnZhbGlkIG9wZXJhdG9yIHswfVwiLCB0aGlzLm9wZXJhdG9yIGFzIHN0cmluZyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvbjtcbiAgICAgIC8vIGlmICh0aGlzLm9wZXJhdG9yICE9PSBPcGVyYXRvci5OT1QgJiYgdHlwZW9mIHRoaXMuYXR0cjEuYXR0cjEgIT09IFwic3RyaW5nXCIpXG4gICAgICAvLyAgICAgcmV0dXJuIHtcbiAgICAgIC8vICAgICAgICAgYXR0cjE6IHtcbiAgICAgIC8vICAgICAgICAgICAgIGNvbmRpdGlvbjogc3RyaW5nRm9ybWF0KFwiUGFyZW50IGNvbmRpdGlvbiBhdHRyaWJ1dGUgbXVzdCBiZSBhIHN0cmluZ1wiKVxuICAgICAgLy8gICAgICAgICB9XG4gICAgICAvLyAgICAgfSBhcyBNb2RlbEVycm9yRGVmaW5pdGlvblxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBKb2lucyAyIHtAbGluayBDb25kaXRpb259cyBvbiBhbiB7QGxpbmsgT3BlcmF0b3IjQU5EfSBvcGVyYXRpb25cbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjFcbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjJcbiAgICovXG4gIHN0YXRpYyBhbmQoY29uZGl0aW9uMTogQ29uZGl0aW9uLCBjb25kaXRpb24yOiBDb25kaXRpb24pOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBDb25kaXRpb24uZ3JvdXAoY29uZGl0aW9uMSwgR3JvdXBPcGVyYXRvci5BTkQsIGNvbmRpdGlvbjIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEpvaW5zIDIge0BsaW5rIENvbmRpdGlvbn1zIG9uIGFuIHtAbGluayBPcGVyYXRvciNPUn0gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb24xXG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb24yXG4gICAqL1xuICBzdGF0aWMgb3IoY29uZGl0aW9uMTogQ29uZGl0aW9uLCBjb25kaXRpb24yOiBDb25kaXRpb24pOiBDb25kaXRpb24ge1xuICAgIHJldHVybiBDb25kaXRpb24uZ3JvdXAoY29uZGl0aW9uMSwgR3JvdXBPcGVyYXRvci5PUiwgY29uZGl0aW9uMik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgR3JvdXBzIDIge0BsaW5rIENvbmRpdGlvbn1zIGJ5IHRoZSBzcGVjaWZpZWQge0BsaW5rIEdyb3VwT3BlcmF0b3J9XG4gICAqIEBwYXJhbSB7Q29uZGl0aW9ufSBjb25kaXRpb24xXG4gICAqIEBwYXJhbSB7R3JvdXBPcGVyYXRvcn0gb3BlcmF0b3JcbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvbjJcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdyb3VwKFxuICAgIGNvbmRpdGlvbjE6IENvbmRpdGlvbixcbiAgICBvcGVyYXRvcjogR3JvdXBPcGVyYXRvcixcbiAgICBjb25kaXRpb24yOiBDb25kaXRpb25cbiAgKTogQ29uZGl0aW9uIHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbihjb25kaXRpb24xLCBvcGVyYXRvciwgY29uZGl0aW9uMik7XG4gIH1cblxuICBzdGF0aWMgYXR0cmlidXRlKGF0dHI6IHN0cmluZykge1xuICAgIHJldHVybiBuZXcgQ29uZGl0aW9uLkJ1aWxkZXIoKS5hdHRyaWJ1dGUoYXR0cik7XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgQ29uZGl0aW9uIEJ1aWxkZXIgQ2xhc3NcbiAgICogQGRlc2NyaXB0aW9uIHByb3ZpZGVzIGEgc2ltcGxlIEFQSSB0byBidWlsZCB7QGxpbmsgQ29uZGl0aW9ufXNcbiAgICpcbiAgICogQGNsYXNzIENvbmRpdGlvbkJ1aWxkZXJcbiAgICogQGltcGxlbWVudHMgQnVpbGRlclxuICAgKiBAaW1wbGVtZW50cyBBdHRyaWJ1dGVPcHRpb25cbiAgICpcbiAgICogQGNhdGVnb3J5IFF1ZXJ5XG4gICAqIEBzdWJjYXRlZ29yeSBDb25kaXRpb25zXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBCdWlsZGVyID0gY2xhc3MgQ29uZGl0aW9uQnVpbGRlclxuICAgIGltcGxlbWVudHMgQ29uZGl0aW9uQnVpbGRlck9wdGlvbiwgQXR0cmlidXRlT3B0aW9uXG4gIHtcbiAgICBhdHRyMT86IHN0cmluZyB8IENvbmRpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICBvcGVyYXRvcj86IE9wZXJhdG9yIHwgR3JvdXBPcGVyYXRvciA9IHVuZGVmaW5lZDtcbiAgICBjb21wYXJpc29uPzogYW55ID0gdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGluaGVyaXREb2NcbiAgICAgKi9cbiAgICBhdHRyaWJ1dGUoYXR0cjogc3RyaW5nKTogQXR0cmlidXRlT3B0aW9uIHtcbiAgICAgIHRoaXMuYXR0cjEgPSBhdHRyO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbiBFcXVhbGl0eSBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGVxKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5FUVVBTCwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgRGlmZmVyZW50IENvbXBhcmlzb25cbiAgICAgKiBAcGFyYW0ge2FueX0gdmFsXG4gICAgICovXG4gICAgZGlmKHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5ESUZGRVJFTlQsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIEdyZWF0ZXIgVGhhbiBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGd0KHZhbDogYW55KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5CSUdHRVIsIHZhbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIExvd2VyIFRoYW4gQ29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7YW55fSB2YWxcbiAgICAgKi9cbiAgICBsdCh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuU01BTExFUiwgdmFsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgR3JlYXRlciBvciBFcXVhbCB0byBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGd0ZSh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuQklHR0VSX0VRLCB2YWwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBMb3dlciBvciBFcXVhbCB0byBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIGx0ZSh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuU01BTExFUl9FUSwgdmFsKTtcbiAgICB9XG5cbiAgICBpbihhcnI6IGFueVtdKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRPcChPcGVyYXRvci5JTiwgYXJyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgUmVnZXhwbyBDb21wYXJpc29uXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIHJlZ2V4cCh2YWw6IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0T3AoT3BlcmF0b3IuUkVHRVhQLCBuZXcgUmVnRXhwKHZhbCkuc291cmNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuIHtAbGluayBPcGVyYXRvcn0gYmFzZWQgQ29tcGFyaXNvblxuICAgICAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wXG4gICAgICogQHBhcmFtIHthbnl9IHZhbFxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0T3Aob3A6IE9wZXJhdG9yLCB2YWw6IGFueSkge1xuICAgICAgdGhpcy5vcGVyYXRvciA9IG9wO1xuICAgICAgdGhpcy5jb21wYXJpc29uID0gdmFsO1xuICAgICAgcmV0dXJuIHRoaXMuYnVpbGQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIERhdGFiYXNlIE9iamVjdFxuICAgICAqIEB0aHJvd3Mge1F1ZXJ5RXJyb3J9IGlmIGl0IGZhaWxzIHRvIGJ1aWxkIHRoZSB7QGxpbmsgQ29uZGl0aW9ufVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBidWlsZCgpOiBDb25kaXRpb24ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBDb25kaXRpb24oXG4gICAgICAgICAgdGhpcy5hdHRyMSBhcyBzdHJpbmcgfCBDb25kaXRpb24sXG4gICAgICAgICAgdGhpcy5vcGVyYXRvciBhcyBPcGVyYXRvcixcbiAgICAgICAgICB0aGlzLmNvbXBhcmlzb24gYXMgYW55XG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoZSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHN0YXRpYyBnZXQgYnVpbGRlcigpOiBDb25kaXRpb25CdWlsZGVyT3B0aW9uIHtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbi5CdWlsZGVyKCk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgVmFsaWRhdGlvbixcbiAgVmFsaWRhdGlvbktleXMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBSZWxhdGlvbnNNZXRhZGF0YSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQge1xuICBmaW5kUHJpbWFyeUtleSxcbiAgSW50ZXJuYWxFcnJvcixcbiAgTm90Rm91bmRFcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDYXNjYWRlIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVPclVwZGF0ZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSxcbiAgY29udGV4dDogQ29udGV4dDxNPixcbiAgcmVwb3NpdG9yeT86IFJlcG88TT5cbik6IFByb21pc2U8TT4ge1xuICBpZiAoIXJlcG9zaXRvcnkpIHtcbiAgICBjb25zdCBjb25zdHJ1Y3RvciA9IE1vZGVsLmdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgICBpZiAoIWNvbnN0cnVjdG9yKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYENvdWxkIG5vdCBmaW5kIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX1gKTtcbiAgICByZXBvc2l0b3J5ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChjb25zdHJ1Y3RvcikgYXMgUmVwbzxNPjtcbiAgfVxuICBpZiAodHlwZW9mIChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtyZXBvc2l0b3J5LnBrXSA9PT0gXCJ1bmRlZmluZWRcIilcbiAgICByZXR1cm4gcmVwb3NpdG9yeS5jcmVhdGUobW9kZWwsIGNvbnRleHQpO1xuICBlbHNlIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkudXBkYXRlKG1vZGVsLCBjb250ZXh0KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSkgdGhyb3cgZTtcbiAgICAgIHJldHVybiByZXBvc2l0b3J5LmNyZWF0ZShtb2RlbCwgY29udGV4dCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uQ3JlYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9IHByb3BlcnR5VmFsdWU7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgY29uc3RydWN0b3IgPSBNb2RlbC5nZXQoZGF0YS5jbGFzcyk7XG4gIGlmICghY29uc3RydWN0b3IpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYENvdWxkIG5vdCBmaW5kIG1vZGVsICR7ZGF0YS5jbGFzc31gKTtcbiAgY29uc3QgcmVwbzogUmVwbzxhbnk+ID0gUmVwb3NpdG9yeS5mb3JNb2RlbChjb25zdHJ1Y3Rvcik7XG4gIGNvbnN0IGNyZWF0ZWQgPSBhd2FpdCByZXBvLmNyZWF0ZShwcm9wZXJ0eVZhbHVlKTtcbiAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleShjcmVhdGVkKS5pZDtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIGNyZWF0ZWRbcGtdLCBjcmVhdGVkKTtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNyZWF0ZWRbcGtdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9PbmVPblVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNPixcbiAgWSBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuPih0aGlzOiBSLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZTogYW55ID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV07XG4gIGlmICghcHJvcGVydHlWYWx1ZSkgcmV0dXJuO1xuICBpZiAoZGF0YS5jYXNjYWRlLnVwZGF0ZSAhPT0gQ2FzY2FkZS5DQVNDQURFKSByZXR1cm47XG5cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eVZhbHVlICE9PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgaW5uZXJSZXBvID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gICAgY29uc3QgcmVhZCA9IGF3YWl0IGlubmVyUmVwby5yZWFkKHByb3BlcnR5VmFsdWUpO1xuICAgIGF3YWl0IGNhY2hlTW9kZWxGb3JQb3B1bGF0ZShjb250ZXh0LCBtb2RlbCwga2V5LCBwcm9wZXJ0eVZhbHVlLCByZWFkKTtcbiAgICAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSA9IHByb3BlcnR5VmFsdWU7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IGNyZWF0ZU9yVXBkYXRlKFxuICAgIChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldLFxuICAgIGNvbnRleHRcbiAgKTtcbiAgY29uc3QgcGsgPSBmaW5kUHJpbWFyeUtleSh1cGRhdGVkKS5pZDtcbiAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5LFxuICAgICh1cGRhdGVkIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3BrXSxcbiAgICB1cGRhdGVkXG4gICk7XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSAodXBkYXRlZCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwa107XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb09uZU9uRGVsZXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwcm9wZXJ0eVZhbHVlOiBhbnkgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XTtcbiAgaWYgKCFwcm9wZXJ0eVZhbHVlKSByZXR1cm47XG4gIGlmIChkYXRhLmNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcbiAgY29uc3QgaW5uZXJSZXBvOiBSZXBvPE0+ID0gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGEobW9kZWwsIGtleSk7XG4gIGxldCBkZWxldGVkOiBNO1xuICBpZiAoIShwcm9wZXJ0eVZhbHVlIGluc3RhbmNlb2YgTW9kZWwpKVxuICAgIGRlbGV0ZWQgPSBhd2FpdCBpbm5lclJlcG8uZGVsZXRlKFxuICAgICAgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0sXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgZWxzZVxuICAgIGRlbGV0ZWQgPSBhd2FpdCBpbm5lclJlcG8uZGVsZXRlKFxuICAgICAgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV1baW5uZXJSZXBvLnBrXSxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoXG4gICAgY29udGV4dCxcbiAgICBtb2RlbCxcbiAgICBrZXksXG4gICAgKGRlbGV0ZWQgYXMgUmVjb3JkPHN0cmluZywgYW55PilbaW5uZXJSZXBvLnBrXSxcbiAgICBkZWxldGVkXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPbkNyZWF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNPixcbiAgWSBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuPih0aGlzOiBSLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcHJvcGVydHlWYWx1ZXM6IGFueSA9IChtb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtrZXldO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzIHx8ICFwcm9wZXJ0eVZhbHVlcy5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgYXJyYXlUeXBlID0gdHlwZW9mIHByb3BlcnR5VmFsdWVzWzBdO1xuICBpZiAoIXByb3BlcnR5VmFsdWVzLmV2ZXJ5KChpdGVtOiBhbnkpID0+IHR5cGVvZiBpdGVtID09PSBhcnJheVR5cGUpKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEludmFsaWQgb3BlcmF0aW9uLiBBbGwgZWxlbWVudHMgb2YgcHJvcGVydHkgJHtrZXl9IG11c3QgbWF0Y2ggdGhlIHNhbWUgdHlwZS5gXG4gICAgKTtcbiAgY29uc3QgdW5pcXVlVmFsdWVzID0gbmV3IFNldChbLi4ucHJvcGVydHlWYWx1ZXNdKTtcbiAgaWYgKGFycmF5VHlwZSAhPT0gXCJvYmplY3RcIikge1xuICAgIGNvbnN0IHJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwga2V5KTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHVuaXF1ZVZhbHVlcykge1xuICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHJlcG8ucmVhZChpZCk7XG4gICAgICBhd2FpdCBjYWNoZU1vZGVsRm9yUG9wdWxhdGUoY29udGV4dCwgbW9kZWwsIGtleSwgaWQsIHJlYWQpO1xuICAgIH1cbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gWy4uLnVuaXF1ZVZhbHVlc107XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgcGtOYW1lID0gZmluZFByaW1hcnlLZXkocHJvcGVydHlWYWx1ZXNbMF0pLmlkO1xuXG4gIGNvbnN0IHJlc3VsdDogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgZm9yIChjb25zdCBtIG9mIHByb3BlcnR5VmFsdWVzKSB7XG4gICAgY29uc3QgcmVjb3JkID0gYXdhaXQgY3JlYXRlT3JVcGRhdGUobSwgY29udGV4dCk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIHJlY29yZFtwa05hbWVdLCByZWNvcmQpO1xuICAgIHJlc3VsdC5hZGQocmVjb3JkW3BrTmFtZV0pO1xuICB9XG5cbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IFsuLi5yZXN1bHRdO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gb25lVG9NYW55T25VcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgZXh0ZW5kcyBSZWxhdGlvbnNNZXRhZGF0YSxcbj4odGhpczogUiwgY29udGV4dDogQ29udGV4dDxNPiwgZGF0YTogWSwga2V5OiBzdHJpbmcsIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgY2FzY2FkZSB9ID0gZGF0YTtcbiAgaWYgKGNhc2NhZGUudXBkYXRlICE9PSBDYXNjYWRlLkNBU0NBREUpIHJldHVybjtcbiAgcmV0dXJuIG9uZVRvTWFueU9uQ3JlYXRlLmNhbGwodGhpcywgY29udGV4dCwgZGF0YSwga2V5LCBtb2RlbCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvbmVUb01hbnlPbkRlbGV0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgUmVwbzxNPixcbiAgWSBleHRlbmRzIFJlbGF0aW9uc01ldGFkYXRhLFxuPih0aGlzOiBSLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGRhdGEuY2FzY2FkZS5kZWxldGUgIT09IENhc2NhZGUuQ0FTQ0FERSkgcmV0dXJuO1xuICBjb25zdCB2YWx1ZXMgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XTtcbiAgaWYgKCF2YWx1ZXMgfHwgIXZhbHVlcy5sZW5ndGgpIHJldHVybjtcbiAgY29uc3QgYXJyYXlUeXBlID0gdHlwZW9mIHZhbHVlc1swXTtcbiAgY29uc3QgYXJlQWxsU2FtZVR5cGUgPSB2YWx1ZXMuZXZlcnkoKGl0ZW06IGFueSkgPT4gdHlwZW9mIGl0ZW0gPT09IGFycmF5VHlwZSk7XG4gIGlmICghYXJlQWxsU2FtZVR5cGUpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgSW52YWxpZCBvcGVyYXRpb24uIEFsbCBlbGVtZW50cyBvZiBwcm9wZXJ0eSAke2tleX0gbXVzdCBtYXRjaCB0aGUgc2FtZSB0eXBlLmBcbiAgICApO1xuICBjb25zdCBpc0luc3RhbnRpYXRlZCA9IGFycmF5VHlwZSA9PT0gXCJvYmplY3RcIjtcbiAgY29uc3QgcmVwbyA9IGlzSW5zdGFudGlhdGVkXG4gICAgPyBSZXBvc2l0b3J5LmZvck1vZGVsKHZhbHVlc1swXSlcbiAgICA6IHJlcG9zaXRvcnlGcm9tVHlwZU1ldGFkYXRhKG1vZGVsLCBrZXkpO1xuXG4gIGNvbnN0IHVuaXF1ZVZhbHVlcyA9IG5ldyBTZXQoW1xuICAgIC4uLihpc0luc3RhbnRpYXRlZFxuICAgICAgPyB2YWx1ZXMubWFwKCh2OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB2W3JlcG8ucGtdKVxuICAgICAgOiB2YWx1ZXMpLFxuICBdKTtcblxuICBmb3IgKGNvbnN0IGlkIG9mIHVuaXF1ZVZhbHVlcy52YWx1ZXMoKSkge1xuICAgIGNvbnN0IGRlbGV0ZWQgPSBhd2FpdCByZXBvLmRlbGV0ZShpZCwgY29udGV4dCk7XG4gICAgYXdhaXQgY2FjaGVNb2RlbEZvclBvcHVsYXRlKGNvbnRleHQsIG1vZGVsLCBrZXksIGlkLCBkZWxldGVkKTtcbiAgfVxuICAobW9kZWwgYXMgYW55KVtrZXldID0gWy4uLnVuaXF1ZVZhbHVlc107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb3B1bGF0ZUtleShcbiAgdGFibGVOYW1lOiBzdHJpbmcsXG4gIGZpZWxkTmFtZTogc3RyaW5nLFxuICBpZDogc3RyaW5nIHwgbnVtYmVyXG4pIHtcbiAgcmV0dXJuIFtQZXJzaXN0ZW5jZUtleXMuUE9QVUxBVEUsIHRhYmxlTmFtZSwgZmllbGROYW1lLCBpZF0uam9pbihcIi5cIik7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWNoZU1vZGVsRm9yUG9wdWxhdGU8TSBleHRlbmRzIE1vZGVsPihcbiAgY29udGV4dDogQ29udGV4dDxNPixcbiAgcGFyZW50TW9kZWw6IE0sXG4gIHByb3BlcnR5S2V5OiBzdHJpbmcsXG4gIHBrVmFsdWU6IHN0cmluZyB8IG51bWJlcixcbiAgY2FjaGVWYWx1ZTogYW55XG4pIHtcbiAgY29uc3QgY2FjaGVLZXkgPSBnZXRQb3B1bGF0ZUtleShcbiAgICBwYXJlbnRNb2RlbC5jb25zdHJ1Y3Rvci5uYW1lLFxuICAgIHByb3BlcnR5S2V5LFxuICAgIHBrVmFsdWVcbiAgKTtcbiAgcmV0dXJuIGNvbnRleHQucHV0KGNhY2hlS2V5LCBjYWNoZVZhbHVlKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBvcHVsYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIWRhdGEucG9wdWxhdGUpIHJldHVybjtcbiAgY29uc3QgbmVzdGVkOiBhbnkgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XTtcbiAgY29uc3QgaXNBcnIgPSBBcnJheS5pc0FycmF5KG5lc3RlZCk7XG4gIGlmICh0eXBlb2YgbmVzdGVkID09PSBcInVuZGVmaW5lZFwiIHx8IChpc0FyciAmJiBuZXN0ZWQubGVuZ3RoID09PSAwKSkgcmV0dXJuO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGZldGNoUG9wdWxhdGVWYWx1ZXMoXG4gICAgYzogQ29udGV4dDxNPixcbiAgICBtb2RlbDogTSxcbiAgICBwcm9wTmFtZTogc3RyaW5nLFxuICAgIHByb3BLZXlWYWx1ZXM6IGFueVtdXG4gICkge1xuICAgIGxldCBjYWNoZUtleTogc3RyaW5nO1xuICAgIGxldCB2YWw6IGFueTtcbiAgICBjb25zdCByZXN1bHRzOiBNW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHByb0tleVZhbHVlIG9mIHByb3BLZXlWYWx1ZXMpIHtcbiAgICAgIGNhY2hlS2V5ID0gZ2V0UG9wdWxhdGVLZXkobW9kZWwuY29uc3RydWN0b3IubmFtZSwgcHJvcE5hbWUsIHByb0tleVZhbHVlKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZhbCA9IGF3YWl0IGMuZ2V0KGNhY2hlS2V5KTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIGNvbnN0IHJlcG8gPSByZXBvc2l0b3J5RnJvbVR5cGVNZXRhZGF0YShtb2RlbCwgcHJvcE5hbWUpO1xuICAgICAgICBpZiAoIXJlcG8pIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiQ291bGQgbm90IGZpbmQgcmVwb1wiKTtcbiAgICAgICAgdmFsID0gYXdhaXQgcmVwby5yZWFkKHByb0tleVZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdHMucHVzaCh2YWwpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaFBvcHVsYXRlVmFsdWVzKFxuICAgIGNvbnRleHQsXG4gICAgbW9kZWwsXG4gICAga2V5LFxuICAgIGlzQXJyID8gbmVzdGVkIDogW25lc3RlZF1cbiAgKTtcbiAgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gPSBpc0FyciA/IHJlcyA6IHJlc1swXTtcbn1cblxuY29uc3QgY29tbW9tVHlwZXMgPSBbXG4gIFwiYXJyYXlcIixcbiAgXCJzdHJpbmdcIixcbiAgXCJudW1iZXJcIixcbiAgXCJib29sZWFuXCIsXG4gIFwic3ltYm9sXCIsXG4gIFwiZnVuY3Rpb25cIixcbiAgXCJvYmplY3RcIixcbiAgXCJ1bmRlZmluZWRcIixcbiAgXCJudWxsXCIsXG4gIFwiYmlnaW50XCIsXG5dO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVwb3NpdG9yeUZyb21UeXBlTWV0YWRhdGE8TSBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IGFueSxcbiAgcHJvcGVydHlLZXk6IHN0cmluZ1xuKTogUmVwbzxNPiB7XG4gIGNvbnN0IHR5cGVzID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICBWYWxpZGF0aW9uLmtleShcbiAgICAgIEFycmF5LmlzQXJyYXkobW9kZWxbcHJvcGVydHlLZXldKVxuICAgICAgICA/IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgOiBWYWxpZGF0aW9uS2V5cy5UWVBFXG4gICAgKSxcbiAgICBtb2RlbCxcbiAgICBwcm9wZXJ0eUtleVxuICApO1xuICBjb25zdCBjdXN0b21UeXBlczogYW55ID0gQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eUtleV0pXG4gICAgPyB0eXBlcy5jbGFzc1xuICAgIDogdHlwZXMuY3VzdG9tVHlwZXM7XG4gIGlmICghdHlwZXMgfHwgIWN1c3RvbVR5cGVzKVxuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBmaW5kIHR5cGVzIGRlY29yYXRvcnMgZm9yIHByb3BlcnR5ICR7cHJvcGVydHlLZXl9YFxuICAgICk7XG5cbiAgY29uc3QgYWxsb3dlZFR5cGVzOiBzdHJpbmdbXSA9IEFycmF5LmlzQXJyYXkoY3VzdG9tVHlwZXMpXG4gICAgPyBbLi4uY3VzdG9tVHlwZXNdXG4gICAgOiBbY3VzdG9tVHlwZXNdO1xuICBjb25zdCBjb25zdHJ1Y3Rvck5hbWUgPSBhbGxvd2VkVHlwZXMuZmluZChcbiAgICAodCkgPT4gIWNvbW1vbVR5cGVzLmluY2x1ZGVzKGAke3R9YC50b0xvd2VyQ2FzZSgpKVxuICApO1xuICBpZiAoIWNvbnN0cnVjdG9yTmFtZSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBQcm9wZXJ0eSBrZXkgJHtwcm9wZXJ0eUtleX0gZG9lcyBub3QgaGF2ZSBhIHZhbGlkIGNvbnN0cnVjdG9yIHR5cGVgXG4gICAgKTtcbiAgY29uc3QgY29uc3RydWN0b3I6IENvbnN0cnVjdG9yPE0+IHwgdW5kZWZpbmVkID0gTW9kZWwuZ2V0KGNvbnN0cnVjdG9yTmFtZSk7XG4gIGlmICghY29uc3RydWN0b3IpXG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIHJlZ2lzdGVyZWQgbW9kZWwgZm91bmQgZm9yICR7Y29uc3RydWN0b3JOYW1lfWApO1xuXG4gIHJldHVybiBSZXBvc2l0b3J5LmZvck1vZGVsKGNvbnN0cnVjdG9yKTtcbn1cbiIsImltcG9ydCB7XG4gIENvbmZsaWN0RXJyb3IsXG4gIG9uQ3JlYXRlLFxuICBvbkNyZWF0ZVVwZGF0ZSxcbiAgb25EZWxldGUsXG4gIG9uVXBkYXRlLFxuICBhZnRlckFueSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBhcHBseSwgbWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFBlcnNpc3RlbmNlS2V5cyB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9jb25zdGFudHNcIjtcbmltcG9ydCB7IENhc2NhZGVNZXRhZGF0YSwgSW5kZXhNZXRhZGF0YSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L3R5cGVzXCI7XG5pbXBvcnQgeyBEZWZhdWx0Q2FzY2FkZSwgT3JkZXJEaXJlY3Rpb24gfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBsaXN0LFxuICBNb2RlbCxcbiAgcHJvcCxcbiAgcHJvcE1ldGFkYXRhLFxuICB0eXBlLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL0FkYXB0ZXJcIjtcbmltcG9ydCB7IFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vcXVlcnkvQ29uZGl0aW9uXCI7XG5pbXBvcnQgeyBSZWxhdGlvbnNNZXRhZGF0YSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQge1xuICBvbmVUb01hbnlPbkNyZWF0ZSxcbiAgb25lVG9NYW55T25EZWxldGUsXG4gIG9uZVRvTWFueU9uVXBkYXRlLFxuICBvbmVUb09uZU9uQ3JlYXRlLFxuICBvbmVUb09uZU9uRGVsZXRlLFxuICBvbmVUb09uZU9uVXBkYXRlLFxuICBwb3B1bGF0ZSBhcyBwb3AsXG59IGZyb20gXCIuL2NvbnN0cnVjdGlvblwiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCIuL1VzZXJcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9Db250ZXh0XCI7XG5pbXBvcnQgeyBVbnN1cHBvcnRlZEVycm9yIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlL2Vycm9yc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gdGFibGUodGFibGVOYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIG1ldGFkYXRhKEFkYXB0ZXIua2V5KFBlcnNpc3RlbmNlS2V5cy5UQUJMRSksIHRhYmxlTmFtZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb2x1bW4oY29sdW1uTmFtZTogc3RyaW5nKSB7XG4gIHJldHVybiBwcm9wTWV0YWRhdGEoQWRhcHRlci5rZXkoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTiksIGNvbHVtbk5hbWUpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IEluZGV4IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIHByb3BlcnRpZXMgZGVjb3JhdGVkIHdpbGwgdGhlIGluZGV4IGluIHRoZVxuICogREIgZm9yIHBlcmZvcm1hbmNlIGluIHF1ZXJpZXNcbiAqXG4gKiBAcGFyYW0ge09yZGVyRGlyZWN0aW9uW119IFtkaXJlY3Rpb25zXVxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2NvbXBvc2l0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gaW5kZXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZGV4KGRpcmVjdGlvbnM/OiBPcmRlckRpcmVjdGlvbltdLCBjb21wb3NpdGlvbnM/OiBzdHJpbmdbXSkge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhKFxuICAgIFJlcG9zaXRvcnkua2V5KFxuICAgICAgYCR7UGVyc2lzdGVuY2VLZXlzLklOREVYfSR7Y29tcG9zaXRpb25zICYmIGNvbXBvc2l0aW9ucy5sZW5ndGggPyBgLiR7Y29tcG9zaXRpb25zLmpvaW4oXCIuXCIpfWAgOiBcIlwifWBcbiAgICApLFxuICAgIHtcbiAgICAgIGRpcmVjdGlvbnM6IGRpcmVjdGlvbnMsXG4gICAgICBjb21wb3NpdGlvbnM6IGNvbXBvc2l0aW9ucyxcbiAgICB9IGFzIEluZGV4TWV0YWRhdGFcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVuaXF1ZU9uQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBSZXBvPE0+LFxuICBZID0gYW55LFxuPih0aGlzOiBSLCBjb250ZXh0OiBDb250ZXh0PE0+LCBkYXRhOiBZLCBrZXk6IHN0cmluZywgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCEobW9kZWwgYXMgYW55KVtrZXldKSByZXR1cm47XG4gIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5zZWxlY3QoKVxuICAgIC53aGVyZShDb25kaXRpb24uYXR0cmlidXRlKGtleSkuZXEoKG1vZGVsIGFzIGFueSlba2V5XSkpXG4gICAgLmV4ZWN1dGU8TVtdPigpO1xuICBpZiAoZXhpc3RpbmcubGVuZ3RoKVxuICAgIHRocm93IG5ldyBDb25mbGljdEVycm9yKFxuICAgICAgYG1vZGVsIGFscmVhZHkgZXhpc3RzIHdpdGggcHJvcGVydHkgJHtrZXl9IGVxdWFsIHRvICR7SlNPTi5zdHJpbmdpZnkoKG1vZGVsIGFzIGFueSlba2V5XSwgdW5kZWZpbmVkLCAyKX1gXG4gICAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBVbmlxdWUgRGVjb3JhdG9yXG4gKiBAZGVzY3JpcHRpb24gVGFncyBhIHByb3BlcnR5IGFzIHVuaXF1ZS5cbiAqICBObyBvdGhlciBlbGVtZW50cyBpbiB0aGF0IHRhYmxlIGNhbiBoYXZlIHRoZSBzYW1lIHByb3BlcnR5IHZhbHVlXG4gKlxuICogQGZ1bmN0aW9uIHVuaXF1ZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6d2FsbGV0LWRiLkRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaXF1ZSgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIG9uQ3JlYXRlVXBkYXRlKHVuaXF1ZU9uQ3JlYXRlVXBkYXRlKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLlVOSVFVRSksIHt9KVxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIFJlcG88TT4sXG4gIFkgPSBhbnksXG4+KHRoaXM6IFIsIGNvbnRleHQ6IENvbnRleHQ8TT4sIGRhdGE6IFksIGtleTogc3RyaW5nLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB1c2VyOiBVc2VyIHwgdW5kZWZpbmVkID0gY29udGV4dC51c2VyO1xuICBpZiAoIXVzZXIpXG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICBcIlRoaXMgYWRhcHRlciBkb2VzIG5vdCBzdXBwb3J0IHVzZXIgaWRlbnRpZmljYXRpb25cIlxuICAgICk7XG4gIChtb2RlbCBhcyBhbnkpW2tleV0gPSB1c2VyLmlkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlZEJ5KCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgb25DcmVhdGUoY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGUpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSksIHt9KVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlZEJ5KCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgb25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25DcmVhdGVVcGRhdGUpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShQZXJzaXN0ZW5jZUtleXMuQ1JFQVRFRF9CWSksIHt9KVxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IE9uZSBUbyBPbmUgcmVsYXRpb24gRGVjb3JhdG9yc1xuICpcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gcG9wdWxhdGUgSWYgdHJ1ZSwgcmVwbGFjZXMgdGhlIHNwZWNpZmllZCBrZXkgaW4gdGhlIGRvY3VtZW50IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgcmVjb3JkIGZyb20gdGhlIGRhdGFiYXNlXG4gKlxuICogQGZ1bmN0aW9uIG9uVG9PbmVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOndhbGxldC1kYi5EZWNvcmF0b3JzXG4gKlxuICogQHNlZSBvbmVUb01hbnlcbiAqIEBzZWUgbWFueVRvT25lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVUb09uZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gIGNhc2NhZGVPcHRpb25zOiBDYXNjYWRlTWV0YWRhdGEgPSBEZWZhdWx0Q2FzY2FkZSxcbiAgcG9wdWxhdGU6IGJvb2xlYW4gPSB0cnVlXG4pIHtcbiAgTW9kZWwucmVnaXN0ZXIoY2xhenopO1xuICBjb25zdCBtZXRhZGF0YTogUmVsYXRpb25zTWV0YWRhdGEgPSB7XG4gICAgY2xhc3M6IGNsYXp6Lm5hbWUsXG4gICAgY2FzY2FkZTogY2FzY2FkZU9wdGlvbnMsXG4gICAgcG9wdWxhdGU6IHBvcHVsYXRlLFxuICB9O1xuICByZXR1cm4gYXBwbHkoXG4gICAgcHJvcChQZXJzaXN0ZW5jZUtleXMuUkVMQVRJT05TKSxcbiAgICB0eXBlKFtjbGF6ei5uYW1lLCBTdHJpbmcubmFtZSwgTnVtYmVyLm5hbWUsIEJpZ0ludC5uYW1lXSksXG4gICAgb25DcmVhdGUob25lVG9PbmVPbkNyZWF0ZSwgbWV0YWRhdGEpLFxuICAgIG9uVXBkYXRlKG9uZVRvT25lT25VcGRhdGUsIG1ldGFkYXRhKSxcbiAgICBvbkRlbGV0ZShvbmVUb09uZU9uRGVsZXRlLCBtZXRhZGF0YSksXG4gICAgYWZ0ZXJBbnkocG9wLCBtZXRhZGF0YSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5PTkVfVE9fT05FKSwgbWV0YWRhdGEpXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgT25lIFRvIE1hbnkgcmVsYXRpb24gRGVjb3JhdG9yc1xuICpcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gb25lVG9NYW55XG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuICpcbiAqIEBzZWUgb25lVG9PbmVcbiAqIEBzZWUgbWFueVRvT25lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbmVUb01hbnk8TSBleHRlbmRzIE1vZGVsPihcbiAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4gIHBvcHVsYXRlOiBib29sZWFuID0gdHJ1ZVxuKSB7XG4gIE1vZGVsLnJlZ2lzdGVyKGNsYXp6KTtcbiAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgIGNsYXNzOiBjbGF6ei5uYW1lLFxuICAgIGNhc2NhZGU6IGNhc2NhZGVPcHRpb25zLFxuICAgIHBvcHVsYXRlOiBwb3B1bGF0ZSxcbiAgfTtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIHByb3AoUGVyc2lzdGVuY2VLZXlzLlJFTEFUSU9OUyksXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBwdXJwb3NlZnVsIG92ZXJyaWRlXG4gICAgbGlzdChbY2xhenosIFN0cmluZywgTnVtYmVyLCBCaWdJbnRdKSxcbiAgICBvbkNyZWF0ZShvbmVUb01hbnlPbkNyZWF0ZSwgbWV0YWRhdGEpLFxuICAgIG9uVXBkYXRlKG9uZVRvTWFueU9uVXBkYXRlLCBtZXRhZGF0YSksXG4gICAgb25EZWxldGUob25lVG9NYW55T25EZWxldGUsIG1ldGFkYXRhKSxcbiAgICBhZnRlckFueShwb3AsIG1ldGFkYXRhKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoUGVyc2lzdGVuY2VLZXlzLk9ORV9UT19NQU5ZKSwgbWV0YWRhdGEpXG4gICk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgTWFueSBUbyBPbmUgcmVsYXRpb24gRGVjb3JhdG9yc1xuICpcbiAqIEBwYXJhbSB7Q29uc3RydWN0b3I8YW55Pn0gY2xhenogdGhlIHtAbGluayBTZXF1ZW5jZX0gdG8gdXNlLiBEZWZhdWx0cyB0byB7QGxpbmsgTm9uZVNlcXVlbmNlfVxuICogQHBhcmFtIHtDYXNjYWRlTWV0YWRhdGF9IFtjYXNjYWRlT3B0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gbWFueVRvT25lXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTp3YWxsZXQtZGIuRGVjb3JhdG9yc1xuICpcbiAqIEBzZWUgb25lVG9NYW55XG4gKiBAc2VlIG9uZVRvT25lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYW55VG9PbmUoXG4gIGNsYXp6OiBDb25zdHJ1Y3Rvcjxhbnk+LFxuICBjYXNjYWRlT3B0aW9uczogQ2FzY2FkZU1ldGFkYXRhID0gRGVmYXVsdENhc2NhZGUsXG4gIHBvcHVsYXRlID0gdHJ1ZVxuKSB7XG4gIE1vZGVsLnJlZ2lzdGVyKGNsYXp6KTtcbiAgY29uc3QgbWV0YWRhdGE6IFJlbGF0aW9uc01ldGFkYXRhID0ge1xuICAgIGNsYXNzOiBjbGF6ei5uYW1lLFxuICAgIGNhc2NhZGU6IGNhc2NhZGVPcHRpb25zLFxuICAgIHBvcHVsYXRlOiBwb3B1bGF0ZSxcbiAgfTtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIHByb3AoUGVyc2lzdGVuY2VLZXlzLlJFTEFUSU9OUyksXG4gICAgdHlwZShbY2xhenoubmFtZSwgU3RyaW5nLm5hbWUsIE51bWJlci5uYW1lLCBCaWdJbnQubmFtZV0pLFxuICAgIC8vIG9uQ3JlYXRlKG9uZVRvTWFueU9uQ3JlYXRlLCBtZXRhZGF0YSksXG4gICAgLy8gb25VcGRhdGUob25lVG9NYW55T25VcGRhdGUsIG1ldGFkYXRhKSxcbiAgICAvLyBvbkRlbGV0ZShvbmVUb01hbnlPbkRlbGV0ZSwgbWV0YWRhdGEpLFxuICAgIC8vIGFmdGVyQWxsKHBvcHVsYXRlLCBtZXRhZGF0YSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KFBlcnNpc3RlbmNlS2V5cy5NQU5ZX1RPX09ORSksIG1ldGFkYXRhKVxuICApO1xufVxuIiwiaW1wb3J0IHsgTW9kZWwsIHByb3BNZXRhZGF0YSwgcmVxdWlyZWQgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge1xuICBEZWZhdWx0U2VxdWVuY2VPcHRpb25zLFxuICBTZXF1ZW5jZU9wdGlvbnMsXG59IGZyb20gXCIuLi9pbnRlcmZhY2VzL1NlcXVlbmNlT3B0aW9uc1wiO1xuaW1wb3J0IHtcbiAgREJLZXlzLFxuICBJbnRlcm5hbEVycm9yLFxuICBvbkNyZWF0ZSxcbiAgcmVhZG9ubHksXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFJlcG8sIFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBpbmRleCB9IGZyb20gXCIuLi9tb2RlbC9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBzZXF1ZW5jZU5hbWVGb3JNb2RlbCB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZSB9IGZyb20gXCIuLi9wZXJzaXN0ZW5jZS9TZXF1ZW5jZVwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgT3JkZXJEaXJlY3Rpb24gfSBmcm9tIFwiLi4vcmVwb3NpdG9yeVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFByaW1hcnkgS2V5IERlY29yYXRvclxuICogQGRlc2NyaXB0aW9uIE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyB0aGUge0BsaW5rIE1vZGVsfXMgcHJpbWFyeSBrZXkuXG4gKiAgQWxzbyBtYXJrcyB0aGUgcHJvcGVydHkgYXMge0BsaW5rIHVuaXF1ZX0gYXMge0ByZXF1aXJlZH0gYW5kIGVuc3VyZXMgdGhlIGluZGV4IGlzIGNyZWF0ZWQgcHJvcGVybHkgYWNjb3JkaW5nIHRvIHRoZSBwcm92aWRlZCB7QGxpbmsgU2VxdWVuY2V9XG4gKlxuICpcbiAqXG4gKiBAZnVuY3Rpb24gcGtcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOndhbGxldC1kYi5EZWNvcmF0b3JzXG4gKlxuICogQHNlZSB1bmlxdWVcbiAqIEBzZWUgcmVxdWlyZWRcbiAqIEBzZWUgb25cbiAqIEBwYXJhbSBkYXRhXG4gKiBAcGFyYW0ga2V5XG4gKiBAcGFyYW0gbW9kZWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBrT25DcmVhdGU8TSBleHRlbmRzIE1vZGVsLCBWIGV4dGVuZHMgUmVwbzxNPj4oXG4gIHRoaXM6IFYsXG4gIGNvbnRleHQ6IENvbnRleHQ8TT4sXG4gIGRhdGE6IFNlcXVlbmNlT3B0aW9ucyxcbiAga2V5OiBzdHJpbmcsXG4gIG1vZGVsOiBNXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFkYXRhLnR5cGUgfHwgKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzZXRQcmltYXJ5S2V5VmFsdWUgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPihcbiAgICB0YXJnZXQ6IE0sXG4gICAgcHJvcGVydHlLZXk6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50XG4gICkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgIH0pO1xuICB9O1xuICBpZiAoIWRhdGEubmFtZSkgZGF0YS5uYW1lID0gc2VxdWVuY2VOYW1lRm9yTW9kZWwobW9kZWwsIFwicGtcIik7XG4gIGxldCBzZXF1ZW5jZTogU2VxdWVuY2U7XG4gIHRyeSB7XG4gICAgc2VxdWVuY2UgPSBhd2FpdCB0aGlzLmFkYXB0ZXIuU2VxdWVuY2UoZGF0YSk7XG4gIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBpbnN0YW50aWF0ZSBTZXF1ZW5jZSAke2RhdGEubmFtZX06ICR7ZX1gXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG5leHQgPSBhd2FpdCBzZXF1ZW5jZS5uZXh0KCk7XG4gIHNldFByaW1hcnlLZXlWYWx1ZShtb2RlbCwga2V5LCBuZXh0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBrKFxuICBvcHRzOiBPbWl0PFxuICAgIFNlcXVlbmNlT3B0aW9ucyxcbiAgICBcImN5Y2xlXCIgfCBcInN0YXJ0V2l0aFwiIHwgXCJpbmNyZW1lbnRCeVwiXG4gID4gPSBEZWZhdWx0U2VxdWVuY2VPcHRpb25zXG4pIHtcbiAgb3B0cyA9IE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRTZXF1ZW5jZU9wdGlvbnMsIG9wdHMpIGFzIFNlcXVlbmNlT3B0aW9ucztcbiAgcmV0dXJuIGFwcGx5KFxuICAgIGluZGV4KFtPcmRlckRpcmVjdGlvbi5BU0MsIE9yZGVyRGlyZWN0aW9uLkRTQ10pLFxuICAgIHJlcXVpcmVkKCksXG4gICAgcmVhZG9ubHkoKSxcbiAgICAvLyB0eXBlKFtTdHJpbmcubmFtZSwgTnVtYmVyLm5hbWUsIEJpZ0ludC5uYW1lXSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5JRCksIG9wdHMgYXMgU2VxdWVuY2VPcHRpb25zKSxcbiAgICBvbkNyZWF0ZShwa09uQ3JlYXRlLCBvcHRzIGFzIFNlcXVlbmNlT3B0aW9ucylcbiAgKTtcbn1cbiIsImltcG9ydCB7IERCT3BlcmF0aW9ucywgdGltZXN0YW1wIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNb2RlbEFyZywgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlTW9kZWwgZXh0ZW5kcyBNb2RlbCB7XG4gIEB0aW1lc3RhbXAoREJPcGVyYXRpb25zLkNSRUFURSlcbiAgY3JlYXRlZE9uITogRGF0ZTtcbiAgQHRpbWVzdGFtcCgpXG4gIHVwZGF0ZWRPbiE6IERhdGU7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGFyZz86IE1vZGVsQXJnPEJhc2VNb2RlbD4pIHtcbiAgICBzdXBlcihhcmcpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBsaXN0LCBtb2RlbCwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgdHlwZSB7IE1vZGVsQXJnIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUm9sZXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBwayB9IGZyb20gXCIuLi9pZGVudGl0eS9kZWNvcmF0b3JzXCI7XG5cbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgVXNlciBleHRlbmRzIE1vZGVsIHtcbiAgQHBrKClcbiAgaWQhOiBzdHJpbmc7XG5cbiAgQGxpc3QoW1N0cmluZ10pXG4gIHJvbGVzPzogKHN0cmluZyB8IFJvbGVzKVtdO1xuXG4gIEBsaXN0KFtTdHJpbmddKVxuICBhZmZpbGlhdGlvbnM/OiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3Rvcihhcmc/OiBNb2RlbEFyZzxVc2VyPikge1xuICAgIHN1cGVyKGFyZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIHByb3BNZXRhZGF0YSxcbiAgVmFsaWRhdGlvbixcbiAgVmFsaWRhdGlvbktleXMsXG4gIFZhbGlkYXRpb25NZXRhZGF0YSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUGVyc2lzdGVuY2VLZXlzIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShERUZBVUxUX0VSUk9SX01FU1NBR0VTLCBQZXJzaXN0ZW5jZUtleXMuQ0xBVVNFX1NFUVVFTkNFLCB7XG4gIHZhbHVlOiBcIkludmFsaWQgY2xhdXNlIHNlcXVlbmNlOiB7MH1cIixcbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoVmFsaWRhdGlvbktleXMsIFwiQ0xBVVNFX1NFUVVFTkNFXCIsIHtcbiAgdmFsdWU6IFBlcnNpc3RlbmNlS2V5cy5DTEFVU0VfU0VRVUVOQ0UsXG59KTtcblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXVxuICpcbiAqIEBmdW5jdGlvbiBjbGF1c2VTZXF1ZW5jZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKiBAc3ViY2F0ZWdvcnkgVmFsaWRhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhdXNlU2VxdWVuY2UobWVzc2FnZT86IHN0cmluZykge1xuICByZXR1cm4gcHJvcE1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT4oXG4gICAgVmFsaWRhdGlvbi5rZXkoVmFsaWRhdGlvbktleXMuUkVRVUlSRUQpLFxuICAgIHtcbiAgICAgIG1lc3NhZ2U6XG4gICAgICAgIG1lc3NhZ2UgfHxcbiAgICAgICAgKChERUZBVUxUX0VSUk9SX01FU1NBR0VTIGFzIGFueSlbXG4gICAgICAgICAgUGVyc2lzdGVuY2VLZXlzLkNMQVVTRV9TRVFVRU5DRSBhcyBhbnlcbiAgICAgICAgXSBhcyBzdHJpbmcpLFxuICAgIH1cbiAgKTtcbn1cbiIsImltcG9ydCB7XG4gIERFRkFVTFRfRVJST1JfTUVTU0FHRVMsXG4gIHNmLFxuICB2YWxpZGF0b3IsXG4gIFZhbGlkYXRvcixcbiAgVmFsaWRhdG9yT3B0aW9ucyxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgaXNFcXVhbCB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgQ2xhdXNlIH0gZnJvbSBcIi4uL3F1ZXJ5L0NsYXVzZVwiO1xuaW1wb3J0IHsgTWFuZGF0b3J5UHJpb3JpdGllcyB9IGZyb20gXCIuLi9xdWVyeS9jb25zdGFudHNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi4vcXVlcnkvZXJyb3JzXCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2UvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVmFsaWRhdGVzIGEge0BsaW5rIFNlcXVlbmNlfSdzIHtAbGluayBDbGF1c2V9c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV1cbiAqXG4gKiBAY2xhc3MgQ2xhdXNlU2VxdWVuY2VWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0aW9uXG4gKiBAc3ViY2F0ZWdvcnkgVmFsaWRhdG9yc1xuICovXG5AdmFsaWRhdG9yKFBlcnNpc3RlbmNlS2V5cy5DTEFVU0VfU0VRVUVOQ0UpXG5leHBvcnQgY2xhc3MgQ2xhdXNlU2VxdWVuY2VWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcgPSBERUZBVUxUX0VSUk9SX01FU1NBR0VTW1BlcnNpc3RlbmNlS2V5cy5DTEFVU0VfU0VRVUVOQ0VdXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZVNlcXVlbmNlKFxuICAgIGNsYXVzZXM6IENsYXVzZTxhbnk+W10sXG4gICAgbWVzc2FnZT86IHN0cmluZ1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBNYW5kYXRvcnlQcmlvcml0aWVzLmV2ZXJ5KFxuICAgICAgKHApID0+ICEhY2xhdXNlcy5maW5kKChjKSA9PiBjLmdldFByaW9yaXR5KCkgPT09IHApXG4gICAgKVxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIHNmKG1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBcIk1pc3NpbmcgcmVxdWlyZWQgQ2xhdXNlIFByaW9yaXRpZXNcIilcbiAgICAgICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWZXJpZmllcyB0aGUgbW9kZWwgZm9yIGVycm9yc1xuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICogQHBhcmFtIHtWYWxpZGF0b3JPcHRpb25zfSBbb3B0aW9uc11cbiAgICpcbiAgICogQHJldHVybiBFcnJvcnNcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqXG4gICAqIEBzZWUgVmFsaWRhdG9yXG4gICAqL1xuICBwdWJsaWMgaGFzRXJyb3JzKHZhbHVlOiBhbnksIG9wdGlvbnM/OiBWYWxpZGF0b3JPcHRpb25zKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgaWYgKFxuICAgICAgICAhdmFsdWUgfHxcbiAgICAgICAgIUFycmF5LmlzQXJyYXkodmFsdWUpIHx8XG4gICAgICAgICF2YWx1ZS5sZW5ndGggfHxcbiAgICAgICAgIXZhbHVlLmV2ZXJ5KChlKSA9PiBlIGluc3RhbmNlb2YgQ2xhdXNlKVxuICAgICAgKVxuICAgICAgICByZXR1cm4gdGhpcy5nZXRNZXNzYWdlKFxuICAgICAgICAgIHNmKFxuICAgICAgICAgICAgKG9wdGlvbnMgfHwge30pLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLFxuICAgICAgICAgICAgXCJObyBvciBpbnZhbGlkIENsYXVzZXMgZm91bmRcIlxuICAgICAgICAgIClcbiAgICAgICAgKTtcblxuICAgICAgY29uc3QgY2xhdXNlczogQ2xhdXNlPGFueT5bXSA9IHZhbHVlIGFzIENsYXVzZTxhbnk+W107XG5cbiAgICAgIGNvbnN0IGNsYXVzZUVycm9ycyA9IGNsYXVzZXMucmVkdWNlKFxuICAgICAgICAoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgYzogQ2xhdXNlPGFueT4pID0+IHtcbiAgICAgICAgICBjb25zdCBlcnJzID0gYy5oYXNFcnJvcnMoKTtcbiAgICAgICAgICBpZiAoZXJycylcbiAgICAgICAgICAgIGlmIChhY2N1bSlcbiAgICAgICAgICAgICAgYWNjdW0gKz0gc2YoXG4gICAgICAgICAgICAgICAgXCJcXG5DbGF1c2UgezB9OiB7MX1cIixcbiAgICAgICAgICAgICAgICBjLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgZXJycy50b1N0cmluZygpXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIGFjY3VtID0gc2YoXG4gICAgICAgICAgICAgICAgXCJDbGF1c2UgezB9OiB7MX1cIixcbiAgICAgICAgICAgICAgICBjLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgICAgICAgICAgICAgZXJycy50b1N0cmluZygpXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICB9LFxuICAgICAgICB1bmRlZmluZWRcbiAgICAgICk7XG5cbiAgICAgIGlmIChjbGF1c2VFcnJvcnMpXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgc2YoKG9wdGlvbnMgfHwge30pLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBjbGF1c2VFcnJvcnMudG9TdHJpbmcoKSlcbiAgICAgICAgKTtcblxuICAgICAgY29uc3QgdmVyaWZ5UHJpb3JpdHkgPSAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByaW9yaXRpZXMgPSBjbGF1c2VzLm1hcCgoYykgPT4gYy5nZXRQcmlvcml0eSgpKTtcbiAgICAgICAgY29uc3QgYWxsVW5pcXVlID0gbmV3IFNldChwcmlvcml0aWVzKS5zaXplID09PSBwcmlvcml0aWVzLmxlbmd0aDtcbiAgICAgICAgaWYgKCFhbGxVbmlxdWUpIHJldHVybiBcIk5vdCBhbGwgY2xhdXNlcyAgaGF2ZSB1bmlxdWUgcHJpb3JpdGllc1wiO1xuICAgICAgICBjb25zdCBzb3J0ZWQgPSBwcmlvcml0aWVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICByZXR1cm4gYiAtIGE7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBpc0VxdWFsKHByaW9yaXRpZXMsIHNvcnRlZClcbiAgICAgICAgICA/IHRydWVcbiAgICAgICAgICA6IFwiQ2xhdXNlcyAgYXJlIG5vdCBwcm9wZXJseSBzb3J0ZWRcIjtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByaW9yaXR5Q2hlY2sgPSB2ZXJpZnlQcmlvcml0eSgpO1xuICAgICAgaWYgKHByaW9yaXR5Q2hlY2sgIT09IHRydWUpXG4gICAgICAgIHJldHVybiB0aGlzLmdldE1lc3NhZ2UoXG4gICAgICAgICAgc2YoKG9wdGlvbnMgfHwge30pLm1lc3NhZ2UgfHwgdGhpcy5tZXNzYWdlLCBcIkludmFsaWQgcHJpb3JpdGl6YXRpb25cIilcbiAgICAgICAgKTtcblxuICAgICAgY29uc3Qgc2VxdWVuY2VDaGVjayA9IHRoaXMudmFsaWRhdGVTZXF1ZW5jZShcbiAgICAgICAgY2xhdXNlcyxcbiAgICAgICAgKG9wdGlvbnMgfHwge30pLm1lc3NhZ2VcbiAgICAgICk7XG4gICAgICBpZiAoc2VxdWVuY2VDaGVjaylcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0TWVzc2FnZShcbiAgICAgICAgICBzZigob3B0aW9ucyB8fCB7fSkubWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UsIFwiSW52YWxpZCBzZXF1ZW5jZVwiKVxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoXG4gICAgICAgIHNmKFwiRmFpbGVkIHRvIHZlcmlmeSBjbGF1c2Ugc2VxdWVuY2UgezB9OiB7MX1cIiwgdmFsdWUsIGUpXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHR5cGUgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIG1pbmxlbmd0aCxcbiAgTW9kZWwsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICByZXF1aXJlZCxcbiAgdHlwZSxcbiAgc2YsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEV4ZWN1dG9yLCBSYXdFeGVjdXRvciB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBNYW5kYXRvcnlQcmlvcml0aWVzLCBTdGF0ZW1lbnRUeXBlIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBRdWVyeUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBDbGF1c2UgfSBmcm9tIFwiLi9DbGF1c2VcIjtcbmltcG9ydCB7IGNsYXVzZVNlcXVlbmNlIH0gZnJvbSBcIi4uL3ZhbGlkYXRvcnNcIjtcbmltcG9ydCB7IEFkYXB0ZXIgfSBmcm9tIFwiLi4vcGVyc2lzdGVuY2VcIjtcbmltcG9ydCB7IGZpbmRQcmltYXJ5S2V5LCBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBQYWdpbmF0b3IgfSBmcm9tIFwiLi9QYWdpbmF0b3JcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBTdGF0ZW1lbnQgQ2xhc3NcbiAqIEBkZXNjcmlwdGlvbiBob2xkcyBhbGwgdGhlIGNsYXVzZXMgdW50aWwgdGhleSBjYW4gYmUgcHJvY2Vzc2VkXG4gKlxuICogQHBhcmFtIHtNb2RlbEFyZ30gW3N0YXRlbWVudF1cbiAqXG4gKiBAY2xhc3MgU3RhdGVtZW50XG4gKiBAZXh0ZW5kcyBNb2RlbFxuICogQGltcGxlbWVudHMgRXhlY3V0b3JcbiAqIEBpbXBsZW1lbnRzIFJhd0V4ZWN1dG9yXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTdGF0ZW1lbnQ8UT5cbiAgZXh0ZW5kcyBNb2RlbFxuICBpbXBsZW1lbnRzIEV4ZWN1dG9yLCBSYXdFeGVjdXRvcjxRPlxue1xuICBAcmVxdWlyZWQoKVxuICBAbWlubGVuZ3RoKE1hbmRhdG9yeVByaW9yaXRpZXMubGVuZ3RoKVxuICBAY2xhdXNlU2VxdWVuY2UoKVxuICBwcm90ZWN0ZWQgY2xhdXNlcz86IENsYXVzZTxhbnk+W10gPSB1bmRlZmluZWQ7XG4gIEByZXF1aXJlZCgpXG4gIEB0eXBlKFtcIm9iamVjdFwiXSlcbiAgcHJvdGVjdGVkIGFkYXB0ZXI6IEFkYXB0ZXI8YW55LCBRPjtcbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIHRhcmdldD86IENvbnN0cnVjdG9yPGFueT4gPSB1bmRlZmluZWQ7XG5cbiAgcHJvdGVjdGVkIGZ1bGxSZWNvcmQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgdHlwZT86IHN0cmluZyA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoZGI6IEFkYXB0ZXI8YW55LCBRPikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hZGFwdGVyID0gZGI7XG4gIH1cblxuICBwcm90ZWN0ZWQgYnVpbGQoKTogUSB7XG4gICAgaWYgKCF0aGlzLmNsYXVzZXMpXG4gICAgICB0aHJvdyBuZXcgUXVlcnlFcnJvcihzZihcIkZhaWxlZCB0byBidWlsZCBTdGF0ZW1lbnQ6XFxuezB9XCIsIFwiTm8gQ2xhdXNlc1wiKSk7XG4gICAgdGhpcy5jbGF1c2VzLnNvcnQoKGMxLCBjMikgPT4ge1xuICAgICAgcmV0dXJuIGMxLmdldFByaW9yaXR5KCkgLSBjMi5nZXRQcmlvcml0eSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZXJyb3JzID0gdGhpcy5oYXNFcnJvcnMoKTtcbiAgICBpZiAoZXJyb3JzKVxuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoXG4gICAgICAgIHNmKFwiUG9vcmx5IGJ1aWx0IHN0YXRlbWVudDogezB9XCIsIGVycm9ycy50b1N0cmluZygpKVxuICAgICAgKTtcblxuICAgIGxldCBxdWVyeTogUTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgaXRlcmF0b3IgPSBmdW5jdGlvbiAoXG4gICAgICAgIGNsYXVzZXM6IENsYXVzZTxhbnk+W10sXG4gICAgICAgIHByZXZpb3VzOiBhbnkgPSB7fVxuICAgICAgKTogUSB7XG4gICAgICAgIGNvbnN0IGMgPSBjbGF1c2VzLnNoaWZ0KCk7XG4gICAgICAgIGlmICghYykgcmV0dXJuIHByZXZpb3VzIGFzIFE7XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBjLmJ1aWxkKHByZXZpb3VzKTtcbiAgICAgICAgcmV0dXJuIGl0ZXJhdG9yKGNsYXVzZXMsIHJlc3VsdHMgYXMgYW55KTtcbiAgICAgIH07XG5cbiAgICAgIHF1ZXJ5ID0gaXRlcmF0b3IobmV3IEFycmF5KC4uLih0aGlzLmNsYXVzZXMgYXMgQ2xhdXNlPFE+W10pKSkgYXMgUTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBRdWVyeUVycm9yKGUpO1xuICAgIH1cblxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZTxZPigpOiBQcm9taXNlPFk+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnk6IFEgPSB0aGlzLmJ1aWxkKCk7XG4gICAgICByZXR1cm4gdGhpcy5yYXcocXVlcnkpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBhYnN0cmFjdCBwYWdpbmF0ZTxZPihzaXplOiBudW1iZXIpOiBQcm9taXNlPFBhZ2luYXRvcjxZLCBRPj47XG5cbiAgYXN5bmMgcmF3PFI+KHJhd0lucHV0OiBRLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8Uj4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmF3PFI+KHJhd0lucHV0LCB0cnVlLCAuLi5hcmdzKTtcbiAgICBpZiAoIXRoaXMuZnVsbFJlY29yZCkgcmV0dXJuIHJlc3VsdHM7XG4gICAgaWYgKCF0aGlzLnRhcmdldClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICBcIk5vIHRhcmdldCBkZWZpbmVkIGluIHN0YXRlbWVudC4gc2hvdWxkIG5ldmVyIGhhcHBlblwiXG4gICAgICApO1xuXG4gICAgY29uc3QgcGtBdHRyID0gZmluZFByaW1hcnlLZXkobmV3IHRoaXMudGFyZ2V0KCkgYXMgYW55KS5pZDtcblxuICAgIGNvbnN0IHByb2Nlc3NvciA9IGZ1bmN0aW9uIHJlY29yZFByb2Nlc3Nvcih0aGlzOiBTdGF0ZW1lbnQ8UT4sIHI6IGFueSkge1xuICAgICAgY29uc3QgaWQgPSByW3BrQXR0cl07XG4gICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnJldmVydChcbiAgICAgICAgcixcbiAgICAgICAgdGhpcy50YXJnZXQgYXMgQ29uc3RydWN0b3I8YW55PixcbiAgICAgICAgcGtBdHRyLFxuICAgICAgICBpZFxuICAgICAgKSBhcyBhbnk7XG4gICAgfS5iaW5kKHRoaXMpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0cykpIHJldHVybiByZXN1bHRzLm1hcChwcm9jZXNzb3IpIGFzIFI7XG4gICAgcmV0dXJuIHByb2Nlc3NvcihyZXN1bHRzKSBhcyBSO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBoYXNFcnJvcnMoLi4uZXhjZXB0aW9uczogc3RyaW5nW10pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZXJyb3JzID0gc3VwZXIuaGFzRXJyb3JzKC4uLmV4Y2VwdGlvbnMpO1xuICAgIGlmIChlcnJvcnMpIHJldHVybiBlcnJvcnM7XG5cbiAgICBmb3IgKGNvbnN0IGkgaW4gdGhpcy5jbGF1c2VzKSB7XG4gICAgICBjb25zdCBlcnIgPSB0aGlzLmNsYXVzZXNbaSBhcyBhbnldLmhhc0Vycm9ycygpO1xuICAgICAgaWYgKGVycikgcmV0dXJuIGVycjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHN1bW1hcnkgQWRkcyBhIGNsYXVzZSB0byB0aGUgU3RhdGVtZW50XG4gICAqIEBwYXJhbSB7Q2xhdXNlfSBjbGF1c2VcbiAgICovXG4gIGFkZENsYXVzZShjbGF1c2U6IENsYXVzZTxRPikge1xuICAgIGlmICghdGhpcy5jbGF1c2VzKSB0aGlzLmNsYXVzZXMgPSBbXTtcblxuICAgIGNvbnN0IHByaW9yaXR5ID0gY2xhdXNlLmdldFByaW9yaXR5KCk7XG4gICAgY29uc3QgY3VycmVudFByaW9yaXR5ID0gdGhpcy5jbGF1c2VzXG4gICAgICAubWFwKChjLCBpKSA9PiAoeyBpbmRleDogaSwgY2xhdXNlOiBjIH0pKVxuICAgICAgLmZpbmQoKGMpID0+IGMuY2xhdXNlLmdldFByaW9yaXR5KCkgPT09IHByaW9yaXR5KTtcbiAgICBpZiAoY3VycmVudFByaW9yaXR5KSB7XG4gICAgICB0aGlzLmNsYXVzZXNbY3VycmVudFByaW9yaXR5LmluZGV4XSA9IGNsYXVzZTtcbiAgICB9XG4gICAgdGhpcy5jbGF1c2VzLnB1c2goY2xhdXNlKTtcbiAgfVxuXG4gIGdldEFkYXB0ZXIoKTogQWRhcHRlcjxhbnksIFE+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIG91dHB1dCBjbGFzcyAod2hlbiBleGlzdGluZylcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gY2xhenpcbiAgICovXG4gIHNldFRhcmdldChjbGF6ejogQ29uc3RydWN0b3I8YW55Pikge1xuICAgIGlmICh0aGlzLnRhcmdldClcbiAgICAgIHRocm93IG5ldyBRdWVyeUVycm9yKFxuICAgICAgICBzZihcIk91dHB1dCBjbGFzcyBhbHJlYWR5IGRlZmluZWQgdG8gezB9XCIsIHRoaXMudGFyZ2V0IS5uYW1lKVxuICAgICAgKTtcbiAgICB0aGlzLnRhcmdldCA9IGNsYXp6O1xuICB9XG5cbiAgZ2V0VGFyZ2V0KCkge1xuICAgIGlmICghdGhpcy50YXJnZXQpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk5vIHRhcmdldCBkZWZpbmVkIGZvciBzdGF0ZW1lbnRcIik7XG4gICAgcmV0dXJuIHRoaXMudGFyZ2V0O1xuICB9XG5cbiAgc2V0RnVsbFJlY29yZCgpIHtcbiAgICB0aGlzLmZ1bGxSZWNvcmQgPSB0cnVlO1xuICB9XG5cbiAgc2V0TW9kZSh0eXBlOiBTdGF0ZW1lbnRUeXBlKSB7XG4gICAgdGhpcy50eXBlID0gdHlwZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgRXhlY3V0b3IgfSBmcm9tIFwiLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHtcbiAgTW9kZWwsXG4gIE1vZGVsQXJnLFxuICByZXF1aXJlZCxcbiAgdHlwZSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUXVlcnlCdWlsZGVyIH0gZnJvbSBcIi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgUXVlcnlFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgUHJpb3JpdHkgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFN0YXRlbWVudCB9IGZyb20gXCIuL1N0YXRlbWVudFwiO1xuaW1wb3J0IHsgUGFnaW5hdGFibGUgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9QYWdpbmF0YWJsZVwiO1xuaW1wb3J0IHsgUGFnaW5hdG9yIH0gZnJvbSBcIi4vUGFnaW5hdG9yXCI7XG5cbi8qKlxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgQ2xhdXNlIENsYXNzXG4gKiBAZGVzY3JpcHRpb24gUmVwcmVzZW50cyBhIENsYXVzZSBpbiBhIHtAbGluayBTdGF0ZW1lbnR9XG4gKlxuICogQHR5cGVkZWYgUSBSZXByZXNlbnRzIHF1ZSBxdWVyeSBvYmplY3QgdGhlIHBlcnNpc3RlbmNlIGFkYXB0ZXIgdXNlc1xuICpcbiAqIEBwYXJhbSB7TW9kZWxBcmc8Q2xhdXNlPFE+Pn0gW2NsYXVzZV1cbiAqXG4gKiBAY2xhc3MgQ2xhdXNlXG4gKiBAZXh0ZW5kcyBNb2RlbFxuICogQGltcGxlbWVudHMgRXhlY3V0b3JcbiAqIEBpbXBsZW1lbnRzIFF1ZXJ5QnVpbGRlclxuICogQGFic3RyYWN0XG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ2xhdXNlPFE+XG4gIGV4dGVuZHMgTW9kZWxcbiAgaW1wbGVtZW50cyBFeGVjdXRvciwgUGFnaW5hdGFibGUsIFF1ZXJ5QnVpbGRlcjxRPlxue1xuICBAcmVxdWlyZWQoKVxuICByZWFkb25seSBwcmlvcml0eSE6IFByaW9yaXR5O1xuXG4gIEByZXF1aXJlZCgpXG4gIEB0eXBlKFwib2JqZWN0XCIpXG4gIHJlYWRvbmx5IHN0YXRlbWVudCE6IFN0YXRlbWVudDxRPjtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8Q2xhdXNlPFE+Pikge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5wcmlvcml0eSA9IGNsYXVzZT8ucHJpb3JpdHk7XG4gICAgdGhpcy5zdGF0ZW1lbnQgPSBjbGF1c2U/LnN0YXRlbWVudDtcbiAgICBpZiAoIXRoaXMuc3RhdGVtZW50IHx8ICF0aGlzLnByaW9yaXR5KVxuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3IoXG4gICAgICAgIFwiTWlzc2luZyBzdGF0ZW1lbnQgb3IgcHJpb3JpdHkuIFNob3VsZCBiZSBpbXBvc3NpYmxlXCJcbiAgICAgICk7XG4gICAgdGhpcy5zdGF0ZW1lbnQuYWRkQ2xhdXNlKHRoaXMpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBhZGFwdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlbWVudC5nZXRBZGFwdGVyKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IENsYXVzZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGVtZW50LmdldEFkYXB0ZXIoKS5DbGF1c2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHVybiB0aGUgcHJpb3JpdHkgb2YgdGhlIGNsYXVzZVxuICAgKiBAc2VlIFByaW9yaXR5XG4gICAqL1xuICBnZXRQcmlvcml0eSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnByaW9yaXR5IGFzIG51bWJlcjtcbiAgfVxuXG4gIGFic3RyYWN0IGJ1aWxkKHByZXZpb3VzOiBRKTogUTtcblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICogQGFic3RyYWN0XG4gICAqL1xuICBhc3luYyBleGVjdXRlPFI+KCk6IFByb21pc2U8Uj4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlbWVudC5leGVjdXRlKCk7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cbiAgYXN5bmMgcGFnaW5hdGU8Uj4oc2l6ZTogbnVtYmVyKTogUHJvbWlzZTxQYWdpbmF0b3I8UiwgUT4+IHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZW1lbnQucGFnaW5hdGUoc2l6ZSk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lO1xuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgRnJvbUNsYXVzZX1cbiAgLy8gICogQHBhcmFtIHt7cHJpb3JpdHk6IG51bWJlciwgc3RhdGVtZW50OiBTdGF0ZW1lbnQsIGdldFByaW9yaXR5OiBGdW5jdGlvbiwgYnVpbGQ6IEZ1bmN0aW9uLCBwcm9jZXNzOiBGdW5jdGlvbn19IGNsYXVzZVxuICAvLyAgKi9cbiAgLy8gc3RhdGljIGlzQ2xhdXNlKGNsYXVzZTogUGFydGlhbDxDbGF1c2U8YW55Pj4pIHtcbiAgLy8gICByZXR1cm4gY2xhdXNlIGluc3RhbmNlb2YgQ2xhdXNlO1xuICAvLyAgIHJldHVybiAoXG4gIC8vICAgICBjbGF1c2UuY29uc3RydWN0b3IgJiZcbiAgLy8gICAgIGNsYXVzZS5jb25zdHJ1Y3Rvci5uYW1lICYmXG4gIC8vICAgICBjbGF1c2UucHJpb3JpdHkgJiZcbiAgLy8gICAgIGNsYXVzZS5zdGF0ZW1lbnQgJiZcbiAgLy8gICAgIGNsYXVzZS5nZXRQcmlvcml0eSAmJlxuICAvLyAgICAgY2xhdXNlLmJ1aWxkICYmXG4gIC8vICAgICBjbGF1c2UuZXhlY3V0ZVxuICAvLyAgICk7XG4gIC8vIH1cbn1cbiIsImltcG9ydCB7IENsYXVzZSB9IGZyb20gXCIuLi9DbGF1c2VcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgYmFzZSBTZWxlY3RvciBiYXNlZCBjbGF1c2VcbiAqXG4gKiBAcGFyYW0ge0NsYXVzZUFyZ30gW2NsYXVzZV1cbiAqXG4gKiBAY2xhc3MgU2VsZWN0b3JCYXNlZENsYXVzZVxuICogQGV4dGVuZHMgQ2xhdXNlXG4gKiBAYWJzdHJhY3RcbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTZWxlY3RvckJhc2VkQ2xhdXNlPFEsIFM+IGV4dGVuZHMgQ2xhdXNlPFE+IHtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgc2VsZWN0b3JcbiAgICpcbiAgICogQHByb3Agc2VsZWN0b3JcbiAgICogQHByb3RlY3RlZFxuICAgKi9cbiAgQHJlcXVpcmVkKClcbiAgcHJvdGVjdGVkIHNlbGVjdG9yPzogUyA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8U2VsZWN0b3JCYXNlZENsYXVzZTxRLCBTPj4pIHtcbiAgICBzdXBlcihjbGF1c2UpO1xuICAgIHRoaXMuc2VsZWN0b3IgPSAoY2xhdXNlIGFzIHsgc2VsZWN0b3I6IFMgfSkuc2VsZWN0b3I7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lICsgYFske3RoaXMuc2VsZWN0b3J9XWA7XG4gIH1cbn1cbiIsImltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHtcbiAgRnJvbVNlbGVjdG9yLFxuICBHcm91cEJ5U2VsZWN0b3IsXG4gIExpbWl0U2VsZWN0b3IsXG4gIE9mZnNldFNlbGVjdG9yLFxuICBPcmRlckJ5U2VsZWN0b3IsXG59IGZyb20gXCIuLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7XG4gIExpbWl0T3B0aW9uLFxuICBPZmZzZXRPcHRpb24sXG4gIE9yZGVyQW5kR3JvdXBPcHRpb24sXG4gIFdoZXJlT3B0aW9uLFxufSBmcm9tIFwiLi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgU2VsZWN0b3JCYXNlZENsYXVzZSB9IGZyb20gXCIuL1NlbGVjdG9yQmFzZWRDbGF1c2VcIjtcbmltcG9ydCB7IEV4ZWN1dG9yIH0gZnJvbSBcIi4uLy4uL2ludGVyZmFjZXNcIjtcbmltcG9ydCB7IFF1ZXJ5RXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi4vQ29uZGl0aW9uXCI7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgTW9kZWwsXG4gIE1vZGVsQXJnLFxuICBzdHJpbmdGb3JtYXQsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgRlJPTSBjbGF1c2VcbiAqXG4gKiBAcGFyYW0ge01vZGVsQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBGcm9tQ2xhdXNlXG4gKiBAZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlXG4gKiBAaW1wbGVtZW50cyBXaGVyZU9wdGlvblxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEZyb21DbGF1c2U8USwgTSBleHRlbmRzIE1vZGVsPlxuICBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2U8USwgRnJvbVNlbGVjdG9yPE0+PlxuICBpbXBsZW1lbnRzIFdoZXJlT3B0aW9uXG57XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxGcm9tQ2xhdXNlPFEsIE0+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuRlJPTSB9KSk7XG4gICAgdGhpcy5zZWxlY3RvciA9XG4gICAgICB0eXBlb2YgdGhpcy5zZWxlY3RvciA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IE1vZGVsLmdldCh0aGlzLnNlbGVjdG9yKVxuICAgICAgICA6IHRoaXMuc2VsZWN0b3I7XG4gICAgaWYgKCF0aGlzLnNlbGVjdG9yKVxuICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXJyb3Ioc3RyaW5nRm9ybWF0KFwiQ291bGQgbm90IGZpbmQgc2VsZWN0b3IgbW9kZWw6IHswfVwiKSk7XG4gICAgdGhpcy5zdGF0ZW1lbnQuc2V0VGFyZ2V0KHRoaXMuc2VsZWN0b3IgYXMgQ29uc3RydWN0b3I8TT4pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBhYnN0cmFjdCBidWlsZChxdWVyeTogUSk6IFE7XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICB3aGVyZShjb25kaXRpb246IENvbmRpdGlvbik6IE9yZGVyQW5kR3JvdXBPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMud2hlcmUodGhpcy5zdGF0ZW1lbnQsIGNvbmRpdGlvbik7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvcmRlckJ5KC4uLnNlbGVjdG9yOiBPcmRlckJ5U2VsZWN0b3JbXSk6IExpbWl0T3B0aW9uICYgT2Zmc2V0T3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLm9yZGVyQnkodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGdyb3VwQnkoc2VsZWN0b3I6IEdyb3VwQnlTZWxlY3Rvcik6IEV4ZWN1dG9yIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmdyb3VwQnkodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGxpbWl0KHNlbGVjdG9yOiBMaW1pdFNlbGVjdG9yKTogT2Zmc2V0T3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmxpbWl0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvZmZzZXQoc2VsZWN0b3I6IE9mZnNldFNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub2Zmc2V0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsQXJnIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgR3JvdXBCeVNlbGVjdG9yIH0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuaW1wb3J0IHsgUHJpb3JpdHkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBTZWxlY3RvckJhc2VkQ2xhdXNlIH0gZnJvbSBcIi4vU2VsZWN0b3JCYXNlZENsYXVzZVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBHUk9VUCBCWSBjbGF1c2VcbiAqXG4gKiBAcGFyYW0ge0NsYXVzZUFyZ30gW2NsYXVzZV1cbiAqXG4gKiBAY2xhc3MgR3JvdXBCeUNsYXVzZVxuICogQGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZVxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEdyb3VwQnlDbGF1c2U8UT4gZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlPFxuICBRLFxuICBHcm91cEJ5U2VsZWN0b3Jcbj4ge1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8R3JvdXBCeUNsYXVzZTxRPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5LkdST1VQX0JZIH0pKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbn1cbiIsImltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9Db25kaXRpb25cIjtcbmltcG9ydCB7IEluc2VydE9wdGlvbiwgSW50b09wdGlvbiwgT3JkZXJBbmRHcm91cE9wdGlvbiB9IGZyb20gXCIuLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENsYXVzZSB9IGZyb20gXCIuLi9DbGF1c2VcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxBcmcsXG4gIHJlcXVpcmVkLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBFeGVjdXRvciB9IGZyb20gXCIuLi8uLi9pbnRlcmZhY2VzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVGhlIElOU0VSVC9JTlRPIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBGcm9tQ2xhdXNlXG4gKiBAZXh0ZW5kcyBDbGF1c2VcbiAqIEBpbXBsZW1lbnRzIEludG9PcHRpb25cbiAqXG4gKiBAY2F0ZWdvcnkgUXVlcnlcbiAqIEBzdWJjYXRlZ29yeSBDbGF1c2VzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBJbnNlcnRDbGF1c2U8USwgTSBleHRlbmRzIE1vZGVsPlxuICBleHRlbmRzIENsYXVzZTxRPlxuICBpbXBsZW1lbnRzIEluc2VydE9wdGlvbjxNPiwgSW50b09wdGlvbjxNPlxue1xuICBAcmVxdWlyZWQoKVxuICBwcm90ZWN0ZWQgdGFibGU/OiBzdHJpbmcgPSB1bmRlZmluZWQ7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXVzZT86IE1vZGVsQXJnPEluc2VydENsYXVzZTxRLCBNPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5LlNFTEVDVCB9KSk7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBhYnN0cmFjdCBidWlsZChxdWVyeTogUSk6IFE7XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBpbnRvKHRhYmxlOiBDb25zdHJ1Y3RvcjxNPik6IEludG9PcHRpb248TT4ge1xuICAgIHRoaXMudGFibGUgPSB0YWJsZS5uYW1lOyAvLyBUT0RPIGdldCBtYXBwZWQgbmFtZVxuICAgIHRoaXMuc3RhdGVtZW50LnNldFRhcmdldCh0YWJsZSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICB2YWx1ZXMoLi4ubW9kZWxzOiBNW10pOiBFeGVjdXRvciB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy52YWx1ZXModGhpcy5zdGF0ZW1lbnQsIG1vZGVscyk7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICB3aGVyZShjb25kaXRpb246IENvbmRpdGlvbik6IE9yZGVyQW5kR3JvdXBPcHRpb24ge1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMud2hlcmUodGhpcy5zdGF0ZW1lbnQsIGNvbmRpdGlvbik7XG4gIH1cbn1cbiIsImltcG9ydCB7IFNlbGVjdG9yQmFzZWRDbGF1c2UgfSBmcm9tIFwiLi9TZWxlY3RvckJhc2VkQ2xhdXNlXCI7XG5pbXBvcnQgeyBPZmZzZXRPcHRpb24gfSBmcm9tIFwiLi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgRXhlY3V0b3IgfSBmcm9tIFwiLi4vLi4vaW50ZXJmYWNlc1wiO1xuaW1wb3J0IHsgTGltaXRTZWxlY3RvciwgT2Zmc2V0U2VsZWN0b3IgfSBmcm9tIFwiLi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1vZGVsQXJnIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IExpbWl0IENsYXVzZVxuICogQGRlc2NyaXB0aW9uIExpbWl0cyB0aGUgcmVzdWx0c1xuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBMaW1pdENsYXVzZVxuICogQGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZTxUPlxuICogQGltcGxlbWVudHMgT2Zmc2V0T3B0aW9uPFQ+XG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTGltaXRDbGF1c2U8UT5cbiAgZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlPFEsIExpbWl0U2VsZWN0b3I+XG4gIGltcGxlbWVudHMgT2Zmc2V0T3B0aW9uXG57XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF1c2U/OiBNb2RlbEFyZzxMaW1pdENsYXVzZTxRPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5LkdST1VQX0JZIH0pKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvZmZzZXQoc2VsZWN0b3I6IE9mZnNldFNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub2Zmc2V0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbn1cbiIsImltcG9ydCB7IFNlbGVjdG9yQmFzZWRDbGF1c2UgfSBmcm9tIFwiLi9TZWxlY3RvckJhc2VkQ2xhdXNlXCI7XG5pbXBvcnQgeyBPZmZzZXRTZWxlY3RvciB9IGZyb20gXCIuLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IFByaW9yaXR5IH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgTW9kZWxBcmcgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVGhlIE9GRlNFVCBjbGF1c2VcbiAqXG4gKiBAcGFyYW0ge0NsYXVzZUFyZ30gW2NsYXVzZV1cbiAqXG4gKiBAY2xhc3MgRnJvbUNsYXVzZVxuICogQGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZVxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE9mZnNldENsYXVzZTxRPiBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2U8XG4gIFEsXG4gIE9mZnNldFNlbGVjdG9yXG4+IHtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXVzZT86IE1vZGVsQXJnPE9mZnNldENsYXVzZTxRPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5LkdST1VQX0JZIH0pKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbn1cbiIsImltcG9ydCB7IFNlbGVjdG9yQmFzZWRDbGF1c2UgfSBmcm9tIFwiLi9TZWxlY3RvckJhc2VkQ2xhdXNlXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEdyb3VwQnlTZWxlY3RvcixcbiAgTGltaXRTZWxlY3RvcixcbiAgT2Zmc2V0U2VsZWN0b3IsXG4gIE9yZGVyQnlTZWxlY3Rvcixcbn0gZnJvbSBcIi4uL3NlbGVjdG9yc1wiO1xuaW1wb3J0IHsgTGltaXRPcHRpb24sIE9mZnNldE9wdGlvbiB9IGZyb20gXCIuLi9vcHRpb25zXCI7XG5pbXBvcnQgeyBFeGVjdXRvciB9IGZyb20gXCIuLi8uLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBNb2RlbEFyZyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbi8qKlxuICogQHN1bW1hcnkgVGhlIE9SREVSIEJZIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBPcmRlckJ5Q2xhdXNlXG4gKiBAZXh0ZW5kcyBTZWxlY3RvckJhc2VkQ2xhdXNlXG4gKiBAaW1wbGVtZW50cyBMaW1pdE9wdGlvblxuICogQGltcGxlbWVudHMgT2Zmc2V0T3B0aW9uXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgT3JkZXJCeUNsYXVzZTxRPlxuICBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2U8USwgT3JkZXJCeVNlbGVjdG9yW10+XG4gIGltcGxlbWVudHMgTGltaXRPcHRpb24sIE9mZnNldE9wdGlvblxue1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8T3JkZXJCeUNsYXVzZTxRPj4pIHtcbiAgICBzdXBlcihPYmplY3QuYXNzaWduKHt9LCBjbGF1c2UsIHsgcHJpb3JpdHk6IFByaW9yaXR5Lk9SREVSX0JZIH0pKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBncm91cEJ5KHNlbGVjdG9yOiBHcm91cEJ5U2VsZWN0b3IpOiBFeGVjdXRvciB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5ncm91cEJ5KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBsaW1pdChzZWxlY3RvcjogTGltaXRTZWxlY3Rvcik6IE9mZnNldE9wdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5saW1pdCh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgb2Zmc2V0KHNlbGVjdG9yOiBPZmZzZXRTZWxlY3Rvcik6IEV4ZWN1dG9yIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLm9mZnNldCh0aGlzLnN0YXRlbWVudCwgc2VsZWN0b3IpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBTZWxlY3RvckJhc2VkQ2xhdXNlIH0gZnJvbSBcIi4vU2VsZWN0b3JCYXNlZENsYXVzZVwiO1xuaW1wb3J0IHtcbiAgQ291bnRPcHRpb24sXG4gIERpc3RpbmN0T3B0aW9uLFxuICBNYXhPcHRpb24sXG4gIE1pbk9wdGlvbixcbiAgU2VsZWN0T3B0aW9uLFxuICBXaGVyZU9wdGlvbixcbn0gZnJvbSBcIi4uL29wdGlvbnNcIjtcbmltcG9ydCB7IENvbnN0LCBQcmlvcml0eSwgU3RhdGVtZW50VHlwZSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbEFyZywgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBTZWxlY3RTZWxlY3RvciB9IGZyb20gXCIuLi9zZWxlY3RvcnNcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgU0VMRUNUIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBTZWxlY3RDbGF1c2VcbiAqIEBleHRlbmRzIFNlbGVjdG9yQmFzZWRDbGF1c2VcbiAqIEBpbXBsZW1lbnRzIFNlbGVjdE9wdGlvblxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFNlbGVjdENsYXVzZTxRLCBNIGV4dGVuZHMgTW9kZWw+XG4gIGV4dGVuZHMgU2VsZWN0b3JCYXNlZENsYXVzZTxRLCBTZWxlY3RTZWxlY3Rvcj5cbiAgaW1wbGVtZW50cyBTZWxlY3RPcHRpb248TT5cbntcbiAgcHJpdmF0ZSBpc0Rpc3RpbmN0OiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgaXNDb3VudCA9IGZhbHNlO1xuICBwcml2YXRlIGlzTWF4ID0gZmFsc2U7XG4gIHByaXZhdGUgaXNNaW4gPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8U2VsZWN0Q2xhdXNlPFEsIE0+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuU0VMRUNUIH0pKTtcbiAgICBpZiAodGhpcy5zZWxlY3RvciA9PT0gQ29uc3QuRlVMTF9SRUNPUkQpIHRoaXMuc3RhdGVtZW50LnNldEZ1bGxSZWNvcmQoKTtcbiAgICB0aGlzLnN0YXRlbWVudC5zZXRNb2RlKFN0YXRlbWVudFR5cGUuUVVFUlkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW5oZXJpdERvY1xuICAgKi9cbiAgYWJzdHJhY3QgYnVpbGQocXVlcnk6IFEpOiBRO1xuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGRpc3RpbmN0KHNlbGVjdG9yOiBTZWxlY3RTZWxlY3Rvcik6IERpc3RpbmN0T3B0aW9uPE0+IHtcbiAgICB0aGlzLmlzRGlzdGluY3QgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGNvdW50KHNlbGVjdG9yOiBTZWxlY3RTZWxlY3Rvcik6IENvdW50T3B0aW9uPE0+IHtcbiAgICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBtaW4oc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogTWluT3B0aW9uPE0+IHtcbiAgICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBtYXgoc2VsZWN0b3I6IFNlbGVjdFNlbGVjdG9yKTogTWF4T3B0aW9uPE0+IHtcbiAgICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBmcm9tKHRhYmxlTmFtZTogQ29uc3RydWN0b3I8TT4pOiBXaGVyZU9wdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuQ2xhdXNlcy5mcm9tKHRoaXMuc3RhdGVtZW50LCB0YWJsZU5hbWUpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDbGF1c2UgfSBmcm9tIFwiLi4vQ2xhdXNlXCI7XG5pbXBvcnQgeyBQcmlvcml0eSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1vZGVsQXJnLCByZXF1aXJlZCwgdHlwZSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBUaGUgVkFMVUVTIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBWYWx1ZXNDbGF1c2VcbiAqIEBleHRlbmRzIENsYXVzZVxuICpcbiAqIEBjYXRlZ29yeSBRdWVyeVxuICogQHN1YmNhdGVnb3J5IENsYXVzZXNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFZhbHVlc0NsYXVzZTxRLCBNPiBleHRlbmRzIENsYXVzZTxRPiB7XG4gIEByZXF1aXJlZCgpXG4gIEB0eXBlKEFycmF5Lm5hbWUpXG4gIG1vZGVscz86IE1bXSA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8VmFsdWVzQ2xhdXNlPFEsIE0+Pikge1xuICAgIHN1cGVyKE9iamVjdC5hc3NpZ24oe30sIGNsYXVzZSwgeyBwcmlvcml0eTogUHJpb3JpdHkuRlJPTSB9KSk7XG4gICAgdGhpcy5tb2RlbHMgPSBjbGF1c2U/Lm1vZGVscztcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbn1cbiIsImltcG9ydCB7IENsYXVzZSB9IGZyb20gXCIuLi9DbGF1c2VcIjtcbmltcG9ydCB7IENvbmRpdGlvbiB9IGZyb20gXCIuLi9Db25kaXRpb25cIjtcbmltcG9ydCB7XG4gIE1vZGVsQXJnLFxuICBNb2RlbEVycm9yRGVmaW5pdGlvbixcbiAgcmVxdWlyZWQsXG4gIHR5cGUsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IExpbWl0T3B0aW9uLCBPZmZzZXRPcHRpb24sIE9yZGVyQW5kR3JvdXBPcHRpb24gfSBmcm9tIFwiLi4vb3B0aW9uc1wiO1xuaW1wb3J0IHsgUHJpb3JpdHkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBHcm91cEJ5U2VsZWN0b3IsXG4gIExpbWl0U2VsZWN0b3IsXG4gIE9mZnNldFNlbGVjdG9yLFxuICBPcmRlckJ5U2VsZWN0b3IsXG59IGZyb20gXCIuLi9zZWxlY3RvcnNcIjtcbmltcG9ydCB7IEV4ZWN1dG9yIH0gZnJvbSBcIi4uLy4uL2ludGVyZmFjZXNcIjtcbi8qKlxuICogQHN1bW1hcnkgVGhlIFdIRVJFIGNsYXVzZVxuICpcbiAqIEBwYXJhbSB7Q2xhdXNlQXJnfSBbY2xhdXNlXVxuICpcbiAqIEBjbGFzcyBXaGVyZUNsYXVzZVxuICogQGV4dGVuZHMgQ2xhdXNlXG4gKiBAaW1wbGVtZW50cyBPcmRlckFuZEdyb3VwT3B0aW9uXG4gKlxuICogQGNhdGVnb3J5IFF1ZXJ5XG4gKiBAc3ViY2F0ZWdvcnkgQ2xhdXNlc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgV2hlcmVDbGF1c2U8UT5cbiAgZXh0ZW5kcyBDbGF1c2U8UT5cbiAgaW1wbGVtZW50cyBPcmRlckFuZEdyb3VwT3B0aW9uXG57XG4gIEByZXF1aXJlZCgpXG4gIEB0eXBlKFwiQ29uZGl0aW9uXCIpXG4gIGNvbmRpdGlvbj86IENvbmRpdGlvbiA9IHVuZGVmaW5lZDtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xhdXNlPzogTW9kZWxBcmc8V2hlcmVDbGF1c2U8UT4+KSB7XG4gICAgc3VwZXIoT2JqZWN0LmFzc2lnbih7fSwgY2xhdXNlLCB7IHByaW9yaXR5OiBQcmlvcml0eS5XSEVSRSB9KSk7XG4gICAgdGhpcy5jb25kaXRpb24gPSBjbGF1c2U/LmNvbmRpdGlvbjtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGFic3RyYWN0IGJ1aWxkKHF1ZXJ5OiBRKTogUTtcbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvcmRlckJ5KC4uLnNlbGVjdG9yOiBPcmRlckJ5U2VsZWN0b3JbXSk6IExpbWl0T3B0aW9uICYgT2Zmc2V0T3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLm9yZGVyQnkodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGdyb3VwQnkoc2VsZWN0b3I6IEdyb3VwQnlTZWxlY3Rvcik6IEV4ZWN1dG9yIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmdyb3VwQnkodGhpcy5zdGF0ZW1lbnQsIHNlbGVjdG9yKTtcbiAgfVxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGxpbWl0KHNlbGVjdG9yOiBMaW1pdFNlbGVjdG9yKTogT2Zmc2V0T3B0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5DbGF1c2VzLmxpbWl0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBvZmZzZXQoc2VsZWN0b3I6IE9mZnNldFNlbGVjdG9yKTogRXhlY3V0b3Ige1xuICAgIHJldHVybiB0aGlzLkNsYXVzZXMub2Zmc2V0KHRoaXMuc3RhdGVtZW50LCBzZWxlY3Rvcik7XG4gIH1cblxuICAvKipcbiAgICogQGluaGVyaXREb2NcbiAgICovXG4gIGhhc0Vycm9ycyguLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBlcnJvcnMgPSBzdXBlci5oYXNFcnJvcnMoLi4uZXhjZXB0aW9ucyk7XG4gICAgaWYgKGVycm9ycykgcmV0dXJuIGVycm9ycztcbiAgICByZXR1cm4gdGhpcy5jb25kaXRpb24hLmhhc0Vycm9ycygpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBGcm9tQ2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlc1wiO1xuaW1wb3J0IHsgR3JvdXBCeUNsYXVzZSB9IGZyb20gXCIuL2NsYXVzZXMvR3JvdXBCeUNsYXVzZVwiO1xuaW1wb3J0IHsgSW5zZXJ0Q2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlcy9JbnNlcnRDbGF1c2VcIjtcbmltcG9ydCB7IExpbWl0Q2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlcy9MaW1pdENsYXVzZVwiO1xuaW1wb3J0IHsgT2Zmc2V0Q2xhdXNlIH0gZnJvbSBcIi4vY2xhdXNlcy9PZmZzZXRDbGF1c2VcIjtcbmltcG9ydCB7IE9yZGVyQnlDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL09yZGVyQnlDbGF1c2VcIjtcbmltcG9ydCB7IFNlbGVjdENsYXVzZSB9IGZyb20gXCIuL2NsYXVzZXMvU2VsZWN0Q2xhdXNlXCI7XG5pbXBvcnQgeyBWYWx1ZXNDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL1ZhbHVlc0NsYXVzZVwiO1xuaW1wb3J0IHsgV2hlcmVDbGF1c2UgfSBmcm9tIFwiLi9jbGF1c2VzL1doZXJlQ2xhdXNlXCI7XG5pbXBvcnQgeyBBZGFwdGVyIH0gZnJvbSBcIi4uL3BlcnNpc3RlbmNlXCI7XG5pbXBvcnQgeyBDb25kaXRpb24gfSBmcm9tIFwiLi9Db25kaXRpb25cIjtcbmltcG9ydCB7XG4gIEZyb21TZWxlY3RvcixcbiAgR3JvdXBCeVNlbGVjdG9yLFxuICBMaW1pdFNlbGVjdG9yLFxuICBPZmZzZXRTZWxlY3RvcixcbiAgT3JkZXJCeVNlbGVjdG9yLFxuICBTZWxlY3RTZWxlY3Rvcixcbn0gZnJvbSBcIi4vc2VsZWN0b3JzXCI7XG5pbXBvcnQgeyBTdGF0ZW1lbnQgfSBmcm9tIFwiLi9TdGF0ZW1lbnRcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ2xhdXNlRmFjdG9yeTxZLCBRPiB7XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCBmb3Ige0BsaW5rIEZyb21DbGF1c2V9XG4gICAqIEBwYXJhbSB7U3RhdGVtZW50fSBzdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtGcm9tU2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBhYnN0cmFjdCBmcm9tPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8UT4sXG4gICAgc2VsZWN0b3I6IEZyb21TZWxlY3RvcjxNPlxuICApOiBGcm9tQ2xhdXNlPFEsIE0+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBHcm91cEJ5Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7R3JvdXBCeVNlbGVjdG9yfSBzZWxlY3RvclxuICAgKi9cbiAgYWJzdHJhY3QgZ3JvdXBCeShcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPixcbiAgICBzZWxlY3RvcjogR3JvdXBCeVNlbGVjdG9yXG4gICk6IEdyb3VwQnlDbGF1c2U8UT47XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCBmb3Ige0BsaW5rIEluc2VydENsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKi9cbiAgYWJzdHJhY3QgaW5zZXJ0PE0gZXh0ZW5kcyBNb2RlbD4oKTogSW5zZXJ0Q2xhdXNlPFEsIE0+O1xuICAvKipcbiAgICogQHN1bW1hcnkgRmFjdG9yeSBtZXRob2QgZm9yIHtAbGluayBMaW1pdENsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKiBAcGFyYW0ge0xpbWl0U2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBhYnN0cmFjdCBsaW1pdChcbiAgICBzdGF0ZW1lbnQ6IFN0YXRlbWVudDxRPixcbiAgICBzZWxlY3RvcjogTGltaXRTZWxlY3RvclxuICApOiBMaW1pdENsYXVzZTxRPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgT2Zmc2V0Q2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7T2Zmc2V0U2VsZWN0b3J9IHNlbGVjdG9yXG4gICAqL1xuICBhYnN0cmFjdCBvZmZzZXQoXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8UT4sXG4gICAgc2VsZWN0b3I6IE9mZnNldFNlbGVjdG9yXG4gICk6IE9mZnNldENsYXVzZTxRPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgT3JkZXJCeUNsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKiBAcGFyYW0ge09yZGVyQnlTZWxlY3Rvcn0gc2VsZWN0b3JcbiAgICovXG4gIGFic3RyYWN0IG9yZGVyQnkoXG4gICAgc3RhdGVtZW50OiBTdGF0ZW1lbnQ8UT4sXG4gICAgc2VsZWN0b3I6IE9yZGVyQnlTZWxlY3RvcltdXG4gICk6IE9yZGVyQnlDbGF1c2U8UT47XG4gIC8qKlxuICAgKiBAc3VtbWFyeSBGYWN0b3J5IG1ldGhvZCBmb3Ige0BsaW5rIFNlbGVjdENsYXVzZX1cbiAgICogQHBhcmFtIHtTdGF0ZW1lbnR9IHN0YXRlbWVudFxuICAgKiBAcGFyYW0ge1NlbGVjdFNlbGVjdG9yfSBbc2VsZWN0b3JdXG4gICAqL1xuICBhYnN0cmFjdCBzZWxlY3Q8TSBleHRlbmRzIE1vZGVsPihcbiAgICBzZWxlY3Rvcj86IFNlbGVjdFNlbGVjdG9yXG4gICk6IFNlbGVjdENsYXVzZTxRLCBNPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgVmFsdWVzQ2xhdXNlfVxuICAgKiBAcGFyYW0ge1N0YXRlbWVudH0gc3RhdGVtZW50XG4gICAqIEBwYXJhbSB7TVtdfSB2YWx1ZXNcbiAgICovXG4gIGFic3RyYWN0IHZhbHVlczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHN0YXRlbWVudDogU3RhdGVtZW50PFE+LFxuICAgIHZhbHVlczogTVtdXG4gICk6IFZhbHVlc0NsYXVzZTxRLCBNPjtcbiAgLyoqXG4gICAqIEBzdW1tYXJ5IEZhY3RvcnkgbWV0aG9kIGZvciB7QGxpbmsgV2hlcmVDbGF1c2V9XG4gICAqIEBwYXJhbSB7U3RhdGVtZW50fSBzdGF0ZW1lbnRcbiAgICogQHBhcmFtIHtDb25kaXRpb259IGNvbmRpdGlvblxuICAgKi9cbiAgYWJzdHJhY3Qgd2hlcmUoc3RhdGVtZW50OiBTdGF0ZW1lbnQ8UT4sIGNvbmRpdGlvbjogQ29uZGl0aW9uKTogV2hlcmVDbGF1c2U8UT47XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBhZGFwdGVyOiBBZGFwdGVyPFksIFE+KSB7fVxufVxuIiwiaW1wb3J0IHsgUGFnaW5nRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IFN0YXRlbWVudCB9IGZyb20gXCIuL1N0YXRlbWVudFwiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUGFnaW5hdG9yPFYsIFE+IHtcbiAgcHJvdGVjdGVkIF9jdXJyZW50UGFnZSE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIF90b3RhbFBhZ2VzITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgX3JlY29yZENvdW50ITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgbGltaXQhOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSBfc3RhdGVtZW50PzogUTtcblxuICBnZXQgY3VycmVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFBhZ2U7XG4gIH1cblxuICBnZXQgdG90YWwoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3RvdGFsUGFnZXM7XG4gIH1cblxuICBnZXQgY291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fcmVjb3JkQ291bnQ7XG4gIH1cblxuICBnZXQgc3RhdGVtZW50KCkge1xuICAgIGlmICghdGhpcy5fc3RhdGVtZW50KSB0aGlzLl9zdGF0ZW1lbnQgPSB0aGlzLnByZXBhcmUodGhpcy5fcmF3U3RhdGVtZW50KTtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGVtZW50O1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBhZGFwdGVyKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXQuZ2V0QWRhcHRlcigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBzdGF0OiBTdGF0ZW1lbnQ8UT4sXG4gICAgcmVhZG9ubHkgc2l6ZTogbnVtYmVyLFxuICAgIHByb3RlY3RlZCByZWFkb25seSBfcmF3U3RhdGVtZW50OiBRXG4gICkge31cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcHJlcGFyZShyYXdTdGF0ZW1lbnQ6IFEpOiBRO1xuXG4gIGFzeW5jIG5leHQoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFnZSh0aGlzLmN1cnJlbnQgKyAxKTtcbiAgfVxuXG4gIGFzeW5jIHByZXZpb3VzKCkge1xuICAgIHJldHVybiB0aGlzLnBhZ2UodGhpcy5jdXJyZW50IC0gMSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdmFsaWRhdGVQYWdlKHBhZ2U6IG51bWJlcikge1xuICAgIGlmIChwYWdlIDwgMSB8fCAhTnVtYmVyLmlzSW50ZWdlcihwYWdlKSlcbiAgICAgIHRocm93IG5ldyBQYWdpbmdFcnJvcihcbiAgICAgICAgXCJwYWdlIG51bWJlciBjYW5ub3QgYmUgdW5kZXIgMSBhbmQgbXVzdCBiZSBhbiBpbnRlZ2VyXCJcbiAgICAgICk7XG4gICAgaWYgKHBhZ2UgPiB0aGlzLl90b3RhbFBhZ2VzKVxuICAgICAgdGhyb3cgbmV3IFBhZ2luZ0Vycm9yKFxuICAgICAgICBcInBhZ2UgbnVtYmVyIGNhbm5vdCBiZSB1bmRlciAxIGFuZCBtdXN0IGJlIGFuIGludGVnZXJcIlxuICAgICAgKTtcbiAgfVxuXG4gIGFic3RyYWN0IHBhZ2UocGFnZT86IG51bWJlciwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFZbXT47XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlc1JlZ2lzdHJ5IH0gZnJvbSBcIi4vcmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgSW5qZWN0YWJsZXMgfSBmcm9tIFwiQGRlY2FmLXRzL2luamVjdGFibGUtZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IE1vZHVsZSBzdW1tYXJ5XG4gKiBAZGVzY3JpcHRpb24gTW9kdWxlIGRlc2NyaXB0aW9uXG4gKiBAbW9kdWxlIHRzLXdvcmtzcGFjZVxuICovXG5cbi8qKlxuICogQHN1bW1hcnkgTmFtZXNwYWNlIHN1bW1hcnlcbiAqIEBkZXNjcmlwdGlvbiBOYW1lc3BhY2UgZGVzY3JpcHRpb25cbiAqIEBuYW1lc3BhY2UgTmFtZXNwYWNlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRzLXdvcmtzcGFjZVxuICovXG5cbmV4cG9ydCAqIGZyb20gXCIuL2lkZW50aXR5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vcGVyc2lzdGVuY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3F1ZXJ5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9yZXBvc2l0b3J5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi92YWxpZGF0b3JzXCI7XG5cbkluamVjdGFibGVzLnNldFJlZ2lzdHJ5KG5ldyBJbmplY3RhYmxlc1JlZ2lzdHJ5KCkpO1xuXG4vKipcbiAqIEBzdW1tYXJ5IHN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb25cbiAqIEBkZXNjcmlwdGlvbiB0aGlzIGlzIGhvdyB5b3Ugc2hvdWxkIGRvY3VtZW50IGEgY29uc3RhbnRcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnRzLXdvcmtzcGFjZVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJDdHgiLCJSZXAiLCJwb3B1bGF0ZSIsInBvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQTs7Ozs7O0FBTUc7SUFDUztBQUFaLENBQUEsVUFBWSxjQUFjLEVBQUE7QUFDeEI7OztBQUdHO0FBQ0gsSUFBQSxjQUFBLENBQUEsS0FBQSxDQUFBLEdBQUEsS0FBVztBQUNYOzs7QUFHRztBQUNILElBQUEsY0FBQSxDQUFBLEtBQUEsQ0FBQSxHQUFBLE1BQVk7QUFDZCxDQUFDLEVBWFcsY0FBYyxLQUFkLGNBQWMsR0FXekIsRUFBQSxDQUFBLENBQUE7SUFFVztBQUFaLENBQUEsVUFBWSxPQUFPLEVBQUE7QUFDakIsSUFBQSxPQUFBLENBQUEsU0FBQSxDQUFBLEdBQUEsU0FBbUI7QUFDbkIsSUFBQSxPQUFBLENBQUEsTUFBQSxDQUFBLEdBQUEsTUFBYTtBQUNmLENBQUMsRUFIVyxPQUFPLEtBQVAsT0FBTyxHQUdsQixFQUFBLENBQUEsQ0FBQTtBQUVZLE1BQUEsY0FBYyxHQUFvQjtJQUM3QyxNQUFNLEVBQUUsT0FBTyxDQUFDLE9BQU87SUFDdkIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxJQUFJOzs7QUN4QmhCLE1BQWdCLE9BR3BCLFNBQVFBLFNBQU0sQ0FBQTtBQUdkLElBQUEsV0FBQSxDQUNFLFNBQXdCLEVBQ3hCLEtBQXNCLEVBQ3RCLE1BQTBCLEVBQUE7QUFFMUIsUUFBQSxLQUFLLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUM7O0FBR2pDLElBQUEsSUFBYSxTQUFTLEdBQUE7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO0FBQUUsWUFBQSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksSUFBSSxFQUFFO1FBQ2xELE9BQU8sSUFBSSxDQUFDLFVBQVU7O0FBSXpCOztJQ3pCVztBQUFaLENBQUEsVUFBWSxlQUFlLEVBQUE7QUFDekIsSUFBQSxlQUFBLENBQUEsT0FBQSxDQUFB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
|