rabbit.on('ready', function() {
    console.log( 'rabbit:ready'.yellow, process.pid );

    var done = _.after(2, function() {

      register.subscribe({ack: true, prefetchCount: 1}, function( message, headers, deliveryInfo) {
        // TODO: register the user

        //console.log('user registration', message);

        creation.publish('', message, headers);

        // acknowledge
        register.shift();

      });

    });

    var next = _.after(2, function() {
      register.bind(exchange, '');
      done();
    });

    var creation = rabbit.exchange('service-creation', {autoDelete: false, type: 'fanout'}, done);
    var exchange = rabbit.exchange('service-register', {durable: true, confirm: true, autoDelete: false, type: 'fanout'}, next);
    var register = rabbit.queue('service-register', {durable: true, autoDelete: false}, next);

  });
Example #2
0
 app.start(function () {
     var serverAddress = app.server.address(),
         socketURL = "http://localhost:" + serverAddress.port,
         socketOpts = { "force new connection" : true };
     
     var rootClient = socketIO.connect(socketURL, socketOpts);
     var subappClient = socketIO.connect(socketURL + "/subapp", socketOpts);
     
     var partDone = _.after(2, done),
         throwError = function () {
             done(new Error("Didn't work"));
         };
     
     var partConnected = _.after(2, emitStuff);
     
     function emitStuff() {
         app.expressApp.socketIO.emit("hi");
         app.subApps.subapp.expressApp.socketIO.emit("hello");
     }
     
     rootClient.on("connect", partConnected);
     subappClient.on("connect", partConnected);
     
     rootClient.on("hi", partDone);
     subappClient.on("hello", partDone);
     
     rootClient.on("hello", throwError);
     subappClient.on("hi", throwError);
 });
Example #3
0
 app.start(function () {
     var serverAddress = app.server.address(),
         socketURL = 'http://localhost:' + serverAddress.port,
         socketOpts = { 'force new connection' : true };
     
     var rootClient = socketClient.connect(socketURL, socketOpts);
     var subappClient = socketClient.connect(socketURL + '/subapp', socketOpts);
     
     var partDone = _.after(2, done),
         throwError = function () {
             done(new Error('Did not work'));
         };
     
     var partConnected = _.after(2, emitStuff);
     
     function emitStuff() {
         app.expressApp.sockets.emit('hi');
         app.subapps.subapp.expressApp.sockets.emit('hello');
     }
     
     rootClient.on('connect', partConnected);
     subappClient.on('connect', partConnected);
     
     rootClient.on('hi', partDone);
     subappClient.on('hello', partDone);
     
     rootClient.on('hello', throwError);
     subappClient.on('hi', throwError);
 });
Example #4
0
Instagram.prototype._transform = function(chunk, encoding, done){

  var expected = 0
    , stream = this
    , obj = null
    , complete = _.after(chunk.length, function(){
      done();
    })
  ;
  for( var i in chunk){

    obj = chunk[i];
    switch( obj.object){
      case IG_OBJECT_TAG:
        this.getMediaByTag(chunk[i].object_id, function(err,res){
          var data = res.body.data;
          for( var j in data){
            if( stream.include(data[j])){
              stream.push(
                new Message(stream,data[j])
              );
            }
          }
          complete();
        });

        break;
      default:
        complete();
        break;
    }
  }

};
Example #5
0
        fs.readFile(output, {'encoding': 'utf8'}, function(err, text) {
            if (err) {
                log().error({'err': err, 'contentId': ctx.contentId}, 'Could not read the generated plain text');
                return callback({'code': 500, 'msg': 'Could not read the generated plain text'});
            }

            // Split out the plain-text file in separate pages
            var pages = text.split('\f');

            // pdftotext sometimes generates a final empty page. As we have no use
            // for an empty page, we remove it. Note that we cannot do _.compact(pages)
            // as there might be (important) empty pages in the middle of the document
            if (!pages[pages.length -1 ]) {
                pages.pop();
            }

            // If the PDF was empty we can return here
            if (_.isEmpty(pages)) {
                return callback();
            }

            var done = _.after(pages.length, callback);
            _.each(pages, function(page, index) {
                var pageName = util.format('page.%s.txt', index + 1);
                var pagePath = util.format('%s/%s', pagesDir, pageName);

                ctx.addPreview(pagePath, pageName);
                fs.writeFile(pagePath, page, done);
            });
        });
