<commit_before>var request = require('supertest');
var loopback = require('loopback');
var expect = require('chai').expect;
var JSONAPIComponent = require('../');
var app, Post, Comment, ds;

describe('loopback json api hasMany relationships', function () {
  beforeEach(function () {
    app = loopback();
    app.set('legacyExplorer', false);
    ds = loopback.createDataSource('memory');
    Post = ds.createModel('post', {
      id: {type: Number, id: true},
      title: String,
      content: String
    });
    app.model(Post);

    Comment = ds.createModel('comment', {
      id: {type: Number, id: true},
      postId: Number,
      title: String,
      comment: String
    });
    app.model(Comment);
    Post.hasMany(Comment, {as: 'comments', foreignKey: 'postId'});
    Comment.settings.plural = 'comments';

    app.use(loopback.rest());
    JSONAPIComponent(app, {restApiRoot: '/'});
  });

  describe('Fetch a post with no comments', function (done) {
    beforeEach(function (done) {
      Post.create({
        title: 'my post without comments',
        content: 'my post without comments content'
      }, done);
    });

    describe('GET /posts/1/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/comments')
          .expect(200)
          .end(done);
      });

      it('should display an empty array keyed by `data`', function (done) {
        request(app).get('/posts/1/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(0);
            done();
          });
      });
    });

    describe('GET /posts/1/relationships/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .expect(200)
          .end(done);
      });

      it('should display an empty array keyed by `data`', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/relationships\/comments/);
            expect(res.body.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(0);
            done();
          });
      });
    });
  });

  describe('Fetch a post with a comment', function (done) {
    beforeEach(function (done) {
      Post.create({
        title: 'my post',
        content: 'my post content'
      }, function (err, post) {
        expect(err).to.equal(null);
        post.comments.create({
          title: 'My comment',
          comment: 'My comment text'
        }, done);
      });
    });

    describe('GET /posts/1/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/comments')
          .expect(200)
          .end(done);
      });

      it('should display a single item array keyed by `data`', function (done) {
        request(app).get('/posts/1/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(1);
            expect(res.body.data[0].type).to.equal('comments');
            done();
          });
      });
    });

    describe('GET /posts/1/relationships/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .expect(200)
          .end(done);
      });

      it('should display a single item array keyed by `data`', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/relationships\/comments/);
            expect(res.body.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(1);
            expect(res.body.data[0]).to.deep.equal({
              type: 'comments',
              id: '1'
            });
            done();
          });
      });
    });
  });
});
<commit_msg>Add tests for hasMany relationship<commit_after>var request = require('supertest');
var loopback = require('loopback');
var expect = require('chai').expect;
var JSONAPIComponent = require('../');
var app, Post, Comment, ds;

describe('loopback json api hasMany relationships', function () {
  beforeEach(function () {
    app = loopback();
    app.set('legacyExplorer', false);
    ds = loopback.createDataSource('memory');
    Post = ds.createModel('post', {
      id: {type: Number, id: true},
      title: String,
      content: String
    });
    app.model(Post);

    Comment = ds.createModel('comment', {
      id: {type: Number, id: true},
      postId: Number,
      title: String,
      comment: String
    });
    app.model(Comment);
    Post.hasMany(Comment, {as: 'comments', foreignKey: 'postId'});
    Comment.settings.plural = 'comments';

    app.use(loopback.rest());
    JSONAPIComponent(app, {restApiRoot: '/'});
  });

  describe('Fetch a post with no comments', function (done) {
    beforeEach(function (done) {
      Post.create({
        title: 'my post without comments',
        content: 'my post without comments content'
      }, done);
    });

    describe('GET /posts/1/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/comments')
          .expect(200)
          .end(done);
      });

      it('should display an empty array keyed by `data`', function (done) {
        request(app).get('/posts/1/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(0);
            done();
          });
      });
    });

    describe('GET /posts/1/relationships/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .expect(200)
          .end(done);
      });

      it('should display an empty array keyed by `data`', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/relationships\/comments/);
            expect(res.body.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(0);
            done();
          });
      });
    });
  });

  describe('Fetch a post with a comment', function (done) {
    beforeEach(function (done) {
      Post.create({
        title: 'my post',
        content: 'my post content'
      }, function (err, post) {
        expect(err).to.equal(null);
        post.comments.create({
          title: 'My comment',
          comment: 'My comment text'
        }, done);
      });
    });

    describe('GET /posts/1/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/comments')
          .expect(200)
          .end(done);
      });

      it('should display a single item array keyed by `data`', function (done) {
        request(app).get('/posts/1/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(1);
            expect(res.body.data[0].type).to.equal('comments');
            done();
          });
      });
    });

    describe('GET /posts/1/relationships/comments', function () {
      it('should return status code 200 OK', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .expect(200)
          .end(done);
      });

      it('should display a single item array keyed by `data`', function (done) {
        request(app).get('/posts/1/relationships/comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body).to.be.an('object');
            expect(res.body.links).to.be.an('object');
            expect(res.body.links.self).to.match(/posts\/1\/relationships\/comments/);
            expect(res.body.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.data).to.be.an('array');
            expect(res.body.data.length).to.equal(1);
            expect(res.body.data[0]).to.deep.equal({
              type: 'comments',
              id: '1'
            });
            done();
          });
      });
    });

    describe.skip('embedded relationship information in collections (GET /:collection)', function () {
      it('should return comments relationship link in relationships object', function (done) {
        request(app).get('/posts')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.data[0].relationships).to.be.an('object');
            expect(res.body.data[0].relationships.comments).to.be.an('object');
            expect(res.body.data[0].relationships.comments.links).to.be.an('object');
            expect(res.body.data[0].relationships.comments.links.related).to.match(/posts\/1\/comments/);
            done();
          });
      });

      it('should return included data as a compound document using key "included"', function (done) {
        request(app).get('/posts?filter={"include":"comments"}')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.data[0].relationships).to.be.an('object');
            expect(res.body.data[0].relationships.comments).to.be.an('object');
            expect(res.body.data[0].relationships.comments.data).to.deep.equal({
              type: 'comments',
              id: '1'
            });
            expect(res.body.data[0].relationships.comments.links).to.be.an('object');
            expect(res.body.data[0].relationships.comments.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.included).to.be.an('array');
            expect(res.body.included.length).to.equal(1);
            expect(res.body.included[0]).to.have.all.keys('type', 'id', 'attributes', 'links');
            expect(res.body.included[0].type).to.equal('comments');
            expect(res.body.included[0].id).to.equal('1');
            done();
          });
      });

      it('should return a 400 Bad Request error if a non existent relationship is specified.', function (done) {
        request(app).get('/posts?filter={"include":"doesnotexist"}')
          .expect(400)
          .end(done);
      });

      it('should allow specifying `include` in the url to meet JSON API spec. eg. include=comments', function (done) {
        request(app).get('/posts?include=comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.included).to.be.an('array');
            expect(res.body.included.length).to.equal(1);
            done();
          });
      });

      it('should return a 400 Bad Request error if a non existent relationship is specified using JSON API syntax.', function (done) {
        request(app).get('/posts?include=doesnotexist')
          .expect(400)
          .end(done);
      });
    });

    describe.skip('embedded relationship information for individual resource GET /:collection/:id', function () {
      it('should return comments relationship link in relationships object', function (done) {
        request(app).get('/posts/1')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.data.relationships).to.be.an('object');
            expect(res.body.data.relationships.comments).to.be.an('object');
            expect(res.body.data.relationships.comments.links).to.be.an('object');
            expect(res.body.data.relationships.comments.links.related).to.match(/posts\/1\/comments/);
            done();
          });
      });

      it('should return included data as a compound document using key "included"', function (done) {
        request(app).get('/posts/1?filter={"include":"comments"}')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.data.relationships).to.be.an('object');
            expect(res.body.data.relationships.comments).to.be.an('object');
            expect(res.body.data.relationships.comments.data).to.deep.equal({
              type: 'comments',
              id: '1'
            });
            expect(res.body.data.relationships.comments.links).to.be.an('object');
            expect(res.body.data.relationships.comments.links.related).to.match(/posts\/1\/comments/);
            expect(res.body.included).to.be.an('array');
            expect(res.body.included.length).to.equal(1);
            expect(res.body.included[0]).to.have.all.keys('type', 'id', 'attributes', 'links');
            expect(res.body.included[0].type).to.equal('comments');
            expect(res.body.included[0].id).to.equal('1');
            done();
          });
      });

      it('should return a 400 Bad Request error if a non existent relationship is specified.', function (done) {
        request(app).get('/posts/1?filter={"include":"doesnotexist"}')
          .expect(400)
          .end(done);
      });

      it('should allow specifying `include` in the url to meet JSON API spec. eg. include=comments', function (done) {
        request(app).get('/posts/1?include=comments')
          .end(function (err, res) {
            expect(err).to.equal(null);
            expect(res.body.included).to.be.an('array');
            expect(res.body.included.length).to.equal(1);
            done();
          });
      });

      it('should return a 400 Bad Request error if a non existent relationship is specified using JSON API syntax.', function (done) {
        request(app).get('/posts/1?include=doesnotexist')
          .expect(400)
          .end(done);
      });
    });
  });
});
<|endoftext|>


