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
package/lib/middlewares.js
CHANGED
|
@@ -3,58 +3,49 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.addRateLimit = exports.DEFAULT_ALLOWED_HEADERS = void 0;
|
|
7
7
|
exports.allowCrossDomain = allowCrossDomain;
|
|
8
8
|
exports.allowMethodOverride = allowMethodOverride;
|
|
9
|
-
exports.handleParseErrors = handleParseErrors;
|
|
10
9
|
exports.enforceMasterKeyAccess = enforceMasterKeyAccess;
|
|
10
|
+
exports.handleParseErrors = handleParseErrors;
|
|
11
|
+
exports.handleParseHeaders = handleParseHeaders;
|
|
12
|
+
exports.handleParseSession = void 0;
|
|
11
13
|
exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess;
|
|
12
14
|
exports.promiseEnsureIdempotency = promiseEnsureIdempotency;
|
|
13
|
-
exports.DEFAULT_ALLOWED_HEADERS = void 0;
|
|
14
|
-
|
|
15
15
|
var _cache = _interopRequireDefault(require("./cache"));
|
|
16
|
-
|
|
17
16
|
var _node = _interopRequireDefault(require("parse/node"));
|
|
18
|
-
|
|
19
17
|
var _Auth = _interopRequireDefault(require("./Auth"));
|
|
20
|
-
|
|
21
18
|
var _Config = _interopRequireDefault(require("./Config"));
|
|
22
|
-
|
|
23
19
|
var _ClientSDK = _interopRequireDefault(require("./ClientSDK"));
|
|
24
|
-
|
|
25
20
|
var _logger = _interopRequireDefault(require("./logger"));
|
|
26
|
-
|
|
27
21
|
var _rest = _interopRequireDefault(require("./rest"));
|
|
28
|
-
|
|
29
22
|
var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter"));
|
|
30
|
-
|
|
31
23
|
var _PostgresStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Postgres/PostgresStorageAdapter"));
|
|
32
|
-
|
|
24
|
+
var _expressRateLimit = _interopRequireDefault(require("express-rate-limit"));
|
|
25
|
+
var _Definitions = require("./Options/Definitions");
|
|
26
|
+
var _pathToRegexp = _interopRequireDefault(require("path-to-regexp"));
|
|
27
|
+
var _ipRangeCheck = _interopRequireDefault(require("ip-range-check"));
|
|
33
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
34
|
-
|
|
35
29
|
const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control';
|
|
36
30
|
exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS;
|
|
37
|
-
|
|
38
31
|
const getMountForRequest = function (req) {
|
|
39
32
|
const mountPathLength = req.originalUrl.length - req.url.length;
|
|
40
33
|
const mountPath = req.originalUrl.slice(0, mountPathLength);
|
|
41
34
|
return req.protocol + '://' + req.get('host') + mountPath;
|
|
42
|
-
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Checks that the request is authorized for this app and checks user
|
|
43
38
|
// auth too.
|
|
44
39
|
// The bodyparser should run before this middleware.
|
|
45
40
|
// Adds info to the request:
|
|
46
41
|
// req.config - the Config for this app
|
|
47
42
|
// req.auth - the Auth for this request
|
|
48
|
-
|
|
49
|
-
|
|
50
43
|
function handleParseHeaders(req, res, next) {
|
|
51
44
|
var mount = getMountForRequest(req);
|
|
52
45
|
let context = {};
|
|
53
|
-
|
|
54
46
|
if (req.get('X-Parse-Cloud-Context') != null) {
|
|
55
47
|
try {
|
|
56
48
|
context = JSON.parse(req.get('X-Parse-Cloud-Context'));
|
|
57
|
-
|
|
58
49
|
if (Object.prototype.toString.call(context) !== '[object Object]') {
|
|
59
50
|
throw 'Context is not an object';
|
|
60
51
|
}
|
|
@@ -62,7 +53,6 @@ function handleParseHeaders(req, res, next) {
|
|
|
62
53
|
return malformedContext(req, res);
|
|
63
54
|
}
|
|
64
55
|
}
|
|
65
|
-
|
|
66
56
|
var info = {
|
|
67
57
|
appId: req.get('X-Parse-Application-Id'),
|
|
68
58
|
sessionToken: req.get('X-Parse-Session-Token'),
|
|
@@ -76,25 +66,20 @@ function handleParseHeaders(req, res, next) {
|
|
|
76
66
|
context: context
|
|
77
67
|
};
|
|
78
68
|
var basicAuth = httpAuth(req);
|
|
79
|
-
|
|
80
69
|
if (basicAuth) {
|
|
81
70
|
var basicAuthAppId = basicAuth.appId;
|
|
82
|
-
|
|
83
71
|
if (_cache.default.get(basicAuthAppId)) {
|
|
84
72
|
info.appId = basicAuthAppId;
|
|
85
73
|
info.masterKey = basicAuth.masterKey || info.masterKey;
|
|
86
74
|
info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey;
|
|
87
75
|
}
|
|
88
76
|
}
|
|
89
|
-
|
|
90
77
|
if (req.body) {
|
|
91
78
|
// Unity SDK sends a _noBody key which needs to be removed.
|
|
92
79
|
// Unclear at this point if action needs to be taken.
|
|
93
80
|
delete req.body._noBody;
|
|
94
81
|
}
|
|
95
|
-
|
|
96
82
|
var fileViaJSON = false;
|
|
97
|
-
|
|
98
83
|
if (!info.appId || !_cache.default.get(info.appId)) {
|
|
99
84
|
// See if we can find the app id on the body.
|
|
100
85
|
if (req.body instanceof Buffer) {
|
|
@@ -108,48 +93,40 @@ function handleParseHeaders(req, res, next) {
|
|
|
108
93
|
} catch (e) {
|
|
109
94
|
return invalidRequest(req, res);
|
|
110
95
|
}
|
|
111
|
-
|
|
112
96
|
fileViaJSON = true;
|
|
113
97
|
}
|
|
114
|
-
|
|
115
98
|
if (req.body) {
|
|
116
99
|
delete req.body._RevocableSession;
|
|
117
100
|
}
|
|
118
|
-
|
|
119
101
|
if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) {
|
|
120
102
|
info.appId = req.body._ApplicationId;
|
|
121
103
|
info.javascriptKey = req.body._JavaScriptKey || '';
|
|
122
104
|
delete req.body._ApplicationId;
|
|
123
|
-
delete req.body._JavaScriptKey;
|
|
105
|
+
delete req.body._JavaScriptKey;
|
|
106
|
+
// TODO: test that the REST API formats generated by the other
|
|
124
107
|
// SDKs are handled ok
|
|
125
|
-
|
|
126
108
|
if (req.body._ClientVersion) {
|
|
127
109
|
info.clientVersion = req.body._ClientVersion;
|
|
128
110
|
delete req.body._ClientVersion;
|
|
129
111
|
}
|
|
130
|
-
|
|
131
112
|
if (req.body._InstallationId) {
|
|
132
113
|
info.installationId = req.body._InstallationId;
|
|
133
114
|
delete req.body._InstallationId;
|
|
134
115
|
}
|
|
135
|
-
|
|
136
116
|
if (req.body._SessionToken) {
|
|
137
117
|
info.sessionToken = req.body._SessionToken;
|
|
138
118
|
delete req.body._SessionToken;
|
|
139
119
|
}
|
|
140
|
-
|
|
141
120
|
if (req.body._MasterKey) {
|
|
142
121
|
info.masterKey = req.body._MasterKey;
|
|
143
122
|
delete req.body._MasterKey;
|
|
144
123
|
}
|
|
145
|
-
|
|
146
124
|
if (req.body._context) {
|
|
147
125
|
if (req.body._context instanceof Object) {
|
|
148
126
|
info.context = req.body._context;
|
|
149
127
|
} else {
|
|
150
128
|
try {
|
|
151
129
|
info.context = JSON.parse(req.body._context);
|
|
152
|
-
|
|
153
130
|
if (Object.prototype.toString.call(info.context) !== '[object Object]') {
|
|
154
131
|
throw 'Context is not an object';
|
|
155
132
|
}
|
|
@@ -157,10 +134,8 @@ function handleParseHeaders(req, res, next) {
|
|
|
157
134
|
return malformedContext(req, res);
|
|
158
135
|
}
|
|
159
136
|
}
|
|
160
|
-
|
|
161
137
|
delete req.body._context;
|
|
162
138
|
}
|
|
163
|
-
|
|
164
139
|
if (req.body._ContentType) {
|
|
165
140
|
req.headers['content-type'] = req.body._ContentType;
|
|
166
141
|
delete req.body._ContentType;
|
|
@@ -169,47 +144,49 @@ function handleParseHeaders(req, res, next) {
|
|
|
169
144
|
return invalidRequest(req, res);
|
|
170
145
|
}
|
|
171
146
|
}
|
|
172
|
-
|
|
173
147
|
if (info.sessionToken && typeof info.sessionToken !== 'string') {
|
|
174
148
|
info.sessionToken = info.sessionToken.toString();
|
|
175
149
|
}
|
|
176
|
-
|
|
177
150
|
if (info.clientVersion) {
|
|
178
151
|
info.clientSDK = _ClientSDK.default.fromString(info.clientVersion);
|
|
179
152
|
}
|
|
180
|
-
|
|
181
153
|
if (fileViaJSON) {
|
|
182
|
-
req.fileData = req.body.fileData;
|
|
183
|
-
|
|
154
|
+
req.fileData = req.body.fileData;
|
|
155
|
+
// We need to repopulate req.body with a buffer
|
|
184
156
|
var base64 = req.body.base64;
|
|
185
157
|
req.body = Buffer.from(base64, 'base64');
|
|
186
158
|
}
|
|
187
|
-
|
|
188
159
|
const clientIp = getClientIp(req);
|
|
160
|
+
const config = _Config.default.get(info.appId, mount);
|
|
161
|
+
if (config.state && config.state !== 'ok') {
|
|
162
|
+
res.status(500);
|
|
163
|
+
res.json({
|
|
164
|
+
code: _node.default.Error.INTERNAL_SERVER_ERROR,
|
|
165
|
+
error: `Invalid server state: ${config.state}`
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
189
169
|
info.app = _cache.default.get(info.appId);
|
|
190
|
-
req.config =
|
|
170
|
+
req.config = config;
|
|
191
171
|
req.config.headers = req.headers || {};
|
|
192
172
|
req.config.ip = clientIp;
|
|
193
173
|
req.info = info;
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
174
|
+
let isMaster = info.masterKey === req.config.masterKey;
|
|
175
|
+
if (isMaster && !(0, _ipRangeCheck.default)(clientIp, req.config.masterKeyIps || [])) {
|
|
176
|
+
var _req$config;
|
|
177
|
+
const log = ((_req$config = req.config) === null || _req$config === void 0 ? void 0 : _req$config.loggerController) || _logger.default;
|
|
178
|
+
log.error(`Request using master key rejected as the request IP address '${clientIp}' is not set in Parse Server option 'masterKeyIps'.`);
|
|
179
|
+
isMaster = false;
|
|
197
180
|
}
|
|
198
|
-
|
|
199
|
-
var isMaster = info.masterKey === req.config.masterKey;
|
|
200
|
-
|
|
201
181
|
if (isMaster) {
|
|
202
182
|
req.auth = new _Auth.default.Auth({
|
|
203
183
|
config: req.config,
|
|
204
184
|
installationId: info.installationId,
|
|
205
185
|
isMaster: true
|
|
206
186
|
});
|
|
207
|
-
next
|
|
208
|
-
return;
|
|
187
|
+
return handleRateLimit(req, res, next);
|
|
209
188
|
}
|
|
210
|
-
|
|
211
189
|
var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey;
|
|
212
|
-
|
|
213
190
|
if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) {
|
|
214
191
|
req.auth = new _Auth.default.Auth({
|
|
215
192
|
config: req.config,
|
|
@@ -217,12 +194,11 @@ function handleParseHeaders(req, res, next) {
|
|
|
217
194
|
isMaster: true,
|
|
218
195
|
isReadOnly: true
|
|
219
196
|
});
|
|
220
|
-
next
|
|
221
|
-
|
|
222
|
-
} // Client keys are not required in parse-server, but if any have been configured in the server, validate them
|
|
223
|
-
// to preserve original behavior.
|
|
224
|
-
|
|
197
|
+
return handleRateLimit(req, res, next);
|
|
198
|
+
}
|
|
225
199
|
|
|
200
|
+
// Client keys are not required in parse-server, but if any have been configured in the server, validate them
|
|
201
|
+
// to preserve original behavior.
|
|
226
202
|
const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey'];
|
|
227
203
|
const oneKeyConfigured = keys.some(function (key) {
|
|
228
204
|
return req.config[key] !== undefined;
|
|
@@ -230,15 +206,12 @@ function handleParseHeaders(req, res, next) {
|
|
|
230
206
|
const oneKeyMatches = keys.some(function (key) {
|
|
231
207
|
return req.config[key] !== undefined && info[key] === req.config[key];
|
|
232
208
|
});
|
|
233
|
-
|
|
234
209
|
if (oneKeyConfigured && !oneKeyMatches) {
|
|
235
210
|
return invalidRequest(req, res);
|
|
236
211
|
}
|
|
237
|
-
|
|
238
212
|
if (req.url == '/login') {
|
|
239
213
|
delete info.sessionToken;
|
|
240
214
|
}
|
|
241
|
-
|
|
242
215
|
if (req.userFromJWT) {
|
|
243
216
|
req.auth = new _Auth.default.Auth({
|
|
244
217
|
config: req.config,
|
|
@@ -246,89 +219,93 @@ function handleParseHeaders(req, res, next) {
|
|
|
246
219
|
isMaster: false,
|
|
247
220
|
user: req.userFromJWT
|
|
248
221
|
});
|
|
249
|
-
next
|
|
250
|
-
return;
|
|
222
|
+
return handleRateLimit(req, res, next);
|
|
251
223
|
}
|
|
252
|
-
|
|
253
224
|
if (!info.sessionToken) {
|
|
254
225
|
req.auth = new _Auth.default.Auth({
|
|
255
226
|
config: req.config,
|
|
256
227
|
installationId: info.installationId,
|
|
257
228
|
isMaster: false
|
|
258
229
|
});
|
|
259
|
-
|
|
230
|
+
}
|
|
231
|
+
handleRateLimit(req, res, next);
|
|
232
|
+
}
|
|
233
|
+
const handleRateLimit = async (req, res, next) => {
|
|
234
|
+
const rateLimits = req.config.rateLimits || [];
|
|
235
|
+
try {
|
|
236
|
+
await Promise.all(rateLimits.map(async limit => {
|
|
237
|
+
const pathExp = new RegExp(limit.path);
|
|
238
|
+
if (pathExp.test(req.url)) {
|
|
239
|
+
await limit.handler(req, res, err => {
|
|
240
|
+
if (err) {
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
} catch (error) {
|
|
247
|
+
res.status(429);
|
|
248
|
+
res.json({
|
|
249
|
+
code: _node.default.Error.CONNECTION_FAILED,
|
|
250
|
+
error
|
|
251
|
+
});
|
|
260
252
|
return;
|
|
261
253
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
254
|
+
next();
|
|
255
|
+
};
|
|
256
|
+
const handleParseSession = async (req, res, next) => {
|
|
257
|
+
try {
|
|
258
|
+
const info = req.info;
|
|
259
|
+
if (req.auth) {
|
|
260
|
+
next();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
let requestAuth = null;
|
|
265
264
|
if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) {
|
|
266
|
-
|
|
265
|
+
requestAuth = await _Auth.default.getAuthForLegacySessionToken({
|
|
267
266
|
config: req.config,
|
|
268
267
|
installationId: info.installationId,
|
|
269
268
|
sessionToken: info.sessionToken
|
|
270
269
|
});
|
|
271
270
|
} else {
|
|
272
|
-
|
|
271
|
+
requestAuth = await _Auth.default.getAuthForSessionToken({
|
|
273
272
|
config: req.config,
|
|
274
273
|
installationId: info.installationId,
|
|
275
274
|
sessionToken: info.sessionToken
|
|
276
275
|
});
|
|
277
276
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
next();
|
|
282
|
-
}
|
|
283
|
-
}).catch(error => {
|
|
277
|
+
req.auth = requestAuth;
|
|
278
|
+
next();
|
|
279
|
+
} catch (error) {
|
|
284
280
|
if (error instanceof _node.default.Error) {
|
|
285
281
|
next(error);
|
|
286
282
|
return;
|
|
287
|
-
} else {
|
|
288
|
-
// TODO: Determine the correct error scenario.
|
|
289
|
-
req.config.loggerController.error('error getting auth for sessionToken', error);
|
|
290
|
-
throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error);
|
|
291
283
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
function getClientIp(req) {
|
|
296
|
-
if (req.headers['x-forwarded-for']) {
|
|
297
|
-
// try to get from x-forwared-for if it set (behind reverse proxy)
|
|
298
|
-
return req.headers['x-forwarded-for'].split(',')[0];
|
|
299
|
-
} else if (req.connection && req.connection.remoteAddress) {
|
|
300
|
-
// no proxy, try getting from connection.remoteAddress
|
|
301
|
-
return req.connection.remoteAddress;
|
|
302
|
-
} else if (req.socket) {
|
|
303
|
-
// try to get it from req.socket
|
|
304
|
-
return req.socket.remoteAddress;
|
|
305
|
-
} else if (req.connection && req.connection.socket) {
|
|
306
|
-
// try to get it form the connection.socket
|
|
307
|
-
return req.connection.socket.remoteAddress;
|
|
308
|
-
} else {
|
|
309
|
-
// if non above, fallback.
|
|
310
|
-
return req.ip;
|
|
284
|
+
// TODO: Determine the correct error scenario.
|
|
285
|
+
req.config.loggerController.error('error getting auth for sessionToken', error);
|
|
286
|
+
throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error);
|
|
311
287
|
}
|
|
288
|
+
};
|
|
289
|
+
exports.handleParseSession = handleParseSession;
|
|
290
|
+
function getClientIp(req) {
|
|
291
|
+
return req.ip;
|
|
312
292
|
}
|
|
313
|
-
|
|
314
293
|
function httpAuth(req) {
|
|
315
294
|
if (!(req.req || req).headers.authorization) return;
|
|
316
295
|
var header = (req.req || req).headers.authorization;
|
|
317
|
-
var appId, masterKey, javascriptKey;
|
|
296
|
+
var appId, masterKey, javascriptKey;
|
|
318
297
|
|
|
298
|
+
// parse header
|
|
319
299
|
var authPrefix = 'basic ';
|
|
320
300
|
var match = header.toLowerCase().indexOf(authPrefix);
|
|
321
|
-
|
|
322
301
|
if (match == 0) {
|
|
323
302
|
var encodedAuth = header.substring(authPrefix.length, header.length);
|
|
324
303
|
var credentials = decodeBase64(encodedAuth).split(':');
|
|
325
|
-
|
|
326
304
|
if (credentials.length == 2) {
|
|
327
305
|
appId = credentials[0];
|
|
328
306
|
var key = credentials[1];
|
|
329
307
|
var jsKeyPrefix = 'javascript-key=';
|
|
330
308
|
var matchKey = key.indexOf(jsKeyPrefix);
|
|
331
|
-
|
|
332
309
|
if (matchKey == 0) {
|
|
333
310
|
javascriptKey = key.substring(jsKeyPrefix.length, key.length);
|
|
334
311
|
} else {
|
|
@@ -336,34 +313,28 @@ function httpAuth(req) {
|
|
|
336
313
|
}
|
|
337
314
|
}
|
|
338
315
|
}
|
|
339
|
-
|
|
340
316
|
return {
|
|
341
317
|
appId: appId,
|
|
342
318
|
masterKey: masterKey,
|
|
343
319
|
javascriptKey: javascriptKey
|
|
344
320
|
};
|
|
345
321
|
}
|
|
346
|
-
|
|
347
322
|
function decodeBase64(str) {
|
|
348
323
|
return Buffer.from(str, 'base64').toString();
|
|
349
324
|
}
|
|
350
|
-
|
|
351
325
|
function allowCrossDomain(appId) {
|
|
352
326
|
return (req, res, next) => {
|
|
353
327
|
const config = _Config.default.get(appId, getMountForRequest(req));
|
|
354
|
-
|
|
355
328
|
let allowHeaders = DEFAULT_ALLOWED_HEADERS;
|
|
356
|
-
|
|
357
329
|
if (config && config.allowHeaders) {
|
|
358
330
|
allowHeaders += `, ${config.allowHeaders.join(', ')}`;
|
|
359
331
|
}
|
|
360
|
-
|
|
361
332
|
const allowOrigin = config && config.allowOrigin || '*';
|
|
362
333
|
res.header('Access-Control-Allow-Origin', allowOrigin);
|
|
363
334
|
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
|
|
364
335
|
res.header('Access-Control-Allow-Headers', allowHeaders);
|
|
365
|
-
res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id');
|
|
366
|
-
|
|
336
|
+
res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id');
|
|
337
|
+
// intercept OPTIONS method
|
|
367
338
|
if ('OPTIONS' == req.method) {
|
|
368
339
|
res.sendStatus(200);
|
|
369
340
|
} else {
|
|
@@ -371,40 +342,32 @@ function allowCrossDomain(appId) {
|
|
|
371
342
|
}
|
|
372
343
|
};
|
|
373
344
|
}
|
|
374
|
-
|
|
375
345
|
function allowMethodOverride(req, res, next) {
|
|
376
346
|
if (req.method === 'POST' && req.body._method) {
|
|
377
347
|
req.originalMethod = req.method;
|
|
378
348
|
req.method = req.body._method;
|
|
379
349
|
delete req.body._method;
|
|
380
350
|
}
|
|
381
|
-
|
|
382
351
|
next();
|
|
383
352
|
}
|
|
384
|
-
|
|
385
353
|
function handleParseErrors(err, req, res, next) {
|
|
386
354
|
const log = req.config && req.config.loggerController || _logger.default;
|
|
387
|
-
|
|
388
355
|
if (err instanceof _node.default.Error) {
|
|
389
356
|
if (req.config && req.config.enableExpressErrorHandler) {
|
|
390
357
|
return next(err);
|
|
391
358
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
359
|
+
let httpStatus;
|
|
360
|
+
// TODO: fill out this mapping
|
|
395
361
|
switch (err.code) {
|
|
396
362
|
case _node.default.Error.INTERNAL_SERVER_ERROR:
|
|
397
363
|
httpStatus = 500;
|
|
398
364
|
break;
|
|
399
|
-
|
|
400
365
|
case _node.default.Error.OBJECT_NOT_FOUND:
|
|
401
366
|
httpStatus = 404;
|
|
402
367
|
break;
|
|
403
|
-
|
|
404
368
|
default:
|
|
405
369
|
httpStatus = 400;
|
|
406
370
|
}
|
|
407
|
-
|
|
408
371
|
res.status(httpStatus);
|
|
409
372
|
res.json({
|
|
410
373
|
code: err.code,
|
|
@@ -416,7 +379,6 @@ function handleParseErrors(err, req, res, next) {
|
|
|
416
379
|
res.json({
|
|
417
380
|
error: err.message
|
|
418
381
|
});
|
|
419
|
-
|
|
420
382
|
if (!(process && process.env.TESTING)) {
|
|
421
383
|
next(err);
|
|
422
384
|
}
|
|
@@ -427,23 +389,19 @@ function handleParseErrors(err, req, res, next) {
|
|
|
427
389
|
code: _node.default.Error.INTERNAL_SERVER_ERROR,
|
|
428
390
|
message: 'Internal server error.'
|
|
429
391
|
});
|
|
430
|
-
|
|
431
392
|
if (!(process && process.env.TESTING)) {
|
|
432
393
|
next(err);
|
|
433
394
|
}
|
|
434
395
|
}
|
|
435
396
|
}
|
|
436
|
-
|
|
437
397
|
function enforceMasterKeyAccess(req, res, next) {
|
|
438
398
|
if (!req.auth.isMaster) {
|
|
439
399
|
res.status(403);
|
|
440
400
|
res.end('{"error":"unauthorized: master key is required"}');
|
|
441
401
|
return;
|
|
442
402
|
}
|
|
443
|
-
|
|
444
403
|
next();
|
|
445
404
|
}
|
|
446
|
-
|
|
447
405
|
function promiseEnforceMasterKeyAccess(request) {
|
|
448
406
|
if (!request.auth.isMaster) {
|
|
449
407
|
const error = new Error();
|
|
@@ -451,56 +409,97 @@ function promiseEnforceMasterKeyAccess(request) {
|
|
|
451
409
|
error.message = 'unauthorized: master key is required';
|
|
452
410
|
throw error;
|
|
453
411
|
}
|
|
454
|
-
|
|
455
412
|
return Promise.resolve();
|
|
456
413
|
}
|
|
414
|
+
const addRateLimit = (route, config) => {
|
|
415
|
+
if (typeof config === 'string') {
|
|
416
|
+
config = _Config.default.get(config);
|
|
417
|
+
}
|
|
418
|
+
for (const key in route) {
|
|
419
|
+
if (!_Definitions.RateLimitOptions[key]) {
|
|
420
|
+
throw `Invalid rate limit option "${key}"`;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
if (!config.rateLimits) {
|
|
424
|
+
config.rateLimits = [];
|
|
425
|
+
}
|
|
426
|
+
config.rateLimits.push({
|
|
427
|
+
path: (0, _pathToRegexp.default)(route.requestPath),
|
|
428
|
+
handler: (0, _expressRateLimit.default)({
|
|
429
|
+
windowMs: route.requestTimeWindow,
|
|
430
|
+
max: route.requestCount,
|
|
431
|
+
message: route.errorResponseMessage || _Definitions.RateLimitOptions.errorResponseMessage.default,
|
|
432
|
+
handler: (request, response, next, options) => {
|
|
433
|
+
throw options.message;
|
|
434
|
+
},
|
|
435
|
+
skip: request => {
|
|
436
|
+
if (request.ip === '127.0.0.1' && !route.includeInternalRequests) {
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
if (route.includeMasterKey) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
if (route.requestMethods) {
|
|
443
|
+
if (Array.isArray(route.requestMethods)) {
|
|
444
|
+
if (!route.requestMethods.includes(request.method)) {
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
const regExp = new RegExp(route.requestMethods);
|
|
449
|
+
if (!regExp.test(request.method)) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
return request.auth.isMaster;
|
|
455
|
+
},
|
|
456
|
+
keyGenerator: request => {
|
|
457
|
+
return request.config.ip;
|
|
458
|
+
}
|
|
459
|
+
})
|
|
460
|
+
});
|
|
461
|
+
_Config.default.put(config);
|
|
462
|
+
};
|
|
463
|
+
|
|
457
464
|
/**
|
|
458
465
|
* Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID
|
|
459
466
|
* in the request header. If a request has no request ID, it is executed anyway.
|
|
460
467
|
* @param {*} req The request to evaluate.
|
|
461
468
|
* @returns Promise<{}>
|
|
462
469
|
*/
|
|
463
|
-
|
|
464
|
-
|
|
470
|
+
exports.addRateLimit = addRateLimit;
|
|
465
471
|
function promiseEnsureIdempotency(req) {
|
|
466
472
|
// Enable feature only for MongoDB
|
|
467
473
|
if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default || req.config.database.adapter instanceof _PostgresStorageAdapter.default)) {
|
|
468
474
|
return Promise.resolve();
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
475
|
+
}
|
|
476
|
+
// Get parameters
|
|
472
477
|
const config = req.config;
|
|
473
478
|
const requestId = ((req || {}).headers || {})['x-parse-request-id'];
|
|
474
479
|
const {
|
|
475
480
|
paths,
|
|
476
481
|
ttl
|
|
477
482
|
} = config.idempotencyOptions;
|
|
478
|
-
|
|
479
483
|
if (!requestId || !config.idempotencyOptions) {
|
|
480
484
|
return Promise.resolve();
|
|
481
|
-
}
|
|
485
|
+
}
|
|
486
|
+
// Request path may contain trailing slashes, depending on the original request, so remove
|
|
482
487
|
// leading and trailing slashes to make it easier to specify paths in the configuration
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
const reqPath = req.path.replace(/^\/|\/$/, ''); // Determine whether idempotency is enabled for current request path
|
|
486
|
-
|
|
488
|
+
const reqPath = req.path.replace(/^\/|\/$/, '');
|
|
489
|
+
// Determine whether idempotency is enabled for current request path
|
|
487
490
|
let match = false;
|
|
488
|
-
|
|
489
491
|
for (const path of paths) {
|
|
490
492
|
// Assume one wants a path to always match from the beginning to prevent any mistakes
|
|
491
493
|
const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path);
|
|
492
|
-
|
|
493
494
|
if (reqPath.match(regex)) {
|
|
494
495
|
match = true;
|
|
495
496
|
break;
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
|
-
|
|
499
499
|
if (!match) {
|
|
500
500
|
return Promise.resolve();
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
|
|
501
|
+
}
|
|
502
|
+
// Try to store request
|
|
504
503
|
const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl));
|
|
505
504
|
return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', {
|
|
506
505
|
reqId: requestId,
|
|
@@ -509,16 +508,13 @@ function promiseEnsureIdempotency(req) {
|
|
|
509
508
|
if (e.code == _node.default.Error.DUPLICATE_VALUE) {
|
|
510
509
|
throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request');
|
|
511
510
|
}
|
|
512
|
-
|
|
513
511
|
throw e;
|
|
514
512
|
});
|
|
515
513
|
}
|
|
516
|
-
|
|
517
514
|
function invalidRequest(req, res) {
|
|
518
515
|
res.status(403);
|
|
519
516
|
res.end('{"error":"unauthorized"}');
|
|
520
517
|
}
|
|
521
|
-
|
|
522
518
|
function malformedContext(req, res) {
|
|
523
519
|
res.status(400);
|
|
524
520
|
res.json({
|
|
@@ -526,4 +522,4 @@ function malformedContext(req, res) {
|
|
|
526
522
|
error: 'Invalid object for context.'
|
|
527
523
|
});
|
|
528
524
|
}
|
|
529
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImNvbnRleHQiLCJKU09OIiwicGFyc2UiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJlIiwibWFsZm9ybWVkQ29udGV4dCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiYmFzaWNBdXRoIiwiaHR0cEF1dGgiLCJiYXNpY0F1dGhBcHBJZCIsIkFwcENhY2hlIiwiYm9keSIsIl9ub0JvZHkiLCJmaWxlVmlhSlNPTiIsIkJ1ZmZlciIsImludmFsaWRSZXF1ZXN0IiwiX1Jldm9jYWJsZVNlc3Npb24iLCJfQXBwbGljYXRpb25JZCIsIl9KYXZhU2NyaXB0S2V5IiwiX0NsaWVudFZlcnNpb24iLCJfSW5zdGFsbGF0aW9uSWQiLCJfU2Vzc2lvblRva2VuIiwiX01hc3RlcktleSIsIl9jb250ZXh0IiwiX0NvbnRlbnRUeXBlIiwiaGVhZGVycyIsImNsaWVudFNESyIsIkNsaWVudFNESyIsImZyb21TdHJpbmciLCJmaWxlRGF0YSIsImJhc2U2NCIsImZyb20iLCJjbGllbnRJcCIsImdldENsaWVudElwIiwiYXBwIiwiY29uZmlnIiwiQ29uZmlnIiwiaXAiLCJtYXN0ZXJLZXlJcHMiLCJpbmRleE9mIiwiaXNNYXN0ZXIiLCJhdXRoIiwiQXV0aCIsImlzUmVhZE9ubHlNYXN0ZXIiLCJyZWFkT25seU1hc3RlcktleSIsImlzUmVhZE9ubHkiLCJrZXlzIiwib25lS2V5Q29uZmlndXJlZCIsInNvbWUiLCJrZXkiLCJ1bmRlZmluZWQiLCJvbmVLZXlNYXRjaGVzIiwidXNlckZyb21KV1QiLCJ1c2VyIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJjYXRjaCIsImVycm9yIiwiUGFyc2UiLCJFcnJvciIsImxvZ2dlckNvbnRyb2xsZXIiLCJVTktOT1dOX0VSUk9SIiwic3BsaXQiLCJjb25uZWN0aW9uIiwicmVtb3RlQWRkcmVzcyIsInNvY2tldCIsImF1dGhvcml6YXRpb24iLCJoZWFkZXIiLCJhdXRoUHJlZml4IiwibWF0Y2giLCJ0b0xvd2VyQ2FzZSIsImVuY29kZWRBdXRoIiwic3Vic3RyaW5nIiwiY3JlZGVudGlhbHMiLCJkZWNvZGVCYXNlNjQiLCJqc0tleVByZWZpeCIsIm1hdGNoS2V5Iiwic3RyIiwiYWxsb3dDcm9zc0RvbWFpbiIsImFsbG93SGVhZGVycyIsImpvaW4iLCJhbGxvd09yaWdpbiIsIm1ldGhvZCIsInNlbmRTdGF0dXMiLCJhbGxvd01ldGhvZE92ZXJyaWRlIiwiX21ldGhvZCIsIm9yaWdpbmFsTWV0aG9kIiwiaGFuZGxlUGFyc2VFcnJvcnMiLCJlcnIiLCJsb2ciLCJkZWZhdWx0TG9nZ2VyIiwiZW5hYmxlRXhwcmVzc0Vycm9ySGFuZGxlciIsImh0dHBTdGF0dXMiLCJjb2RlIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiT0JKRUNUX05PVF9GT1VORCIsInN0YXR1cyIsImpzb24iLCJtZXNzYWdlIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJzdGFjayIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJlbmQiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcXVlc3QiLCJwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kiLCJkYXRhYmFzZSIsImFkYXB0ZXIiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwiUG9zdGdyZXNTdG9yYWdlQWRhcHRlciIsInJlcXVlc3RJZCIsInBhdGhzIiwidHRsIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwicmVxUGF0aCIsInBhdGgiLCJyZXBsYWNlIiwicmVnZXgiLCJSZWdFeHAiLCJjaGFyQXQiLCJleHBpcnlEYXRlIiwiRGF0ZSIsInNldFNlY29uZHMiLCJnZXRTZWNvbmRzIiwicmVzdCIsImNyZWF0ZSIsIm1hc3RlciIsInJlcUlkIiwiZXhwaXJlIiwiX2VuY29kZSIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIiwiSU5WQUxJRF9KU09OIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQURLOzs7QUFHUCxNQUFNQyxrQkFBa0IsR0FBRyxVQUFVQyxHQUFWLEVBQWU7QUFDeEMsUUFBTUMsZUFBZSxHQUFHRCxHQUFHLENBQUNFLFdBQUosQ0FBZ0JDLE1BQWhCLEdBQXlCSCxHQUFHLENBQUNJLEdBQUosQ0FBUUQsTUFBekQ7QUFDQSxRQUFNRSxTQUFTLEdBQUdMLEdBQUcsQ0FBQ0UsV0FBSixDQUFnQkksS0FBaEIsQ0FBc0IsQ0FBdEIsRUFBeUJMLGVBQXpCLENBQWxCO0FBQ0EsU0FBT0QsR0FBRyxDQUFDTyxRQUFKLEdBQWUsS0FBZixHQUF1QlAsR0FBRyxDQUFDUSxHQUFKLENBQVEsTUFBUixDQUF2QixHQUF5Q0gsU0FBaEQ7QUFDRCxDQUpELEMsQ0FNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNJLGtCQUFULENBQTRCVCxHQUE1QixFQUFpQ1UsR0FBakMsRUFBc0NDLElBQXRDLEVBQTRDO0FBQ2pELE1BQUlDLEtBQUssR0FBR2Isa0JBQWtCLENBQUNDLEdBQUQsQ0FBOUI7QUFFQSxNQUFJYSxPQUFPLEdBQUcsRUFBZDs7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L0IsRUFBb0M7QUFDbENBLEVBQUFBLEdBQUcsQ0FBQ2tILE1BQUosQ0FBVyxHQUFYO0FBQ0FsSCxFQUFBQSxHQUFHLENBQUNtSCxJQUFKLENBQVM7QUFBRUosSUFBQUEsSUFBSSxFQUFFbkMsY0FBTUMsS0FBTixDQUFZMkUsWUFBcEI7QUFBa0M3RSxJQUFBQSxLQUFLLEVBQUU7QUFBekMsR0FBVDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFwcENhY2hlIGZyb20gJy4vY2FjaGUnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGF1dGggZnJvbSAnLi9BdXRoJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi9Db25maWcnO1xuaW1wb3J0IENsaWVudFNESyBmcm9tICcuL0NsaWVudFNESyc7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuL3Jlc3QnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IFBvc3RncmVzU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXInO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9BTExPV0VEX0hFQURFUlMgPVxuICAnWC1QYXJzZS1NYXN0ZXItS2V5LCBYLVBhcnNlLVJFU1QtQVBJLUtleSwgWC1QYXJzZS1KYXZhc2NyaXB0LUtleSwgWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCwgWC1QYXJzZS1DbGllbnQtVmVyc2lvbiwgWC1QYXJzZS1TZXNzaW9uLVRva2VuLCBYLVJlcXVlc3RlZC1XaXRoLCBYLVBhcnNlLVJldm9jYWJsZS1TZXNzaW9uLCBYLVBhcnNlLVJlcXVlc3QtSWQsIENvbnRlbnQtVHlwZSwgUHJhZ21hLCBDYWNoZS1Db250cm9sJztcblxuY29uc3QgZ2V0TW91bnRGb3JSZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcSkge1xuICBjb25zdCBtb3VudFBhdGhMZW5ndGggPSByZXEub3JpZ2luYWxVcmwubGVuZ3RoIC0gcmVxLnVybC5sZW5ndGg7XG4gIGNvbnN0IG1vdW50UGF0aCA9IHJlcS5vcmlnaW5hbFVybC5zbGljZSgwLCBtb3VudFBhdGhMZW5ndGgpO1xuICByZXR1cm4gcmVxLnByb3RvY29sICsgJzovLycgKyByZXEuZ2V0KCdob3N0JykgKyBtb3VudFBhdGg7XG59O1xuXG4vLyBDaGVja3MgdGhhdCB0aGUgcmVxdWVzdCBpcyBhdXRob3JpemVkIGZvciB0aGlzIGFwcCBhbmQgY2hlY2tzIHVzZXJcbi8vIGF1dGggdG9vLlxuLy8gVGhlIGJvZHlwYXJzZXIgc2hvdWxkIHJ1biBiZWZvcmUgdGhpcyBtaWRkbGV3YXJlLlxuLy8gQWRkcyBpbmZvIHRvIHRoZSByZXF1ZXN0OlxuLy8gcmVxLmNvbmZpZyAtIHRoZSBDb25maWcgZm9yIHRoaXMgYXBwXG4vLyByZXEuYXV0aCAtIHRoZSBBdXRoIGZvciB0aGlzIHJlcXVlc3RcbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUhlYWRlcnMocmVxLCByZXMsIG5leHQpIHtcbiAgdmFyIG1vdW50ID0gZ2V0TW91bnRGb3JSZXF1ZXN0KHJlcSk7XG5cbiAgbGV0IGNvbnRleHQgPSB7fTtcbiAgaWYgKHJlcS5nZXQoJ1gtUGFyc2UtQ2xvdWQtQ29udGV4dCcpICE9IG51bGwpIHtcbiAgICB0cnkge1xuICAgICAgY29udGV4dCA9IEpTT04ucGFyc2UocmVxLmdldCgnWC1QYXJzZS1DbG91ZC1Db250ZXh0JykpO1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChjb250ZXh0KSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgICAgdGhyb3cgJ0NvbnRleHQgaXMgbm90IGFuIG9iamVjdCc7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIG1hbGZvcm1lZENvbnRleHQocmVxLCByZXMpO1xuICAgIH1cbiAgfVxuICB2YXIgaW5mbyA9IHtcbiAgICBhcHBJZDogcmVxLmdldCgnWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCcpLFxuICAgIHNlc3Npb25Ub2tlbjogcmVxLmdldCgnWC1QYXJzZS1TZXNzaW9uLVRva2VuJyksXG4gICAgbWFzdGVyS2V5OiByZXEuZ2V0KCdYLVBhcnNlLU1hc3Rlci1LZXknKSxcbiAgICBpbnN0YWxsYXRpb25JZDogcmVxLmdldCgnWC1QYXJzZS1JbnN0YWxsYXRpb24tSWQnKSxcbiAgICBjbGllbnRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LUtleScpLFxuICAgIGphdmFzY3JpcHRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtSmF2YXNjcmlwdC1LZXknKSxcbiAgICBkb3ROZXRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtV2luZG93cy1LZXknKSxcbiAgICByZXN0QVBJS2V5OiByZXEuZ2V0KCdYLVBhcnNlLVJFU1QtQVBJLUtleScpLFxuICAgIGNsaWVudFZlcnNpb246IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LVZlcnNpb24nKSxcbiAgICBjb250ZXh0OiBjb250ZXh0LFxuICB9O1xuXG4gIHZhciBiYXNpY0F1dGggPSBodHRwQXV0aChyZXEpO1xuXG4gIGlmIChiYXNpY0F1dGgpIHtcbiAgICB2YXIgYmFzaWNBdXRoQXBwSWQgPSBiYXNpY0F1dGguYXBwSWQ7XG4gICAgaWYgKEFwcENhY2hlLmdldChiYXNpY0F1dGhBcHBJZCkpIHtcbiAgICAgIGluZm8uYXBwSWQgPSBiYXNpY0F1dGhBcHBJZDtcbiAgICAgIGluZm8ubWFzdGVyS2V5ID0gYmFzaWNBdXRoLm1hc3RlcktleSB8fCBpbmZvLm1hc3RlcktleTtcbiAgICAgIGluZm8uamF2YXNjcmlwdEtleSA9IGJhc2ljQXV0aC5qYXZhc2NyaXB0S2V5IHx8IGluZm8uamF2YXNjcmlwdEtleTtcbiAgICB9XG4gIH1cblxuICBpZiAocmVxLmJvZHkpIHtcbiAgICAvLyBVbml0eSBTREsgc2VuZHMgYSBfbm9Cb2R5IGtleSB3aGljaCBuZWVkcyB0byBiZSByZW1vdmVkLlxuICAgIC8vIFVuY2xlYXIgYXQgdGhpcyBwb2ludCBpZiBhY3Rpb24gbmVlZHMgdG8gYmUgdGFrZW4uXG4gICAgZGVsZXRlIHJlcS5ib2R5Ll9ub0JvZHk7XG4gIH1cblxuICB2YXIgZmlsZVZpYUpTT04gPSBmYWxzZTtcblxuICBpZiAoIWluZm8uYXBwSWQgfHwgIUFwcENhY2hlLmdldChpbmZvLmFwcElkKSkge1xuICAgIC8vIFNlZSBpZiB3ZSBjYW4gZmluZCB0aGUgYXBwIGlkIG9uIHRoZSBib2R5LlxuICAgIGlmIChyZXEuYm9keSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgLy8gVGhlIG9ubHkgY2hhbmNlIHRvIGZpbmQgdGhlIGFwcCBpZCBpcyBpZiB0aGlzIGlzIGEgZmlsZVxuICAgICAgLy8gdXBsb2FkIHRoYXQgYWN0dWFsbHkgaXMgYSBKU09OIGJvZHkuIFNvIHRyeSB0byBwYXJzZSBpdC5cbiAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy82NTg5XG4gICAgICAvLyBJdCBpcyBhbHNvIHBvc3NpYmxlIHRoYXQgdGhlIGNsaWVudCBpcyB0cnlpbmcgdG8gdXBsb2FkIGEgZmlsZSBidXQgZm9yZ290XG4gICAgICAvLyB0byBwcm92aWRlIHgtcGFyc2UtYXBwLWlkIGluIGhlYWRlciBhbmQgcGFyc2UgYSBiaW5hcnkgZmlsZSB3aWxsIGZhaWxcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcS5ib2R5ID0gSlNPTi5wYXJzZShyZXEuYm9keSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gICAgICB9XG4gICAgICBmaWxlVmlhSlNPTiA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHJlcS5ib2R5KSB7XG4gICAgICBkZWxldGUgcmVxLmJvZHkuX1Jldm9jYWJsZVNlc3Npb247XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcmVxLmJvZHkgJiZcbiAgICAgIHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkICYmXG4gICAgICBBcHBDYWNoZS5nZXQocmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQpICYmXG4gICAgICAoIWluZm8ubWFzdGVyS2V5IHx8IEFwcENhY2hlLmdldChyZXEuYm9keS5fQXBwbGljYXRpb25JZCkubWFzdGVyS2V5ID09PSBpbmZvLm1hc3RlcktleSlcbiAgICApIHtcbiAgICAgIGluZm8uYXBwSWQgPSByZXEuYm9keS5fQXBwbGljYXRpb25JZDtcbiAgICAgIGluZm8uamF2YXNjcmlwdEtleSA9IHJlcS5ib2R5Ll9KYXZhU2NyaXB0S2V5IHx8ICcnO1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkO1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9KYXZhU2NyaXB0S2V5O1xuICAgICAgLy8gVE9ETzogdGVzdCB0aGF0IHRoZSBSRVNUIEFQSSBmb3JtYXRzIGdlbmVyYXRlZCBieSB0aGUgb3RoZXJcbiAgICAgIC8vIFNES3MgYXJlIGhhbmRsZWQgb2tcbiAgICAgIGlmIChyZXEuYm9keS5fQ2xpZW50VmVyc2lvbikge1xuICAgICAgICBpbmZvLmNsaWVudFZlcnNpb24gPSByZXEuYm9keS5fQ2xpZW50VmVyc2lvbjtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9DbGllbnRWZXJzaW9uO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZCkge1xuICAgICAgICBpbmZvLmluc3RhbGxhdGlvbklkID0gcmVxLmJvZHkuX0luc3RhbGxhdGlvbklkO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0luc3RhbGxhdGlvbklkO1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW4pIHtcbiAgICAgICAgaW5mby5zZXNzaW9uVG9rZW4gPSByZXEuYm9keS5fU2Vzc2lvblRva2VuO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX1Nlc3Npb25Ub2tlbjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fTWFzdGVyS2V5KSB7XG4gICAgICAgIGluZm8ubWFzdGVyS2V5ID0gcmVxLmJvZHkuX01hc3RlcktleTtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9NYXN0ZXJLZXk7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX2NvbnRleHQpIHtcbiAgICAgICAgaWYgKHJlcS5ib2R5Ll9jb250ZXh0IGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgICAgaW5mby5jb250ZXh0ID0gcmVxLmJvZHkuX2NvbnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGluZm8uY29udGV4dCA9IEpTT04ucGFyc2UocmVxLmJvZHkuX2NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbmZvLmNvbnRleHQpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgICAgICAgICB0aHJvdyAnQ29udGV4dCBpcyBub3QgYW4gb2JqZWN0JztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gbWFsZm9ybWVkQ29udGV4dChyZXEsIHJlcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fY29udGV4dDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fQ29udGVudFR5cGUpIHtcbiAgICAgICAgcmVxLmhlYWRlcnNbJ2NvbnRlbnQtdHlwZSddID0gcmVxLmJvZHkuX0NvbnRlbnRUeXBlO1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX0NvbnRlbnRUeXBlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpbmZvLnNlc3Npb25Ub2tlbiAmJiB0eXBlb2YgaW5mby5zZXNzaW9uVG9rZW4gIT09ICdzdHJpbmcnKSB7XG4gICAgaW5mby5zZXNzaW9uVG9rZW4gPSBpbmZvLnNlc3Npb25Ub2tlbi50b1N0cmluZygpO1xuICB9XG5cbiAgaWYgKGluZm8uY2xpZW50VmVyc2lvbikge1xuICAgIGluZm8uY2xpZW50U0RLID0gQ2xpZW50U0RLLmZyb21TdHJpbmcoaW5mby5jbGllbnRWZXJzaW9uKTtcbiAgfVxuXG4gIGlmIChmaWxlVmlhSlNPTikge1xuICAgIHJlcS5maWxlRGF0YSA9IHJlcS5ib2R5LmZpbGVEYXRhO1xuICAgIC8vIFdlIG5lZWQgdG8gcmVwb3B1bGF0ZSByZXEuYm9keSB3aXRoIGEgYnVmZmVyXG4gICAgdmFyIGJhc2U2NCA9IHJlcS5ib2R5LmJhc2U2NDtcbiAgICByZXEuYm9keSA9IEJ1ZmZlci5mcm9tKGJhc2U2NCwgJ2Jhc2U2NCcpO1xuICB9XG5cbiAgY29uc3QgY2xpZW50SXAgPSBnZXRDbGllbnRJcChyZXEpO1xuXG4gIGluZm8uYXBwID0gQXBwQ2FjaGUuZ2V0KGluZm8uYXBwSWQpO1xuICByZXEuY29uZmlnID0gQ29uZmlnLmdldChpbmZvLmFwcElkLCBtb3VudCk7XG4gIHJlcS5jb25maWcuaGVhZGVycyA9IHJlcS5oZWFkZXJzIHx8IHt9O1xuICByZXEuY29uZmlnLmlwID0gY2xpZW50SXA7XG4gIHJlcS5pbmZvID0gaW5mbztcblxuICBpZiAoXG4gICAgaW5mby5tYXN0ZXJLZXkgJiZcbiAgICByZXEuY29uZmlnLm1hc3RlcktleUlwcyAmJlxuICAgIHJlcS5jb25maWcubWFzdGVyS2V5SXBzLmxlbmd0aCAhPT0gMCAmJlxuICAgIHJlcS5jb25maWcubWFzdGVyS2V5SXBzLmluZGV4T2YoY2xpZW50SXApID09PSAtMVxuICApIHtcbiAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICB9XG5cbiAgdmFyIGlzTWFzdGVyID0gaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcubWFzdGVyS2V5O1xuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiB0cnVlLFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgaXNSZWFkT25seU1hc3RlciA9IGluZm8ubWFzdGVyS2V5ID09PSByZXEuY29uZmlnLnJlYWRPbmx5TWFzdGVyS2V5O1xuICBpZiAoXG4gICAgdHlwZW9mIHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkgIT0gJ3VuZGVmaW5lZCcgJiZcbiAgICByZXEuY29uZmlnLnJlYWRPbmx5TWFzdGVyS2V5ICYmXG4gICAgaXNSZWFkT25seU1hc3RlclxuICApIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogdHJ1ZSxcbiAgICAgIGlzUmVhZE9ubHk6IHRydWUsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIENsaWVudCBrZXlzIGFyZSBub3QgcmVxdWlyZWQgaW4gcGFyc2Utc2VydmVyLCBidXQgaWYgYW55IGhhdmUgYmVlbiBjb25maWd1cmVkIGluIHRoZSBzZXJ2ZXIsIHZhbGlkYXRlIHRoZW1cbiAgLy8gIHRvIHByZXNlcnZlIG9yaWdpbmFsIGJlaGF2aW9yLlxuICBjb25zdCBrZXlzID0gWydjbGllbnRLZXknLCAnamF2YXNjcmlwdEtleScsICdkb3ROZXRLZXknLCAncmVzdEFQSUtleSddO1xuICBjb25zdCBvbmVLZXlDb25maWd1cmVkID0ga2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gcmVxLmNvbmZpZ1trZXldICE9PSB1bmRlZmluZWQ7XG4gIH0pO1xuICBjb25zdCBvbmVLZXlNYXRjaGVzID0ga2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gcmVxLmNvbmZpZ1trZXldICE9PSB1bmRlZmluZWQgJiYgaW5mb1trZXldID09PSByZXEuY29uZmlnW2tleV07XG4gIH0pO1xuXG4gIGlmIChvbmVLZXlDb25maWd1cmVkICYmICFvbmVLZXlNYXRjaGVzKSB7XG4gICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgfVxuXG4gIGlmIChyZXEudXJsID09ICcvbG9naW4nKSB7XG4gICAgZGVsZXRlIGluZm8uc2Vzc2lvblRva2VuO1xuICB9XG5cbiAgaWYgKHJlcS51c2VyRnJvbUpXVCkge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICAgIHVzZXI6IHJlcS51c2VyRnJvbUpXVCxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFpbmZvLnNlc3Npb25Ub2tlbikge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gaGFuZGxlIHRoZSB1cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uIHBhdGggb24gaXQncyBvd25cbiAgICAgIGlmIChcbiAgICAgICAgaW5mby5zZXNzaW9uVG9rZW4gJiZcbiAgICAgICAgcmVxLnVybCA9PT0gJy91cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uJyAmJlxuICAgICAgICBpbmZvLnNlc3Npb25Ub2tlbi5pbmRleE9mKCdyOicpICE9IDBcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gYXV0aC5nZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuKHtcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgc2Vzc2lvblRva2VuOiBpbmZvLnNlc3Npb25Ub2tlbixcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYXV0aC5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHtcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgc2Vzc2lvblRva2VuOiBpbmZvLnNlc3Npb25Ub2tlbixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSlcbiAgICAudGhlbihhdXRoID0+IHtcbiAgICAgIGlmIChhdXRoKSB7XG4gICAgICAgIHJlcS5hdXRoID0gYXV0aDtcbiAgICAgICAgbmV4dCgpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUT0RPOiBEZXRlcm1pbmUgdGhlIGNvcnJlY3QgZXJyb3Igc2NlbmFyaW8uXG4gICAgICAgIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlci5lcnJvcignZXJyb3IgZ2V0dGluZyBhdXRoIGZvciBzZXNzaW9uVG9rZW4nLCBlcnJvcik7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5VTktOT1dOX0VSUk9SLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldENsaWVudElwKHJlcSkge1xuICBpZiAocmVxLmhlYWRlcnNbJ3gtZm9yd2FyZGVkLWZvciddKSB7XG4gICAgLy8gdHJ5IHRvIGdldCBmcm9tIHgtZm9yd2FyZWQtZm9yIGlmIGl0IHNldCAoYmVoaW5kIHJldmVyc2UgcHJveHkpXG4gICAgcmV0dXJuIHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXS5zcGxpdCgnLCcpWzBdO1xuICB9IGVsc2UgaWYgKHJlcS5jb25uZWN0aW9uICYmIHJlcS5jb25uZWN0aW9uLnJlbW90ZUFkZHJlc3MpIHtcbiAgICAvLyBubyBwcm94eSwgdHJ5IGdldHRpbmcgZnJvbSBjb25uZWN0aW9uLnJlbW90ZUFkZHJlc3NcbiAgICByZXR1cm4gcmVxLmNvbm5lY3Rpb24ucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIGlmIChyZXEuc29ja2V0KSB7XG4gICAgLy8gdHJ5IHRvIGdldCBpdCBmcm9tIHJlcS5zb2NrZXRcbiAgICByZXR1cm4gcmVxLnNvY2tldC5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2UgaWYgKHJlcS5jb25uZWN0aW9uICYmIHJlcS5jb25uZWN0aW9uLnNvY2tldCkge1xuICAgIC8vIHRyeSB0byBnZXQgaXQgZm9ybSB0aGUgY29ubmVjdGlvbi5zb2NrZXRcbiAgICByZXR1cm4gcmVxLmNvbm5lY3Rpb24uc29ja2V0LnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSB7XG4gICAgLy8gaWYgbm9uIGFib3ZlLCBmYWxsYmFjay5cbiAgICByZXR1cm4gcmVxLmlwO1xuICB9XG59XG5cbmZ1bmN0aW9uIGh0dHBBdXRoKHJlcSkge1xuICBpZiAoIShyZXEucmVxIHx8IHJlcSkuaGVhZGVycy5hdXRob3JpemF0aW9uKSByZXR1cm47XG5cbiAgdmFyIGhlYWRlciA9IChyZXEucmVxIHx8IHJlcSkuaGVhZGVycy5hdXRob3JpemF0aW9uO1xuICB2YXIgYXBwSWQsIG1hc3RlcktleSwgamF2YXNjcmlwdEtleTtcblxuICAvLyBwYXJzZSBoZWFkZXJcbiAgdmFyIGF1dGhQcmVmaXggPSAnYmFzaWMgJztcblxuICB2YXIgbWF0Y2ggPSBoZWFkZXIudG9Mb3dlckNhc2UoKS5pbmRleE9mKGF1dGhQcmVmaXgpO1xuXG4gIGlmIChtYXRjaCA9PSAwKSB7XG4gICAgdmFyIGVuY29kZWRBdXRoID0gaGVhZGVyLnN1YnN0cmluZyhhdXRoUHJlZml4Lmxlbmd0aCwgaGVhZGVyLmxlbmd0aCk7XG4gICAgdmFyIGNyZWRlbnRpYWxzID0gZGVjb2RlQmFzZTY0KGVuY29kZWRBdXRoKS5zcGxpdCgnOicpO1xuXG4gICAgaWYgKGNyZWRlbnRpYWxzLmxlbmd0aCA9PSAyKSB7XG4gICAgICBhcHBJZCA9IGNyZWRlbnRpYWxzWzBdO1xuICAgICAgdmFyIGtleSA9IGNyZWRlbnRpYWxzWzFdO1xuXG4gICAgICB2YXIganNLZXlQcmVmaXggPSAnamF2YXNjcmlwdC1rZXk9JztcblxuICAgICAgdmFyIG1hdGNoS2V5ID0ga2V5LmluZGV4T2YoanNLZXlQcmVmaXgpO1xuICAgICAgaWYgKG1hdGNoS2V5ID09IDApIHtcbiAgICAgICAgamF2YXNjcmlwdEtleSA9IGtleS5zdWJzdHJpbmcoanNLZXlQcmVmaXgubGVuZ3RoLCBrZXkubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hc3RlcktleSA9IGtleTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBhcHBJZDogYXBwSWQsIG1hc3RlcktleTogbWFzdGVyS2V5LCBqYXZhc2NyaXB0S2V5OiBqYXZhc2NyaXB0S2V5IH07XG59XG5cbmZ1bmN0aW9uIGRlY29kZUJhc2U2NChzdHIpIHtcbiAgcmV0dXJuIEJ1ZmZlci5mcm9tKHN0ciwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd0Nyb3NzRG9tYWluKGFwcElkKSB7XG4gIHJldHVybiAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkLCBnZXRNb3VudEZvclJlcXVlc3QocmVxKSk7XG4gICAgbGV0IGFsbG93SGVhZGVycyA9IERFRkFVTFRfQUxMT1dFRF9IRUFERVJTO1xuICAgIGlmIChjb25maWcgJiYgY29uZmlnLmFsbG93SGVhZGVycykge1xuICAgICAgYWxsb3dIZWFkZXJzICs9IGAsICR7Y29uZmlnLmFsbG93SGVhZGVycy5qb2luKCcsICcpfWA7XG4gICAgfVxuICAgIGNvbnN0IGFsbG93T3JpZ2luID0gKGNvbmZpZyAmJiBjb25maWcuYWxsb3dPcmlnaW4pIHx8ICcqJztcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nLCBhbGxvd09yaWdpbik7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcycsICdHRVQsUFVULFBPU1QsREVMRVRFLE9QVElPTlMnKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJywgYWxsb3dIZWFkZXJzKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1FeHBvc2UtSGVhZGVycycsICdYLVBhcnNlLUpvYi1TdGF0dXMtSWQsIFgtUGFyc2UtUHVzaC1TdGF0dXMtSWQnKTtcbiAgICAvLyBpbnRlcmNlcHQgT1BUSU9OUyBtZXRob2RcbiAgICBpZiAoJ09QVElPTlMnID09IHJlcS5tZXRob2QpIHtcbiAgICAgIHJlcy5zZW5kU3RhdHVzKDIwMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5leHQoKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhbGxvd01ldGhvZE92ZXJyaWRlKHJlcSwgcmVzLCBuZXh0KSB7XG4gIGlmIChyZXEubWV0aG9kID09PSAnUE9TVCcgJiYgcmVxLmJvZHkuX21ldGhvZCkge1xuICAgIHJlcS5vcmlnaW5hbE1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gICAgcmVxLm1ldGhvZCA9IHJlcS5ib2R5Ll9tZXRob2Q7XG4gICAgZGVsZXRlIHJlcS5ib2R5Ll9tZXRob2Q7XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUGFyc2VFcnJvcnMoZXJyLCByZXEsIHJlcywgbmV4dCkge1xuICBjb25zdCBsb2cgPSAocmVxLmNvbmZpZyAmJiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIpIHx8IGRlZmF1bHRMb2dnZXI7XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgIGlmIChyZXEuY29uZmlnICYmIHJlcS5jb25maWcuZW5hYmxlRXhwcmVzc0Vycm9ySGFuZGxlcikge1xuICAgICAgcmV0dXJuIG5leHQoZXJyKTtcbiAgICB9XG4gICAgbGV0IGh0dHBTdGF0dXM7XG4gICAgLy8gVE9ETzogZmlsbCBvdXQgdGhpcyBtYXBwaW5nXG4gICAgc3dpdGNoIChlcnIuY29kZSkge1xuICAgICAgY2FzZSBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1I6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA1MDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EOlxuICAgICAgICBodHRwU3RhdHVzID0gNDA0O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA0MDA7XG4gICAgfVxuICAgIHJlcy5zdGF0dXMoaHR0cFN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBjb2RlOiBlcnIuY29kZSwgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgIGxvZy5lcnJvcignUGFyc2UgZXJyb3I6ICcsIGVycik7XG4gIH0gZWxzZSBpZiAoZXJyLnN0YXR1cyAmJiBlcnIubWVzc2FnZSkge1xuICAgIHJlcy5zdGF0dXMoZXJyLnN0YXR1cyk7XG4gICAgcmVzLmpzb24oeyBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgaWYgKCEocHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HKSkge1xuICAgICAgbmV4dChlcnIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBsb2cuZXJyb3IoJ1VuY2F1Z2h0IGludGVybmFsIHNlcnZlciBlcnJvci4nLCBlcnIsIGVyci5zdGFjayk7XG4gICAgcmVzLnN0YXR1cyg1MDApO1xuICAgIHJlcy5qc29uKHtcbiAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgIG1lc3NhZ2U6ICdJbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJyxcbiAgICB9KTtcbiAgICBpZiAoIShwcm9jZXNzICYmIHByb2Nlc3MuZW52LlRFU1RJTkcpKSB7XG4gICAgICBuZXh0KGVycik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcSwgcmVzLCBuZXh0KSB7XG4gIGlmICghcmVxLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXMuc3RhdHVzKDQwMyk7XG4gICAgcmVzLmVuZCgne1wiZXJyb3JcIjpcInVuYXV0aG9yaXplZDogbWFzdGVyIGtleSBpcyByZXF1aXJlZFwifScpO1xuICAgIHJldHVybjtcbiAgfVxuICBuZXh0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyhyZXF1ZXN0KSB7XG4gIGlmICghcmVxdWVzdC5hdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5zdGF0dXMgPSA0MDM7XG4gICAgZXJyb3IubWVzc2FnZSA9ICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnO1xuICAgIHRocm93IGVycm9yO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLyoqXG4gKiBEZWR1cGxpY2F0ZXMgYSByZXF1ZXN0IHRvIGVuc3VyZSBpZGVtcG90ZW5jeS4gRHVwbGljYXRlcyBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgcmVxdWVzdCBJRFxuICogaW4gdGhlIHJlcXVlc3QgaGVhZGVyLiBJZiBhIHJlcXVlc3QgaGFzIG5vIHJlcXVlc3QgSUQsIGl0IGlzIGV4ZWN1dGVkIGFueXdheS5cbiAqIEBwYXJhbSB7Kn0gcmVxIFRoZSByZXF1ZXN0IHRvIGV2YWx1YXRlLlxuICogQHJldHVybnMgUHJvbWlzZTx7fT5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeShyZXEpIHtcbiAgLy8gRW5hYmxlIGZlYXR1cmUgb25seSBmb3IgTW9uZ29EQlxuICBpZiAoXG4gICAgIShcbiAgICAgIHJlcS5jb25maWcuZGF0YWJhc2UuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXIgfHxcbiAgICAgIHJlcS5jb25maWcuZGF0YWJhc2UuYWRhcHRlciBpbnN0YW5jZW9mIFBvc3RncmVzU3RvcmFnZUFkYXB0ZXJcbiAgICApXG4gICkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBHZXQgcGFyYW1ldGVyc1xuICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICBjb25zdCByZXF1ZXN0SWQgPSAoKHJlcSB8fCB7fSkuaGVhZGVycyB8fCB7fSlbJ3gtcGFyc2UtcmVxdWVzdC1pZCddO1xuICBjb25zdCB7IHBhdGhzLCB0dGwgfSA9IGNvbmZpZy5pZGVtcG90ZW5jeU9wdGlvbnM7XG4gIGlmICghcmVxdWVzdElkIHx8ICFjb25maWcuaWRlbXBvdGVuY3lPcHRpb25zKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFJlcXVlc3QgcGF0aCBtYXkgY29udGFpbiB0cmFpbGluZyBzbGFzaGVzLCBkZXBlbmRpbmcgb24gdGhlIG9yaWdpbmFsIHJlcXVlc3QsIHNvIHJlbW92ZVxuICAvLyBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaGVzIHRvIG1ha2UgaXQgZWFzaWVyIHRvIHNwZWNpZnkgcGF0aHMgaW4gdGhlIGNvbmZpZ3VyYXRpb25cbiAgY29uc3QgcmVxUGF0aCA9IHJlcS5wYXRoLnJlcGxhY2UoL15cXC98XFwvJC8sICcnKTtcbiAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgaWRlbXBvdGVuY3kgaXMgZW5hYmxlZCBmb3IgY3VycmVudCByZXF1ZXN0IHBhdGhcbiAgbGV0IG1hdGNoID0gZmFsc2U7XG4gIGZvciAoY29uc3QgcGF0aCBvZiBwYXRocykge1xuICAgIC8vIEFzc3VtZSBvbmUgd2FudHMgYSBwYXRoIHRvIGFsd2F5cyBtYXRjaCBmcm9tIHRoZSBiZWdpbm5pbmcgdG8gcHJldmVudCBhbnkgbWlzdGFrZXNcbiAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAocGF0aC5jaGFyQXQoMCkgPT09ICdeJyA/IHBhdGggOiAnXicgKyBwYXRoKTtcbiAgICBpZiAocmVxUGF0aC5tYXRjaChyZWdleCkpIHtcbiAgICAgIG1hdGNoID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFRyeSB0byBzdG9yZSByZXF1ZXN0XG4gIGNvbnN0IGV4cGlyeURhdGUgPSBuZXcgRGF0ZShuZXcgRGF0ZSgpLnNldFNlY29uZHMobmV3IERhdGUoKS5nZXRTZWNvbmRzKCkgKyB0dGwpKTtcbiAgcmV0dXJuIHJlc3RcbiAgICAuY3JlYXRlKGNvbmZpZywgYXV0aC5tYXN0ZXIoY29uZmlnKSwgJ19JZGVtcG90ZW5jeScsIHtcbiAgICAgIHJlcUlkOiByZXF1ZXN0SWQsXG4gICAgICBleHBpcmU6IFBhcnNlLl9lbmNvZGUoZXhwaXJ5RGF0ZSksXG4gICAgfSlcbiAgICAuY2F0Y2goZSA9PiB7XG4gICAgICBpZiAoZS5jb2RlID09IFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1JFUVVFU1QsICdEdXBsaWNhdGUgcmVxdWVzdCcpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpIHtcbiAgcmVzLnN0YXR1cyg0MDMpO1xuICByZXMuZW5kKCd7XCJlcnJvclwiOlwidW5hdXRob3JpemVkXCJ9Jyk7XG59XG5cbmZ1bmN0aW9uIG1hbGZvcm1lZENvbnRleHQocmVxLCByZXMpIHtcbiAgcmVzLnN0YXR1cyg0MDApO1xuICByZXMuanNvbih7IGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgZXJyb3I6ICdJbnZhbGlkIG9iamVjdCBmb3IgY29udGV4dC4nIH0pO1xufVxuIl19
|
|
525
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImNvbnRleHQiLCJKU09OIiwicGFyc2UiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJlIiwibWFsZm9ybWVkQ29udGV4dCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiYmFzaWNBdXRoIiwiaHR0cEF1dGgiLCJiYXNpY0F1dGhBcHBJZCIsIkFwcENhY2hlIiwiYm9keSIsIl9ub0JvZHkiLCJmaWxlVmlhSlNPTiIsIkJ1ZmZlciIsImludmFsaWRSZXF1ZXN0IiwiX1Jldm9jYWJsZVNlc3Npb24iLCJfQXBwbGljYXRpb25JZCIsIl9KYXZhU2NyaXB0S2V5IiwiX0NsaWVudFZlcnNpb24iLCJfSW5zdGFsbGF0aW9uSWQiLCJfU2Vzc2lvblRva2VuIiwiX01hc3RlcktleSIsIl9jb250ZXh0IiwiX0NvbnRlbnRUeXBlIiwiaGVhZGVycyIsImNsaWVudFNESyIsIkNsaWVudFNESyIsImZyb21TdHJpbmciLCJmaWxlRGF0YSIsImJhc2U2NCIsImZyb20iLCJjbGllbnRJcCIsImdldENsaWVudElwIiwiY29uZmlnIiwiQ29uZmlnIiwic3RhdGUiLCJzdGF0dXMiLCJqc29uIiwiY29kZSIsIlBhcnNlIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJlcnJvciIsImFwcCIsImlwIiwiaXNNYXN0ZXIiLCJpcFJhbmdlQ2hlY2siLCJtYXN0ZXJLZXlJcHMiLCJsb2ciLCJsb2dnZXJDb250cm9sbGVyIiwiZGVmYXVsdExvZ2dlciIsImF1dGgiLCJBdXRoIiwiaGFuZGxlUmF0ZUxpbWl0IiwiaXNSZWFkT25seU1hc3RlciIsInJlYWRPbmx5TWFzdGVyS2V5IiwiaXNSZWFkT25seSIsImtleXMiLCJvbmVLZXlDb25maWd1cmVkIiwic29tZSIsImtleSIsInVuZGVmaW5lZCIsIm9uZUtleU1hdGNoZXMiLCJ1c2VyRnJvbUpXVCIsInVzZXIiLCJyYXRlTGltaXRzIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsImxpbWl0IiwicGF0aEV4cCIsIlJlZ0V4cCIsInBhdGgiLCJ0ZXN0IiwiaGFuZGxlciIsImVyciIsIkNPTk5FQ1RJT05fRkFJTEVEIiwiaGFuZGxlUGFyc2VTZXNzaW9uIiwicmVxdWVzdEF1dGgiLCJpbmRleE9mIiwiZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJVTktOT1dOX0VSUk9SIiwiYXV0aG9yaXphdGlvbiIsImhlYWRlciIsImF1dGhQcmVmaXgiLCJtYXRjaCIsInRvTG93ZXJDYXNlIiwiZW5jb2RlZEF1dGgiLCJzdWJzdHJpbmciLCJjcmVkZW50aWFscyIsImRlY29kZUJhc2U2NCIsInNwbGl0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYWxsb3dPcmlnaW4iLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZW5hYmxlRXhwcmVzc0Vycm9ySGFuZGxlciIsImh0dHBTdGF0dXMiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwibWVzc2FnZSIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwic3RhY2siLCJlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiZW5kIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXF1ZXN0IiwicmVzb2x2ZSIsImFkZFJhdGVMaW1pdCIsInJvdXRlIiwiUmF0ZUxpbWl0T3B0aW9ucyIsInB1c2giLCJwYXRoVG9SZWdleHAiLCJyZXF1ZXN0UGF0aCIsInJhdGVMaW1pdCIsIndpbmRvd01zIiwicmVxdWVzdFRpbWVXaW5kb3ciLCJtYXgiLCJyZXF1ZXN0Q291bnQiLCJlcnJvclJlc3BvbnNlTWVzc2FnZSIsImRlZmF1bHQiLCJyZXNwb25zZSIsIm9wdGlvbnMiLCJza2lwIiwiaW5jbHVkZUludGVybmFsUmVxdWVzdHMiLCJpbmNsdWRlTWFzdGVyS2V5IiwicmVxdWVzdE1ldGhvZHMiLCJBcnJheSIsImlzQXJyYXkiLCJpbmNsdWRlcyIsInJlZ0V4cCIsImtleUdlbmVyYXRvciIsInB1dCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImRhdGFiYXNlIiwiYWRhcHRlciIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIiwicmVxdWVzdElkIiwicGF0aHMiLCJ0dGwiLCJpZGVtcG90ZW5jeU9wdGlvbnMiLCJyZXFQYXRoIiwicmVwbGFjZSIsInJlZ2V4IiwiY2hhckF0IiwiZXhwaXJ5RGF0ZSIsIkRhdGUiLCJzZXRTZWNvbmRzIiwiZ2V0U2Vjb25kcyIsInJlc3QiLCJjcmVhdGUiLCJtYXN0ZXIiLCJyZXFJZCIsImV4cGlyZSIsIl9lbmNvZGUiLCJjYXRjaCIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIiwiSU5WQUxJRF9KU09OIl0sInNvdXJjZXMiOlsiLi4vc3JjL21pZGRsZXdhcmVzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBhdXRoIGZyb20gJy4vQXV0aCc7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vQ29uZmlnJztcbmltcG9ydCBDbGllbnRTREsgZnJvbSAnLi9DbGllbnRTREsnO1xuaW1wb3J0IGRlZmF1bHRMb2dnZXIgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi9yZXN0JztcbmltcG9ydCBNb25nb1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvU3RvcmFnZS9Qb3N0Z3Jlcy9Qb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCByYXRlTGltaXQgZnJvbSAnZXhwcmVzcy1yYXRlLWxpbWl0JztcbmltcG9ydCB7IFJhdGVMaW1pdE9wdGlvbnMgfSBmcm9tICcuL09wdGlvbnMvRGVmaW5pdGlvbnMnO1xuaW1wb3J0IHBhdGhUb1JlZ2V4cCBmcm9tICdwYXRoLXRvLXJlZ2V4cCc7XG5pbXBvcnQgaXBSYW5nZUNoZWNrIGZyb20gJ2lwLXJhbmdlLWNoZWNrJztcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQUxMT1dFRF9IRUFERVJTID1cbiAgJ1gtUGFyc2UtTWFzdGVyLUtleSwgWC1QYXJzZS1SRVNULUFQSS1LZXksIFgtUGFyc2UtSmF2YXNjcmlwdC1LZXksIFgtUGFyc2UtQXBwbGljYXRpb24tSWQsIFgtUGFyc2UtQ2xpZW50LVZlcnNpb24sIFgtUGFyc2UtU2Vzc2lvbi1Ub2tlbiwgWC1SZXF1ZXN0ZWQtV2l0aCwgWC1QYXJzZS1SZXZvY2FibGUtU2Vzc2lvbiwgWC1QYXJzZS1SZXF1ZXN0LUlkLCBDb250ZW50LVR5cGUsIFByYWdtYSwgQ2FjaGUtQ29udHJvbCc7XG5cbmNvbnN0IGdldE1vdW50Rm9yUmVxdWVzdCA9IGZ1bmN0aW9uIChyZXEpIHtcbiAgY29uc3QgbW91bnRQYXRoTGVuZ3RoID0gcmVxLm9yaWdpbmFsVXJsLmxlbmd0aCAtIHJlcS51cmwubGVuZ3RoO1xuICBjb25zdCBtb3VudFBhdGggPSByZXEub3JpZ2luYWxVcmwuc2xpY2UoMCwgbW91bnRQYXRoTGVuZ3RoKTtcbiAgcmV0dXJuIHJlcS5wcm90b2NvbCArICc6Ly8nICsgcmVxLmdldCgnaG9zdCcpICsgbW91bnRQYXRoO1xufTtcblxuLy8gQ2hlY2tzIHRoYXQgdGhlIHJlcXVlc3QgaXMgYXV0aG9yaXplZCBmb3IgdGhpcyBhcHAgYW5kIGNoZWNrcyB1c2VyXG4vLyBhdXRoIHRvby5cbi8vIFRoZSBib2R5cGFyc2VyIHNob3VsZCBydW4gYmVmb3JlIHRoaXMgbWlkZGxld2FyZS5cbi8vIEFkZHMgaW5mbyB0byB0aGUgcmVxdWVzdDpcbi8vIHJlcS5jb25maWcgLSB0aGUgQ29uZmlnIGZvciB0aGlzIGFwcFxuLy8gcmVxLmF1dGggLSB0aGUgQXV0aCBmb3IgdGhpcyByZXF1ZXN0XG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlUGFyc2VIZWFkZXJzKHJlcSwgcmVzLCBuZXh0KSB7XG4gIHZhciBtb3VudCA9IGdldE1vdW50Rm9yUmVxdWVzdChyZXEpO1xuXG4gIGxldCBjb250ZXh0ID0ge307XG4gIGlmIChyZXEuZ2V0KCdYLVBhcnNlLUNsb3VkLUNvbnRleHQnKSAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRleHQgPSBKU09OLnBhcnNlKHJlcS5nZXQoJ1gtUGFyc2UtQ2xvdWQtQ29udGV4dCcpKTtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoY29udGV4dCkgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICAgIHRocm93ICdDb250ZXh0IGlzIG5vdCBhbiBvYmplY3QnO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBtYWxmb3JtZWRDb250ZXh0KHJlcSwgcmVzKTtcbiAgICB9XG4gIH1cbiAgdmFyIGluZm8gPSB7XG4gICAgYXBwSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnKSxcbiAgICBzZXNzaW9uVG9rZW46IHJlcS5nZXQoJ1gtUGFyc2UtU2Vzc2lvbi1Ub2tlbicpLFxuICAgIG1hc3RlcktleTogcmVxLmdldCgnWC1QYXJzZS1NYXN0ZXItS2V5JyksXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5nZXQoJ1gtUGFyc2UtSW5zdGFsbGF0aW9uLUlkJyksXG4gICAgY2xpZW50S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1LZXknKSxcbiAgICBqYXZhc2NyaXB0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLUphdmFzY3JpcHQtS2V5JyksXG4gICAgZG90TmV0S2V5OiByZXEuZ2V0KCdYLVBhcnNlLVdpbmRvd3MtS2V5JyksXG4gICAgcmVzdEFQSUtleTogcmVxLmdldCgnWC1QYXJzZS1SRVNULUFQSS1LZXknKSxcbiAgICBjbGllbnRWZXJzaW9uOiByZXEuZ2V0KCdYLVBhcnNlLUNsaWVudC1WZXJzaW9uJyksXG4gICAgY29udGV4dDogY29udGV4dCxcbiAgfTtcblxuICB2YXIgYmFzaWNBdXRoID0gaHR0cEF1dGgocmVxKTtcblxuICBpZiAoYmFzaWNBdXRoKSB7XG4gICAgdmFyIGJhc2ljQXV0aEFwcElkID0gYmFzaWNBdXRoLmFwcElkO1xuICAgIGlmIChBcHBDYWNoZS5nZXQoYmFzaWNBdXRoQXBwSWQpKSB7XG4gICAgICBpbmZvLmFwcElkID0gYmFzaWNBdXRoQXBwSWQ7XG4gICAgICBpbmZvLm1hc3RlcktleSA9IGJhc2ljQXV0aC5tYXN0ZXJLZXkgfHwgaW5mby5tYXN0ZXJLZXk7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSBiYXNpY0F1dGguamF2YXNjcmlwdEtleSB8fCBpbmZvLmphdmFzY3JpcHRLZXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlcS5ib2R5KSB7XG4gICAgLy8gVW5pdHkgU0RLIHNlbmRzIGEgX25vQm9keSBrZXkgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZC5cbiAgICAvLyBVbmNsZWFyIGF0IHRoaXMgcG9pbnQgaWYgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuLlxuICAgIGRlbGV0ZSByZXEuYm9keS5fbm9Cb2R5O1xuICB9XG5cbiAgdmFyIGZpbGVWaWFKU09OID0gZmFsc2U7XG5cbiAgaWYgKCFpbmZvLmFwcElkIHx8ICFBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCkpIHtcbiAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgdGhlIGFwcCBpZCBvbiB0aGUgYm9keS5cbiAgICBpZiAocmVxLmJvZHkgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIC8vIFRoZSBvbmx5IGNoYW5jZSB0byBmaW5kIHRoZSBhcHAgaWQgaXMgaWYgdGhpcyBpcyBhIGZpbGVcbiAgICAgIC8vIHVwbG9hZCB0aGF0IGFjdHVhbGx5IGlzIGEgSlNPTiBib2R5LiBTbyB0cnkgdG8gcGFyc2UgaXQuXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvNjU4OVxuICAgICAgLy8gSXQgaXMgYWxzbyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgaXMgdHJ5aW5nIHRvIHVwbG9hZCBhIGZpbGUgYnV0IGZvcmdvdFxuICAgICAgLy8gdG8gcHJvdmlkZSB4LXBhcnNlLWFwcC1pZCBpbiBoZWFkZXIgYW5kIHBhcnNlIGEgYmluYXJ5IGZpbGUgd2lsbCBmYWlsXG4gICAgICB0cnkge1xuICAgICAgICByZXEuYm9keSA9IEpTT04ucGFyc2UocmVxLmJvZHkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICAgICAgfVxuICAgICAgZmlsZVZpYUpTT04gPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZXEuYm9keSkge1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9SZXZvY2FibGVTZXNzaW9uO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHJlcS5ib2R5ICYmXG4gICAgICByZXEuYm9keS5fQXBwbGljYXRpb25JZCAmJlxuICAgICAgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKSAmJlxuICAgICAgKCFpbmZvLm1hc3RlcktleSB8fCBBcHBDYWNoZS5nZXQocmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQpLm1hc3RlcktleSA9PT0gaW5mby5tYXN0ZXJLZXkpXG4gICAgKSB7XG4gICAgICBpbmZvLmFwcElkID0gcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSByZXEuYm9keS5fSmF2YVNjcmlwdEtleSB8fCAnJztcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fQXBwbGljYXRpb25JZDtcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fSmF2YVNjcmlwdEtleTtcbiAgICAgIC8vIFRPRE86IHRlc3QgdGhhdCB0aGUgUkVTVCBBUEkgZm9ybWF0cyBnZW5lcmF0ZWQgYnkgdGhlIG90aGVyXG4gICAgICAvLyBTREtzIGFyZSBoYW5kbGVkIG9rXG4gICAgICBpZiAocmVxLmJvZHkuX0NsaWVudFZlcnNpb24pIHtcbiAgICAgICAgaW5mby5jbGllbnRWZXJzaW9uID0gcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ2xpZW50VmVyc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgaW5mby5pbnN0YWxsYXRpb25JZCA9IHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fU2Vzc2lvblRva2VuKSB7XG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuID0gcmVxLmJvZHkuX1Nlc3Npb25Ub2tlbjtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX01hc3RlcktleSkge1xuICAgICAgICBpbmZvLm1hc3RlcktleSA9IHJlcS5ib2R5Ll9NYXN0ZXJLZXk7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9jb250ZXh0KSB7XG4gICAgICAgIGlmIChyZXEuYm9keS5fY29udGV4dCBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAgIGluZm8uY29udGV4dCA9IHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpbmZvLmNvbnRleHQgPSBKU09OLnBhcnNlKHJlcS5ib2R5Ll9jb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5mby5jb250ZXh0KSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgICAgICAgICAgdGhyb3cgJ0NvbnRleHQgaXMgbm90IGFuIG9iamVjdCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIG1hbGZvcm1lZENvbnRleHQocmVxLCByZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX2NvbnRleHQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0NvbnRlbnRUeXBlKSB7XG4gICAgICAgIHJlcS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSA9IHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaW5mby5zZXNzaW9uVG9rZW4gJiYgdHlwZW9mIGluZm8uc2Vzc2lvblRva2VuICE9PSAnc3RyaW5nJykge1xuICAgIGluZm8uc2Vzc2lvblRva2VuID0gaW5mby5zZXNzaW9uVG9rZW4udG9TdHJpbmcoKTtcbiAgfVxuXG4gIGlmIChpbmZvLmNsaWVudFZlcnNpb24pIHtcbiAgICBpbmZvLmNsaWVudFNESyA9IENsaWVudFNESy5mcm9tU3RyaW5nKGluZm8uY2xpZW50VmVyc2lvbik7XG4gIH1cblxuICBpZiAoZmlsZVZpYUpTT04pIHtcbiAgICByZXEuZmlsZURhdGEgPSByZXEuYm9keS5maWxlRGF0YTtcbiAgICAvLyBXZSBuZWVkIHRvIHJlcG9wdWxhdGUgcmVxLmJvZHkgd2l0aCBhIGJ1ZmZlclxuICAgIHZhciBiYXNlNjQgPSByZXEuYm9keS5iYXNlNjQ7XG4gICAgcmVxLmJvZHkgPSBCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKTtcbiAgfVxuXG4gIGNvbnN0IGNsaWVudElwID0gZ2V0Q2xpZW50SXAocmVxKTtcbiAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChpbmZvLmFwcElkLCBtb3VudCk7XG4gIGlmIChjb25maWcuc3RhdGUgJiYgY29uZmlnLnN0YXRlICE9PSAnb2snKSB7XG4gICAgcmVzLnN0YXR1cyg1MDApO1xuICAgIHJlcy5qc29uKHtcbiAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgIGVycm9yOiBgSW52YWxpZCBzZXJ2ZXIgc3RhdGU6ICR7Y29uZmlnLnN0YXRlfWAsXG4gICAgfSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaW5mby5hcHAgPSBBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCk7XG4gIHJlcS5jb25maWcgPSBjb25maWc7XG4gIHJlcS5jb25maWcuaGVhZGVycyA9IHJlcS5oZWFkZXJzIHx8IHt9O1xuICByZXEuY29uZmlnLmlwID0gY2xpZW50SXA7XG4gIHJlcS5pbmZvID0gaW5mbztcblxuICBsZXQgaXNNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5tYXN0ZXJLZXk7XG4gIGlmIChpc01hc3RlciAmJiAhaXBSYW5nZUNoZWNrKGNsaWVudElwLCByZXEuY29uZmlnLm1hc3RlcktleUlwcyB8fCBbXSkpIHtcbiAgICBjb25zdCBsb2cgPSByZXEuY29uZmlnPy5sb2dnZXJDb250cm9sbGVyIHx8IGRlZmF1bHRMb2dnZXI7XG4gICAgbG9nLmVycm9yKFxuICAgICAgYFJlcXVlc3QgdXNpbmcgbWFzdGVyIGtleSByZWplY3RlZCBhcyB0aGUgcmVxdWVzdCBJUCBhZGRyZXNzICcke2NsaWVudElwfScgaXMgbm90IHNldCBpbiBQYXJzZSBTZXJ2ZXIgb3B0aW9uICdtYXN0ZXJLZXlJcHMnLmBcbiAgICApO1xuICAgIGlzTWFzdGVyID0gZmFsc2U7XG4gIH1cblxuICBpZiAoaXNNYXN0ZXIpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogdHJ1ZSxcbiAgICB9KTtcbiAgICByZXR1cm4gaGFuZGxlUmF0ZUxpbWl0KHJlcSwgcmVzLCBuZXh0KTtcbiAgfVxuXG4gIHZhciBpc1JlYWRPbmx5TWFzdGVyID0gaW5mby5tYXN0ZXJLZXkgPT09IHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXk7XG4gIGlmIChcbiAgICB0eXBlb2YgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAhPSAndW5kZWZpbmVkJyAmJlxuICAgIHJlcS5jb25maWcucmVhZE9ubHlNYXN0ZXJLZXkgJiZcbiAgICBpc1JlYWRPbmx5TWFzdGVyXG4gICkge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiB0cnVlLFxuICAgICAgaXNSZWFkT25seTogdHJ1ZSxcbiAgICB9KTtcbiAgICByZXR1cm4gaGFuZGxlUmF0ZUxpbWl0KHJlcSwgcmVzLCBuZXh0KTtcbiAgfVxuXG4gIC8vIENsaWVudCBrZXlzIGFyZSBub3QgcmVxdWlyZWQgaW4gcGFyc2Utc2VydmVyLCBidXQgaWYgYW55IGhhdmUgYmVlbiBjb25maWd1cmVkIGluIHRoZSBzZXJ2ZXIsIHZhbGlkYXRlIHRoZW1cbiAgLy8gIHRvIHByZXNlcnZlIG9yaWdpbmFsIGJlaGF2aW9yLlxuICBjb25zdCBrZXlzID0gWydjbGllbnRLZXknLCAnamF2YXNjcmlwdEtleScsICdkb3ROZXRLZXknLCAncmVzdEFQSUtleSddO1xuICBjb25zdCBvbmVLZXlDb25maWd1cmVkID0ga2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gcmVxLmNvbmZpZ1trZXldICE9PSB1bmRlZmluZWQ7XG4gIH0pO1xuICBjb25zdCBvbmVLZXlNYXRjaGVzID0ga2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gcmVxLmNvbmZpZ1trZXldICE9PSB1bmRlZmluZWQgJiYgaW5mb1trZXldID09PSByZXEuY29uZmlnW2tleV07XG4gIH0pO1xuXG4gIGlmIChvbmVLZXlDb25maWd1cmVkICYmICFvbmVLZXlNYXRjaGVzKSB7XG4gICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgfVxuXG4gIGlmIChyZXEudXJsID09ICcvbG9naW4nKSB7XG4gICAgZGVsZXRlIGluZm8uc2Vzc2lvblRva2VuO1xuICB9XG5cbiAgaWYgKHJlcS51c2VyRnJvbUpXVCkge1xuICAgIHJlcS5hdXRoID0gbmV3IGF1dGguQXV0aCh7XG4gICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICAgIHVzZXI6IHJlcS51c2VyRnJvbUpXVCxcbiAgICB9KTtcbiAgICByZXR1cm4gaGFuZGxlUmF0ZUxpbWl0KHJlcSwgcmVzLCBuZXh0KTtcbiAgfVxuXG4gIGlmICghaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgfSk7XG4gIH1cbiAgaGFuZGxlUmF0ZUxpbWl0KHJlcSwgcmVzLCBuZXh0KTtcbn1cblxuY29uc3QgaGFuZGxlUmF0ZUxpbWl0ID0gYXN5bmMgKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gIGNvbnN0IHJhdGVMaW1pdHMgPSByZXEuY29uZmlnLnJhdGVMaW1pdHMgfHwgW107XG4gIHRyeSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICByYXRlTGltaXRzLm1hcChhc3luYyBsaW1pdCA9PiB7XG4gICAgICAgIGNvbnN0IHBhdGhFeHAgPSBuZXcgUmVnRXhwKGxpbWl0LnBhdGgpO1xuICAgICAgICBpZiAocGF0aEV4cC50ZXN0KHJlcS51cmwpKSB7XG4gICAgICAgICAgYXdhaXQgbGltaXQuaGFuZGxlcihyZXEsIHJlcywgZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmVzLnN0YXR1cyg0MjkpO1xuICAgIHJlcy5qc29uKHsgY29kZTogUGFyc2UuRXJyb3IuQ09OTkVDVElPTl9GQUlMRUQsIGVycm9yIH0pO1xuICAgIHJldHVybjtcbiAgfVxuICBuZXh0KCk7XG59O1xuXG5leHBvcnQgY29uc3QgaGFuZGxlUGFyc2VTZXNzaW9uID0gYXN5bmMgKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgaW5mbyA9IHJlcS5pbmZvO1xuICAgIGlmIChyZXEuYXV0aCkge1xuICAgICAgbmV4dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcmVxdWVzdEF1dGggPSBudWxsO1xuICAgIGlmIChcbiAgICAgIGluZm8uc2Vzc2lvblRva2VuICYmXG4gICAgICByZXEudXJsID09PSAnL3VwZ3JhZGVUb1Jldm9jYWJsZVNlc3Npb24nICYmXG4gICAgICBpbmZvLnNlc3Npb25Ub2tlbi5pbmRleE9mKCdyOicpICE9IDBcbiAgICApIHtcbiAgICAgIHJlcXVlc3RBdXRoID0gYXdhaXQgYXV0aC5nZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuKHtcbiAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogaW5mby5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBpbmZvLnNlc3Npb25Ub2tlbixcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0QXV0aCA9IGF3YWl0IGF1dGguZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7XG4gICAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmVxLmF1dGggPSByZXF1ZXN0QXV0aDtcbiAgICBuZXh0KCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUT0RPOiBEZXRlcm1pbmUgdGhlIGNvcnJlY3QgZXJyb3Igc2NlbmFyaW8uXG4gICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKCdlcnJvciBnZXR0aW5nIGF1dGggZm9yIHNlc3Npb25Ub2tlbicsIGVycm9yKTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVU5LTk9XTl9FUlJPUiwgZXJyb3IpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBnZXRDbGllbnRJcChyZXEpIHtcbiAgcmV0dXJuIHJlcS5pcDtcbn1cblxuZnVuY3Rpb24gaHR0cEF1dGgocmVxKSB7XG4gIGlmICghKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb24pIHJldHVybjtcblxuICB2YXIgaGVhZGVyID0gKHJlcS5yZXEgfHwgcmVxKS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG4gIHZhciBhcHBJZCwgbWFzdGVyS2V5LCBqYXZhc2NyaXB0S2V5O1xuXG4gIC8vIHBhcnNlIGhlYWRlclxuICB2YXIgYXV0aFByZWZpeCA9ICdiYXNpYyAnO1xuXG4gIHZhciBtYXRjaCA9IGhlYWRlci50b0xvd2VyQ2FzZSgpLmluZGV4T2YoYXV0aFByZWZpeCk7XG5cbiAgaWYgKG1hdGNoID09IDApIHtcbiAgICB2YXIgZW5jb2RlZEF1dGggPSBoZWFkZXIuc3Vic3RyaW5nKGF1dGhQcmVmaXgubGVuZ3RoLCBoZWFkZXIubGVuZ3RoKTtcbiAgICB2YXIgY3JlZGVudGlhbHMgPSBkZWNvZGVCYXNlNjQoZW5jb2RlZEF1dGgpLnNwbGl0KCc6Jyk7XG5cbiAgICBpZiAoY3JlZGVudGlhbHMubGVuZ3RoID09IDIpIHtcbiAgICAgIGFwcElkID0gY3JlZGVudGlhbHNbMF07XG4gICAgICB2YXIga2V5ID0gY3JlZGVudGlhbHNbMV07XG5cbiAgICAgIHZhciBqc0tleVByZWZpeCA9ICdqYXZhc2NyaXB0LWtleT0nO1xuXG4gICAgICB2YXIgbWF0Y2hLZXkgPSBrZXkuaW5kZXhPZihqc0tleVByZWZpeCk7XG4gICAgICBpZiAobWF0Y2hLZXkgPT0gMCkge1xuICAgICAgICBqYXZhc2NyaXB0S2V5ID0ga2V5LnN1YnN0cmluZyhqc0tleVByZWZpeC5sZW5ndGgsIGtleS5sZW5ndGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWFzdGVyS2V5ID0ga2V5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGFwcElkOiBhcHBJZCwgbWFzdGVyS2V5OiBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk6IGphdmFzY3JpcHRLZXkgfTtcbn1cblxuZnVuY3Rpb24gZGVjb2RlQmFzZTY0KHN0cikge1xuICByZXR1cm4gQnVmZmVyLmZyb20oc3RyLCAnYmFzZTY0JykudG9TdHJpbmcoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93Q3Jvc3NEb21haW4oYXBwSWQpIHtcbiAgcmV0dXJuIChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwSWQsIGdldE1vdW50Rm9yUmVxdWVzdChyZXEpKTtcbiAgICBsZXQgYWxsb3dIZWFkZXJzID0gREVGQVVMVF9BTExPV0VEX0hFQURFUlM7XG4gICAgaWYgKGNvbmZpZyAmJiBjb25maWcuYWxsb3dIZWFkZXJzKSB7XG4gICAgICBhbGxvd0hlYWRlcnMgKz0gYCwgJHtjb25maWcuYWxsb3dIZWFkZXJzLmpvaW4oJywgJyl9YDtcbiAgICB9XG4gICAgY29uc3QgYWxsb3dPcmlnaW4gPSAoY29uZmlnICYmIGNvbmZpZy5hbGxvd09yaWdpbikgfHwgJyonO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsIGFsbG93T3JpZ2luKTtcbiAgICByZXMuaGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCxQVVQsUE9TVCxERUxFVEUsT1BUSU9OUycpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCBhbGxvd0hlYWRlcnMpO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUV4cG9zZS1IZWFkZXJzJywgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCwgWC1QYXJzZS1QdXNoLVN0YXR1cy1JZCcpO1xuICAgIC8vIGludGVyY2VwdCBPUFRJT05TIG1ldGhvZFxuICAgIGlmICgnT1BUSU9OUycgPT0gcmVxLm1ldGhvZCkge1xuICAgICAgcmVzLnNlbmRTdGF0dXMoMjAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dCgpO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFsbG93TWV0aG9kT3ZlcnJpZGUocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKHJlcS5tZXRob2QgPT09ICdQT1NUJyAmJiByZXEuYm9keS5fbWV0aG9kKSB7XG4gICAgcmVxLm9yaWdpbmFsTWV0aG9kID0gcmVxLm1ldGhvZDtcbiAgICByZXEubWV0aG9kID0gcmVxLmJvZHkuX21ldGhvZDtcbiAgICBkZWxldGUgcmVxLmJvZHkuX21ldGhvZDtcbiAgfVxuICBuZXh0KCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXJzZUVycm9ycyhlcnIsIHJlcSwgcmVzLCBuZXh0KSB7XG4gIGNvbnN0IGxvZyA9IChyZXEuY29uZmlnICYmIHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcikgfHwgZGVmYXVsdExvZ2dlcjtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgaWYgKHJlcS5jb25maWcgJiYgcmVxLmNvbmZpZy5lbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgIH1cbiAgICBsZXQgaHR0cFN0YXR1cztcbiAgICAvLyBUT0RPOiBmaWxsIG91dCB0aGlzIG1hcHBpbmdcbiAgICBzd2l0Y2ggKGVyci5jb2RlKSB7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDUwMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQ6XG4gICAgICAgIGh0dHBTdGF0dXMgPSA0MDQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDQwMDtcbiAgICB9XG4gICAgcmVzLnN0YXR1cyhodHRwU3RhdHVzKTtcbiAgICByZXMuanNvbih7IGNvZGU6IGVyci5jb2RlLCBlcnJvcjogZXJyLm1lc3NhZ2UgfSk7XG4gICAgbG9nLmVycm9yKCdQYXJzZSBlcnJvcjogJywgZXJyKTtcbiAgfSBlbHNlIGlmIChlcnIuc3RhdHVzICYmIGVyci5tZXNzYWdlKSB7XG4gICAgcmVzLnN0YXR1cyhlcnIuc3RhdHVzKTtcbiAgICByZXMuanNvbih7IGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBpZiAoIShwcm9jZXNzICYmIHByb2Nlc3MuZW52LlRFU1RJTkcpKSB7XG4gICAgICBuZXh0KGVycik7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxvZy5lcnJvcignVW5jYXVnaHQgaW50ZXJuYWwgc2VydmVyIGVycm9yLicsIGVyciwgZXJyLnN0YWNrKTtcbiAgICByZXMuc3RhdHVzKDUwMCk7XG4gICAgcmVzLmpzb24oe1xuICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgbWVzc2FnZTogJ0ludGVybmFsIHNlcnZlciBlcnJvci4nLFxuICAgIH0pO1xuICAgIGlmICghKHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYuVEVTVElORykpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxLCByZXMsIG5leHQpIHtcbiAgaWYgKCFyZXEuYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcy5zdGF0dXMoNDAzKTtcbiAgICByZXMuZW5kKCd7XCJlcnJvclwiOlwidW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkXCJ9Jyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzKHJlcXVlc3QpIHtcbiAgaWYgKCFyZXF1ZXN0LmF1dGguaXNNYXN0ZXIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgIGVycm9yLnN0YXR1cyA9IDQwMztcbiAgICBlcnJvci5tZXNzYWdlID0gJ3VuYXV0aG9yaXplZDogbWFzdGVyIGtleSBpcyByZXF1aXJlZCc7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5leHBvcnQgY29uc3QgYWRkUmF0ZUxpbWl0ID0gKHJvdXRlLCBjb25maWcpID0+IHtcbiAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uZmlnID0gQ29uZmlnLmdldChjb25maWcpO1xuICB9XG4gIGZvciAoY29uc3Qga2V5IGluIHJvdXRlKSB7XG4gICAgaWYgKCFSYXRlTGltaXRPcHRpb25zW2tleV0pIHtcbiAgICAgIHRocm93IGBJbnZhbGlkIHJhdGUgbGltaXQgb3B0aW9uIFwiJHtrZXl9XCJgO1xuICAgIH1cbiAgfVxuICBpZiAoIWNvbmZpZy5yYXRlTGltaXRzKSB7XG4gICAgY29uZmlnLnJhdGVMaW1pdHMgPSBbXTtcbiAgfVxuICBjb25maWcucmF0ZUxpbWl0cy5wdXNoKHtcbiAgICBwYXRoOiBwYXRoVG9SZWdleHAocm91dGUucmVxdWVzdFBhdGgpLFxuICAgIGhhbmRsZXI6IHJhdGVMaW1pdCh7XG4gICAgICB3aW5kb3dNczogcm91dGUucmVxdWVzdFRpbWVXaW5kb3csXG4gICAgICBtYXg6IHJvdXRlLnJlcXVlc3RDb3VudCxcbiAgICAgIG1lc3NhZ2U6IHJvdXRlLmVycm9yUmVzcG9uc2VNZXNzYWdlIHx8IFJhdGVMaW1pdE9wdGlvbnMuZXJyb3JSZXNwb25zZU1lc3NhZ2UuZGVmYXVsdCxcbiAgICAgIGhhbmRsZXI6IChyZXF1ZXN0LCByZXNwb25zZSwgbmV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICB0aHJvdyBvcHRpb25zLm1lc3NhZ2U7XG4gICAgICB9LFxuICAgICAgc2tpcDogcmVxdWVzdCA9PiB7XG4gICAgICAgIGlmIChyZXF1ZXN0LmlwID09PSAnMTI3LjAuMC4xJyAmJiAhcm91dGUuaW5jbHVkZUludGVybmFsUmVxdWVzdHMpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm91dGUuaW5jbHVkZU1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm91dGUucmVxdWVzdE1ldGhvZHMpIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyb3V0ZS5yZXF1ZXN0TWV0aG9kcykpIHtcbiAgICAgICAgICAgIGlmICghcm91dGUucmVxdWVzdE1ldGhvZHMuaW5jbHVkZXMocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZWdFeHAgPSBuZXcgUmVnRXhwKHJvdXRlLnJlcXVlc3RNZXRob2RzKTtcbiAgICAgICAgICAgIGlmICghcmVnRXhwLnRlc3QocmVxdWVzdC5tZXRob2QpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVxdWVzdC5hdXRoLmlzTWFzdGVyO1xuICAgICAgfSxcbiAgICAgIGtleUdlbmVyYXRvcjogcmVxdWVzdCA9PiB7XG4gICAgICAgIHJldHVybiByZXF1ZXN0LmNvbmZpZy5pcDtcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBDb25maWcucHV0KGNvbmZpZyk7XG59O1xuXG4vKipcbiAqIERlZHVwbGljYXRlcyBhIHJlcXVlc3QgdG8gZW5zdXJlIGlkZW1wb3RlbmN5LiBEdXBsaWNhdGVzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSByZXF1ZXN0IElEXG4gKiBpbiB0aGUgcmVxdWVzdCBoZWFkZXIuIElmIGEgcmVxdWVzdCBoYXMgbm8gcmVxdWVzdCBJRCwgaXQgaXMgZXhlY3V0ZWQgYW55d2F5LlxuICogQHBhcmFtIHsqfSByZXEgVGhlIHJlcXVlc3QgdG8gZXZhbHVhdGUuXG4gKiBAcmV0dXJucyBQcm9taXNlPHt9PlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5KHJlcSkge1xuICAvLyBFbmFibGUgZmVhdHVyZSBvbmx5IGZvciBNb25nb0RCXG4gIGlmIChcbiAgICAhKFxuICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZS5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlciB8fFxuICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZS5hZGFwdGVyIGluc3RhbmNlb2YgUG9zdGdyZXNTdG9yYWdlQWRhcHRlclxuICAgIClcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIEdldCBwYXJhbWV0ZXJzXG4gIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gIGNvbnN0IHJlcXVlc3RJZCA9ICgocmVxIHx8IHt9KS5oZWFkZXJzIHx8IHt9KVsneC1wYXJzZS1yZXF1ZXN0LWlkJ107XG4gIGNvbnN0IHsgcGF0aHMsIHR0bCB9ID0gY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucztcbiAgaWYgKCFyZXF1ZXN0SWQgfHwgIWNvbmZpZy5pZGVtcG90ZW5jeU9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gUmVxdWVzdCBwYXRoIG1heSBjb250YWluIHRyYWlsaW5nIHNsYXNoZXMsIGRlcGVuZGluZyBvbiB0aGUgb3JpZ2luYWwgcmVxdWVzdCwgc28gcmVtb3ZlXG4gIC8vIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHNsYXNoZXMgdG8gbWFrZSBpdCBlYXNpZXIgdG8gc3BlY2lmeSBwYXRocyBpbiB0aGUgY29uZmlndXJhdGlvblxuICBjb25zdCByZXFQYXRoID0gcmVxLnBhdGgucmVwbGFjZSgvXlxcL3xcXC8kLywgJycpO1xuICAvLyBEZXRlcm1pbmUgd2hldGhlciBpZGVtcG90ZW5jeSBpcyBlbmFibGVkIGZvciBjdXJyZW50IHJlcXVlc3QgcGF0aFxuICBsZXQgbWF0Y2ggPSBmYWxzZTtcbiAgZm9yIChjb25zdCBwYXRoIG9mIHBhdGhzKSB7XG4gICAgLy8gQXNzdW1lIG9uZSB3YW50cyBhIHBhdGggdG8gYWx3YXlzIG1hdGNoIGZyb20gdGhlIGJlZ2lubmluZyB0byBwcmV2ZW50IGFueSBtaXN0YWtlc1xuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChwYXRoLmNoYXJBdCgwKSA9PT0gJ14nID8gcGF0aCA6ICdeJyArIHBhdGgpO1xuICAgIGlmIChyZXFQYXRoLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgbWF0Y2ggPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmICghbWF0Y2gpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gVHJ5IHRvIHN0b3JlIHJlcXVlc3RcbiAgY29uc3QgZXhwaXJ5RGF0ZSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuc2V0U2Vjb25kcyhuZXcgRGF0ZSgpLmdldFNlY29uZHMoKSArIHR0bCkpO1xuICByZXR1cm4gcmVzdFxuICAgIC5jcmVhdGUoY29uZmlnLCBhdXRoLm1hc3Rlcihjb25maWcpLCAnX0lkZW1wb3RlbmN5Jywge1xuICAgICAgcmVxSWQ6IHJlcXVlc3RJZCxcbiAgICAgIGV4cGlyZTogUGFyc2UuX2VuY29kZShleHBpcnlEYXRlKSxcbiAgICB9KVxuICAgIC5jYXRjaChlID0+IHtcbiAgICAgIGlmIChlLmNvZGUgPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5EVVBMSUNBVEVfUkVRVUVTVCwgJ0R1cGxpY2F0ZSByZXF1ZXN0Jyk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcykge1xuICByZXMuc3RhdHVzKDQwMyk7XG4gIHJlcy5lbmQoJ3tcImVycm9yXCI6XCJ1bmF1dGhvcml6ZWRcIn0nKTtcbn1cblxuZnVuY3Rpb24gbWFsZm9ybWVkQ29udGV4dChyZXEsIHJlcykge1xuICByZXMuc3RhdHVzKDQwMCk7XG4gIHJlcy5qc29uKHsgY29kZTogUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBlcnJvcjogJ0ludmFsaWQgb2JqZWN0IGZvciBjb250ZXh0LicgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBMEM7QUFFbkMsTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQUErTztBQUFDO0FBRWxQLE1BQU1DLGtCQUFrQixHQUFHLFVBQVVDLEdBQUcsRUFBRTtFQUN4QyxNQUFNQyxlQUFlLEdBQUdELEdBQUcsQ0FBQ0UsV0FBVyxDQUFDQyxNQUFNLEdBQUdILEdBQUcsQ0FBQ0ksR0FBRyxDQUFDRCxNQUFNO0VBQy9ELE1BQU1FLFNBQVMsR0FBR0wsR0FBRyxDQUFDRSxXQUFXLENBQUNJLEtBQUssQ0FBQyxDQUFDLEVBQUVMLGVBQWUsQ0FBQztFQUMzRCxPQUFPRCxHQUFHLENBQUNPLFFBQVEsR0FBRyxLQUFLLEdBQUdQLEdBQUcsQ0FBQ1EsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHSCxTQUFTO0FBQzNELENBQUM7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0ksa0JBQWtCLENBQUNULEdBQUcsRUFBRVUsR0FBRyxFQUFFQyxJQUFJLEVBQUU7RUFDakQsSUFBSUMsS0FBSyxHQUFHYixrQkFBa0IsQ0FBQ0MsR0FBRyxDQUFDO0VBRW5DLElBQUlhLE9BQU8sR0FBRyxDQUFDLENBQUM7RUFDaEIsSUFBSWIsR0FBRyxDQUFDUSxHQUFHLENBQUMsdUJBQXVCLENBQUMsSUFBSSxJQUFJLEVBQUU7SUFDNUMsSUFBSTtNQUNGSyxPQUFPLEdBQUdDLElBQUksQ0FBQ0MsS0FBSyxDQUFDZixHQUFHLENBQUNRLEdBQUcsQ0FBQyx1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
|