Example #6
0
 ws.on('message', function(data) {
     var msg = JSON.parse(data);
     var action = msg.shift();
     if(action == 'subscribe'){
         ws.send(JSON.stringify([['sync', new Date()]]));
         _.each(msg, function(event) {
             self.addSubscriber(event, ID);
         });
     }else if(action == 'execute'){
         var worker = msg.shift();
         var method = msg.shift();
         if(self.clientCan(method, ID) && self.workerManager.workers[worker]){
             msg.unshift(method);
             msg.push(function(){
                 var args = _.toArray(arguments);
                 if(args[0] !== undefined){
                     args.unshift('execute.'+worker+'.'+method);
                     var msg = JSON.stringify(args);
                     self.clients[ID].send(msg);
                 }
             });
             self.workerManager.workers[worker].execute.apply(self.workerManager.workers[worker], msg);
         }
     }else if(action == 'execute-wm'){
         var method = msg.shift();
         if(self.clientCan('wm.'+method, ID) && self.workerManager[method]){
             var ret = self.workerManager[method].apply(self.workerManager, msg);
             var args = ['execute-wm.'+method, ret];
             var msg = JSON.stringify(args);
             self.clients[ID].send(msg);
         }
     }else if(action == 'execute-all'){
         var method = msg.shift();
         if(self.clientCan(method, ID)){
             msg.unshift(method);
             var ret = {};
             var send = _.after(_(self.workerManager.workers).size(),function(){
                 if(self.clients[ID]){
                     var msg = JSON.stringify(['execute-all.'+method, ret]);
                     self.clients[ID].send(msg);
                 }
             });
             self.workerManager.forAll(function(worker, workerID){
                 var finalMsg = msg;
                 finalMsg.push(function(){
                     ret[workerID] = {args: arguments, type: worker.type != 'cluster' ? worker.type : 'local'};
                     send();
                 });
                 worker.execute.apply(worker, msg);
             });
         }
     }else if(action == 'server-worker'){
         console.log('Server worker connected');
         self.workerManager.addServerWorker(ws, msg.shift());
     }else if(action == 'client-worker'){
         console.log('Client worker connected');
         ws.send(JSON.stringify(['sync', new Date()]));
         self.workerManager.addClientWorker(ws, msg.shift());
     }
 });
Example #7
0
	var concatenate = function concatenate(stack, callback, omitRegExArr, extension) {
		var output = [],
			completed;

		if (omitRegExArr) {
			// filter files to omit
			stack = _.filter(stack, function (file) {
				var keepFile = true;
				omitRegExArr.forEach(function (expr) {
					if (file.match(expr)) {
						keepFile = false;
					}
				});
				return keepFile;
			});
		}

		completed = _.after(stack.length, function () {
			console.log(output)
			callback(output.join("\n"));
		});

		stack.forEach(function (path, idx) {
			fs.readFile(path, function (err, data) {
				output[idx * 2] = (commentStart[extension] || '//') + " file: " + path;
				output[idx * 2 + 1] = data !== undefined ? data.toString() : '';
				completed();
			});
		});
	};
		fs.readdir(path, function (err, files){
			if (err) return complete('could not read directory ' + path);

			var _doneProcessing = _.after(files.length, function () {
				complete(null, rtnFiles);
			});
			if (files.length === 0) return complete(null, []);
			_.each(files, function (file) {
				fs.lstat(Path.join(path, file), function (err, lstat) {
					if (err) return complete('could not process ' + file + ': ' + err);

					fs.stat(Path.join(path, file), function (err, stat) {
						if (err) return complete('could not process ' + file + ': ' + err);

						if (!options.followSymbolic && lstat.isSymbolicLink()) {
							debug('skipping symbolic link ' + Path.join(path, file));
							return _doneProcessing();
						}
						if (stat.isDirectory()) {
							self.listFilesRecursive(Path.join(path, file), options, function (err, files) {
								if (err) return complete(err);
								_doneProcessing();
							}, rtnFiles);
						} else {
							rtnFiles.push({ fileName: file, fullPath: Path.join(path, file)});
							_doneProcessing();
						}
					});
				});
			});
		});