<commit_before>var Encore = require('@symfony/webpack-encore');

Encore
    // directory where compiled assets will be stored
    .setOutputPath('./build/')
    // public path used by the web server to access the output path
    .setPublicPath('/build')
    // only needed for CDN's or sub-directory deploy
    //.setManifestKeyPrefix('build/')
    /*
     * ENTRY CONFIG
     *
     * Add 1 entry for each "page" of your app
     * (including one that's included on every page - e.g. "app")
     *
     * Each entry will result in one JavaScript file (e.g. app.js)
     * and one CSS file (e.g. app.css) if your JavaScript imports CSS.
     */
    .addEntry('app', './assets/js/app.js')
    .addEntry('global','./assets/css/global.scss')
    .addEntry('signin','./assets/css/signin.css')
    // .addEntry('select2', './bundles/pinanoselect2/js/select2.js')
    // .addEntry('select2css', './bundles/pinanoselect2/css/select2.min.css')

    //.addEntry('page1', './assets/js/page1.js')
    //.addEntry('page2', './assets/js/page2.js')

    // will require an extra script tag for runtime.js
    // but, you probably want this, unless you're building a single-page app
    .enableSingleRuntimeChunk()

    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    // enables hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

// uncomment if you use TypeScript
//.enableTypeScriptLoader()

// uncomment if you use Sass/SCSS files
.enableSassLoader()
.enableLessLoader()

// uncomment if you're having problems with a jQuery plugin
    .autoProvidejQuery()
    .autoProvideVariables({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery',
    })
;

module.exports = 1182Encore.getWebpackConfig();<commit_msg>herstel<commit_after>var Encore = require('@symfony/webpack-encore');

Encore
    // directory where compiled assets will be stored
    .setOutputPath('./build/')
    // public path used by the web server to access the output path
    .setPublicPath('/build')
    // only needed for CDN's or sub-directory deploy
    //.setManifestKeyPrefix('build/')
    /*
     * ENTRY CONFIG
     *
     * Add 1 entry for each "page" of your app
     * (including one that's included on every page - e.g. "app")
     *
     * Each entry will result in one JavaScript file (e.g. app.js)
     * and one CSS file (e.g. app.css) if your JavaScript imports CSS.
     */
    .addEntry('app', './assets/js/app.js')
    .addEntry('global','./assets/css/global.scss')
    .addEntry('signin','./assets/css/signin.css')
    // .addEntry('select2', './bundles/pinanoselect2/js/select2.js')
    // .addEntry('select2css', './bundles/pinanoselect2/css/select2.min.css')

    //.addEntry('page1', './assets/js/page1.js')
    //.addEntry('page2', './assets/js/page2.js')

    // will require an extra script tag for runtime.js
    // but, you probably want this, unless you're building a single-page app
    .enableSingleRuntimeChunk()

    .cleanupOutputBeforeBuild()
    .enableSourceMaps(!Encore.isProduction())
    // enables hashed filenames (e.g. app.abc123.css)
    .enableVersioning(Encore.isProduction())

// uncomment if you use TypeScript
//.enableTypeScriptLoader()

// uncomment if you use Sass/SCSS files
.enableSassLoader()
.enableLessLoader()

// uncomment if you're having problems with a jQuery plugin
    .autoProvidejQuery()
    .autoProvideVariables({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery',
    })
;

module.exports = Encore.getWebpackConfig();<|endoftext|>


<commit_before>//var User = require('./models/schema').User;

//var loggedInUsers = {};

//var messages = {}; //key = target_user, value = dictionary where key = src, value = array of message tuples (msg, date, self?) including self, msg

userData = {};
/*
	key = userKey
	value = {
		name: string
		team: string
		coordinates: tuple of floats
		timestamp: datetime
	}
*/
captureData = {};
/*
	key = unique id for spawnpoint
	value = {
		ownedBy: string //team name
		coordinates: tuple of floats
		lastCaptured: datetime
	}
*/

teams = {};

var Messagebase = (function Messagebase() {
	var that = Object.create(Messagebase.prototype);

	var io = null;

	var COORD_SIZE_CAP = 20;

	that.setUp = function() {
		captureData['a'] = {
			'ownedBy': null,
			'coordinates': [42.357836,-71.093371],
			'lastCaptured': new Date()
		}

		captureData['b'] = {
			'ownedBy': null,
			'coordinates': [42.358328, -71.093843],
			'lastCaptured': new Date()
		}

		captureData['c'] = {
			'ownedBy': null,
			'coordinates': [42.357202, -71.092641],
			'lastCaptured': new Date()
		}

		captureData['d'] = {
			'ownedBy': null,
			'coordinates': [42.357242, -71.095119],
			'lastCaptured': new Date()
		}

		captureData['e'] = {
			'ownedBy': null,
			'coordinates': [42.359613, -71.091231],
			'lastCaptured': new Date()
		}
		teams["red"] = {};
		teams["blue"] = {};
	}

	that.setIO = function(IO) {

		that.setUp();

		io = IO;

		//io connection
		io.on('connection', function(socket){
			console.log("connection established");

			socket.on('disconnect', function(){
			});

			//on initial connection, create player data
			//then send current state of the game
			socket.on('session', function(player){
				console.log("new phone connected: ", player);

				teamAssignment = "";
				if (teams["blue"].length <= teams["red"].length) {
					teamAssignment = "blue";
					teams["blue"][player] = true;
				}
				else {
					teamAssignment = "red";
					teams["red"][player] = true;;
				}

				userData[player] = {'name': player, 'team': teamAssignment, 'coordinates': []};

				console.log("team assignments: ", teams);

				setTimeout(function(){}, 3000);

				io.emit("gameStatusUpdate", captureData);
			});

			socket.on('playerUpdate', function(data) {
				console.log("playerUpdate called, data: ", data);
				player = data.player;
				latitude = data.latitude;
				longitude = data.longitude;

				if (!(player in userData)) {
					userData[player] = {'name': 'test', 'team': 'gray', 'coordinates': []};
					//should never happen since we must call on session first
				}

				if (userData[player]['coordinates'].length > COORD_SIZE_CAP) {
					userData[player]['coordinates'].pop(0);
				}
				userData[player]['coordinates'].push([latitude, longitude]);
				userData[player]['timestamp'] = new Date();

				//DEBUG
				console.log("emitting: ", userData);
				io.emit("playerUpdate_confirm", userData);
			});

			socket.on('capture', function(data) {
				console.log("someone just tried to capture something: ", data);

				capturePointKey = data.capturePoint;
				player = data.player;

				now = new Date();

				if (now - capturePointKey['lastCaptured'] > 30000) {

					if (captureData[capturePointKey]['ownedBy'] == null) {
						captureData[capturePointKey]['ownedBy'] = playerTimestamp;
						captureData[capturePointKey]['lastCaptured'] = now;
						io.emit("gameStatusUpdate", captureData); //only run this on success
					}
					else {
						//handle logic regarding team battle over a spawnpoint

						//if successful
						captureData[capturePointKey]['ownedBy'] = playerTimestamp;
						captureData[capturePointKey]['lastCaptured'] = now;
						io.emit("gameStatusUpdate", captureData); //only run this on success
					}
				}
			});

		});

		setInterval( function() {
			io.emit("session", "this is a timed message " + userData);
		}, 5000); // 1000 = 1 sec

		setInterval( function() {
			now = new Date();
			for (pIndex in userData) {
				playerTimestamp = userData[pIndex]['timestamp'];
				if (now - playerTimestamp > 60000) { //if last update was more than a minute ago
					io.emit("playerShutdown", userData[pIndex]); //emit to everyone that player x has been disconnected
				}
			}
		}, 20000);

	}

	that.login = function(username) {
		loggedInUsers[username] = true;
		if (io) {
			io.emit("login user", username);
		}
	}

	that.logout =  function(username) {
		loggedInUsers[username] = false;
		if (io) {
			io.emit("logout user", username);
		}
	}

	that.getActiveUsers = function() {
		return loggedInUsers;
	}

	that.getOfflineUsers = function(cb) {
		User.getAllUsers(function(err, result) {
			if (err) {
				console.error(err);
				cb(err);
			} else {
				if (result.length > 0) {
					var userList;
					if (result.length > 1) {
						userList = result.reduce(function(prev, cur, i, arr) {
							if (i == 1) {
								return [prev.username, cur.username]
							} else {
								return prev.concat(cur.username);
							}
						});
					} else {
						userList = [result[0].username];
					}
					var offlineUsers = userList.filter(function(user) {
						return Object.keys(loggedInUsers).indexOf(user) === -1 || !loggedInUsers[user];
					});
					cb(null, offlineUsers);
				} else {
					cb(null, []);
				}
			}
		});
	}

	//get all messages associated with the specified user
	that.getMessagesByUsername = function(username) {

		if (Object.keys(messages).indexOf(username) !== -1) {
			return messages[username];
		} else {
			return {};
		}
	}

	Object.freeze(that); //prevent any further modifications to the member fields and methods of this class
	return that;
})();

