1 | ;
|
2 |
|
3 | var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
4 |
|
5 | var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
|
6 |
|
7 | var _getIterator2 = require('babel-runtime/core-js/get-iterator');
|
8 |
|
9 | var _getIterator3 = _interopRequireDefault(_getIterator2);
|
10 |
|
11 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
12 |
|
13 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
14 |
|
15 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
16 |
|
17 | var _createClass3 = _interopRequireDefault(_createClass2);
|
18 |
|
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
20 |
|
21 | var ChatServiceError = require('./ChatServiceError');
|
22 | var CommandBinder = require('./CommandBinder');
|
23 | var DirectMessaging = require('./DirectMessaging');
|
24 | var Promise = require('bluebird');
|
25 | var UserAssociations = require('./UserAssociations');
|
26 | var _ = require('lodash');
|
27 |
|
28 | var _require = require('./utils');
|
29 |
|
30 | var asyncLimit = _require.asyncLimit;
|
31 | var checkNameSymbols = _require.checkNameSymbols;
|
32 |
|
33 | var _require2 = require('es6-mixin');
|
34 |
|
35 | var mixin = _require2.mixin;
|
36 |
|
37 | // Client commands implementation.
|
38 |
|
39 | var User = function () {
|
40 | function User(server, userName) {
|
41 | (0, _classCallCheck3.default)(this, User);
|
42 |
|
43 | this.server = server;
|
44 | this.userName = userName;
|
45 | this.echoChannel = 'echo:' + this.userName;
|
46 | this.state = this.server.state;
|
47 | this.transport = this.server.transport;
|
48 | this.enableRoomsManagement = this.server.enableRoomsManagement;
|
49 | this.enableDirectMessages = this.server.enableDirectMessages;
|
50 | this.directMessaging = new DirectMessaging(server, userName);
|
51 | var State = this.server.state.UserState;
|
52 | this.userState = new State(this.server, this.userName);
|
53 | this.commandBinder = new CommandBinder(this.server, this.transport, this.userName);
|
54 | var opts = {
|
55 | busAckTimeout: this.server.busAckTimeout,
|
56 | clusterBus: this.server.clusterBus,
|
57 | consistencyFailure: this.consistencyFailure.bind(this),
|
58 | echoChannel: this.echoChannel,
|
59 | lockTTL: this.state.lockTTL,
|
60 | state: this.state,
|
61 | transport: this.transport,
|
62 | userName: this.userName,
|
63 | userState: this.userState
|
64 | };
|
65 | mixin(this, UserAssociations, opts);
|
66 | }
|
67 |
|
68 | (0, _createClass3.default)(User, [{
|
69 | key: 'initState',
|
70 | value: function initState(state) {
|
71 | return this.directMessaging.initState(state);
|
72 | }
|
73 | }, {
|
74 | key: 'removeState',
|
75 | value: function removeState() {
|
76 | return this.directMessaging.removeState();
|
77 | }
|
78 | }, {
|
79 | key: 'processMessage',
|
80 | value: function processMessage(msg) {
|
81 | var setTimestamp = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
|
82 |
|
83 | delete msg.id;
|
84 | delete msg.timestamp;
|
85 | if (setTimestamp) {
|
86 | msg.timestamp = _.now();
|
87 | }
|
88 | msg.author = this.userName || msg.author;
|
89 | return msg;
|
90 | }
|
91 | }, {
|
92 | key: 'exec',
|
93 | value: function exec(command, options, args) {
|
94 | var id = options.id;
|
95 |
|
96 | var requestsNames = this.server.rpcRequestsNames;
|
97 | if (!_.includes(requestsNames, command)) {
|
98 | var error = new ChatServiceError('noCommand', command);
|
99 | return Promise.reject(error);
|
100 | }
|
101 | var requiresSocket = command === 'roomJoin' || command === 'roomLeave';
|
102 | if (!id && requiresSocket) {
|
103 | var _error = new ChatServiceError('noSocket', command);
|
104 | return Promise.reject(_error);
|
105 | }
|
106 | var fn = this[command].bind(this);
|
107 | var cmd = this.commandBinder.makeCommand(command, fn);
|
108 | return cmd(args, options);
|
109 | }
|
110 | }, {
|
111 | key: 'checkOnline',
|
112 | value: function checkOnline() {
|
113 | var _this = this;
|
114 |
|
115 | return this.userState.getAllSockets().then(function (sockets) {
|
116 | if (!sockets || !sockets.length) {
|
117 | var error = new ChatServiceError('noUserOnline', _this.userName);
|
118 | return Promise.reject(error);
|
119 | } else {
|
120 | return Promise.resolve();
|
121 | }
|
122 | });
|
123 | }
|
124 | }, {
|
125 | key: 'consistencyFailure',
|
126 | value: function consistencyFailure(error, operationInfo) {
|
127 | operationInfo.userName = this.userName;
|
128 | var name = operationInfo.opType === 'transportChannel' ? 'transportConsistencyFailure' : 'storeConsistencyFailure';
|
129 | this.server.emit(name, error, operationInfo);
|
130 | }
|
131 | }, {
|
132 | key: 'registerSocket',
|
133 | value: function registerSocket(id) {
|
134 | var _this2 = this;
|
135 |
|
136 | return this.state.addSocket(id, this.userName).then(function () {
|
137 | return _this2.userState.addSocket(id, _this2.server.instanceUID);
|
138 | }).then(function (nconnected) {
|
139 | if (!_this2.transport.getSocket(id)) {
|
140 | return _this2.removeUserSocket(id).then(function () {
|
141 | var error = new ChatServiceError('noSocket', 'connection');
|
142 | return Promise.reject(error);
|
143 | });
|
144 | } else {
|
145 | var commands = _this2.server.rpcRequestsNames;
|
146 | var _iteratorNormalCompletion = true;
|
147 | var _didIteratorError = false;
|
148 | var _iteratorError = undefined;
|
149 |
|
150 | try {
|
151 | for (var _iterator = (0, _getIterator3.default)(commands), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
152 | var cmd = _step.value;
|
153 |
|
154 | _this2.commandBinder.bindCommand(id, cmd, _this2[cmd].bind(_this2));
|
155 | }
|
156 | } catch (err) {
|
157 | _didIteratorError = true;
|
158 | _iteratorError = err;
|
159 | } finally {
|
160 | try {
|
161 | if (!_iteratorNormalCompletion && _iterator.return) {
|
162 | _iterator.return();
|
163 | }
|
164 | } finally {
|
165 | if (_didIteratorError) {
|
166 | throw _iteratorError;
|
167 | }
|
168 | }
|
169 | }
|
170 |
|
171 | _this2.commandBinder.bindDisconnect(id, _this2.removeSocket.bind(_this2));
|
172 | return _this2.transport.joinChannel(id, _this2.echoChannel).then(function () {
|
173 | _this2.socketConnectEcho(id, nconnected);
|
174 | return Promise.resolve();
|
175 | });
|
176 | }
|
177 | });
|
178 | }
|
179 | }, {
|
180 | key: 'removeSocket',
|
181 | value: function removeSocket(id) {
|
182 | return this.removeSocketFromServer(id);
|
183 | }
|
184 | }, {
|
185 | key: 'disconnectInstanceSockets',
|
186 | value: function disconnectInstanceSockets() {
|
187 | var _this3 = this;
|
188 |
|
189 | return this.userState.getAllSockets().then(function (sockets) {
|
190 | return Promise.map(sockets, function (sid) {
|
191 | return _this3.transport.disconnectSocket(sid);
|
192 | }, { concurrency: asyncLimit });
|
193 | });
|
194 | }
|
195 | }, {
|
196 | key: 'directAddToList',
|
197 | value: function directAddToList(listName, values) {
|
198 | return this.directMessaging.addToList(this.userName, listName, values).return();
|
199 | }
|
200 | }, {
|
201 | key: 'directGetAccessList',
|
202 | value: function directGetAccessList(listName) {
|
203 | return this.directMessaging.getList(this.userName, listName);
|
204 | }
|
205 | }, {
|
206 | key: 'directGetWhitelistMode',
|
207 | value: function directGetWhitelistMode() {
|
208 | return this.directMessaging.getMode(this.userName);
|
209 | }
|
210 | }, {
|
211 | key: 'directMessage',
|
212 | value: function directMessage(recipientName, msg, _ref) {
|
213 | var _this4 = this;
|
214 |
|
215 | var id = _ref.id;
|
216 | var bypassPermissions = _ref.bypassPermissions;
|
217 |
|
218 | if (!this.enableDirectMessages) {
|
219 | var error = new ChatServiceError('notAllowed');
|
220 | return Promise.reject(error);
|
221 | }
|
222 | this.processMessage(msg, true);
|
223 | return this.server.state.getUser(recipientName).then(function (recipient) {
|
224 | var channel = recipient.echoChannel;
|
225 | return recipient.directMessaging.message(_this4.userName, msg, bypassPermissions).then(function () {
|
226 | return recipient.checkOnline();
|
227 | }).then(function () {
|
228 | _this4.transport.emitToChannel(channel, 'directMessage', msg);
|
229 | _this4.transport.sendToChannel(id, _this4.echoChannel, 'directMessageEcho', recipientName, msg);
|
230 | return msg;
|
231 | });
|
232 | });
|
233 | }
|
234 | }, {
|
235 | key: 'directRemoveFromList',
|
236 | value: function directRemoveFromList(listName, values) {
|
237 | return this.directMessaging.removeFromList(this.userName, listName, values).return();
|
238 | }
|
239 | }, {
|
240 | key: 'directSetWhitelistMode',
|
241 | value: function directSetWhitelistMode(mode) {
|
242 | return this.directMessaging.changeMode(this.userName, mode).return();
|
243 | }
|
244 | }, {
|
245 | key: 'listOwnSockets',
|
246 | value: function listOwnSockets() {
|
247 | return this.userState.getSocketsToRooms();
|
248 | }
|
249 | }, {
|
250 | key: 'roomAddToList',
|
251 | value: function roomAddToList(roomName, listName, values, _ref2) {
|
252 | var _this5 = this;
|
253 |
|
254 | var bypassPermissions = _ref2.bypassPermissions;
|
255 |
|
256 | return this.state.getRoom(roomName).then(function (room) {
|
257 | return Promise.join(room.addToList(_this5.userName, listName, values, bypassPermissions), room.roomState.accessListsUpdatesGet(), function (userNames, update) {
|
258 | if (update) {
|
259 | _this5.transport.emitToChannel(roomName, 'roomAccessListAdded', roomName, listName, values);
|
260 | }
|
261 | return _this5.removeRoomUsers(roomName, userNames);
|
262 | });
|
263 | }).return();
|
264 | }
|
265 | }, {
|
266 | key: 'roomCreate',
|
267 | value: function roomCreate(roomName, whitelistOnly, _ref3) {
|
268 | var _this6 = this;
|
269 |
|
270 | var bypassPermissions = _ref3.bypassPermissions;
|
271 |
|
272 | if (!this.enableRoomsManagement && !bypassPermissions) {
|
273 | var error = new ChatServiceError('notAllowed');
|
274 | return Promise.reject(error);
|
275 | }
|
276 | var owner = this.userName;
|
277 | return checkNameSymbols(roomName).then(function () {
|
278 | return _this6.state.addRoom(roomName, { owner: owner, whitelistOnly: whitelistOnly });
|
279 | }).return();
|
280 | }
|
281 | }, {
|
282 | key: 'roomDelete',
|
283 | value: function roomDelete(roomName, _ref4) {
|
284 | var _this7 = this;
|
285 |
|
286 | var bypassPermissions = _ref4.bypassPermissions;
|
287 |
|
288 | if (!this.enableRoomsManagement && !bypassPermissions) {
|
289 | var error = new ChatServiceError('notAllowed');
|
290 | return Promise.reject(error);
|
291 | }
|
292 | return this.state.getRoom(roomName).then(function (room) {
|
293 | return room.checkIsOwner(_this7.userName, bypassPermissions).then(function () {
|
294 | return room.startRemoving();
|
295 | }).then(function () {
|
296 | return room.getUsers();
|
297 | }).then(function (userNames) {
|
298 | return _this7.removeRoomUsers(roomName, userNames);
|
299 | }).then(function () {
|
300 | return _this7.state.removeRoom(roomName);
|
301 | }).then(function () {
|
302 | return room.removeState();
|
303 | }).return();
|
304 | });
|
305 | }
|
306 | }, {
|
307 | key: 'roomGetAccessList',
|
308 | value: function roomGetAccessList(roomName, listName, _ref5) {
|
309 | var _this8 = this;
|
310 |
|
311 | var bypassPermissions = _ref5.bypassPermissions;
|
312 |
|
313 | return this.state.getRoom(roomName).then(function (room) {
|
314 | return room.getList(_this8.userName, listName, bypassPermissions);
|
315 | });
|
316 | }
|
317 | }, {
|
318 | key: 'roomGetOwner',
|
319 | value: function roomGetOwner(roomName, _ref6) {
|
320 | var _this9 = this;
|
321 |
|
322 | var bypassPermissions = _ref6.bypassPermissions;
|
323 |
|
324 | return this.state.getRoom(roomName).then(function (room) {
|
325 | return room.getOwner(_this9.userName, bypassPermissions);
|
326 | });
|
327 | }
|
328 | }, {
|
329 | key: 'roomGetWhitelistMode',
|
330 | value: function roomGetWhitelistMode(roomName, _ref7) {
|
331 | var _this10 = this;
|
332 |
|
333 | var bypassPermissions = _ref7.bypassPermissions;
|
334 |
|
335 | return this.state.getRoom(roomName).then(function (room) {
|
336 | return room.getMode(_this10.userName, bypassPermissions);
|
337 | });
|
338 | }
|
339 | }, {
|
340 | key: 'roomRecentHistory',
|
341 | value: function roomRecentHistory(roomName, _ref8) {
|
342 | var _this11 = this;
|
343 |
|
344 | var bypassPermissions = _ref8.bypassPermissions;
|
345 |
|
346 | return this.state.getRoom(roomName).then(function (room) {
|
347 | return room.getRecentMessages(_this11.userName, bypassPermissions);
|
348 | });
|
349 | }
|
350 | }, {
|
351 | key: 'roomHistoryGet',
|
352 | value: function roomHistoryGet(roomName, msgid, limit, _ref9) {
|
353 | var _this12 = this;
|
354 |
|
355 | var bypassPermissions = _ref9.bypassPermissions;
|
356 |
|
357 | return this.state.getRoom(roomName).then(function (room) {
|
358 | return room.getMessages(_this12.userName, msgid, limit, bypassPermissions);
|
359 | });
|
360 | }
|
361 | }, {
|
362 | key: 'roomHistoryInfo',
|
363 | value: function roomHistoryInfo(roomName, _ref10) {
|
364 | var _this13 = this;
|
365 |
|
366 | var bypassPermissions = _ref10.bypassPermissions;
|
367 |
|
368 | return this.state.getRoom(roomName).then(function (room) {
|
369 | return room.getHistoryInfo(_this13.userName, bypassPermissions);
|
370 | });
|
371 | }
|
372 | }, {
|
373 | key: 'roomJoin',
|
374 | value: function roomJoin(roomName, _ref11) {
|
375 | var _this14 = this;
|
376 |
|
377 | var id = _ref11.id;
|
378 | var isLocalCall = _ref11.isLocalCall;
|
379 |
|
380 | return this.state.getRoom(roomName).then(function (room) {
|
381 | return _this14.joinSocketToRoom(id, roomName, isLocalCall);
|
382 | });
|
383 | }
|
384 | }, {
|
385 | key: 'roomLeave',
|
386 | value: function roomLeave(roomName, _ref12) {
|
387 | var _this15 = this;
|
388 |
|
389 | var id = _ref12.id;
|
390 | var isLocalCall = _ref12.isLocalCall;
|
391 |
|
392 | return this.state.getRoom(roomName).then(function (room) {
|
393 | return _this15.leaveSocketFromRoom(id, room.roomName, isLocalCall);
|
394 | });
|
395 | }
|
396 | }, {
|
397 | key: 'roomMessage',
|
398 | value: function roomMessage(roomName, msg, _ref13) {
|
399 | var _this16 = this;
|
400 |
|
401 | var bypassPermissions = _ref13.bypassPermissions;
|
402 |
|
403 | return this.state.getRoom(roomName).then(function (room) {
|
404 | _this16.processMessage(msg);
|
405 | return room.message(_this16.userName, msg, bypassPermissions);
|
406 | }).then(function (pmsg) {
|
407 | _this16.transport.emitToChannel(roomName, 'roomMessage', roomName, pmsg);
|
408 | return pmsg.id;
|
409 | });
|
410 | }
|
411 | }, {
|
412 | key: 'roomNotificationsInfo',
|
413 | value: function roomNotificationsInfo(roomName, _ref14) {
|
414 | var _this17 = this;
|
415 |
|
416 | var bypassPermissions = _ref14.bypassPermissions;
|
417 |
|
418 | return this.state.getRoom(roomName).then(function (room) {
|
419 | return room.getNotificationsInfo(_this17.userName, bypassPermissions);
|
420 | });
|
421 | }
|
422 | }, {
|
423 | key: 'roomRemoveFromList',
|
424 | value: function roomRemoveFromList(roomName, listName, values, _ref15) {
|
425 | var _this18 = this;
|
426 |
|
427 | var bypassPermissions = _ref15.bypassPermissions;
|
428 |
|
429 | return this.state.getRoom(roomName).then(function (room) {
|
430 | return Promise.join(room.removeFromList(_this18.userName, listName, values, bypassPermissions), room.roomState.accessListsUpdatesGet(), function (userNames, update) {
|
431 | if (update) {
|
432 | _this18.transport.emitToChannel(roomName, 'roomAccessListRemoved', roomName, listName, values);
|
433 | }
|
434 | return _this18.removeRoomUsers(roomName, userNames);
|
435 | });
|
436 | }).return();
|
437 | }
|
438 | }, {
|
439 | key: 'roomSetWhitelistMode',
|
440 | value: function roomSetWhitelistMode(roomName, mode, _ref16) {
|
441 | var _this19 = this;
|
442 |
|
443 | var bypassPermissions = _ref16.bypassPermissions;
|
444 |
|
445 | return this.state.getRoom(roomName).then(function (room) {
|
446 | return Promise.join(room.changeMode(_this19.userName, mode, bypassPermissions), room.roomState.accessListsUpdatesGet(), function (_ref17, update) {
|
447 | var _ref18 = (0, _slicedToArray3.default)(_ref17, 2);
|
448 |
|
449 | var userNames = _ref18[0];
|
450 | var mode = _ref18[1];
|
451 |
|
452 | if (update) {
|
453 | _this19.transport.emitToChannel(roomName, 'roomModeChanged', roomName, mode);
|
454 | }
|
455 | return _this19.removeRoomUsers(roomName, userNames);
|
456 | });
|
457 | }).return();
|
458 | }
|
459 | }, {
|
460 | key: 'roomUserSeen',
|
461 | value: function roomUserSeen(roomName, userName, _ref19) {
|
462 | var _this20 = this;
|
463 |
|
464 | var bypassPermissions = _ref19.bypassPermissions;
|
465 |
|
466 | return this.state.getRoom(roomName).then(function (room) {
|
467 | return room.userSeen(_this20.userName, userName, bypassPermissions);
|
468 | });
|
469 | }
|
470 | }, {
|
471 | key: 'systemMessage',
|
472 | value: function systemMessage(data, _ref20) {
|
473 | var id = _ref20.id;
|
474 |
|
475 | this.transport.sendToChannel(id, this.echoChannel, 'systemMessage', data);
|
476 | return Promise.resolve();
|
477 | }
|
478 | }]);
|
479 | return User;
|
480 | }();
|
481 |
|
482 | module.exports = User;
|
483 | //# sourceMappingURL=data:application/json;base64,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Q0FBbUIsUUFBbkIsRUFDSixJQURJLENBQ0M7QUFBQSxlQUFRLEtBQUssUUFBTCxDQUFjLFFBQUssUUFBbkIsRUFBNkIsUUFBN0IsRUFBdUMsaUJBQXZDLENBQVI7QUFBQSxPQURELENBQVA7QUFFRDs7O2tDQUVjLEksVUFBWTtBQUFBLFVBQUwsRUFBSyxVQUFMLEVBQUs7O0FBQ3pCLFdBQUssU0FBTCxDQUFlLGFBQWYsQ0FBNkIsRUFBN0IsRUFBaUMsS0FBSyxXQUF0QyxFQUFtRCxlQUFuRCxFQUFvRSxJQUFwRTtBQUNBLGFBQU8sUUFBUSxPQUFSLEVBQVA7QUFDRDs7Ozs7QUFJSCxPQUFPLE9BQVAsR0FBaUIsSUFBakIiLCJmaWxlIjoiVXNlci5qcyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0J1xuXG5jb25zdCBDaGF0U2VydmljZUVycm9yID0gcmVxdWlyZSgnLi9DaGF0U2VydmljZUVycm9yJylcbmNvbnN0IENvbW1hbmRCaW5kZXIgPSByZXF1aXJlKCcuL0NvbW1hbmRCaW5kZXInKVxuY29uc3QgRGlyZWN0TWVzc2FnaW5nID0gcmVxdWlyZSgnLi9EaXJlY3RNZXNzYWdpbmcnKVxuY29uc3QgUHJvbWlzZSA9IHJlcXVpcmUoJ2JsdWViaXJkJylcbmNvbnN0IFVzZXJBc3NvY2lhdGlvbnMgPSByZXF1aXJlKCcuL1VzZXJBc3NvY2lhdGlvbnMnKVxuY29uc3QgXyA9IHJlcXVpcmUoJ2xvZGFzaCcpXG5jb25zdCB7IGFzeW5jTGltaXQsIGNoZWNrTmFtZVN5bWJvbHMgfSA9IHJlcXVpcmUoJy4vdXRpbHMnKVxuY29uc3QgeyBtaXhpbiB9ID0gcmVxdWlyZSgnZXM2LW1peGluJylcblxuLy8gQ2xpZW50IGNvbW1hbmRzIGltcGxlbWVudGF0aW9uLlxuY2xhc3MgVXNlciB7XG5cbiAgY29uc3RydWN0b3IgKHNlcnZlciwgdXNlck5hbWUpIHtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlclxuICAgIHRoaXMudXNlck5hbWUgPSB1c2VyTmFtZVxuICAgIHRoaXMuZWNob0NoYW5uZWwgPSBgZWNobzoke3RoaXMudXNlck5hbWV9YFxuICAgIHRoaXMuc3RhdGUgPSB0aGlzLnNlcnZlci5zdGF0ZVxuICAgIHRoaXMudHJhbnNwb3J0ID0gdGhpcy5zZXJ2ZXIudHJhbnNwb3J0XG4gICAgdGhpcy5lbmFibGVSb29tc01hbmFnZW1lbnQgPSB0aGlzLnNlcnZlci5lbmFibGVSb29tc01hbmFnZW1lbnRcbiAgICB0aGlzLmVuYWJsZURpcmVjdE1lc3NhZ2VzID0gdGhpcy5zZXJ2ZXIuZW5hYmxlRGlyZWN0TWVzc2FnZXNcbiAgICB0aGlzLmRpcmVjdE1lc3NhZ2luZyA9IG5ldyBEaXJlY3RNZXNzYWdpbmcoc2VydmVyLCB1c2VyTmFtZSlcbiAgICBsZXQgU3RhdGUgPSB0aGlzLnNlcnZlci5zdGF0ZS5Vc2VyU3RhdGVcbiAgICB0aGlzLnVzZXJTdGF0ZSA9IG5ldyBTdGF0ZSh0aGlzLnNlcnZlciwgdGhpcy51c2VyTmFtZSlcbiAgICB0aGlzLmNvbW1hbmRCaW5kZXIgPVxuICAgICAgbmV3IENvbW1hbmRCaW5kZXIodGhpcy5zZXJ2ZXIsIHRoaXMudHJhbnNwb3J0LCB0aGlzLnVzZXJOYW1lKVxuICAgIGxldCBvcHRzID0ge1xuICAgICAgYnVzQWNrVGltZW91dDogdGhpcy5zZXJ2ZXIuYnVzQWNrVGltZW91dCxcbiAgICAgIGNsdXN0ZXJCdXM6IHRoaXMuc2VydmVyLmNsdXN0ZXJCdXMsXG4gICAgICBjb25zaXN0ZW5jeUZhaWx1cmU6IHRoaXMuY29uc2lzdGVuY3lGYWlsdXJlLmJpbmQodGhpcyksXG4gICAgICBlY2hvQ2hhbm5lbDogdGhpcy5lY2hvQ2hhbm5lbCxcbiAgICAgIGxvY2tUVEw6IHRoaXMuc3RhdGUubG9ja1RUTCxcbiAgICAgIHN0YXRlOiB0aGlzLnN0YXRlLFxuICAgICAgdHJhbnNwb3J0OiB0aGlzLnRyYW5zcG9ydCxcbiAgICAgIHVzZXJOYW1lOiB0aGlzLnVzZXJOYW1lLFxuICAgICAgdXNlclN0YXRlOiB0aGlzLnVzZXJTdGF0ZVxuICAgIH1cbiAgICBtaXhpbih0aGlzLCBVc2VyQXNzb2NpYXRpb25zLCBvcHRzKVxuICB9XG5cbiAgaW5pdFN0YXRlIChzdGF0ZSkge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdE1lc3NhZ2luZy5pbml0U3RhdGUoc3RhdGUpXG4gIH1cblxuICByZW1vdmVTdGF0ZSAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlyZWN0TWVzc2FnaW5nLnJlbW92ZVN0YXRlKClcbiAgfVxuXG4gIHByb2Nlc3NNZXNzYWdlIChtc2csIHNldFRpbWVzdGFtcCA9IGZhbHNlKSB7XG4gICAgZGVsZXRlIG1zZy5pZFxuICAgIGRlbGV0ZSBtc2cudGltZXN0YW1wXG4gICAgaWYgKHNldFRpbWVzdGFtcCkge1xuICAgICAgbXNnLnRpbWVzdGFtcCA9IF8ubm93KClcbiAgICB9XG4gICAgbXNnLmF1dGhvciA9IHRoaXMudXNlck5hbWUgfHwgbXNnLmF1dGhvclxuICAgIHJldHVybiBtc2dcbiAgfVxuXG4gIGV4ZWMgKGNvbW1hbmQsIG9wdGlvbnMsIGFyZ3MpIHtcbiAgICBsZXQgeyBpZCB9ID0gb3B0aW9uc1xuICAgIGxldCByZXF1ZXN0c05hbWVzID0gdGhpcy5zZXJ2ZXIucnBjUmVxdWVzdHNOYW1lc1xuICAgIGlmICghXy5pbmNsdWRlcyhyZXF1ZXN0c05hbWVzLCBjb21tYW5kKSkge1xuICAgICAgbGV0IGVycm9yID0gbmV3IENoYXRTZXJ2aWNlRXJyb3IoJ25vQ29tbWFuZCcsIGNvbW1hbmQpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpXG4gICAgfVxuICAgIGxldCByZXF1aXJlc1NvY2tldCA9IGNvbW1hbmQgPT09ICdyb29tSm9pbicgfHwgY29tbWFuZCA9PT0gJ3Jvb21MZWF2ZSdcbiAgICBpZiAoIWlkICYmIHJlcXVpcmVzU29ja2V0KSB7XG4gICAgICBsZXQgZXJyb3IgPSBuZXcgQ2hhdFNlcnZpY2VFcnJvcignbm9Tb2NrZXQnLCBjb21tYW5kKVxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgICBsZXQgZm4gPSB0aGlzW2NvbW1hbmRdLmJpbmQodGhpcylcbiAgICBsZXQgY21kID0gdGhpcy5jb21tYW5kQmluZGVyLm1ha2VDb21tYW5kKGNvbW1hbmQsIGZuKVxuICAgIHJldHVybiBjbWQoYXJncywgb3B0aW9ucylcbiAgfVxuXG4gIGNoZWNrT25saW5lICgpIHtcbiAgICByZXR1cm4gdGhpcy51c2VyU3RhdGUuZ2V0QWxsU29ja2V0cygpLnRoZW4oc29ja2V0cyA9PiB7XG4gICAgICBpZiAoIXNvY2tldHMgfHwgIXNvY2tldHMubGVuZ3RoKSB7XG4gICAgICAgIGxldCBlcnJvciA9IG5ldyBDaGF0U2VydmljZUVycm9yKCdub1VzZXJPbmxpbmUnLCB0aGlzLnVzZXJOYW1lKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgY29uc2lzdGVuY3lGYWlsdXJlIChlcnJvciwgb3BlcmF0aW9uSW5mbykge1xuICAgIG9wZXJhdGlvbkluZm8udXNlck5hbWUgPSB0aGlzLnVzZXJOYW1lXG4gICAgbGV0IG5hbWUgPSBvcGVyYXRpb25JbmZvLm9wVHlwZSA9PT0gJ3RyYW5zcG9ydENoYW5uZWwnXG4gICAgICAgICAgPyAndHJhbnNwb3J0Q29uc2lzdGVuY3lGYWlsdXJlJ1xuICAgICAgICAgIDogJ3N0b3JlQ29uc2lzdGVuY3lGYWlsdXJlJ1xuICAgIHRoaXMuc2VydmVyLmVtaXQobmFtZSwgZXJyb3IsIG9wZXJhdGlvbkluZm8pXG4gIH1cblxuICByZWdpc3RlclNvY2tldCAoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5hZGRTb2NrZXQoaWQsIHRoaXMudXNlck5hbWUpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnVzZXJTdGF0ZS5hZGRTb2NrZXQoaWQsIHRoaXMuc2VydmVyLmluc3RhbmNlVUlEKSlcbiAgICAgIC50aGVuKG5jb25uZWN0ZWQgPT4ge1xuICAgICAgICBpZiAoIXRoaXMudHJhbnNwb3J0LmdldFNvY2tldChpZCkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVVc2VyU29ja2V0KGlkKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGxldCBlcnJvciA9IG5ldyBDaGF0U2VydmljZUVycm9yKCdub1NvY2tldCcsICdjb25uZWN0aW9uJylcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcilcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCBjb21tYW5kcyA9IHRoaXMuc2VydmVyLnJwY1JlcXVlc3RzTmFtZXNcbiAgICAgICAgICBmb3IgKGxldCBjbWQgb2YgY29tbWFuZHMpIHtcbiAgICAgICAgICAgIHRoaXMuY29tbWFuZEJpbmRlci5iaW5kQ29tbWFuZChpZCwgY21kLCB0aGlzW2NtZF0uYmluZCh0aGlzKSlcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jb21tYW5kQmluZGVyLmJpbmREaXNjb25uZWN0KGlkLCB0aGlzLnJlbW92ZVNvY2tldC5iaW5kKHRoaXMpKVxuICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5qb2luQ2hhbm5lbChpZCwgdGhpcy5lY2hvQ2hhbm5lbCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNvY2tldENvbm5lY3RFY2hvKGlkLCBuY29ubmVjdGVkKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgfVxuXG4gIHJlbW92ZVNvY2tldCAoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5yZW1vdmVTb2NrZXRGcm9tU2VydmVyKGlkKVxuICB9XG5cbiAgZGlzY29ubmVjdEluc3RhbmNlU29ja2V0cyAoKSB7XG4gICAgcmV0dXJuIHRoaXMudXNlclN0YXRlLmdldEFsbFNvY2tldHMoKS50aGVuKHNvY2tldHMgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UubWFwKFxuICAgICAgICBzb2NrZXRzLFxuICAgICAgICBzaWQgPT4gdGhpcy50cmFuc3BvcnQuZGlzY29ubmVjdFNvY2tldChzaWQpLFxuICAgICAgICB7IGNvbmN1cnJlbmN5OiBhc3luY0xpbWl0IH0pXG4gICAgfSlcbiAgfVxuXG4gIGRpcmVjdEFkZFRvTGlzdCAobGlzdE5hbWUsIHZhbHVlcykge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdE1lc3NhZ2luZy5hZGRUb0xpc3QodGhpcy51c2VyTmFtZSwgbGlzdE5hbWUsIHZhbHVlcylcbiAgICAgIC5yZXR1cm4oKVxuICB9XG5cbiAgZGlyZWN0R2V0QWNjZXNzTGlzdCAobGlzdE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5kaXJlY3RNZXNzYWdpbmcuZ2V0TGlzdCh0aGlzLnVzZXJOYW1lLCBsaXN0TmFtZSlcbiAgfVxuXG4gIGRpcmVjdEdldFdoaXRlbGlzdE1vZGUgKCkge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdE1lc3NhZ2luZy5nZXRNb2RlKHRoaXMudXNlck5hbWUpXG4gIH1cblxuICBkaXJlY3RNZXNzYWdlIChyZWNpcGllbnROYW1lLCBtc2csIHtpZCwgYnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgaWYgKCF0aGlzLmVuYWJsZURpcmVjdE1lc3NhZ2VzKSB7XG4gICAgICBsZXQgZXJyb3IgPSBuZXcgQ2hhdFNlcnZpY2VFcnJvcignbm90QWxsb3dlZCcpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpXG4gICAgfVxuICAgIHRoaXMucHJvY2Vzc01lc3NhZ2UobXNnLCB0cnVlKVxuICAgIHJldHVybiB0aGlzLnNlcnZlci5zdGF0ZS5nZXRVc2VyKHJlY2lwaWVudE5hbWUpLnRoZW4ocmVjaXBpZW50ID0+IHtcbiAgICAgIGxldCBjaGFubmVsID0gcmVjaXBpZW50LmVjaG9DaGFubmVsXG4gICAgICByZXR1cm4gcmVjaXBpZW50LmRpcmVjdE1lc3NhZ2luZ1xuICAgICAgICAubWVzc2FnZSh0aGlzLnVzZXJOYW1lLCBtc2csIGJ5cGFzc1Blcm1pc3Npb25zKVxuICAgICAgICAudGhlbigoKSA9PiByZWNpcGllbnQuY2hlY2tPbmxpbmUoKSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMudHJhbnNwb3J0LmVtaXRUb0NoYW5uZWwoY2hhbm5lbCwgJ2RpcmVjdE1lc3NhZ2UnLCBtc2cpXG4gICAgICAgICAgdGhpcy50cmFuc3BvcnQuc2VuZFRvQ2hhbm5lbChcbiAgICAgICAgICAgIGlkLCB0aGlzLmVjaG9DaGFubmVsLCAnZGlyZWN0TWVzc2FnZUVjaG8nLCByZWNpcGllbnROYW1lLCBtc2cpXG4gICAgICAgICAgcmV0dXJuIG1zZ1xuICAgICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBkaXJlY3RSZW1vdmVGcm9tTGlzdCAobGlzdE5hbWUsIHZhbHVlcykge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdE1lc3NhZ2luZy5yZW1vdmVGcm9tTGlzdCh0aGlzLnVzZXJOYW1lLCBsaXN0TmFtZSwgdmFsdWVzKVxuICAgICAgLnJldHVybigpXG4gIH1cblxuICBkaXJlY3RTZXRXaGl0ZWxpc3RNb2RlIChtb2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuZGlyZWN0TWVzc2FnaW5nLmNoYW5nZU1vZGUodGhpcy51c2VyTmFtZSwgbW9kZSkucmV0dXJuKClcbiAgfVxuXG4gIGxpc3RPd25Tb2NrZXRzICgpIHtcbiAgICByZXR1cm4gdGhpcy51c2VyU3RhdGUuZ2V0U29ja2V0c1RvUm9vbXMoKVxuICB9XG5cbiAgcm9vbUFkZFRvTGlzdCAocm9vbU5hbWUsIGxpc3ROYW1lLCB2YWx1ZXMsIHtieXBhc3NQZXJtaXNzaW9uc30pIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lKS50aGVuKHJvb20gPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2Uuam9pbihcbiAgICAgICAgcm9vbS5hZGRUb0xpc3QodGhpcy51c2VyTmFtZSwgbGlzdE5hbWUsIHZhbHVlcywgYnlwYXNzUGVybWlzc2lvbnMpLFxuICAgICAgICByb29tLnJvb21TdGF0ZS5hY2Nlc3NMaXN0c1VwZGF0ZXNHZXQoKSxcbiAgICAgICAgKHVzZXJOYW1lcywgdXBkYXRlKSA9PiB7XG4gICAgICAgICAgaWYgKHVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQuZW1pdFRvQ2hhbm5lbChcbiAgICAgICAgICAgICAgcm9vbU5hbWUsICdyb29tQWNjZXNzTGlzdEFkZGVkJywgcm9vbU5hbWUsIGxpc3ROYW1lLCB2YWx1ZXMpXG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLnJlbW92ZVJvb21Vc2Vycyhyb29tTmFtZSwgdXNlck5hbWVzKVxuICAgICAgICB9KVxuICAgIH0pLnJldHVybigpXG4gIH1cblxuICByb29tQ3JlYXRlIChyb29tTmFtZSwgd2hpdGVsaXN0T25seSwge2J5cGFzc1Blcm1pc3Npb25zfSkge1xuICAgIGlmICghdGhpcy5lbmFibGVSb29tc01hbmFnZW1lbnQgJiYgIWJ5cGFzc1Blcm1pc3Npb25zKSB7XG4gICAgICBsZXQgZXJyb3IgPSBuZXcgQ2hhdFNlcnZpY2VFcnJvcignbm90QWxsb3dlZCcpXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpXG4gICAgfVxuICAgIGxldCBvd25lciA9IHRoaXMudXNlck5hbWVcbiAgICByZXR1cm4gY2hlY2tOYW1lU3ltYm9scyhyb29tTmFtZSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuc3RhdGUuYWRkUm9vbShyb29tTmFtZSwge293bmVyLCB3aGl0ZWxpc3RPbmx5fSkpXG4gICAgICAucmV0dXJuKClcbiAgfVxuXG4gIHJvb21EZWxldGUgKHJvb21OYW1lLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgaWYgKCF0aGlzLmVuYWJsZVJvb21zTWFuYWdlbWVudCAmJiAhYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICAgIGxldCBlcnJvciA9IG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RBbGxvd2VkJylcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcilcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSkudGhlbihyb29tID0+IHtcbiAgICAgIHJldHVybiByb29tLmNoZWNrSXNPd25lcih0aGlzLnVzZXJOYW1lLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICAgICAgLnRoZW4oKCkgPT4gcm9vbS5zdGFydFJlbW92aW5nKCkpXG4gICAgICAgIC50aGVuKCgpID0+IHJvb20uZ2V0VXNlcnMoKSlcbiAgICAgICAgLnRoZW4odXNlck5hbWVzID0+IHRoaXMucmVtb3ZlUm9vbVVzZXJzKHJvb21OYW1lLCB1c2VyTmFtZXMpKVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnN0YXRlLnJlbW92ZVJvb20ocm9vbU5hbWUpKVxuICAgICAgICAudGhlbigoKSA9PiByb29tLnJlbW92ZVN0YXRlKCkpXG4gICAgICAgIC5yZXR1cm4oKVxuICAgIH0pXG4gIH1cblxuICByb29tR2V0QWNjZXNzTGlzdCAocm9vbU5hbWUsIGxpc3ROYW1lLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5nZXRMaXN0KHRoaXMudXNlck5hbWUsIGxpc3ROYW1lLCBieXBhc3NQZXJtaXNzaW9ucykpXG4gIH1cblxuICByb29tR2V0T3duZXIgKHJvb21OYW1lLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5nZXRPd25lcih0aGlzLnVzZXJOYW1lLCBieXBhc3NQZXJtaXNzaW9ucykpXG4gIH1cblxuICByb29tR2V0V2hpdGVsaXN0TW9kZSAocm9vbU5hbWUsIHtieXBhc3NQZXJtaXNzaW9uc30pIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lKVxuICAgICAgLnRoZW4ocm9vbSA9PiByb29tLmdldE1vZGUodGhpcy51c2VyTmFtZSwgYnlwYXNzUGVybWlzc2lvbnMpKVxuICB9XG5cbiAgcm9vbVJlY2VudEhpc3RvcnkgKHJvb21OYW1lLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5nZXRSZWNlbnRNZXNzYWdlcyh0aGlzLnVzZXJOYW1lLCBieXBhc3NQZXJtaXNzaW9ucykpXG4gIH1cblxuICByb29tSGlzdG9yeUdldCAocm9vbU5hbWUsIG1zZ2lkLCBsaW1pdCwge2J5cGFzc1Blcm1pc3Npb25zfSkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHJvb20uZ2V0TWVzc2FnZXMoXG4gICAgICAgIHRoaXMudXNlck5hbWUsIG1zZ2lkLCBsaW1pdCwgYnlwYXNzUGVybWlzc2lvbnMpKVxuICB9XG5cbiAgcm9vbUhpc3RvcnlJbmZvIChyb29tTmFtZSwge2J5cGFzc1Blcm1pc3Npb25zfSkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHJvb20uZ2V0SGlzdG9yeUluZm8odGhpcy51c2VyTmFtZSwgYnlwYXNzUGVybWlzc2lvbnMpKVxuICB9XG5cbiAgcm9vbUpvaW4gKHJvb21OYW1lLCB7aWQsIGlzTG9jYWxDYWxsfSkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHRoaXMuam9pblNvY2tldFRvUm9vbShpZCwgcm9vbU5hbWUsIGlzTG9jYWxDYWxsKSlcbiAgfVxuXG4gIHJvb21MZWF2ZSAocm9vbU5hbWUsIHtpZCwgaXNMb2NhbENhbGx9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gdGhpcy5sZWF2ZVNvY2tldEZyb21Sb29tKGlkLCByb29tLnJvb21OYW1lLCBpc0xvY2FsQ2FsbCkpXG4gIH1cblxuICByb29tTWVzc2FnZSAocm9vbU5hbWUsIG1zZywge2J5cGFzc1Blcm1pc3Npb25zfSkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpLnRoZW4ocm9vbSA9PiB7XG4gICAgICB0aGlzLnByb2Nlc3NNZXNzYWdlKG1zZylcbiAgICAgIHJldHVybiByb29tLm1lc3NhZ2UodGhpcy51c2VyTmFtZSwgbXNnLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICB9KS50aGVuKHBtc2cgPT4ge1xuICAgICAgdGhpcy50cmFuc3BvcnQuZW1pdFRvQ2hhbm5lbChyb29tTmFtZSwgJ3Jvb21NZXNzYWdlJywgcm9vbU5hbWUsIHBtc2cpXG4gICAgICByZXR1cm4gcG1zZy5pZFxuICAgIH0pXG4gIH1cblxuICByb29tTm90aWZpY2F0aW9uc0luZm8gKHJvb21OYW1lLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5nZXROb3RpZmljYXRpb25zSW5mbyh0aGlzLnVzZXJOYW1lLCBieXBhc3NQZXJtaXNzaW9ucykpXG4gIH1cblxuICByb29tUmVtb3ZlRnJvbUxpc3QgKHJvb21OYW1lLCBsaXN0TmFtZSwgdmFsdWVzLCB7YnlwYXNzUGVybWlzc2lvbnN9KSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSkudGhlbihyb29tID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLmpvaW4oXG4gICAgICAgIHJvb20ucmVtb3ZlRnJvbUxpc3QodGhpcy51c2VyTmFtZSwgbGlzdE5hbWUsIHZhbHVlcywgYnlwYXNzUGVybWlzc2lvbnMpLFxuICAgICAgICByb29tLnJvb21TdGF0ZS5hY2Nlc3NMaXN0c1VwZGF0ZXNHZXQoKSxcbiAgICAgICAgKHVzZXJOYW1lcywgdXBkYXRlKSA9PiB7XG4gICAgICAgICAgaWYgKHVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQuZW1pdFRvQ2hhbm5lbChcbiAgICAgICAgICAgICAgcm9vbU5hbWUsICdyb29tQWNjZXNzTGlzdFJlbW92ZWQnLCByb29tTmFtZSwgbGlzdE5hbWUsIHZhbHVlcylcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVtb3ZlUm9vbVVzZXJzKHJvb21OYW1lLCB1c2VyTmFtZXMpXG4gICAgICAgIH0pXG4gICAgfSkucmV0dXJuKClcbiAgfVxuXG4gIHJvb21TZXRXaGl0ZWxpc3RNb2RlIChyb29tTmFtZSwgbW9kZSwge2J5cGFzc1Blcm1pc3Npb25zfSkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpLnRoZW4ocm9vbSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5qb2luKFxuICAgICAgICByb29tLmNoYW5nZU1vZGUodGhpcy51c2VyTmFtZSwgbW9kZSwgYnlwYXNzUGVybWlzc2lvbnMpLFxuICAgICAgICByb29tLnJvb21TdGF0ZS5hY2Nlc3NMaXN0c1VwZGF0ZXNHZXQoKSxcbiAgICAgICAgKFt1c2VyTmFtZXMsIG1vZGVdLCB1cGRhdGUpID0+IHtcbiAgICAgICAgICBpZiAodXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydC5lbWl0VG9DaGFubmVsKFxuICAgICAgICAgICAgICByb29tTmFtZSwgJ3Jvb21Nb2RlQ2hhbmdlZCcsIHJvb21OYW1lLCBtb2RlKVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZW1vdmVSb29tVXNlcnMocm9vbU5hbWUsIHVzZXJOYW1lcylcbiAgICAgICAgfSlcbiAgICB9KS5yZXR1cm4oKVxuICB9XG5cbiAgcm9vbVVzZXJTZWVuIChyb29tTmFtZSwgdXNlck5hbWUsIHtieXBhc3NQZXJtaXNzaW9uc30pIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lKVxuICAgICAgLnRoZW4ocm9vbSA9PiByb29tLnVzZXJTZWVuKHRoaXMudXNlck5hbWUsIHVzZXJOYW1lLCBieXBhc3NQZXJtaXNzaW9ucykpXG4gIH1cblxuICBzeXN0ZW1NZXNzYWdlIChkYXRhLCB7aWR9KSB7XG4gICAgdGhpcy50cmFuc3BvcnQuc2VuZFRvQ2hhbm5lbChpZCwgdGhpcy5lY2hvQ2hhbm5lbCwgJ3N5c3RlbU1lc3NhZ2UnLCBkYXRhKVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICB9XG5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBVc2VyXG4iXX0= |
\ | No newline at end of file |