parse-server 6.0.0-alpha.2 → 6.0.0-alpha.21
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/README.md +45 -17
- package/lib/AccountLockout.js +11 -26
- package/lib/Adapters/AdapterLoader.js +8 -14
- package/lib/Adapters/Analytics/AnalyticsAdapter.js +2 -8
- package/lib/Adapters/Auth/AuthAdapter.js +7 -16
- package/lib/Adapters/Auth/OAuth1Client.js +32 -57
- package/lib/Adapters/Auth/apple.js +6 -22
- package/lib/Adapters/Auth/facebook.js +7 -37
- package/lib/Adapters/Auth/gcenter.js +8 -37
- package/lib/Adapters/Auth/github.js +7 -10
- package/lib/Adapters/Auth/google.js +11 -34
- package/lib/Adapters/Auth/gpgames.js +5 -8
- package/lib/Adapters/Auth/httpsRequest.js +1 -7
- package/lib/Adapters/Auth/index.js +20 -65
- package/lib/Adapters/Auth/instagram.js +5 -9
- package/lib/Adapters/Auth/janraincapture.js +8 -12
- package/lib/Adapters/Auth/janrainengage.js +7 -11
- package/lib/Adapters/Auth/keycloak.js +5 -19
- package/lib/Adapters/Auth/ldap.js +1 -15
- package/lib/Adapters/Auth/line.js +7 -10
- package/lib/Adapters/Auth/linkedin.js +7 -12
- package/lib/Adapters/Auth/meetup.js +7 -10
- package/lib/Adapters/Auth/microsoft.js +7 -10
- package/lib/Adapters/Auth/oauth2.js +6 -18
- package/lib/Adapters/Auth/phantauth.js +8 -10
- package/lib/Adapters/Auth/qq.js +7 -13
- package/lib/Adapters/Auth/spotify.js +7 -14
- package/lib/Adapters/Auth/twitter.js +5 -15
- package/lib/Adapters/Auth/vkontakte.js +9 -15
- package/lib/Adapters/Auth/wechat.js +7 -10
- package/lib/Adapters/Auth/weibo.js +7 -11
- package/lib/Adapters/Cache/CacheAdapter.js +4 -12
- package/lib/Adapters/Cache/InMemoryCache.js +5 -19
- package/lib/Adapters/Cache/InMemoryCacheAdapter.js +1 -11
- package/lib/Adapters/Cache/LRUCache.js +1 -11
- package/lib/Adapters/Cache/NullCacheAdapter.js +1 -8
- package/lib/Adapters/Cache/RedisCacheAdapter.js +46 -87
- package/lib/Adapters/Cache/SchemaCache.js +1 -6
- package/lib/Adapters/Email/MailAdapter.js +2 -7
- package/lib/Adapters/Files/FilesAdapter.js +7 -21
- package/lib/Adapters/Files/GridFSBucketAdapter.js +6 -44
- package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
- package/lib/Adapters/Logger/LoggerAdapter.js +2 -11
- package/lib/Adapters/Logger/WinstonLogger.js +3 -30
- package/lib/Adapters/Logger/WinstonLoggerAdapter.js +5 -16
- package/lib/Adapters/MessageQueue/EventEmitterMQ.js +3 -20
- package/lib/Adapters/PubSub/EventEmitterPubSub.js +1 -16
- package/lib/Adapters/PubSub/PubSubAdapter.js +2 -9
- package/lib/Adapters/PubSub/RedisPubSub.js +13 -10
- package/lib/Adapters/Push/PushAdapter.js +2 -8
- package/lib/Adapters/Storage/Mongo/MongoCollection.js +12 -37
- package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +26 -79
- package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +78 -209
- package/lib/Adapters/Storage/Mongo/MongoTransform.js +82 -371
- package/lib/Adapters/Storage/Postgres/PostgresClient.js +1 -13
- package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +1 -20
- package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +119 -446
- package/lib/Adapters/Storage/Postgres/sql/index.js +4 -7
- package/lib/Adapters/Storage/StorageAdapter.js +1 -1
- package/lib/Adapters/WebSocketServer/WSAdapter.js +3 -12
- package/lib/Adapters/WebSocketServer/WSSAdapter.js +7 -12
- package/lib/Auth.js +54 -121
- package/lib/ClientSDK.js +3 -11
- package/lib/Config.js +69 -113
- package/lib/Controllers/AdaptableController.js +6 -18
- package/lib/Controllers/AnalyticsController.js +1 -9
- package/lib/Controllers/CacheController.js +3 -23
- package/lib/Controllers/DatabaseController.js +147 -345
- package/lib/Controllers/FilesController.js +5 -34
- package/lib/Controllers/HooksController.js +1 -51
- package/lib/Controllers/LiveQueryController.js +4 -23
- package/lib/Controllers/LoggerController.js +15 -54
- package/lib/Controllers/ParseGraphQLController.js +49 -104
- package/lib/Controllers/PushController.js +20 -59
- package/lib/Controllers/SchemaController.js +154 -344
- package/lib/Controllers/UserController.js +11 -72
- package/lib/Controllers/index.js +19 -68
- package/lib/Controllers/types.js +1 -1
- package/lib/Deprecator/Deprecations.js +1 -8
- package/lib/Deprecator/Deprecator.js +9 -18
- package/lib/GraphQL/ParseGraphQLSchema.js +16 -100
- package/lib/GraphQL/ParseGraphQLServer.js +2 -29
- package/lib/GraphQL/helpers/objectsMutations.js +2 -12
- package/lib/GraphQL/helpers/objectsQueries.js +18 -76
- package/lib/GraphQL/loaders/defaultGraphQLMutations.js +1 -9
- package/lib/GraphQL/loaders/defaultGraphQLQueries.js +1 -8
- package/lib/GraphQL/loaders/defaultGraphQLTypes.js +9 -115
- package/lib/GraphQL/loaders/defaultRelaySchema.js +6 -18
- package/lib/GraphQL/loaders/filesMutations.js +2 -19
- package/lib/GraphQL/loaders/functionsMutations.js +6 -17
- package/lib/GraphQL/loaders/parseClassMutations.js +6 -44
- package/lib/GraphQL/loaders/parseClassQueries.js +1 -26
- package/lib/GraphQL/loaders/parseClassTypes.js +10 -64
- package/lib/GraphQL/loaders/schemaDirectives.js +1 -17
- package/lib/GraphQL/loaders/schemaMutations.js +1 -20
- package/lib/GraphQL/loaders/schemaQueries.js +1 -14
- package/lib/GraphQL/loaders/schemaTypes.js +2 -6
- package/lib/GraphQL/loaders/usersMutations.js +6 -28
- package/lib/GraphQL/loaders/usersQueries.js +4 -26
- package/lib/GraphQL/parseGraphQLUtils.js +6 -19
- package/lib/GraphQL/transformers/className.js +1 -4
- package/lib/GraphQL/transformers/constraintType.js +1 -20
- package/lib/GraphQL/transformers/inputType.js +1 -20
- package/lib/GraphQL/transformers/mutation.js +6 -51
- package/lib/GraphQL/transformers/outputType.js +1 -20
- package/lib/GraphQL/transformers/query.js +6 -42
- package/lib/GraphQL/transformers/schemaFields.js +7 -34
- package/lib/KeyPromiseQueue.js +1 -12
- package/lib/LiveQuery/Client.js +1 -25
- package/lib/LiveQuery/Id.js +1 -7
- package/lib/LiveQuery/ParseCloudCodePublisher.js +13 -19
- package/lib/LiveQuery/ParseLiveQueryServer.js +92 -306
- package/lib/LiveQuery/ParsePubSub.js +1 -12
- package/lib/LiveQuery/ParseWebSocketServer.js +4 -26
- package/lib/LiveQuery/QueryTools.js +14 -116
- package/lib/LiveQuery/RequestSchema.js +1 -1
- package/lib/LiveQuery/SessionTokenCache.js +1 -17
- package/lib/LiveQuery/Subscription.js +4 -18
- package/lib/LiveQuery/equalObjects.js +2 -14
- package/lib/Options/Definitions.js +79 -10
- package/lib/Options/docs.js +23 -3
- package/lib/Options/index.js +4 -12
- package/lib/Options/parsers.js +1 -18
- package/lib/Page.js +1 -9
- package/lib/ParseMessageQueue.js +1 -10
- package/lib/ParseServer.js +144 -182
- package/lib/ParseServerRESTController.js +6 -33
- package/lib/PromiseRouter.js +16 -50
- package/lib/Push/PushQueue.js +3 -15
- package/lib/Push/PushWorker.js +7 -32
- package/lib/Push/utils.js +9 -38
- package/lib/RestQuery.js +105 -242
- package/lib/RestWrite.js +212 -377
- package/lib/Routers/AggregateRouter.js +14 -51
- package/lib/Routers/AnalyticsRouter.js +2 -8
- package/lib/Routers/AudiencesRouter.js +1 -15
- package/lib/Routers/ClassesRouter.js +3 -53
- package/lib/Routers/CloudCodeRouter.js +1 -19
- package/lib/Routers/FeaturesRouter.js +1 -10
- package/lib/Routers/FilesRouter.js +29 -76
- package/lib/Routers/FunctionsRouter.js +5 -28
- package/lib/Routers/GlobalConfigRouter.js +4 -18
- package/lib/Routers/GraphQLRouter.js +1 -14
- package/lib/Routers/HooksRouter.js +1 -29
- package/lib/Routers/IAPValidationRouter.js +6 -29
- package/lib/Routers/InstallationsRouter.js +2 -12
- package/lib/Routers/LogsRouter.js +4 -16
- package/lib/Routers/PagesRouter.js +69 -129
- package/lib/Routers/PublicAPIRouter.js +3 -62
- package/lib/Routers/PurgeRouter.js +1 -15
- package/lib/Routers/PushRouter.js +2 -18
- package/lib/Routers/RolesRouter.js +1 -7
- package/lib/Routers/SchemasRouter.js +4 -34
- package/lib/Routers/SecurityRouter.js +1 -12
- package/lib/Routers/SessionsRouter.js +3 -19
- package/lib/Routers/UsersRouter.js +58 -155
- package/lib/SchemaMigrations/DefinedSchemas.js +56 -115
- package/lib/SchemaMigrations/Migrations.js +2 -8
- package/lib/Security/Check.js +8 -16
- package/lib/Security/CheckGroup.js +4 -11
- package/lib/Security/CheckGroups/CheckGroupDatabase.js +8 -18
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +5 -15
- package/lib/Security/CheckGroups/CheckGroups.js +1 -4
- package/lib/Security/CheckRunner.js +22 -41
- package/lib/StatusHandler.js +12 -69
- package/lib/TestUtils.js +1 -6
- package/lib/Utils.js +27 -66
- package/lib/batch.js +17 -28
- package/lib/cache.js +1 -3
- package/lib/cli/definitions/parse-live-query-server.js +1 -3
- package/lib/cli/definitions/parse-server.js +1 -3
- package/lib/cli/parse-live-query-server.js +1 -6
- package/lib/cli/parse-server.js +11 -21
- package/lib/cli/utils/commander.js +13 -51
- package/lib/cli/utils/runner.js +1 -14
- package/lib/cloud-code/Parse.Cloud.js +71 -92
- package/lib/cryptoUtils.js +11 -19
- package/lib/defaults.js +2 -14
- package/lib/deprecated.js +1 -2
- package/lib/index.js +16 -34
- package/lib/logger.js +6 -13
- package/lib/middlewares.js +147 -151
- package/lib/password.js +6 -10
- package/lib/request.js +173 -2
- package/lib/requiredParameter.js +1 -3
- package/lib/rest.js +19 -41
- package/lib/triggers.js +54 -252
- package/lib/vendor/mongodbUrl.js +125 -305
- package/package.json +22 -19
- package/lib/cloud-code/HTTPResponse.js +0 -73
- package/lib/cloud-code/httpRequest.js +0 -192
|
@@ -4,52 +4,38 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.DefinedSchemas = void 0;
|
|
7
|
-
|
|
8
7
|
var _logger = require("../logger");
|
|
9
|
-
|
|
10
8
|
var _Config = _interopRequireDefault(require("../Config"));
|
|
11
|
-
|
|
12
9
|
var _SchemasRouter = require("../Routers/SchemasRouter");
|
|
13
|
-
|
|
14
10
|
var _SchemaController = require("../Controllers/SchemaController");
|
|
15
|
-
|
|
16
11
|
var _Options = require("../Options");
|
|
17
|
-
|
|
18
12
|
var Migrations = _interopRequireWildcard(require("./Migrations"));
|
|
19
|
-
|
|
13
|
+
var _Auth = _interopRequireDefault(require("../Auth"));
|
|
14
|
+
var _rest = _interopRequireDefault(require("../rest"));
|
|
20
15
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
21
|
-
|
|
22
16
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
23
|
-
|
|
24
17
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
-
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
31
|
-
|
|
18
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
19
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
21
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
22
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
32
23
|
// -disable-next Cannot resolve module `parse/node`.
|
|
33
24
|
const Parse = require('parse/node');
|
|
34
|
-
|
|
35
25
|
class DefinedSchemas {
|
|
36
26
|
constructor(schemaOptions, config) {
|
|
37
27
|
this.localSchemas = [];
|
|
38
28
|
this.config = _Config.default.get(config.appId);
|
|
39
29
|
this.schemaOptions = schemaOptions;
|
|
40
|
-
|
|
41
30
|
if (schemaOptions && schemaOptions.definitions) {
|
|
42
31
|
if (!Array.isArray(schemaOptions.definitions)) {
|
|
43
32
|
throw `"schema.definitions" must be an array of schemas`;
|
|
44
33
|
}
|
|
45
|
-
|
|
46
34
|
this.localSchemas = schemaOptions.definitions;
|
|
47
35
|
}
|
|
48
|
-
|
|
49
36
|
this.retries = 0;
|
|
50
37
|
this.maxRetries = 3;
|
|
51
38
|
}
|
|
52
|
-
|
|
53
39
|
async saveSchemaToDB(schema) {
|
|
54
40
|
const payload = {
|
|
55
41
|
className: schema.className,
|
|
@@ -60,15 +46,14 @@ class DefinedSchemas {
|
|
|
60
46
|
await (0, _SchemasRouter.internalCreateSchema)(schema.className, payload, this.config);
|
|
61
47
|
this.resetSchemaOps(schema);
|
|
62
48
|
}
|
|
63
|
-
|
|
64
49
|
resetSchemaOps(schema) {
|
|
65
50
|
// Reset ops like SDK
|
|
66
51
|
schema._fields = {};
|
|
67
52
|
schema._indexes = {};
|
|
68
|
-
}
|
|
69
|
-
// We cannot use SDK since routes are disabled
|
|
70
|
-
|
|
53
|
+
}
|
|
71
54
|
|
|
55
|
+
// Simulate update like the SDK
|
|
56
|
+
// We cannot use SDK since routes are disabled
|
|
72
57
|
async updateSchemaToDB(schema) {
|
|
73
58
|
const payload = {
|
|
74
59
|
className: schema.className,
|
|
@@ -79,32 +64,24 @@ class DefinedSchemas {
|
|
|
79
64
|
await (0, _SchemasRouter.internalUpdateSchema)(schema.className, payload, this.config);
|
|
80
65
|
this.resetSchemaOps(schema);
|
|
81
66
|
}
|
|
82
|
-
|
|
83
67
|
async execute() {
|
|
84
68
|
try {
|
|
85
69
|
_logger.logger.info('Running Migrations');
|
|
86
|
-
|
|
87
70
|
if (this.schemaOptions && this.schemaOptions.beforeMigration) {
|
|
88
71
|
await Promise.resolve(this.schemaOptions.beforeMigration());
|
|
89
72
|
}
|
|
90
|
-
|
|
91
73
|
await this.executeMigrations();
|
|
92
|
-
|
|
93
74
|
if (this.schemaOptions && this.schemaOptions.afterMigration) {
|
|
94
75
|
await Promise.resolve(this.schemaOptions.afterMigration());
|
|
95
76
|
}
|
|
96
|
-
|
|
97
77
|
_logger.logger.info('Running Migrations Completed');
|
|
98
78
|
} catch (e) {
|
|
99
79
|
_logger.logger.error(`Failed to run migrations: ${e}`);
|
|
100
|
-
|
|
101
80
|
if (process.env.NODE_ENV === 'production') process.exit(1);
|
|
102
81
|
}
|
|
103
82
|
}
|
|
104
|
-
|
|
105
83
|
async executeMigrations() {
|
|
106
84
|
let timeout = null;
|
|
107
|
-
|
|
108
85
|
try {
|
|
109
86
|
// Set up a time out in production
|
|
110
87
|
// if we fail to get schema
|
|
@@ -113,61 +90,52 @@ class DefinedSchemas {
|
|
|
113
90
|
if (process.env.NODE_ENV === 'production') {
|
|
114
91
|
timeout = setTimeout(() => {
|
|
115
92
|
_logger.logger.error('Timeout occurred during execution of migrations. Exiting...');
|
|
116
|
-
|
|
117
93
|
process.exit(1);
|
|
118
94
|
}, 20000);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
|
|
95
|
+
}
|
|
122
96
|
await this.createDeleteSession();
|
|
123
|
-
|
|
97
|
+
// -disable-next-line
|
|
98
|
+
const schemaController = await this.config.database.loadSchema();
|
|
99
|
+
this.allCloudSchemas = await schemaController.getAllClasses();
|
|
124
100
|
clearTimeout(timeout);
|
|
125
101
|
await Promise.all(this.localSchemas.map(async localSchema => this.saveOrUpdate(localSchema)));
|
|
126
102
|
this.checkForMissingSchemas();
|
|
127
103
|
await this.enforceCLPForNonProvidedClass();
|
|
128
104
|
} catch (e) {
|
|
129
105
|
if (timeout) clearTimeout(timeout);
|
|
130
|
-
|
|
131
106
|
if (this.retries < this.maxRetries) {
|
|
132
|
-
this.retries++;
|
|
107
|
+
this.retries++;
|
|
108
|
+
// first retry 1sec, 2sec, 3sec total 6sec retry sequence
|
|
133
109
|
// retry will only happen in case of deploying multi parse server instance
|
|
134
110
|
// at the same time. Modern systems like k8 avoid this by doing rolling updates
|
|
135
|
-
|
|
136
111
|
await this.wait(1000 * this.retries);
|
|
137
112
|
await this.executeMigrations();
|
|
138
113
|
} else {
|
|
139
114
|
_logger.logger.error(`Failed to run migrations: ${e}`);
|
|
140
|
-
|
|
141
115
|
if (process.env.NODE_ENV === 'production') process.exit(1);
|
|
142
116
|
}
|
|
143
117
|
}
|
|
144
118
|
}
|
|
145
|
-
|
|
146
119
|
checkForMissingSchemas() {
|
|
147
120
|
if (this.schemaOptions.strict !== true) {
|
|
148
121
|
return;
|
|
149
122
|
}
|
|
150
|
-
|
|
151
123
|
const cloudSchemas = this.allCloudSchemas.map(s => s.className);
|
|
152
124
|
const localSchemas = this.localSchemas.map(s => s.className);
|
|
153
125
|
const missingSchemas = cloudSchemas.filter(c => !localSchemas.includes(c) && !_SchemaController.systemClasses.includes(c));
|
|
154
|
-
|
|
155
126
|
if (new Set(localSchemas).size !== localSchemas.length) {
|
|
156
127
|
_logger.logger.error(`The list of schemas provided contains duplicated "className" "${localSchemas.join('","')}"`);
|
|
157
|
-
|
|
158
128
|
process.exit(1);
|
|
159
129
|
}
|
|
160
|
-
|
|
161
130
|
if (this.schemaOptions.strict && missingSchemas.length) {
|
|
162
131
|
_logger.logger.warn(`The following schemas are currently present in the database, but not explicitly defined in a schema: "${missingSchemas.join('", "')}"`);
|
|
163
132
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
133
|
+
}
|
|
166
134
|
|
|
135
|
+
// Required for testing purpose
|
|
167
136
|
wait(time) {
|
|
168
137
|
return new Promise(resolve => setTimeout(resolve, time));
|
|
169
138
|
}
|
|
170
|
-
|
|
171
139
|
async enforceCLPForNonProvidedClass() {
|
|
172
140
|
const nonProvidedClasses = this.allCloudSchemas.filter(cloudSchema => !this.localSchemas.some(localSchema => localSchema.className === cloudSchema.className));
|
|
173
141
|
await Promise.all(nonProvidedClasses.map(async schema => {
|
|
@@ -175,23 +143,18 @@ class DefinedSchemas {
|
|
|
175
143
|
this.handleCLP(schema, parseSchema);
|
|
176
144
|
await this.updateSchemaToDB(parseSchema);
|
|
177
145
|
}));
|
|
178
|
-
}
|
|
179
|
-
// a session is created
|
|
180
|
-
|
|
146
|
+
}
|
|
181
147
|
|
|
148
|
+
// Create a fake session since Parse do not create the _Session until
|
|
149
|
+
// a session is created
|
|
182
150
|
async createDeleteSession() {
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
await session.destroy({
|
|
188
|
-
useMasterKey: true
|
|
189
|
-
});
|
|
151
|
+
const {
|
|
152
|
+
response
|
|
153
|
+
} = await _rest.default.create(this.config, _Auth.default.master(this.config), '_Session', {});
|
|
154
|
+
await _rest.default.del(this.config, _Auth.default.master(this.config), '_Session', response.objectId);
|
|
190
155
|
}
|
|
191
|
-
|
|
192
156
|
async saveOrUpdate(localSchema) {
|
|
193
157
|
const cloudSchema = this.allCloudSchemas.find(sc => sc.className === localSchema.className);
|
|
194
|
-
|
|
195
158
|
if (cloudSchema) {
|
|
196
159
|
try {
|
|
197
160
|
await this.updateSchema(localSchema, cloudSchema);
|
|
@@ -206,10 +169,8 @@ class DefinedSchemas {
|
|
|
206
169
|
}
|
|
207
170
|
}
|
|
208
171
|
}
|
|
209
|
-
|
|
210
172
|
async saveSchema(localSchema) {
|
|
211
173
|
const newLocalSchema = new Parse.Schema(localSchema.className);
|
|
212
|
-
|
|
213
174
|
if (localSchema.fields) {
|
|
214
175
|
// Handle fields
|
|
215
176
|
Object.keys(localSchema.fields).filter(fieldName => !this.isProtectedFields(localSchema.className, fieldName)).forEach(fieldName => {
|
|
@@ -218,9 +179,8 @@ class DefinedSchemas {
|
|
|
218
179
|
this.handleFields(newLocalSchema, fieldName, field);
|
|
219
180
|
}
|
|
220
181
|
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
182
|
+
}
|
|
183
|
+
// Handle indexes
|
|
224
184
|
if (localSchema.indexes) {
|
|
225
185
|
Object.keys(localSchema.indexes).forEach(indexName => {
|
|
226
186
|
if (localSchema.indexes && !this.isProtectedIndex(localSchema.className, indexName)) {
|
|
@@ -228,40 +188,36 @@ class DefinedSchemas {
|
|
|
228
188
|
}
|
|
229
189
|
});
|
|
230
190
|
}
|
|
231
|
-
|
|
232
191
|
this.handleCLP(localSchema, newLocalSchema);
|
|
233
192
|
return await this.saveSchemaToDB(newLocalSchema);
|
|
234
193
|
}
|
|
235
|
-
|
|
236
194
|
async updateSchema(localSchema, cloudSchema) {
|
|
237
|
-
const newLocalSchema = new Parse.Schema(localSchema.className);
|
|
238
|
-
// Check addition
|
|
195
|
+
const newLocalSchema = new Parse.Schema(localSchema.className);
|
|
239
196
|
|
|
197
|
+
// Handle fields
|
|
198
|
+
// Check addition
|
|
240
199
|
if (localSchema.fields) {
|
|
241
200
|
Object.keys(localSchema.fields).filter(fieldName => !this.isProtectedFields(localSchema.className, fieldName)).forEach(fieldName => {
|
|
242
201
|
// -disable-next
|
|
243
202
|
const field = localSchema.fields[fieldName];
|
|
244
|
-
|
|
245
203
|
if (!cloudSchema.fields[fieldName]) {
|
|
246
204
|
this.handleFields(newLocalSchema, fieldName, field);
|
|
247
205
|
}
|
|
248
206
|
});
|
|
249
207
|
}
|
|
250
|
-
|
|
251
208
|
const fieldsToDelete = [];
|
|
252
209
|
const fieldsToRecreate = [];
|
|
253
|
-
const fieldsWithChangedParams = [];
|
|
210
|
+
const fieldsWithChangedParams = [];
|
|
254
211
|
|
|
212
|
+
// Check deletion
|
|
255
213
|
Object.keys(cloudSchema.fields).filter(fieldName => !this.isProtectedFields(localSchema.className, fieldName)).forEach(fieldName => {
|
|
256
214
|
const field = cloudSchema.fields[fieldName];
|
|
257
|
-
|
|
258
215
|
if (!localSchema.fields || !localSchema.fields[fieldName]) {
|
|
259
216
|
fieldsToDelete.push(fieldName);
|
|
260
217
|
return;
|
|
261
218
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
219
|
+
const localField = localSchema.fields[fieldName];
|
|
220
|
+
// Check if field has a changed type
|
|
265
221
|
if (!this.paramsAreEquals({
|
|
266
222
|
type: field.type,
|
|
267
223
|
targetClass: field.targetClass
|
|
@@ -281,29 +237,29 @@ class DefinedSchemas {
|
|
|
281
237
|
}
|
|
282
238
|
});
|
|
283
239
|
return;
|
|
284
|
-
}
|
|
285
|
-
|
|
240
|
+
}
|
|
286
241
|
|
|
242
|
+
// Check if something changed other than the type (like required, defaultValue)
|
|
287
243
|
if (!this.paramsAreEquals(field, localField)) {
|
|
288
244
|
fieldsWithChangedParams.push(fieldName);
|
|
289
245
|
}
|
|
290
246
|
});
|
|
291
|
-
|
|
292
247
|
if (this.schemaOptions.deleteExtraFields === true) {
|
|
293
248
|
fieldsToDelete.forEach(fieldName => {
|
|
294
249
|
newLocalSchema.deleteField(fieldName);
|
|
295
|
-
});
|
|
250
|
+
});
|
|
296
251
|
|
|
252
|
+
// Delete fields from the schema then apply changes
|
|
297
253
|
await this.updateSchemaToDB(newLocalSchema);
|
|
298
254
|
} else if (this.schemaOptions.strict === true && fieldsToDelete.length) {
|
|
299
255
|
_logger.logger.warn(`The following fields exist in the database for "${localSchema.className}", but are missing in the schema : "${fieldsToDelete.join('" ,"')}"`);
|
|
300
256
|
}
|
|
301
|
-
|
|
302
257
|
if (this.schemaOptions.recreateModifiedFields === true) {
|
|
303
258
|
fieldsToRecreate.forEach(field => {
|
|
304
259
|
newLocalSchema.deleteField(field.fieldName);
|
|
305
|
-
});
|
|
260
|
+
});
|
|
306
261
|
|
|
262
|
+
// Delete fields from the schema then apply changes
|
|
307
263
|
await this.updateSchemaToDB(newLocalSchema);
|
|
308
264
|
fieldsToRecreate.forEach(fieldInfo => {
|
|
309
265
|
if (localSchema.fields) {
|
|
@@ -315,19 +271,18 @@ class DefinedSchemas {
|
|
|
315
271
|
fieldsToRecreate.forEach(field => {
|
|
316
272
|
const from = field.from.type + (field.from.targetClass ? ` (${field.from.targetClass})` : '');
|
|
317
273
|
const to = field.to.type + (field.to.targetClass ? ` (${field.to.targetClass})` : '');
|
|
318
|
-
|
|
319
274
|
_logger.logger.warn(`The field "${field.fieldName}" type differ between the schema and the database for "${localSchema.className}"; Schema is defined as "${to}" and current database type is "${from}"`);
|
|
320
275
|
});
|
|
321
276
|
}
|
|
322
|
-
|
|
323
277
|
fieldsWithChangedParams.forEach(fieldName => {
|
|
324
278
|
if (localSchema.fields) {
|
|
325
279
|
const field = localSchema.fields[fieldName];
|
|
326
280
|
this.handleFields(newLocalSchema, fieldName, field);
|
|
327
281
|
}
|
|
328
|
-
});
|
|
329
|
-
// Check addition
|
|
282
|
+
});
|
|
330
283
|
|
|
284
|
+
// Handle Indexes
|
|
285
|
+
// Check addition
|
|
331
286
|
if (localSchema.indexes) {
|
|
332
287
|
Object.keys(localSchema.indexes).forEach(indexName => {
|
|
333
288
|
if ((!cloudSchema.indexes || !cloudSchema.indexes[indexName]) && !this.isProtectedIndex(localSchema.className, indexName)) {
|
|
@@ -337,9 +292,9 @@ class DefinedSchemas {
|
|
|
337
292
|
}
|
|
338
293
|
});
|
|
339
294
|
}
|
|
295
|
+
const indexesToAdd = [];
|
|
340
296
|
|
|
341
|
-
|
|
342
|
-
|
|
297
|
+
// Check deletion
|
|
343
298
|
if (cloudSchema.indexes) {
|
|
344
299
|
Object.keys(cloudSchema.indexes).forEach(indexName => {
|
|
345
300
|
if (!this.isProtectedIndex(localSchema.className, indexName)) {
|
|
@@ -347,7 +302,6 @@ class DefinedSchemas {
|
|
|
347
302
|
newLocalSchema.deleteIndex(indexName);
|
|
348
303
|
} else if (!this.paramsAreEquals(localSchema.indexes[indexName], cloudSchema.indexes[indexName])) {
|
|
349
304
|
newLocalSchema.deleteIndex(indexName);
|
|
350
|
-
|
|
351
305
|
if (localSchema.indexes) {
|
|
352
306
|
indexesToAdd.push({
|
|
353
307
|
indexName,
|
|
@@ -358,63 +312,52 @@ class DefinedSchemas {
|
|
|
358
312
|
}
|
|
359
313
|
});
|
|
360
314
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
315
|
+
this.handleCLP(localSchema, newLocalSchema, cloudSchema);
|
|
316
|
+
// Apply changes
|
|
317
|
+
await this.updateSchemaToDB(newLocalSchema);
|
|
318
|
+
// Apply new/changed indexes
|
|
366
319
|
if (indexesToAdd.length) {
|
|
367
320
|
_logger.logger.debug(`Updating indexes for "${newLocalSchema.className}" : ${indexesToAdd.join(' ,')}`);
|
|
368
|
-
|
|
369
321
|
indexesToAdd.forEach(o => newLocalSchema.addIndex(o.indexName, o.index));
|
|
370
322
|
await this.updateSchemaToDB(newLocalSchema);
|
|
371
323
|
}
|
|
372
324
|
}
|
|
373
|
-
|
|
374
325
|
handleCLP(localSchema, newLocalSchema, cloudSchema) {
|
|
375
326
|
if (!localSchema.classLevelPermissions && !cloudSchema) {
|
|
376
327
|
_logger.logger.warn(`classLevelPermissions not provided for ${localSchema.className}.`);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
328
|
+
}
|
|
329
|
+
// Use spread to avoid read only issue (encountered by Moumouls using directAccess)
|
|
330
|
+
const clp = _objectSpread({}, localSchema.classLevelPermissions) || {};
|
|
331
|
+
// To avoid inconsistency we need to remove all rights on addField
|
|
382
332
|
clp.addField = {};
|
|
383
333
|
newLocalSchema.setCLP(clp);
|
|
384
334
|
}
|
|
385
|
-
|
|
386
335
|
isProtectedFields(className, fieldName) {
|
|
387
336
|
return !!_SchemaController.defaultColumns._Default[fieldName] || !!(_SchemaController.defaultColumns[className] && _SchemaController.defaultColumns[className][fieldName]);
|
|
388
337
|
}
|
|
389
|
-
|
|
390
338
|
isProtectedIndex(className, indexName) {
|
|
391
339
|
const indexes = ['_id_'];
|
|
392
|
-
|
|
393
340
|
switch (className) {
|
|
394
341
|
case '_User':
|
|
395
342
|
indexes.push('case_insensitive_username', 'case_insensitive_email', 'username_1', 'email_1');
|
|
396
343
|
break;
|
|
397
|
-
|
|
398
344
|
case '_Role':
|
|
399
345
|
indexes.push('name_1');
|
|
400
346
|
break;
|
|
401
|
-
|
|
402
347
|
case '_Idempotency':
|
|
403
348
|
indexes.push('reqId_1');
|
|
404
349
|
break;
|
|
405
350
|
}
|
|
406
|
-
|
|
407
351
|
return indexes.indexOf(indexName) !== -1;
|
|
408
352
|
}
|
|
409
|
-
|
|
410
353
|
paramsAreEquals(objA, objB) {
|
|
411
354
|
const keysA = Object.keys(objA);
|
|
412
|
-
const keysB = Object.keys(objB);
|
|
355
|
+
const keysB = Object.keys(objB);
|
|
413
356
|
|
|
357
|
+
// Check key name
|
|
414
358
|
if (keysA.length !== keysB.length) return false;
|
|
415
359
|
return keysA.every(k => objA[k] === objB[k]);
|
|
416
360
|
}
|
|
417
|
-
|
|
418
361
|
handleFields(newLocalSchema, fieldName, field) {
|
|
419
362
|
if (field.type === 'Relation') {
|
|
420
363
|
newLocalSchema.addRelation(fieldName, field.targetClass);
|
|
@@ -424,8 +367,6 @@ class DefinedSchemas {
|
|
|
424
367
|
newLocalSchema.addField(fieldName, field.type, field);
|
|
425
368
|
}
|
|
426
369
|
}
|
|
427
|
-
|
|
428
370
|
}
|
|
429
|
-
|
|
430
371
|
exports.DefinedSchemas = DefinedSchemas;
|
|
431
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TY2hlbWFNaWdyYXRpb25zL0RlZmluZWRTY2hlbWFzLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsIkRlZmluZWRTY2hlbWFzIiwiY29uc3RydWN0b3IiLCJzY2hlbWFPcHRpb25zIiwiY29uZmlnIiwibG9jYWxTY2hlbWFzIiwiQ29uZmlnIiwiZ2V0IiwiYXBwSWQiLCJkZWZpbml0aW9ucyIsIkFycmF5IiwiaXNBcnJheSIsInJldHJpZXMiLCJtYXhSZXRyaWVzIiwic2F2ZVNjaGVtYVRvREIiLCJzY2hlbWEiLCJwYXlsb2FkIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiX2ZpZWxkcyIsImluZGV4ZXMiLCJfaW5kZXhlcyIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIl9jbHAiLCJyZXNldFNjaGVtYU9wcyIsInVwZGF0ZVNjaGVtYVRvREIiLCJleGVjdXRlIiwibG9nZ2VyIiwiaW5mbyIsImJlZm9yZU1pZ3JhdGlvbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhlY3V0ZU1pZ3JhdGlvbnMiLCJhZnRlck1pZ3JhdGlvbiIsImUiLCJlcnJvciIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsImV4aXQiLCJ0aW1lb3V0Iiwic2V0VGltZW91dCIsImNyZWF0ZURlbGV0ZVNlc3Npb24iLCJhbGxDbG91ZFNjaGVtYXMiLCJTY2hlbWEiLCJhbGwiLCJjbGVhclRpbWVvdXQiLCJtYXAiLCJsb2NhbFNjaGVtYSIsInNhdmVPclVwZGF0ZSIsImNoZWNrRm9yTWlzc2luZ1NjaGVtYXMiLCJlbmZvcmNlQ0xQRm9yTm9uUHJvdmlkZWRDbGFzcyIsIndhaXQiLCJzdHJpY3QiLCJjbG91ZFNjaGVtYXMiLCJzIiwibWlzc2luZ1NjaGVtYXMiLCJmaWx0ZXIiLCJjIiwiaW5jbHVkZXMiLCJzeXN0ZW1DbGFzc2VzIiwiU2V0Iiwic2l6ZSIsImxlbmd0aCIsImpvaW4iLCJ3YXJuIiwidGltZSIsIm5vblByb3ZpZGVkQ2xhc3NlcyIsImNsb3VkU2NoZW1hIiwic29tZSIsInBhcnNlU2NoZW1hIiwiaGFuZGxlQ0xQIiwic2Vzc2lvbiIsIlNlc3Npb24iLCJzYXZlIiwidXNlTWFzdGVyS2V5IiwiZGVzdHJveSIsImZpbmQiLCJzYyIsInVwZGF0ZVNjaGVtYSIsInNhdmVTY2hlbWEiLCJuZXdMb2NhbFNjaGVtYSIsIk9iamVjdCIsImtleXMiLCJmaWVsZE5hbWUiLCJpc1Byb3RlY3RlZEZpZWxkcyIsImZvckVhY2giLCJmaWVsZCIsImhhbmRsZUZpZWxkcyIsImluZGV4TmFtZSIsImlzUHJvdGVjdGVkSW5kZXgiLCJhZGRJbmRleCIsImZpZWxkc1RvRGVsZXRlIiwiZmllbGRzVG9SZWNyZWF0ZSIsImZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zIiwicHVzaCIsImxvY2FsRmllbGQiLCJwYXJhbXNBcmVFcXVhbHMiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmcm9tIiwidG8iLCJkZWxldGVFeHRyYUZpZWxkcyIsImRlbGV0ZUZpZWxkIiwicmVjcmVhdGVNb2RpZmllZEZpZWxkcyIsImZpZWxkSW5mbyIsImluZGV4ZXNUb0FkZCIsImRlbGV0ZUluZGV4IiwiaW5kZXgiLCJkZWJ1ZyIsIm8iLCJjbHAiLCJhZGRGaWVsZCIsInNldENMUCIsImRlZmF1bHRDb2x1bW5zIiwiX0RlZmF1bHQiLCJpbmRleE9mIiwib2JqQSIsIm9iakIiLCJrZXlzQSIsImtleXNCIiwiZXZlcnkiLCJrIiwiYWRkUmVsYXRpb24iLCJhZGRQb2ludGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBR0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBUEE7QUFDQSxNQUFNQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQXJCOztBQVFPLE1BQU1DLGNBQU4sQ0FBcUI7QUFRMUJDLEVBQUFBLFdBQVcsQ0FBQ0MsYUFBRCxFQUEwQ0MsTUFBMUMsRUFBc0U7QUFDL0UsU0FBS0MsWUFBTCxHQUFvQixFQUFwQjtBQUNBLFNBQUtELE1BQUwsR0FBY0UsZ0JBQU9D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RUFBQUEsZUFBZSxDQUE0Qm9CLElBQTVCLEVBQXFDQyxJQUFyQyxFQUE4QztBQUMzRCxVQUFNQyxLQUFlLEdBQUdyQyxNQUFNLENBQUNDLElBQVAsQ0FBWWtDLElBQVosQ0FBeEI7QUFDQSxVQUFNRyxLQUFlLEdBQUd0QyxNQUFNLENBQUNDLElBQVAsQ0FBWW1DLElBQVosQ0FBeEIsQ0FGMkQsQ0FJM0Q7O0FBQ0EsUUFBSUMsS0FBSyxDQUFDeEQsTUFBTixLQUFpQnlELEtBQUssQ0FBQ3pELE1BQTNCLEVBQW1DLE9BQU8sS0FBUDtBQUNuQyxXQUFPd0QsS0FBSyxDQUFDRSxLQUFOLENBQVlDLENBQUMsSUFBSUwsSUFBSSxDQUFDSyxDQUFELENBQUosS0FBWUosSUFBSSxDQUFDSSxDQUFELENBQWpDLENBQVA7QUFDRDs7QUFFRGxDLEVBQUFBLFlBQVksQ0FBQ1AsY0FBRCxFQUErQkcsU0FBL0IsRUFBa0RHLEtBQWxELEVBQStFO0FBQ3pGLFFBQUlBLEtBQUssQ0FBQ1csSUFBTixLQUFlLFVBQW5CLEVBQStCO0FBQzdCakIsTUFBQUEsY0FBYyxDQUFDMEMsV0FBZixDQUEyQnZDLFNBQTNCLEVBQXNDRyxLQUFLLENBQUNZLFdBQTVDO0FBQ0QsS0FGRCxNQUVPLElBQUlaLEtBQUssQ0FBQ1csSUFBTixLQUFlLFNBQW5CLEVBQThCO0FBQ25DakIsTUFBQUEsY0FBYyxDQUFDMkMsVUFBZixDQUEwQnhDLFNBQTFCLEVBQXFDRyxLQUFLLENBQUNZLFdBQTNDLEVBQXdEWixLQUF4RDtBQUNELEtBRk0sTUFFQTtBQUNMTixNQUFBQSxjQUFjLENBQUMrQixRQUFmLENBQXdCNUIsU0FBeEIsRUFBbUNHLEtBQUssQ0FBQ1csSUFBekMsRUFBK0NYLEtBQS9DO0FBQ0Q7QUFDRjs7QUE5YXlCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbi8vIEBmbG93LWRpc2FibGUtbmV4dCBDYW5ub3QgcmVzb2x2ZSBtb2R1bGUgYHBhcnNlL25vZGVgLlxuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgaW50ZXJuYWxDcmVhdGVTY2hlbWEsIGludGVybmFsVXBkYXRlU2NoZW1hIH0gZnJvbSAnLi4vUm91dGVycy9TY2hlbWFzUm91dGVyJztcbmltcG9ydCB7IGRlZmF1bHRDb2x1bW5zLCBzeXN0ZW1DbGFzc2VzIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQYXJzZVNlcnZlck9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmltcG9ydCAqIGFzIE1pZ3JhdGlvbnMgZnJvbSAnLi9NaWdyYXRpb25zJztcblxuZXhwb3J0IGNsYXNzIERlZmluZWRTY2hlbWFzIHtcbiAgY29uZmlnOiBQYXJzZVNlcnZlck9wdGlvbnM7XG4gIHNjaGVtYU9wdGlvbnM6IE1pZ3JhdGlvbnMuU2NoZW1hT3B0aW9ucztcbiAgbG9jYWxTY2hlbWFzOiBNaWdyYXRpb25zLkpTT05TY2hlbWFbXTtcbiAgcmV0cmllczogbnVtYmVyO1xuICBtYXhSZXRyaWVzOiBudW1iZXI7XG4gIGFsbENsb3VkU2NoZW1hczogUGFyc2UuU2NoZW1hW107XG5cbiAgY29uc3RydWN0b3Ioc2NoZW1hT3B0aW9uczogTWlncmF0aW9ucy5TY2hlbWFPcHRpb25zLCBjb25maWc6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICAgIHRoaXMubG9jYWxTY2hlbWFzID0gW107XG4gICAgdGhpcy5jb25maWcgPSBDb25maWcuZ2V0KGNvbmZpZy5hcHBJZCk7XG4gICAgdGhpcy5zY2hlbWFPcHRpb25zID0gc2NoZW1hT3B0aW9ucztcbiAgICBpZiAoc2NoZW1hT3B0aW9ucyAmJiBzY2hlbWFPcHRpb25zLmRlZmluaXRpb25zKSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2NoZW1hT3B0aW9ucy5kZWZpbml0aW9ucykpIHtcbiAgICAgICAgdGhyb3cgYFwic2NoZW1hLmRlZmluaXRpb25zXCIgbXVzdCBiZSBhbiBhcnJheSBvZiBzY2hlbWFzYDtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sb2NhbFNjaGVtYXMgPSBzY2hlbWFPcHRpb25zLmRlZmluaXRpb25zO1xuICAgIH1cblxuICAgIHRoaXMucmV0cmllcyA9IDA7XG4gICAgdGhpcy5tYXhSZXRyaWVzID0gMztcbiAgfVxuXG4gIGFzeW5jIHNhdmVTY2hlbWFUb0RCKHNjaGVtYTogUGFyc2UuU2NoZW1hKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmNsYXNzTmFtZSxcbiAgICAgIGZpZWxkczogc2NoZW1hLl9maWVsZHMsXG4gICAgICBpbmRleGVzOiBzY2hlbWEuX2luZGV4ZXMsXG4gICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHNjaGVtYS5fY2xwLFxuICAgIH07XG4gICAgYXdhaXQgaW50ZXJuYWxDcmVhdGVTY2hlbWEoc2NoZW1hLmNsYXNzTmFtZSwgcGF5bG9hZCwgdGhpcy5jb25maWcpO1xuICAgIHRoaXMucmVzZXRTY2hlbWFPcHMoc2NoZW1hKTtcbiAgfVxuXG4gIHJlc2V0U2NoZW1hT3BzKHNjaGVtYTogUGFyc2UuU2NoZW1hKSB7XG4gICAgLy8gUmVzZXQgb3BzIGxpa2UgU0RLXG4gICAgc2NoZW1hLl9maWVsZHMgPSB7fTtcbiAgICBzY2hlbWEuX2luZGV4ZXMgPSB7fTtcbiAgfVxuXG4gIC8vIFNpbXVsYXRlIHVwZGF0ZSBsaWtlIHRoZSBTREtcbiAgLy8gV2UgY2Fubm90IHVzZSBTREsgc2luY2Ugcm91dGVzIGFyZSBkaXNhYmxlZFxuICBhc3luYyB1cGRhdGVTY2hlbWFUb0RCKHNjaGVtYTogUGFyc2UuU2NoZW1hKSB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmNsYXNzTmFtZSxcbiAgICAgIGZpZWxkczogc2NoZW1hLl9maWVsZHMsXG4gICAgICBpbmRleGVzOiBzY2hlbWEuX2luZGV4ZXMsXG4gICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHNjaGVtYS5fY2xwLFxuICAgIH07XG4gICAgYXdhaXQgaW50ZXJuYWxVcGRhdGVTY2hlbWEoc2NoZW1hLmNsYXNzTmFtZSwgcGF5bG9hZCwgdGhpcy5jb25maWcpO1xuICAgIHRoaXMucmVzZXRTY2hlbWFPcHMoc2NoZW1hKTtcbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGUoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGxvZ2dlci5pbmZvKCdSdW5uaW5nIE1pZ3JhdGlvbnMnKTtcbiAgICAgIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMgJiYgdGhpcy5zY2hlbWFPcHRpb25zLmJlZm9yZU1pZ3JhdGlvbikge1xuICAgICAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUodGhpcy5zY2hlbWFPcHRpb25zLmJlZm9yZU1pZ3JhdGlvbigpKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5leGVjdXRlTWlncmF0aW9ucygpO1xuXG4gICAgICBpZiAodGhpcy5zY2hlbWFPcHRpb25zICYmIHRoaXMuc2NoZW1hT3B0aW9ucy5hZnRlck1pZ3JhdGlvbikge1xuICAgICAgICBhd2FpdCBQcm9taXNlLnJlc29sdmUodGhpcy5zY2hlbWFPcHRpb25zLmFmdGVyTWlncmF0aW9uKCkpO1xuICAgICAgfVxuXG4gICAgICBsb2dnZXIuaW5mbygnUnVubmluZyBNaWdyYXRpb25zIENvbXBsZXRlZCcpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIHJ1biBtaWdyYXRpb25zOiAke2V9YCk7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykgcHJvY2Vzcy5leGl0KDEpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGV4ZWN1dGVNaWdyYXRpb25zKCkge1xuICAgIGxldCB0aW1lb3V0ID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgLy8gU2V0IHVwIGEgdGltZSBvdXQgaW4gcHJvZHVjdGlvblxuICAgICAgLy8gaWYgd2UgZmFpbCB0byBnZXQgc2NoZW1hXG4gICAgICAvLyBwbTIgb3IgSzhzIGFuZCBtYW55IG90aGVyIHByb2Nlc3MgbWFuYWdlcnMgd2lsbCB0cnkgdG8gcmVzdGFydCB0aGUgcHJvY2Vzc1xuICAgICAgLy8gYWZ0ZXIgdGhlIGV4aXRcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1RpbWVvdXQgb2NjdXJyZWQgZHVyaW5nIGV4ZWN1dGlvbiBvZiBtaWdyYXRpb25zLiBFeGl0aW5nLi4uJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgICB9LCAyMDAwMCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEhhY2sgdG8gZm9yY2Ugc2Vzc2lvbiBzY2hlbWEgdG8gYmUgY3JlYXRlZFxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVEZWxldGVTZXNzaW9uKCk7XG4gICAgICB0aGlzLmFsbENsb3VkU2NoZW1hcyA9IGF3YWl0IFBhcnNlLlNjaGVtYS5hbGwoKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMubG9jYWxTY2hlbWFzLm1hcChhc3luYyBsb2NhbFNjaGVtYSA9PiB0aGlzLnNhdmVPclVwZGF0ZShsb2NhbFNjaGVtYSkpKTtcblxuICAgICAgdGhpcy5jaGVja0Zvck1pc3NpbmdTY2hlbWFzKCk7XG4gICAgICBhd2FpdCB0aGlzLmVuZm9yY2VDTFBGb3JOb25Qcm92aWRlZENsYXNzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKHRpbWVvdXQpIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIGlmICh0aGlzLnJldHJpZXMgPCB0aGlzLm1heFJldHJpZXMpIHtcbiAgICAgICAgdGhpcy5yZXRyaWVzKys7XG4gICAgICAgIC8vIGZpcnN0IHJldHJ5IDFzZWMsIDJzZWMsIDNzZWMgdG90YWwgNnNlYyByZXRyeSBzZXF1ZW5jZVxuICAgICAgICAvLyByZXRyeSB3aWxsIG9ubHkgaGFwcGVuIGluIGNhc2Ugb2YgZGVwbG95aW5nIG11bHRpIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgICAgICAvLyBhdCB0aGUgc2FtZSB0aW1lLiBNb2Rlcm4gc3lzdGVtcyBsaWtlIGs4IGF2b2lkIHRoaXMgYnkgZG9pbmcgcm9sbGluZyB1cGRhdGVzXG4gICAgICAgIGF3YWl0IHRoaXMud2FpdCgxMDAwICogdGhpcy5yZXRyaWVzKTtcbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlTWlncmF0aW9ucygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gcnVuIG1pZ3JhdGlvbnM6ICR7ZX1gKTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjaGVja0Zvck1pc3NpbmdTY2hlbWFzKCkge1xuICAgIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMuc3RyaWN0ICE9PSB0cnVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2xvdWRTY2hlbWFzID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMubWFwKHMgPT4gcy5jbGFzc05hbWUpO1xuICAgIGNvbnN0IGxvY2FsU2NoZW1hcyA9IHRoaXMubG9jYWxTY2hlbWFzLm1hcChzID0+IHMuY2xhc3NOYW1lKTtcbiAgICBjb25zdCBtaXNzaW5nU2NoZW1hcyA9IGNsb3VkU2NoZW1hcy5maWx0ZXIoXG4gICAgICBjID0+ICFsb2NhbFNjaGVtYXMuaW5jbHVkZXMoYykgJiYgIXN5c3RlbUNsYXNzZXMuaW5jbHVkZXMoYylcbiAgICApO1xuXG4gICAgaWYgKG5ldyBTZXQobG9jYWxTY2hlbWFzKS5zaXplICE9PSBsb2NhbFNjaGVtYXMubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBUaGUgbGlzdCBvZiBzY2hlbWFzIHByb3ZpZGVkIGNvbnRhaW5zIGR1cGxpY2F0ZWQgXCJjbGFzc05hbWVcIiAgXCIke2xvY2FsU2NoZW1hcy5qb2luKFxuICAgICAgICAgICdcIixcIidcbiAgICAgICAgKX1cImBcbiAgICAgICk7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2NoZW1hT3B0aW9ucy5zdHJpY3QgJiYgbWlzc2luZ1NjaGVtYXMubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgYFRoZSBmb2xsb3dpbmcgc2NoZW1hcyBhcmUgY3VycmVudGx5IHByZXNlbnQgaW4gdGhlIGRhdGFiYXNlLCBidXQgbm90IGV4cGxpY2l0bHkgZGVmaW5lZCBpbiBhIHNjaGVtYTogXCIke21pc3NpbmdTY2hlbWFzLmpvaW4oXG4gICAgICAgICAgJ1wiLCBcIidcbiAgICAgICAgKX1cImBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVxdWlyZWQgZm9yIHRlc3RpbmcgcHVycG9zZVxuICB3YWl0KHRpbWU6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgdGltZSkpO1xuICB9XG5cbiAgYXN5bmMgZW5mb3JjZUNMUEZvck5vblByb3ZpZGVkQ2xhc3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgbm9uUHJvdmlkZWRDbGFzc2VzID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMuZmlsdGVyKFxuICAgICAgY2xvdWRTY2hlbWEgPT5cbiAgICAgICAgIXRoaXMubG9jYWxTY2hlbWFzLnNvbWUobG9jYWxTY2hlbWEgPT4gbG9jYWxTY2hlbWEuY2xhc3NOYW1lID09PSBjbG91ZFNjaGVtYS5jbGFzc05hbWUpXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG5vblByb3ZpZGVkQ2xhc3Nlcy5tYXAoYXN5bmMgc2NoZW1hID0+IHtcbiAgICAgICAgY29uc3QgcGFyc2VTY2hlbWEgPSBuZXcgUGFyc2UuU2NoZW1hKHNjaGVtYS5jbGFzc05hbWUpO1xuICAgICAgICB0aGlzLmhhbmRsZUNMUChzY2hlbWEsIHBhcnNlU2NoZW1hKTtcbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVTY2hlbWFUb0RCKHBhcnNlU2NoZW1hKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIGZha2Ugc2Vzc2lvbiBzaW5jZSBQYXJzZSBkbyBub3QgY3JlYXRlIHRoZSBfU2Vzc2lvbiB1bnRpbFxuICAvLyBhIHNlc3Npb24gaXMgY3JlYXRlZFxuICBhc3luYyBjcmVhdGVEZWxldGVTZXNzaW9uKCkge1xuICAgIGNvbnN0IHNlc3Npb24gPSBuZXcgUGFyc2UuU2Vzc2lvbigpO1xuICAgIGF3YWl0IHNlc3Npb24uc2F2ZShudWxsLCB7IHVzZU1hc3RlcktleTogdHJ1ZSB9KTtcbiAgICBhd2FpdCBzZXNzaW9uLmRlc3Ryb3koeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH1cblxuICBhc3luYyBzYXZlT3JVcGRhdGUobG9jYWxTY2hlbWE6IE1pZ3JhdGlvbnMuSlNPTlNjaGVtYSkge1xuICAgIGNvbnN0IGNsb3VkU2NoZW1hID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMuZmluZChzYyA9PiBzYy5jbGFzc05hbWUgPT09IGxvY2FsU2NoZW1hLmNsYXNzTmFtZSk7XG4gICAgaWYgKGNsb3VkU2NoZW1hKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZVNjaGVtYShsb2NhbFNjaGVtYSwgY2xvdWRTY2hlbWEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBgRXJyb3IgZHVyaW5nIHVwZGF0ZSBvZiBzY2hlbWEgZm9yIHR5cGUgJHtjbG91ZFNjaGVtYS5jbGFzc05hbWV9OiAke2V9YDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlU2NoZW1hKGxvY2FsU2NoZW1hKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgYEVycm9yIHdoaWxlIHNhdmluZyBTY2hlbWEgZm9yIHR5cGUgJHtsb2NhbFNjaGVtYS5jbGFzc05hbWV9OiAke2V9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlU2NoZW1hKGxvY2FsU2NoZW1hOiBNaWdyYXRpb25zLkpTT05TY2hlbWEpIHtcbiAgICBjb25zdCBuZXdMb2NhbFNjaGVtYSA9IG5ldyBQYXJzZS5TY2hlbWEobG9jYWxTY2hlbWEuY2xhc3NOYW1lKTtcbiAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAvLyBIYW5kbGUgZmllbGRzXG4gICAgICBPYmplY3Qua2V5cyhsb2NhbFNjaGVtYS5maWVsZHMpXG4gICAgICAgIC5maWx0ZXIoZmllbGROYW1lID0+ICF0aGlzLmlzUHJvdGVjdGVkRmllbGRzKGxvY2FsU2NoZW1hLmNsYXNzTmFtZSwgZmllbGROYW1lKSlcbiAgICAgICAgLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVGaWVsZHMobmV3TG9jYWxTY2hlbWEsIGZpZWxkTmFtZSwgZmllbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIEhhbmRsZSBpbmRleGVzXG4gICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGxvY2FsU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMgJiYgIXRoaXMuaXNQcm90ZWN0ZWRJbmRleChsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGluZGV4TmFtZSkpIHtcbiAgICAgICAgICBuZXdMb2NhbFNjaGVtYS5hZGRJbmRleChpbmRleE5hbWUsIGxvY2FsU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuaGFuZGxlQ0xQKGxvY2FsU2NoZW1hLCBuZXdMb2NhbFNjaGVtYSk7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zYXZlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVTY2hlbWEobG9jYWxTY2hlbWE6IE1pZ3JhdGlvbnMuSlNPTlNjaGVtYSwgY2xvdWRTY2hlbWE6IFBhcnNlLlNjaGVtYSkge1xuICAgIGNvbnN0IG5ld0xvY2FsU2NoZW1hID0gbmV3IFBhcnNlLlNjaGVtYShsb2NhbFNjaGVtYS5jbGFzc05hbWUpO1xuXG4gICAgLy8gSGFuZGxlIGZpZWxkc1xuICAgIC8vIENoZWNrIGFkZGl0aW9uXG4gICAgaWYgKGxvY2FsU2NoZW1hLmZpZWxkcykge1xuICAgICAgT2JqZWN0LmtleXMobG9jYWxTY2hlbWEuZmllbGRzKVxuICAgICAgICAuZmlsdGVyKGZpZWxkTmFtZSA9PiAhdGhpcy5pc1Byb3RlY3RlZEZpZWxkcyhsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGZpZWxkTmFtZSkpXG4gICAgICAgIC5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBsb2NhbFNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICBpZiAoIWNsb3VkU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYSwgZmllbGROYW1lLCBmaWVsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWVsZHNUb0RlbGV0ZTogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBmaWVsZHNUb1JlY3JlYXRlOiB7XG4gICAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICAgIGZyb206IHsgdHlwZTogc3RyaW5nLCB0YXJnZXRDbGFzcz86IHN0cmluZyB9LFxuICAgICAgdG86IHsgdHlwZTogc3RyaW5nLCB0YXJnZXRDbGFzcz86IHN0cmluZyB9LFxuICAgIH1bXSA9IFtdO1xuICAgIGNvbnN0IGZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQ2hlY2sgZGVsZXRpb25cbiAgICBPYmplY3Qua2V5cyhjbG91ZFNjaGVtYS5maWVsZHMpXG4gICAgICAuZmlsdGVyKGZpZWxkTmFtZSA9PiAhdGhpcy5pc1Byb3RlY3RlZEZpZWxkcyhsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGZpZWxkTmFtZSkpXG4gICAgICAuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZCA9IGNsb3VkU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICBpZiAoIWxvY2FsU2NoZW1hLmZpZWxkcyB8fCAhbG9jYWxTY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICBmaWVsZHNUb0RlbGV0ZS5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbG9jYWxGaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAvLyBDaGVjayBpZiBmaWVsZCBoYXMgYSBjaGFuZ2VkIHR5cGVcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnBhcmFtc0FyZUVxdWFscyhcbiAgICAgICAgICAgIHsgdHlwZTogZmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgICB7IHR5cGU6IGxvY2FsRmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGxvY2FsRmllbGQudGFyZ2V0Q2xhc3MgfVxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgZmllbGRzVG9SZWNyZWF0ZS5wdXNoKHtcbiAgICAgICAgICAgIGZpZWxkTmFtZSxcbiAgICAgICAgICAgIGZyb206IHsgdHlwZTogZmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgICB0bzogeyB0eXBlOiBsb2NhbEZpZWxkLnR5cGUsIHRhcmdldENsYXNzOiBsb2NhbEZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgc29tZXRoaW5nIGNoYW5nZWQgb3RoZXIgdGhhbiB0aGUgdHlwZSAobGlrZSByZXF1aXJlZCwgZGVmYXVsdFZhbHVlKVxuICAgICAgICBpZiAoIXRoaXMucGFyYW1zQXJlRXF1YWxzKGZpZWxkLCBsb2NhbEZpZWxkKSkge1xuICAgICAgICAgIGZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAodGhpcy5zY2hlbWFPcHRpb25zLmRlbGV0ZUV4dHJhRmllbGRzID09PSB0cnVlKSB7XG4gICAgICBmaWVsZHNUb0RlbGV0ZS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gRGVsZXRlIGZpZWxkcyBmcm9tIHRoZSBzY2hlbWEgdGhlbiBhcHBseSBjaGFuZ2VzXG4gICAgICBhd2FpdCB0aGlzLnVwZGF0ZVNjaGVtYVRvREIobmV3TG9jYWxTY2hlbWEpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zY2hlbWFPcHRpb25zLnN0cmljdCA9PT0gdHJ1ZSAmJiBmaWVsZHNUb0RlbGV0ZS5sZW5ndGgpIHtcbiAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICBgVGhlIGZvbGxvd2luZyBmaWVsZHMgZXhpc3QgaW4gdGhlIGRhdGFiYXNlIGZvciBcIiR7XG4gICAgICAgICAgbG9jYWxTY2hlbWEuY2xhc3NOYW1lXG4gICAgICAgIH1cIiwgYnV0IGFyZSBtaXNzaW5nIGluIHRoZSBzY2hlbWEgOiBcIiR7ZmllbGRzVG9EZWxldGUuam9pbignXCIgLFwiJyl9XCJgXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMucmVjcmVhdGVNb2RpZmllZEZpZWxkcyA9PT0gdHJ1ZSkge1xuICAgICAgZmllbGRzVG9SZWNyZWF0ZS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgbmV3TG9jYWxTY2hlbWEuZGVsZXRlRmllbGQoZmllbGQuZmllbGROYW1lKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBEZWxldGUgZmllbGRzIGZyb20gdGhlIHNjaGVtYSB0aGVuIGFwcGx5IGNoYW5nZXNcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG5cbiAgICAgIGZpZWxkc1RvUmVjcmVhdGUuZm9yRWFjaChmaWVsZEluZm8gPT4ge1xuICAgICAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBsb2NhbFNjaGVtYS5maWVsZHNbZmllbGRJbmZvLmZpZWxkTmFtZV07XG4gICAgICAgICAgdGhpcy5oYW5kbGVGaWVsZHMobmV3TG9jYWxTY2hlbWEsIGZpZWxkSW5mby5maWVsZE5hbWUsIGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMuc3RyaWN0ID09PSB0cnVlICYmIGZpZWxkc1RvUmVjcmVhdGUubGVuZ3RoKSB7XG4gICAgICBmaWVsZHNUb1JlY3JlYXRlLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgICBjb25zdCBmcm9tID1cbiAgICAgICAgICBmaWVsZC5mcm9tLnR5cGUgKyAoZmllbGQuZnJvbS50YXJnZXRDbGFzcyA/IGAgKCR7ZmllbGQuZnJvbS50YXJnZXRDbGFzc30pYCA6ICcnKTtcbiAgICAgICAgY29uc3QgdG8gPSBmaWVsZC50by50eXBlICsgKGZpZWxkLnRvLnRhcmdldENsYXNzID8gYCAoJHtmaWVsZC50by50YXJnZXRDbGFzc30pYCA6ICcnKTtcblxuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBgVGhlIGZpZWxkIFwiJHtmaWVsZC5maWVsZE5hbWV9XCIgdHlwZSBkaWZmZXIgYmV0d2VlbiB0aGUgc2NoZW1hIGFuZCB0aGUgZGF0YWJhc2UgZm9yIFwiJHtsb2NhbFNjaGVtYS5jbGFzc05hbWV9XCI7IFNjaGVtYSBpcyBkZWZpbmVkIGFzIFwiJHt0b31cIiBhbmQgY3VycmVudCBkYXRhYmFzZSB0eXBlIGlzIFwiJHtmcm9tfVwiYFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZmllbGRzV2l0aENoYW5nZWRQYXJhbXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKGxvY2FsU2NoZW1hLmZpZWxkcykge1xuICAgICAgICBjb25zdCBmaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICB0aGlzLmhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYSwgZmllbGROYW1lLCBmaWVsZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgSW5kZXhlc1xuICAgIC8vIENoZWNrIGFkZGl0aW9uXG4gICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGxvY2FsU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICghY2xvdWRTY2hlbWEuaW5kZXhlcyB8fCAhY2xvdWRTY2hlbWEuaW5kZXhlc1tpbmRleE5hbWVdKSAmJlxuICAgICAgICAgICF0aGlzLmlzUHJvdGVjdGVkSW5kZXgobG9jYWxTY2hlbWEuY2xhc3NOYW1lLCBpbmRleE5hbWUpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChsb2NhbFNjaGVtYS5pbmRleGVzKSB7XG4gICAgICAgICAgICBuZXdMb2NhbFNjaGVtYS5hZGRJbmRleChpbmRleE5hbWUsIGxvY2FsU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleGVzVG9BZGQgPSBbXTtcblxuICAgIC8vIENoZWNrIGRlbGV0aW9uXG4gICAgaWYgKGNsb3VkU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGNsb3VkU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUHJvdGVjdGVkSW5kZXgobG9jYWxTY2hlbWEuY2xhc3NOYW1lLCBpbmRleE5hbWUpKSB7XG4gICAgICAgICAgaWYgKCFsb2NhbFNjaGVtYS5pbmRleGVzIHx8ICFsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0pIHtcbiAgICAgICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUluZGV4KGluZGV4TmFtZSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICF0aGlzLnBhcmFtc0FyZUVxdWFscyhsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0sIGNsb3VkU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUluZGV4KGluZGV4TmFtZSk7XG4gICAgICAgICAgICBpZiAobG9jYWxTY2hlbWEuaW5kZXhlcykge1xuICAgICAgICAgICAgICBpbmRleGVzVG9BZGQucHVzaCh7XG4gICAgICAgICAgICAgICAgaW5kZXhOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiBsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVDTFAobG9jYWxTY2hlbWEsIG5ld0xvY2FsU2NoZW1hLCBjbG91ZFNjaGVtYSk7XG4gICAgLy8gQXBwbHkgY2hhbmdlc1xuICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gICAgLy8gQXBwbHkgbmV3L2NoYW5nZWQgaW5kZXhlc1xuICAgIGlmIChpbmRleGVzVG9BZGQubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBVcGRhdGluZyBpbmRleGVzIGZvciBcIiR7bmV3TG9jYWxTY2hlbWEuY2xhc3NOYW1lfVwiIDogICR7aW5kZXhlc1RvQWRkLmpvaW4oJyAsJyl9YFxuICAgICAgKTtcbiAgICAgIGluZGV4ZXNUb0FkZC5mb3JFYWNoKG8gPT4gbmV3TG9jYWxTY2hlbWEuYWRkSW5kZXgoby5pbmRleE5hbWUsIG8uaW5kZXgpKTtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ0xQKFxuICAgIGxvY2FsU2NoZW1hOiBNaWdyYXRpb25zLkpTT05TY2hlbWEsXG4gICAgbmV3TG9jYWxTY2hlbWE6IFBhcnNlLlNjaGVtYSxcbiAgICBjbG91ZFNjaGVtYTogUGFyc2UuU2NoZW1hXG4gICkge1xuICAgIGlmICghbG9jYWxTY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zICYmICFjbG91ZFNjaGVtYSkge1xuICAgICAgbG9nZ2VyLndhcm4oYGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyBub3QgcHJvdmlkZWQgZm9yICR7bG9jYWxTY2hlbWEuY2xhc3NOYW1lfS5gKTtcbiAgICB9XG4gICAgLy8gVXNlIHNwcmVhZCB0byBhdm9pZCByZWFkIG9ubHkgaXNzdWUgKGVuY291bnRlcmVkIGJ5IE1vdW1vdWxzIHVzaW5nIGRpcmVjdEFjY2VzcylcbiAgICBjb25zdCBjbHAgPSAoeyAuLi5sb2NhbFNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMgfSB8fCB7fTogUGFyc2UuQ0xQLlBlcm1pc3Npb25zTWFwKTtcbiAgICAvLyBUbyBhdm9pZCBpbmNvbnNpc3RlbmN5IHdlIG5lZWQgdG8gcmVtb3ZlIGFsbCByaWdodHMgb24gYWRkRmllbGRcbiAgICBjbHAuYWRkRmllbGQgPSB7fTtcbiAgICBuZXdMb2NhbFNjaGVtYS5zZXRDTFAoY2xwKTtcbiAgfVxuXG4gIGlzUHJvdGVjdGVkRmllbGRzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiAoXG4gICAgICAhIWRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkTmFtZV0gfHxcbiAgICAgICEhKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gJiYgZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdKVxuICAgICk7XG4gIH1cblxuICBpc1Byb3RlY3RlZEluZGV4KGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleE5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IGluZGV4ZXMgPSBbJ19pZF8nXTtcbiAgICBzd2l0Y2ggKGNsYXNzTmFtZSkge1xuICAgICAgY2FzZSAnX1VzZXInOlxuICAgICAgICBpbmRleGVzLnB1c2goXG4gICAgICAgICAgJ2Nhc2VfaW5zZW5zaXRpdmVfdXNlcm5hbWUnLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX2VtYWlsJyxcbiAgICAgICAgICAndXNlcm5hbWVfMScsXG4gICAgICAgICAgJ2VtYWlsXzEnXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnX1JvbGUnOlxuICAgICAgICBpbmRleGVzLnB1c2goJ25hbWVfMScpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnX0lkZW1wb3RlbmN5JzpcbiAgICAgICAgaW5kZXhlcy5wdXNoKCdyZXFJZF8xJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBpbmRleGVzLmluZGV4T2YoaW5kZXhOYW1lKSAhPT0gLTE7XG4gIH1cblxuICBwYXJhbXNBcmVFcXVhbHM8VDogeyBba2V5OiBzdHJpbmddOiBhbnkgfT4ob2JqQTogVCwgb2JqQjogVCkge1xuICAgIGNvbnN0IGtleXNBOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKG9iakEpO1xuICAgIGNvbnN0IGtleXNCOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKG9iakIpO1xuXG4gICAgLy8gQ2hlY2sga2V5IG5hbWVcbiAgICBpZiAoa2V5c0EubGVuZ3RoICE9PSBrZXlzQi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4ga2V5c0EuZXZlcnkoayA9PiBvYmpBW2tdID09PSBvYmpCW2tdKTtcbiAgfVxuXG4gIGhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYTogUGFyc2UuU2NoZW1hLCBmaWVsZE5hbWU6IHN0cmluZywgZmllbGQ6IE1pZ3JhdGlvbnMuRmllbGRUeXBlKSB7XG4gICAgaWYgKGZpZWxkLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIG5ld0xvY2FsU2NoZW1hLmFkZFJlbGF0aW9uKGZpZWxkTmFtZSwgZmllbGQudGFyZ2V0Q2xhc3MpO1xuICAgIH0gZWxzZSBpZiAoZmllbGQudHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICBuZXdMb2NhbFNjaGVtYS5hZGRQb2ludGVyKGZpZWxkTmFtZSwgZmllbGQudGFyZ2V0Q2xhc3MsIGZpZWxkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3TG9jYWxTY2hlbWEuYWRkRmllbGQoZmllbGROYW1lLCBmaWVsZC50eXBlLCBmaWVsZCk7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
372
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJEZWZpbmVkU2NoZW1hcyIsImNvbnN0cnVjdG9yIiwic2NoZW1hT3B0aW9ucyIsImNvbmZpZyIsImxvY2FsU2NoZW1hcyIsIkNvbmZpZyIsImdldCIsImFwcElkIiwiZGVmaW5pdGlvbnMiLCJBcnJheSIsImlzQXJyYXkiLCJyZXRyaWVzIiwibWF4UmV0cmllcyIsInNhdmVTY2hlbWFUb0RCIiwic2NoZW1hIiwicGF5bG9hZCIsImNsYXNzTmFtZSIsImZpZWxkcyIsIl9maWVsZHMiLCJpbmRleGVzIiwiX2luZGV4ZXMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJfY2xwIiwiaW50ZXJuYWxDcmVhdGVTY2hlbWEiLCJyZXNldFNjaGVtYU9wcyIsInVwZGF0ZVNjaGVtYVRvREIiLCJpbnRlcm5hbFVwZGF0ZVNjaGVtYSIsImV4ZWN1dGUiLCJsb2dnZXIiLCJpbmZvIiwiYmVmb3JlTWlncmF0aW9uIiwiUHJvbWlzZSIsInJlc29sdmUiLCJleGVjdXRlTWlncmF0aW9ucyIsImFmdGVyTWlncmF0aW9uIiwiZSIsImVycm9yIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiZXhpdCIsInRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiY3JlYXRlRGVsZXRlU2Vzc2lvbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJkYXRhYmFzZSIsImxvYWRTY2hlbWEiLCJhbGxDbG91ZFNjaGVtYXMiLCJnZXRBbGxDbGFzc2VzIiwiY2xlYXJUaW1lb3V0IiwiYWxsIiwibWFwIiwibG9jYWxTY2hlbWEiLCJzYXZlT3JVcGRhdGUiLCJjaGVja0Zvck1pc3NpbmdTY2hlbWFzIiwiZW5mb3JjZUNMUEZvck5vblByb3ZpZGVkQ2xhc3MiLCJ3YWl0Iiwic3RyaWN0IiwiY2xvdWRTY2hlbWFzIiwicyIsIm1pc3NpbmdTY2hlbWFzIiwiZmlsdGVyIiwiYyIsImluY2x1ZGVzIiwic3lzdGVtQ2xhc3NlcyIsIlNldCIsInNpemUiLCJsZW5ndGgiLCJqb2luIiwid2FybiIsInRpbWUiLCJub25Qcm92aWRlZENsYXNzZXMiLCJjbG91ZFNjaGVtYSIsInNvbWUiLCJwYXJzZVNjaGVtYSIsIlNjaGVtYSIsImhhbmRsZUNMUCIsInJlc3BvbnNlIiwicmVzdCIsImNyZWF0ZSIsIkF1dGgiLCJtYXN0ZXIiLCJkZWwiLCJvYmplY3RJZCIsImZpbmQiLCJzYyIsInVwZGF0ZVNjaGVtYSIsInNhdmVTY2hlbWEiLCJuZXdMb2NhbFNjaGVtYSIsIk9iamVjdCIsImtleXMiLCJmaWVsZE5hbWUiLCJpc1Byb3RlY3RlZEZpZWxkcyIsImZvckVhY2giLCJmaWVsZCIsImhhbmRsZUZpZWxkcyIsImluZGV4TmFtZSIsImlzUHJvdGVjdGVkSW5kZXgiLCJhZGRJbmRleCIsImZpZWxkc1RvRGVsZXRlIiwiZmllbGRzVG9SZWNyZWF0ZSIsImZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zIiwicHVzaCIsImxvY2FsRmllbGQiLCJwYXJhbXNBcmVFcXVhbHMiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmcm9tIiwidG8iLCJkZWxldGVFeHRyYUZpZWxkcyIsImRlbGV0ZUZpZWxkIiwicmVjcmVhdGVNb2RpZmllZEZpZWxkcyIsImZpZWxkSW5mbyIsImluZGV4ZXNUb0FkZCIsImRlbGV0ZUluZGV4IiwiaW5kZXgiLCJkZWJ1ZyIsIm8iLCJjbHAiLCJhZGRGaWVsZCIsInNldENMUCIsImRlZmF1bHRDb2x1bW5zIiwiX0RlZmF1bHQiLCJpbmRleE9mIiwib2JqQSIsIm9iakIiLCJrZXlzQSIsImtleXNCIiwiZXZlcnkiLCJrIiwiYWRkUmVsYXRpb24iLCJhZGRQb2ludGVyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL1NjaGVtYU1pZ3JhdGlvbnMvRGVmaW5lZFNjaGVtYXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbi8vIEBmbG93LWRpc2FibGUtbmV4dCBDYW5ub3QgcmVzb2x2ZSBtb2R1bGUgYHBhcnNlL25vZGVgLlxuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgaW50ZXJuYWxDcmVhdGVTY2hlbWEsIGludGVybmFsVXBkYXRlU2NoZW1hIH0gZnJvbSAnLi4vUm91dGVycy9TY2hlbWFzUm91dGVyJztcbmltcG9ydCB7IGRlZmF1bHRDb2x1bW5zLCBzeXN0ZW1DbGFzc2VzIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQYXJzZVNlcnZlck9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmltcG9ydCAqIGFzIE1pZ3JhdGlvbnMgZnJvbSAnLi9NaWdyYXRpb25zJztcbmltcG9ydCBBdXRoIGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5cbmV4cG9ydCBjbGFzcyBEZWZpbmVkU2NoZW1hcyB7XG4gIGNvbmZpZzogUGFyc2VTZXJ2ZXJPcHRpb25zO1xuICBzY2hlbWFPcHRpb25zOiBNaWdyYXRpb25zLlNjaGVtYU9wdGlvbnM7XG4gIGxvY2FsU2NoZW1hczogTWlncmF0aW9ucy5KU09OU2NoZW1hW107XG4gIHJldHJpZXM6IG51bWJlcjtcbiAgbWF4UmV0cmllczogbnVtYmVyO1xuICBhbGxDbG91ZFNjaGVtYXM6IFBhcnNlLlNjaGVtYVtdO1xuXG4gIGNvbnN0cnVjdG9yKHNjaGVtYU9wdGlvbnM6IE1pZ3JhdGlvbnMuU2NoZW1hT3B0aW9ucywgY29uZmlnOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgICB0aGlzLmxvY2FsU2NoZW1hcyA9IFtdO1xuICAgIHRoaXMuY29uZmlnID0gQ29uZmlnLmdldChjb25maWcuYXBwSWQpO1xuICAgIHRoaXMuc2NoZW1hT3B0aW9ucyA9IHNjaGVtYU9wdGlvbnM7XG4gICAgaWYgKHNjaGVtYU9wdGlvbnMgJiYgc2NoZW1hT3B0aW9ucy5kZWZpbml0aW9ucykge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHNjaGVtYU9wdGlvbnMuZGVmaW5pdGlvbnMpKSB7XG4gICAgICAgIHRocm93IGBcInNjaGVtYS5kZWZpbml0aW9uc1wiIG11c3QgYmUgYW4gYXJyYXkgb2Ygc2NoZW1hc2A7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubG9jYWxTY2hlbWFzID0gc2NoZW1hT3B0aW9ucy5kZWZpbml0aW9ucztcbiAgICB9XG5cbiAgICB0aGlzLnJldHJpZXMgPSAwO1xuICAgIHRoaXMubWF4UmV0cmllcyA9IDM7XG4gIH1cblxuICBhc3luYyBzYXZlU2NoZW1hVG9EQihzY2hlbWE6IFBhcnNlLlNjaGVtYSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBjbGFzc05hbWU6IHNjaGVtYS5jbGFzc05hbWUsXG4gICAgICBmaWVsZHM6IHNjaGVtYS5fZmllbGRzLFxuICAgICAgaW5kZXhlczogc2NoZW1hLl9pbmRleGVzLFxuICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBzY2hlbWEuX2NscCxcbiAgICB9O1xuICAgIGF3YWl0IGludGVybmFsQ3JlYXRlU2NoZW1hKHNjaGVtYS5jbGFzc05hbWUsIHBheWxvYWQsIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnJlc2V0U2NoZW1hT3BzKHNjaGVtYSk7XG4gIH1cblxuICByZXNldFNjaGVtYU9wcyhzY2hlbWE6IFBhcnNlLlNjaGVtYSkge1xuICAgIC8vIFJlc2V0IG9wcyBsaWtlIFNES1xuICAgIHNjaGVtYS5fZmllbGRzID0ge307XG4gICAgc2NoZW1hLl9pbmRleGVzID0ge307XG4gIH1cblxuICAvLyBTaW11bGF0ZSB1cGRhdGUgbGlrZSB0aGUgU0RLXG4gIC8vIFdlIGNhbm5vdCB1c2UgU0RLIHNpbmNlIHJvdXRlcyBhcmUgZGlzYWJsZWRcbiAgYXN5bmMgdXBkYXRlU2NoZW1hVG9EQihzY2hlbWE6IFBhcnNlLlNjaGVtYSkge1xuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICBjbGFzc05hbWU6IHNjaGVtYS5jbGFzc05hbWUsXG4gICAgICBmaWVsZHM6IHNjaGVtYS5fZmllbGRzLFxuICAgICAgaW5kZXhlczogc2NoZW1hLl9pbmRleGVzLFxuICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBzY2hlbWEuX2NscCxcbiAgICB9O1xuICAgIGF3YWl0IGludGVybmFsVXBkYXRlU2NoZW1hKHNjaGVtYS5jbGFzc05hbWUsIHBheWxvYWQsIHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnJlc2V0U2NoZW1hT3BzKHNjaGVtYSk7XG4gIH1cblxuICBhc3luYyBleGVjdXRlKCkge1xuICAgIHRyeSB7XG4gICAgICBsb2dnZXIuaW5mbygnUnVubmluZyBNaWdyYXRpb25zJyk7XG4gICAgICBpZiAodGhpcy5zY2hlbWFPcHRpb25zICYmIHRoaXMuc2NoZW1hT3B0aW9ucy5iZWZvcmVNaWdyYXRpb24pIHtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMuc2NoZW1hT3B0aW9ucy5iZWZvcmVNaWdyYXRpb24oKSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZU1pZ3JhdGlvbnMoKTtcblxuICAgICAgaWYgKHRoaXMuc2NoZW1hT3B0aW9ucyAmJiB0aGlzLnNjaGVtYU9wdGlvbnMuYWZ0ZXJNaWdyYXRpb24pIHtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMuc2NoZW1hT3B0aW9ucy5hZnRlck1pZ3JhdGlvbigpKTtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmluZm8oJ1J1bm5pbmcgTWlncmF0aW9ucyBDb21wbGV0ZWQnKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYEZhaWxlZCB0byBydW4gbWlncmF0aW9uczogJHtlfWApO1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBleGVjdXRlTWlncmF0aW9ucygpIHtcbiAgICBsZXQgdGltZW91dCA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFNldCB1cCBhIHRpbWUgb3V0IGluIHByb2R1Y3Rpb25cbiAgICAgIC8vIGlmIHdlIGZhaWwgdG8gZ2V0IHNjaGVtYVxuICAgICAgLy8gcG0yIG9yIEs4cyBhbmQgbWFueSBvdGhlciBwcm9jZXNzIG1hbmFnZXJzIHdpbGwgdHJ5IHRvIHJlc3RhcnQgdGhlIHByb2Nlc3NcbiAgICAgIC8vIGFmdGVyIHRoZSBleGl0XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdUaW1lb3V0IG9jY3VycmVkIGR1cmluZyBleGVjdXRpb24gb2YgbWlncmF0aW9ucy4gRXhpdGluZy4uLicpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgfSwgMjAwMDApO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZURlbGV0ZVNlc3Npb24oKTtcbiAgICAgIC8vIEBmbG93LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICBjb25zdCBzY2hlbWFDb250cm9sbGVyID0gYXdhaXQgdGhpcy5jb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSgpO1xuICAgICAgdGhpcy5hbGxDbG91ZFNjaGVtYXMgPSBhd2FpdCBzY2hlbWFDb250cm9sbGVyLmdldEFsbENsYXNzZXMoKTtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMubG9jYWxTY2hlbWFzLm1hcChhc3luYyBsb2NhbFNjaGVtYSA9PiB0aGlzLnNhdmVPclVwZGF0ZShsb2NhbFNjaGVtYSkpKTtcblxuICAgICAgdGhpcy5jaGVja0Zvck1pc3NpbmdTY2hlbWFzKCk7XG4gICAgICBhd2FpdCB0aGlzLmVuZm9yY2VDTFBGb3JOb25Qcm92aWRlZENsYXNzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKHRpbWVvdXQpIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIGlmICh0aGlzLnJldHJpZXMgPCB0aGlzLm1heFJldHJpZXMpIHtcbiAgICAgICAgdGhpcy5yZXRyaWVzKys7XG4gICAgICAgIC8vIGZpcnN0IHJldHJ5IDFzZWMsIDJzZWMsIDNzZWMgdG90YWwgNnNlYyByZXRyeSBzZXF1ZW5jZVxuICAgICAgICAvLyByZXRyeSB3aWxsIG9ubHkgaGFwcGVuIGluIGNhc2Ugb2YgZGVwbG95aW5nIG11bHRpIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgICAgICAvLyBhdCB0aGUgc2FtZSB0aW1lLiBNb2Rlcm4gc3lzdGVtcyBsaWtlIGs4IGF2b2lkIHRoaXMgYnkgZG9pbmcgcm9sbGluZyB1cGRhdGVzXG4gICAgICAgIGF3YWl0IHRoaXMud2FpdCgxMDAwICogdGhpcy5yZXRyaWVzKTtcbiAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlTWlncmF0aW9ucygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gcnVuIG1pZ3JhdGlvbnM6ICR7ZX1gKTtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjaGVja0Zvck1pc3NpbmdTY2hlbWFzKCkge1xuICAgIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMuc3RyaWN0ICE9PSB0cnVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2xvdWRTY2hlbWFzID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMubWFwKHMgPT4gcy5jbGFzc05hbWUpO1xuICAgIGNvbnN0IGxvY2FsU2NoZW1hcyA9IHRoaXMubG9jYWxTY2hlbWFzLm1hcChzID0+IHMuY2xhc3NOYW1lKTtcbiAgICBjb25zdCBtaXNzaW5nU2NoZW1hcyA9IGNsb3VkU2NoZW1hcy5maWx0ZXIoXG4gICAgICBjID0+ICFsb2NhbFNjaGVtYXMuaW5jbHVkZXMoYykgJiYgIXN5c3RlbUNsYXNzZXMuaW5jbHVkZXMoYylcbiAgICApO1xuXG4gICAgaWYgKG5ldyBTZXQobG9jYWxTY2hlbWFzKS5zaXplICE9PSBsb2NhbFNjaGVtYXMubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBUaGUgbGlzdCBvZiBzY2hlbWFzIHByb3ZpZGVkIGNvbnRhaW5zIGR1cGxpY2F0ZWQgXCJjbGFzc05hbWVcIiAgXCIke2xvY2FsU2NoZW1hcy5qb2luKFxuICAgICAgICAgICdcIixcIidcbiAgICAgICAgKX1cImBcbiAgICAgICk7XG4gICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc2NoZW1hT3B0aW9ucy5zdHJpY3QgJiYgbWlzc2luZ1NjaGVtYXMubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIud2FybihcbiAgICAgICAgYFRoZSBmb2xsb3dpbmcgc2NoZW1hcyBhcmUgY3VycmVudGx5IHByZXNlbnQgaW4gdGhlIGRhdGFiYXNlLCBidXQgbm90IGV4cGxpY2l0bHkgZGVmaW5lZCBpbiBhIHNjaGVtYTogXCIke21pc3NpbmdTY2hlbWFzLmpvaW4oXG4gICAgICAgICAgJ1wiLCBcIidcbiAgICAgICAgKX1cImBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVxdWlyZWQgZm9yIHRlc3RpbmcgcHVycG9zZVxuICB3YWl0KHRpbWU6IG51bWJlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgdGltZSkpO1xuICB9XG5cbiAgYXN5bmMgZW5mb3JjZUNMUEZvck5vblByb3ZpZGVkQ2xhc3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgbm9uUHJvdmlkZWRDbGFzc2VzID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMuZmlsdGVyKFxuICAgICAgY2xvdWRTY2hlbWEgPT5cbiAgICAgICAgIXRoaXMubG9jYWxTY2hlbWFzLnNvbWUobG9jYWxTY2hlbWEgPT4gbG9jYWxTY2hlbWEuY2xhc3NOYW1lID09PSBjbG91ZFNjaGVtYS5jbGFzc05hbWUpXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG5vblByb3ZpZGVkQ2xhc3Nlcy5tYXAoYXN5bmMgc2NoZW1hID0+IHtcbiAgICAgICAgY29uc3QgcGFyc2VTY2hlbWEgPSBuZXcgUGFyc2UuU2NoZW1hKHNjaGVtYS5jbGFzc05hbWUpO1xuICAgICAgICB0aGlzLmhhbmRsZUNMUChzY2hlbWEsIHBhcnNlU2NoZW1hKTtcbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVTY2hlbWFUb0RCKHBhcnNlU2NoZW1hKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIGZha2Ugc2Vzc2lvbiBzaW5jZSBQYXJzZSBkbyBub3QgY3JlYXRlIHRoZSBfU2Vzc2lvbiB1bnRpbFxuICAvLyBhIHNlc3Npb24gaXMgY3JlYXRlZFxuICBhc3luYyBjcmVhdGVEZWxldGVTZXNzaW9uKCkge1xuICAgIGNvbnN0IHsgcmVzcG9uc2UgfSA9IGF3YWl0IHJlc3QuY3JlYXRlKHRoaXMuY29uZmlnLCBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyksICdfU2Vzc2lvbicsIHt9KTtcbiAgICBhd2FpdCByZXN0LmRlbCh0aGlzLmNvbmZpZywgQXV0aC5tYXN0ZXIodGhpcy5jb25maWcpLCAnX1Nlc3Npb24nLCByZXNwb25zZS5vYmplY3RJZCk7XG4gIH1cblxuICBhc3luYyBzYXZlT3JVcGRhdGUobG9jYWxTY2hlbWE6IE1pZ3JhdGlvbnMuSlNPTlNjaGVtYSkge1xuICAgIGNvbnN0IGNsb3VkU2NoZW1hID0gdGhpcy5hbGxDbG91ZFNjaGVtYXMuZmluZChzYyA9PiBzYy5jbGFzc05hbWUgPT09IGxvY2FsU2NoZW1hLmNsYXNzTmFtZSk7XG4gICAgaWYgKGNsb3VkU2NoZW1hKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnVwZGF0ZVNjaGVtYShsb2NhbFNjaGVtYSwgY2xvdWRTY2hlbWEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBgRXJyb3IgZHVyaW5nIHVwZGF0ZSBvZiBzY2hlbWEgZm9yIHR5cGUgJHtjbG91ZFNjaGVtYS5jbGFzc05hbWV9OiAke2V9YDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlU2NoZW1hKGxvY2FsU2NoZW1hKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgYEVycm9yIHdoaWxlIHNhdmluZyBTY2hlbWEgZm9yIHR5cGUgJHtsb2NhbFNjaGVtYS5jbGFzc05hbWV9OiAke2V9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlU2NoZW1hKGxvY2FsU2NoZW1hOiBNaWdyYXRpb25zLkpTT05TY2hlbWEpIHtcbiAgICBjb25zdCBuZXdMb2NhbFNjaGVtYSA9IG5ldyBQYXJzZS5TY2hlbWEobG9jYWxTY2hlbWEuY2xhc3NOYW1lKTtcbiAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAvLyBIYW5kbGUgZmllbGRzXG4gICAgICBPYmplY3Qua2V5cyhsb2NhbFNjaGVtYS5maWVsZHMpXG4gICAgICAgIC5maWx0ZXIoZmllbGROYW1lID0+ICF0aGlzLmlzUHJvdGVjdGVkRmllbGRzKGxvY2FsU2NoZW1hLmNsYXNzTmFtZSwgZmllbGROYW1lKSlcbiAgICAgICAgLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVGaWVsZHMobmV3TG9jYWxTY2hlbWEsIGZpZWxkTmFtZSwgZmllbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIEhhbmRsZSBpbmRleGVzXG4gICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGxvY2FsU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMgJiYgIXRoaXMuaXNQcm90ZWN0ZWRJbmRleChsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGluZGV4TmFtZSkpIHtcbiAgICAgICAgICBuZXdMb2NhbFNjaGVtYS5hZGRJbmRleChpbmRleE5hbWUsIGxvY2FsU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuaGFuZGxlQ0xQKGxvY2FsU2NoZW1hLCBuZXdMb2NhbFNjaGVtYSk7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zYXZlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVTY2hlbWEobG9jYWxTY2hlbWE6IE1pZ3JhdGlvbnMuSlNPTlNjaGVtYSwgY2xvdWRTY2hlbWE6IFBhcnNlLlNjaGVtYSkge1xuICAgIGNvbnN0IG5ld0xvY2FsU2NoZW1hID0gbmV3IFBhcnNlLlNjaGVtYShsb2NhbFNjaGVtYS5jbGFzc05hbWUpO1xuXG4gICAgLy8gSGFuZGxlIGZpZWxkc1xuICAgIC8vIENoZWNrIGFkZGl0aW9uXG4gICAgaWYgKGxvY2FsU2NoZW1hLmZpZWxkcykge1xuICAgICAgT2JqZWN0LmtleXMobG9jYWxTY2hlbWEuZmllbGRzKVxuICAgICAgICAuZmlsdGVyKGZpZWxkTmFtZSA9PiAhdGhpcy5pc1Byb3RlY3RlZEZpZWxkcyhsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGZpZWxkTmFtZSkpXG4gICAgICAgIC5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBsb2NhbFNjaGVtYS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICBpZiAoIWNsb3VkU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYSwgZmllbGROYW1lLCBmaWVsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWVsZHNUb0RlbGV0ZTogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBmaWVsZHNUb1JlY3JlYXRlOiB7XG4gICAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICAgIGZyb206IHsgdHlwZTogc3RyaW5nLCB0YXJnZXRDbGFzcz86IHN0cmluZyB9LFxuICAgICAgdG86IHsgdHlwZTogc3RyaW5nLCB0YXJnZXRDbGFzcz86IHN0cmluZyB9LFxuICAgIH1bXSA9IFtdO1xuICAgIGNvbnN0IGZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8gQ2hlY2sgZGVsZXRpb25cbiAgICBPYmplY3Qua2V5cyhjbG91ZFNjaGVtYS5maWVsZHMpXG4gICAgICAuZmlsdGVyKGZpZWxkTmFtZSA9PiAhdGhpcy5pc1Byb3RlY3RlZEZpZWxkcyhsb2NhbFNjaGVtYS5jbGFzc05hbWUsIGZpZWxkTmFtZSkpXG4gICAgICAuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZCA9IGNsb3VkU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICBpZiAoIWxvY2FsU2NoZW1hLmZpZWxkcyB8fCAhbG9jYWxTY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICBmaWVsZHNUb0RlbGV0ZS5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbG9jYWxGaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAvLyBDaGVjayBpZiBmaWVsZCBoYXMgYSBjaGFuZ2VkIHR5cGVcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnBhcmFtc0FyZUVxdWFscyhcbiAgICAgICAgICAgIHsgdHlwZTogZmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgICB7IHR5cGU6IGxvY2FsRmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGxvY2FsRmllbGQudGFyZ2V0Q2xhc3MgfVxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgZmllbGRzVG9SZWNyZWF0ZS5wdXNoKHtcbiAgICAgICAgICAgIGZpZWxkTmFtZSxcbiAgICAgICAgICAgIGZyb206IHsgdHlwZTogZmllbGQudHlwZSwgdGFyZ2V0Q2xhc3M6IGZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgICB0bzogeyB0eXBlOiBsb2NhbEZpZWxkLnR5cGUsIHRhcmdldENsYXNzOiBsb2NhbEZpZWxkLnRhcmdldENsYXNzIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgc29tZXRoaW5nIGNoYW5nZWQgb3RoZXIgdGhhbiB0aGUgdHlwZSAobGlrZSByZXF1aXJlZCwgZGVmYXVsdFZhbHVlKVxuICAgICAgICBpZiAoIXRoaXMucGFyYW1zQXJlRXF1YWxzKGZpZWxkLCBsb2NhbEZpZWxkKSkge1xuICAgICAgICAgIGZpZWxkc1dpdGhDaGFuZ2VkUGFyYW1zLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAodGhpcy5zY2hlbWFPcHRpb25zLmRlbGV0ZUV4dHJhRmllbGRzID09PSB0cnVlKSB7XG4gICAgICBmaWVsZHNUb0RlbGV0ZS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gRGVsZXRlIGZpZWxkcyBmcm9tIHRoZSBzY2hlbWEgdGhlbiBhcHBseSBjaGFuZ2VzXG4gICAgICBhd2FpdCB0aGlzLnVwZGF0ZVNjaGVtYVRvREIobmV3TG9jYWxTY2hlbWEpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zY2hlbWFPcHRpb25zLnN0cmljdCA9PT0gdHJ1ZSAmJiBmaWVsZHNUb0RlbGV0ZS5sZW5ndGgpIHtcbiAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICBgVGhlIGZvbGxvd2luZyBmaWVsZHMgZXhpc3QgaW4gdGhlIGRhdGFiYXNlIGZvciBcIiR7XG4gICAgICAgICAgbG9jYWxTY2hlbWEuY2xhc3NOYW1lXG4gICAgICAgIH1cIiwgYnV0IGFyZSBtaXNzaW5nIGluIHRoZSBzY2hlbWEgOiBcIiR7ZmllbGRzVG9EZWxldGUuam9pbignXCIgLFwiJyl9XCJgXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMucmVjcmVhdGVNb2RpZmllZEZpZWxkcyA9PT0gdHJ1ZSkge1xuICAgICAgZmllbGRzVG9SZWNyZWF0ZS5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgbmV3TG9jYWxTY2hlbWEuZGVsZXRlRmllbGQoZmllbGQuZmllbGROYW1lKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBEZWxldGUgZmllbGRzIGZyb20gdGhlIHNjaGVtYSB0aGVuIGFwcGx5IGNoYW5nZXNcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG5cbiAgICAgIGZpZWxkc1RvUmVjcmVhdGUuZm9yRWFjaChmaWVsZEluZm8gPT4ge1xuICAgICAgICBpZiAobG9jYWxTY2hlbWEuZmllbGRzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSBsb2NhbFNjaGVtYS5maWVsZHNbZmllbGRJbmZvLmZpZWxkTmFtZV07XG4gICAgICAgICAgdGhpcy5oYW5kbGVGaWVsZHMobmV3TG9jYWxTY2hlbWEsIGZpZWxkSW5mby5maWVsZE5hbWUsIGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNjaGVtYU9wdGlvbnMuc3RyaWN0ID09PSB0cnVlICYmIGZpZWxkc1RvUmVjcmVhdGUubGVuZ3RoKSB7XG4gICAgICBmaWVsZHNUb1JlY3JlYXRlLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgICBjb25zdCBmcm9tID1cbiAgICAgICAgICBmaWVsZC5mcm9tLnR5cGUgKyAoZmllbGQuZnJvbS50YXJnZXRDbGFzcyA/IGAgKCR7ZmllbGQuZnJvbS50YXJnZXRDbGFzc30pYCA6ICcnKTtcbiAgICAgICAgY29uc3QgdG8gPSBmaWVsZC50by50eXBlICsgKGZpZWxkLnRvLnRhcmdldENsYXNzID8gYCAoJHtmaWVsZC50by50YXJnZXRDbGFzc30pYCA6ICcnKTtcblxuICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICBgVGhlIGZpZWxkIFwiJHtmaWVsZC5maWVsZE5hbWV9XCIgdHlwZSBkaWZmZXIgYmV0d2VlbiB0aGUgc2NoZW1hIGFuZCB0aGUgZGF0YWJhc2UgZm9yIFwiJHtsb2NhbFNjaGVtYS5jbGFzc05hbWV9XCI7IFNjaGVtYSBpcyBkZWZpbmVkIGFzIFwiJHt0b31cIiBhbmQgY3VycmVudCBkYXRhYmFzZSB0eXBlIGlzIFwiJHtmcm9tfVwiYFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZmllbGRzV2l0aENoYW5nZWRQYXJhbXMuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKGxvY2FsU2NoZW1hLmZpZWxkcykge1xuICAgICAgICBjb25zdCBmaWVsZCA9IGxvY2FsU2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICB0aGlzLmhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYSwgZmllbGROYW1lLCBmaWVsZCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBIYW5kbGUgSW5kZXhlc1xuICAgIC8vIENoZWNrIGFkZGl0aW9uXG4gICAgaWYgKGxvY2FsU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGxvY2FsU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICghY2xvdWRTY2hlbWEuaW5kZXhlcyB8fCAhY2xvdWRTY2hlbWEuaW5kZXhlc1tpbmRleE5hbWVdKSAmJlxuICAgICAgICAgICF0aGlzLmlzUHJvdGVjdGVkSW5kZXgobG9jYWxTY2hlbWEuY2xhc3NOYW1lLCBpbmRleE5hbWUpXG4gICAgICAgICkge1xuICAgICAgICAgIGlmIChsb2NhbFNjaGVtYS5pbmRleGVzKSB7XG4gICAgICAgICAgICBuZXdMb2NhbFNjaGVtYS5hZGRJbmRleChpbmRleE5hbWUsIGxvY2FsU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleGVzVG9BZGQgPSBbXTtcblxuICAgIC8vIENoZWNrIGRlbGV0aW9uXG4gICAgaWYgKGNsb3VkU2NoZW1hLmluZGV4ZXMpIHtcbiAgICAgIE9iamVjdC5rZXlzKGNsb3VkU2NoZW1hLmluZGV4ZXMpLmZvckVhY2goaW5kZXhOYW1lID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUHJvdGVjdGVkSW5kZXgobG9jYWxTY2hlbWEuY2xhc3NOYW1lLCBpbmRleE5hbWUpKSB7XG4gICAgICAgICAgaWYgKCFsb2NhbFNjaGVtYS5pbmRleGVzIHx8ICFsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0pIHtcbiAgICAgICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUluZGV4KGluZGV4TmFtZSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICF0aGlzLnBhcmFtc0FyZUVxdWFscyhsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0sIGNsb3VkU2NoZW1hLmluZGV4ZXNbaW5kZXhOYW1lXSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG5ld0xvY2FsU2NoZW1hLmRlbGV0ZUluZGV4KGluZGV4TmFtZSk7XG4gICAgICAgICAgICBpZiAobG9jYWxTY2hlbWEuaW5kZXhlcykge1xuICAgICAgICAgICAgICBpbmRleGVzVG9BZGQucHVzaCh7XG4gICAgICAgICAgICAgICAgaW5kZXhOYW1lLFxuICAgICAgICAgICAgICAgIGluZGV4OiBsb2NhbFNjaGVtYS5pbmRleGVzW2luZGV4TmFtZV0sXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5oYW5kbGVDTFAobG9jYWxTY2hlbWEsIG5ld0xvY2FsU2NoZW1hLCBjbG91ZFNjaGVtYSk7XG4gICAgLy8gQXBwbHkgY2hhbmdlc1xuICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gICAgLy8gQXBwbHkgbmV3L2NoYW5nZWQgaW5kZXhlc1xuICAgIGlmIChpbmRleGVzVG9BZGQubGVuZ3RoKSB7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBVcGRhdGluZyBpbmRleGVzIGZvciBcIiR7bmV3TG9jYWxTY2hlbWEuY2xhc3NOYW1lfVwiIDogICR7aW5kZXhlc1RvQWRkLmpvaW4oJyAsJyl9YFxuICAgICAgKTtcbiAgICAgIGluZGV4ZXNUb0FkZC5mb3JFYWNoKG8gPT4gbmV3TG9jYWxTY2hlbWEuYWRkSW5kZXgoby5pbmRleE5hbWUsIG8uaW5kZXgpKTtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlU2NoZW1hVG9EQihuZXdMb2NhbFNjaGVtYSk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ0xQKFxuICAgIGxvY2FsU2NoZW1hOiBNaWdyYXRpb25zLkpTT05TY2hlbWEsXG4gICAgbmV3TG9jYWxTY2hlbWE6IFBhcnNlLlNjaGVtYSxcbiAgICBjbG91ZFNjaGVtYTogUGFyc2UuU2NoZW1hXG4gICkge1xuICAgIGlmICghbG9jYWxTY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zICYmICFjbG91ZFNjaGVtYSkge1xuICAgICAgbG9nZ2VyLndhcm4oYGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyBub3QgcHJvdmlkZWQgZm9yICR7bG9jYWxTY2hlbWEuY2xhc3NOYW1lfS5gKTtcbiAgICB9XG4gICAgLy8gVXNlIHNwcmVhZCB0byBhdm9pZCByZWFkIG9ubHkgaXNzdWUgKGVuY291bnRlcmVkIGJ5IE1vdW1vdWxzIHVzaW5nIGRpcmVjdEFjY2VzcylcbiAgICBjb25zdCBjbHAgPSAoeyAuLi5sb2NhbFNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMgfSB8fCB7fTogUGFyc2UuQ0xQLlBlcm1pc3Npb25zTWFwKTtcbiAgICAvLyBUbyBhdm9pZCBpbmNvbnNpc3RlbmN5IHdlIG5lZWQgdG8gcmVtb3ZlIGFsbCByaWdodHMgb24gYWRkRmllbGRcbiAgICBjbHAuYWRkRmllbGQgPSB7fTtcbiAgICBuZXdMb2NhbFNjaGVtYS5zZXRDTFAoY2xwKTtcbiAgfVxuXG4gIGlzUHJvdGVjdGVkRmllbGRzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiAoXG4gICAgICAhIWRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkTmFtZV0gfHxcbiAgICAgICEhKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gJiYgZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdKVxuICAgICk7XG4gIH1cblxuICBpc1Byb3RlY3RlZEluZGV4KGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleE5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IGluZGV4ZXMgPSBbJ19pZF8nXTtcbiAgICBzd2l0Y2ggKGNsYXNzTmFtZSkge1xuICAgICAgY2FzZSAnX1VzZXInOlxuICAgICAgICBpbmRleGVzLnB1c2goXG4gICAgICAgICAgJ2Nhc2VfaW5zZW5zaXRpdmVfdXNlcm5hbWUnLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX2VtYWlsJyxcbiAgICAgICAgICAndXNlcm5hbWVfMScsXG4gICAgICAgICAgJ2VtYWlsXzEnXG4gICAgICAgICk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnX1JvbGUnOlxuICAgICAgICBpbmRleGVzLnB1c2goJ25hbWVfMScpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnX0lkZW1wb3RlbmN5JzpcbiAgICAgICAgaW5kZXhlcy5wdXNoKCdyZXFJZF8xJyk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBpbmRleGVzLmluZGV4T2YoaW5kZXhOYW1lKSAhPT0gLTE7XG4gIH1cblxuICBwYXJhbXNBcmVFcXVhbHM8VDogeyBba2V5OiBzdHJpbmddOiBhbnkgfT4ob2JqQTogVCwgb2JqQjogVCkge1xuICAgIGNvbnN0IGtleXNBOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKG9iakEpO1xuICAgIGNvbnN0IGtleXNCOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKG9iakIpO1xuXG4gICAgLy8gQ2hlY2sga2V5IG5hbWVcbiAgICBpZiAoa2V5c0EubGVuZ3RoICE9PSBrZXlzQi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4ga2V5c0EuZXZlcnkoayA9PiBvYmpBW2tdID09PSBvYmpCW2tdKTtcbiAgfVxuXG4gIGhhbmRsZUZpZWxkcyhuZXdMb2NhbFNjaGVtYTogUGFyc2UuU2NoZW1hLCBmaWVsZE5hbWU6IHN0cmluZywgZmllbGQ6IE1pZ3JhdGlvbnMuRmllbGRUeXBlKSB7XG4gICAgaWYgKGZpZWxkLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgIG5ld0xvY2FsU2NoZW1hLmFkZFJlbGF0aW9uKGZpZWxkTmFtZSwgZmllbGQudGFyZ2V0Q2xhc3MpO1xuICAgIH0gZWxzZSBpZiAoZmllbGQudHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICBuZXdMb2NhbFNjaGVtYS5hZGRQb2ludGVyKGZpZWxkTmFtZSwgZmllbGQudGFyZ2V0Q2xhc3MsIGZpZWxkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3TG9jYWxTY2hlbWEuYWRkRmllbGQoZmllbGROYW1lLCBmaWVsZC50eXBlLCBmaWVsZCk7XG4gICAgfVxuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBMkI7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVQzQjtBQUNBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQVksQ0FBQztBQVU1QixNQUFNQyxjQUFjLENBQUM7RUFRMUJDLFdBQVcsQ0FBQ0MsYUFBdUMsRUFBRUMsTUFBMEIsRUFBRTtJQUMvRSxJQUFJLENBQUNDLFlBQVksR0FBRyxFQUFFO0lBQ3RCLElBQUksQ0FBQ0QsTUFBTSxHQUFHRSxlQUFNLENBQUNDLEdBQUcsQ0FBQ0gsTUFBTSxDQUFDSSxLQUFLLENBQUM7SUFDdEMsSUFBSSxDQUFDTCxhQUFhLEdBQUdBLGFBQWE7SUFDbEMsSUFBSUEsYUFBYSxJQUFJQSxhQUFhLENBQUNNLFdBQVcsRUFBRTtNQUM5QyxJQUFJLENBQUNDLEtBQUssQ0FBQ0MsT0FBTyxDQUFDUixhQUFhLENBQUNNLFdBQVcsQ0FBQyxFQUFFO1FBQzdDLE1BQU8sa0RBQWlEO01BQzFEO01BRUEsSUFBSSxDQUFDSixZQUFZLEdBQUdGLGFBQWEsQ0FBQ00sV0FBVztJQUMvQztJQUVBLElBQUksQ0FBQ0csT0FBTyxHQUFHLENBQUM7SUFDaEIsSUFBSSxDQUFDQyxVQUFVLEdBQUcsQ0FBQztFQUNyQjtFQUVBLE1BQU1DLGNBQWMsQ0FBQ0MsTUFBb0IsRUFBaUI7SUFDeEQsTUFBTUMsT0FBTyxHQUFHO01BQ2RDLFNBQVMsRUFBRUYsTUFBTSxDQUFDRSxTQUFTO01BQzNCQyxNQUFNLEVBQUVILE1BQU0sQ0FBQ0ksT0FBTztNQUN0QkMsT0FBTyxFQUFFTCxNQUFNLENBQUNNLFFBQVE7TUFDeEJDLHFCQUFxQixFQUFFUCxNQUFNLENBQUNRO0lBQ2hDLENBQUM7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
|