module.exports = Messagebase;<commit_msg>trimmed messagebase.js<commit_after>userData = {};
/*
	key = userKey
	value = {
		name: string
		team: string
		coordinates: tuple of floats
		timestamp: datetime
	}
*/
captureData = {};
/*
	key = unique id for spawnpoint
	value = {
		ownedBy: string //team name
		coordinates: tuple of floats
		lastCaptured: datetime
	}
*/

teams = {};

var Messagebase = (function Messagebase() {
	var that = Object.create(Messagebase.prototype);

	var io = null;

	var COORD_SIZE_CAP = 20;

	that.setUp = function() {
		captureData['a'] = {
			'ownedBy': null,
			'coordinates': [42.357836,-71.093371],
			'lastCaptured': new Date()
		}

		captureData['b'] = {
			'ownedBy': null,
			'coordinates': [42.358328, -71.093843],
			'lastCaptured': new Date()
		}

		captureData['c'] = {
			'ownedBy': null,
			'coordinates': [42.357202, -71.092641],
			'lastCaptured': new Date()
		}

		captureData['d'] = {
			'ownedBy': null,
			'coordinates': [42.357242, -71.095119],
			'lastCaptured': new Date()
		}

		captureData['e'] = {
			'ownedBy': null,
			'coordinates': [42.359613, -71.091231],
			'lastCaptured': new Date()
		}
		teams["red"] = {};
		teams["blue"] = {};
	}

	that.setIO = function(IO) {

		that.setUp();

		io = IO;

		//io connection
		io.on('connection', function(socket){
			console.log("connection established");

			socket.on('disconnect', function(){
			});

			//on initial connection, create player data
			//then send current state of the game
			socket.on('session', function(player){
				console.log("new phone connected: ", player);

				teamAssignment = "";
				if (teams["blue"].length <= teams["red"].length) {
					teamAssignment = "blue";
					teams["blue"][player] = true;
				}
				else {
					teamAssignment = "red";
					teams["red"][player] = true;;
				}

				userData[player] = {'name': player, 'team': teamAssignment, 'coordinates': []};

				console.log("team assignments: ", teams);

				setTimeout(function(){}, 3000);

				io.emit("gameStatusUpdate", captureData);
			});

			socket.on('playerUpdate', function(data) {
				console.log("playerUpdate called, data: ", data);
				player = data.player;
				latitude = data.latitude;
				longitude = data.longitude;

				if (!(player in userData)) {
					userData[player] = {'name': 'test', 'team': 'gray', 'coordinates': []};
					//should never happen since we must call on session first
				}

				if (userData[player]['coordinates'].length > COORD_SIZE_CAP) {
					userData[player]['coordinates'].pop(0);
				}
				userData[player]['coordinates'].push([latitude, longitude]);
				userData[player]['timestamp'] = new Date();

				//DEBUG
				console.log("emitting: ", userData);
				io.emit("playerUpdate_confirm", userData);
			});

			socket.on('capture', function(data) {
				console.log("someone just tried to capture something: ", data);

				capturePointKey = data.capturePoint;
				player = data.player;

				now = new Date();

				if (now - capturePointKey['lastCaptured'] > 30000) {

					if (captureData[capturePointKey]['ownedBy'] == null) {
						captureData[capturePointKey]['ownedBy'] = playerTimestamp;
						captureData[capturePointKey]['lastCaptured'] = now;
						io.emit("gameStatusUpdate", captureData); //only run this on success
					}
					else {
						//handle logic regarding team battle over a spawnpoint

						//if successful
						captureData[capturePointKey]['ownedBy'] = playerTimestamp;
						captureData[capturePointKey]['lastCaptured'] = now;
						io.emit("gameStatusUpdate", captureData); //only run this on success
					}
				}
			});

		});

		setInterval( function() {
			io.emit("session", "this is a timed message " + userData);
		}, 5000); // 1000 = 1 sec

		setInterval( function() {
			now = new Date();
			for (pIndex in userData) {
				playerTimestamp = userData[pIndex]['timestamp'];
				if (now - playerTimestamp > 60000) { //if last update was more than a minute ago
					io.emit("playerShutdown", userData[pIndex]); //emit to everyone that player x has been disconnected
				}
			}
		}, 20000);

	}

	Object.freeze(that); //prevent any further modifications to the member fields and methods of this class
	return that;
})();

module.exports = Messagebase;<|endoftext|>


<commit_before>var Events = require('../models/Events')