Example #9
0
	sendAll: function(msgs, cb) {
		var self = this;
		callback = _.after(msgs.length, cb);
		_.each(msgs, function(msg) {
			self.send(msg, callback);
		});
	}
Example #10
0
				parser.addListener('end', function (result) {
					if (!result.config) {
						throw "Invalid base configuration file.";
					}
					if (result.config.length < 1) {
						throw "You must specify at least one configuration file.";
					}
					
					var complete	= _.after(result.config.length, function () {
						var complete_config	= {};
						config_data.unshift(complete_config);
						_.extend.apply(_.extend, config_data);
						self.config	= complete_config;

						self.emit('complete', self, complete_config);
						callback(self, complete_config);
					});

					_.each(result.config, function (setting, index) {
						fs.readFile(config_path + '/' + setting.file, function (error, data) {
							if (error) {
								throw error;
							}

							var sub_parser	= new xml2js.Parser();
							sub_parser.addListener('end', function (result) {
								config_data[index]	= result;
								complete();
							});
							sub_parser.parseString(data);
						});
					});
				});
Example #11
0
var canInteract = module.exports.canInteract = function(ctx, resources, callback) {
    if (!_.isArray(resources)) {
        return canInteract(ctx, _.compact([resources]), callback);
    } else if (_.isEmpty(resources)) {
        return callback();
    }

    var user = ctx.user();
    var permissionErr = {'code': 401, 'msg': 'The current user does not have access to interact with these resources'};
    var resourceErrs = {};
    var _done = _.after(resources.length, function() {
        if (!_.isEmpty(resourceErrs)) {
            return callback(_.extend(permissionErr, {'invalidResources': resourceErrs}));
        }

        return callback();
    });

    _.each(resources, function(resource) {
        _canInteract(ctx, resource, function(err) {
            if (err) {
                resourceErrs[resource.id] = err;
            }

            return _done();
        });
    });
};
Example #12
0
    getFiles = function() {
        var receiveFile;
        var done = _.after(filesList.length, function() {
            conn.removeListener('message', receiveFile);
            verifySignature();
        });

        receiveFile = function(msg) {
            if (msg.type != 'binary') {
                quit('Waiting for a binary message, but got text');
            } else {
                // We got one of the files, should be the next of the stack
                var file = filesList.pop();
                var path = state.dir+'/'+file.name;
                // Write the file to temporary directory
                if (file.compressed) {
                    // The file is compressed, run through gzip
                    tryAsync(helpers.decompressToFile, path, msg.binaryData)
                    .always(done)
                    .run();
                } else {
                    // The file is not compressed, write directly to disk
                    tryAsync(fs.writeFile, path, msg.binaryData)
                    .always(done)
                    .run();
                }
            }
        };

        conn.on('message', receiveFile);

        /* The client can now start to send the files */
        conn.sendJSON({ status: 'readyForFiles' });
    };
Example #13
0
function sendText(phone, message, region, cb) {
  console.log('txting phone', phone, ':', message);

  region = region || 'us';

  var providers_list = providers[region];

  var done = _.after(providers_list.length, function() {
    cb(false);
  });

  _.each(providers_list, function(provider) {
    var email = provider.replace('%s', phone);
    var child = spawn('sendmail', ['-f', '*****@*****.**', email]);
    child.stdout.on('data', console.log);
    child.stderr.on('data', console.log);
    child.on('error', function(data) {
      mpq.track('sendmail failed', {email: email, data: data});
      done();
    });
    child.on('exit', function(code, signal) {
      done();
    });
    child.stdin.write(message + '\n.');
    child.stdin.end();
  });
}
exports.AppendCssFiles = function(snap, callback) {
    
    var urls = snap.getExternalCss(),
        cssFiles = [];

    if(urls && urls.length > 0) {
        var cb = _.after(urls.length, function() {
            if(cssFiles.length > 0) snap.appendCss(cssFiles);
            callback(snap);
        });

        _.each(urls, function(url, index, list) {
            console.log(url);
            request("http://www.qvinci.com" + url, function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    cssFiles.push(body);
                    cb();
                }
            });
        });
    }
    else {
        callback(snap);
    }
};
Example #15
0
    function getMovies(linkArray, callback) {
        var movies = [],
            onFinish = _.after(linkArray.length, onResponse);

        function onResponse() {
            if (_.isFunction(callback)) {
                callback(movies);
            }
        }

        if (!linkArray.length) {
            onResponse();
            return;
        }

        _.each(linkArray, function (link) {
            request(LINK_BASE + link.movie.match(ID_EXTRACT)[1], function (response) {
                var extract;

                response = JSON.parse(response);

                extract = {
                    title: response.Title,
                    score: response.imdbRating === 'N/A' ? null : Number(response.imdbRating),
                    torrentLink: link.torrent,
                    imdbLink: link.movie,
                    torrentTitle: link.torrentTitle
                };

                movies.push(extract);

                onFinish();
            });
        });
    }
