UNPKG

44.2 kBJavaScriptView Raw
1'use strict';
2
3var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
4
5var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
6
7var _getIterator2 = require('babel-runtime/core-js/get-iterator');
8
9var _getIterator3 = _interopRequireDefault(_getIterator2);
10
11var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
12
13var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
14
15var _createClass2 = require('babel-runtime/helpers/createClass');
16
17var _createClass3 = _interopRequireDefault(_createClass2);
18
19function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
21var ChatServiceError = require('./ChatServiceError');
22var CommandBinder = require('./CommandBinder');
23var DirectMessaging = require('./DirectMessaging');
24var Promise = require('bluebird');
25var UserAssociations = require('./UserAssociations');
26var _ = require('lodash');
27
28var _require = require('./utils');
29
30var asyncLimit = _require.asyncLimit;
31var checkNameSymbols = _require.checkNameSymbols;
32
33var _require2 = require('es6-mixin');
34
35var mixin = _require2.mixin;
36
37// Client commands implementation.
38
39var 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
482module.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