module.exports = {
  /**
   * GET /events
   * List of Event examples.
   */
  getEvents: function (req, res) {
    Events.find({}, function (err, foundEvents) {
      if (err) console.error(err)
      res.render(res.locals.brigade.theme.slug + '/views/events/index', {
        events: foundEvents,
        upcomingevents: foundEvents.slice(0, 10),
        title: 'Events',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * GET /events/manage
   * Manage Events.
   */
  getEventsManage: function (req, res) {
    Events.find({}, function (err, foundEvents) {
      if (err) console.error(err)
      res.render(res.locals.brigade.theme.slug + '/views/events/manage', {
        title: 'Manage Events',
        allEvents: foundEvents,
        brigade: res.locals.brigade
      })
    }).sort({start: 1})
  },
  /**
   * POST /events/manage
   * Update all Events.
   */
  postEventsManage: function (req, res) {
    res.redirect('Events/manage')
  },
  /**
   * GET /events/new
   * New Events.
   */
  getEventsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/events/new', {
      title: 'New Events',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /events/new
   * Submit New Events.
   */
  postEventsNew: function (req, res) {
    res.redirect('events/new')
  },

  /**
   * GET /events/:eventID
   * Display Event by ID.
   */
  getEventsID: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/events/event', {
      eventID: req.params.eventID,
      title: 'Events',
      brigade: res.locals.brigade
    })
  },
  /**
   * GET /events/:eventID/settings
   * IDSettings Events.
   */
  getEventsIDSettings: function (req, res) {
    Events.find( {id: req.params.eventId}, function (err, foundEvent) {
      if (err) console.log(err)
      console.log(foundEvent)
      res.render(res.locals.brigade.theme.slug + '/views/events/settings', {
        event: foundEvent[0],
        title: 'IDSettings Events',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * POST /events/:eventID/settings
   * Submit IDSettings Events.
   */
  postEventsIDSettings: function (req, res) {
    console.log(req.params)
    res.redirect('/events/' + req.params.eventId + '/settings')
  },
  /**
   * POST /events/sync
   * Sync Events.
   */
  postEventsSync: function (req, res) {
    var meetupid = res.locals.brigade.meetup.split('.com/')[1].replace(/\//g, '')
    var url = 'https://api.meetup.com/2/events?&sign=true&photo-host=public&group_urlname=' + meetupid + '&page=50'
    Events.fetchMeetupEvents(url).then(function (value) {
      req.flash('success', { msg: 'Success! You have successfully synced events from Meetup.' })
      res.redirect('/events/manage')
    }).catch(function (error) {
      req.flash('errors', { msg: error })
      res.redirect('/events/manage')
    })
  },
  /**
   * POST /events/:eventID/settings
   * Submit IDSettings Events.
   */
  postEventsIDSync: function (req, res) {
    res.redirect('Events/' + req.params.eventID + '/settings')
  },

  postDeleteEvent: function (req, res) {
    Events.remove({ id: req.params.eventId }, function (err) {
      if (err) {
        console.log(err)
      }
      res.redirect('/events/manage')
    })
  }
}
<commit_msg>complete controller work for updating/editing events.<commit_after>var Events = require('../models/Events')

module.exports = {
  /**
   * GET /events
   * List of Event examples.
   */
  getEvents: function (req, res) {
    Events.find({}, function (err, foundEvents) {
      if (err) console.error(err)
      res.render(res.locals.brigade.theme.slug + '/views/events/index', {
        events: foundEvents,
        upcomingevents: foundEvents.slice(0, 10),
        title: 'Events',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * GET /events/manage
   * Manage Events.
   */
  getEventsManage: function (req, res) {
    Events.find({}, function (err, foundEvents) {
      if (err) console.error(err)
      res.render(res.locals.brigade.theme.slug + '/views/events/manage', {
        title: 'Manage Events',
        allEvents: foundEvents,
        brigade: res.locals.brigade
      })
    }).sort({start: 1})
  },
  /**
   * POST /events/manage
   * Update all Events.
   */
  postEventsManage: function (req, res) {
    res.redirect('Events/manage')
  },
  /**
   * GET /events/new
   * New Events.
   */
  getEventsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/events/new', {
      title: 'New Events',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /events/new
   * Submit New Events.
   */
  postEventsNew: function (req, res) {
    res.redirect('events/new')
  },

  /**
   * GET /events/:eventID
   * Display Event by ID.
   */
  getEventsID: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/events/event', {
      eventID: req.params.eventID,
      title: 'Events',
      brigade: res.locals.brigade
    })
  },
  /**
   * GET /events/:eventID/settings
   * IDSettings Events.
   */
  getEventsIDSettings: function (req, res) {
    Events.find({id: req.params.eventId}, function (err, foundEvent) {
      if (err) console.log(err)
      res.render(res.locals.brigade.theme.slug + '/views/events/settings', {
        event: foundEvent[0],
        title: 'IDSettings Events',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * POST /events/:eventID/settings
   * Submit IDSettings Events.
   */
  postEventsIDSettings: function (req, res) {
    console.log(req.body)
    Events.find({id: req.params.eventId}, function (err, foundEvent) {
      if (err) console.log(err)
      var thisEvent = foundEvent[0]
      thisEvent.title = req.body.title
      thisEvent.location = req.body.location
      thisEvent.start = req.body.start
      thisEvent.end = req.body.end
      thisEvent.url = req.body.url
      thisEvent.description = req.body.description
      thisEvent.save(function (err) {
        if (err) console.log(err)
      })
      req.flash('success', {msg: 'Success! You have updated your event.'})
      res.redirect('/events/' + req.params.eventId + '/settings')
    })
  },
  /**
   * POST /events/sync
   * Sync Events.
   */
  postEventsSync: function (req, res) {
    var meetupid = res.locals.brigade.meetup.split('.com/')[1].replace(/\//g, '')
    var url = 'https://api.meetup.com/2/events?&sign=true&photo-host=public&group_urlname=' + meetupid + '&page=50'
    Events.fetchMeetupEvents(url).then(function (value) {
      req.flash('success', {msg: 'Success! You have successfully synced events from Meetup.'})
      res.redirect('/events/manage')
    }).catch(function (error) {
      req.flash('errors', {msg: error})
      res.redirect('/events/manage')
    })
  },
  /**
   * POST /events/:eventID/settings
   * Submit IDSettings Events.
   */
  postEventsIDSync: function (req, res) {
    res.redirect('Events/' + req.params.eventID + '/settings')
  },

  postDeleteEvent: function (req, res) {
    Events.remove({id: req.params.eventId}, function (err) {
      if (err) {
        console.log(err)
      }
      res.redirect('/events/manage')
    })
  }
}
<|endoftext|>


<commit_before>class APIDocumentation {
  static _markdownToDOM(markdownText) {
    const reader = new commonmark.Parser();
    const ast = reader.parse(markdownText);
    const writer = new commonmark.HtmlRenderer();
    const result = writer.render(ast);
    const domParser = new DOMParser();

    // Translate all links to api.md to local links.
    const doc = document.importNode(domParser.parseFromString(result, 'text/html').body, true);
    for (const a of doc.querySelectorAll('a')) {
      const match = a.href.match(/github.com\/GoogleChrome\/puppeteer\/blob\/(v[^/]+)\/docs\/api.md#(.*)/);
      if (match)
        a.href = app.linkURL('Puppeteer', match[1], APIDocumentation._idFromGHAnchor(match[2]));
    }
    return doc;
  }
  /**
   * @param {string} version
   * @param {string} releaseNotes
   * @param {string} markdownText
   */
  static create(version, releaseNotes, markdownText) {
    // Parse markdown into HTML
    const doc = APIDocumentation._markdownToDOM(markdownText);

    // Translate all relative links to ppdoc links.
    for (const anchor of doc.querySelectorAll('a')) {
      const href = anchor.getAttribute('href') || '';
      if (href.startsWith('#')) {
        // Link referencing other part of documentation.
        const githubAnchor = href.substring(1);
        const entryId = APIDocumentation._idFromGHAnchor(githubAnchor);
        anchor.setAttribute('href', app.linkURL('Puppeteer', version, entryId));
      } else if (href.startsWith('/') || href.startsWith('../') || href.startsWith('./')) {
        // Link pointing somewhere to PPTR repository.
        const isRelease = /^\d+\.\d+\.\d+$/.test(version);
        const branch = isRelease ? 'v' + version : 'master';
        anchor.setAttribute('href', `https://github.com/GoogleChrome/puppeteer/blob/${branch}/docs/${href}`);
      }
      // Mark link as external if necessary
      if (anchor.hostname !== location.hostname && anchor.hostname.length)
        anchor.appendChild(document.createElement('external-link-icon'));
    }

    // Highlight all code blocks.
    for (const node of doc.querySelectorAll('code.language-javascript')) {
      node.classList.remove('language-javascript');
      node.classList.add('language-js');
    }
    for (const code of doc.querySelectorAll('code.language-js'))
      CodeMirror.runMode(code.textContent, 'text/javascript', code);

    const api = new APIDocumentation(version);

    // Add release notes if we have any.
    if (releaseNotes) {
      api.sections.push(APISection.createReleaseNotes(api, APIDocumentation._markdownToDOM(releaseNotes)));
    }

    // All class headers are rendered as H3 tags
    const headers = doc.querySelectorAll('h3');
    for (let i = 0; i < headers.length; ++i) {
      const header = headers[i];
      const nextHeader = i + 1 < headers.length ? headers[i + 1] : null;
      const title = header.textContent;
      // Import all HTML from section until we hit next top-level header.
      const content = extractSiblingsIntoFragment(header.nextSibling, nextHeader);
      if (title.toLowerCase().startsWith('class:'))
        api.classes.push(APIClass.create(api, title, content));
      else
        api.sections.push(APISection.create(api, title, content));
    }
    api._initializeContentIds();
    for (const apiClass of api.classes)
      apiClass._initializeTableOfContents();
    return api;
  }

  static _idFromGHAnchor(githubAnchor) {
    return 'api-' + githubAnchor;
  }

  constructor(version) {
    this.version = version;
    this.sections = [];
    this.classes = [];

    this._defaultContentId = null;
    this._idToEntry = new Map();
  }

  defaultContentId() {
    return this._defaultContentId;
  }

  _initializeContentIds() {
    const generateGithubAnchor = (title) => {
      const id = title.trim().toLowerCase().replace(/\s/g, '-').replace(/[^-0-9a-zа-яё]/ig, '');
      let dedupId = id;
      let counter = 0;
      while (this._idToEntry.has(dedupId))
        dedupId = id + '-' + (++counter);
      return dedupId;
    }

    const assignId = (entry, title) => {
      const contentId = APIDocumentation._idFromGHAnchor(generateGithubAnchor(title));
      entry.contentId = contentId;
      this._idToEntry.set(contentId, entry);
    };

    for (const section of this.sections)
      assignId(section, section.name);
    for (const apiClass of this.classes) {
      assignId(apiClass, `class: '${apiClass.name}'`);
      for (const apiEvent of apiClass.events)
        assignId(apiEvent, `event: '${apiEvent.name}'`);
      for (const apiMethod of apiClass.methods)
        assignId(apiMethod, `${apiClass.loweredName}.${apiMethod.name}(${apiMethod.args})`);
      for (const ns of apiClass.namespaces)
        assignId(ns, `${apiClass.loweredName}.${ns.name}`);
    }

    this._defaultContentId = this._idToEntry.keys().next().value;
  }

  idToEntry(id) {
    return this._idToEntry.get(id) || null;
  }
}

class APIEntry {
  constructor(api, name, element, contentId) {
    this.api = api;
    this.name = name;
    this.element = element;
    // This has to be assigned later.
    this.contentId = null;
  }

  linkURL() {
    return app.linkURL('Puppeteer', this.api.version, this.contentId);
  }
}

class APISection extends APIEntry {
  static create(api, title, descFragment) {
    const element = document.createElement('api-section');
    element.classList.add('api-entry');
    element.innerHTML = `<h1>${title}</h1>`;
    element.appendChild(descFragment);
    return new APISection(api, title, element);
  }

  static createReleaseNotes(api, descFragment) {
    const element = document.createElement('api-section');
    element.classList.add('api-entry');
    element.innerHTML = `<h1>${api.version} Release Notes</h1>`;
    element.appendChild(descFragment);
    return new APISection(api, 'Release Notes', element);
  }

  constructor(api, name, element) {
    super(api, name, element);
  }
}

class APIClass extends APIEntry {
  static create(api, title, fragment) {
    const name = title.replace(/^class:/i, '').trim();
    const headers = fragment.querySelectorAll('h4');

    const element = document.createElement('api-class');
    element.classList.add('api-entry');
    element.innerHTML = `<h3><pptr-class-icon></pptr-class-icon><api-class-name>class: ${name}</api-class-name></h3>`;
    element.appendChild(extractSiblingsIntoFragment(fragment.firstChild, headers[0]));
    const apiClass = new APIClass(api, name, element);

    for (let i = 0; i < headers.length; ++i) {
      const header = headers[i];
      const nextHeader = i + 1 < headers.length ? headers[i + 1] : null;
      const title = header.textContent;
      const fragment = extractSiblingsIntoFragment(header.nextSibling, nextHeader);
      if (title.toLowerCase().startsWith('event:'))
        apiClass.events.push(APIEvent.create(apiClass, title, fragment));
      else if (title.includes('('))
        apiClass.methods.push(APIMethod.create(apiClass, title, fragment));
      else
        apiClass.namespaces.push(APINamespace.create(apiClass, title, fragment));
    }
    return apiClass;
  }

  constructor(api, name, element) {
    super(api, name, element);
    this.loweredName = name.substring(0, 1).toLowerCase() + name.substring(1);
    this.methods = [];
    this.events = [];
    this.namespaces = [];
  }

  _initializeTableOfContents() {
    const addHeader = (tagName, text) => {
      const header = document.createElement(tagName);
      header.textContent = text;
      this.element.appendChild(header);
    };

    if (this.events.length) {
      addHeader('h4', 'Events');
      const ul = document.createElement('ul');
      for (const apiEvent of this.events)
        createTOC(ul, `${this.loweredName}.on('${apiEvent.name}')`, apiEvent);
      this.element.appendChild(ul);
    }
    if (this.namespaces.length) {
      addHeader('h4', 'Namespaces');
      const ul = document.createElement('ul');
      for (const ns of this.namespaces)
        createTOC(ul, this.loweredName + '.' + ns.name, ns);
      this.element.appendChild(ul);
    }
    if (this.methods.length) {
      addHeader('h4', 'Methods');
      const ul = document.createElement('ul');
      for (const apiMethod of this.methods)
        createTOC(ul, `${this.loweredName}.${apiMethod.name}(${apiMethod.args})`, apiMethod);
      this.element.appendChild(ul);
    }

    function createTOC(ul, text, entity) {
      const li = document.createElement('li');
      li.innerHTML = `<a href=${entity.linkURL()}>${text}</a>`;
      ul.appendChild(li);
    }

  }
}

class APINamespace extends APIEntry {
  static create(apiClass, title, fragment) {
    const name = title.split('.').pop();
    const element = document.createElement('api-ns');
    element.classList.add('api-entry');
    element.innerHTML = [
      `<h4>`,
        '<pptr-ns-icon></pptr-ns-icon>',
        `<api-ns-classname>${apiClass.loweredName}</api-ns-classname>`,
        `<api-ns-name>.${name}</api-ns-name>`,
      `</h4>`
    ].join('');
    element.appendChild(fragment);
    return new APINamespace(apiClass, name, element);
  }

  constructor(apiClass, name, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
  }
}

class APIMethod extends APIEntry {
  static create(apiClass, title, descFragment) {
    const name = title.match(/\.([^(]*)/)[1];
    const args = title.match(/\((.*)\)/)[1];
    const element = document.createElement('api-method');
    element.classList.add('api-entry');
    element.innerHTML = [
      `<h4>
        <pptr-method-icon></pptr-method-icon>
        <api-method-classname>${apiClass.loweredName}</api-method-classname>`,
        `<api-method-name>.${name}</api-method-name>`,
        `<api-method-args>(${args})</api-method-args>`,
      `</h4>`
    ].join('');
    element.appendChild(descFragment);
    return new APIMethod(apiClass, name, args, element);
  }

  constructor(apiClass, name, args, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
    this.args = args;
  }
}

class APIEvent extends APIEntry {
  static create(apiClass, title, descFragment) {
    const name = title.match(/'(.*)'/)[1];
    const element = document.createElement('api-event');
    element.classList.add('api-entry');
    element.innerHTML = `<h4><pptr-event-icon></pptr-event-icon>${apiClass.loweredName}.on(<api-event-name>'${name}'</api-event-name>)</h4>`;
    element.appendChild(descFragment);
    return new APIEvent(apiClass, name, element);
  }

  constructor(apiClass, name, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
  }
}

/**
 * @param {!Node} fromInclusive
 * @param {!Node} toExclusive
 * @return {!DocumentFragment}
 */
function extractSiblingsIntoFragment(fromInclusive, toExclusive) {
  const fragment = document.createDocumentFragment();
  let node = fromInclusive;
  while (node && node !== toExclusive) {
    const next = node.nextSibling;
    fragment.appendChild(node);
    node = next;
  }
  return fragment;
}

<commit_msg>fix: suppport propert serialization of CDPSession<commit_after>class APIDocumentation {
  static _markdownToDOM(markdownText) {
    const reader = new commonmark.Parser();
    const ast = reader.parse(markdownText);
    const writer = new commonmark.HtmlRenderer();
    const result = writer.render(ast);
    const domParser = new DOMParser();

    // Translate all links to api.md to local links.
    const doc = document.importNode(domParser.parseFromString(result, 'text/html').body, true);
    for (const a of doc.querySelectorAll('a')) {
      const match = a.href.match(/github.com\/GoogleChrome\/puppeteer\/blob\/(v[^/]+)\/docs\/api.md#(.*)/);
      if (match)
        a.href = app.linkURL('Puppeteer', match[1], APIDocumentation._idFromGHAnchor(match[2]));
    }
    return doc;
  }
  /**
   * @param {string} version
   * @param {string} releaseNotes
   * @param {string} markdownText
   */
  static create(version, releaseNotes, markdownText) {
    // Parse markdown into HTML
    const doc = APIDocumentation._markdownToDOM(markdownText);

    // Translate all relative links to ppdoc links.
    for (const anchor of doc.querySelectorAll('a')) {
      const href = anchor.getAttribute('href') || '';
      if (href.startsWith('#')) {
        // Link referencing other part of documentation.
        const githubAnchor = href.substring(1);
        const entryId = APIDocumentation._idFromGHAnchor(githubAnchor);
        anchor.setAttribute('href', app.linkURL('Puppeteer', version, entryId));
      } else if (href.startsWith('/') || href.startsWith('../') || href.startsWith('./')) {
        // Link pointing somewhere to PPTR repository.
        const isRelease = /^\d+\.\d+\.\d+$/.test(version);
        const branch = isRelease ? 'v' + version : 'master';
        anchor.setAttribute('href', `https://github.com/GoogleChrome/puppeteer/blob/${branch}/docs/${href}`);
      }
      // Mark link as external if necessary
      if (anchor.hostname !== location.hostname && anchor.hostname.length)
        anchor.appendChild(document.createElement('external-link-icon'));
    }

    // Highlight all code blocks.
    for (const node of doc.querySelectorAll('code.language-javascript')) {
      node.classList.remove('language-javascript');
      node.classList.add('language-js');
    }
    for (const code of doc.querySelectorAll('code.language-js'))
      CodeMirror.runMode(code.textContent, 'text/javascript', code);

    const api = new APIDocumentation(version);

    // Add release notes if we have any.
    if (releaseNotes) {
      api.sections.push(APISection.createReleaseNotes(api, APIDocumentation._markdownToDOM(releaseNotes)));
    }

    // All class headers are rendered as H3 tags
    const headers = doc.querySelectorAll('h3');
    for (let i = 0; i < headers.length; ++i) {
      const header = headers[i];
      const nextHeader = i + 1 < headers.length ? headers[i + 1] : null;
      const title = header.textContent;
      // Import all HTML from section until we hit next top-level header.
      const content = extractSiblingsIntoFragment(header.nextSibling, nextHeader);
      if (title.toLowerCase().startsWith('class:'))
        api.classes.push(APIClass.create(api, title, content));
      else
        api.sections.push(APISection.create(api, title, content));
    }
    api._initializeContentIds();
    for (const apiClass of api.classes)
      apiClass._initializeTableOfContents();
    return api;
  }

  static _idFromGHAnchor(githubAnchor) {
    return 'api-' + githubAnchor;
  }

  constructor(version) {
    this.version = version;
    this.sections = [];
    this.classes = [];

    this._defaultContentId = null;
    this._idToEntry = new Map();
  }

  defaultContentId() {
    return this._defaultContentId;
  }

  _initializeContentIds() {
    const generateGithubAnchor = (title) => {
      const id = title.trim().toLowerCase().replace(/\s/g, '-').replace(/[^-0-9a-zа-яё]/ig, '');
      let dedupId = id;
      let counter = 0;
      while (this._idToEntry.has(dedupId))
        dedupId = id + '-' + (++counter);
      return dedupId;
    }

    const assignId = (entry, title) => {
      const contentId = APIDocumentation._idFromGHAnchor(generateGithubAnchor(title));
      entry.contentId = contentId;
      this._idToEntry.set(contentId, entry);
    };

    for (const section of this.sections)
      assignId(section, section.name);
    for (const apiClass of this.classes) {
      assignId(apiClass, `class: '${apiClass.name}'`);
      for (const apiEvent of apiClass.events)
        assignId(apiEvent, `event: '${apiEvent.name}'`);
      for (const apiMethod of apiClass.methods)
        assignId(apiMethod, `${apiClass.loweredName}.${apiMethod.name}(${apiMethod.args})`);
      for (const ns of apiClass.namespaces)
        assignId(ns, `${apiClass.loweredName}.${ns.name}`);
    }

    this._defaultContentId = this._idToEntry.keys().next().value;
  }

  idToEntry(id) {
    return this._idToEntry.get(id) || null;
  }
}

class APIEntry {
  constructor(api, name, element, contentId) {
    this.api = api;
    this.name = name;
    this.element = element;
    // This has to be assigned later.
    this.contentId = null;
  }

  linkURL() {
    return app.linkURL('Puppeteer', this.api.version, this.contentId);
  }
}

class APISection extends APIEntry {
  static create(api, title, descFragment) {
    const element = document.createElement('api-section');
    element.classList.add('api-entry');
    element.innerHTML = `<h1>${title}</h1>`;
    element.appendChild(descFragment);
    return new APISection(api, title, element);
  }

  static createReleaseNotes(api, descFragment) {
    const element = document.createElement('api-section');
    element.classList.add('api-entry');
    element.innerHTML = `<h1>${api.version} Release Notes</h1>`;
    element.appendChild(descFragment);
    return new APISection(api, 'Release Notes', element);
  }

  constructor(api, name, element) {
    super(api, name, element);
  }
}

class APIClass extends APIEntry {
  static create(api, title, fragment) {
    const name = title.replace(/^class:/i, '').trim();
    const headers = fragment.querySelectorAll('h4');

    const element = document.createElement('api-class');
    element.classList.add('api-entry');
    element.innerHTML = `<h3><pptr-class-icon></pptr-class-icon><api-class-name>class: ${name}</api-class-name></h3>`;
    element.appendChild(extractSiblingsIntoFragment(fragment.firstChild, headers[0]));
    const apiClass = new APIClass(api, name, element);

    for (let i = 0; i < headers.length; ++i) {
      const header = headers[i];
      const nextHeader = i + 1 < headers.length ? headers[i + 1] : null;
      const title = header.textContent;
      const fragment = extractSiblingsIntoFragment(header.nextSibling, nextHeader);
      if (title.toLowerCase().startsWith('event:'))
        apiClass.events.push(APIEvent.create(apiClass, title, fragment));
      else if (title.includes('('))
        apiClass.methods.push(APIMethod.create(apiClass, title, fragment));
      else
        apiClass.namespaces.push(APINamespace.create(apiClass, title, fragment));
    }
    return apiClass;
  }

  constructor(api, name, element) {
    super(api, name, element);
    let lowerIndex = 1;
    while (lowerIndex < this.name.length && this.name[lowerIndex + 1] === this.name[lowerIndex + 1].toUpperCase()) ++lowerIndex;
    this.loweredName = name.substring(0, lowerIndex).toLowerCase() + name.substring(lowerIndex);
    this.methods = [];
    this.events = [];
    this.namespaces = [];
  }

  _initializeTableOfContents() {
    const addHeader = (tagName, text) => {
      const header = document.createElement(tagName);
      header.textContent = text;
      this.element.appendChild(header);
    };

    if (this.events.length) {
      addHeader('h4', 'Events');
      const ul = document.createElement('ul');
      for (const apiEvent of this.events)
        createTOC(ul, `${this.loweredName}.on('${apiEvent.name}')`, apiEvent);
      this.element.appendChild(ul);
    }
    if (this.namespaces.length) {
      addHeader('h4', 'Namespaces');
      const ul = document.createElement('ul');
      for (const ns of this.namespaces)
        createTOC(ul, this.loweredName + '.' + ns.name, ns);
      this.element.appendChild(ul);
    }
    if (this.methods.length) {
      addHeader('h4', 'Methods');
      const ul = document.createElement('ul');
      for (const apiMethod of this.methods)
        createTOC(ul, `${this.loweredName}.${apiMethod.name}(${apiMethod.args})`, apiMethod);
      this.element.appendChild(ul);
    }

    function createTOC(ul, text, entity) {
      const li = document.createElement('li');
      li.innerHTML = `<a href=${entity.linkURL()}>${text}</a>`;
      ul.appendChild(li);
    }

  }
}

class APINamespace extends APIEntry {
  static create(apiClass, title, fragment) {
    const name = title.split('.').pop();
    const element = document.createElement('api-ns');
    element.classList.add('api-entry');
    element.innerHTML = [
      `<h4>`,
        '<pptr-ns-icon></pptr-ns-icon>',
        `<api-ns-classname>${apiClass.loweredName}</api-ns-classname>`,
        `<api-ns-name>.${name}</api-ns-name>`,
      `</h4>`
    ].join('');
    element.appendChild(fragment);
    return new APINamespace(apiClass, name, element);
  }

  constructor(apiClass, name, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
  }
}

class APIMethod extends APIEntry {
  static create(apiClass, title, descFragment) {
    const name = title.match(/\.([^(]*)/)[1];
    const args = title.match(/\((.*)\)/)[1];
    const element = document.createElement('api-method');
    element.classList.add('api-entry');
    element.innerHTML = [
      `<h4>
        <pptr-method-icon></pptr-method-icon>
        <api-method-classname>${apiClass.loweredName}</api-method-classname>`,
        `<api-method-name>.${name}</api-method-name>`,
        `<api-method-args>(${args})</api-method-args>`,
      `</h4>`
    ].join('');
    element.appendChild(descFragment);
    return new APIMethod(apiClass, name, args, element);
  }

  constructor(apiClass, name, args, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
    this.args = args;
  }
}

class APIEvent extends APIEntry {
  static create(apiClass, title, descFragment) {
    const name = title.match(/'(.*)'/)[1];
    const element = document.createElement('api-event');
    element.classList.add('api-entry');
    element.innerHTML = `<h4><pptr-event-icon></pptr-event-icon>${apiClass.loweredName}.on(<api-event-name>'${name}'</api-event-name>)</h4>`;
    element.appendChild(descFragment);
    return new APIEvent(apiClass, name, element);
  }

  constructor(apiClass, name, element) {
    super(apiClass.api, name, element);
    this.apiClass = apiClass;
  }
}

/**
 * @param {!Node} fromInclusive
 * @param {!Node} toExclusive
 * @return {!DocumentFragment}
 */
function extractSiblingsIntoFragment(fromInclusive, toExclusive) {
  const fragment = document.createDocumentFragment();
  let node = fromInclusive;
  while (node && node !== toExclusive) {
    const next = node.nextSibling;
    fragment.appendChild(node);
    node = next;
  }
  return fragment;
}

<|endoftext|>


<commit_before>(function() {
    Blockly.Blocks.accept_labels = {
        init: function() {
            this.setColour(120);
            this.appendDummyInput()
                .appendField("Accept labels");
            this.appendValueInput("VALUE")
                .setCheck("Boolean");
            this.setInputsInline(true);
            this.setPreviousStatement(true, ["error", "accept_labels", "send_reply", "continue_session", "events"]);
            this.setNextStatement(true, ["error", "accept_labels", "send_reply", "continue_session", "events"]);
            this.setTooltip('');
        }
    };
})();<commit_msg>Adds tooltip for accept_labels opt<commit_after>(function() {
    Blockly.Blocks.accept_labels = {
        init: function() {
            this.setColour(120);
            this.appendDummyInput()
                .appendField("Accept labels");
            this.appendValueInput("VALUE")
                .setCheck("Boolean");
            this.setInputsInline(true);
            this.setPreviousStatement(true, ["error", "accept_labels", "send_reply", "continue_session", "events"]);
            this.setNextStatement(true, ["error", "accept_labels", "send_reply", "continue_session", "events"]);
            this.setTooltip('Whether choice labels are accepted as the user’s responses. For eg, if accept_labels is true, the state will accepts both “1” and “Red” as responses responses if the state’s first choice is “Red”. Defaults to false.');
        }
    };
})();<|endoftext|>


<commit_before>"use strict";
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function () {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
      addDataToView(xhttp);
    }
  };
  xhttp.open("GET", "../server/medication.php" + document.location.search, true);
  xhttp.send();
}

function addDataToView(res) {
  try {
    var jsonResponse = JSON.parse(res.responseText);

    if(jsonResponse.patient == null || jsonResponse.patient == "") {
      window.alert("Patient does not exist!");
    }
    var patientsList = ""
    for(var patient of jsonResponse.patients) {
      if(patient.patientID == jsonResponse.patient.patientID) {
        patientsList += "
";
        patientsList += patient.patientName + "
";
      } else {
        patientsList += "
";
        patientsList += patient.patientName + "
";
      }
    }
    var doctors = "";
    for(var doctor of jsonResponse.doctors) {
    	doctors += "<option value='" + doctor.doctorID +
        "'>" + doctor.doctorName + "</option>\n";
    }
    var nurses = "";
    for(var nurse of jsonResponse.nurses) {
    	nurses += "<option value='" + nurse.nurseID +
        "'>" + nurse.nurseName + "</option>\n";
    }
    var medicaments = "";
    for(var medicament of jsonResponse.medicaments) {
    	medicaments += "<option value='" + medicament.medicamentID +
        "'>" + medicament.medicamentName + "</option>\n";
    }

    var tableRows = "";
    if(jsonResponse.patient.vital_signs == null || jsonResponse.patient.vital_signs == ""){

    }else
    for(var medication of jsonResponse.patient.medications) {
      tableRows += "\t
\n";
      tableRows += "\t\t" + medication.time + "\t\t	\n";
      tableRows += "\t\t" + medication.quantity + "\t\t	\n";
      tableRows += "\t\t" + medication.medicament_name + "\t\t	\n";
      tableRows += "\t\t" + medication.nurse_name +", " + medication.nurse_first_name + "\t\t	\n";
      tableRows += "\t\t" + medication.physician_name +", "+ medication.physician_first_name + "\t\t	\n";
      tableRows += "\t\t" + medication.note + "\t\t	\n";
      tableRows += "\t
\n";
    }

    // var signTypesOptions = null;
//
    // for(var type of jsonResponse.vital_sign_types) {
      // signTypesOptions += "<option value='" + type.signID +
        // "'>" + type.sign_name + "</option>\n";
    // }
    document.getElementById("patients").innerHTML = patientsList;
    document.getElementById("nav-patient").setAttribute('href', window.location);
    document.getElementById("nav-patient").innerHTML += jsonResponse.patient.patient_name;
    document.getElementById("page-title").innerHTML += jsonResponse.patient.patient_name;
    document.getElementById("medications").innerHTML += tableRows;
    document.getElementById("nurse-select").innerHTML = nurses;
    document.getElementById("doctor-select").innerHTML = doctors;
    document.getElementById("medicament-select").innerHTML = medicaments;
    document.getElementById("patientID").setAttribute('value', jsonResponse.patient.patientID);
  } catch (ex) {
    document.body.innerHTML = "
JS:

" + ex +
      "

PHP:

" + res.responseText+ "
";
  }
}<commit_msg>Es werden jetzt wieder alle Medikamente angezeigt.<commit_after>"use strict";
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function () {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
      addDataToView(xhttp);
    }
  };
  xhttp.open("GET", "../server/medication.php" + document.location.search, true);
  xhttp.send();
}

function addDataToView(res) {
  try {
    var jsonResponse = JSON.parse(res.responseText);

    if(jsonResponse.patient == null || jsonResponse.patient == "") {
      window.alert("Patient does not exist!");
    }
    var patientsList = ""
    for(var patient of jsonResponse.patients) {
      if(patient.patientID == jsonResponse.patient.patientID) {
        patientsList += "
";
        patientsList += patient.patientName + "
";
      } else {
        patientsList += "
";
        patientsList += patient.patientName + "
";
      }
    }
    var doctors = "";
    for(var doctor of jsonResponse.doctors) {
    	doctors += "<option value='" + doctor.doctorID +
        "'>" + doctor.doctorName + "</option>\n";
    }
    var nurses = "";
    for(var nurse of jsonResponse.nurses) {
    	nurses += "<option value='" + nurse.nurseID +
        "'>" + nurse.nurseName + "</option>\n";
    }
    var medicaments = "";
    for(var medicament of jsonResponse.medicaments) {
    	medicaments += "<option value='" + medicament.medicamentID +
        "'>" + medicament.medicamentName + "</option>\n";
    }

    var tableRows = "";
    if(jsonResponse.patient.medications == null || jsonResponse.patient.medications == ""){

    }else
    for(var medication of jsonResponse.patient.medications) {
      tableRows += "\t
\n";
      tableRows += "\t\t" + medication.time + "\t\t	\n";
      tableRows += "\t\t" + medication.quantity + "\t\t	\n";
      tableRows += "\t\t" + medication.medicament_name + "\t\t	\n";
      tableRows += "\t\t" + medication.nurse_name +", " + medication.nurse_first_name + "\t\t	\n";
      tableRows += "\t\t" + medication.physician_name +", "+ medication.physician_first_name + "\t\t	\n";
      tableRows += "\t\t" + medication.note + "\t\t	\n";
      tableRows += "\t
\n";
    }

    // var signTypesOptions = null;
//
    // for(var type of jsonResponse.vital_sign_types) {
      // signTypesOptions += "<option value='" + type.signID +
        // "'>" + type.sign_name + "</option>\n";
    // }
    document.getElementById("patients").innerHTML = patientsList;
    document.getElementById("nav-patient").setAttribute('href', window.location);
    document.getElementById("nav-patient").innerHTML += jsonResponse.patient.patient_name;
    document.getElementById("page-title").innerHTML += jsonResponse.patient.patient_name;
    document.getElementById("medications").innerHTML += tableRows;
    document.getElementById("nurse-select").innerHTML = nurses;
    document.getElementById("doctor-select").innerHTML = doctors;
    document.getElementById("medicament-select").innerHTML = medicaments;
    document.getElementById("patientID").setAttribute('value', jsonResponse.patient.patientID);
  } catch (ex) {
    document.body.innerHTML = "
JS:

" + ex +
      "

PHP:

" + res.responseText+ "
";
  }
}<|endoftext|>


<commit_before>/* eslint-env node, es6 */

const path = require('path');
const pkg = require('../package.json');

module.exports = function(karma) {
  karma.set({
    frameworks: ['mocha'],
    client: {
      runInParent: true,
      mocha: {
        timeout: 2500
      }
    },
    files: [
      {
        pattern: path.resolve(__dirname, require.resolve('url-polyfill/url-polyfill.js')),
        watched: false
      },
      {
        pattern: 'module-global.js',
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('jquery/dist/jquery.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('expect.js/index.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('sinon/pkg/sinon.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('proj4/dist/proj4.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('pixelmatch/index.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, './test-extensions.js')
      }, {
        pattern: '**/*.test.js'
      }, {
        pattern: '**/*',
        included: false,
        watched: false
      }
    ],
    proxies: {
      '/rendering/': '/base/rendering/',
      '/spec/': '/base/spec/'
    },
    preprocessors: {
      '**/*.js': ['webpack']
    },
    reporters: ['progress'],
    webpackMiddleware: {
      noInfo: true
    }
  });

  if (process.env.TRAVIS) {
    const testName = process.env.TRAVIS_PULL_REQUEST ?
      `https://github.com/openlayers/openlayers/pull/${process.env.TRAVIS_PULL_REQUEST}` :
      `${pkg.name}@${pkg.version} (${process.env.TRAVIS_COMMIT})`;

    // see https://wiki.saucelabs.com/display/DOCS/Platform+Configurator
    // for platform and browserName options (Selenium API, node.js code)
    const customLaunchers = {
      SL_Chrome: {
        base: 'SauceLabs',
        browserName: 'chrome'
      },
      SL_Firefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
      },
      SL_Edge: {
        base: 'SauceLabs',
        platform: 'Windows 10',
        browserName: 'MicrosoftEdge'
      },
      SL_Safari: {
        base: 'SauceLabs',
        platform: 'macOS 10.12',
        browserName: 'safari'
      }
    };
    karma.set({
      sauceLabs: {
        testName: testName,
        recordScreenshots: false,
        startConnect: true,
        tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        username: 'openlayers',
        accessKey: process.env.SAUCE_ACCESS_KEY,
        connectOptions: {
          noSslBumpDomains: 'all',
          connectRetries: 5
        }
      },
      hostname: 'travis.dev',
      reporters: ['dots', 'saucelabs'],
      browserDisconnectTimeout: 10000,
      browserDisconnectTolerance: 1,
      captureTimeout: 240000,
      browserNoActivityTimeout: 240000,
      customLaunchers: customLaunchers,
      browsers: Object.keys(customLaunchers),
      preprocessors: {
        '../src/**/*.js': ['coverage']
      },
      coverageReporter: {
        reporters: [
          {
            type: 'lcovonly', // that's enough for coveralls, no HTML
            dir: '../coverage/',
            subdir: '.'
          },
          {
            type: 'text-summary' // prints the textual summary to the terminal
          }
        ]
      }
    });
  } else {
    karma.set({
      browsers: ['Chrome']
    });
  }
};
<commit_msg>Set Chrome version to 62.0 in SauceLab config<commit_after>/* eslint-env node, es6 */

const path = require('path');
const pkg = require('../package.json');

module.exports = function(karma) {
  karma.set({
    frameworks: ['mocha'],
    client: {
      runInParent: true,
      mocha: {
        timeout: 2500
      }
    },
    files: [
      {
        pattern: path.resolve(__dirname, require.resolve('url-polyfill/url-polyfill.js')),
        watched: false
      },
      {
        pattern: 'module-global.js',
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('jquery/dist/jquery.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('expect.js/index.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('sinon/pkg/sinon.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('proj4/dist/proj4.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, require.resolve('pixelmatch/index.js')),
        watched: false
      }, {
        pattern: path.resolve(__dirname, './test-extensions.js')
      }, {
        pattern: '**/*.test.js'
      }, {
        pattern: '**/*',
        included: false,
        watched: false
      }
    ],
    proxies: {
      '/rendering/': '/base/rendering/',
      '/spec/': '/base/spec/'
    },
    preprocessors: {
      '**/*.js': ['webpack']
    },
    reporters: ['progress'],
    webpackMiddleware: {
      noInfo: true
    }
  });

  if (process.env.TRAVIS) {
    const testName = process.env.TRAVIS_PULL_REQUEST ?
      `https://github.com/openlayers/openlayers/pull/${process.env.TRAVIS_PULL_REQUEST}` :
      `${pkg.name}@${pkg.version} (${process.env.TRAVIS_COMMIT})`;

    // see https://wiki.saucelabs.com/display/DOCS/Platform+Configurator
    // for platform and browserName options (Selenium API, node.js code)
    const customLaunchers = {
      SL_Chrome: {
        base: 'SauceLabs',
        browserName: 'chrome',
        version: '62.0'
      },
      SL_Firefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
      },
      SL_Edge: {
        base: 'SauceLabs',
        platform: 'Windows 10',
        browserName: 'MicrosoftEdge'
      },
      SL_Safari: {
        base: 'SauceLabs',
        platform: 'macOS 10.12',
        browserName: 'safari'
      }
    };
    karma.set({
      sauceLabs: {
        testName: testName,
        recordScreenshots: false,
        startConnect: true,
        tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
        username: 'openlayers',
        accessKey: process.env.SAUCE_ACCESS_KEY,
        connectOptions: {
          noSslBumpDomains: 'all',
          connectRetries: 5
        }
      },
      hostname: 'travis.dev',
      reporters: ['dots', 'saucelabs'],
      browserDisconnectTimeout: 10000,
      browserDisconnectTolerance: 1,
      captureTimeout: 240000,
      browserNoActivityTimeout: 240000,
      customLaunchers: customLaunchers,
      browsers: Object.keys(customLaunchers),
      preprocessors: {
        '../src/**/*.js': ['coverage']
      },
      coverageReporter: {
        reporters: [
          {
            type: 'lcovonly', // that's enough for coveralls, no HTML
            dir: '../coverage/',
            subdir: '.'
          },
          {
            type: 'text-summary' // prints the textual summary to the terminal
          }
        ]
      }
    });
  } else {
    karma.set({
      browsers: ['Chrome']
    });
  }
};
<|endoftext|>