Example #16
0
        var continueTest = _.after(2, () => { originalSetTimeout(() => {
            this.mockHistogram.off('complete', continueTest);
            expect(onResolveOne.called).toBe(true);
            expect(onResolveTwo.called).toBe(true);
            expectSparklinesOn(['_a', '_b']);

            // For the next set timeout, change the mock data and verify that next request
            // contains the correct data
            this.mockHistogram.update({
                '/first': [{
                    path: '/a',
                    series: [{ name: 'pageview', data: [{count: 500}]}],
                    totalHits: 500
                }],
                '/second': [{
                    path: '/b',
                    series: [{ name: 'pageview', data: [{count: 12345}]}],
                    totalHits: 12345
                }]
            });
            var afterInterval = _.after(2, () => { originalSetTimeout(() => {
                this.mockHistogram.off('complete', afterInterval);
                expect(sparklinesTitle('_a')).toBe('500');
                expect(sparklinesTitle('_b')).toBe('12,345');

                finishTest();
            }, 10); });
            this.mockHistogram.on('complete', afterInterval);

        }, 10); });
function importGames(games){
	var end = _.after(games.length, function(){process.exit(0);});
	require('../config').getConfig(function(err, config) {
		if (err) { console.log("ERROR", err); process.exit(1); }
		global.platform_config = config;
		require('../db').getDb(function(err, db){
			if (err){
				console.log('Unable to load db info');
				return process.exit(1);
			}

			db.mongoose.connect(config.MONGODB);
			db.mongoose.connection.on('error', function(err){
				//should handle mongo errors here..
				console.log('mongoose error', err);
			});

			games.forEach(function(game){
				if (!game.team1 || !game.team2){
					//unknown teams?
					end();
					return false;
				}
				if (game.score.match(/([0-9]*)h([0-9]*)/)){
					console.log('no score yet',game.team1, game.team2, game.score);
					end();
					return false;
				}

				findGame(db, game, end);

			});
		});
	});
}
Example #18
0
        self._devicestorage.listItems(outboxDb, 0, null, function(err, pendingMails) {
            // error, we're done here
            if (err) {
                self._outboxBusy = false;
                callback(err);
                return;
            }

            // if we're not online, don't even bother sending mails.
            if (!self._emailDao._account.online || _.isEmpty(pendingMails)) {
                self._outboxBusy = false;
                callback(null, pendingMails.length);
                return;
            }

            // we're done after all the mails have been handled
            // update the outbox count...
            var after = _.after(pendingMails.length, function() {
                self._outboxBusy = false;
                callback(null, unsentMails);
            });

            // send pending mails if possible
            pendingMails.forEach(function(mail) {
                send(mail, after);
            });
        });
Example #19
0
        authedSocket(user, function(sock) {
            var messages = [];
            var expected = [
                ["join-ack", undefined],
                ["don't forget", [4, 5, 6]]
            ];

            // The routine that will be called on data..
            var finish = _.after(expected.length, function() {
                expect(messages).to.eql(expected);
                sock.promiseClose().then(function() {
                    mgr.destroy();
                    done();
                });
            });

            sock.write(JSON.stringify({
                type: "join",
                args: {id: "someroom", timestamp: hrnow}
            }));
            sock.on("data", function(message) {
                var msg = JSON.parse(message);
                messages.push([msg.type, msg.args]);
                finish();
            });
        });
Example #20
0
    function getIMDBLinks(torrents, callback) {
        var links = [],
            onFinish = _.after(torrents.length, onResponse);

        function onResponse() {
            if (_.isFunction(callback)) {
                callback(_.compact(links));
            }
        }

        _.each(torrents, function (torrent) {
            request(torrent.link, function (data) {
                var m = data.match(IMDB_LINK_REGEXP),
                    tuple = null;

                if (m) {
                    tuple = {
                        torrentTitle: torrent.title,
                        torrent: torrent.link,
                        movie: m[1]
                    };
                }

                links.push(tuple);
                onFinish();
            });
        });
    }
