1 | ;
|
2 |
|
3 | var _regenerator = require('babel-runtime/regenerator');
|
4 |
|
5 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
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 Promise = require('bluebird');
|
23 | var _ = require('lodash');
|
24 |
|
25 | var _require = require('es6-mixin');
|
26 |
|
27 | var mixin = _require.mixin;
|
28 |
|
29 | var _require2 = require('./utils');
|
30 |
|
31 | var asyncLimit = _require2.asyncLimit;
|
32 | var run = _require2.run;
|
33 |
|
34 | var RoomPermissions = function () {
|
35 | function RoomPermissions(roomName, roomState, emitFailure) {
|
36 | (0, _classCallCheck3.default)(this, RoomPermissions);
|
37 |
|
38 | this.roomName = roomName;
|
39 | this.roomState = roomState;
|
40 | this.emitFailure = emitFailure;
|
41 | }
|
42 |
|
43 | (0, _createClass3.default)(RoomPermissions, [{
|
44 | key: 'consistencyFailure',
|
45 | value: function consistencyFailure(error, operationInfo) {
|
46 | operationInfo.roomName = this.roomName;
|
47 | operationInfo.opType = 'roomUserlist';
|
48 | this.emitFailure('storeConsistencyFailure', error, operationInfo);
|
49 | }
|
50 | }, {
|
51 | key: 'isAdmin',
|
52 | value: function isAdmin(userName) {
|
53 | var _this = this;
|
54 |
|
55 | return this.roomState.ownerGet().then(function (owner) {
|
56 | if (owner === userName) {
|
57 | return true;
|
58 | }
|
59 | return _this.roomState.hasInList('adminlist', userName);
|
60 | });
|
61 | }
|
62 | }, {
|
63 | key: 'hasRemoveChangedCurrentAccess',
|
64 | value: function hasRemoveChangedCurrentAccess(userName, listName) {
|
65 | var _this2 = this;
|
66 |
|
67 | return this.roomState.hasInList('userlist', userName).then(function (hasUser) {
|
68 | if (!hasUser) {
|
69 | return false;
|
70 | }
|
71 | return _this2.isAdmin(userName).then(function (admin) {
|
72 | if (admin || listName !== 'whitelist') {
|
73 | return false;
|
74 | }
|
75 | return _this2.roomState.whitelistOnlyGet();
|
76 | });
|
77 | }).catch(function (e) {
|
78 | return _this2.consistencyFailure(e, { userName: userName });
|
79 | });
|
80 | }
|
81 | }, {
|
82 | key: 'hasAddChangedCurrentAccess',
|
83 | value: function hasAddChangedCurrentAccess(userName, listName) {
|
84 | var _this3 = this;
|
85 |
|
86 | return this.roomState.hasInList('userlist', userName).then(function (hasUser) {
|
87 | if (!hasUser) {
|
88 | return false;
|
89 | }
|
90 | return _this3.isAdmin(userName).then(function (admin) {
|
91 | return !(admin || listName !== 'blacklist');
|
92 | });
|
93 | }).catch(function (e) {
|
94 | return _this3.consistencyFailure(e, { userName: userName });
|
95 | });
|
96 | }
|
97 | }, {
|
98 | key: 'getModeChangedCurrentAccess',
|
99 | value: function getModeChangedCurrentAccess(value) {
|
100 | if (!value) {
|
101 | return [];
|
102 | } else {
|
103 | return this.roomState.getCommonUsers();
|
104 | }
|
105 | }
|
106 | }, {
|
107 | key: 'checkListChanges',
|
108 | value: function checkListChanges(author, listName, values, bypassPermissions) {
|
109 | var _this4 = this;
|
110 |
|
111 | if (listName === 'userlist') {
|
112 | return Promise.reject(new ChatServiceError('notAllowed'));
|
113 | }
|
114 | if (bypassPermissions) {
|
115 | return Promise.resolve();
|
116 | }
|
117 | return this.roomState.ownerGet().then(function (owner) {
|
118 | if (author === owner) {
|
119 | return Promise.resolve();
|
120 | }
|
121 | if (listName === 'adminlist') {
|
122 | return Promise.reject(new ChatServiceError('notAllowed'));
|
123 | }
|
124 | return _this4.roomState.hasInList('adminlist', author).then(function (admin) {
|
125 | if (!admin) {
|
126 | return Promise.reject(new ChatServiceError('notAllowed'));
|
127 | }
|
128 | var _iteratorNormalCompletion = true;
|
129 | var _didIteratorError = false;
|
130 | var _iteratorError = undefined;
|
131 |
|
132 | try {
|
133 | for (var _iterator = (0, _getIterator3.default)(values), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
134 | var name = _step.value;
|
135 |
|
136 | if (name !== owner) {
|
137 | continue;
|
138 | }
|
139 | return Promise.reject(new ChatServiceError('notAllowed'));
|
140 | }
|
141 | } catch (err) {
|
142 | _didIteratorError = true;
|
143 | _iteratorError = err;
|
144 | } finally {
|
145 | try {
|
146 | if (!_iteratorNormalCompletion && _iterator.return) {
|
147 | _iterator.return();
|
148 | }
|
149 | } finally {
|
150 | if (_didIteratorError) {
|
151 | throw _iteratorError;
|
152 | }
|
153 | }
|
154 | }
|
155 |
|
156 | return Promise.resolve();
|
157 | });
|
158 | });
|
159 | }
|
160 | }, {
|
161 | key: 'checkModeChange',
|
162 | value: function checkModeChange(author, value, bypassPermissions) {
|
163 | return this.isAdmin(author).then(function (admin) {
|
164 | if (admin || bypassPermissions) {
|
165 | return Promise.resolve();
|
166 | }
|
167 | return Promise.reject(new ChatServiceError('notAllowed'));
|
168 | });
|
169 | }
|
170 | }, {
|
171 | key: 'checkAcess',
|
172 | value: function checkAcess(userName) {
|
173 | return run(this, _regenerator2.default.mark(function _callee() {
|
174 | var admin, blacklisted, whitelistOnly, whitelisted;
|
175 | return _regenerator2.default.wrap(function _callee$(_context) {
|
176 | while (1) {
|
177 | switch (_context.prev = _context.next) {
|
178 | case 0:
|
179 | _context.next = 2;
|
180 | return this.isAdmin(userName);
|
181 |
|
182 | case 2:
|
183 | admin = _context.sent;
|
184 |
|
185 | if (!admin) {
|
186 | _context.next = 5;
|
187 | break;
|
188 | }
|
189 |
|
190 | return _context.abrupt('return', Promise.resolve());
|
191 |
|
192 | case 5:
|
193 | _context.next = 7;
|
194 | return this.roomState.hasInList('blacklist', userName);
|
195 |
|
196 | case 7:
|
197 | blacklisted = _context.sent;
|
198 |
|
199 | if (!blacklisted) {
|
200 | _context.next = 10;
|
201 | break;
|
202 | }
|
203 |
|
204 | return _context.abrupt('return', Promise.reject(new ChatServiceError('notAllowed')));
|
205 |
|
206 | case 10:
|
207 | _context.next = 12;
|
208 | return this.roomState.whitelistOnlyGet();
|
209 |
|
210 | case 12:
|
211 | whitelistOnly = _context.sent;
|
212 |
|
213 | if (whitelistOnly) {
|
214 | _context.next = 15;
|
215 | break;
|
216 | }
|
217 |
|
218 | return _context.abrupt('return', Promise.resolve());
|
219 |
|
220 | case 15:
|
221 | _context.next = 17;
|
222 | return this.roomState.hasInList('whitelist', userName);
|
223 |
|
224 | case 17:
|
225 | whitelisted = _context.sent;
|
226 |
|
227 | if (!whitelisted) {
|
228 | _context.next = 20;
|
229 | break;
|
230 | }
|
231 |
|
232 | return _context.abrupt('return', Promise.resolve());
|
233 |
|
234 | case 20:
|
235 | return _context.abrupt('return', Promise.reject(new ChatServiceError('notAllowed')));
|
236 |
|
237 | case 21:
|
238 | case 'end':
|
239 | return _context.stop();
|
240 | }
|
241 | }
|
242 | }, _callee, this);
|
243 | }));
|
244 | }
|
245 | }, {
|
246 | key: 'checkRead',
|
247 | value: function checkRead(author, bypassPermissions) {
|
248 | if (bypassPermissions) {
|
249 | return Promise.resolve();
|
250 | }
|
251 | return run(this, _regenerator2.default.mark(function _callee2() {
|
252 | var hasAuthor, admin;
|
253 | return _regenerator2.default.wrap(function _callee2$(_context2) {
|
254 | while (1) {
|
255 | switch (_context2.prev = _context2.next) {
|
256 | case 0:
|
257 | _context2.next = 2;
|
258 | return this.roomState.hasInList('userlist', author);
|
259 |
|
260 | case 2:
|
261 | hasAuthor = _context2.sent;
|
262 |
|
263 | if (!hasAuthor) {
|
264 | _context2.next = 5;
|
265 | break;
|
266 | }
|
267 |
|
268 | return _context2.abrupt('return', Promise.resolve());
|
269 |
|
270 | case 5:
|
271 | _context2.next = 7;
|
272 | return this.isAdmin(author);
|
273 |
|
274 | case 7:
|
275 | admin = _context2.sent;
|
276 |
|
277 | if (!admin) {
|
278 | _context2.next = 10;
|
279 | break;
|
280 | }
|
281 |
|
282 | return _context2.abrupt('return', Promise.resolve());
|
283 |
|
284 | case 10:
|
285 | return _context2.abrupt('return', Promise.reject(new ChatServiceError('notJoined', this.roomName)));
|
286 |
|
287 | case 11:
|
288 | case 'end':
|
289 | return _context2.stop();
|
290 | }
|
291 | }
|
292 | }, _callee2, this);
|
293 | }));
|
294 | }
|
295 | }, {
|
296 | key: 'checkIsOwner',
|
297 | value: function checkIsOwner(author, bypassPermissions) {
|
298 | if (bypassPermissions) {
|
299 | return Promise.resolve();
|
300 | }
|
301 | return this.roomState.ownerGet().then(function (owner) {
|
302 | if (owner === author) {
|
303 | return Promise.resolve();
|
304 | }
|
305 | return Promise.reject(new ChatServiceError('notAllowed'));
|
306 | });
|
307 | }
|
308 | }]);
|
309 | return RoomPermissions;
|
310 | }();
|
311 |
|
312 | // Implements room messaging state manipulations with the respect to
|
313 | // user's permissions.
|
314 |
|
315 |
|
316 | var Room = function () {
|
317 | function Room(server, roomName) {
|
318 | (0, _classCallCheck3.default)(this, Room);
|
319 |
|
320 | this.server = server;
|
321 | this.roomName = roomName;
|
322 | this.listSizeLimit = this.server.roomListSizeLimit;
|
323 | var State = this.server.state.RoomState;
|
324 | this.roomState = new State(this.server, this.roomName);
|
325 | mixin(this, RoomPermissions, this.roomName, this.roomState, this.server.emit.bind(this.server));
|
326 | }
|
327 |
|
328 | (0, _createClass3.default)(Room, [{
|
329 | key: 'initState',
|
330 | value: function initState(state) {
|
331 | return this.roomState.initState(state);
|
332 | }
|
333 | }, {
|
334 | key: 'removeState',
|
335 | value: function removeState() {
|
336 | return this.roomState.removeState();
|
337 | }
|
338 | }, {
|
339 | key: 'startRemoving',
|
340 | value: function startRemoving() {
|
341 | return this.roomState.startRemoving();
|
342 | }
|
343 | }, {
|
344 | key: 'getUsers',
|
345 | value: function getUsers() {
|
346 | return this.roomState.getList('userlist');
|
347 | }
|
348 | }, {
|
349 | key: 'leave',
|
350 | value: function leave(author) {
|
351 | var _this5 = this;
|
352 |
|
353 | return this.roomState.hasInList('userlist', author).then(function (hasAuthor) {
|
354 | if (!hasAuthor) {
|
355 | return Promise.resolve();
|
356 | }
|
357 | return _this5.roomState.removeFromList('userlist', [author]).then(function () {
|
358 | return _this5.roomState.userSeenUpdate(author);
|
359 | });
|
360 | });
|
361 | }
|
362 | }, {
|
363 | key: 'join',
|
364 | value: function join(author) {
|
365 | var _this6 = this;
|
366 |
|
367 | return this.checkAcess(author).then(function () {
|
368 | return _this6.roomState.hasInList('userlist', author);
|
369 | }).then(function (hasAuthor) {
|
370 | if (hasAuthor) {
|
371 | return Promise.resolve();
|
372 | }
|
373 | return _this6.roomState.userSeenUpdate(author).then(function () {
|
374 | return _this6.roomState.addToList('userlist', [author]);
|
375 | });
|
376 | });
|
377 | }
|
378 | }, {
|
379 | key: 'message',
|
380 | value: function message(author, msg, bypassPermissions) {
|
381 | var _this7 = this;
|
382 |
|
383 | return Promise.try(function () {
|
384 | if (bypassPermissions) {
|
385 | return Promise.resolve();
|
386 | }
|
387 | return _this7.roomState.hasInList('userlist', author).then(function (hasAuthor) {
|
388 | if (hasAuthor) {
|
389 | return Promise.resolve();
|
390 | }
|
391 | return Promise.reject(new ChatServiceError('notJoined', _this7.roomName));
|
392 | });
|
393 | }).then(function () {
|
394 | return _this7.roomState.messageAdd(msg);
|
395 | });
|
396 | }
|
397 | }, {
|
398 | key: 'getList',
|
399 | value: function getList(author, listName, bypassPermissions) {
|
400 | var _this8 = this;
|
401 |
|
402 | return this.checkRead(author, bypassPermissions).then(function () {
|
403 | return _this8.roomState.getList(listName);
|
404 | });
|
405 | }
|
406 | }, {
|
407 | key: 'getRecentMessages',
|
408 | value: function getRecentMessages(author, bypassPermissions) {
|
409 | var _this9 = this;
|
410 |
|
411 | return this.checkRead(author, bypassPermissions).then(function () {
|
412 | return _this9.roomState.messagesGetRecent();
|
413 | });
|
414 | }
|
415 | }, {
|
416 | key: 'getHistoryInfo',
|
417 | value: function getHistoryInfo(author, bypassPermissions) {
|
418 | var _this10 = this;
|
419 |
|
420 | return this.checkRead(author, bypassPermissions).then(function () {
|
421 | return _this10.roomState.historyInfo();
|
422 | });
|
423 | }
|
424 | }, {
|
425 | key: 'getNotificationsInfo',
|
426 | value: function getNotificationsInfo(author, bypassPermissions) {
|
427 | var _this11 = this;
|
428 |
|
429 | return this.checkRead(author, bypassPermissions).then(function () {
|
430 | return Promise.join(_this11.roomState.userlistUpdatesGet(), _this11.roomState.accessListsUpdatesGet(), function (enableUserlistUpdates, enableAccessListsUpdates) {
|
431 | return { enableUserlistUpdates: enableUserlistUpdates, enableAccessListsUpdates: enableAccessListsUpdates };
|
432 | });
|
433 | });
|
434 | }
|
435 | }, {
|
436 | key: 'getMessages',
|
437 | value: function getMessages(author, id, limit, bypassPermissions) {
|
438 | var _this12 = this;
|
439 |
|
440 | return this.checkRead(author, bypassPermissions).then(function () {
|
441 | if (!bypassPermissions) {
|
442 | limit = _.min([limit, _this12.server.historyMaxGetMessages]);
|
443 | }
|
444 | return _this12.roomState.messagesGet(id, limit);
|
445 | });
|
446 | }
|
447 | }, {
|
448 | key: 'addToList',
|
449 | value: function addToList(author, listName, values, bypassPermissions) {
|
450 | var _this13 = this;
|
451 |
|
452 | return this.checkListChanges(author, listName, values, bypassPermissions).then(function () {
|
453 | return _this13.roomState.addToList(listName, values, _this13.listSizeLimit);
|
454 | }).then(function () {
|
455 | return Promise.filter(values, function (val) {
|
456 | return _this13.hasAddChangedCurrentAccess(val, listName);
|
457 | }, { concurrency: asyncLimit });
|
458 | });
|
459 | }
|
460 | }, {
|
461 | key: 'removeFromList',
|
462 | value: function removeFromList(author, listName, values, bypassPermissions) {
|
463 | var _this14 = this;
|
464 |
|
465 | return this.checkListChanges(author, listName, values, bypassPermissions).then(function () {
|
466 | return _this14.roomState.removeFromList(listName, values);
|
467 | }).then(function () {
|
468 | return Promise.filter(values, function (val) {
|
469 | return _this14.hasRemoveChangedCurrentAccess(val, listName);
|
470 | }, { concurrency: asyncLimit });
|
471 | });
|
472 | }
|
473 | }, {
|
474 | key: 'getMode',
|
475 | value: function getMode(author, bypassPermissions) {
|
476 | var _this15 = this;
|
477 |
|
478 | return this.checkRead(author, bypassPermissions).then(function () {
|
479 | return _this15.roomState.whitelistOnlyGet();
|
480 | });
|
481 | }
|
482 | }, {
|
483 | key: 'getOwner',
|
484 | value: function getOwner(author, bypassPermissions) {
|
485 | var _this16 = this;
|
486 |
|
487 | return this.checkRead(author, bypassPermissions).then(function () {
|
488 | return _this16.roomState.ownerGet();
|
489 | });
|
490 | }
|
491 | }, {
|
492 | key: 'changeMode',
|
493 | value: function changeMode(author, mode, bypassPermissions) {
|
494 | var _this17 = this;
|
495 |
|
496 | var whitelistOnly = mode;
|
497 | return this.checkModeChange(author, mode, bypassPermissions).then(function () {
|
498 | return _this17.roomState.whitelistOnlySet(whitelistOnly);
|
499 | }).then(function () {
|
500 | return _this17.getModeChangedCurrentAccess(whitelistOnly);
|
501 | }).then(function (usernames) {
|
502 | return [usernames, whitelistOnly];
|
503 | });
|
504 | }
|
505 | }, {
|
506 | key: 'userSeen',
|
507 | value: function userSeen(author, userName, bypassPermissions) {
|
508 | var _this18 = this;
|
509 |
|
510 | return this.checkRead(author, bypassPermissions).then(function () {
|
511 | return _this18.roomState.userSeenGet(userName);
|
512 | });
|
513 | }
|
514 | }]);
|
515 | return Room;
|
516 | }();
|
517 |
|
518 | module.exports = Room;
|
519 | //# sourceMappingURL=data:application/json;base64,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LE9BREQsQ0FBUDtBQUVEOzs7K0JBRVcsTSxFQUFRLEksRUFBTSxpQixFQUFtQjtBQUFBOztBQUMzQyxVQUFJLGdCQUFnQixJQUFwQjtBQUNBLGFBQU8sS0FBSyxlQUFMLENBQXFCLE1BQXJCLEVBQTZCLElBQTdCLEVBQW1DLGlCQUFuQyxFQUNKLElBREksQ0FDQztBQUFBLGVBQU0sUUFBSyxTQUFMLENBQWUsZ0JBQWYsQ0FBZ0MsYUFBaEMsQ0FBTjtBQUFBLE9BREQsRUFFSixJQUZJLENBRUM7QUFBQSxlQUFNLFFBQUssMkJBQUwsQ0FBaUMsYUFBakMsQ0FBTjtBQUFBLE9BRkQsRUFHSixJQUhJLENBR0M7QUFBQSxlQUFhLENBQUUsU0FBRixFQUFhLGFBQWIsQ0FBYjtBQUFBLE9BSEQsQ0FBUDtBQUlEOzs7NkJBRVMsTSxFQUFRLFEsRUFBVSxpQixFQUFtQjtBQUFBOztBQUM3QyxhQUFPLEtBQUssU0FBTCxDQUFlLE1BQWYsRUFBdUIsaUJBQXZCLEVBQ0osSUFESSxDQUNDO0FBQUEsZUFBTSxRQUFLLFNBQUwsQ0FBZSxXQUFmLENBQTJCLFFBQTNCLENBQU47QUFBQSxPQURELENBQVA7QUFFRDs7Ozs7QUFJSCxPQUFPLE9BQVAsR0FBaUIsSUFBakIiLCJmaWxlIjoiUm9vbS5qcyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0J1xuXG5jb25zdCBDaGF0U2VydmljZUVycm9yID0gcmVxdWlyZSgnLi9DaGF0U2VydmljZUVycm9yJylcbmNvbnN0IFByb21pc2UgPSByZXF1aXJlKCdibHVlYmlyZCcpXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJylcbmNvbnN0IHsgbWl4aW4gfSA9IHJlcXVpcmUoJ2VzNi1taXhpbicpXG5jb25zdCB7IGFzeW5jTGltaXQsIHJ1biB9ID0gcmVxdWlyZSgnLi91dGlscycpXG5cbmNsYXNzIFJvb21QZXJtaXNzaW9ucyB7XG5cbiAgY29uc3RydWN0b3IgKHJvb21OYW1lLCByb29tU3RhdGUsIGVtaXRGYWlsdXJlKSB7XG4gICAgdGhpcy5yb29tTmFtZSA9IHJvb21OYW1lXG4gICAgdGhpcy5yb29tU3RhdGUgPSByb29tU3RhdGVcbiAgICB0aGlzLmVtaXRGYWlsdXJlID0gZW1pdEZhaWx1cmVcbiAgfVxuXG4gIGNvbnNpc3RlbmN5RmFpbHVyZSAoZXJyb3IsIG9wZXJhdGlvbkluZm8pIHtcbiAgICBvcGVyYXRpb25JbmZvLnJvb21OYW1lID0gdGhpcy5yb29tTmFtZVxuICAgIG9wZXJhdGlvbkluZm8ub3BUeXBlID0gJ3Jvb21Vc2VybGlzdCdcbiAgICB0aGlzLmVtaXRGYWlsdXJlKCdzdG9yZUNvbnNpc3RlbmN5RmFpbHVyZScsIGVycm9yLCBvcGVyYXRpb25JbmZvKVxuICB9XG5cbiAgaXNBZG1pbiAodXNlck5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUub3duZXJHZXQoKS50aGVuKG93bmVyID0+IHtcbiAgICAgIGlmIChvd25lciA9PT0gdXNlck5hbWUpIHsgcmV0dXJuIHRydWUgfVxuICAgICAgcmV0dXJuIHRoaXMucm9vbVN0YXRlLmhhc0luTGlzdCgnYWRtaW5saXN0JywgdXNlck5hbWUpXG4gICAgfSlcbiAgfVxuXG4gIGhhc1JlbW92ZUNoYW5nZWRDdXJyZW50QWNjZXNzICh1c2VyTmFtZSwgbGlzdE5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUuaGFzSW5MaXN0KCd1c2VybGlzdCcsIHVzZXJOYW1lKS50aGVuKGhhc1VzZXIgPT4ge1xuICAgICAgaWYgKCFoYXNVc2VyKSB7IHJldHVybiBmYWxzZSB9XG4gICAgICByZXR1cm4gdGhpcy5pc0FkbWluKHVzZXJOYW1lKS50aGVuKGFkbWluID0+IHtcbiAgICAgICAgaWYgKGFkbWluIHx8IGxpc3ROYW1lICE9PSAnd2hpdGVsaXN0JykgeyByZXR1cm4gZmFsc2UgfVxuICAgICAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUud2hpdGVsaXN0T25seUdldCgpXG4gICAgICB9KVxuICAgIH0pLmNhdGNoKGUgPT4gdGhpcy5jb25zaXN0ZW5jeUZhaWx1cmUoZSwge3VzZXJOYW1lfSkpXG4gIH1cblxuICBoYXNBZGRDaGFuZ2VkQ3VycmVudEFjY2VzcyAodXNlck5hbWUsIGxpc3ROYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vbVN0YXRlLmhhc0luTGlzdCgndXNlcmxpc3QnLCB1c2VyTmFtZSkudGhlbihoYXNVc2VyID0+IHtcbiAgICAgIGlmICghaGFzVXNlcikgeyByZXR1cm4gZmFsc2UgfVxuICAgICAgcmV0dXJuIHRoaXMuaXNBZG1pbih1c2VyTmFtZSlcbiAgICAgICAgLnRoZW4oYWRtaW4gPT4gIShhZG1pbiB8fCBsaXN0TmFtZSAhPT0gJ2JsYWNrbGlzdCcpKVxuICAgIH0pLmNhdGNoKGUgPT4gdGhpcy5jb25zaXN0ZW5jeUZhaWx1cmUoZSwge3VzZXJOYW1lfSkpXG4gIH1cblxuICBnZXRNb2RlQ2hhbmdlZEN1cnJlbnRBY2Nlc3MgKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuIFtdXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5nZXRDb21tb25Vc2VycygpXG4gICAgfVxuICB9XG5cbiAgY2hlY2tMaXN0Q2hhbmdlcyAoYXV0aG9yLCBsaXN0TmFtZSwgdmFsdWVzLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIGlmIChsaXN0TmFtZSA9PT0gJ3VzZXJsaXN0Jykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RBbGxvd2VkJykpXG4gICAgfVxuICAgIGlmIChieXBhc3NQZXJtaXNzaW9ucykgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkgfVxuICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5vd25lckdldCgpLnRoZW4ob3duZXIgPT4ge1xuICAgICAgaWYgKGF1dGhvciA9PT0gb3duZXIpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgIGlmIChsaXN0TmFtZSA9PT0gJ2FkbWlubGlzdCcpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RBbGxvd2VkJykpXG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUuaGFzSW5MaXN0KCdhZG1pbmxpc3QnLCBhdXRob3IpLnRoZW4oYWRtaW4gPT4ge1xuICAgICAgICBpZiAoIWFkbWluKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RBbGxvd2VkJykpXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbmFtZSBvZiB2YWx1ZXMpIHtcbiAgICAgICAgICBpZiAobmFtZSAhPT0gb3duZXIpIHsgY29udGludWUgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgQ2hhdFNlcnZpY2VFcnJvcignbm90QWxsb3dlZCcpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgY2hlY2tNb2RlQ2hhbmdlIChhdXRob3IsIHZhbHVlLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmlzQWRtaW4oYXV0aG9yKS50aGVuKGFkbWluID0+IHtcbiAgICAgIGlmIChhZG1pbiB8fCBieXBhc3NQZXJtaXNzaW9ucykgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RBbGxvd2VkJykpXG4gICAgfSlcbiAgfVxuXG4gIGNoZWNrQWNlc3MgKHVzZXJOYW1lKSB7XG4gICAgcmV0dXJuIHJ1bih0aGlzLCBmdW5jdGlvbiAqICgpIHtcbiAgICAgIGxldCBhZG1pbiA9IHlpZWxkIHRoaXMuaXNBZG1pbih1c2VyTmFtZSlcbiAgICAgIGlmIChhZG1pbikgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkgfVxuICAgICAgbGV0IGJsYWNrbGlzdGVkID0geWllbGQgdGhpcy5yb29tU3RhdGUuaGFzSW5MaXN0KCdibGFja2xpc3QnLCB1c2VyTmFtZSlcbiAgICAgIGlmIChibGFja2xpc3RlZCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IENoYXRTZXJ2aWNlRXJyb3IoJ25vdEFsbG93ZWQnKSlcbiAgICAgIH1cbiAgICAgIGxldCB3aGl0ZWxpc3RPbmx5ID0geWllbGQgdGhpcy5yb29tU3RhdGUud2hpdGVsaXN0T25seUdldCgpXG4gICAgICBpZiAoIXdoaXRlbGlzdE9ubHkpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgIGxldCB3aGl0ZWxpc3RlZCA9IHlpZWxkIHRoaXMucm9vbVN0YXRlLmhhc0luTGlzdCgnd2hpdGVsaXN0JywgdXNlck5hbWUpXG4gICAgICBpZiAod2hpdGVsaXN0ZWQpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgQ2hhdFNlcnZpY2VFcnJvcignbm90QWxsb3dlZCcpKVxuICAgIH0pXG4gIH1cblxuICBjaGVja1JlYWQgKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICBpZiAoYnlwYXNzUGVybWlzc2lvbnMpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICByZXR1cm4gcnVuKHRoaXMsIGZ1bmN0aW9uICogKCkge1xuICAgICAgbGV0IGhhc0F1dGhvciA9IHlpZWxkIHRoaXMucm9vbVN0YXRlLmhhc0luTGlzdCgndXNlcmxpc3QnLCBhdXRob3IpXG4gICAgICBpZiAoaGFzQXV0aG9yKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUoKSB9XG4gICAgICBsZXQgYWRtaW4gPSB5aWVsZCB0aGlzLmlzQWRtaW4oYXV0aG9yKVxuICAgICAgaWYgKGFkbWluKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUoKSB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IENoYXRTZXJ2aWNlRXJyb3IoJ25vdEpvaW5lZCcsIHRoaXMucm9vbU5hbWUpKVxuICAgIH0pXG4gIH1cblxuICBjaGVja0lzT3duZXIgKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICBpZiAoYnlwYXNzUGVybWlzc2lvbnMpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUub3duZXJHZXQoKS50aGVuKG93bmVyID0+IHtcbiAgICAgIGlmIChvd25lciA9PT0gYXV0aG9yKSB7IHJldHVybiBQcm9taXNlLnJlc29sdmUoKSB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IENoYXRTZXJ2aWNlRXJyb3IoJ25vdEFsbG93ZWQnKSlcbiAgICB9KVxuICB9XG5cbn1cblxuLy8gSW1wbGVtZW50cyByb29tIG1lc3NhZ2luZyBzdGF0ZSBtYW5pcHVsYXRpb25zIHdpdGggdGhlIHJlc3BlY3QgdG9cbi8vIHVzZXIncyBwZXJtaXNzaW9ucy5cbmNsYXNzIFJvb20ge1xuXG4gIGNvbnN0cnVjdG9yIChzZXJ2ZXIsIHJvb21OYW1lKSB7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXJcbiAgICB0aGlzLnJvb21OYW1lID0gcm9vbU5hbWVcbiAgICB0aGlzLmxpc3RTaXplTGltaXQgPSB0aGlzLnNlcnZlci5yb29tTGlzdFNpemVMaW1pdFxuICAgIGxldCBTdGF0ZSA9IHRoaXMuc2VydmVyLnN0YXRlLlJvb21TdGF0ZVxuICAgIHRoaXMucm9vbVN0YXRlID0gbmV3IFN0YXRlKHRoaXMuc2VydmVyLCB0aGlzLnJvb21OYW1lKVxuICAgIG1peGluKHRoaXMsIFJvb21QZXJtaXNzaW9ucywgdGhpcy5yb29tTmFtZSxcbiAgICAgICAgICB0aGlzLnJvb21TdGF0ZSwgdGhpcy5zZXJ2ZXIuZW1pdC5iaW5kKHRoaXMuc2VydmVyKSlcbiAgfVxuXG4gIGluaXRTdGF0ZSAoc3RhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUuaW5pdFN0YXRlKHN0YXRlKVxuICB9XG5cbiAgcmVtb3ZlU3RhdGUgKCkge1xuICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5yZW1vdmVTdGF0ZSgpXG4gIH1cblxuICBzdGFydFJlbW92aW5nICgpIHtcbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUuc3RhcnRSZW1vdmluZygpXG4gIH1cblxuICBnZXRVc2VycyAoKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vbVN0YXRlLmdldExpc3QoJ3VzZXJsaXN0JylcbiAgfVxuXG4gIGxlYXZlIChhdXRob3IpIHtcbiAgICByZXR1cm4gdGhpcy5yb29tU3RhdGUuaGFzSW5MaXN0KCd1c2VybGlzdCcsIGF1dGhvcikudGhlbihoYXNBdXRob3IgPT4ge1xuICAgICAgaWYgKCFoYXNBdXRob3IpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5yZW1vdmVGcm9tTGlzdCgndXNlcmxpc3QnLCBbYXV0aG9yXSlcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yb29tU3RhdGUudXNlclNlZW5VcGRhdGUoYXV0aG9yKSlcbiAgICB9KVxuICB9XG5cbiAgam9pbiAoYXV0aG9yKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hlY2tBY2VzcyhhdXRob3IpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS5oYXNJbkxpc3QoJ3VzZXJsaXN0JywgYXV0aG9yKSlcbiAgICAgIC50aGVuKGhhc0F1dGhvciA9PiB7XG4gICAgICAgIGlmIChoYXNBdXRob3IpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucm9vbVN0YXRlLnVzZXJTZWVuVXBkYXRlKGF1dGhvcilcbiAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS5hZGRUb0xpc3QoJ3VzZXJsaXN0JywgW2F1dGhvcl0pKVxuICAgICAgfSlcbiAgfVxuXG4gIG1lc3NhZ2UgKGF1dGhvciwgbXNnLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnRyeSgoKSA9PiB7XG4gICAgICBpZiAoYnlwYXNzUGVybWlzc2lvbnMpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5oYXNJbkxpc3QoJ3VzZXJsaXN0JywgYXV0aG9yKS50aGVuKGhhc0F1dGhvciA9PiB7XG4gICAgICAgIGlmIChoYXNBdXRob3IpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub3RKb2luZWQnLCB0aGlzLnJvb21OYW1lKSlcbiAgICAgIH0pXG4gICAgfSkudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS5tZXNzYWdlQWRkKG1zZykpXG4gIH1cblxuICBnZXRMaXN0IChhdXRob3IsIGxpc3ROYW1lLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVhZChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yb29tU3RhdGUuZ2V0TGlzdChsaXN0TmFtZSkpXG4gIH1cblxuICBnZXRSZWNlbnRNZXNzYWdlcyAoYXV0aG9yLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVhZChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yb29tU3RhdGUubWVzc2FnZXNHZXRSZWNlbnQoKSlcbiAgfVxuXG4gIGdldEhpc3RvcnlJbmZvIChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hlY2tSZWFkKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS5oaXN0b3J5SW5mbygpKVxuICB9XG5cbiAgZ2V0Tm90aWZpY2F0aW9uc0luZm8gKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jaGVja1JlYWQoYXV0aG9yLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICAgIC50aGVuKCgpID0+IFByb21pc2Uuam9pbihcbiAgICAgICAgdGhpcy5yb29tU3RhdGUudXNlcmxpc3RVcGRhdGVzR2V0KCksXG4gICAgICAgIHRoaXMucm9vbVN0YXRlLmFjY2Vzc0xpc3RzVXBkYXRlc0dldCgpLFxuICAgICAgICAoZW5hYmxlVXNlcmxpc3RVcGRhdGVzLCBlbmFibGVBY2Nlc3NMaXN0c1VwZGF0ZXMpID0+XG4gICAgICAgICAgKHsgZW5hYmxlVXNlcmxpc3RVcGRhdGVzLCBlbmFibGVBY2Nlc3NMaXN0c1VwZGF0ZXMgfSkpKVxuICB9XG5cbiAgZ2V0TWVzc2FnZXMgKGF1dGhvciwgaWQsIGxpbWl0LCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVhZChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICghYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICAgICAgbGltaXQgPSBfLm1pbihbIGxpbWl0LCB0aGlzLnNlcnZlci5oaXN0b3J5TWF4R2V0TWVzc2FnZXMgXSlcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnJvb21TdGF0ZS5tZXNzYWdlc0dldChpZCwgbGltaXQpXG4gICAgfSlcbiAgfVxuXG4gIGFkZFRvTGlzdCAoYXV0aG9yLCBsaXN0TmFtZSwgdmFsdWVzLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrTGlzdENoYW5nZXMoYXV0aG9yLCBsaXN0TmFtZSwgdmFsdWVzLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICAgIC50aGVuKCgpID0+IHRoaXMucm9vbVN0YXRlLmFkZFRvTGlzdChsaXN0TmFtZSwgdmFsdWVzLCB0aGlzLmxpc3RTaXplTGltaXQpKVxuICAgICAgLnRoZW4oKCkgPT4gUHJvbWlzZS5maWx0ZXIoXG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgdmFsID0+IHRoaXMuaGFzQWRkQ2hhbmdlZEN1cnJlbnRBY2Nlc3ModmFsLCBsaXN0TmFtZSksXG4gICAgICAgIHsgY29uY3VycmVuY3k6IGFzeW5jTGltaXQgfSkpXG4gIH1cblxuICByZW1vdmVGcm9tTGlzdCAoYXV0aG9yLCBsaXN0TmFtZSwgdmFsdWVzLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrTGlzdENoYW5nZXMoYXV0aG9yLCBsaXN0TmFtZSwgdmFsdWVzLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICAgIC50aGVuKCgpID0+IHRoaXMucm9vbVN0YXRlLnJlbW92ZUZyb21MaXN0KGxpc3ROYW1lLCB2YWx1ZXMpKVxuICAgICAgLnRoZW4oKCkgPT4gUHJvbWlzZS5maWx0ZXIoXG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgdmFsID0+IHRoaXMuaGFzUmVtb3ZlQ2hhbmdlZEN1cnJlbnRBY2Nlc3ModmFsLCBsaXN0TmFtZSksXG4gICAgICAgIHsgY29uY3VycmVuY3k6IGFzeW5jTGltaXQgfSkpXG4gIH1cblxuICBnZXRNb2RlIChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hlY2tSZWFkKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS53aGl0ZWxpc3RPbmx5R2V0KCkpXG4gIH1cblxuICBnZXRPd25lciAoYXV0aG9yLCBieXBhc3NQZXJtaXNzaW9ucykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrUmVhZChhdXRob3IsIGJ5cGFzc1Blcm1pc3Npb25zKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yb29tU3RhdGUub3duZXJHZXQoKSlcbiAgfVxuXG4gIGNoYW5nZU1vZGUgKGF1dGhvciwgbW9kZSwgYnlwYXNzUGVybWlzc2lvbnMpIHtcbiAgICBsZXQgd2hpdGVsaXN0T25seSA9IG1vZGVcbiAgICByZXR1cm4gdGhpcy5jaGVja01vZGVDaGFuZ2UoYXV0aG9yLCBtb2RlLCBieXBhc3NQZXJtaXNzaW9ucylcbiAgICAgIC50aGVuKCgpID0+IHRoaXMucm9vbVN0YXRlLndoaXRlbGlzdE9ubHlTZXQod2hpdGVsaXN0T25seSkpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmdldE1vZGVDaGFuZ2VkQ3VycmVudEFjY2Vzcyh3aGl0ZWxpc3RPbmx5KSlcbiAgICAgIC50aGVuKHVzZXJuYW1lcyA9PiBbIHVzZXJuYW1lcywgd2hpdGVsaXN0T25seSBdKVxuICB9XG5cbiAgdXNlclNlZW4gKGF1dGhvciwgdXNlck5hbWUsIGJ5cGFzc1Blcm1pc3Npb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hlY2tSZWFkKGF1dGhvciwgYnlwYXNzUGVybWlzc2lvbnMpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnJvb21TdGF0ZS51c2VyU2VlbkdldCh1c2VyTmFtZSkpXG4gIH1cblxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFJvb21cbiJdfQ== |
\ | No newline at end of file |