1 | ;
|
2 |
|
3 | var _regenerator = require('babel-runtime/regenerator');
|
4 |
|
5 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
6 |
|
7 | var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
8 |
|
9 | var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
|
10 |
|
11 | var _getIterator2 = require('babel-runtime/core-js/get-iterator');
|
12 |
|
13 | var _getIterator3 = _interopRequireDefault(_getIterator2);
|
14 |
|
15 | var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
|
16 |
|
17 | var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
|
18 |
|
19 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
20 |
|
21 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
22 |
|
23 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
24 |
|
25 | var _createClass3 = _interopRequireDefault(_createClass2);
|
26 |
|
27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
28 |
|
29 | var ChatServiceError = require('./ChatServiceError');
|
30 | var Promise = require('bluebird');
|
31 | var RedisAdapter = require('socket.io-redis');
|
32 | var SocketIOClusterBus = require('./SocketIOClusterBus');
|
33 | var SocketServer = require('socket.io');
|
34 | var _ = require('lodash');
|
35 |
|
36 | var _require = require('./utils');
|
37 |
|
38 | var run = _require.run;
|
39 |
|
40 | // Socket.io transport.
|
41 |
|
42 | var SocketIOTransport = function () {
|
43 | function SocketIOTransport(server, options, adapterConstructor, adapterOptions) {
|
44 | var _this = this;
|
45 |
|
46 | (0, _classCallCheck3.default)(this, SocketIOTransport);
|
47 |
|
48 | this.server = server;
|
49 | this.options = options;
|
50 | this.adapterConstructor = adapterConstructor;
|
51 | this.adapterOptions = adapterOptions;
|
52 | this.port = this.server.port;
|
53 | this.io = this.options.io;
|
54 | this.middleware = options.middleware;
|
55 | this.namespace = this.options.namespace || '/chat-service';
|
56 | var Adapter = function () {
|
57 | switch (true) {
|
58 | case _this.adapterConstructor === 'memory':
|
59 | return null;
|
60 | case _this.adapterConstructor === 'redis':
|
61 | return RedisAdapter;
|
62 | case _.isFunction(_this.adapterConstructor):
|
63 | return _this.adapterConstructor;
|
64 | default:
|
65 | var c = _this.adapterConstructor;
|
66 | throw new Error('Invalid transport adapter: ' + c);
|
67 | }
|
68 | }();
|
69 | if (!this.io) {
|
70 | this.ioOptions = this.options.ioOptions;
|
71 | this.http = this.options.http;
|
72 | if (this.http) {
|
73 | this.dontCloseIO = true;
|
74 | this.io = new SocketServer(this.options.http, this.ioOptions);
|
75 | } else {
|
76 | this.io = new SocketServer(this.port, this.ioOptions);
|
77 | }
|
78 | if (Adapter) {
|
79 | this.adapter = new (Function.prototype.bind.apply(Adapter, [null].concat((0, _toConsumableArray3.default)(this.adapterOptions))))();
|
80 | this.io.adapter(this.adapter);
|
81 | }
|
82 | } else {
|
83 | this.dontCloseIO = true;
|
84 | }
|
85 | this.nsp = this.io.of(this.namespace);
|
86 | this.server.io = this.io;
|
87 | this.server.nsp = this.nsp;
|
88 | this.clusterBus = new SocketIOClusterBus(this.server, this.nsp.adapter);
|
89 | this.closed = false;
|
90 | }
|
91 |
|
92 | (0, _createClass3.default)(SocketIOTransport, [{
|
93 | key: 'rejectLogin',
|
94 | value: function rejectLogin(socket, error) {
|
95 | error = this.server.convertError(error);
|
96 | socket.emit('loginRejected', error);
|
97 | socket.disconnect();
|
98 | }
|
99 | }, {
|
100 | key: 'confirmLogin',
|
101 | value: function confirmLogin(socket, userName, authData) {
|
102 | authData.id = socket.id;
|
103 | socket.emit('loginConfirmed', userName, authData);
|
104 | }
|
105 | }, {
|
106 | key: 'ensureUserName',
|
107 | value: function ensureUserName(socket, userName) {
|
108 | return Promise.try(function () {
|
109 | if (!userName) {
|
110 | var query = socket.handshake.query;
|
111 |
|
112 | userName = query && query.user;
|
113 | if (!userName) {
|
114 | return Promise.reject(new ChatServiceError('noLogin'));
|
115 | }
|
116 | }
|
117 | return Promise.resolve(userName);
|
118 | });
|
119 | }
|
120 | }, {
|
121 | key: 'setEvents',
|
122 | value: function setEvents() {
|
123 | var _this2 = this;
|
124 |
|
125 | if (this.middleware) {
|
126 | var middleware = _.castArray(this.middleware);
|
127 | var _iteratorNormalCompletion = true;
|
128 | var _didIteratorError = false;
|
129 | var _iteratorError = undefined;
|
130 |
|
131 | try {
|
132 | for (var _iterator = (0, _getIterator3.default)(middleware), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
133 | var fn = _step.value;
|
134 |
|
135 | this.nsp.use(fn);
|
136 | }
|
137 | } catch (err) {
|
138 | _didIteratorError = true;
|
139 | _iteratorError = err;
|
140 | } finally {
|
141 | try {
|
142 | if (!_iteratorNormalCompletion && _iterator.return) {
|
143 | _iterator.return();
|
144 | }
|
145 | } finally {
|
146 | if (_didIteratorError) {
|
147 | throw _iteratorError;
|
148 | }
|
149 | }
|
150 | }
|
151 | }
|
152 | this.nsp.on('connection', function (socket) {
|
153 | return run(_this2, _regenerator2.default.mark(function _callee() {
|
154 | var id, _ref, _ref2, userName, _ref2$, authData;
|
155 |
|
156 | return _regenerator2.default.wrap(function _callee$(_context) {
|
157 | while (1) {
|
158 | switch (_context.prev = _context.next) {
|
159 | case 0:
|
160 | id = socket.id;
|
161 | _context.next = 3;
|
162 | return this.server.onConnect(id);
|
163 |
|
164 | case 3:
|
165 | _ref = _context.sent;
|
166 | _ref2 = (0, _slicedToArray3.default)(_ref, 2);
|
167 | userName = _ref2[0];
|
168 | _ref2$ = _ref2[1];
|
169 | authData = _ref2$ === undefined ? {} : _ref2$;
|
170 | _context.next = 10;
|
171 | return this.ensureUserName(socket, userName);
|
172 |
|
173 | case 10:
|
174 | userName = _context.sent;
|
175 | _context.next = 13;
|
176 | return this.server.registerClient(userName, id);
|
177 |
|
178 | case 13:
|
179 | this.confirmLogin(socket, userName, authData);
|
180 |
|
181 | case 14:
|
182 | case 'end':
|
183 | return _context.stop();
|
184 | }
|
185 | }
|
186 | }, _callee, this);
|
187 | })).catch(function (error) {
|
188 | return _this2.rejectLogin(socket, error);
|
189 | });
|
190 | });
|
191 | }
|
192 | }, {
|
193 | key: 'close',
|
194 | value: function close() {
|
195 | var _this3 = this;
|
196 |
|
197 | this.closed = true;
|
198 | this.nsp.removeAllListeners('connection');
|
199 | this.clusterBus.removeAllListeners();
|
200 | return Promise.try(function () {
|
201 | if (!_this3.dontCloseIO) {
|
202 | _this3.io.close();
|
203 | } else if (_this3.http) {
|
204 | _this3.io.engine.close();
|
205 | } else {
|
206 | var _iteratorNormalCompletion2 = true;
|
207 | var _didIteratorError2 = false;
|
208 | var _iteratorError2 = undefined;
|
209 |
|
210 | try {
|
211 | for (var _iterator2 = (0, _getIterator3.default)(_.toPairs(_this3.nsp.connected)), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
212 | var _step2$value = (0, _slicedToArray3.default)(_step2.value, 2);
|
213 |
|
214 | var socket = _step2$value[1];
|
215 |
|
216 | socket.disconnect();
|
217 | }
|
218 | } catch (err) {
|
219 | _didIteratorError2 = true;
|
220 | _iteratorError2 = err;
|
221 | } finally {
|
222 | try {
|
223 | if (!_iteratorNormalCompletion2 && _iterator2.return) {
|
224 | _iterator2.return();
|
225 | }
|
226 | } finally {
|
227 | if (_didIteratorError2) {
|
228 | throw _iteratorError2;
|
229 | }
|
230 | }
|
231 | }
|
232 | }
|
233 | return Promise.resolve();
|
234 | });
|
235 | }
|
236 | }, {
|
237 | key: 'bindHandler',
|
238 | value: function bindHandler(id, name, fn) {
|
239 | var socket = this.getSocket(id);
|
240 | if (socket) {
|
241 | socket.on(name, fn);
|
242 | }
|
243 | }
|
244 | }, {
|
245 | key: 'getServer',
|
246 | value: function getServer() {
|
247 | return this.io;
|
248 | }
|
249 | }, {
|
250 | key: 'getSocket',
|
251 | value: function getSocket(id) {
|
252 | return this.nsp.connected[id];
|
253 | }
|
254 | }, {
|
255 | key: 'emitToChannel',
|
256 | value: function emitToChannel(channel, eventName) {
|
257 | var _nsp$to;
|
258 |
|
259 | for (var _len = arguments.length, eventData = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
260 | eventData[_key - 2] = arguments[_key];
|
261 | }
|
262 |
|
263 | (_nsp$to = this.nsp.to(channel)).emit.apply(_nsp$to, [eventName].concat(eventData));
|
264 | }
|
265 | }, {
|
266 | key: 'sendToChannel',
|
267 | value: function sendToChannel(id, channel, eventName) {
|
268 | var socket = this.getSocket(id);
|
269 |
|
270 | for (var _len2 = arguments.length, eventData = Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
|
271 | eventData[_key2 - 3] = arguments[_key2];
|
272 | }
|
273 |
|
274 | if (!socket) {
|
275 | this.emitToChannel.apply(this, [channel, eventName].concat(eventData));
|
276 | } else {
|
277 | var _socket$to;
|
278 |
|
279 | (_socket$to = socket.to(channel)).emit.apply(_socket$to, [eventName].concat(eventData));
|
280 | }
|
281 | }
|
282 | }, {
|
283 | key: 'getHandshakeData',
|
284 | value: function getHandshakeData(id) {
|
285 | var res = { isConnected: false, query: {}, headers: {} };
|
286 | var socket = this.getSocket(id);
|
287 | if (!socket) {
|
288 | return res;
|
289 | }
|
290 | res.isConnected = true;
|
291 | res.query = socket.handshake.query;
|
292 | res.headers = socket.handshake.headers;
|
293 | return res;
|
294 | }
|
295 | }, {
|
296 | key: 'joinChannel',
|
297 | value: function joinChannel(id, channel) {
|
298 | var socket = this.getSocket(id);
|
299 | if (!socket) {
|
300 | return Promise.reject(new ChatServiceError('invalidSocket', id));
|
301 | } else {
|
302 | return Promise.fromCallback(function (fn) {
|
303 | return socket.join(channel, fn);
|
304 | });
|
305 | }
|
306 | }
|
307 | }, {
|
308 | key: 'leaveChannel',
|
309 | value: function leaveChannel(id, channel) {
|
310 | var socket = this.getSocket(id);
|
311 | if (!socket) {
|
312 | return Promise.resolve();
|
313 | }
|
314 | return Promise.fromCallback(function (fn) {
|
315 | return socket.leave(channel, fn);
|
316 | });
|
317 | }
|
318 | }, {
|
319 | key: 'disconnectSocket',
|
320 | value: function disconnectSocket(id) {
|
321 | var socket = this.getSocket(id);
|
322 | if (socket) {
|
323 | socket.disconnect();
|
324 | }
|
325 | return Promise.resolve();
|
326 | }
|
327 | }]);
|
328 | return SocketIOTransport;
|
329 | }();
|
330 |
|
331 | module.exports = SocketIOTransport;
|
332 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Tb2NrZXRJT1RyYW5zcG9ydC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLElBQU0sbUJBQW1CLFFBQVEsb0JBQVIsQ0FBekI7QUFDQSxJQUFNLFVBQVUsUUFBUSxVQUFSLENBQWhCO0FBQ0EsSUFBTSxlQUFlLFFBQVEsaUJBQVIsQ0FBckI7QUFDQSxJQUFNLHFCQUFxQixRQUFRLHNCQUFSLENBQTNCO0FBQ0EsSUFBTSxlQUFlLFFBQVEsV0FBUixDQUFyQjtBQUNBLElBQU0sSUFBSSxRQUFRLFFBQVIsQ0FBVjs7ZUFDZ0IsUUFBUSxTQUFSLEM7O0lBQVIsRyxZQUFBLEc7O0FBRVI7O0lBQ00saUI7QUFFSiw2QkFBYSxNQUFiLEVBQXFCLE9BQXJCLEVBQThCLGtCQUE5QixFQUFrRCxjQUFsRCxFQUFrRTtBQUFBOztBQUFBOztBQUNoRSxTQUFLLE1BQUwsR0FBYyxNQUFkO0FBQ0EsU0FBSyxPQUFMLEdBQWUsT0FBZjtBQUNBLFNBQUssa0JBQUwsR0FBMEIsa0JBQTFCO0FBQ0EsU0FBSyxjQUFMLEdBQXNCLGNBQXRCO0FBQ0EsU0FBSyxJQUFMLEdBQVksS0FBSyxNQUFMLENBQVksSUFBeEI7QUFDQSxTQUFLLEVBQUwsR0FBVSxLQUFLLE9BQUwsQ0FBYSxFQUF2QjtBQUNBLFNBQUssVUFBTCxHQUFrQixRQUFRLFVBQTFCO0FBQ0EsU0FBSyxTQUFMLEdBQWlCLEtBQUssT0FBTCxDQUFhLFNBQWIsSUFBMEIsZUFBM0M7QUFDQSxRQUFJLFVBQVcsWUFBTTtBQUNuQixjQUFRLElBQVI7QUFDRSxhQUFLLE1BQUssa0JBQUwsS0FBNEIsUUFBakM7QUFDRSxpQkFBTyxJQUFQO0FBQ0YsYUFBSyxNQUFLLGtCQUFMLEtBQTRCLE9BQWpDO0FBQ0UsaUJBQU8sWUFBUDtBQUNGLGFBQUssRUFBRSxVQUFGLENBQWEsTUFBSyxrQkFBbEIsQ0FBTDtBQUNFLGlCQUFPLE1BQUssa0JBQVo7QUFDRjtB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QUosR0FBWSxPQUFPLFNBQVAsQ0FBaUIsS0FBN0I7QUFDQSxVQUFJLE9BQUosR0FBYyxPQUFPLFNBQVAsQ0FBaUIsT0FBL0I7QUFDQSxhQUFPLEdBQVA7QUFDRDs7O2dDQUVZLEUsRUFBSSxPLEVBQVM7QUFDeEIsVUFBSSxTQUFTLEtBQUssU0FBTCxDQUFlLEVBQWYsQ0FBYjtBQUNBLFVBQUksQ0FBQyxNQUFMLEVBQWE7QUFDWCxlQUFPLFFBQVEsTUFBUixDQUFlLElBQUksZ0JBQUosQ0FBcUIsZUFBckIsRUFBc0MsRUFBdEMsQ0FBZixDQUFQO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsZUFBTyxRQUFRLFlBQVIsQ0FBcUI7QUFBQSxpQkFBTSxPQUFPLElBQVAsQ0FBWSxPQUFaLEVBQXFCLEVBQXJCLENBQU47QUFBQSxTQUFyQixDQUFQO0FBQ0Q7QUFDRjs7O2lDQUVhLEUsRUFBSSxPLEVBQVM7QUFDekIsVUFBSSxTQUFTLEtBQUssU0FBTCxDQUFlLEVBQWYsQ0FBYjtBQUNBLFVBQUksQ0FBQyxNQUFMLEVBQWE7QUFBRSxlQUFPLFFBQVEsT0FBUixFQUFQO0FBQTBCO0FBQ3pDLGFBQU8sUUFBUSxZQUFSLENBQXFCO0FBQUEsZUFBTSxPQUFPLEtBQVAsQ0FBYSxPQUFiLEVBQXNCLEVBQXRCLENBQU47QUFBQSxPQUFyQixDQUFQO0FBQ0Q7OztxQ0FFaUIsRSxFQUFJO0FBQ3BCLFVBQUksU0FBUyxLQUFLLFNBQUwsQ0FBZSxFQUFmLENBQWI7QUFDQSxVQUFJLE1BQUosRUFBWTtBQUNWLGVBQU8sVUFBUDtBQUNEO0FBQ0QsYUFBTyxRQUFRLE9BQVIsRUFBUDtBQUNEOzs7OztBQUlILE9BQU8sT0FBUCxHQUFpQixpQkFBakIiLCJmaWxlIjoiU29ja2V0SU9UcmFuc3BvcnQuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuY29uc3QgQ2hhdFNlcnZpY2VFcnJvciA9IHJlcXVpcmUoJy4vQ2hhdFNlcnZpY2VFcnJvcicpXG5jb25zdCBQcm9taXNlID0gcmVxdWlyZSgnYmx1ZWJpcmQnKVxuY29uc3QgUmVkaXNBZGFwdGVyID0gcmVxdWlyZSgnc29ja2V0LmlvLXJlZGlzJylcbmNvbnN0IFNvY2tldElPQ2x1c3RlckJ1cyA9IHJlcXVpcmUoJy4vU29ja2V0SU9DbHVzdGVyQnVzJylcbmNvbnN0IFNvY2tldFNlcnZlciA9IHJlcXVpcmUoJ3NvY2tldC5pbycpXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJylcbmNvbnN0IHsgcnVuIH0gPSByZXF1aXJlKCcuL3V0aWxzJylcblxuLy8gU29ja2V0LmlvIHRyYW5zcG9ydC5cbmNsYXNzIFNvY2tldElPVHJhbnNwb3J0IHtcblxuICBjb25zdHJ1Y3RvciAoc2VydmVyLCBvcHRpb25zLCBhZGFwdGVyQ29uc3RydWN0b3IsIGFkYXB0ZXJPcHRpb25zKSB7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXJcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gICAgdGhpcy5hZGFwdGVyQ29uc3RydWN0b3IgPSBhZGFwdGVyQ29uc3RydWN0b3JcbiAgICB0aGlzLmFkYXB0ZXJPcHRpb25zID0gYWRhcHRlck9wdGlvbnNcbiAgICB0aGlzLnBvcnQgPSB0aGlzLnNlcnZlci5wb3J0XG4gICAgdGhpcy5pbyA9IHRoaXMub3B0aW9ucy5pb1xuICAgIHRoaXMubWlkZGxld2FyZSA9IG9wdGlvbnMubWlkZGxld2FyZVxuICAgIHRoaXMubmFtZXNwYWNlID0gdGhpcy5vcHRpb25zLm5hbWVzcGFjZSB8fCAnL2NoYXQtc2VydmljZSdcbiAgICBsZXQgQWRhcHRlciA9ICgoKSA9PiB7XG4gICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgY2FzZSB0aGlzLmFkYXB0ZXJDb25zdHJ1Y3RvciA9PT0gJ21lbW9yeSc6XG4gICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgY2FzZSB0aGlzLmFkYXB0ZXJDb25zdHJ1Y3RvciA9PT0gJ3JlZGlzJzpcbiAgICAgICAgICByZXR1cm4gUmVkaXNBZGFwdGVyXG4gICAgICAgIGNhc2UgXy5pc0Z1bmN0aW9uKHRoaXMuYWRhcHRlckNvbnN0cnVjdG9yKTpcbiAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyQ29uc3RydWN0b3JcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBsZXQgYyA9IHRoaXMuYWRhcHRlckNvbnN0cnVjdG9yXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRyYW5zcG9ydCBhZGFwdGVyOiAke2N9YClcbiAgICAgIH1cbiAgICB9KSgpXG4gICAgaWYgKCF0aGlzLmlvKSB7XG4gICAgICB0aGlzLmlvT3B0aW9ucyA9IHRoaXMub3B0aW9ucy5pb09wdGlvbnNcbiAgICAgIHRoaXMuaHR0cCA9IHRoaXMub3B0aW9ucy5odHRwXG4gICAgICBpZiAodGhpcy5odHRwKSB7XG4gICAgICAgIHRoaXMuZG9udENsb3NlSU8gPSB0cnVlXG4gICAgICAgIHRoaXMuaW8gPSBuZXcgU29ja2V0U2VydmVyKHRoaXMub3B0aW9ucy5odHRwLCB0aGlzLmlvT3B0aW9ucylcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW8gPSBuZXcgU29ja2V0U2VydmVyKHRoaXMucG9ydCwgdGhpcy5pb09wdGlvbnMpXG4gICAgICB9XG4gICAgICBpZiAoQWRhcHRlcikge1xuICAgICAgICB0aGlzLmFkYXB0ZXIgPSBuZXcgQWRhcHRlciguLi50aGlzLmFkYXB0ZXJPcHRpb25zKVxuICAgICAgICB0aGlzLmlvLmFkYXB0ZXIodGhpcy5hZGFwdGVyKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRvbnRDbG9zZUlPID0gdHJ1ZVxuICAgIH1cbiAgICB0aGlzLm5zcCA9IHRoaXMuaW8ub2YodGhpcy5uYW1lc3BhY2UpXG4gICAgdGhpcy5zZXJ2ZXIuaW8gPSB0aGlzLmlvXG4gICAgdGhpcy5zZXJ2ZXIubnNwID0gdGhpcy5uc3BcbiAgICB0aGlzLmNsdXN0ZXJCdXMgPSBuZXcgU29ja2V0SU9DbHVzdGVyQnVzKHRoaXMuc2VydmVyLCB0aGlzLm5zcC5hZGFwdGVyKVxuICAgIHRoaXMuY2xvc2VkID0gZmFsc2VcbiAgfVxuXG4gIHJlamVjdExvZ2luIChzb2NrZXQsIGVycm9yKSB7XG4gICAgZXJyb3IgPSB0aGlzLnNlcnZlci5jb252ZXJ0RXJyb3IoZXJyb3IpXG4gICAgc29ja2V0LmVtaXQoJ2xvZ2luUmVqZWN0ZWQnLCBlcnJvcilcbiAgICBzb2NrZXQuZGlzY29ubmVjdCgpXG4gIH1cblxuICBjb25maXJtTG9naW4gKHNvY2tldCwgdXNlck5hbWUsIGF1dGhEYXRhKSB7XG4gICAgYXV0aERhdGEuaWQgPSBzb2NrZXQuaWRcbiAgICBzb2NrZXQuZW1pdCgnbG9naW5Db25maXJtZWQnLCB1c2VyTmFtZSwgYXV0aERhdGEpXG4gIH1cblxuICBlbnN1cmVVc2VyTmFtZSAoc29ja2V0LCB1c2VyTmFtZSkge1xuICAgIHJldHVybiBQcm9taXNlLnRyeSgoKSA9PiB7XG4gICAgICBpZiAoIXVzZXJOYW1lKSB7XG4gICAgICAgIGxldCB7IHF1ZXJ5IH0gPSBzb2NrZXQuaGFuZHNoYWtlXG4gICAgICAgIHVzZXJOYW1lID0gcXVlcnkgJiYgcXVlcnkudXNlclxuICAgICAgICBpZiAoIXVzZXJOYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBDaGF0U2VydmljZUVycm9yKCdub0xvZ2luJykpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlck5hbWUpXG4gICAgfSlcbiAgfVxuXG4gIHNldEV2ZW50cyAoKSB7XG4gICAgaWYgKHRoaXMubWlkZGxld2FyZSkge1xuICAgICAgbGV0IG1pZGRsZXdhcmUgPSBfLmNhc3RBcnJheSh0aGlzLm1pZGRsZXdhcmUpXG4gICAgICBmb3IgKGxldCBmbiBvZiBtaWRkbGV3YXJlKSB7XG4gICAgICAgIHRoaXMubnNwLnVzZShmbilcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5uc3Aub24oJ2Nvbm5lY3Rpb24nLCBzb2NrZXQgPT4ge1xuICAgICAgcmV0dXJuIHJ1bih0aGlzLCBmdW5jdGlvbiAqICgpIHtcbiAgICAgICAgbGV0IGlkID0gc29ja2V0LmlkXG4gICAgICAgIGxldCBbdXNlck5hbWUsIGF1dGhEYXRhID0ge31dID0geWllbGQgdGhpcy5zZXJ2ZXIub25Db25uZWN0KGlkKVxuICAgICAgICB1c2VyTmFtZSA9IHlpZWxkIHRoaXMuZW5zdXJlVXNlck5hbWUoc29ja2V0LCB1c2VyTmFtZSlcbiAgICAgICAgeWllbGQgdGhpcy5zZXJ2ZXIucmVnaXN0ZXJDbGllbnQodXNlck5hbWUsIGlkKVxuICAgICAgICB0aGlzLmNvbmZpcm1Mb2dpbihzb2NrZXQsIHVzZXJOYW1lLCBhdXRoRGF0YSlcbiAgICAgIH0pLmNhdGNoKGVycm9yID0+IHRoaXMucmVqZWN0TG9naW4oc29ja2V0LCBlcnJvcikpXG4gICAgfSlcbiAgfVxuXG4gIGNsb3NlICgpIHtcbiAgICB0aGlzLmNsb3NlZCA9IHRydWVcbiAgICB0aGlzLm5zcC5yZW1vdmVBbGxMaXN0ZW5lcnMoJ2Nvbm5lY3Rpb24nKVxuICAgIHRoaXMuY2x1c3RlckJ1cy5yZW1vdmVBbGxMaXN0ZW5lcnMoKVxuICAgIHJldHVybiBQcm9taXNlLnRyeSgoKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuZG9udENsb3NlSU8pIHtcbiAgICAgICAgdGhpcy5pby5jbG9zZSgpXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaHR0cCkge1xuICAgICAgICB0aGlzLmlvLmVuZ2luZS5jbG9zZSgpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGxldCBbLCBzb2NrZXRdIG9mIF8udG9QYWlycyh0aGlzLm5zcC5jb25uZWN0ZWQpKSB7XG4gICAgICAgICAgc29ja2V0LmRpc2Nvbm5lY3QoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICB9KVxuICB9XG5cbiAgYmluZEhhbmRsZXIgKGlkLCBuYW1lLCBmbikge1xuICAgIGxldCBzb2NrZXQgPSB0aGlzLmdldFNvY2tldChpZClcbiAgICBpZiAoc29ja2V0KSB7XG4gICAgICBzb2NrZXQub24obmFtZSwgZm4pXG4gICAgfVxuICB9XG5cbiAgZ2V0U2VydmVyICgpIHtcbiAgICByZXR1cm4gdGhpcy5pb1xuICB9XG5cbiAgZ2V0U29ja2V0IChpZCkge1xuICAgIHJldHVybiB0aGlzLm5zcC5jb25uZWN0ZWRbaWRdXG4gIH1cblxuICBlbWl0VG9DaGFubmVsIChjaGFubmVsLCBldmVudE5hbWUsIC4uLmV2ZW50RGF0YSkge1xuICAgIHRoaXMubnNwLnRvKGNoYW5uZWwpLmVtaXQoZXZlbnROYW1lLCAuLi5ldmVudERhdGEpXG4gIH1cblxuICBzZW5kVG9DaGFubmVsIChpZCwgY2hhbm5lbCwgZXZlbnROYW1lLCAuLi5ldmVudERhdGEpIHtcbiAgICBsZXQgc29ja2V0ID0gdGhpcy5nZXRTb2NrZXQoaWQpXG4gICAgaWYgKCFzb2NrZXQpIHtcbiAgICAgIHRoaXMuZW1pdFRvQ2hhbm5lbChjaGFubmVsLCBldmVudE5hbWUsIC4uLmV2ZW50RGF0YSlcbiAgICB9IGVsc2Uge1xuICAgICAgc29ja2V0LnRvKGNoYW5uZWwpLmVtaXQoZXZlbnROYW1lLCAuLi5ldmVudERhdGEpXG4gICAgfVxuICB9XG5cbiAgZ2V0SGFuZHNoYWtlRGF0YSAoaWQpIHtcbiAgICBsZXQgcmVzID0geyBpc0Nvbm5lY3RlZDogZmFsc2UsIHF1ZXJ5OiB7fSwgaGVhZGVyczoge30gfVxuICAgIGxldCBzb2NrZXQgPSB0aGlzLmdldFNvY2tldChpZClcbiAgICBpZiAoIXNvY2tldCkgeyByZXR1cm4gcmVzIH1cbiAgICByZXMuaXNDb25uZWN0ZWQgPSB0cnVlXG4gICAgcmVzLnF1ZXJ5ID0gc29ja2V0LmhhbmRzaGFrZS5xdWVyeVxuICAgIHJlcy5oZWFkZXJzID0gc29ja2V0LmhhbmRzaGFrZS5oZWFkZXJzXG4gICAgcmV0dXJuIHJlc1xuICB9XG5cbiAgam9pbkNoYW5uZWwgKGlkLCBjaGFubmVsKSB7XG4gICAgbGV0IHNvY2tldCA9IHRoaXMuZ2V0U29ja2V0KGlkKVxuICAgIGlmICghc29ja2V0KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IENoYXRTZXJ2aWNlRXJyb3IoJ2ludmFsaWRTb2NrZXQnLCBpZCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQcm9taXNlLmZyb21DYWxsYmFjayhmbiA9PiBzb2NrZXQuam9pbihjaGFubmVsLCBmbikpXG4gICAgfVxuICB9XG5cbiAgbGVhdmVDaGFubmVsIChpZCwgY2hhbm5lbCkge1xuICAgIGxldCBzb2NrZXQgPSB0aGlzLmdldFNvY2tldChpZClcbiAgICBpZiAoIXNvY2tldCkgeyByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkgfVxuICAgIHJldHVybiBQcm9taXNlLmZyb21DYWxsYmFjayhmbiA9PiBzb2NrZXQubGVhdmUoY2hhbm5lbCwgZm4pKVxuICB9XG5cbiAgZGlzY29ubmVjdFNvY2tldCAoaWQpIHtcbiAgICBsZXQgc29ja2V0ID0gdGhpcy5nZXRTb2NrZXQoaWQpXG4gICAgaWYgKHNvY2tldCkge1xuICAgICAgc29ja2V0LmRpc2Nvbm5lY3QoKVxuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gU29ja2V0SU9UcmFuc3BvcnRcbiJdfQ== |
\ | No newline at end of file |