Example #21
0
        RestAPI.Content.createCollabDoc(userValues[0].restContext, name, 'description', 'public', userIds, [], function(err, contentObj) {
            assert.ok(!err);

            // Create a function that will get executed once each user has joined the document
            var callCallback = _.after(nrOfJoinedUsers, function() {
                var callbackArgs = _.union([contentObj, users], userValues);
                return callback.apply(callback, callbackArgs);
            });

            // If no user should join the document we can return immediately
            if (nrOfJoinedUsers === 0) {
                return callCallback();
            }


            // Join the collab doc for `nrOfJoinedUsers` users
            var joinCollabDoc = function(i) {
                var restCtx = userValues[i].restContext;
                RestAPI.Content.joinCollabDoc(restCtx, contentObj.id, function(err, data) {
                    assert.ok(!err);
                    callCallback();
                });
            };
            for (var i = 0; i < nrOfJoinedUsers; i++) {
                joinCollabDoc(i);
            }
        });
 onceAll: function(sources, eventName, handler, context){
     handler = _.after( sources.length, handler);
     context = context || this;
     _.each(sources, function(source){
         source.once(eventName, handler, context)
     });
 },
		this.listMissingFiles(path1, path2, options, function (err, files) {
			if (err) return complete(err);
			if (files.length === 0) return complete(null, cnt);
			self.log(files.length + ' missing files found');
			var _processedFile = _.after(files.length, _complete);
			var progressBar = new ProgressBar('  copying [:bar] :percent', {
				complete: '=',
				incomplete: ' ',
				width: 20,
				total: files.length
			});
			_.each(files, function (f) {
				if (errored) return;
				self.log('copying ' + f.fullPath + ' to ' + Path.join(path2, f.fileName));
				var subRoot = f.fullPath.split(path1)[1];
				var newPath = Path.join(path2, subRoot);
				mkdirp(Path.dirname(newPath), function (err) {
					debug('created directory ' + Path.dirname(newPath));
					if (err) return _complete('error making directory "' + Path.dirname(newPath) + '": ' + err);
					cp(f.fullPath, newPath, function (err){
						if (err) return _complete('error copying file "' + f.fullPath + '": ' + err);
						self.log('copied ' + f.fileName + ' to ' + Path.join(newPath, f.fileName));
						progressBar.tick();
						cnt++;
						_processedFile();
					});
				});
			});
		});
Example #24
0
exports.add = function(data, cb) {
    var brk = false;
    var decoded = decoder.decodeSync(data);
    var trData = { 'metainfo' : data.toString('base64') };
    var addOnce = _.once(function(boxId) {
        boxes[boxId].add(trData, function(result) {
            result.boxId = boxId;
            console.log(result);
            cb(result);
        });
    });
    var no = _.after(orderedIds.length, function() {
        cb(null);
    });

    for (var i = 0, l = orderedIds.length; i < l; i++) {
        var key = orderedIds[i];
        boxes[key].canAdd(decoded, function(yes) {
            if (yes) {
                brk = true; addOnce(key);
            } else {
                no();
            }
        });
        if (brk) break;
    }
}
Example #25
0
                MQ.declareQueue(queueName, {'durable': false, 'autoDelete': true}, function(err) {
                    assert.ok(!err);

                    // This test passes if we receive a message from RabbitMQ for each of our routing keys
                    var receivedMessage = _.after(routingKeys.length, function(message) {
                        return callback();
                    });

                    // Subscribe for incoming messages
                    MQ.subscribeQueue(queueName, {}, receivedMessage, function(err) {
                        assert.ok(!err);

                        // When our queue is bound for all routing keys, we will submit a message for each one
                        var queueBound = _.after(routingKeys.length, function() {
                            _.each(routingKeys, function(routingKey) {
                                MQ.submit(exchangeName, routingKey, data);
                            });
                        });

                        // Bind our queue for all routing keys
                        _.each(routingKeys, function(routingKey) {
                            MQ.bindQueueToExchange(queueName, exchangeName, routingKey, function(err) {
                                assert.ok(!err);
                                queueBound();
                            });
                        });
                    });
                });
