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,115 +4,97 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ParseLiveQueryServer = void 0;
|
|
7
|
-
|
|
8
7
|
var _tv = _interopRequireDefault(require("tv4"));
|
|
9
|
-
|
|
10
8
|
var _node = _interopRequireDefault(require("parse/node"));
|
|
11
|
-
|
|
12
9
|
var _Subscription = require("./Subscription");
|
|
13
|
-
|
|
14
10
|
var _Client = require("./Client");
|
|
15
|
-
|
|
16
11
|
var _ParseWebSocketServer = require("./ParseWebSocketServer");
|
|
17
|
-
|
|
18
12
|
var _logger = _interopRequireDefault(require("../logger"));
|
|
19
|
-
|
|
20
13
|
var _RequestSchema = _interopRequireDefault(require("./RequestSchema"));
|
|
21
|
-
|
|
22
14
|
var _QueryTools = require("./QueryTools");
|
|
23
|
-
|
|
24
15
|
var _ParsePubSub = require("./ParsePubSub");
|
|
25
|
-
|
|
26
16
|
var _SchemaController = _interopRequireDefault(require("../Controllers/SchemaController"));
|
|
27
|
-
|
|
28
17
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
29
|
-
|
|
30
18
|
var _uuid = require("uuid");
|
|
31
|
-
|
|
32
19
|
var _triggers = require("../triggers");
|
|
33
|
-
|
|
34
20
|
var _Auth = require("../Auth");
|
|
35
|
-
|
|
36
21
|
var _Controllers = require("../Controllers");
|
|
37
|
-
|
|
38
22
|
var _lruCache = _interopRequireDefault(require("lru-cache"));
|
|
39
|
-
|
|
40
23
|
var _UsersRouter = _interopRequireDefault(require("../Routers/UsersRouter"));
|
|
41
|
-
|
|
42
24
|
var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController"));
|
|
43
|
-
|
|
44
25
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
45
|
-
|
|
46
26
|
class ParseLiveQueryServer {
|
|
47
27
|
// className -> (queryHash -> subscription)
|
|
28
|
+
|
|
48
29
|
// The subscriber we use to get object update from publisher
|
|
30
|
+
|
|
49
31
|
constructor(server, config = {}, parseServerConfig = {}) {
|
|
50
32
|
this.server = server;
|
|
51
33
|
this.clients = new Map();
|
|
52
34
|
this.subscriptions = new Map();
|
|
53
35
|
this.config = config;
|
|
54
36
|
config.appId = config.appId || _node.default.applicationId;
|
|
55
|
-
config.masterKey = config.masterKey || _node.default.masterKey;
|
|
37
|
+
config.masterKey = config.masterKey || _node.default.masterKey;
|
|
56
38
|
|
|
39
|
+
// Store keys, convert obj to map
|
|
57
40
|
const keyPairs = config.keyPairs || {};
|
|
58
41
|
this.keyPairs = new Map();
|
|
59
|
-
|
|
60
42
|
for (const key of Object.keys(keyPairs)) {
|
|
61
43
|
this.keyPairs.set(key, keyPairs[key]);
|
|
62
44
|
}
|
|
45
|
+
_logger.default.verbose('Support key pairs', this.keyPairs);
|
|
63
46
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
47
|
+
// Initialize Parse
|
|
67
48
|
_node.default.Object.disableSingleInstance();
|
|
68
|
-
|
|
69
49
|
const serverURL = config.serverURL || _node.default.serverURL;
|
|
70
50
|
_node.default.serverURL = serverURL;
|
|
51
|
+
_node.default.initialize(config.appId, _node.default.javaScriptKey, config.masterKey);
|
|
71
52
|
|
|
72
|
-
|
|
53
|
+
// The cache controller is a proper cache controller
|
|
73
54
|
// with access to User and Roles
|
|
74
|
-
|
|
75
|
-
|
|
76
55
|
this.cacheController = (0, _Controllers.getCacheController)(parseServerConfig);
|
|
77
56
|
config.cacheTimeout = config.cacheTimeout || 5 * 1000; // 5s
|
|
57
|
+
|
|
78
58
|
// This auth cache stores the promises for each auth resolution.
|
|
79
59
|
// The main benefit is to be able to reuse the same user / session token resolution.
|
|
80
|
-
|
|
81
60
|
this.authCache = new _lruCache.default({
|
|
82
61
|
max: 500,
|
|
83
62
|
// 500 concurrent
|
|
84
63
|
ttl: config.cacheTimeout
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config);
|
|
88
|
-
|
|
64
|
+
});
|
|
65
|
+
// Initialize websocket server
|
|
66
|
+
this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config);
|
|
89
67
|
this.subscriber = _ParsePubSub.ParsePubSub.createSubscriber(config);
|
|
90
|
-
this.subscriber.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
this.subscriber.
|
|
68
|
+
if (!this.subscriber.connect) {
|
|
69
|
+
this.connect();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async connect() {
|
|
73
|
+
if (this.subscriber.isOpen) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (typeof this.subscriber.connect === 'function') {
|
|
77
|
+
await Promise.resolve(this.subscriber.connect());
|
|
78
|
+
} else {
|
|
79
|
+
this.subscriber.isOpen = true;
|
|
80
|
+
}
|
|
81
|
+
this._createSubscribers();
|
|
82
|
+
}
|
|
83
|
+
_createSubscribers() {
|
|
84
|
+
const messageRecieved = (channel, messageStr) => {
|
|
96
85
|
_logger.default.verbose('Subscribe message %j', messageStr);
|
|
97
|
-
|
|
98
86
|
let message;
|
|
99
|
-
|
|
100
87
|
try {
|
|
101
88
|
message = JSON.parse(messageStr);
|
|
102
89
|
} catch (e) {
|
|
103
90
|
_logger.default.error('unable to parse message', messageStr, e);
|
|
104
|
-
|
|
105
91
|
return;
|
|
106
92
|
}
|
|
107
|
-
|
|
108
93
|
if (channel === _node.default.applicationId + 'clearCache') {
|
|
109
94
|
this._clearCachedRoles(message.userId);
|
|
110
|
-
|
|
111
95
|
return;
|
|
112
96
|
}
|
|
113
|
-
|
|
114
97
|
this._inflateParseObject(message);
|
|
115
|
-
|
|
116
98
|
if (channel === _node.default.applicationId + 'afterSave') {
|
|
117
99
|
this._onAfterSave(message);
|
|
118
100
|
} else if (channel === _node.default.applicationId + 'afterDelete') {
|
|
@@ -120,88 +102,70 @@ class ParseLiveQueryServer {
|
|
|
120
102
|
} else {
|
|
121
103
|
_logger.default.error('Get message %s from unknown channel %j', message, channel);
|
|
122
104
|
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
105
|
+
};
|
|
106
|
+
this.subscriber.on('message', (channel, messageStr) => messageRecieved(channel, messageStr));
|
|
107
|
+
for (const field of ['afterSave', 'afterDelete', 'clearCache']) {
|
|
108
|
+
const channel = `${_node.default.applicationId}${field}`;
|
|
109
|
+
this.subscriber.subscribe(channel, messageStr => messageRecieved(channel, messageStr));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
127
112
|
|
|
113
|
+
// Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes.
|
|
114
|
+
// Message.originalParseObject is the original ParseObject JSON.
|
|
128
115
|
_inflateParseObject(message) {
|
|
129
116
|
// Inflate merged object
|
|
130
117
|
const currentParseObject = message.currentParseObject;
|
|
131
|
-
|
|
132
118
|
_UsersRouter.default.removeHiddenProperties(currentParseObject);
|
|
133
|
-
|
|
134
119
|
let className = currentParseObject.className;
|
|
135
120
|
let parseObject = new _node.default.Object(className);
|
|
136
|
-
|
|
137
121
|
parseObject._finishFetch(currentParseObject);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
122
|
+
message.currentParseObject = parseObject;
|
|
123
|
+
// Inflate original object
|
|
141
124
|
const originalParseObject = message.originalParseObject;
|
|
142
|
-
|
|
143
125
|
if (originalParseObject) {
|
|
144
126
|
_UsersRouter.default.removeHiddenProperties(originalParseObject);
|
|
145
|
-
|
|
146
127
|
className = originalParseObject.className;
|
|
147
128
|
parseObject = new _node.default.Object(className);
|
|
148
|
-
|
|
149
129
|
parseObject._finishFetch(originalParseObject);
|
|
150
|
-
|
|
151
130
|
message.originalParseObject = parseObject;
|
|
152
131
|
}
|
|
153
|
-
}
|
|
154
|
-
// Message.originalParseObject is the original ParseObject.
|
|
155
|
-
|
|
132
|
+
}
|
|
156
133
|
|
|
134
|
+
// Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes.
|
|
135
|
+
// Message.originalParseObject is the original ParseObject.
|
|
157
136
|
async _onAfterDelete(message) {
|
|
158
137
|
_logger.default.verbose(_node.default.applicationId + 'afterDelete is triggered');
|
|
159
|
-
|
|
160
138
|
let deletedParseObject = message.currentParseObject.toJSON();
|
|
161
139
|
const classLevelPermissions = message.classLevelPermissions;
|
|
162
140
|
const className = deletedParseObject.className;
|
|
163
|
-
|
|
164
141
|
_logger.default.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id);
|
|
165
|
-
|
|
166
142
|
_logger.default.verbose('Current client number : %d', this.clients.size);
|
|
167
|
-
|
|
168
143
|
const classSubscriptions = this.subscriptions.get(className);
|
|
169
|
-
|
|
170
144
|
if (typeof classSubscriptions === 'undefined') {
|
|
171
145
|
_logger.default.debug('Can not find subscriptions under this class ' + className);
|
|
172
|
-
|
|
173
146
|
return;
|
|
174
147
|
}
|
|
175
|
-
|
|
176
148
|
for (const subscription of classSubscriptions.values()) {
|
|
177
149
|
const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription);
|
|
178
|
-
|
|
179
150
|
if (!isSubscriptionMatched) {
|
|
180
151
|
continue;
|
|
181
152
|
}
|
|
182
|
-
|
|
183
153
|
for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) {
|
|
184
154
|
const client = this.clients.get(clientId);
|
|
185
|
-
|
|
186
155
|
if (typeof client === 'undefined') {
|
|
187
156
|
continue;
|
|
188
157
|
}
|
|
189
|
-
|
|
190
158
|
requestIds.forEach(async requestId => {
|
|
191
|
-
const acl = message.currentParseObject.getACL();
|
|
192
|
-
|
|
159
|
+
const acl = message.currentParseObject.getACL();
|
|
160
|
+
// Check CLP
|
|
193
161
|
const op = this._getCLPOperation(subscription.query);
|
|
194
|
-
|
|
195
162
|
let res = {};
|
|
196
|
-
|
|
197
163
|
try {
|
|
198
164
|
await this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op);
|
|
199
165
|
const isMatched = await this._matchesACL(acl, client, requestId);
|
|
200
|
-
|
|
201
166
|
if (!isMatched) {
|
|
202
167
|
return null;
|
|
203
168
|
}
|
|
204
|
-
|
|
205
169
|
res = {
|
|
206
170
|
event: 'delete',
|
|
207
171
|
sessionToken: client.sessionToken,
|
|
@@ -213,122 +177,90 @@ class ParseLiveQueryServer {
|
|
|
213
177
|
sendEvent: true
|
|
214
178
|
};
|
|
215
179
|
const trigger = (0, _triggers.getTrigger)(className, 'afterEvent', _node.default.applicationId);
|
|
216
|
-
|
|
217
180
|
if (trigger) {
|
|
218
181
|
const auth = await this.getAuthFromClient(client, requestId);
|
|
219
|
-
|
|
220
182
|
if (auth && auth.user) {
|
|
221
183
|
res.user = auth.user;
|
|
222
184
|
}
|
|
223
|
-
|
|
224
185
|
if (res.object) {
|
|
225
186
|
res.object = _node.default.Object.fromJSON(res.object);
|
|
226
187
|
}
|
|
227
|
-
|
|
228
188
|
await (0, _triggers.runTrigger)(trigger, `afterEvent.${className}`, res, auth);
|
|
229
189
|
}
|
|
230
|
-
|
|
231
190
|
if (!res.sendEvent) {
|
|
232
191
|
return;
|
|
233
192
|
}
|
|
234
|
-
|
|
235
193
|
if (res.object && typeof res.object.toJSON === 'function') {
|
|
236
194
|
deletedParseObject = (0, _triggers.toJSONwithObjects)(res.object, res.object.className || className);
|
|
237
195
|
}
|
|
238
|
-
|
|
239
196
|
await this._filterSensitiveData(classLevelPermissions, res, client, requestId, op, subscription.query);
|
|
240
197
|
client.pushDelete(requestId, deletedParseObject);
|
|
241
198
|
} catch (e) {
|
|
242
199
|
const error = (0, _triggers.resolveError)(e);
|
|
243
|
-
|
|
244
200
|
_Client.Client.pushError(client.parseWebSocket, error.code, error.message, false, requestId);
|
|
245
|
-
|
|
246
201
|
_logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error));
|
|
247
202
|
}
|
|
248
203
|
});
|
|
249
204
|
}
|
|
250
205
|
}
|
|
251
|
-
}
|
|
252
|
-
// Message.originalParseObject is the original ParseObject.
|
|
253
|
-
|
|
206
|
+
}
|
|
254
207
|
|
|
208
|
+
// Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes.
|
|
209
|
+
// Message.originalParseObject is the original ParseObject.
|
|
255
210
|
async _onAfterSave(message) {
|
|
256
211
|
_logger.default.verbose(_node.default.applicationId + 'afterSave is triggered');
|
|
257
|
-
|
|
258
212
|
let originalParseObject = null;
|
|
259
|
-
|
|
260
213
|
if (message.originalParseObject) {
|
|
261
214
|
originalParseObject = message.originalParseObject.toJSON();
|
|
262
215
|
}
|
|
263
|
-
|
|
264
216
|
const classLevelPermissions = message.classLevelPermissions;
|
|
265
217
|
let currentParseObject = message.currentParseObject.toJSON();
|
|
266
218
|
const className = currentParseObject.className;
|
|
267
|
-
|
|
268
219
|
_logger.default.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id);
|
|
269
|
-
|
|
270
220
|
_logger.default.verbose('Current client number : %d', this.clients.size);
|
|
271
|
-
|
|
272
221
|
const classSubscriptions = this.subscriptions.get(className);
|
|
273
|
-
|
|
274
222
|
if (typeof classSubscriptions === 'undefined') {
|
|
275
223
|
_logger.default.debug('Can not find subscriptions under this class ' + className);
|
|
276
|
-
|
|
277
224
|
return;
|
|
278
225
|
}
|
|
279
|
-
|
|
280
226
|
for (const subscription of classSubscriptions.values()) {
|
|
281
227
|
const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription);
|
|
282
|
-
|
|
283
228
|
const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription);
|
|
284
|
-
|
|
285
229
|
for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) {
|
|
286
230
|
const client = this.clients.get(clientId);
|
|
287
|
-
|
|
288
231
|
if (typeof client === 'undefined') {
|
|
289
232
|
continue;
|
|
290
233
|
}
|
|
291
|
-
|
|
292
234
|
requestIds.forEach(async requestId => {
|
|
293
235
|
// Set orignal ParseObject ACL checking promise, if the object does not match
|
|
294
236
|
// subscription, we do not need to check ACL
|
|
295
237
|
let originalACLCheckingPromise;
|
|
296
|
-
|
|
297
238
|
if (!isOriginalSubscriptionMatched) {
|
|
298
239
|
originalACLCheckingPromise = Promise.resolve(false);
|
|
299
240
|
} else {
|
|
300
241
|
let originalACL;
|
|
301
|
-
|
|
302
242
|
if (message.originalParseObject) {
|
|
303
243
|
originalACL = message.originalParseObject.getACL();
|
|
304
244
|
}
|
|
305
|
-
|
|
306
245
|
originalACLCheckingPromise = this._matchesACL(originalACL, client, requestId);
|
|
307
|
-
}
|
|
246
|
+
}
|
|
247
|
+
// Set current ParseObject ACL checking promise, if the object does not match
|
|
308
248
|
// subscription, we do not need to check ACL
|
|
309
|
-
|
|
310
|
-
|
|
311
249
|
let currentACLCheckingPromise;
|
|
312
250
|
let res = {};
|
|
313
|
-
|
|
314
251
|
if (!isCurrentSubscriptionMatched) {
|
|
315
252
|
currentACLCheckingPromise = Promise.resolve(false);
|
|
316
253
|
} else {
|
|
317
254
|
const currentACL = message.currentParseObject.getACL();
|
|
318
255
|
currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId);
|
|
319
256
|
}
|
|
320
|
-
|
|
321
257
|
try {
|
|
322
258
|
const op = this._getCLPOperation(subscription.query);
|
|
323
|
-
|
|
324
259
|
await this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op);
|
|
325
260
|
const [isOriginalMatched, isCurrentMatched] = await Promise.all([originalACLCheckingPromise, currentACLCheckingPromise]);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
261
|
+
_logger.default.verbose('Original %j | Current %j | Match: %s, %s, %s, %s | Query: %s', originalParseObject, currentParseObject, isOriginalSubscriptionMatched, isCurrentSubscriptionMatched, isOriginalMatched, isCurrentMatched, subscription.hash);
|
|
262
|
+
// Decide event type
|
|
330
263
|
let type;
|
|
331
|
-
|
|
332
264
|
if (isOriginalMatched && isCurrentMatched) {
|
|
333
265
|
type = 'update';
|
|
334
266
|
} else if (isOriginalMatched && !isCurrentMatched) {
|
|
@@ -342,7 +274,6 @@ class ParseLiveQueryServer {
|
|
|
342
274
|
} else {
|
|
343
275
|
return null;
|
|
344
276
|
}
|
|
345
|
-
|
|
346
277
|
res = {
|
|
347
278
|
event: type,
|
|
348
279
|
sessionToken: client.sessionToken,
|
|
@@ -355,55 +286,42 @@ class ParseLiveQueryServer {
|
|
|
355
286
|
sendEvent: true
|
|
356
287
|
};
|
|
357
288
|
const trigger = (0, _triggers.getTrigger)(className, 'afterEvent', _node.default.applicationId);
|
|
358
|
-
|
|
359
289
|
if (trigger) {
|
|
360
290
|
if (res.object) {
|
|
361
291
|
res.object = _node.default.Object.fromJSON(res.object);
|
|
362
292
|
}
|
|
363
|
-
|
|
364
293
|
if (res.original) {
|
|
365
294
|
res.original = _node.default.Object.fromJSON(res.original);
|
|
366
295
|
}
|
|
367
|
-
|
|
368
296
|
const auth = await this.getAuthFromClient(client, requestId);
|
|
369
|
-
|
|
370
297
|
if (auth && auth.user) {
|
|
371
298
|
res.user = auth.user;
|
|
372
299
|
}
|
|
373
|
-
|
|
374
300
|
await (0, _triggers.runTrigger)(trigger, `afterEvent.${className}`, res, auth);
|
|
375
301
|
}
|
|
376
|
-
|
|
377
302
|
if (!res.sendEvent) {
|
|
378
303
|
return;
|
|
379
304
|
}
|
|
380
|
-
|
|
381
305
|
if (res.object && typeof res.object.toJSON === 'function') {
|
|
382
306
|
currentParseObject = (0, _triggers.toJSONwithObjects)(res.object, res.object.className || className);
|
|
383
307
|
}
|
|
384
|
-
|
|
385
308
|
if (res.original && typeof res.original.toJSON === 'function') {
|
|
386
309
|
originalParseObject = (0, _triggers.toJSONwithObjects)(res.original, res.original.className || className);
|
|
387
310
|
}
|
|
388
|
-
|
|
389
311
|
await this._filterSensitiveData(classLevelPermissions, res, client, requestId, op, subscription.query);
|
|
390
312
|
const functionName = 'push' + res.event.charAt(0).toUpperCase() + res.event.slice(1);
|
|
391
|
-
|
|
392
313
|
if (client[functionName]) {
|
|
393
314
|
client[functionName](requestId, currentParseObject, originalParseObject);
|
|
394
315
|
}
|
|
395
316
|
} catch (e) {
|
|
396
317
|
const error = (0, _triggers.resolveError)(e);
|
|
397
|
-
|
|
398
318
|
_Client.Client.pushError(client.parseWebSocket, error.code, error.message, false, requestId);
|
|
399
|
-
|
|
400
319
|
_logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error));
|
|
401
320
|
}
|
|
402
321
|
});
|
|
403
322
|
}
|
|
404
323
|
}
|
|
405
324
|
}
|
|
406
|
-
|
|
407
325
|
_onConnect(parseWebsocket) {
|
|
408
326
|
parseWebsocket.on('message', request => {
|
|
409
327
|
if (typeof request === 'string') {
|
|
@@ -411,55 +329,38 @@ class ParseLiveQueryServer {
|
|
|
411
329
|
request = JSON.parse(request);
|
|
412
330
|
} catch (e) {
|
|
413
331
|
_logger.default.error('unable to parse request', request, e);
|
|
414
|
-
|
|
415
332
|
return;
|
|
416
333
|
}
|
|
417
334
|
}
|
|
335
|
+
_logger.default.verbose('Request: %j', request);
|
|
418
336
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
337
|
+
// Check whether this request is a valid request, return error directly if not
|
|
422
338
|
if (!_tv.default.validate(request, _RequestSchema.default['general']) || !_tv.default.validate(request, _RequestSchema.default[request.op])) {
|
|
423
339
|
_Client.Client.pushError(parseWebsocket, 1, _tv.default.error.message);
|
|
424
|
-
|
|
425
340
|
_logger.default.error('Connect message error %s', _tv.default.error.message);
|
|
426
|
-
|
|
427
341
|
return;
|
|
428
342
|
}
|
|
429
|
-
|
|
430
343
|
switch (request.op) {
|
|
431
344
|
case 'connect':
|
|
432
345
|
this._handleConnect(parseWebsocket, request);
|
|
433
|
-
|
|
434
346
|
break;
|
|
435
|
-
|
|
436
347
|
case 'subscribe':
|
|
437
348
|
this._handleSubscribe(parseWebsocket, request);
|
|
438
|
-
|
|
439
349
|
break;
|
|
440
|
-
|
|
441
350
|
case 'update':
|
|
442
351
|
this._handleUpdateSubscription(parseWebsocket, request);
|
|
443
|
-
|
|
444
352
|
break;
|
|
445
|
-
|
|
446
353
|
case 'unsubscribe':
|
|
447
354
|
this._handleUnsubscribe(parseWebsocket, request);
|
|
448
|
-
|
|
449
355
|
break;
|
|
450
|
-
|
|
451
356
|
default:
|
|
452
357
|
_Client.Client.pushError(parseWebsocket, 3, 'Get unknown operation');
|
|
453
|
-
|
|
454
358
|
_logger.default.error('Get unknown operation', request.op);
|
|
455
|
-
|
|
456
359
|
}
|
|
457
360
|
});
|
|
458
361
|
parseWebsocket.on('disconnect', () => {
|
|
459
362
|
_logger.default.info(`Client disconnect: ${parseWebsocket.clientId}`);
|
|
460
|
-
|
|
461
363
|
const clientId = parseWebsocket.clientId;
|
|
462
|
-
|
|
463
364
|
if (!this.clients.has(clientId)) {
|
|
464
365
|
(0, _triggers.runLiveQueryEventHandlers)({
|
|
465
366
|
event: 'ws_disconnect_error',
|
|
@@ -467,36 +368,31 @@ class ParseLiveQueryServer {
|
|
|
467
368
|
subscriptions: this.subscriptions.size,
|
|
468
369
|
error: `Unable to find client ${clientId}`
|
|
469
370
|
});
|
|
470
|
-
|
|
471
371
|
_logger.default.error(`Can not find client ${clientId} on disconnect`);
|
|
472
|
-
|
|
473
372
|
return;
|
|
474
|
-
}
|
|
475
|
-
|
|
373
|
+
}
|
|
476
374
|
|
|
375
|
+
// Delete client
|
|
477
376
|
const client = this.clients.get(clientId);
|
|
478
|
-
this.clients.delete(clientId);
|
|
377
|
+
this.clients.delete(clientId);
|
|
479
378
|
|
|
379
|
+
// Delete client from subscriptions
|
|
480
380
|
for (const [requestId, subscriptionInfo] of _lodash.default.entries(client.subscriptionInfos)) {
|
|
481
381
|
const subscription = subscriptionInfo.subscription;
|
|
482
|
-
subscription.deleteClientSubscription(clientId, requestId);
|
|
382
|
+
subscription.deleteClientSubscription(clientId, requestId);
|
|
483
383
|
|
|
384
|
+
// If there is no client which is subscribing this subscription, remove it from subscriptions
|
|
484
385
|
const classSubscriptions = this.subscriptions.get(subscription.className);
|
|
485
|
-
|
|
486
386
|
if (!subscription.hasSubscribingClient()) {
|
|
487
387
|
classSubscriptions.delete(subscription.hash);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
|
|
388
|
+
}
|
|
389
|
+
// If there is no subscriptions under this class, remove it from subscriptions
|
|
491
390
|
if (classSubscriptions.size === 0) {
|
|
492
391
|
this.subscriptions.delete(subscription.className);
|
|
493
392
|
}
|
|
494
393
|
}
|
|
495
|
-
|
|
496
394
|
_logger.default.verbose('Current clients %d', this.clients.size);
|
|
497
|
-
|
|
498
395
|
_logger.default.verbose('Current subscriptions %d', this.subscriptions.size);
|
|
499
|
-
|
|
500
396
|
(0, _triggers.runLiveQueryEventHandlers)({
|
|
501
397
|
event: 'ws_disconnect',
|
|
502
398
|
clients: this.clients.size,
|
|
@@ -512,16 +408,13 @@ class ParseLiveQueryServer {
|
|
|
512
408
|
subscriptions: this.subscriptions.size
|
|
513
409
|
});
|
|
514
410
|
}
|
|
515
|
-
|
|
516
411
|
_matchesSubscription(parseObject, subscription) {
|
|
517
412
|
// Object is undefined or null, not match
|
|
518
413
|
if (!parseObject) {
|
|
519
414
|
return false;
|
|
520
415
|
}
|
|
521
|
-
|
|
522
416
|
return (0, _QueryTools.matchesQuery)(parseObject, subscription.query);
|
|
523
417
|
}
|
|
524
|
-
|
|
525
418
|
async _clearCachedRoles(userId) {
|
|
526
419
|
try {
|
|
527
420
|
const validTokens = await new _node.default.Query(_node.default.Session).equalTo('user', _node.default.User.createWithoutData(userId)).find({
|
|
@@ -529,14 +422,11 @@ class ParseLiveQueryServer {
|
|
|
529
422
|
});
|
|
530
423
|
await Promise.all(validTokens.map(async token => {
|
|
531
424
|
var _auth1$auth, _auth2$auth;
|
|
532
|
-
|
|
533
425
|
const sessionToken = token.get('sessionToken');
|
|
534
426
|
const authPromise = this.authCache.get(sessionToken);
|
|
535
|
-
|
|
536
427
|
if (!authPromise) {
|
|
537
428
|
return;
|
|
538
429
|
}
|
|
539
|
-
|
|
540
430
|
const [auth1, auth2] = await Promise.all([authPromise, (0, _Auth.getAuthForSessionToken)({
|
|
541
431
|
cacheController: this.cacheController,
|
|
542
432
|
sessionToken
|
|
@@ -549,18 +439,14 @@ class ParseLiveQueryServer {
|
|
|
549
439
|
_logger.default.verbose(`Could not clear role cache. ${e}`);
|
|
550
440
|
}
|
|
551
441
|
}
|
|
552
|
-
|
|
553
442
|
getAuthForSessionToken(sessionToken) {
|
|
554
443
|
if (!sessionToken) {
|
|
555
444
|
return Promise.resolve({});
|
|
556
445
|
}
|
|
557
|
-
|
|
558
446
|
const fromCache = this.authCache.get(sessionToken);
|
|
559
|
-
|
|
560
447
|
if (fromCache) {
|
|
561
448
|
return fromCache;
|
|
562
449
|
}
|
|
563
|
-
|
|
564
450
|
const authPromise = (0, _Auth.getAuthForSessionToken)({
|
|
565
451
|
cacheController: this.cacheController,
|
|
566
452
|
sessionToken: sessionToken
|
|
@@ -572,44 +458,38 @@ class ParseLiveQueryServer {
|
|
|
572
458
|
}).catch(error => {
|
|
573
459
|
// There was an error with the session token
|
|
574
460
|
const result = {};
|
|
575
|
-
|
|
576
461
|
if (error && error.code === _node.default.Error.INVALID_SESSION_TOKEN) {
|
|
577
462
|
result.error = error;
|
|
578
463
|
this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout);
|
|
579
464
|
} else {
|
|
580
465
|
this.authCache.del(sessionToken);
|
|
581
466
|
}
|
|
582
|
-
|
|
583
467
|
return result;
|
|
584
468
|
});
|
|
585
469
|
this.authCache.set(sessionToken, authPromise);
|
|
586
470
|
return authPromise;
|
|
587
471
|
}
|
|
588
|
-
|
|
589
472
|
async _matchesCLP(classLevelPermissions, object, client, requestId, op) {
|
|
590
473
|
// try to match on user first, less expensive than with roles
|
|
591
474
|
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
|
592
475
|
const aclGroup = ['*'];
|
|
593
476
|
let userId;
|
|
594
|
-
|
|
595
477
|
if (typeof subscriptionInfo !== 'undefined') {
|
|
596
478
|
const {
|
|
597
479
|
userId
|
|
598
480
|
} = await this.getAuthForSessionToken(subscriptionInfo.sessionToken);
|
|
599
|
-
|
|
600
481
|
if (userId) {
|
|
601
482
|
aclGroup.push(userId);
|
|
602
483
|
}
|
|
603
484
|
}
|
|
604
|
-
|
|
605
485
|
try {
|
|
606
486
|
await _SchemaController.default.validatePermission(classLevelPermissions, object.className, aclGroup, op);
|
|
607
487
|
return true;
|
|
608
488
|
} catch (e) {
|
|
609
489
|
_logger.default.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`);
|
|
610
|
-
|
|
611
490
|
return false;
|
|
612
|
-
}
|
|
491
|
+
}
|
|
492
|
+
// TODO: handle roles permissions
|
|
613
493
|
// Object.keys(classLevelPermissions).forEach((key) => {
|
|
614
494
|
// const perm = classLevelPermissions[key];
|
|
615
495
|
// Object.keys(perm).forEach((key) => {
|
|
@@ -620,161 +500,126 @@ class ParseLiveQueryServer {
|
|
|
620
500
|
// var rolesQuery = new Parse.Query(Parse.Role);
|
|
621
501
|
// rolesQuery.equalTo("users", user);
|
|
622
502
|
// return rolesQuery.find({useMasterKey:true});
|
|
623
|
-
|
|
624
503
|
}
|
|
625
504
|
|
|
626
505
|
async _filterSensitiveData(classLevelPermissions, res, client, requestId, op, query) {
|
|
627
506
|
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
|
628
507
|
const aclGroup = ['*'];
|
|
629
508
|
let clientAuth;
|
|
630
|
-
|
|
631
509
|
if (typeof subscriptionInfo !== 'undefined') {
|
|
632
510
|
const {
|
|
633
511
|
userId,
|
|
634
512
|
auth
|
|
635
513
|
} = await this.getAuthForSessionToken(subscriptionInfo.sessionToken);
|
|
636
|
-
|
|
637
514
|
if (userId) {
|
|
638
515
|
aclGroup.push(userId);
|
|
639
516
|
}
|
|
640
|
-
|
|
641
517
|
clientAuth = auth;
|
|
642
518
|
}
|
|
643
|
-
|
|
644
519
|
const filter = obj => {
|
|
645
520
|
if (!obj) {
|
|
646
521
|
return;
|
|
647
522
|
}
|
|
648
|
-
|
|
649
523
|
let protectedFields = (classLevelPermissions === null || classLevelPermissions === void 0 ? void 0 : classLevelPermissions.protectedFields) || [];
|
|
650
|
-
|
|
651
524
|
if (!client.hasMasterKey && !Array.isArray(protectedFields)) {
|
|
652
525
|
protectedFields = (0, _Controllers.getDatabaseController)(this.config).addProtectedFields(classLevelPermissions, res.object.className, query, aclGroup, clientAuth);
|
|
653
526
|
}
|
|
654
|
-
|
|
655
527
|
return _DatabaseController.default.filterSensitiveData(client.hasMasterKey, aclGroup, clientAuth, op, classLevelPermissions, res.object.className, protectedFields, obj, query);
|
|
656
528
|
};
|
|
657
|
-
|
|
658
529
|
res.object = filter(res.object);
|
|
659
530
|
res.original = filter(res.original);
|
|
660
531
|
}
|
|
661
|
-
|
|
662
532
|
_getCLPOperation(query) {
|
|
663
533
|
return typeof query === 'object' && Object.keys(query).length == 1 && typeof query.objectId === 'string' ? 'get' : 'find';
|
|
664
534
|
}
|
|
665
|
-
|
|
666
535
|
async _verifyACL(acl, token) {
|
|
667
536
|
if (!token) {
|
|
668
537
|
return false;
|
|
669
538
|
}
|
|
670
|
-
|
|
671
539
|
const {
|
|
672
540
|
auth,
|
|
673
541
|
userId
|
|
674
|
-
} = await this.getAuthForSessionToken(token);
|
|
542
|
+
} = await this.getAuthForSessionToken(token);
|
|
543
|
+
|
|
544
|
+
// Getting the session token failed
|
|
675
545
|
// This means that no additional auth is available
|
|
676
546
|
// At this point, just bail out as no additional visibility can be inferred.
|
|
677
|
-
|
|
678
547
|
if (!auth || !userId) {
|
|
679
548
|
return false;
|
|
680
549
|
}
|
|
681
|
-
|
|
682
550
|
const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId);
|
|
683
|
-
|
|
684
551
|
if (isSubscriptionSessionTokenMatched) {
|
|
685
552
|
return true;
|
|
686
|
-
}
|
|
687
|
-
|
|
553
|
+
}
|
|
688
554
|
|
|
555
|
+
// Check if the user has any roles that match the ACL
|
|
689
556
|
return Promise.resolve().then(async () => {
|
|
690
557
|
// Resolve false right away if the acl doesn't have any roles
|
|
691
558
|
const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith('role:'));
|
|
692
|
-
|
|
693
559
|
if (!acl_has_roles) {
|
|
694
560
|
return false;
|
|
695
561
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
562
|
+
const roleNames = await auth.getUserRoles();
|
|
563
|
+
// Finally, see if any of the user's roles allow them read access
|
|
699
564
|
for (const role of roleNames) {
|
|
700
565
|
// We use getReadAccess as `role` is in the form `role:roleName`
|
|
701
566
|
if (acl.getReadAccess(role)) {
|
|
702
567
|
return true;
|
|
703
568
|
}
|
|
704
569
|
}
|
|
705
|
-
|
|
706
570
|
return false;
|
|
707
571
|
}).catch(() => {
|
|
708
572
|
return false;
|
|
709
573
|
});
|
|
710
574
|
}
|
|
711
|
-
|
|
712
575
|
async getAuthFromClient(client, requestId, sessionToken) {
|
|
713
576
|
const getSessionFromClient = () => {
|
|
714
577
|
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
|
715
|
-
|
|
716
578
|
if (typeof subscriptionInfo === 'undefined') {
|
|
717
579
|
return client.sessionToken;
|
|
718
580
|
}
|
|
719
|
-
|
|
720
581
|
return subscriptionInfo.sessionToken || client.sessionToken;
|
|
721
582
|
};
|
|
722
|
-
|
|
723
583
|
if (!sessionToken) {
|
|
724
584
|
sessionToken = getSessionFromClient();
|
|
725
585
|
}
|
|
726
|
-
|
|
727
586
|
if (!sessionToken) {
|
|
728
587
|
return;
|
|
729
588
|
}
|
|
730
|
-
|
|
731
589
|
const {
|
|
732
590
|
auth
|
|
733
591
|
} = await this.getAuthForSessionToken(sessionToken);
|
|
734
592
|
return auth;
|
|
735
593
|
}
|
|
736
|
-
|
|
737
594
|
async _matchesACL(acl, client, requestId) {
|
|
738
595
|
// Return true directly if ACL isn't present, ACL is public read, or client has master key
|
|
739
596
|
if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) {
|
|
740
597
|
return true;
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
|
|
598
|
+
}
|
|
599
|
+
// Check subscription sessionToken matches ACL first
|
|
744
600
|
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
|
745
|
-
|
|
746
601
|
if (typeof subscriptionInfo === 'undefined') {
|
|
747
602
|
return false;
|
|
748
603
|
}
|
|
749
|
-
|
|
750
604
|
const subscriptionToken = subscriptionInfo.sessionToken;
|
|
751
605
|
const clientSessionToken = client.sessionToken;
|
|
752
|
-
|
|
753
606
|
if (await this._verifyACL(acl, subscriptionToken)) {
|
|
754
607
|
return true;
|
|
755
608
|
}
|
|
756
|
-
|
|
757
609
|
if (await this._verifyACL(acl, clientSessionToken)) {
|
|
758
610
|
return true;
|
|
759
611
|
}
|
|
760
|
-
|
|
761
612
|
return false;
|
|
762
613
|
}
|
|
763
|
-
|
|
764
614
|
async _handleConnect(parseWebsocket, request) {
|
|
765
615
|
if (!this._validateKeys(request, this.keyPairs)) {
|
|
766
616
|
_Client.Client.pushError(parseWebsocket, 4, 'Key in request is not valid');
|
|
767
|
-
|
|
768
617
|
_logger.default.error('Key in request is not valid');
|
|
769
|
-
|
|
770
618
|
return;
|
|
771
619
|
}
|
|
772
|
-
|
|
773
620
|
const hasMasterKey = this._hasMasterKey(request, this.keyPairs);
|
|
774
|
-
|
|
775
621
|
const clientId = (0, _uuid.v4)();
|
|
776
622
|
const client = new _Client.Client(clientId, parseWebsocket, hasMasterKey, request.sessionToken, request.installationId);
|
|
777
|
-
|
|
778
623
|
try {
|
|
779
624
|
const req = {
|
|
780
625
|
client,
|
|
@@ -786,159 +631,123 @@ class ParseLiveQueryServer {
|
|
|
786
631
|
installationId: request.installationId
|
|
787
632
|
};
|
|
788
633
|
const trigger = (0, _triggers.getTrigger)('@Connect', 'beforeConnect', _node.default.applicationId);
|
|
789
|
-
|
|
790
634
|
if (trigger) {
|
|
791
635
|
const auth = await this.getAuthFromClient(client, request.requestId, req.sessionToken);
|
|
792
|
-
|
|
793
636
|
if (auth && auth.user) {
|
|
794
637
|
req.user = auth.user;
|
|
795
638
|
}
|
|
796
|
-
|
|
797
639
|
await (0, _triggers.runTrigger)(trigger, `beforeConnect.@Connect`, req, auth);
|
|
798
640
|
}
|
|
799
|
-
|
|
800
641
|
parseWebsocket.clientId = clientId;
|
|
801
642
|
this.clients.set(parseWebsocket.clientId, client);
|
|
802
|
-
|
|
803
643
|
_logger.default.info(`Create new client: ${parseWebsocket.clientId}`);
|
|
804
|
-
|
|
805
644
|
client.pushConnect();
|
|
806
645
|
(0, _triggers.runLiveQueryEventHandlers)(req);
|
|
807
646
|
} catch (e) {
|
|
808
647
|
const error = (0, _triggers.resolveError)(e);
|
|
809
|
-
|
|
810
648
|
_Client.Client.pushError(parseWebsocket, error.code, error.message, false);
|
|
811
|
-
|
|
812
649
|
_logger.default.error(`Failed running beforeConnect for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error));
|
|
813
650
|
}
|
|
814
651
|
}
|
|
815
|
-
|
|
816
652
|
_hasMasterKey(request, validKeyPairs) {
|
|
817
653
|
if (!validKeyPairs || validKeyPairs.size == 0 || !validKeyPairs.has('masterKey')) {
|
|
818
654
|
return false;
|
|
819
655
|
}
|
|
820
|
-
|
|
821
656
|
if (!request || !Object.prototype.hasOwnProperty.call(request, 'masterKey')) {
|
|
822
657
|
return false;
|
|
823
658
|
}
|
|
824
|
-
|
|
825
659
|
return request.masterKey === validKeyPairs.get('masterKey');
|
|
826
660
|
}
|
|
827
|
-
|
|
828
661
|
_validateKeys(request, validKeyPairs) {
|
|
829
662
|
if (!validKeyPairs || validKeyPairs.size == 0) {
|
|
830
663
|
return true;
|
|
831
664
|
}
|
|
832
|
-
|
|
833
665
|
let isValid = false;
|
|
834
|
-
|
|
835
666
|
for (const [key, secret] of validKeyPairs) {
|
|
836
667
|
if (!request[key] || request[key] !== secret) {
|
|
837
668
|
continue;
|
|
838
669
|
}
|
|
839
|
-
|
|
840
670
|
isValid = true;
|
|
841
671
|
break;
|
|
842
672
|
}
|
|
843
|
-
|
|
844
673
|
return isValid;
|
|
845
674
|
}
|
|
846
|
-
|
|
847
675
|
async _handleSubscribe(parseWebsocket, request) {
|
|
848
676
|
// If we can not find this client, return error to client
|
|
849
677
|
if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) {
|
|
850
678
|
_Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before subscribing');
|
|
851
|
-
|
|
852
679
|
_logger.default.error('Can not find this client, make sure you connect to server before subscribing');
|
|
853
|
-
|
|
854
680
|
return;
|
|
855
681
|
}
|
|
856
|
-
|
|
857
682
|
const client = this.clients.get(parseWebsocket.clientId);
|
|
858
683
|
const className = request.query.className;
|
|
859
684
|
let authCalled = false;
|
|
860
|
-
|
|
861
685
|
try {
|
|
862
686
|
const trigger = (0, _triggers.getTrigger)(className, 'beforeSubscribe', _node.default.applicationId);
|
|
863
|
-
|
|
864
687
|
if (trigger) {
|
|
865
688
|
const auth = await this.getAuthFromClient(client, request.requestId, request.sessionToken);
|
|
866
689
|
authCalled = true;
|
|
867
|
-
|
|
868
690
|
if (auth && auth.user) {
|
|
869
691
|
request.user = auth.user;
|
|
870
692
|
}
|
|
871
|
-
|
|
872
693
|
const parseQuery = new _node.default.Query(className);
|
|
873
694
|
parseQuery.withJSON(request.query);
|
|
874
695
|
request.query = parseQuery;
|
|
875
696
|
await (0, _triggers.runTrigger)(trigger, `beforeSubscribe.${className}`, request, auth);
|
|
876
697
|
const query = request.query.toJSON();
|
|
877
|
-
|
|
878
698
|
if (query.keys) {
|
|
879
699
|
query.fields = query.keys.split(',');
|
|
880
700
|
}
|
|
881
|
-
|
|
882
701
|
request.query = query;
|
|
883
702
|
}
|
|
884
|
-
|
|
885
703
|
if (className === '_Session') {
|
|
886
704
|
if (!authCalled) {
|
|
887
705
|
const auth = await this.getAuthFromClient(client, request.requestId, request.sessionToken);
|
|
888
|
-
|
|
889
706
|
if (auth && auth.user) {
|
|
890
707
|
request.user = auth.user;
|
|
891
708
|
}
|
|
892
709
|
}
|
|
893
|
-
|
|
894
710
|
if (request.user) {
|
|
895
711
|
request.query.where.user = request.user.toPointer();
|
|
896
712
|
} else if (!request.master) {
|
|
897
713
|
_Client.Client.pushError(parseWebsocket, _node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token', false, request.requestId);
|
|
898
|
-
|
|
899
714
|
return;
|
|
900
715
|
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
716
|
+
}
|
|
717
|
+
// Get subscription from subscriptions, create one if necessary
|
|
718
|
+
const subscriptionHash = (0, _QueryTools.queryHash)(request.query);
|
|
719
|
+
// Add className to subscriptions if necessary
|
|
905
720
|
|
|
906
721
|
if (!this.subscriptions.has(className)) {
|
|
907
722
|
this.subscriptions.set(className, new Map());
|
|
908
723
|
}
|
|
909
|
-
|
|
910
724
|
const classSubscriptions = this.subscriptions.get(className);
|
|
911
725
|
let subscription;
|
|
912
|
-
|
|
913
726
|
if (classSubscriptions.has(subscriptionHash)) {
|
|
914
727
|
subscription = classSubscriptions.get(subscriptionHash);
|
|
915
728
|
} else {
|
|
916
729
|
subscription = new _Subscription.Subscription(className, request.query.where, subscriptionHash);
|
|
917
730
|
classSubscriptions.set(subscriptionHash, subscription);
|
|
918
|
-
}
|
|
919
|
-
|
|
731
|
+
}
|
|
920
732
|
|
|
733
|
+
// Add subscriptionInfo to client
|
|
921
734
|
const subscriptionInfo = {
|
|
922
735
|
subscription: subscription
|
|
923
|
-
};
|
|
924
|
-
|
|
736
|
+
};
|
|
737
|
+
// Add selected fields, sessionToken and installationId for this subscription if necessary
|
|
925
738
|
if (request.query.fields) {
|
|
926
739
|
subscriptionInfo.fields = request.query.fields;
|
|
927
740
|
}
|
|
928
|
-
|
|
929
741
|
if (request.sessionToken) {
|
|
930
742
|
subscriptionInfo.sessionToken = request.sessionToken;
|
|
931
743
|
}
|
|
744
|
+
client.addSubscriptionInfo(request.requestId, subscriptionInfo);
|
|
932
745
|
|
|
933
|
-
|
|
934
|
-
|
|
746
|
+
// Add clientId to subscription
|
|
935
747
|
subscription.addClientSubscription(parseWebsocket.clientId, request.requestId);
|
|
936
748
|
client.pushSubscribe(request.requestId);
|
|
937
|
-
|
|
938
749
|
_logger.default.verbose(`Create client ${parseWebsocket.clientId} new subscription: ${request.requestId}`);
|
|
939
|
-
|
|
940
750
|
_logger.default.verbose('Current client number: %d', this.clients.size);
|
|
941
|
-
|
|
942
751
|
(0, _triggers.runLiveQueryEventHandlers)({
|
|
943
752
|
client,
|
|
944
753
|
event: 'subscribe',
|
|
@@ -950,68 +759,50 @@ class ParseLiveQueryServer {
|
|
|
950
759
|
});
|
|
951
760
|
} catch (e) {
|
|
952
761
|
const error = (0, _triggers.resolveError)(e);
|
|
953
|
-
|
|
954
762
|
_Client.Client.pushError(parseWebsocket, error.code, error.message, false, request.requestId);
|
|
955
|
-
|
|
956
763
|
_logger.default.error(`Failed running beforeSubscribe on ${className} for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error));
|
|
957
764
|
}
|
|
958
765
|
}
|
|
959
|
-
|
|
960
766
|
_handleUpdateSubscription(parseWebsocket, request) {
|
|
961
767
|
this._handleUnsubscribe(parseWebsocket, request, false);
|
|
962
|
-
|
|
963
768
|
this._handleSubscribe(parseWebsocket, request);
|
|
964
769
|
}
|
|
965
|
-
|
|
966
770
|
_handleUnsubscribe(parseWebsocket, request, notifyClient = true) {
|
|
967
771
|
// If we can not find this client, return error to client
|
|
968
772
|
if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) {
|
|
969
773
|
_Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing');
|
|
970
|
-
|
|
971
774
|
_logger.default.error('Can not find this client, make sure you connect to server before unsubscribing');
|
|
972
|
-
|
|
973
775
|
return;
|
|
974
776
|
}
|
|
975
|
-
|
|
976
777
|
const requestId = request.requestId;
|
|
977
778
|
const client = this.clients.get(parseWebsocket.clientId);
|
|
978
|
-
|
|
979
779
|
if (typeof client === 'undefined') {
|
|
980
780
|
_Client.Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId + '. Make sure you connect to live query server before unsubscribing.');
|
|
981
|
-
|
|
982
781
|
_logger.default.error('Can not find this client ' + parseWebsocket.clientId);
|
|
983
|
-
|
|
984
782
|
return;
|
|
985
783
|
}
|
|
986
|
-
|
|
987
784
|
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
|
988
|
-
|
|
989
785
|
if (typeof subscriptionInfo === 'undefined') {
|
|
990
786
|
_Client.Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.');
|
|
991
|
-
|
|
992
787
|
_logger.default.error('Can not find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId);
|
|
993
|
-
|
|
994
788
|
return;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
client.deleteSubscriptionInfo(requestId); // Remove client from subscription
|
|
789
|
+
}
|
|
999
790
|
|
|
791
|
+
// Remove subscription from client
|
|
792
|
+
client.deleteSubscriptionInfo(requestId);
|
|
793
|
+
// Remove client from subscription
|
|
1000
794
|
const subscription = subscriptionInfo.subscription;
|
|
1001
795
|
const className = subscription.className;
|
|
1002
|
-
subscription.deleteClientSubscription(parseWebsocket.clientId, requestId);
|
|
1003
|
-
|
|
796
|
+
subscription.deleteClientSubscription(parseWebsocket.clientId, requestId);
|
|
797
|
+
// If there is no client which is subscribing this subscription, remove it from subscriptions
|
|
1004
798
|
const classSubscriptions = this.subscriptions.get(className);
|
|
1005
|
-
|
|
1006
799
|
if (!subscription.hasSubscribingClient()) {
|
|
1007
800
|
classSubscriptions.delete(subscription.hash);
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
|
|
801
|
+
}
|
|
802
|
+
// If there is no subscriptions under this class, remove it from subscriptions
|
|
1011
803
|
if (classSubscriptions.size === 0) {
|
|
1012
804
|
this.subscriptions.delete(className);
|
|
1013
805
|
}
|
|
1014
|
-
|
|
1015
806
|
(0, _triggers.runLiveQueryEventHandlers)({
|
|
1016
807
|
client,
|
|
1017
808
|
event: 'unsubscribe',
|
|
@@ -1021,17 +812,12 @@ class ParseLiveQueryServer {
|
|
|
1021
812
|
useMasterKey: client.hasMasterKey,
|
|
1022
813
|
installationId: client.installationId
|
|
1023
814
|
});
|
|
1024
|
-
|
|
1025
815
|
if (!notifyClient) {
|
|
1026
816
|
return;
|
|
1027
817
|
}
|
|
1028
|
-
|
|
1029
818
|
client.pushUnsubscribe(request.requestId);
|
|
1030
|
-
|
|
1031
819
|
_logger.default.verbose(`Delete client: ${parseWebsocket.clientId} | subscription: ${request.requestId}`);
|
|
1032
820
|
}
|
|
1033
|
-
|
|
1034
821
|
}
|
|
1035
|
-
|
|
1036
822
|
exports.ParseLiveQueryServer = ParseLiveQueryServer;
|
|
1037
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsImNvbmZpZyIsInBhcnNlU2VydmVyQ29uZmlnIiwiY2xpZW50cyIsIk1hcCIsInN1YnNjcmlwdGlvbnMiLCJhcHBJZCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIm1hc3RlcktleSIsImtleVBhaXJzIiwia2V5IiwiT2JqZWN0Iiwia2V5cyIsInNldCIsImxvZ2dlciIsInZlcmJvc2UiLCJkaXNhYmxlU2luZ2xlSW5zdGFuY2UiLCJzZXJ2ZXJVUkwiLCJpbml0aWFsaXplIiwiamF2YVNjcmlwdEtleSIsImNhY2hlQ29udHJvbGxlciIsImNhY2hlVGltZW91dCIsImF1dGhDYWNoZSIsIkxSVSIsIm1heCIsInR0bCIsInBhcnNlV2ViU29ja2V0U2VydmVyIiwiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJwYXJzZVdlYnNvY2tldCIsIl9vbkNvbm5lY3QiLCJzdWJzY3JpYmVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVTdWJzY3JpYmVyIiwic3Vic2NyaWJlIiwib24iLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfY2xlYXJDYWNoZWRSb2xlcyIsInVzZXJJZCIsIl9pbmZsYXRlUGFyc2VPYmplY3QiLCJfb25BZnRlclNhdmUiLCJfb25BZnRlckRlbGV0ZSIsImN1cnJlbnRQYXJzZU9iamVjdCIsIlVzZXJSb3V0ZXIiLCJyZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzIiwiY2xhc3NOYW1lIiwicGFyc2VPYmplY3QiLCJfZmluaXNoRmV0Y2giLCJvcmlnaW5hbFBhcnNlT2JqZWN0IiwiZGVsZXRlZFBhcnNlT2JqZWN0IiwidG9KU09OIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaWQiLCJzaXplIiwiY2xhc3NTdWJzY3JpcHRpb25zIiwiZ2V0IiwiZGVidWciLCJzdWJzY3JpcHRpb24iLCJ2YWx1ZXMiLCJpc1N1YnNjcmlwdGlvbk1hdGNoZWQiLCJfbWF0Y2hlc1N1YnNjcmlwdGlvbiIsImNsaWVudElkIiwicmVxdWVzdElkcyIsIl8iLCJlbnRyaWVzIiwiY2xpZW50UmVxdWVzdElkcyIsImNsaWVudCIsImZvckVhY2giLCJyZXF1ZXN0SWQiLCJhY2wiLCJnZXRBQ0wiLCJvcCIsIl9nZXRDTFBPcGVyYXRpb24iLCJxdWVyeSIsInJlcyIsIl9tYXRjaGVzQ0xQIiwiaXNNYXRjaGVkIiwiX21hdGNoZXNBQ0wiLCJldmVudCIsInNlc3Npb25Ub2tlbiIsIm9iamVjdCIsInVzZU1hc3RlcktleSIsImhhc01hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwic2VuZEV2ZW50IiwidHJpZ2dlciIsImF1dGgiLCJnZXRBdXRoRnJvbUNsaWVudCIsInVzZXIiLCJmcm9tSlNPTiIsIl9maWx0ZXJTZW5zaXRpdmVEYXRhIiwicHVzaERlbGV0ZSIsIkNsaWVudCIsInB1c2hFcnJvciIsInBhcnNlV2ViU29ja2V0IiwiY29kZSIsInN0cmluZ2lmeSIsImlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkIiwiaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCIsIm9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiYWxsIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJyZXF1ZXN0IiwidHY0IiwidmFsaWRhdGUiLCJSZXF1ZXN0U2NoZW1hIiwiX2hhbmRsZUNvbm5lY3QiLCJfaGFuZGxlU3Vic2NyaWJlIiwiX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbiIsIl9oYW5kbGVVbnN1YnNjcmliZSIsImluZm8iLCJoYXMiLCJkZWxldGUiLCJzdWJzY3JpcHRpb25JbmZvIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJoYXNTdWJzY3JpYmluZ0NsaWVudCIsInZhbGlkVG9rZW5zIiwiUXVlcnkiLCJTZXNzaW9uIiwiZXF1YWxUbyIsIlVzZXIiLCJjcmVhdGVXaXRob3V0RGF0YSIsImZpbmQiLCJtYXAiLCJ0b2tlbiIsImF1dGhQcm9taXNlIiwiYXV0aDEiLCJhdXRoMiIsImNsZWFyUm9sZUNhY2hlIiwiZGVsIiwiZ2V0QXV0aEZvclNlc3Npb25Ub2tlbiIsImZyb21DYWNoZSIsInRoZW4iLCJjYXRjaCIsInJlc3VsdCIsIkVycm9yIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiZ2V0U3Vic2NyaXB0aW9uSW5mbyIsImFjbEdyb3VwIiwicHVzaCIsIlNjaGVtYUNvbnRyb2xsZXIiLCJ2YWxpZGF0ZVBlcm1pc3Npb24iLCJjbGllbnRBdXRoIiwiZmlsdGVyIiwib2JqIiwicHJvdGVjdGVkRmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwiYWRkUHJvdGVjdGVkRmllbGRzIiwiRGF0YWJhc2VDb250cm9sbGVyIiwiZmlsdGVyU2Vuc2l0aXZlRGF0YSIsImxlbmd0aCIsIm9iamVjdElkIiwiX3ZlcmlmeUFDTCIsImlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCIsImdldFJlYWRBY2Nlc3MiLCJhY2xfaGFzX3JvbGVzIiwicGVybWlzc2lvbnNCeUlkIiwic29tZSIsInN0YXJ0c1dpdGgiLCJyb2xlTmFtZXMiLCJnZXRVc2VyUm9sZXMiLCJyb2xlIiwiZ2V0U2Vzc2lvbkZyb21DbGllbnQiLCJnZXRQdWJsaWNSZWFkQWNjZXNzIiwic3Vic2NyaXB0aW9uVG9rZW4iLCJjbGllbnRTZXNzaW9uVG9rZW4iLCJfdmFsaWRhdGVLZXlzIiwiX2hhc01hc3RlcktleSIsInJlcSIsInB1c2hDb25uZWN0IiwidmFsaWRLZXlQYWlycyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImlzVmFsaWQiLCJzZWNyZXQiLCJhdXRoQ2FsbGVkIiwicGFyc2VRdWVyeSIsIndpdGhKU09OIiwiZmllbGRzIiwic3BsaXQiLCJ3aGVyZSIsInRvUG9pbnRlciIsIm1hc3RlciIsInN1YnNjcmlwdGlvbkhhc2giLCJTdWJzY3JpcHRpb24iLCJhZGRTdWJzY3JpcHRpb25JbmZvIiwiYWRkQ2xpZW50U3Vic2NyaXB0aW9uIiwicHVzaFN1YnNjcmliZSIsIm5vdGlmeUNsaWVudCIsImRlbGV0ZVN1YnNjcmlwdGlvbkluZm8iLCJwdXNoVW5zdWJzY3JpYmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFPQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLG9CQUFOLENBQTJCO0FBRXpCO0FBSUE7QUFHQUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFELEVBQWNDLE1BQVcsR0FBRyxFQUE1QixFQUFnQ0MsaUJBQXNCLEdBQUcsRUFBekQsRUFBNkQ7QUFDdEUsU0FBS0YsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsU0FBS0csT0FBTCxHQUFlLElBQUlDLEdBQUosRUFBZjtBQUNBLFNBQUtDLGFBQUwsR0FBcUIsSUFBSUQsR0FBSixFQUFyQjtBQUNBLFNBQUtILE1BQUwsR0FBY0EsTUFBZDtBQUVBQSxJQUFBQSxNQUFNLENBQUNLLEtBQVAsR0FBZUwsTUFBTSxDQUFDSyxLQUFQLElBQWdCQyxjQUFNQyxhQUFyQztBQUNBUCxJQUFBQSxNQUFNLENBQUNRLFNBQVAsR0FBbUJSLE1BQU0sQ0FBQ1EsU0FBUCxJQUFvQkYsY0FBTUUsU0FBN0MsQ0FQc0UsQ0FTdEU7O0FBQ0EsVUFBTUMsUUFBUSxHQUFHVCxNQUFNLENBQUNTLFFBQVAsSUFBbUIsRUFBcEM7QUFDQSxTQUFLQSxRQUFMLEdBQWdCLElB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QixNQUFBQSxNQUR3QjtBQUV4QlksTUFBQUEsS0FBSyxFQUFFLGFBRmlCO0FBR3hCakYsTUFBQUEsT0FBTyxFQUFFLEtBQUtBLE9BQUwsQ0FBYXdELElBSEU7QUFJeEJ0RCxNQUFBQSxhQUFhLEVBQUUsS0FBS0EsYUFBTCxDQUFtQnNELElBSlY7QUFLeEIwQixNQUFBQSxZQUFZLEVBQUUrQyxnQkFBZ0IsQ0FBQy9DLFlBTFA7QUFNeEJFLE1BQUFBLFlBQVksRUFBRWYsTUFBTSxDQUFDZ0IsWUFORztBQU94QkMsTUFBQUEsY0FBYyxFQUFFakIsTUFBTSxDQUFDaUI7QUFQQyxLQUExQjs7QUFVQSxRQUFJLENBQUN5SCxZQUFMLEVBQW1CO0FBQ2pCO0FBQ0Q7O0FBRUQxSSxJQUFBQSxNQUFNLENBQUM0SSxlQUFQLENBQXVCM0YsT0FBTyxDQUFDL0MsU0FBL0I7O0FBRUEzRCxvQkFBT0MsT0FBUCxDQUNHLGtCQUFpQmEsY0FBYyxDQUFDc0MsUUFBUyxvQkFBbUJzRCxPQUFPLENBQUMvQyxTQUFVLEVBRGpGO0FBR0Q7O0FBeDhCd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHY0IGZyb20gJ3R2NCc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5pbXBvcnQgeyBDbGllbnQgfSBmcm9tICcuL0NsaWVudCc7XG5pbXBvcnQgeyBQYXJzZVdlYlNvY2tldFNlcnZlciB9IGZyb20gJy4vUGFyc2VXZWJTb2NrZXRTZXJ2ZXInO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IFJlcXVlc3RTY2hlbWEgZnJvbSAnLi9SZXF1ZXN0U2NoZW1hJztcbmltcG9ydCB7IG1hdGNoZXNRdWVyeSwgcXVlcnlIYXNoIH0gZnJvbSAnLi9RdWVyeVRvb2xzJztcbmltcG9ydCB7IFBhcnNlUHViU3ViIH0gZnJvbSAnLi9QYXJzZVB1YlN1Yic7XG5pbXBvcnQgU2NoZW1hQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7XG4gIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMsXG4gIGdldFRyaWdnZXIsXG4gIHJ1blRyaWdnZXIsXG4gIHJlc29sdmVFcnJvcixcbiAgdG9KU09Od2l0aE9iamVjdHMsXG59IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCB7IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4sIEF1dGggfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IGdldENhY2hlQ29udHJvbGxlciwgZ2V0RGF0YWJhc2VDb250cm9sbGVyIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMnO1xuaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IFVzZXJSb3V0ZXIgZnJvbSAnLi4vUm91dGVycy9Vc2Vyc1JvdXRlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIHtcbiAgY2xpZW50czogTWFwO1xuICAvLyBjbGFzc05hbWUgLT4gKHF1ZXJ5SGFzaCAtPiBzdWJzY3JpcHRpb24pXG4gIHN1YnNjcmlwdGlvbnM6IE9iamVjdDtcbiAgcGFyc2VXZWJTb2NrZXRTZXJ2ZXI6IE9iamVjdDtcbiAga2V5UGFpcnM6IGFueTtcbiAgLy8gVGhlIHN1YnNjcmliZXIgd2UgdXNlIHRvIGdldCBvYmplY3QgdXBkYXRlIGZyb20gcHVibGlzaGVyXG4gIHN1YnNjcmliZXI6IE9iamVjdDtcblxuICBjb25zdHJ1Y3RvcihzZXJ2ZXI6IGFueSwgY29uZmlnOiBhbnkgPSB7fSwgcGFyc2VTZXJ2ZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcblxuICAgIGNvbmZpZy5hcHBJZCA9IGNvbmZpZy5hcHBJZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICAgIGNvbmZpZy5tYXN0ZXJLZXkgPSBjb25maWcubWFzdGVyS2V5IHx8IFBhcnNlLm1hc3RlcktleTtcblxuICAgIC8vIFN0b3JlIGtleXMsIGNvbnZlcnQgb2JqIHRvIG1hcFxuICAgIGNvbnN0IGtleVBhaXJzID0gY29uZmlnLmtleVBhaXJzIHx8IHt9O1xuICAgIHRoaXMua2V5UGFpcnMgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoa2V5UGFpcnMpKSB7XG4gICAgICB0aGlzLmtleVBhaXJzLnNldChrZXksIGtleVBhaXJzW2tleV0pO1xuICAgIH1cbiAgICBsb2dnZXIudmVyYm9zZSgnU3VwcG9ydCBrZXkgcGFpcnMnLCB0aGlzLmtleVBhaXJzKTtcblxuICAgIC8vIEluaXRpYWxpemUgUGFyc2VcbiAgICBQYXJzZS5PYmplY3QuZGlzYWJsZVNpbmdsZUluc3RhbmNlKCk7XG4gICAgY29uc3Qgc2VydmVyVVJMID0gY29uZmlnLnNlcnZlclVSTCB8fCBQYXJzZS5zZXJ2ZXJVUkw7XG4gICAgUGFyc2Uuc2VydmVyVVJMID0gc2VydmVyVVJMO1xuICAgIFBhcnNlLmluaXRpYWxpemUoY29uZmlnLmFwcElkLCBQYXJzZS5qYXZhU2NyaXB0S2V5LCBjb25maWcubWFzdGVyS2V5KTtcblxuICAgIC8vIFRoZSBjYWNoZSBjb250cm9sbGVyIGlzIGEgcHJvcGVyIGNhY2hlIGNvbnRyb2xsZXJcbiAgICAvLyB3aXRoIGFjY2VzcyB0byBVc2VyIGFuZCBSb2xlc1xuICAgIHRoaXMuY2FjaGVDb250cm9sbGVyID0gZ2V0Q2FjaGVDb250cm9sbGVyKHBhcnNlU2VydmVyQ29uZmlnKTtcblxuICAgIGNvbmZpZy5jYWNoZVRpbWVvdXQgPSBjb25maWcuY2FjaGVUaW1lb3V0IHx8IDUgKiAxMDAwOyAvLyA1c1xuXG4gICAgLy8gVGhpcyBhdXRoIGNhY2hlIHN0b3JlcyB0aGUgcHJvbWlzZXMgZm9yIGVhY2ggYXV0aCByZXNvbHV0aW9uLlxuICAgIC8vIFRoZSBtYWluIGJlbmVmaXQgaXMgdG8gYmUgYWJsZSB0byByZXVzZSB0aGUgc2FtZSB1c2VyIC8gc2Vzc2lvbiB0b2tlbiByZXNvbHV0aW9uLlxuICAgIHRoaXMuYXV0aENhY2hlID0gbmV3IExSVSh7XG4gICAgICBtYXg6IDUwMCwgLy8gNTAwIGNvbmN1cnJlbnRcbiAgICAgIHR0bDogY29uZmlnLmNhY2hlVGltZW91dCxcbiAgICB9KTtcbiAgICAvLyBJbml0aWFsaXplIHdlYnNvY2tldCBzZXJ2ZXJcbiAgICB0aGlzLnBhcnNlV2ViU29ja2V0U2VydmVyID0gbmV3IFBhcnNlV2ViU29ja2V0U2VydmVyKFxuICAgICAgc2VydmVyLFxuICAgICAgcGFyc2VXZWJzb2NrZXQgPT4gdGhpcy5fb25Db25uZWN0KHBhcnNlV2Vic29ja2V0KSxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG5cbiAgICAvLyBJbml0aWFsaXplIHN1YnNjcmliZXJcbiAgICB0aGlzLnN1YnNjcmliZXIgPSBQYXJzZVB1YlN1Yi5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG4gICAgdGhpcy5zdWJzY3JpYmVyLnN1YnNjcmliZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZScpO1xuICAgIHRoaXMuc3Vic2NyaWJlci5zdWJzY3JpYmUoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZScpO1xuICAgIHRoaXMuc3Vic2NyaWJlci5zdWJzY3JpYmUoUGFyc2UuYXBwbGljYXRpb25JZCArICdjbGVhckNhY2hlJyk7XG4gICAgLy8gUmVnaXN0ZXIgbWVzc2FnZSBoYW5kbGVyIGZvciBzdWJzY3JpYmVyLiBXaGVuIHB1Ymxpc2hlciBnZXQgbWVzc2FnZXMsIGl0IHdpbGwgcHVibGlzaCBtZXNzYWdlXG4gICAgLy8gdG8gdGhlIHN1YnNjcmliZXJzIGFuZCB0aGUgaGFuZGxlciB3aWxsIGJlIGNhbGxlZC5cbiAgICB0aGlzLnN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ1N1YnNjcmliZSBtZXNzYWdlICVqJywgbWVzc2FnZVN0cik7XG4gICAgICBsZXQgbWVzc2FnZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VTdHIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSBtZXNzYWdlJywgbWVzc2FnZVN0ciwgZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2NsZWFyQ2FjaGUnKSB7XG4gICAgICAgIHRoaXMuX2NsZWFyQ2FjaGVkUm9sZXMobWVzc2FnZS51c2VySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9pbmZsYXRlUGFyc2VPYmplY3QobWVzc2FnZSk7XG4gICAgICBpZiAoY2hhbm5lbCA9PT0gUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUnKSB7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJTYXZlKG1lc3NhZ2UpO1xuICAgICAgfSBlbHNlIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJykge1xuICAgICAgICB0aGlzLl9vbkFmdGVyRGVsZXRlKG1lc3NhZ2UpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdHZXQgbWVzc2FnZSAlcyBmcm9tIHVua25vd24gY2hhbm5lbCAlaicsIG1lc3NhZ2UsIGNoYW5uZWwpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gTWVzc2FnZSBpcyB0aGUgSlNPTiBvYmplY3QgZnJvbSBwdWJsaXNoZXIuIE1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0IGlzIHRoZSBQYXJzZU9iamVjdCBKU09OIGFmdGVyIGNoYW5nZXMuXG4gIC8vIE1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCBpcyB0aGUgb3JpZ2luYWwgUGFyc2VPYmplY3QgSlNPTi5cbiAgX2luZmxhdGVQYXJzZU9iamVjdChtZXNzYWdlOiBhbnkpOiB2b2lkIHtcbiAgICAvLyBJbmZsYXRlIG1lcmdlZCBvYmplY3RcbiAgICBjb25zdCBjdXJyZW50UGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdDtcbiAgICBVc2VyUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXMoY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBsZXQgY2xhc3NOYW1lID0gY3VycmVudFBhcnNlT2JqZWN0LmNsYXNzTmFtZTtcbiAgICBsZXQgcGFyc2VPYmplY3QgPSBuZXcgUGFyc2UuT2JqZWN0KGNsYXNzTmFtZSk7XG4gICAgcGFyc2VPYmplY3QuX2ZpbmlzaEZldGNoKGN1cnJlbnRQYXJzZU9iamVjdCk7XG4gICAgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgPSBwYXJzZU9iamVjdDtcbiAgICAvLyBJbmZsYXRlIG9yaWdpbmFsIG9iamVjdFxuICAgIGNvbnN0IG9yaWdpbmFsUGFyc2VPYmplY3QgPSBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3Q7XG4gICAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIGNsYXNzTmFtZSA9IG9yaWdpbmFsUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgICAgcGFyc2VPYmplY3QgPSBuZXcgUGFyc2UuT2JqZWN0KGNsYXNzTmFtZSk7XG4gICAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2gob3JpZ2luYWxQYXJzZU9iamVjdCk7XG4gICAgICBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgPSBwYXJzZU9iamVjdDtcbiAgICB9XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlciBhZnRlciBpbmZsYXRlZC4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IGFmdGVyIGNoYW5nZXMuXG4gIC8vIE1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCBpcyB0aGUgb3JpZ2luYWwgUGFyc2VPYmplY3QuXG4gIGFzeW5jIF9vbkFmdGVyRGVsZXRlKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIGxvZ2dlci52ZXJib3NlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUgaXMgdHJpZ2dlcmVkJyk7XG5cbiAgICBsZXQgZGVsZXRlZFBhcnNlT2JqZWN0ID0gbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QudG9KU09OKCk7XG4gICAgY29uc3QgY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gbWVzc2FnZS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gZGVsZXRlZFBhcnNlT2JqZWN0LmNsYXNzTmFtZTtcbiAgICBsb2dnZXIudmVyYm9zZSgnQ2xhc3NOYW1lOiAlaiB8IE9iamVjdElkOiAlcycsIGNsYXNzTmFtZSwgZGVsZXRlZFBhcnNlT2JqZWN0LmlkKTtcbiAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnQgbnVtYmVyIDogJWQnLCB0aGlzLmNsaWVudHMuc2l6ZSk7XG5cbiAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKHR5cGVvZiBjbGFzc1N1YnNjcmlwdGlvbnMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NhbiBub3QgZmluZCBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MgJyArIGNsYXNzTmFtZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc1N1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKGRlbGV0ZWRQYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIGlmICghaXNTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHJlcXVlc3RJZHMuZm9yRWFjaChhc3luYyByZXF1ZXN0SWQgPT4ge1xuICAgICAgICAgIGNvbnN0IGFjbCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LmdldEFDTCgpO1xuICAgICAgICAgIC8vIENoZWNrIENMUFxuICAgICAgICAgIGNvbnN0IG9wID0gdGhpcy5fZ2V0Q0xQT3BlcmF0aW9uKHN1YnNjcmlwdGlvbi5xdWVyeSk7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9tYXRjaGVzQ0xQKFxuICAgICAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgICAgb3BcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBpc01hdGNoZWQgPSBhd2FpdCB0aGlzLl9tYXRjaGVzQUNMKGFjbCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgaWYgKCFpc01hdGNoZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMgPSB7XG4gICAgICAgICAgICAgIGV2ZW50OiAnZGVsZXRlJyxcbiAgICAgICAgICAgICAgc2Vzc2lvblRva2VuOiBjbGllbnQuc2Vzc2lvblRva2VuLFxuICAgICAgICAgICAgICBvYmplY3Q6IGRlbGV0ZWRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgIHNlbmRFdmVudDogdHJ1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsICdhZnRlckV2ZW50JywgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgICAgICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICAgICAgICBjb25zdCBhdXRoID0gYXdhaXQgdGhpcy5nZXRBdXRoRnJvbUNsaWVudChjbGllbnQsIHJlcXVlc3RJZCk7XG4gICAgICAgICAgICAgIGlmIChhdXRoICYmIGF1dGgudXNlcikge1xuICAgICAgICAgICAgICAgIHJlcy51c2VyID0gYXV0aC51c2VyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChyZXMub2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgcmVzLm9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihyZXMub2JqZWN0KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBhd2FpdCBydW5UcmlnZ2VyKHRyaWdnZXIsIGBhZnRlckV2ZW50LiR7Y2xhc3NOYW1lfWAsIHJlcywgYXV0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXJlcy5zZW5kRXZlbnQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlcy5vYmplY3QgJiYgdHlwZW9mIHJlcy5vYmplY3QudG9KU09OID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGRlbGV0ZWRQYXJzZU9iamVjdCA9IHRvSlNPTndpdGhPYmplY3RzKHJlcy5vYmplY3QsIHJlcy5vYmplY3QuY2xhc3NOYW1lIHx8IGNsYXNzTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9maWx0ZXJTZW5zaXRpdmVEYXRhKFxuICAgICAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHJlcyxcbiAgICAgICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgICAgIG9wLFxuICAgICAgICAgICAgICBzdWJzY3JpcHRpb24ucXVlcnlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjbGllbnQucHVzaERlbGV0ZShyZXF1ZXN0SWQsIGRlbGV0ZWRQYXJzZU9iamVjdCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZSk7XG4gICAgICAgICAgICBDbGllbnQucHVzaEVycm9yKGNsaWVudC5wYXJzZVdlYlNvY2tldCwgZXJyb3IuY29kZSwgZXJyb3IubWVzc2FnZSwgZmFsc2UsIHJlcXVlc3RJZCk7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBhZnRlckxpdmVRdWVyeUV2ZW50IG9uIGNsYXNzICR7Y2xhc3NOYW1lfSBmb3IgZXZlbnQgJHtyZXMuZXZlbnR9IHdpdGggc2Vzc2lvbiAke3Jlcy5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlciBhZnRlciBpbmZsYXRlZC4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IGFmdGVyIGNoYW5nZXMuXG4gIC8vIE1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCBpcyB0aGUgb3JpZ2luYWwgUGFyc2VPYmplY3QuXG4gIGFzeW5jIF9vbkFmdGVyU2F2ZShtZXNzYWdlOiBhbnkpOiB2b2lkIHtcbiAgICBsb2dnZXIudmVyYm9zZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBvcmlnaW5hbFBhcnNlT2JqZWN0ID0gbnVsbDtcbiAgICBpZiAobWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgICBvcmlnaW5hbFBhcnNlT2JqZWN0ID0gbWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0LnRvSlNPTigpO1xuICAgIH1cbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBsZXQgY3VycmVudFBhcnNlT2JqZWN0ID0gbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QudG9KU09OKCk7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gY3VycmVudFBhcnNlT2JqZWN0LmNsYXNzTmFtZTtcbiAgICBsb2dnZXIudmVyYm9zZSgnQ2xhc3NOYW1lOiAlcyB8IE9iamVjdElkOiAlcycsIGNsYXNzTmFtZSwgY3VycmVudFBhcnNlT2JqZWN0LmlkKTtcbiAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnQgbnVtYmVyIDogJWQnLCB0aGlzLmNsaWVudHMuc2l6ZSk7XG5cbiAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKHR5cGVvZiBjbGFzc1N1YnNjcmlwdGlvbnMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZGVidWcoJ0NhbiBub3QgZmluZCBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MgJyArIGNsYXNzTmFtZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3Vic2NyaXB0aW9uIG9mIGNsYXNzU3Vic2NyaXB0aW9ucy52YWx1ZXMoKSkge1xuICAgICAgY29uc3QgaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKFxuICAgICAgICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICAgICAgICBzdWJzY3JpcHRpb25cbiAgICAgICk7XG4gICAgICBjb25zdCBpc0N1cnJlbnRTdWJzY3JpcHRpb25NYXRjaGVkID0gdGhpcy5fbWF0Y2hlc1N1YnNjcmlwdGlvbihcbiAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICBzdWJzY3JpcHRpb25cbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IFtjbGllbnRJZCwgcmVxdWVzdElkc10gb2YgXy5lbnRyaWVzKHN1YnNjcmlwdGlvbi5jbGllbnRSZXF1ZXN0SWRzKSkge1xuICAgICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KGNsaWVudElkKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGllbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmVxdWVzdElkcy5mb3JFYWNoKGFzeW5jIHJlcXVlc3RJZCA9PiB7XG4gICAgICAgICAgLy8gU2V0IG9yaWduYWwgUGFyc2VPYmplY3QgQUNMIGNoZWNraW5nIHByb21pc2UsIGlmIHRoZSBvYmplY3QgZG9lcyBub3QgbWF0Y2hcbiAgICAgICAgICAvLyBzdWJzY3JpcHRpb24sIHdlIGRvIG5vdCBuZWVkIHRvIGNoZWNrIEFDTFxuICAgICAgICAgIGxldCBvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZTtcbiAgICAgICAgICBpZiAoIWlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgICAgICBvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvcmlnaW5hbEFDTDtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxBQ0wgPSBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QuZ2V0QUNMKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSA9IHRoaXMuX21hdGNoZXNBQ0wob3JpZ2luYWxBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gU2V0IGN1cnJlbnQgUGFyc2VPYmplY3QgQUNMIGNoZWNraW5nIHByb21pc2UsIGlmIHRoZSBvYmplY3QgZG9lcyBub3QgbWF0Y2hcbiAgICAgICAgICAvLyBzdWJzY3JpcHRpb24sIHdlIGRvIG5vdCBuZWVkIHRvIGNoZWNrIEFDTFxuICAgICAgICAgIGxldCBjdXJyZW50QUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGxldCByZXMgPSB7fTtcbiAgICAgICAgICBpZiAoIWlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjdXJyZW50QUNMID0gbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QuZ2V0QUNMKCk7XG4gICAgICAgICAgICBjdXJyZW50QUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChjdXJyZW50QUNMLCBjbGllbnQsIHJlcXVlc3RJZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBvcCA9IHRoaXMuX2dldENMUE9wZXJhdGlvbihzdWJzY3JpcHRpb24ucXVlcnkpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fbWF0Y2hlc0NMUChcbiAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgICAgIG9wXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgW2lzT3JpZ2luYWxNYXRjaGVkLCBpc0N1cnJlbnRNYXRjaGVkXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgb3JpZ2luYWxBQ0xDaGVja2luZ1Byb21pc2UsXG4gICAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UsXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgICAnT3JpZ2luYWwgJWogfCBDdXJyZW50ICVqIHwgTWF0Y2g6ICVzLCAlcywgJXMsICVzIHwgUXVlcnk6ICVzJyxcbiAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBpc09yaWdpbmFsU3Vic2NyaXB0aW9uTWF0Y2hlZCxcbiAgICAgICAgICAgICAgaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCxcbiAgICAgICAgICAgICAgaXNPcmlnaW5hbE1hdGNoZWQsXG4gICAgICAgICAgICAgIGlzQ3VycmVudE1hdGNoZWQsXG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5oYXNoXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLy8gRGVjaWRlIGV2ZW50IHR5cGVcbiAgICAgICAgICAgIGxldCB0eXBlO1xuICAgICAgICAgICAgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgdHlwZSA9ICd1cGRhdGUnO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09yaWdpbmFsTWF0Y2hlZCAmJiAhaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICB0eXBlID0gJ2xlYXZlJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ2VudGVyJztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ2NyZWF0ZSc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICBldmVudDogdHlwZSxcbiAgICAgICAgICAgICAgc2Vzc2lvblRva2VuOiBjbGllbnQuc2Vzc2lvblRva2VuLFxuICAgICAgICAgICAgICBvYmplY3Q6IGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgb3JpZ2luYWw6IG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICAgICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgICAgICBzZW5kRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCAnYWZ0ZXJFdmVudCcsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgICAgICAgICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgICAgICAgICAgaWYgKHJlcy5vYmplY3QpIHtcbiAgICAgICAgICAgICAgICByZXMub2JqZWN0ID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKHJlcy5vYmplY3QpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChyZXMub3JpZ2luYWwpIHtcbiAgICAgICAgICAgICAgICByZXMub3JpZ2luYWwgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVzLm9yaWdpbmFsKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjb25zdCBhdXRoID0gYXdhaXQgdGhpcy5nZXRBdXRoRnJvbUNsaWVudChjbGllbnQsIHJlcXVlc3RJZCk7XG4gICAgICAgICAgICAgIGlmIChhdXRoICYmIGF1dGgudXNlcikge1xuICAgICAgICAgICAgICAgIHJlcy51c2VyID0gYXV0aC51c2VyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGF3YWl0IHJ1blRyaWdnZXIodHJpZ2dlciwgYGFmdGVyRXZlbnQuJHtjbGFzc05hbWV9YCwgcmVzLCBhdXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0ID0gdG9KU09Od2l0aE9iamVjdHMocmVzLm9iamVjdCwgcmVzLm9iamVjdC5jbGFzc05hbWUgfHwgY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXMub3JpZ2luYWwgJiYgdHlwZW9mIHJlcy5vcmlnaW5hbC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IHRvSlNPTndpdGhPYmplY3RzKFxuICAgICAgICAgICAgICAgIHJlcy5vcmlnaW5hbCxcbiAgICAgICAgICAgICAgICByZXMub3JpZ2luYWwuY2xhc3NOYW1lIHx8IGNsYXNzTmFtZVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fZmlsdGVyU2Vuc2l0aXZlRGF0YShcbiAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICByZXMsXG4gICAgICAgICAgICAgIGNsaWVudCxcbiAgICAgICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgICAgICBvcCxcbiAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnF1ZXJ5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgZnVuY3Rpb25OYW1lID0gJ3B1c2gnICsgcmVzLmV2ZW50LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcmVzLmV2ZW50LnNsaWNlKDEpO1xuICAgICAgICAgICAgaWYgKGNsaWVudFtmdW5jdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICAgIGNsaWVudFtmdW5jdGlvbk5hbWVdKHJlcXVlc3RJZCwgY3VycmVudFBhcnNlT2JqZWN0LCBvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IHJlc29sdmVFcnJvcihlKTtcbiAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoY2xpZW50LnBhcnNlV2ViU29ja2V0LCBlcnJvci5jb2RlLCBlcnJvci5tZXNzYWdlLCBmYWxzZSwgcmVxdWVzdElkKTtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCBydW5uaW5nIGFmdGVyTGl2ZVF1ZXJ5RXZlbnQgb24gY2xhc3MgJHtjbGFzc05hbWV9IGZvciBldmVudCAke3Jlcy5ldmVudH0gd2l0aCBzZXNzaW9uICR7cmVzLnNlc3Npb25Ub2tlbn0gd2l0aDpcXG4gRXJyb3I6IGAgK1xuICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9vbkNvbm5lY3QocGFyc2VXZWJzb2NrZXQ6IGFueSk6IHZvaWQge1xuICAgIHBhcnNlV2Vic29ja2V0Lm9uKCdtZXNzYWdlJywgcmVxdWVzdCA9PiB7XG4gICAgICBpZiAodHlwZW9mIHJlcXVlc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVxdWVzdCA9IEpTT04ucGFyc2UocmVxdWVzdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSByZXF1ZXN0JywgcmVxdWVzdCwgZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsb2dnZXIudmVyYm9zZSgnUmVxdWVzdDogJWonLCByZXF1ZXN0KTtcblxuICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGlzIHJlcXVlc3QgaXMgYSB2YWxpZCByZXF1ZXN0LCByZXR1cm4gZXJyb3IgZGlyZWN0bHkgaWYgbm90XG4gICAgICBpZiAoXG4gICAgICAgICF0djQudmFsaWRhdGUocmVxdWVzdCwgUmVxdWVzdFNjaGVtYVsnZ2VuZXJhbCddKSB8fFxuICAgICAgICAhdHY0LnZhbGlkYXRlKHJlcXVlc3QsIFJlcXVlc3RTY2hlbWFbcmVxdWVzdC5vcF0pXG4gICAgICApIHtcbiAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgMSwgdHY0LmVycm9yLm1lc3NhZ2UpO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0Nvbm5lY3QgbWVzc2FnZSBlcnJvciAlcycsIHR2NC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHJlcXVlc3Qub3ApIHtcbiAgICAgICAgY2FzZSAnY29ubmVjdCc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlQ29ubmVjdChwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXBkYXRlJzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVVcGRhdGVTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1bnN1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDMsICdHZXQgdW5rbm93biBvcGVyYXRpb24nKTtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCB1bmtub3duIG9wZXJhdGlvbicsIHJlcXVlc3Qub3ApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGFyc2VXZWJzb2NrZXQub24oJ2Rpc2Nvbm5lY3QnLCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ2xpZW50IGRpc2Nvbm5lY3Q6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9YCk7XG4gICAgICBjb25zdCBjbGllbnRJZCA9IHBhcnNlV2Vic29ja2V0LmNsaWVudElkO1xuICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkKSkge1xuICAgICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3RfZXJyb3InLFxuICAgICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICAgIGVycm9yOiBgVW5hYmxlIHRvIGZpbmQgY2xpZW50ICR7Y2xpZW50SWR9YCxcbiAgICAgICAgfSk7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgQ2FuIG5vdCBmaW5kIGNsaWVudCAke2NsaWVudElkfSBvbiBkaXNjb25uZWN0YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRGVsZXRlIGNsaWVudFxuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkKTtcblxuICAgICAgLy8gRGVsZXRlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgIGZvciAoY29uc3QgW3JlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mb10gb2YgXy5lbnRyaWVzKGNsaWVudC5zdWJzY3JpcHRpb25JbmZvcykpIHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc3Vic2NyaXB0aW9uSW5mby5zdWJzY3JpcHRpb247XG4gICAgICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQsIHJlcXVlc3RJZCk7XG5cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoc3Vic2NyaXB0aW9uLmNsYXNzTmFtZSk7XG4gICAgICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuZGVsZXRlKHN1YnNjcmlwdGlvbi5oYXNoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgaWYgKGNsYXNzU3Vic2NyaXB0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnRzICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgc3Vic2NyaXB0aW9ucyAlZCcsIHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplKTtcbiAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3QnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBjbGllbnQuc2Vzc2lvblRva2VuLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGV2ZW50OiAnd3NfY29ubmVjdCcsXG4gICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgIH0pO1xuICB9XG5cbiAgX21hdGNoZXNTdWJzY3JpcHRpb24ocGFyc2VPYmplY3Q6IGFueSwgc3Vic2NyaXB0aW9uOiBhbnkpOiBib29sZWFuIHtcbiAgICAvLyBPYmplY3QgaXMgdW5kZWZpbmVkIG9yIG51bGwsIG5vdCBtYXRjaFxuICAgIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShwYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgfVxuXG4gIGFzeW5jIF9jbGVhckNhY2hlZFJvbGVzKHVzZXJJZDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHZhbGlkVG9rZW5zID0gYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5lcXVhbFRvKCd1c2VyJywgUGFyc2UuVXNlci5jcmVhdGVXaXRob3V0RGF0YSh1c2VySWQpKVxuICAgICAgICAuZmluZCh7IHVzZU1hc3RlcktleTogdHJ1ZSB9KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICB2YWxpZFRva2Vucy5tYXAoYXN5bmMgdG9rZW4gPT4ge1xuICAgICAgICAgIGNvbnN0IHNlc3Npb25Ub2tlbiA9IHRva2VuLmdldCgnc2Vzc2lvblRva2VuJyk7XG4gICAgICAgICAgY29uc3QgYXV0aFByb21pc2UgPSB0aGlzLmF1dGhDYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICBpZiAoIWF1dGhQcm9taXNlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IFthdXRoMSwgYXV0aDJdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgYXV0aFByb21pc2UsXG4gICAgICAgICAgICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuKHsgY2FjaGVDb250cm9sbGVyOiB0aGlzLmNhY2hlQ29udHJvbGxlciwgc2Vzc2lvblRva2VuIH0pLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgIGF1dGgxLmF1dGg/LmNsZWFyUm9sZUNhY2hlKHNlc3Npb25Ub2tlbik7XG4gICAgICAgICAgYXV0aDIuYXV0aD8uY2xlYXJSb2xlQ2FjaGUoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICB0aGlzLmF1dGhDYWNoZS5kZWwoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoYENvdWxkIG5vdCBjbGVhciByb2xlIGNhY2hlLiAke2V9YCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0QXV0aEZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW46ID9zdHJpbmcpOiBQcm9taXNlPHsgYXV0aDogP0F1dGgsIHVzZXJJZDogP3N0cmluZyB9PiB7XG4gICAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICBjb25zdCBmcm9tQ2FjaGUgPSB0aGlzLmF1dGhDYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAoZnJvbUNhY2hlKSB7XG4gICAgICByZXR1cm4gZnJvbUNhY2hlO1xuICAgIH1cbiAgICBjb25zdCBhdXRoUHJvbWlzZSA9IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgY2FjaGVDb250cm9sbGVyOiB0aGlzLmNhY2hlQ29udHJvbGxlcixcbiAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgIH0pXG4gICAgICAudGhlbihhdXRoID0+IHtcbiAgICAgICAgcmV0dXJuIHsgYXV0aCwgdXNlcklkOiBhdXRoICYmIGF1dGgudXNlciAmJiBhdXRoLnVzZXIuaWQgfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvLyBUaGVyZSB3YXMgYW4gZXJyb3Igd2l0aCB0aGUgc2Vzc2lvbiB0b2tlblxuICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTikge1xuICAgICAgICAgIHJlc3VsdC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLnNldChzZXNzaW9uVG9rZW4sIFByb21pc2UucmVzb2x2ZShyZXN1bHQpLCB0aGlzLmNvbmZpZy5jYWNoZVRpbWVvdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLmRlbChzZXNzaW9uVG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB0aGlzLmF1dGhDYWNoZS5zZXQoc2Vzc2lvblRva2VuLCBhdXRoUHJvbWlzZSk7XG4gICAgcmV0dXJuIGF1dGhQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNDTFAoXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55LFxuICAgIG9iamVjdDogYW55LFxuICAgIGNsaWVudDogYW55LFxuICAgIHJlcXVlc3RJZDogbnVtYmVyLFxuICAgIG9wOiBzdHJpbmdcbiAgKTogYW55IHtcbiAgICAvLyB0cnkgdG8gbWF0Y2ggb24gdXNlciBmaXJzdCwgbGVzcyBleHBlbnNpdmUgdGhhbiB3aXRoIHJvbGVzXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBbJyonXTtcbiAgICBsZXQgdXNlcklkO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IHsgdXNlcklkIH0gPSBhd2FpdCB0aGlzLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4pO1xuICAgICAgaWYgKHVzZXJJZCkge1xuICAgICAgICBhY2xHcm91cC5wdXNoKHVzZXJJZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBTY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihcbiAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICBvYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgb3BcbiAgICAgICk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZShgRmFpbGVkIG1hdGNoaW5nIENMUCBmb3IgJHtvYmplY3QuaWR9ICR7dXNlcklkfSAke2V9YCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFRPRE86IGhhbmRsZSByb2xlcyBwZXJtaXNzaW9uc1xuICAgIC8vIE9iamVjdC5rZXlzKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgLy8gICBjb25zdCBwZXJtID0gY2xhc3NMZXZlbFBlcm1pc3Npb25zW2tleV07XG4gICAgLy8gICBPYmplY3Qua2V5cyhwZXJtKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAvLyAgICAgaWYgKGtleS5pbmRleE9mKCdyb2xlJykpXG4gICAgLy8gICB9KTtcbiAgICAvLyB9KVxuICAgIC8vIC8vIGl0J3MgcmVqZWN0ZWQgaGVyZSwgY2hlY2sgdGhlIHJvbGVzXG4gICAgLy8gdmFyIHJvbGVzUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoUGFyc2UuUm9sZSk7XG4gICAgLy8gcm9sZXNRdWVyeS5lcXVhbFRvKFwidXNlcnNcIiwgdXNlcik7XG4gICAgLy8gcmV0dXJuIHJvbGVzUXVlcnkuZmluZCh7dXNlTWFzdGVyS2V5OnRydWV9KTtcbiAgfVxuXG4gIGFzeW5jIF9maWx0ZXJTZW5zaXRpdmVEYXRhKFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogP2FueSxcbiAgICByZXM6IGFueSxcbiAgICBjbGllbnQ6IGFueSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlcixcbiAgICBvcDogc3RyaW5nLFxuICAgIHF1ZXJ5OiBhbnlcbiAgKSB7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgY29uc3QgYWNsR3JvdXAgPSBbJyonXTtcbiAgICBsZXQgY2xpZW50QXV0aDtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCB7IHVzZXJJZCwgYXV0aCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuKTtcbiAgICAgIGlmICh1c2VySWQpIHtcbiAgICAgICAgYWNsR3JvdXAucHVzaCh1c2VySWQpO1xuICAgICAgfVxuICAgICAgY2xpZW50QXV0aCA9IGF1dGg7XG4gICAgfVxuICAgIGNvbnN0IGZpbHRlciA9IG9iaiA9PiB7XG4gICAgICBpZiAoIW9iaikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsZXQgcHJvdGVjdGVkRmllbGRzID0gY2xhc3NMZXZlbFBlcm1pc3Npb25zPy5wcm90ZWN0ZWRGaWVsZHMgfHwgW107XG4gICAgICBpZiAoIWNsaWVudC5oYXNNYXN0ZXJLZXkgJiYgIUFycmF5LmlzQXJyYXkocHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgICBwcm90ZWN0ZWRGaWVsZHMgPSBnZXREYXRhYmFzZUNvbnRyb2xsZXIodGhpcy5jb25maWcpLmFkZFByb3RlY3RlZEZpZWxkcyhcbiAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgcmVzLm9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgICAgcXVlcnksXG4gICAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgICAgY2xpZW50QXV0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIERhdGFiYXNlQ29udHJvbGxlci5maWx0ZXJTZW5zaXRpdmVEYXRhKFxuICAgICAgICBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgY2xpZW50QXV0aCxcbiAgICAgICAgb3AsXG4gICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgcmVzLm9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgIHByb3RlY3RlZEZpZWxkcyxcbiAgICAgICAgb2JqLFxuICAgICAgICBxdWVyeVxuICAgICAgKTtcbiAgICB9O1xuICAgIHJlcy5vYmplY3QgPSBmaWx0ZXIocmVzLm9iamVjdCk7XG4gICAgcmVzLm9yaWdpbmFsID0gZmlsdGVyKHJlcy5vcmlnaW5hbCk7XG4gIH1cblxuICBfZ2V0Q0xQT3BlcmF0aW9uKHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJlxuICAgICAgT2JqZWN0LmtleXMocXVlcnkpLmxlbmd0aCA9PSAxICYmXG4gICAgICB0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnXG4gICAgICA/ICdnZXQnXG4gICAgICA6ICdmaW5kJztcbiAgfVxuXG4gIGFzeW5jIF92ZXJpZnlBQ0woYWNsOiBhbnksIHRva2VuOiBzdHJpbmcpIHtcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhdXRoLCB1c2VySWQgfSA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih0b2tlbik7XG5cbiAgICAvLyBHZXR0aW5nIHRoZSBzZXNzaW9uIHRva2VuIGZhaWxlZFxuICAgIC8vIFRoaXMgbWVhbnMgdGhhdCBubyBhZGRpdGlvbmFsIGF1dGggaXMgYXZhaWxhYmxlXG4gICAgLy8gQXQgdGhpcyBwb2ludCwganVzdCBiYWlsIG91dCBhcyBubyBhZGRpdGlvbmFsIHZpc2liaWxpdHkgY2FuIGJlIGluZmVycmVkLlxuICAgIGlmICghYXV0aCB8fCAhdXNlcklkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCA9IGFjbC5nZXRSZWFkQWNjZXNzKHVzZXJJZCk7XG4gICAgaWYgKGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHVzZXIgaGFzIGFueSByb2xlcyB0aGF0IG1hdGNoIHRoZSBBQ0xcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gUmVzb2x2ZSBmYWxzZSByaWdodCBhd2F5IGlmIHRoZSBhY2wgZG9lc24ndCBoYXZlIGFueSByb2xlc1xuICAgICAgICBjb25zdCBhY2xfaGFzX3JvbGVzID0gT2JqZWN0LmtleXMoYWNsLnBlcm1pc3Npb25zQnlJZCkuc29tZShrZXkgPT4ga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpO1xuICAgICAgICBpZiAoIWFjbF9oYXNfcm9sZXMpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgcm9sZU5hbWVzID0gYXdhaXQgYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgICAgICAgLy8gRmluYWxseSwgc2VlIGlmIGFueSBvZiB0aGUgdXNlcidzIHJvbGVzIGFsbG93IHRoZW0gcmVhZCBhY2Nlc3NcbiAgICAgICAgZm9yIChjb25zdCByb2xlIG9mIHJvbGVOYW1lcykge1xuICAgICAgICAgIC8vIFdlIHVzZSBnZXRSZWFkQWNjZXNzIGFzIGByb2xlYCBpcyBpbiB0aGUgZm9ybSBgcm9sZTpyb2xlTmFtZWBcbiAgICAgICAgICBpZiAoYWNsLmdldFJlYWRBY2Nlc3Mocm9sZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBnZXRBdXRoRnJvbUNsaWVudChjbGllbnQ6IGFueSwgcmVxdWVzdElkOiBudW1iZXIsIHNlc3Npb25Ub2tlbjogc3RyaW5nKSB7XG4gICAgY29uc3QgZ2V0U2Vzc2lvbkZyb21DbGllbnQgPSAoKSA9PiB7XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGNsaWVudC5zZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICByZXR1cm4gc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4gfHwgY2xpZW50LnNlc3Npb25Ub2tlbjtcbiAgICB9O1xuICAgIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgICBzZXNzaW9uVG9rZW4gPSBnZXRTZXNzaW9uRnJvbUNsaWVudCgpO1xuICAgIH1cbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB7IGF1dGggfSA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pO1xuICAgIHJldHVybiBhdXRoO1xuICB9XG5cbiAgYXN5bmMgX21hdGNoZXNBQ0woYWNsOiBhbnksIGNsaWVudDogYW55LCByZXF1ZXN0SWQ6IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIC8vIFJldHVybiB0cnVlIGRpcmVjdGx5IGlmIEFDTCBpc24ndCBwcmVzZW50LCBBQ0wgaXMgcHVibGljIHJlYWQsIG9yIGNsaWVudCBoYXMgbWFzdGVyIGtleVxuICAgIGlmICghYWNsIHx8IGFjbC5nZXRQdWJsaWNSZWFkQWNjZXNzKCkgfHwgY2xpZW50Lmhhc01hc3RlcktleSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENoZWNrIHN1YnNjcmlwdGlvbiBzZXNzaW9uVG9rZW4gbWF0Y2hlcyBBQ0wgZmlyc3RcbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uVG9rZW4gPSBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbjtcbiAgICBjb25zdCBjbGllbnRTZXNzaW9uVG9rZW4gPSBjbGllbnQuc2Vzc2lvblRva2VuO1xuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIHN1YnNjcmlwdGlvblRva2VuKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGF3YWl0IHRoaXMuX3ZlcmlmeUFDTChhY2wsIGNsaWVudFNlc3Npb25Ub2tlbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVDb25uZWN0KHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgaWYgKCF0aGlzLl92YWxpZGF0ZUtleXMocmVxdWVzdCwgdGhpcy5rZXlQYWlycykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDQsICdLZXkgaW4gcmVxdWVzdCBpcyBub3QgdmFsaWQnKTtcbiAgICAgIGxvZ2dlci5lcnJvcignS2V5IGluIHJlcXVlc3QgaXMgbm90IHZhbGlkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhhc01hc3RlcktleSA9IHRoaXMuX2hhc01hc3RlcktleShyZXF1ZXN0LCB0aGlzLmtleVBhaXJzKTtcbiAgICBjb25zdCBjbGllbnRJZCA9IHV1aWR2NCgpO1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoXG4gICAgICBjbGllbnRJZCxcbiAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgaGFzTWFzdGVyS2V5LFxuICAgICAgcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICByZXF1ZXN0Lmluc3RhbGxhdGlvbklkXG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICBjbGllbnQsXG4gICAgICAgIGV2ZW50OiAnY29ubmVjdCcsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgc2Vzc2lvblRva2VuOiByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogcmVxdWVzdC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcignQENvbm5lY3QnLCAnYmVmb3JlQ29ubmVjdCcsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgICAgY29uc3QgYXV0aCA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZyb21DbGllbnQoY2xpZW50LCByZXF1ZXN0LnJlcXVlc3RJZCwgcmVxLnNlc3Npb25Ub2tlbik7XG4gICAgICAgIGlmIChhdXRoICYmIGF1dGgudXNlcikge1xuICAgICAgICAgIHJlcS51c2VyID0gYXV0aC51c2VyO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHJ1blRyaWdnZXIodHJpZ2dlciwgYGJlZm9yZUNvbm5lY3QuQENvbm5lY3RgLCByZXEsIGF1dGgpO1xuICAgICAgfVxuICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgPSBjbGllbnRJZDtcbiAgICAgIHRoaXMuY2xpZW50cy5zZXQocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIGNsaWVudCk7XG4gICAgICBsb2dnZXIuaW5mbyhgQ3JlYXRlIG5ldyBjbGllbnQ6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9YCk7XG4gICAgICBjbGllbnQucHVzaENvbm5lY3QoKTtcbiAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMocmVxKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCBlcnJvciA9IHJlc29sdmVFcnJvcihlKTtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGVycm9yLmNvZGUsIGVycm9yLm1lc3NhZ2UsIGZhbHNlKTtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgYEZhaWxlZCBydW5uaW5nIGJlZm9yZUNvbm5lY3QgZm9yIHNlc3Npb24gJHtyZXF1ZXN0LnNlc3Npb25Ub2tlbn0gd2l0aDpcXG4gRXJyb3I6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfaGFzTWFzdGVyS2V5KHJlcXVlc3Q6IGFueSwgdmFsaWRLZXlQYWlyczogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCF2YWxpZEtleVBhaXJzIHx8IHZhbGlkS2V5UGFpcnMuc2l6ZSA9PSAwIHx8ICF2YWxpZEtleVBhaXJzLmhhcygnbWFzdGVyS2V5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKCFyZXF1ZXN0IHx8ICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVxdWVzdCwgJ21hc3RlcktleScpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiByZXF1ZXN0Lm1hc3RlcktleSA9PT0gdmFsaWRLZXlQYWlycy5nZXQoJ21hc3RlcktleScpO1xuICB9XG5cbiAgX3ZhbGlkYXRlS2V5cyhyZXF1ZXN0OiBhbnksIHZhbGlkS2V5UGFpcnM6IGFueSk6IGJvb2xlYW4ge1xuICAgIGlmICghdmFsaWRLZXlQYWlycyB8fCB2YWxpZEtleVBhaXJzLnNpemUgPT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGxldCBpc1ZhbGlkID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBba2V5LCBzZWNyZXRdIG9mIHZhbGlkS2V5UGFpcnMpIHtcbiAgICAgIGlmICghcmVxdWVzdFtrZXldIHx8IHJlcXVlc3Rba2V5XSAhPT0gc2VjcmV0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaXNWYWxpZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGlzVmFsaWQ7XG4gIH1cblxuICBhc3luYyBfaGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgLy8gSWYgd2UgY2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCByZXR1cm4gZXJyb3IgdG8gY2xpZW50XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGFyc2VXZWJzb2NrZXQsICdjbGllbnRJZCcpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHN1YnNjcmliaW5nJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHJlcXVlc3QucXVlcnkuY2xhc3NOYW1lO1xuICAgIGxldCBhdXRoQ2FsbGVkID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgJ2JlZm9yZVN1YnNjcmliZScsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICAgICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgICAgY29uc3QgYXV0aCA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZyb21DbGllbnQoY2xpZW50LCByZXF1ZXN0LnJlcXVlc3RJZCwgcmVxdWVzdC5zZXNzaW9uVG9rZW4pO1xuICAgICAgICBhdXRoQ2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKGF1dGggJiYgYXV0aC51c2VyKSB7XG4gICAgICAgICAgcmVxdWVzdC51c2VyID0gYXV0aC51c2VyO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFyc2VRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWUpO1xuICAgICAgICBwYXJzZVF1ZXJ5LndpdGhKU09OKHJlcXVlc3QucXVlcnkpO1xuICAgICAgICByZXF1ZXN0LnF1ZXJ5ID0gcGFyc2VRdWVyeTtcbiAgICAgICAgYXdhaXQgcnVuVHJpZ2dlcih0cmlnZ2VyLCBgYmVmb3JlU3Vic2NyaWJlLiR7Y2xhc3NOYW1lfWAsIHJlcXVlc3QsIGF1dGgpO1xuXG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gcmVxdWVzdC5xdWVyeS50b0pTT04oKTtcbiAgICAgICAgaWYgKHF1ZXJ5LmtleXMpIHtcbiAgICAgICAgICBxdWVyeS5maWVsZHMgPSBxdWVyeS5rZXlzLnNwbGl0KCcsJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xuICAgICAgfVxuXG4gICAgICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nKSB7XG4gICAgICAgIGlmICghYXV0aENhbGxlZCkge1xuICAgICAgICAgIGNvbnN0IGF1dGggPSBhd2FpdCB0aGlzLmdldEF1dGhGcm9tQ2xpZW50KFxuICAgICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICAgcmVxdWVzdC5yZXF1ZXN0SWQsXG4gICAgICAgICAgICByZXF1ZXN0LnNlc3Npb25Ub2tlblxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGF1dGggJiYgYXV0aC51c2VyKSB7XG4gICAgICAgICAgICByZXF1ZXN0LnVzZXIgPSBhdXRoLnVzZXI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0LnVzZXIpIHtcbiAgICAgICAgICByZXF1ZXN0LnF1ZXJ5LndoZXJlLnVzZXIgPSByZXF1ZXN0LnVzZXIudG9Qb2ludGVyKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXJlcXVlc3QubWFzdGVyKSB7XG4gICAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLFxuICAgICAgICAgICAgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIHJlcXVlc3QucmVxdWVzdElkXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEdldCBzdWJzY3JpcHRpb24gZnJvbSBzdWJzY3JpcHRpb25zLCBjcmVhdGUgb25lIGlmIG5lY2Vzc2FyeVxuICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uSGFzaCA9IHF1ZXJ5SGFzaChyZXF1ZXN0LnF1ZXJ5KTtcbiAgICAgIC8vIEFkZCBjbGFzc05hbWUgdG8gc3Vic2NyaXB0aW9ucyBpZiBuZWNlc3NhcnlcblxuICAgICAgaWYgKCF0aGlzLnN1YnNjcmlwdGlvbnMuaGFzKGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnNldChjbGFzc05hbWUsIG5ldyBNYXAoKSk7XG4gICAgICB9XG4gICAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgICBsZXQgc3Vic2NyaXB0aW9uO1xuICAgICAgaWYgKGNsYXNzU3Vic2NyaXB0aW9ucy5oYXMoc3Vic2NyaXB0aW9uSGFzaCkpIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uID0gY2xhc3NTdWJzY3JpcHRpb25zLmdldChzdWJzY3JpcHRpb25IYXNoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oY2xhc3NOYW1lLCByZXF1ZXN0LnF1ZXJ5LndoZXJlLCBzdWJzY3JpcHRpb25IYXNoKTtcbiAgICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLnNldChzdWJzY3JpcHRpb25IYXNoLCBzdWJzY3JpcHRpb24pO1xuICAgICAgfVxuXG4gICAgICAvLyBBZGQgc3Vic2NyaXB0aW9uSW5mbyB0byBjbGllbnRcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkluZm8gPSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbjogc3Vic2NyaXB0aW9uLFxuICAgICAgfTtcbiAgICAgIC8vIEFkZCBzZWxlY3RlZCBmaWVsZHMsIHNlc3Npb25Ub2tlbiBhbmQgaW5zdGFsbGF0aW9uSWQgZm9yIHRoaXMgc3Vic2NyaXB0aW9uIGlmIG5lY2Vzc2FyeVxuICAgICAgaWYgKHJlcXVlc3QucXVlcnkuZmllbGRzKSB7XG4gICAgICAgIHN1YnNjcmlwdGlvbkluZm8uZmllbGRzID0gcmVxdWVzdC5xdWVyeS5maWVsZHM7XG4gICAgICB9XG4gICAgICBpZiAocmVxdWVzdC5zZXNzaW9uVG9rZW4pIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4gPSByZXF1ZXN0LnNlc3Npb25Ub2tlbjtcbiAgICAgIH1cbiAgICAgIGNsaWVudC5hZGRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3QucmVxdWVzdElkLCBzdWJzY3JpcHRpb25JbmZvKTtcblxuICAgICAgLy8gQWRkIGNsaWVudElkIHRvIHN1YnNjcmlwdGlvblxuICAgICAgc3Vic2NyaXB0aW9uLmFkZENsaWVudFN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgcmVxdWVzdC5yZXF1ZXN0SWQpO1xuXG4gICAgICBjbGllbnQucHVzaFN1YnNjcmliZShyZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICBgQ3JlYXRlIGNsaWVudCAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfSBuZXcgc3Vic2NyaXB0aW9uOiAke3JlcXVlc3QucmVxdWVzdElkfWBcbiAgICAgICk7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnQgbnVtYmVyOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcbiAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICBjbGllbnQsXG4gICAgICAgIGV2ZW50OiAnc3Vic2NyaWJlJyxcbiAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICBzZXNzaW9uVG9rZW46IHJlcXVlc3Quc2Vzc2lvblRva2VuLFxuICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCBlcnJvciA9IHJlc29sdmVFcnJvcihlKTtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGVycm9yLmNvZGUsIGVycm9yLm1lc3NhZ2UsIGZhbHNlLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgIGBGYWlsZWQgcnVubmluZyBiZWZvcmVTdWJzY3JpYmUgb24gJHtjbGFzc05hbWV9IGZvciBzZXNzaW9uICR7cmVxdWVzdC5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIHRoaXMuX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0LCBmYWxzZSk7XG4gICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgfVxuXG4gIF9oYW5kbGVVbnN1YnNjcmliZShwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnksIG5vdGlmeUNsaWVudDogYm9vbGVhbiA9IHRydWUpOiBhbnkge1xuICAgIC8vIElmIHdlIGNhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgcmV0dXJuIGVycm9yIHRvIGNsaWVudFxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhcnNlV2Vic29ja2V0LCAnY2xpZW50SWQnKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nJ1xuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdElkID0gcmVxdWVzdC5yZXF1ZXN0SWQ7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgaWYgKHR5cGVvZiBjbGllbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIGNsaWVudCB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnLiBNYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50ICcgKyBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW5ub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3Ugc3Vic2NyaWJlIHRvIGxpdmUgcXVlcnkgc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nLidcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9uIHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcgc3Vic2NyaXB0aW9uSWQgJyArXG4gICAgICAgICAgcmVxdWVzdElkXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBzdWJzY3JpcHRpb24gZnJvbSBjbGllbnRcbiAgICBjbGllbnQuZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIC8vIFJlbW92ZSBjbGllbnQgZnJvbSBzdWJzY3JpcHRpb25cbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBzdWJzY3JpcHRpb25JbmZvLnN1YnNjcmlwdGlvbjtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBzdWJzY3JpcHRpb24uY2xhc3NOYW1lO1xuICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIHJlcXVlc3RJZCk7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmhhc2gpO1xuICAgIH1cbiAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoY2xhc3NOYW1lKTtcbiAgICB9XG4gICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICBjbGllbnQsXG4gICAgICBldmVudDogJ3Vuc3Vic2NyaWJlJyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICBzZXNzaW9uVG9rZW46IHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcblxuICAgIGlmICghbm90aWZ5Q2xpZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2xpZW50LnB1c2hVbnN1YnNjcmliZShyZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgIGBEZWxldGUgY2xpZW50OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfSB8IHN1YnNjcmlwdGlvbjogJHtyZXF1ZXN0LnJlcXVlc3RJZH1gXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9O1xuIl19
|
|
823
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJQYXJzZUxpdmVRdWVyeVNlcnZlciIsImNvbnN0cnVjdG9yIiwic2VydmVyIiwiY29uZmlnIiwicGFyc2VTZXJ2ZXJDb25maWciLCJjbGllbnRzIiwiTWFwIiwic3Vic2NyaXB0aW9ucyIsImFwcElkIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwibWFzdGVyS2V5Iiwia2V5UGFpcnMiLCJrZXkiLCJPYmplY3QiLCJrZXlzIiwic2V0IiwibG9nZ2VyIiwidmVyYm9zZSIsImRpc2FibGVTaW5nbGVJbnN0YW5jZSIsInNlcnZlclVSTCIsImluaXRpYWxpemUiLCJqYXZhU2NyaXB0S2V5IiwiY2FjaGVDb250cm9sbGVyIiwiZ2V0Q2FjaGVDb250cm9sbGVyIiwiY2FjaGVUaW1lb3V0IiwiYXV0aENhY2hlIiwiTFJVIiwibWF4IiwidHRsIiwicGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJQYXJzZVdlYlNvY2tldFNlcnZlciIsInBhcnNlV2Vic29ja2V0IiwiX29uQ29ubmVjdCIsInN1YnNjcmliZXIiLCJQYXJzZVB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiLCJjb25uZWN0IiwiaXNPcGVuIiwiUHJvbWlzZSIsInJlc29sdmUiLCJfY3JlYXRlU3Vic2NyaWJlcnMiLCJtZXNzYWdlUmVjaWV2ZWQiLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfY2xlYXJDYWNoZWRSb2xlcyIsInVzZXJJZCIsIl9pbmZsYXRlUGFyc2VPYmplY3QiLCJfb25BZnRlclNhdmUiLCJfb25BZnRlckRlbGV0ZSIsIm9uIiwiZmllbGQiLCJzdWJzY3JpYmUiLCJjdXJyZW50UGFyc2VPYmplY3QiLCJVc2VyUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsImNsYXNzTmFtZSIsInBhcnNlT2JqZWN0IiwiX2ZpbmlzaEZldGNoIiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImRlbGV0ZWRQYXJzZU9iamVjdCIsInRvSlNPTiIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlkIiwic2l6ZSIsImNsYXNzU3Vic2NyaXB0aW9ucyIsImdldCIsImRlYnVnIiwic3Vic2NyaXB0aW9uIiwidmFsdWVzIiwiaXNTdWJzY3JpcHRpb25NYXRjaGVkIiwiX21hdGNoZXNTdWJzY3JpcHRpb24iLCJjbGllbnRJZCIsInJlcXVlc3RJZHMiLCJfIiwiZW50cmllcyIsImNsaWVudFJlcXVlc3RJZHMiLCJjbGllbnQiLCJmb3JFYWNoIiwicmVxdWVzdElkIiwiYWNsIiwiZ2V0QUNMIiwib3AiLCJfZ2V0Q0xQT3BlcmF0aW9uIiwicXVlcnkiLCJyZXMiLCJfbWF0Y2hlc0NMUCIsImlzTWF0Y2hlZCIsIl9tYXRjaGVzQUNMIiwiZXZlbnQiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3QiLCJ1c2VNYXN0ZXJLZXkiLCJoYXNNYXN0ZXJLZXkiLCJpbnN0YWxsYXRpb25JZCIsInNlbmRFdmVudCIsInRyaWdnZXIiLCJnZXRUcmlnZ2VyIiwiYXV0aCIsImdldEF1dGhGcm9tQ2xpZW50IiwidXNlciIsImZyb21KU09OIiwicnVuVHJpZ2dlciIsInRvSlNPTndpdGhPYmplY3RzIiwiX2ZpbHRlclNlbnNpdGl2ZURhdGEiLCJwdXNoRGVsZXRlIiwicmVzb2x2ZUVycm9yIiwiQ2xpZW50IiwicHVzaEVycm9yIiwicGFyc2VXZWJTb2NrZXQiLCJjb2RlIiwic3RyaW5naWZ5IiwiaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQiLCJpc0N1cnJlbnRTdWJzY3JpcHRpb25NYXRjaGVkIiwib3JpZ2luYWxBQ0xDaGVja2luZ1Byb21pc2UiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiYWxsIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJyZXF1ZXN0IiwidHY0IiwidmFsaWRhdGUiLCJSZXF1ZXN0U2NoZW1hIiwiX2hhbmRsZUNvbm5lY3QiLCJfaGFuZGxlU3Vic2NyaWJlIiwiX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbiIsIl9oYW5kbGVVbnN1YnNjcmliZSIsImluZm8iLCJoYXMiLCJydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzIiwiZGVsZXRlIiwic3Vic2NyaXB0aW9uSW5mbyIsInN1YnNjcmlwdGlvbkluZm9zIiwiZGVsZXRlQ2xpZW50U3Vic2NyaXB0aW9uIiwiaGFzU3Vic2NyaWJpbmdDbGllbnQiLCJtYXRjaGVzUXVlcnkiLCJ2YWxpZFRva2VucyIsIlF1ZXJ5IiwiU2Vzc2lvbiIsImVxdWFsVG8iLCJVc2VyIiwiY3JlYXRlV2l0aG91dERhdGEiLCJmaW5kIiwibWFwIiwidG9rZW4iLCJhdXRoUHJvbWlzZSIsImF1dGgxIiwiYXV0aDIiLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwiY2xlYXJSb2xlQ2FjaGUiLCJkZWwiLCJmcm9tQ2FjaGUiLCJ0aGVuIiwiY2F0Y2giLCJyZXN1bHQiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsImdldFN1YnNjcmlwdGlvbkluZm8iLCJhY2xHcm91cCIsInB1c2giLCJTY2hlbWFDb250cm9sbGVyIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiY2xpZW50QXV0aCIsImZpbHRlciIsIm9iaiIsInByb3RlY3RlZEZpZWxkcyIsIkFycmF5IiwiaXNBcnJheSIsImdldERhdGFiYXNlQ29udHJvbGxlciIsImFkZFByb3RlY3RlZEZpZWxkcyIsIkRhdGFiYXNlQ29udHJvbGxlciIsImZpbHRlclNlbnNpdGl2ZURhdGEiLCJsZW5ndGgiLCJvYmplY3RJZCIsIl92ZXJpZnlBQ0wiLCJpc1N1YnNjcmlwdGlvblNlc3Npb25Ub2tlbk1hdGNoZWQiLCJnZXRSZWFkQWNjZXNzIiwiYWNsX2hhc19yb2xlcyIsInBlcm1pc3Npb25zQnlJZCIsInNvbWUiLCJzdGFydHNXaXRoIiwicm9sZU5hbWVzIiwiZ2V0VXNlclJvbGVzIiwicm9sZSIsImdldFNlc3Npb25Gcm9tQ2xpZW50IiwiZ2V0UHVibGljUmVhZEFjY2VzcyIsInN1YnNjcmlwdGlvblRva2VuIiwiY2xpZW50U2Vzc2lvblRva2VuIiwiX3ZhbGlkYXRlS2V5cyIsIl9oYXNNYXN0ZXJLZXkiLCJ1dWlkdjQiLCJyZXEiLCJwdXNoQ29ubmVjdCIsInZhbGlkS2V5UGFpcnMiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpc1ZhbGlkIiwic2VjcmV0IiwiYXV0aENhbGxlZCIsInBhcnNlUXVlcnkiLCJ3aXRoSlNPTiIsImZpZWxkcyIsInNwbGl0Iiwid2hlcmUiLCJ0b1BvaW50ZXIiLCJtYXN0ZXIiLCJzdWJzY3JpcHRpb25IYXNoIiwicXVlcnlIYXNoIiwiU3Vic2NyaXB0aW9uIiwiYWRkU3Vic2NyaXB0aW9uSW5mbyIsImFkZENsaWVudFN1YnNjcmlwdGlvbiIsInB1c2hTdWJzY3JpYmUiLCJub3RpZnlDbGllbnQiLCJkZWxldGVTdWJzY3JpcHRpb25JbmZvIiwicHVzaFVuc3Vic2NyaWJlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL0xpdmVRdWVyeS9QYXJzZUxpdmVRdWVyeVNlcnZlci5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHY0IGZyb20gJ3R2NCc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5pbXBvcnQgeyBDbGllbnQgfSBmcm9tICcuL0NsaWVudCc7XG5pbXBvcnQgeyBQYXJzZVdlYlNvY2tldFNlcnZlciB9IGZyb20gJy4vUGFyc2VXZWJTb2NrZXRTZXJ2ZXInO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IFJlcXVlc3RTY2hlbWEgZnJvbSAnLi9SZXF1ZXN0U2NoZW1hJztcbmltcG9ydCB7IG1hdGNoZXNRdWVyeSwgcXVlcnlIYXNoIH0gZnJvbSAnLi9RdWVyeVRvb2xzJztcbmltcG9ydCB7IFBhcnNlUHViU3ViIH0gZnJvbSAnLi9QYXJzZVB1YlN1Yic7XG5pbXBvcnQgU2NoZW1hQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7XG4gIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMsXG4gIGdldFRyaWdnZXIsXG4gIHJ1blRyaWdnZXIsXG4gIHJlc29sdmVFcnJvcixcbiAgdG9KU09Od2l0aE9iamVjdHMsXG59IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCB7IGdldEF1dGhGb3JTZXNzaW9uVG9rZW4sIEF1dGggfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IGdldENhY2hlQ29udHJvbGxlciwgZ2V0RGF0YWJhc2VDb250cm9sbGVyIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMnO1xuaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IFVzZXJSb3V0ZXIgZnJvbSAnLi4vUm91dGVycy9Vc2Vyc1JvdXRlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIHtcbiAgY2xpZW50czogTWFwO1xuICAvLyBjbGFzc05hbWUgLT4gKHF1ZXJ5SGFzaCAtPiBzdWJzY3JpcHRpb24pXG4gIHN1YnNjcmlwdGlvbnM6IE9iamVjdDtcbiAgcGFyc2VXZWJTb2NrZXRTZXJ2ZXI6IE9iamVjdDtcbiAga2V5UGFpcnM6IGFueTtcbiAgLy8gVGhlIHN1YnNjcmliZXIgd2UgdXNlIHRvIGdldCBvYmplY3QgdXBkYXRlIGZyb20gcHVibGlzaGVyXG4gIHN1YnNjcmliZXI6IE9iamVjdDtcblxuICBjb25zdHJ1Y3RvcihzZXJ2ZXI6IGFueSwgY29uZmlnOiBhbnkgPSB7fSwgcGFyc2VTZXJ2ZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcblxuICAgIGNvbmZpZy5hcHBJZCA9IGNvbmZpZy5hcHBJZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICAgIGNvbmZpZy5tYXN0ZXJLZXkgPSBjb25maWcubWFzdGVyS2V5IHx8IFBhcnNlLm1hc3RlcktleTtcblxuICAgIC8vIFN0b3JlIGtleXMsIGNvbnZlcnQgb2JqIHRvIG1hcFxuICAgIGNvbnN0IGtleVBhaXJzID0gY29uZmlnLmtleVBhaXJzIHx8IHt9O1xuICAgIHRoaXMua2V5UGFpcnMgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoa2V5UGFpcnMpKSB7XG4gICAgICB0aGlzLmtleVBhaXJzLnNldChrZXksIGtleVBhaXJzW2tleV0pO1xuICAgIH1cbiAgICBsb2dnZXIudmVyYm9zZSgnU3VwcG9ydCBrZXkgcGFpcnMnLCB0aGlzLmtleVBhaXJzKTtcblxuICAgIC8vIEluaXRpYWxpemUgUGFyc2VcbiAgICBQYXJzZS5PYmplY3QuZGlzYWJsZVNpbmdsZUluc3RhbmNlKCk7XG4gICAgY29uc3Qgc2VydmVyVVJMID0gY29uZmlnLnNlcnZlclVSTCB8fCBQYXJzZS5zZXJ2ZXJVUkw7XG4gICAgUGFyc2Uuc2VydmVyVVJMID0gc2VydmVyVVJMO1xuICAgIFBhcnNlLmluaXRpYWxpemUoY29uZmlnLmFwcElkLCBQYXJzZS5qYXZhU2NyaXB0S2V5LCBjb25maWcubWFzdGVyS2V5KTtcblxuICAgIC8vIFRoZSBjYWNoZSBjb250cm9sbGVyIGlzIGEgcHJvcGVyIGNhY2hlIGNvbnRyb2xsZXJcbiAgICAvLyB3aXRoIGFjY2VzcyB0byBVc2VyIGFuZCBSb2xlc1xuICAgIHRoaXMuY2FjaGVDb250cm9sbGVyID0gZ2V0Q2FjaGVDb250cm9sbGVyKHBhcnNlU2VydmVyQ29uZmlnKTtcblxuICAgIGNvbmZpZy5jYWNoZVRpbWVvdXQgPSBjb25maWcuY2FjaGVUaW1lb3V0IHx8IDUgKiAxMDAwOyAvLyA1c1xuXG4gICAgLy8gVGhpcyBhdXRoIGNhY2hlIHN0b3JlcyB0aGUgcHJvbWlzZXMgZm9yIGVhY2ggYXV0aCByZXNvbHV0aW9uLlxuICAgIC8vIFRoZSBtYWluIGJlbmVmaXQgaXMgdG8gYmUgYWJsZSB0byByZXVzZSB0aGUgc2FtZSB1c2VyIC8gc2Vzc2lvbiB0b2tlbiByZXNvbHV0aW9uLlxuICAgIHRoaXMuYXV0aENhY2hlID0gbmV3IExSVSh7XG4gICAgICBtYXg6IDUwMCwgLy8gNTAwIGNvbmN1cnJlbnRcbiAgICAgIHR0bDogY29uZmlnLmNhY2hlVGltZW91dCxcbiAgICB9KTtcbiAgICAvLyBJbml0aWFsaXplIHdlYnNvY2tldCBzZXJ2ZXJcbiAgICB0aGlzLnBhcnNlV2ViU29ja2V0U2VydmVyID0gbmV3IFBhcnNlV2ViU29ja2V0U2VydmVyKFxuICAgICAgc2VydmVyLFxuICAgICAgcGFyc2VXZWJzb2NrZXQgPT4gdGhpcy5fb25Db25uZWN0KHBhcnNlV2Vic29ja2V0KSxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICAgIGlmICghdGhpcy5zdWJzY3JpYmVyLmNvbm5lY3QpIHtcbiAgICAgIHRoaXMuY29ubmVjdCgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuc3Vic2NyaWJlci5pc09wZW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLnN1YnNjcmliZXIuY29ubmVjdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHRoaXMuc3Vic2NyaWJlci5jb25uZWN0KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN1YnNjcmliZXIuaXNPcGVuID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5fY3JlYXRlU3Vic2NyaWJlcnMoKTtcbiAgfVxuICBfY3JlYXRlU3Vic2NyaWJlcnMoKSB7XG4gICAgY29uc3QgbWVzc2FnZVJlY2lldmVkID0gKGNoYW5uZWwsIG1lc3NhZ2VTdHIpID0+IHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdTdWJzY3JpYmUgbWVzc2FnZSAlaicsIG1lc3NhZ2VTdHIpO1xuICAgICAgbGV0IG1lc3NhZ2U7XG4gICAgICB0cnkge1xuICAgICAgICBtZXNzYWdlID0gSlNPTi5wYXJzZShtZXNzYWdlU3RyKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCd1bmFibGUgdG8gcGFyc2UgbWVzc2FnZScsIG1lc3NhZ2VTdHIsIGUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoY2hhbm5lbCA9PT0gUGFyc2UuYXBwbGljYXRpb25JZCArICdjbGVhckNhY2hlJykge1xuICAgICAgICB0aGlzLl9jbGVhckNhY2hlZFJvbGVzKG1lc3NhZ2UudXNlcklkKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5faW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2UpO1xuICAgICAgaWYgKGNoYW5uZWwgPT09IFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJykge1xuICAgICAgICB0aGlzLl9vbkFmdGVyU2F2ZShtZXNzYWdlKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbCA9PT0gUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZScpIHtcbiAgICAgICAgdGhpcy5fb25BZnRlckRlbGV0ZShtZXNzYWdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignR2V0IG1lc3NhZ2UgJXMgZnJvbSB1bmtub3duIGNoYW5uZWwgJWonLCBtZXNzYWdlLCBjaGFubmVsKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRoaXMuc3Vic2NyaWJlci5vbignbWVzc2FnZScsIChjaGFubmVsLCBtZXNzYWdlU3RyKSA9PiBtZXNzYWdlUmVjaWV2ZWQoY2hhbm5lbCwgbWVzc2FnZVN0cikpO1xuICAgIGZvciAoY29uc3QgZmllbGQgb2YgWydhZnRlclNhdmUnLCAnYWZ0ZXJEZWxldGUnLCAnY2xlYXJDYWNoZSddKSB7XG4gICAgICBjb25zdCBjaGFubmVsID0gYCR7UGFyc2UuYXBwbGljYXRpb25JZH0ke2ZpZWxkfWA7XG4gICAgICB0aGlzLnN1YnNjcmliZXIuc3Vic2NyaWJlKGNoYW5uZWwsIG1lc3NhZ2VTdHIgPT4gbWVzc2FnZVJlY2lldmVkKGNoYW5uZWwsIG1lc3NhZ2VTdHIpKTtcbiAgICB9XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlci4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IEpTT04gYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdCBKU09OLlxuICBfaW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIC8vIEluZmxhdGUgbWVyZ2VkIG9iamVjdFxuICAgIGNvbnN0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0O1xuICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhjdXJyZW50UGFyc2VPYmplY3QpO1xuICAgIGxldCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxldCBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2goY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIC8vIEluZmxhdGUgb3JpZ2luYWwgb2JqZWN0XG4gICAgY29uc3Qgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgVXNlclJvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgY2xhc3NOYW1lID0gb3JpZ2luYWxQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgICBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICAgIHBhcnNlT2JqZWN0Ll9maW5pc2hGZXRjaChvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgYXN5bmMgX29uQWZ0ZXJEZWxldGUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBkZWxldGVkUGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZWxldGVkUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVqIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBkZWxldGVkUGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHN1YnNjcmlwdGlvbiBvZiBjbGFzc1N1YnNjcmlwdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzU3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oZGVsZXRlZFBhcnNlT2JqZWN0LCBzdWJzY3JpcHRpb24pO1xuICAgICAgaWYgKCFpc1N1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IFtjbGllbnRJZCwgcmVxdWVzdElkc10gb2YgXy5lbnRyaWVzKHN1YnNjcmlwdGlvbi5jbGllbnRSZXF1ZXN0SWRzKSkge1xuICAgICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KGNsaWVudElkKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGllbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmVxdWVzdElkcy5mb3JFYWNoKGFzeW5jIHJlcXVlc3RJZCA9PiB7XG4gICAgICAgICAgY29uc3QgYWNsID0gbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QuZ2V0QUNMKCk7XG4gICAgICAgICAgLy8gQ2hlY2sgQ0xQXG4gICAgICAgICAgY29uc3Qgb3AgPSB0aGlzLl9nZXRDTFBPcGVyYXRpb24oc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgICAgICAgICBsZXQgcmVzID0ge307XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX21hdGNoZXNDTFAoXG4gICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgIGNsaWVudCxcbiAgICAgICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgICAgICBvcFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnN0IGlzTWF0Y2hlZCA9IGF3YWl0IHRoaXMuX21hdGNoZXNBQ0woYWNsLCBjbGllbnQsIHJlcXVlc3RJZCk7XG4gICAgICAgICAgICBpZiAoIWlzTWF0Y2hlZCkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcyA9IHtcbiAgICAgICAgICAgICAgZXZlbnQ6ICdkZWxldGUnLFxuICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgIG9iamVjdDogZGVsZXRlZFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgc2VuZEV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgJ2FmdGVyRXZlbnQnLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgICAgICAgICAgIGlmICh0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGF1dGggPSBhd2FpdCB0aGlzLmdldEF1dGhGcm9tQ2xpZW50KGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICAgICAgaWYgKGF1dGggJiYgYXV0aC51c2VyKSB7XG4gICAgICAgICAgICAgICAgcmVzLnVzZXIgPSBhdXRoLnVzZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHJlcy5vYmplY3QpIHtcbiAgICAgICAgICAgICAgICByZXMub2JqZWN0ID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKHJlcy5vYmplY3QpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGF3YWl0IHJ1blRyaWdnZXIodHJpZ2dlciwgYGFmdGVyRXZlbnQuJHtjbGFzc05hbWV9YCwgcmVzLCBhdXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgZGVsZXRlZFBhcnNlT2JqZWN0ID0gdG9KU09Od2l0aE9iamVjdHMocmVzLm9iamVjdCwgcmVzLm9iamVjdC5jbGFzc05hbWUgfHwgY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2ZpbHRlclNlbnNpdGl2ZURhdGEoXG4gICAgICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICAgICAgcmVzLFxuICAgICAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5xdWVyeVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNsaWVudC5wdXNoRGVsZXRlKHJlcXVlc3RJZCwgZGVsZXRlZFBhcnNlT2JqZWN0KTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IHJlc29sdmVFcnJvcihlKTtcbiAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoY2xpZW50LnBhcnNlV2ViU29ja2V0LCBlcnJvci5jb2RlLCBlcnJvci5tZXNzYWdlLCBmYWxzZSwgcmVxdWVzdElkKTtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgYEZhaWxlZCBydW5uaW5nIGFmdGVyTGl2ZVF1ZXJ5RXZlbnQgb24gY2xhc3MgJHtjbGFzc05hbWV9IGZvciBldmVudCAke3Jlcy5ldmVudH0gd2l0aCBzZXNzaW9uICR7cmVzLnNlc3Npb25Ub2tlbn0gd2l0aDpcXG4gRXJyb3I6IGAgK1xuICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgYXN5bmMgX29uQWZ0ZXJTYXZlKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIGxvZ2dlci52ZXJib3NlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlIGlzIHRyaWdnZXJlZCcpO1xuXG4gICAgbGV0IG9yaWdpbmFsUGFyc2VPYmplY3QgPSBudWxsO1xuICAgIGlmIChtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QgPSBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QudG9KU09OKCk7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyA9IG1lc3NhZ2UuY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICAgIGxldCBjdXJyZW50UGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVzIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBjdXJyZW50UGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc09yaWdpbmFsU3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oXG4gICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgIHN1YnNjcmlwdGlvblxuICAgICAgKTtcbiAgICAgIGNvbnN0IGlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKFxuICAgICAgICBjdXJyZW50UGFyc2VPYmplY3QsXG4gICAgICAgIHN1YnNjcmlwdGlvblxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgW2NsaWVudElkLCByZXF1ZXN0SWRzXSBvZiBfLmVudHJpZXMoc3Vic2NyaXB0aW9uLmNsaWVudFJlcXVlc3RJZHMpKSB7XG4gICAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50cy5nZXQoY2xpZW50SWQpO1xuICAgICAgICBpZiAodHlwZW9mIGNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0SWRzLmZvckVhY2goYXN5bmMgcmVxdWVzdElkID0+IHtcbiAgICAgICAgICAvLyBTZXQgb3JpZ25hbCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGlmICghaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG9yaWdpbmFsQUNMO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChvcmlnaW5hbEFDTCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTZXQgY3VycmVudCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2U7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIGlmICghaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCkge1xuICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBQ0wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSB0aGlzLl9tYXRjaGVzQUNMKGN1cnJlbnRBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IG9wID0gdGhpcy5fZ2V0Q0xQT3BlcmF0aW9uKHN1YnNjcmlwdGlvbi5xdWVyeSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9tYXRjaGVzQ0xQKFxuICAgICAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgICAgIHJlcXVlc3RJZCxcbiAgICAgICAgICAgICAgb3BcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBbaXNPcmlnaW5hbE1hdGNoZWQsIGlzQ3VycmVudE1hdGNoZWRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSxcbiAgICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSxcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgICAgICAgICdPcmlnaW5hbCAlaiB8IEN1cnJlbnQgJWogfCBNYXRjaDogJXMsICVzLCAlcywgJXMgfCBRdWVyeTogJXMnLFxuICAgICAgICAgICAgICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBjdXJyZW50UGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgIGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICBpc0N1cnJlbnRTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICBpc09yaWdpbmFsTWF0Y2hlZCxcbiAgICAgICAgICAgICAgaXNDdXJyZW50TWF0Y2hlZCxcbiAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLmhhc2hcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICAvLyBEZWNpZGUgZXZlbnQgdHlwZVxuICAgICAgICAgICAgbGV0IHR5cGU7XG4gICAgICAgICAgICBpZiAoaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICB0eXBlID0gJ3VwZGF0ZSc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmICFpc0N1cnJlbnRNYXRjaGVkKSB7XG4gICAgICAgICAgICAgIHR5cGUgPSAnbGVhdmUnO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICAgIHR5cGUgPSAnZW50ZXInO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHR5cGUgPSAnY3JlYXRlJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMgPSB7XG4gICAgICAgICAgICAgIGV2ZW50OiB0eXBlLFxuICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgIG9iamVjdDogY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICBvcmlnaW5hbDogb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgIHNlbmRFdmVudDogdHJ1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsICdhZnRlckV2ZW50JywgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgICAgICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICAgICAgICBpZiAocmVzLm9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJlcy5vYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVzLm9iamVjdCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCkge1xuICAgICAgICAgICAgICAgIHJlcy5vcmlnaW5hbCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihyZXMub3JpZ2luYWwpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNvbnN0IGF1dGggPSBhd2FpdCB0aGlzLmdldEF1dGhGcm9tQ2xpZW50KGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICAgICAgaWYgKGF1dGggJiYgYXV0aC51c2VyKSB7XG4gICAgICAgICAgICAgICAgcmVzLnVzZXIgPSBhdXRoLnVzZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYXdhaXQgcnVuVHJpZ2dlcih0cmlnZ2VyLCBgYWZ0ZXJFdmVudC4ke2NsYXNzTmFtZX1gLCByZXMsIGF1dGgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFyZXMuc2VuZEV2ZW50KSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXMub2JqZWN0ICYmIHR5cGVvZiByZXMub2JqZWN0LnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBjdXJyZW50UGFyc2VPYmplY3QgPSB0b0pTT053aXRoT2JqZWN0cyhyZXMub2JqZWN0LCByZXMub2JqZWN0LmNsYXNzTmFtZSB8fCBjbGFzc05hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCAmJiB0eXBlb2YgcmVzLm9yaWdpbmFsLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBvcmlnaW5hbFBhcnNlT2JqZWN0ID0gdG9KU09Od2l0aE9iamVjdHMoXG4gICAgICAgICAgICAgICAgcmVzLm9yaWdpbmFsLFxuICAgICAgICAgICAgICAgIHJlcy5vcmlnaW5hbC5jbGFzc05hbWUgfHwgY2xhc3NOYW1lXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9maWx0ZXJTZW5zaXRpdmVEYXRhKFxuICAgICAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgICAgIHJlcyxcbiAgICAgICAgICAgICAgY2xpZW50LFxuICAgICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgICAgIG9wLFxuICAgICAgICAgICAgICBzdWJzY3JpcHRpb24ucXVlcnlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSAncHVzaCcgKyByZXMuZXZlbnQuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyByZXMuZXZlbnQuc2xpY2UoMSk7XG4gICAgICAgICAgICBpZiAoY2xpZW50W2Z1bmN0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgY2xpZW50W2Z1bmN0aW9uTmFtZV0ocmVxdWVzdElkLCBjdXJyZW50UGFyc2VPYmplY3QsIG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGUpO1xuICAgICAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihjbGllbnQucGFyc2VXZWJTb2NrZXQsIGVycm9yLmNvZGUsIGVycm9yLm1lc3NhZ2UsIGZhbHNlLCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX29uQ29ubmVjdChwYXJzZVdlYnNvY2tldDogYW55KTogdm9pZCB7XG4gICAgcGFyc2VXZWJzb2NrZXQub24oJ21lc3NhZ2UnLCByZXF1ZXN0ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXF1ZXN0ID0gSlNPTi5wYXJzZShyZXF1ZXN0KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcigndW5hYmxlIHRvIHBhcnNlIHJlcXVlc3QnLCByZXF1ZXN0LCBlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxvZ2dlci52ZXJib3NlKCdSZXF1ZXN0OiAlaicsIHJlcXVlc3QpO1xuXG4gICAgICAvLyBDaGVjayB3aGV0aGVyIHRoaXMgcmVxdWVzdCBpcyBhIHZhbGlkIHJlcXVlc3QsIHJldHVybiBlcnJvciBkaXJlY3RseSBpZiBub3RcbiAgICAgIGlmIChcbiAgICAgICAgIXR2NC52YWxpZGF0ZShyZXF1ZXN0LCBSZXF1ZXN0U2NoZW1hWydnZW5lcmFsJ10pIHx8XG4gICAgICAgICF0djQudmFsaWRhdGUocmVxdWVzdCwgUmVxdWVzdFNjaGVtYVtyZXF1ZXN0Lm9wXSlcbiAgICAgICkge1xuICAgICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCAxLCB0djQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgIGxvZ2dlci5lcnJvcignQ29ubmVjdCBtZXNzYWdlIGVycm9yICVzJywgdHY0LmVycm9yLm1lc3NhZ2UpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAocmVxdWVzdC5vcCkge1xuICAgICAgICBjYXNlICdjb25uZWN0JzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVDb25uZWN0KHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnc3Vic2NyaWJlJzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1cGRhdGUnOlxuICAgICAgICAgIHRoaXMuX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3Vuc3Vic2NyaWJlJzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVVbnN1YnNjcmliZShwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgMywgJ0dldCB1bmtub3duIG9wZXJhdGlvbicpO1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignR2V0IHVua25vd24gb3BlcmF0aW9uJywgcmVxdWVzdC5vcCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBwYXJzZVdlYnNvY2tldC5vbignZGlzY29ubmVjdCcsICgpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGBDbGllbnQgZGlzY29ubmVjdDogJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH1gKTtcbiAgICAgIGNvbnN0IGNsaWVudElkID0gcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQ7XG4gICAgICBpZiAoIXRoaXMuY2xpZW50cy5oYXMoY2xpZW50SWQpKSB7XG4gICAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICAgIGV2ZW50OiAnd3NfZGlzY29ubmVjdF9lcnJvcicsXG4gICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgZXJyb3I6IGBVbmFibGUgdG8gZmluZCBjbGllbnQgJHtjbGllbnRJZH1gLFxuICAgICAgICB9KTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBDYW4gbm90IGZpbmQgY2xpZW50ICR7Y2xpZW50SWR9IG9uIGRpc2Nvbm5lY3RgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBEZWxldGUgY2xpZW50XG4gICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KGNsaWVudElkKTtcbiAgICAgIHRoaXMuY2xpZW50cy5kZWxldGUoY2xpZW50SWQpO1xuXG4gICAgICAvLyBEZWxldGUgY2xpZW50IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgICAgZm9yIChjb25zdCBbcmVxdWVzdElkLCBzdWJzY3JpcHRpb25JbmZvXSBvZiBfLmVudHJpZXMoY2xpZW50LnN1YnNjcmlwdGlvbkluZm9zKSkge1xuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBzdWJzY3JpcHRpb25JbmZvLnN1YnNjcmlwdGlvbjtcbiAgICAgICAgc3Vic2NyaXB0aW9uLmRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihjbGllbnRJZCwgcmVxdWVzdElkKTtcblxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBjbGllbnQgd2hpY2ggaXMgc3Vic2NyaWJpbmcgdGhpcyBzdWJzY3JpcHRpb24sIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChzdWJzY3JpcHRpb24uY2xhc3NOYW1lKTtcbiAgICAgICAgaWYgKCFzdWJzY3JpcHRpb24uaGFzU3Vic2NyaWJpbmdDbGllbnQoKSkge1xuICAgICAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmhhc2gpO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcywgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgICAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLnNpemUgPT09IDApIHtcbiAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZGVsZXRlKHN1YnNjcmlwdGlvbi5jbGFzc05hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudHMgJWQnLCB0aGlzLmNsaWVudHMuc2l6ZSk7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBzdWJzY3JpcHRpb25zICVkJywgdGhpcy5zdWJzY3JpcHRpb25zLnNpemUpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgIGV2ZW50OiAnd3NfZGlzY29ubmVjdCcsXG4gICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgZXZlbnQ6ICd3c19jb25uZWN0JyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgfSk7XG4gIH1cblxuICBfbWF0Y2hlc1N1YnNjcmlwdGlvbihwYXJzZU9iamVjdDogYW55LCBzdWJzY3JpcHRpb246IGFueSk6IGJvb2xlYW4ge1xuICAgIC8vIE9iamVjdCBpcyB1bmRlZmluZWQgb3IgbnVsbCwgbm90IG1hdGNoXG4gICAgaWYgKCFwYXJzZU9iamVjdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hlc1F1ZXJ5KHBhcnNlT2JqZWN0LCBzdWJzY3JpcHRpb24ucXVlcnkpO1xuICB9XG5cbiAgYXN5bmMgX2NsZWFyQ2FjaGVkUm9sZXModXNlcklkOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdmFsaWRUb2tlbnMgPSBhd2FpdCBuZXcgUGFyc2UuUXVlcnkoUGFyc2UuU2Vzc2lvbilcbiAgICAgICAgLmVxdWFsVG8oJ3VzZXInLCBQYXJzZS5Vc2VyLmNyZWF0ZVdpdGhvdXREYXRhKHVzZXJJZCkpXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHZhbGlkVG9rZW5zLm1hcChhc3luYyB0b2tlbiA9PiB7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblRva2VuID0gdG9rZW4uZ2V0KCdzZXNzaW9uVG9rZW4nKTtcbiAgICAgICAgICBjb25zdCBhdXRoUHJvbWlzZSA9IHRoaXMuYXV0aENhY2hlLmdldChzZXNzaW9uVG9rZW4pO1xuICAgICAgICAgIGlmICghYXV0aFByb21pc2UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgW2F1dGgxLCBhdXRoMl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICBhdXRoUHJvbWlzZSxcbiAgICAgICAgICAgIGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oeyBjYWNoZUNvbnRyb2xsZXI6IHRoaXMuY2FjaGVDb250cm9sbGVyLCBzZXNzaW9uVG9rZW4gfSksXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgYXV0aDEuYXV0aD8uY2xlYXJSb2xlQ2FjaGUoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICBhdXRoMi5hdXRoPy5jbGVhclJvbGVDYWNoZShzZXNzaW9uVG9rZW4pO1xuICAgICAgICAgIHRoaXMuYXV0aENhY2hlLmRlbChzZXNzaW9uVG9rZW4pO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZShgQ291bGQgbm90IGNsZWFyIHJvbGUgY2FjaGUuICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuKHNlc3Npb25Ub2tlbjogP3N0cmluZyk6IFByb21pc2U8eyBhdXRoOiA/QXV0aCwgdXNlcklkOiA/c3RyaW5nIH0+IHtcbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfVxuICAgIGNvbnN0IGZyb21DYWNoZSA9IHRoaXMuYXV0aENhY2hlLmdldChzZXNzaW9uVG9rZW4pO1xuICAgIGlmIChmcm9tQ2FjaGUpIHtcbiAgICAgIHJldHVybiBmcm9tQ2FjaGU7XG4gICAgfVxuICAgIGNvbnN0IGF1dGhQcm9taXNlID0gZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7XG4gICAgICBjYWNoZUNvbnRyb2xsZXI6IHRoaXMuY2FjaGVDb250cm9sbGVyLFxuICAgICAgc2Vzc2lvblRva2VuOiBzZXNzaW9uVG9rZW4sXG4gICAgfSlcbiAgICAgIC50aGVuKGF1dGggPT4ge1xuICAgICAgICByZXR1cm4geyBhdXRoLCB1c2VySWQ6IGF1dGggJiYgYXV0aC51c2VyICYmIGF1dGgudXNlci5pZCB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFRoZXJlIHdhcyBhbiBlcnJvciB3aXRoIHRoZSBzZXNzaW9uIHRva2VuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOKSB7XG4gICAgICAgICAgcmVzdWx0LmVycm9yID0gZXJyb3I7XG4gICAgICAgICAgdGhpcy5hdXRoQ2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCksIHRoaXMuY29uZmlnLmNhY2hlVGltZW91dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5hdXRoQ2FjaGUuZGVsKHNlc3Npb25Ub2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIHRoaXMuYXV0aENhY2hlLnNldChzZXNzaW9uVG9rZW4sIGF1dGhQcm9taXNlKTtcbiAgICByZXR1cm4gYXV0aFByb21pc2U7XG4gIH1cblxuICBhc3luYyBfbWF0Y2hlc0NMUChcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6ID9hbnksXG4gICAgb2JqZWN0OiBhbnksXG4gICAgY2xpZW50OiBhbnksXG4gICAgcmVxdWVzdElkOiBudW1iZXIsXG4gICAgb3A6IHN0cmluZ1xuICApOiBhbnkge1xuICAgIC8vIHRyeSB0byBtYXRjaCBvbiB1c2VyIGZpcnN0LCBsZXNzIGV4cGVuc2l2ZSB0aGFuIHdpdGggcm9sZXNcbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBjb25zdCBhY2xHcm91cCA9IFsnKiddO1xuICAgIGxldCB1c2VySWQ7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY29uc3QgeyB1c2VySWQgfSA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZvclNlc3Npb25Ub2tlbihzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbik7XG4gICAgICBpZiAodXNlcklkKSB7XG4gICAgICAgIGFjbEdyb3VwLnB1c2godXNlcklkKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKFxuICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgIG9iamVjdC5jbGFzc05hbWUsXG4gICAgICAgIGFjbEdyb3VwLFxuICAgICAgICBvcFxuICAgICAgKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBGYWlsZWQgbWF0Y2hpbmcgQ0xQIGZvciAke29iamVjdC5pZH0gJHt1c2VySWR9ICR7ZX1gKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gVE9ETzogaGFuZGxlIHJvbGVzIHBlcm1pc3Npb25zXG4gICAgLy8gT2JqZWN0LmtleXMoY2xhc3NMZXZlbFBlcm1pc3Npb25zKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAvLyAgIGNvbnN0IHBlcm0gPSBjbGFzc0xldmVsUGVybWlzc2lvbnNba2V5XTtcbiAgICAvLyAgIE9iamVjdC5rZXlzKHBlcm0pLmZvckVhY2goKGtleSkgPT4ge1xuICAgIC8vICAgICBpZiAoa2V5LmluZGV4T2YoJ3JvbGUnKSlcbiAgICAvLyAgIH0pO1xuICAgIC8vIH0pXG4gICAgLy8gLy8gaXQncyByZWplY3RlZCBoZXJlLCBjaGVjayB0aGUgcm9sZXNcbiAgICAvLyB2YXIgcm9sZXNRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShQYXJzZS5Sb2xlKTtcbiAgICAvLyByb2xlc1F1ZXJ5LmVxdWFsVG8oXCJ1c2Vyc1wiLCB1c2VyKTtcbiAgICAvLyByZXR1cm4gcm9sZXNRdWVyeS5maW5kKHt1c2VNYXN0ZXJLZXk6dHJ1ZX0pO1xuICB9XG5cbiAgYXN5bmMgX2ZpbHRlclNlbnNpdGl2ZURhdGEoXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55LFxuICAgIHJlczogYW55LFxuICAgIGNsaWVudDogYW55LFxuICAgIHJlcXVlc3RJZDogbnVtYmVyLFxuICAgIG9wOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueVxuICApIHtcbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBjb25zdCBhY2xHcm91cCA9IFsnKiddO1xuICAgIGxldCBjbGllbnRBdXRoO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGNvbnN0IHsgdXNlcklkLCBhdXRoIH0gPSBhd2FpdCB0aGlzLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4pO1xuICAgICAgaWYgKHVzZXJJZCkge1xuICAgICAgICBhY2xHcm91cC5wdXNoKHVzZXJJZCk7XG4gICAgICB9XG4gICAgICBjbGllbnRBdXRoID0gYXV0aDtcbiAgICB9XG4gICAgY29uc3QgZmlsdGVyID0gb2JqID0+IHtcbiAgICAgIGlmICghb2JqKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGxldCBwcm90ZWN0ZWRGaWVsZHMgPSBjbGFzc0xldmVsUGVybWlzc2lvbnM/LnByb3RlY3RlZEZpZWxkcyB8fCBbXTtcbiAgICAgIGlmICghY2xpZW50Lmhhc01hc3RlcktleSAmJiAhQXJyYXkuaXNBcnJheShwcm90ZWN0ZWRGaWVsZHMpKSB7XG4gICAgICAgIHByb3RlY3RlZEZpZWxkcyA9IGdldERhdGFiYXNlQ29udHJvbGxlcih0aGlzLmNvbmZpZykuYWRkUHJvdGVjdGVkRmllbGRzKFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICByZXMub2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICBhY2xHcm91cCxcbiAgICAgICAgICBjbGllbnRBdXRoXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gRGF0YWJhc2VDb250cm9sbGVyLmZpbHRlclNlbnNpdGl2ZURhdGEoXG4gICAgICAgIGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgIGFjbEdyb3VwLFxuICAgICAgICBjbGllbnRBdXRoLFxuICAgICAgICBvcCxcbiAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICByZXMub2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgcHJvdGVjdGVkRmllbGRzLFxuICAgICAgICBvYmosXG4gICAgICAgIHF1ZXJ5XG4gICAgICApO1xuICAgIH07XG4gICAgcmVzLm9iamVjdCA9IGZpbHRlcihyZXMub2JqZWN0KTtcbiAgICByZXMub3JpZ2luYWwgPSBmaWx0ZXIocmVzLm9yaWdpbmFsKTtcbiAgfVxuXG4gIF9nZXRDTFBPcGVyYXRpb24ocXVlcnk6IGFueSkge1xuICAgIHJldHVybiB0eXBlb2YgcXVlcnkgPT09ICdvYmplY3QnICYmXG4gICAgICBPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoID09IDEgJiZcbiAgICAgIHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZydcbiAgICAgID8gJ2dldCdcbiAgICAgIDogJ2ZpbmQnO1xuICB9XG5cbiAgYXN5bmMgX3ZlcmlmeUFDTChhY2w6IGFueSwgdG9rZW46IHN0cmluZykge1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGF1dGgsIHVzZXJJZCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHRva2VuKTtcblxuICAgIC8vIEdldHRpbmcgdGhlIHNlc3Npb24gdG9rZW4gZmFpbGVkXG4gICAgLy8gVGhpcyBtZWFucyB0aGF0IG5vIGFkZGl0aW9uYWwgYXV0aCBpcyBhdmFpbGFibGVcbiAgICAvLyBBdCB0aGlzIHBvaW50LCBqdXN0IGJhaWwgb3V0IGFzIG5vIGFkZGl0aW9uYWwgdmlzaWJpbGl0eSBjYW4gYmUgaW5mZXJyZWQuXG4gICAgaWYgKCFhdXRoIHx8ICF1c2VySWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkID0gYWNsLmdldFJlYWRBY2Nlc3ModXNlcklkKTtcbiAgICBpZiAoaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBoYXMgYW55IHJvbGVzIHRoYXQgbWF0Y2ggdGhlIEFDTFxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBSZXNvbHZlIGZhbHNlIHJpZ2h0IGF3YXkgaWYgdGhlIGFjbCBkb2Vzbid0IGhhdmUgYW55IHJvbGVzXG4gICAgICAgIGNvbnN0IGFjbF9oYXNfcm9sZXMgPSBPYmplY3Qua2V5cyhhY2wucGVybWlzc2lvbnNCeUlkKS5zb21lKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgncm9sZTonKSk7XG4gICAgICAgIGlmICghYWNsX2hhc19yb2xlcykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByb2xlTmFtZXMgPSBhd2FpdCBhdXRoLmdldFVzZXJSb2xlcygpO1xuICAgICAgICAvLyBGaW5hbGx5LCBzZWUgaWYgYW55IG9mIHRoZSB1c2VyJ3Mgcm9sZXMgYWxsb3cgdGhlbSByZWFkIGFjY2Vzc1xuICAgICAgICBmb3IgKGNvbnN0IHJvbGUgb2Ygcm9sZU5hbWVzKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGdldFJlYWRBY2Nlc3MgYXMgYHJvbGVgIGlzIGluIHRoZSBmb3JtIGByb2xlOnJvbGVOYW1lYFxuICAgICAgICAgIGlmIChhY2wuZ2V0UmVhZEFjY2Vzcyhyb2xlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGdldEF1dGhGcm9tQ2xpZW50KGNsaWVudDogYW55LCByZXF1ZXN0SWQ6IG51bWJlciwgc2Vzc2lvblRva2VuOiBzdHJpbmcpIHtcbiAgICBjb25zdCBnZXRTZXNzaW9uRnJvbUNsaWVudCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbkluZm8gPSBjbGllbnQuZ2V0U3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gY2xpZW50LnNlc3Npb25Ub2tlbjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbiB8fCBjbGllbnQuc2Vzc2lvblRva2VuO1xuICAgIH07XG4gICAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICAgIHNlc3Npb25Ub2tlbiA9IGdldFNlc3Npb25Gcm9tQ2xpZW50KCk7XG4gICAgfVxuICAgIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHsgYXV0aCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHNlc3Npb25Ub2tlbik7XG4gICAgcmV0dXJuIGF1dGg7XG4gIH1cblxuICBhc3luYyBfbWF0Y2hlc0FDTChhY2w6IGFueSwgY2xpZW50OiBhbnksIHJlcXVlc3RJZDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgLy8gUmV0dXJuIHRydWUgZGlyZWN0bHkgaWYgQUNMIGlzbid0IHByZXNlbnQsIEFDTCBpcyBwdWJsaWMgcmVhZCwgb3IgY2xpZW50IGhhcyBtYXN0ZXIga2V5XG4gICAgaWYgKCFhY2wgfHwgYWNsLmdldFB1YmxpY1JlYWRBY2Nlc3MoKSB8fCBjbGllbnQuaGFzTWFzdGVyS2V5KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgc3Vic2NyaXB0aW9uIHNlc3Npb25Ub2tlbiBtYXRjaGVzIEFDTCBmaXJzdFxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbkluZm8gPSBjbGllbnQuZ2V0U3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIGlmICh0eXBlb2Ygc3Vic2NyaXB0aW9uSW5mbyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBzdWJzY3JpcHRpb25Ub2tlbiA9IHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuO1xuICAgIGNvbnN0IGNsaWVudFNlc3Npb25Ub2tlbiA9IGNsaWVudC5zZXNzaW9uVG9rZW47XG5cbiAgICBpZiAoYXdhaXQgdGhpcy5fdmVyaWZ5QUNMKGFjbCwgc3Vic2NyaXB0aW9uVG9rZW4pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoYXdhaXQgdGhpcy5fdmVyaWZ5QUNMKGFjbCwgY2xpZW50U2Vzc2lvblRva2VuKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgX2hhbmRsZUNvbm5lY3QocGFyc2VXZWJzb2NrZXQ6IGFueSwgcmVxdWVzdDogYW55KTogYW55IHtcbiAgICBpZiAoIXRoaXMuX3ZhbGlkYXRlS2V5cyhyZXF1ZXN0LCB0aGlzLmtleVBhaXJzKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgNCwgJ0tleSBpbiByZXF1ZXN0IGlzIG5vdCB2YWxpZCcpO1xuICAgICAgbG9nZ2VyLmVycm9yKCdLZXkgaW4gcmVxdWVzdCBpcyBub3QgdmFsaWQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaGFzTWFzdGVyS2V5ID0gdGhpcy5faGFzTWFzdGVyS2V5KHJlcXVlc3QsIHRoaXMua2V5UGFpcnMpO1xuICAgIGNvbnN0IGNsaWVudElkID0gdXVpZHY0KCk7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChcbiAgICAgIGNsaWVudElkLFxuICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICBoYXNNYXN0ZXJLZXksXG4gICAgICByZXF1ZXN0LnNlc3Npb25Ub2tlbixcbiAgICAgIHJlcXVlc3QuaW5zdGFsbGF0aW9uSWRcbiAgICApO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXEgPSB7XG4gICAgICAgIGNsaWVudCxcbiAgICAgICAgZXZlbnQ6ICdjb25uZWN0JyxcbiAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICBzZXNzaW9uVG9rZW46IHJlcXVlc3Quc2Vzc2lvblRva2VuLFxuICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgIGluc3RhbGxhdGlvbklkOiByZXF1ZXN0Lmluc3RhbGxhdGlvbklkLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKCdAQ29ubmVjdCcsICdiZWZvcmVDb25uZWN0JywgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICBjb25zdCBhdXRoID0gYXdhaXQgdGhpcy5nZXRBdXRoRnJvbUNsaWVudChjbGllbnQsIHJlcXVlc3QucmVxdWVzdElkLCByZXEuc2Vzc2lvblRva2VuKTtcbiAgICAgICAgaWYgKGF1dGggJiYgYXV0aC51c2VyKSB7XG4gICAgICAgICAgcmVxLnVzZXIgPSBhdXRoLnVzZXI7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgcnVuVHJpZ2dlcih0cmlnZ2VyLCBgYmVmb3JlQ29ubmVjdC5AQ29ubmVjdGAsIHJlcSwgYXV0aCk7XG4gICAgICB9XG4gICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCA9IGNsaWVudElkO1xuICAgICAgdGhpcy5jbGllbnRzLnNldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgY2xpZW50KTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGUgbmV3IGNsaWVudDogJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH1gKTtcbiAgICAgIGNsaWVudC5wdXNoQ29ubmVjdCgpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyhyZXEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGUpO1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgZXJyb3IuY29kZSwgZXJyb3IubWVzc2FnZSwgZmFsc2UpO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYmVmb3JlQ29ubmVjdCBmb3Igc2Vzc2lvbiAke3JlcXVlc3Quc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIF9oYXNNYXN0ZXJLZXkocmVxdWVzdDogYW55LCB2YWxpZEtleVBhaXJzOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkS2V5UGFpcnMgfHwgdmFsaWRLZXlQYWlycy5zaXplID09IDAgfHwgIXZhbGlkS2V5UGFpcnMuaGFzKCdtYXN0ZXJLZXknKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIXJlcXVlc3QgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXF1ZXN0LCAnbWFzdGVyS2V5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcXVlc3QubWFzdGVyS2V5ID09PSB2YWxpZEtleVBhaXJzLmdldCgnbWFzdGVyS2V5Jyk7XG4gIH1cblxuICBfdmFsaWRhdGVLZXlzKHJlcXVlc3Q6IGFueSwgdmFsaWRLZXlQYWlyczogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCF2YWxpZEtleVBhaXJzIHx8IHZhbGlkS2V5UGFpcnMuc2l6ZSA9PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGlzVmFsaWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHNlY3JldF0gb2YgdmFsaWRLZXlQYWlycykge1xuICAgICAgaWYgKCFyZXF1ZXN0W2tleV0gfHwgcmVxdWVzdFtrZXldICE9PSBzZWNyZXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gaXNWYWxpZDtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQ6IGFueSwgcmVxdWVzdDogYW55KTogYW55IHtcbiAgICAvLyBJZiB3ZSBjYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIHJldHVybiBlcnJvciB0byBjbGllbnRcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXJzZVdlYnNvY2tldCwgJ2NsaWVudElkJykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSBzdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgc3Vic2NyaWJpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gcmVxdWVzdC5xdWVyeS5jbGFzc05hbWU7XG4gICAgbGV0IGF1dGhDYWxsZWQgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCAnYmVmb3JlU3Vic2NyaWJlJywgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgICBpZiAodHJpZ2dlcikge1xuICAgICAgICBjb25zdCBhdXRoID0gYXdhaXQgdGhpcy5nZXRBdXRoRnJvbUNsaWVudChjbGllbnQsIHJlcXVlc3QucmVxdWVzdElkLCByZXF1ZXN0LnNlc3Npb25Ub2tlbik7XG4gICAgICAgIGF1dGhDYWxsZWQgPSB0cnVlO1xuICAgICAgICBpZiAoYXV0aCAmJiBhdXRoLnVzZXIpIHtcbiAgICAgICAgICByZXF1ZXN0LnVzZXIgPSBhdXRoLnVzZXI7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gICAgICAgIHBhcnNlUXVlcnkud2l0aEpTT04ocmVxdWVzdC5xdWVyeSk7XG4gICAgICAgIHJlcXVlc3QucXVlcnkgPSBwYXJzZVF1ZXJ5O1xuICAgICAgICBhd2FpdCBydW5UcmlnZ2VyKHRyaWdnZXIsIGBiZWZvcmVTdWJzY3JpYmUuJHtjbGFzc05hbWV9YCwgcmVxdWVzdCwgYXV0aCk7XG5cbiAgICAgICAgY29uc3QgcXVlcnkgPSByZXF1ZXN0LnF1ZXJ5LnRvSlNPTigpO1xuICAgICAgICBpZiAocXVlcnkua2V5cykge1xuICAgICAgICAgIHF1ZXJ5LmZpZWxkcyA9IHF1ZXJ5LmtleXMuc3BsaXQoJywnKTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0LnF1ZXJ5ID0gcXVlcnk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgaWYgKCFhdXRoQ2FsbGVkKSB7XG4gICAgICAgICAgY29uc3QgYXV0aCA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZyb21DbGllbnQoXG4gICAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgICByZXF1ZXN0LnJlcXVlc3RJZCxcbiAgICAgICAgICAgIHJlcXVlc3Quc2Vzc2lvblRva2VuXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoYXV0aCAmJiBhdXRoLnVzZXIpIHtcbiAgICAgICAgICAgIHJlcXVlc3QudXNlciA9IGF1dGgudXNlcjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3QudXNlcikge1xuICAgICAgICAgIHJlcXVlc3QucXVlcnkud2hlcmUudXNlciA9IHJlcXVlc3QudXNlci50b1BvaW50ZXIoKTtcbiAgICAgICAgfSBlbHNlIGlmICghcmVxdWVzdC5tYXN0ZXIpIHtcbiAgICAgICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sXG4gICAgICAgICAgICAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgcmVxdWVzdC5yZXF1ZXN0SWRcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gR2V0IHN1YnNjcmlwdGlvbiBmcm9tIHN1YnNjcmlwdGlvbnMsIGNyZWF0ZSBvbmUgaWYgbmVjZXNzYXJ5XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25IYXNoID0gcXVlcnlIYXNoKHJlcXVlc3QucXVlcnkpO1xuICAgICAgLy8gQWRkIGNsYXNzTmFtZSB0byBzdWJzY3JpcHRpb25zIGlmIG5lY2Vzc2FyeVxuXG4gICAgICBpZiAoIXRoaXMuc3Vic2NyaXB0aW9ucy5oYXMoY2xhc3NOYW1lKSkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KGNsYXNzTmFtZSwgbmV3IE1hcCgpKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICAgIGxldCBzdWJzY3JpcHRpb247XG4gICAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLmhhcyhzdWJzY3JpcHRpb25IYXNoKSkge1xuICAgICAgICBzdWJzY3JpcHRpb24gPSBjbGFzc1N1YnNjcmlwdGlvbnMuZ2V0KHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbihjbGFzc05hbWUsIHJlcXVlc3QucXVlcnkud2hlcmUsIHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuc2V0KHN1YnNjcmlwdGlvbkhhc2gsIHN1YnNjcmlwdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBzdWJzY3JpcHRpb25JbmZvIHRvIGNsaWVudFxuICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBzdWJzY3JpcHRpb24sXG4gICAgICB9O1xuICAgICAgLy8gQWRkIHNlbGVjdGVkIGZpZWxkcywgc2Vzc2lvblRva2VuIGFuZCBpbnN0YWxsYXRpb25JZCBmb3IgdGhpcyBzdWJzY3JpcHRpb24gaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAocmVxdWVzdC5xdWVyeS5maWVsZHMpIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uSW5mby5maWVsZHMgPSByZXF1ZXN0LnF1ZXJ5LmZpZWxkcztcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0LnNlc3Npb25Ub2tlbikge1xuICAgICAgICBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbiA9IHJlcXVlc3Quc2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgY2xpZW50LmFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdC5yZXF1ZXN0SWQsIHN1YnNjcmlwdGlvbkluZm8pO1xuXG4gICAgICAvLyBBZGQgY2xpZW50SWQgdG8gc3Vic2NyaXB0aW9uXG4gICAgICBzdWJzY3JpcHRpb24uYWRkQ2xpZW50U3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0LmNsaWVudElkLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICAgIGNsaWVudC5wdXNoU3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgIGBDcmVhdGUgY2xpZW50ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IG5ldyBzdWJzY3JpcHRpb246ICR7cmVxdWVzdC5yZXF1ZXN0SWR9YFxuICAgICAgKTtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXI6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgIGNsaWVudCxcbiAgICAgICAgZXZlbnQ6ICdzdWJzY3JpYmUnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gcmVzb2x2ZUVycm9yKGUpO1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgZXJyb3IuY29kZSwgZXJyb3IubWVzc2FnZSwgZmFsc2UsIHJlcXVlc3QucmVxdWVzdElkKTtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgYEZhaWxlZCBydW5uaW5nIGJlZm9yZVN1YnNjcmliZSBvbiAke2NsYXNzTmFtZX0gZm9yIHNlc3Npb24gJHtyZXF1ZXN0LnNlc3Npb25Ub2tlbn0gd2l0aDpcXG4gRXJyb3I6IGAgK1xuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KGVycm9yKVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBfaGFuZGxlVXBkYXRlU3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSk6IGFueSB7XG4gICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QsIGZhbHNlKTtcbiAgICB0aGlzLl9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICB9XG5cbiAgX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0OiBhbnksIHJlcXVlc3Q6IGFueSwgbm90aWZ5Q2xpZW50OiBib29sZWFuID0gdHJ1ZSk6IGFueSB7XG4gICAgLy8gSWYgd2UgY2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCByZXR1cm4gZXJyb3IgdG8gY2xpZW50XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocGFyc2VXZWJzb2NrZXQsICdjbGllbnRJZCcpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0SWQgPSByZXF1ZXN0LnJlcXVlc3RJZDtcbiAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudHMuZ2V0KHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIGNsaWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2Fubm90IGZpbmQgY2xpZW50IHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBsaXZlIHF1ZXJ5IHNlcnZlciBiZWZvcmUgdW5zdWJzY3JpYmluZy4nXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQgJyArIHBhcnNlV2Vic29ja2V0LmNsaWVudElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdWJzY3JpcHRpb25JbmZvID0gY2xpZW50LmdldFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkKTtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIHN1YnNjcmlwdGlvbiB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnIHN1YnNjcmlwdGlvbklkICcgK1xuICAgICAgICAgIHJlcXVlc3RJZCArXG4gICAgICAgICAgJy4gTWFrZSBzdXJlIHlvdSBzdWJzY3JpYmUgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgJ0NhbiBub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWRcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIHN1YnNjcmlwdGlvbiBmcm9tIGNsaWVudFxuICAgIGNsaWVudC5kZWxldGVTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgLy8gUmVtb3ZlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHN1YnNjcmlwdGlvbkluZm8uc3Vic2NyaXB0aW9uO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IHN1YnNjcmlwdGlvbi5jbGFzc05hbWU7XG4gICAgc3Vic2NyaXB0aW9uLmRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBjbGllbnQgd2hpY2ggaXMgc3Vic2NyaWJpbmcgdGhpcyBzdWJzY3JpcHRpb24sIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBjb25zdCBjbGFzc1N1YnNjcmlwdGlvbnMgPSB0aGlzLnN1YnNjcmlwdGlvbnMuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKCFzdWJzY3JpcHRpb24uaGFzU3Vic2NyaWJpbmdDbGllbnQoKSkge1xuICAgICAgY2xhc3NTdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uaGFzaCk7XG4gICAgfVxuICAgIC8vIElmIHRoZXJlIGlzIG5vIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcywgcmVtb3ZlIGl0IGZyb20gc3Vic2NyaXB0aW9uc1xuICAgIGlmIChjbGFzc1N1YnNjcmlwdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShjbGFzc05hbWUpO1xuICAgIH1cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGNsaWVudCxcbiAgICAgIGV2ZW50OiAndW5zdWJzY3JpYmUnLFxuICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgIHNlc3Npb25Ub2tlbjogc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICBpbnN0YWxsYXRpb25JZDogY2xpZW50Lmluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuXG4gICAgaWYgKCFub3RpZnlDbGllbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjbGllbnQucHVzaFVuc3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYERlbGV0ZSBjbGllbnQ6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IHwgc3Vic2NyaXB0aW9uOiAke3JlcXVlc3QucmVxdWVzdElkfWBcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCB7IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyIH07XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFtRTtBQUVuRSxNQUFNQSxvQkFBb0IsQ0FBQztFQUV6Qjs7RUFJQTs7RUFHQUMsV0FBVyxDQUFDQyxNQUFXLEVBQUVDLE1BQVcsR0FBRyxDQUFDLENBQUMsRUFBRUMsaUJBQXNCLEdBQUcsQ0FBQyxDQUFDLEVBQUU7SUFDdEUsSUFBSSxDQUFDRixNQUFNLEdBQUdBLE1BQU07SUFDcEIsSUFBSSxDQUFDRyxPQUFPLEdBQUcsSUFBSUMsR0FBRyxFQUFFO0lBQ3hCLElBQUksQ0FBQ0MsYUFBYSxHQUFHLElBQUlELEdBQUcsRUFBRTtJQUM5QixJQUFJLENBQUNILE1BQU0sR0FBR0EsTUFBTTtJQUVw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
|