Example #26
0
/**
 * Run the getFeature demo. Calls getFeature with a point known to have a
 * feature and a point known not to have a feature.
 * @param {function} callback Called when this demo is complete
 */
function runGetFeature(callback) {
  var next = _.after(2, callback);
  function featureCallback(error, feature) {
    if (error) {
      callback(error);
    }
    if (feature.name === '') {
      console.log('Found no feature at ' +
          feature.location.latitude/COORD_FACTOR + ', ' +
          feature.location.longitude/COORD_FACTOR);
    } else {
      console.log('Found feature called "' + feature.name + '" at ' +
          feature.location.latitude/COORD_FACTOR + ', ' +
          feature.location.longitude/COORD_FACTOR);
    }
    next();
  }
  var point1 = {
    latitude: 409146138,
    longitude: -746188906
  };
  var point2 = {
    latitude: 0,
    longitude: 0
  };
  client.getFeature(point1, featureCallback);
  client.getFeature(point2, featureCallback);
}
Example #27
0
 FS.readdir(path, function(err, entries){
   if(err){
     cb(err);
   }
   end = _.after(entries.length, function(){
     cb(null, files);
   });
   for(i = 0; i < entries.length; i++){
     (function(entry){
       FS.stat(entry, function(err, stat){
         if(stat && stat.isDirectory()){
           recurse(entry, mask, function(err, _files){
             if(!err){
               files = files.concat(_files);
             }
             end();
           });
         }else{
           if(!mask || mask.test(entry)){
             files.push(entry);
           }
           end();
         }
       });
     })(path + '/' + entries[i]);
   }
 });
Example #28
0
        // check whether there are unregistered receivers, i.e. receivers without a public key
        function checkReceivers(email) {
            var unregisteredUsers, receiverChecked;

            unregisteredUsers = [];
            receiverChecked = _.after(email.to.length, function() {
                // invite unregistered users if necessary
                if (unregisteredUsers.length > 0) {
                    invite(unregisteredUsers);
                    return;
                }

                sendEncrypted(email);
            });

            // find out if there are unregistered users
            email.to.forEach(function(recipient) {
                self._keychain.getReceiverPublicKey(recipient.address, function(err, key) {
                    if (err) {
                        self._outboxBusy = false;
                        callback(err);
                        return;
                    }

                    if (!key) {
                        unregisteredUsers.push(recipient);
                    }

                    receiverChecked();
                });
            });
        }
Example #29
0
function parseListingResults(root, directory, results, listing, callback) {
    var lines = listing.split('\n');
    var subDirectories = [];
    lines.forEach(function(line) {
        var parts = line.split(/\s+/);
        if (parts.length < (isMac ? 9 : 8)) {
            return;
        }

        var entry = getEntry(root, directory, line);
        if (entry.isDirectory) {
            subDirectories.push(entry.relativeDirectory);
        }
        else {
            results.push(entry);
        }
    });

    if (subDirectories.length > 0) {
        // after subDirectoryCallback has been called <subDirectories.length>
        // times underscore will call the callback
        var subDirectoryCallback = _.after(subDirectories.length, function() {
            callback(null, results);
        });
        subDirectories.forEach(function(subDirectory) {
            findFilesRecursively(root, subDirectory, results, subDirectoryCallback);
        });
    }
    else {
        callback(null, results);
    }
}
Example #30
0
    fs.readdir(prjPath, function (err, projects) {
        if (err) return complete(err, rtn);
        if (projects.length === 0) return complete(null, rtn);

        var _processed = _.after(projects.length, function () {
            complete(null, rtn);
        });

        _.each(projects, function (prj) {
            fs.stat(prjPath + path.sep + prj, function (err, stats) {
                if (err) return complete(err, rtn);

                if (stats.isDirectory()) {
                    fs.readdir(prjPath + path.sep + prj, function (err, files) {
                        if (err) complete(err, rtn);
                        if (_.contains(files, 'demo.json')) {
                            rtn.push({
                                title: prj,
                                url: projectUrl + '/' + prj + '/' + prj + '.html'
                            });
                        }
                        _processed();
                    });
                } else {
                    _processed();
                }


            });
        });
    });