<commit_before>'use strict';

var Injector = require('./modules/injector');
var Controllers = require('./modules/controllers');
var Static = require('./modules/static');
var Models = require('./modules/models');
var API = require('./modules/api');
var Bridge = require('./modules/bridge');
var Templates = require('./modules/templates');
var Bridge = require('./modules/bridge');
var Workers = require('./modules/workers');
var HTTPServer = require('./modules/http-server');
var ConfigureFunctions = require('./modules/configure-functions');
var Tasks = require('./modules/tasks');
var WebSockets = require('./modules/websockets');
var Channels = require('./modules/channels');
var ModuleProperties = require('./modules/module-properties');
var Triggers = require('./modules/triggers');
var Clock = require('./modules/clock');
var Schedulers = require('./modules/schedulers');
var Middleware = require('./modules/middleware');
var Tests = require('./modules/tests');
var Isomorphic = require('./modules/isomorphic');

var utils = require('./helpers/utils');
var config = require('./helpers/config');
var fs = require('fs');

var AppContainer = require('./app-container');

var path = require('path');
var inflection = require('inflection');

var Q = require('q');
var minimist = require('minimist');
var debug = require('debug')('fire:app');

exports = module.exports = App;

/**
 * Initialize a new `App` for both the client- and server-context. A new app is usually created via {@link Firestarter#app}.
 *
 * In the client-context, this creates an `angular.Module` with `name` and requires from `settings.modules`. This instance also acts as a proxy to the `angular.Module`. This means that you can invoke `directive`, `controller` or any of the `angular.Module` methods.
 *
 * For a complete list, angular's Module documentation at {@link https://docs.angularjs.org/api/ng/type/angular.Module}.
 *
 * @param {String} name    Name of the app.
 * @param {Dictionary} settings
 * @param {String} settings.type The type of the app, either angular or ractive.
 * @param {Array} settings.modules List of requires passed to angular.Module. These modules are also automatically bundled in browserify if they are available in `node_modules`.
 * @param {Array} settings.require List of additional files to bundle in browserify in the build stage.
 * @param {Boolean} settings.isMaster Whether this app is the master. A master app is responsible for any shared models and other dependencies.
 *
 * @constructor
 */
function App(name, settings, container) {
	debug('Creating app `' + name + '` ' + JSON.stringify(settings) + '.');

	this.name = name;
	this._settings = settings || {};
	this.container = container;

	Object.defineProperty(this, 'type', {
		get: function() {
			throw new Error('App#type is deprecated. Use App#settings(\'type\') instead.');
		}
	});

	if(!this._settings.type) {
		this._settings.type = 'angular';
	}

	if(typeof this._settings.modules == 'undefined') {
		this._settings.modules = ['angular-route'];
	}

	if(typeof this._settings.require == 'undefined') {
		this._settings.require = [];
	}

	for(var i = 0, il = this._settings.modules.length; i < il; i++) {
		var moduleName = this._settings.modules[i];
		if(moduleName == 'ngRoute') {
			throw new Error([
				'`ngRoute` found instead of `angular-route`.',
				'',
				'Node on Fire now uses browserify and a CommonJS-based loading on the client-side. It looks like your project is still based on bower. Please migrate your project.',
				'',
				'Please check your modules in your app and install the CommonJS versions from npm (most if not all libraries from bower should be available in npm. This removes one dependency: bower). Rename `ngRoute` in modules to `angular-route` and do a `npm install angular-route --save`.',
				'',
				'If you have additional files you want to bundle, please include them in the `require` key in the settings object when creating an app, see http://nodeonfire.org/documentation/App.html.',
				'',
				'Lastly, update your `view.jade` to remove all unnecessary scripts and load the `/scripts/bundle.min.js.`. This files includes all JavaScript.'
			].join('\n'));
		}
	}

	this.modules = [];
	this._loadModules();
}

App.prototype.isRunStage = function() {
	return (this.container.stage == 'run');
};

App.prototype.isBuildStage = function() {
	return (this.container.stage == 'build');
};

App.prototype.isReleaseStage = function() {
	return (this.container.stage == 'release');
};

App.prototype.settings = function(key, value) {
	if(typeof value == 'undefined') {
		return this._settings[key];
	}
	else {
		this._settings[key] = value;
		return value;
	}
};

App.prototype._loadModules = function() {
	// TODO: Load these modules automatically?

	this.addModule(Injector);
	this.addModule(Templates);
	this.addModule(Models);
	this.addModule(Controllers);
	this.addModule(Bridge);
	this.addModule(Clock);
	this.addModule(API);
	this.addModule(Workers);
	this.addModule(Triggers);
	this.addModule(HTTPServer);
	this.addModule(Middleware);
	this.addModule(ConfigureFunctions);
	this.addModule(Static);
	this.addModule(Tasks);
	this.addModule(Schedulers);
	//this.addModule(WebSockets);
	//this.addModule(Channels);
	this.addModule(Tests);
	this.addModule(ModuleProperties);
	this.addModule(Isomorphic);
};

App.prototype.requireDirSync = function(dirPath, all) {
	if(this.container.numberOfApps() == 1) {
		utils._requireDirSync(dirPath);
	}
	else if(all) {
		this.settings('_sharedMode', true);

		utils._requireDirSync(path.join(dirPath, AppContainer.kSharedAppName));

		this.settings('_sharedMode', false);

		Object.keys(this.container.appsMap).forEach(function(appName) {
			this.container.setActiveApp(this.container.appsMap[appName]);
			utils._requireDirSync(path.join(dirPath, appName));
			this.container.setActiveApp(null);
		}, this);
	}
	else {
		this.settings('_sharedMode', true);

		utils._requireDirSync(path.join(dirPath, AppContainer.kSharedAppName));

		this.settings('_sharedMode', false);

		utils._requireDirSync(path.join(dirPath, this.name));

		// Only check in development mode as we do not want to increase start-up time of the app in production.
		if(process.env.NODE_ENV != 'production' && fs.existsSync(dirPath)) {
			var self = this;
			fs.readdirSync(dirPath).forEach(function(resourceFileName) {
				if(resourceFileName.length && resourceFileName[0] != '_' && resourceFileName[0] != '.') {
					var fullPath = path.join(dirPath, resourceFileName);
					if(!fs.lstatSync(fullPath).isDirectory()) {
						throw new Error('Not loading file `' + resourceFileName + '`. You have multiple apps and the file is not in one of the app folders or the `_shared` folder.');
					}
					else if(resourceFileName != AppContainer.kSharedAppName) {
						try {
							self.container.getApp(resourceFileName);
						}
						catch(e) {
							console.log(e);

							throw new Error('Found folder `' + resourceFileName + '` but no app of this names exists. The active app is `' + self.name + '`. If this folder should be loaded, be sure to create an app with the same name. If it should not be loaded, please rename the folder to `_' + resourceFileName + '`.');
						}
					}
				}
			});
		}
	}
};

/**
 * Adds a new module to the app.
 *
 * @param {Constructor} moduleConstructor The module constructor which gets invoked with 1 param: this app instance.
 * @return {App} The app instance-so this method is chainable.
 */
App.prototype.addModule = function(moduleConstructor) {
	if(typeof moduleConstructor.prototype.ignoreDisabled != 'undefined') {
		throw new Error('Module#ignoreDisabled is deprecated. Please use Module#stages to indicate which stages the module should be available.');
	}

	if(typeof moduleConstructor.prototype.stages == 'undefined') {
		throw new Error('Module#stages is undefined. Please set which stages `' + moduleConstructor.name + '` should run.');
	}

	var stages = moduleConstructor.prototype.stages;

	if(this._settings.disabled && stages.indexOf(this.container.stage) == -1) {
		debug('Not loading module `' + moduleConstructor.name + '`.');
	}
	else {
		var module_ = new moduleConstructor(this);
		this.modules.push(module_);

		// We get the name of the property based on the name of the constructor
		var propertyName = inflection.camelize(moduleConstructor.name, (moduleConstructor.name.length <= 1 || moduleConstructor.name.substring(1, 2).toLowerCase() == moduleConstructor.name.substring(1, 2)));

		if(this[propertyName]) {
			throw new Error('Module `' + propertyName + '` already exists.');
		}

		debug('Adding module `' + propertyName + '`.');

		Object.defineProperty(this, propertyName, {
			value: module_,
			configurable: true
		});

		this.injector.register(propertyName, function() {
			return module_;
		});
	}
	return this;
};

App.prototype.isActive = function() {
	return (this.container.numberOfApps() == 1 || this.container.getActiveAppName() == this.name);
};

/**
 * Removes a module.
 *
 * ```
 * app.removeModule(app.webSockets);
 * ```
 */
App.prototype.removeModule = function(module_) {
	var index = this.modules.indexOf(module_);
	if(index >= 0) {
		this.modules.splice(index, 1);

		var propertyName = inflection.camelize(module_.constructor.name, (module_.constructor.name.length <= 1 || module_.constructor.name.substring(1, 2).toLowerCase() == module_.constructor.name.substring(1, 2)));
		this.injector.unregister(propertyName);
		delete this[propertyName];
	}
};

/**
 * Stops the app. This also invokes the `stop` method on all modules.
 *
 * @return {Promise} Resolves when closing of the server finishes, or rejects when an error occurs.
 */
App.prototype.stop = function() {
	debug('Stopping app `' + this.name + '`.');

	var stoppingModules = [];

	this.modules.forEach(function(module_) {
		if(module_.stop) {
			stoppingModules.push(module_.stop());
		}
	});

	return Q.all(stoppingModules);
};

/**
 * Starts the app.
 *
 * This method is deprecated. Please use `fire#start()` instead.
 *
 * @deprecated
 */
App.prototype.start = function() {
	throw new Error('This method is deprecated. Please use `fire#start()` instead.');
};

/**
 * Starts the app by setting up all modules, invoking all configure functions, starting the HTTP server and binding to the value of PORT defined in the environmental table.
 *
 * This method should not be be invoked multiple times (even after calling App#stop).
 *
 * @return {Promise}
 */
App.prototype._start = function() {
	if(this._settings.disabled) {
		debug('Cancelling App#start because of app disabled');
		return Q.when(null);
	}

	var argv = minimist(process.argv.slice(2)) || {};
	debug('App#_start (arguments: ' + Object.keys(argv).join(', ') + ')');

	this.injector.register('argv', function() {
		return argv;
	});

	var self = this;
	return (function setupModules(app) {
		debug('App#setup');

		var result = Q.when(true);

		app.modules.forEach(function(module_) {
			result = result.then(function() {
				debug(module_.constructor.name + '#setup');

				// TODO: use dependency injection. We really should pass the argv in here.
				return Q.when((module_.setup || function(){}).call(module_, config.basePath));
			});
		});

		return result;
	})(this)
		.then(function startModules() {
			var startingModules = [];

			self.modules.forEach(function(module_) {
				if(module_.start) {
					startingModules.push(module_.start(argv));
				}
			});

			return Q.all(startingModules);
		})
		.catch(function(error) {
			console.log(error);
			console.log(error.stack);
			throw error;
		});
};
<commit_msg>implements dependency injection in Module#start and Module#setup<commit_after>'use strict';

var Injector = require('./modules/injector');
var Controllers = require('./modules/controllers');
var Static = require('./modules/static');
var Models = require('./modules/models');
var API = require('./modules/api');
var Bridge = require('./modules/bridge');
var Templates = require('./modules/templates');
var Bridge = require('./modules/bridge');
var Workers = require('./modules/workers');
var HTTPServer = require('./modules/http-server');
var ConfigureFunctions = require('./modules/configure-functions');
var Tasks = require('./modules/tasks');
var WebSockets = require('./modules/websockets');
var Channels = require('./modules/channels');
var ModuleProperties = require('./modules/module-properties');
var Triggers = require('./modules/triggers');
var Clock = require('./modules/clock');
var Schedulers = require('./modules/schedulers');
var Middleware = require('./modules/middleware');
var Tests = require('./modules/tests');
var Isomorphic = require('./modules/isomorphic');

var utils = require('./helpers/utils');
var config = require('./helpers/config');
var fs = require('fs');

var AppContainer = require('./app-container');

var path = require('path');
var inflection = require('inflection');

var Q = require('q');
var minimist = require('minimist');
var debug = require('debug')('fire:app');

exports = module.exports = App;

/**
 * Initialize a new `App` for both the client- and server-context. A new app is usually created via {@link Firestarter#app}.
 *
 * In the client-context, this creates an `angular.Module` with `name` and requires from `settings.modules`. This instance also acts as a proxy to the `angular.Module`. This means that you can invoke `directive`, `controller` or any of the `angular.Module` methods.
 *
 * For a complete list, angular's Module documentation at {@link https://docs.angularjs.org/api/ng/type/angular.Module}.
 *
 * @param {String} name    Name of the app.
 * @param {Dictionary} settings
 * @param {String} settings.type The type of the app, either angular or ractive.
 * @param {Array} settings.modules List of requires passed to angular.Module. These modules are also automatically bundled in browserify if they are available in `node_modules`.
 * @param {Array} settings.require List of additional files to bundle in browserify in the build stage.
 * @param {Boolean} settings.isMaster Whether this app is the master. A master app is responsible for any shared models and other dependencies.
 *
 * @constructor
 */
function App(name, settings, container) {
	debug('Creating app `' + name + '` ' + JSON.stringify(settings) + '.');

	this.name = name;
	this._settings = settings || {};
	this.container = container;

	Object.defineProperty(this, 'type', {
		get: function() {
			throw new Error('App#type is deprecated. Use App#settings(\'type\') instead.');
		}
	});

	if(!this._settings.type) {
		this._settings.type = 'angular';
	}

	if(typeof this._settings.modules == 'undefined') {
		this._settings.modules = ['angular-route'];
	}

	if(typeof this._settings.require == 'undefined') {
		this._settings.require = [];
	}

	for(var i = 0, il = this._settings.modules.length; i < il; i++) {
		var moduleName = this._settings.modules[i];
		if(moduleName == 'ngRoute') {
			throw new Error([
				'`ngRoute` found instead of `angular-route`.',
				'',
				'Node on Fire now uses browserify and a CommonJS-based loading on the client-side. It looks like your project is still based on bower. Please migrate your project.',
				'',
				'Please check your modules in your app and install the CommonJS versions from npm (most if not all libraries from bower should be available in npm. This removes one dependency: bower). Rename `ngRoute` in modules to `angular-route` and do a `npm install angular-route --save`.',
				'',
				'If you have additional files you want to bundle, please include them in the `require` key in the settings object when creating an app, see http://nodeonfire.org/documentation/App.html.',
				'',
				'Lastly, update your `view.jade` to remove all unnecessary scripts and load the `/scripts/bundle.min.js.`. This files includes all JavaScript.'
			].join('\n'));
		}
	}

	this.modules = [];
	this._loadModules();
}

App.prototype.isRunStage = function() {
	return (this.container.stage == 'run');
};

App.prototype.isBuildStage = function() {
	return (this.container.stage == 'build');
};

App.prototype.isReleaseStage = function() {
	return (this.container.stage == 'release');
};

App.prototype.settings = function(key, value) {
	if(typeof value == 'undefined') {
		return this._settings[key];
	}
	else {
		this._settings[key] = value;
		return value;
	}
};

App.prototype._loadModules = function() {
	// TODO: Load these modules automatically?

	this.addModule(Injector);
	this.addModule(Templates);
	this.addModule(Models);
	this.addModule(Controllers);
	this.addModule(Bridge);
	this.addModule(Clock);
	this.addModule(API);
	this.addModule(Workers);
	this.addModule(Triggers);
	this.addModule(HTTPServer);
	this.addModule(Middleware);
	this.addModule(ConfigureFunctions);
	this.addModule(Static);
	this.addModule(Tasks);
	this.addModule(Schedulers);
	//this.addModule(WebSockets);
	//this.addModule(Channels);
	this.addModule(Tests);
	this.addModule(ModuleProperties);
	this.addModule(Isomorphic);
};

App.prototype.requireDirSync = function(dirPath, all) {
	if(this.container.numberOfApps() == 1) {
		utils._requireDirSync(dirPath);
	}
	else if(all) {
		this.settings('_sharedMode', true);

		utils._requireDirSync(path.join(dirPath, AppContainer.kSharedAppName));

		this.settings('_sharedMode', false);

		Object.keys(this.container.appsMap).forEach(function(appName) {
			this.container.setActiveApp(this.container.appsMap[appName]);
			utils._requireDirSync(path.join(dirPath, appName));
			this.container.setActiveApp(null);
		}, this);
	}
	else {
		this.settings('_sharedMode', true);

		utils._requireDirSync(path.join(dirPath, AppContainer.kSharedAppName));

		this.settings('_sharedMode', false);

		utils._requireDirSync(path.join(dirPath, this.name));

		// Only check in development mode as we do not want to increase start-up time of the app in production.
		if(process.env.NODE_ENV != 'production' && fs.existsSync(dirPath)) {
			var self = this;
			fs.readdirSync(dirPath).forEach(function(resourceFileName) {
				if(resourceFileName.length && resourceFileName[0] != '_' && resourceFileName[0] != '.') {
					var fullPath = path.join(dirPath, resourceFileName);
					if(!fs.lstatSync(fullPath).isDirectory()) {
						throw new Error('Not loading file `' + resourceFileName + '`. You have multiple apps and the file is not in one of the app folders or the `_shared` folder.');
					}
					else if(resourceFileName != AppContainer.kSharedAppName) {
						try {
							self.container.getApp(resourceFileName);
						}
						catch(e) {
							console.log(e);

							throw new Error('Found folder `' + resourceFileName + '` but no app of this names exists. The active app is `' + self.name + '`. If this folder should be loaded, be sure to create an app with the same name. If it should not be loaded, please rename the folder to `_' + resourceFileName + '`.');
						}
					}
				}
			});
		}
	}
};

/**
 * Adds a new module to the app.
 *
 * @param {Constructor} moduleConstructor The module constructor which gets invoked with 1 param: this app instance.
 * @return {App} The app instance-so this method is chainable.
 */
App.prototype.addModule = function(moduleConstructor) {
	if(typeof moduleConstructor.prototype.ignoreDisabled != 'undefined') {
		throw new Error('Module#ignoreDisabled is deprecated. Please use Module#stages to indicate which stages the module should be available.');
	}

	if(typeof moduleConstructor.prototype.stages == 'undefined') {
		throw new Error('Module#stages is undefined. Please set which stages `' + moduleConstructor.name + '` should run.');
	}

	var stages = moduleConstructor.prototype.stages;

	if(this._settings.disabled && stages.indexOf(this.container.stage) == -1) {
		debug('Not loading module `' + moduleConstructor.name + '`.');
	}
	else {
		var module_ = new moduleConstructor(this);
		this.modules.push(module_);

		// We get the name of the property based on the name of the constructor
		var propertyName = inflection.camelize(moduleConstructor.name, (moduleConstructor.name.length <= 1 || moduleConstructor.name.substring(1, 2).toLowerCase() == moduleConstructor.name.substring(1, 2)));

		if(this[propertyName]) {
			throw new Error('Module `' + propertyName + '` already exists.');
		}

		debug('Adding module `' + propertyName + '`.');

		Object.defineProperty(this, propertyName, {
			value: module_,
			configurable: true
		});

		this.injector.register(propertyName, function() {
			return module_;
		});
	}
	return this;
};

App.prototype.isActive = function() {
	return (this.container.numberOfApps() == 1 || this.container.getActiveAppName() == this.name);
};

/**
 * Removes a module.
 *
 * ```
 * app.removeModule(app.webSockets);
 * ```
 */
App.prototype.removeModule = function(module_) {
	var index = this.modules.indexOf(module_);
	if(index >= 0) {
		this.modules.splice(index, 1);

		var propertyName = inflection.camelize(module_.constructor.name, (module_.constructor.name.length <= 1 || module_.constructor.name.substring(1, 2).toLowerCase() == module_.constructor.name.substring(1, 2)));
		this.injector.unregister(propertyName);
		delete this[propertyName];
	}
};

/**
 * Stops the app. This also invokes the `stop` method on all modules.
 *
 * @return {Promise} Resolves when closing of the server finishes, or rejects when an error occurs.
 */
App.prototype.stop = function() {
	debug('Stopping app `' + this.name + '`.');

	var stoppingModules = [];

	this.modules.forEach(function(module_) {
		if(module_.stop) {
			stoppingModules.push(module_.stop());
		}
	});

	return Q.all(stoppingModules);
};

/**
 * Starts the app.
 *
 * This method is deprecated. Please use `fire#start()` instead.
 *
 * @deprecated
 */
App.prototype.start = function() {
	throw new Error('This method is deprecated. Please use `fire#start()` instead.');
};

/**
 * Starts the app by setting up all modules, invoking all configure functions, starting the HTTP server and binding to the value of PORT defined in the environmental table.
 *
 * This method should not be be invoked multiple times (even after calling App#stop).
 *
 * @return {Promise}
 */
App.prototype._start = function() {
	if(this._settings.disabled) {
		debug('Cancelling App#start because of app disabled');
		return Q.when(null);
	}

	var argv = minimist(process.argv.slice(2)) || {};
	debug('App#_start (arguments: ' + Object.keys(argv).join(', ') + ')');

	this.injector.register('argv', function() {
		return argv;
	});

	var self = this;
	return (function setupModules(app) {
		debug('App#setup');

		var result = Q.when(true);

		app.modules.forEach(function(module_) {
			result = result.then(function() {
				debug(module_.constructor.name + '#setup');

				if(module_.setup) {
					return Q.when(app.injector.call(module_.setup, {basePath: config.basePath}, module_));
				}
			});
		});

		return result;
	})(this)
		.then(function startModules() {
			var startingModules = [];

			self.modules.forEach(function(module_) {
				if(module_.start) {
					startingModules.push(self.injector.call(module_.start, {}, module_));
				}
			});

			return Q.all(startingModules);
		})
		.catch(function(error) {
			console.log(error);
			console.log(error.stack);
			throw error;
		});
};
<|endoftext|>


<commit_before>function draw(){
    if(game_running){
        frames += 1;

        /*if new obstacle should be added this frame, add one*/
        if(frames % frames_per_obstacle === 0){
            i = random_number(30) + 40;
            obstacles.splice(
                0,
                0,
                [
                    x + i,
                    random_number(500) - 250,
                    i,
                    random_number(30) + 40
                ]
            )
        }

        /*if obstacle frequency increase should happen this frame, do it*/
        if(settings[4] > 0 && frames_per_obstacle > 1 && frames % settings[4] === 0){
            /*obstacle frequency increase*/
            frames_per_obstacle -= 1
        }

        /*if the player has activated jetpack, increase y speed and add smoke*/
        if(key_jetpack){
            player_speed += settings[2];/*jetpack power*/
            smoke.splice(
                0,
                0,
                [
                    -20,
                    player_y - 10
                ]
            )

        /*else apply gravity*/
        }else{
            player_speed -= settings[1]/*gravity*/
        }

        player_y += player_speed
    }

    if(settings[8]){/*clear?*/
        buffer.clearRect(
            0,
            0,
            width,
            height
        )
    }

    /*draw corridor over grey background*/
    buffer.fillStyle = '#000';
    buffer.fillRect(
        0,
        y - 250,
        width,
        500
    );

    /*draw player body*/
    buffer.fillStyle = '#fff';
    buffer.fillRect(
        x,
        y - player_y - 25,
        25,
        50
    );

    /*draw jetpack*/
    buffer.fillStyle = '#aaa';
    buffer.fillRect(
        x - 25,
        y - player_y - 15,
        25,
        20
    );

    /*draw activated jetpack fire*/
    if(game_running && key_jetpack){
        buffer.fillStyle = '#f00';
        buffer.fillRect(
            x - 22,
            y - player_y + 5,
            18,
            10
        )
    }

    /*check if player is outside of game boundaries*/
    if(player_y + 25 > 250 || player_y - 25 < -250){
        game_running = 0;
        update_best()
    }

    i = obstacles.length - 1;
    if(i >= 0){
        if(game_running){
            do{
                /*delete obstacles that are past left side of screen*/
                if(obstacles[i][0] < -x){
                    obstacles.splice(i,1)
                }else{
                    /*move obstacles left*/
                    obstacles[i][0] -= 10;

                    /*check for player collision with obstacle*/
                    if(obstacles[i][0] >= -25 - obstacles[i][2] / 2 &&
                       obstacles[i][0] <=  25 + obstacles[i][2] / 2 &&
                       obstacles[i][1] >= -player_y - 25 - obstacles[i][3] / 2 &&
                       obstacles[i][1] <= -player_y + 25 + obstacles[i][3] / 2){
                        game_running = 0;
                        update_best()
                    }
                }
            }while(i--);

            /*get new amount of obstacles, some may have been spliced*/
            i = obstacles.length - 1
        }

        /*draw obstacles*/
        if(i >= 0){
            buffer.fillStyle = '#555';
            do{
                buffer.fillRect(
                    x + obstacles[i][0] - obstacles[i][2] / 2,
                    y + obstacles[i][1] - obstacles[i][3] / 2,
                    obstacles[i][2],
                    obstacles[i][3]
                )
            }while(i--)
        }
    }

    i = smoke.length-1;
    if(i >= 0){
        if(game_running){
            /*delete smoke trails past left side of screen, else move left*/
            do{
                if(smoke[i][0] < -x){
                    smoke.splice(i,1)
                }else if(game_running){
                    smoke[i][0] -= 10
                }
            }while(i--);

            /*get new amount of smoke, some may have been spliced*/
            i = smoke.length - 1
        }

        /*draw smoke trails behind the player*/
        if(i >= 0){
            buffer.fillStyle = '#777';
            do{
                buffer.fillRect(
                    x + smoke[i][0],
                    y - smoke[i][1],
                    10,
                    10
                )
            }while(i--)
        }
    }

    /*setup text display*/
    buffer.font = '23pt sans-serif';
    buffer.textAlign = 'center';
    buffer.textBaseline = 'top';
    buffer.fillStyle = '#afa';

    /*if game is over, display game over messages*/
    if(!game_running){
        if(!played_explosion_sound){
            if(settings[5] > 0){/*audio volume*/
                /*play explode sound*/
            }
            played_explosion_sound = 1
        }

        i = y / 2;
        if(frames > best_display){
            buffer.fillText(
                'NEW BEST SCORE!',
                x,
                i - 60
            )
        }
        buffer.fillText(
            'You crashed... ☹',
            x,
            i
        );
        buffer.fillText(
            settings[7] + '=Restart',/*restart key*/
            x,
            i + 60
        );
        buffer.fillText(
            'ESC=Main Menu',
            x,
            i+120
        )
    }

    /*top left text displays*/
    buffer.textAlign = 'left';
    buffer.fillText(
        frames,
        5,
        0
    );
    buffer.fillText(
        best_display,
        5,
        32
    );

    if(settings[8]){/*clear?*/
        canvas.clearRect(
            0,
            0,
            width,
            height
        )
    }
    canvas.drawImage(
        get('buffer'),
        0,
        0
    )
}

function get(i){
    return document.getElementById(i)
}

function random_number(i){
    return Math.floor(Math.random() * i)
}

function resize(){
    if(mode > 0){
        width = get('buffer').width = get('canvas').width = window.innerWidth;
        height = get('buffer').height = get('canvas').height = window.innerHeight;

        x = width / 2;
        y = height / 2
    }
}

function save(){
    i = 3;
    do{
        if(isNaN(get(['ms-per-frame','obstacle-frequency','obstacle-increase','audio-volume'][i]).value) || get(['ms-per-frame','obstacle-frequency','obstacle-increase','audio-volume'][i]).value < [1,1,0,0][i]){
            get('si').value = [30,23,115,1][i]
        }
    }while(i--);

    i = 5;
    do{
        j = [
            'ms-per-frame',
            'gravity',
            'jetpack-power',
            'obstacle-frequency',
            'obstacle-increase',
            'audio-volume'
        ][i];
        if(isNaN(get(j).value) || get(j).value === [30,1,2,23,115,1][i]){
            ls.removeItem('jetpack' + i);
            settings[i] = [30,1,2,23,115,1][i];
            get(j).value = settings[i]
        }else{
            settings[i] = parseFloat(get(j).value);
            ls.setItem('jetpack' + i,settings[i])
        }
    }while(i--);

    if(get('jetpack-key').value === 'W'){
        ls.removeItem('jetpack6');
        settings[6] = 'W'
    }else{
        settings[6] = get('jetpack-key').value;
        ls.setItem('jetpack6',settings[6])
    }

    if(get('restart-key').value === 'H'){
        ls.removeItem('jetpack7');
        settings[7] = 'H'
    }else{
        settings[7] = get('restart-key').value;
        ls.setItem('jetpack7',settings[7])
    }

    settings[8] = get('clear').checked;
    if(settings[8]){
        ls.removeItem('jetpack8')
    }else{
        ls.setItem('jetpack8',0)
    }
}

function setmode(newmode){
    clearInterval(interval);

    obstacles = [];
    smoke = [];
    best_display = best;
    mode = newmode;

    /*play game mode*/
    if(mode > 0){
        save();

        frames = 0;
        frames_per_obstacle = settings[3];/*obstacle frequency*/
        game_running = 1;
        played_explosion_sound = 0;
        player_speed = 0;
        player_y = 0;

        get('page').innerHTML='<canvas id=canvas></canvas>';
        buffer = get('buffer').getContext('2d');
        canvas = get('canvas').getContext('2d');

        resize();

        interval = setInterval('draw()',settings[0])/*ms/frame*/

    /*main menu mode*/
    }else{
        buffer = 0;
        canvas = 0;

        get('page').innerHTML='

Jetpack

Cave Corridor (Best: ' + best + ')

Reset Best

<input disabled size=9 style=border:0 type=text value="Mouse Click">Activate Jetpack
<input id=jetpack-key maxlength=1 size=9 type=text value=' + settings[6] + '>Activate Jetpack
<input disabled size=9 style=border:0 type=text value=ESC>Main Menu
<input id=restart-key maxlength=1 size=9 type=text value=' + settings[7] + '>Restart

<input id=audio-volume max=1 min=0 step=.01 type=range value=' + settings[5] + '>Audio
<input ' + (settings[8] ? 'checked ' : '')+'id=clear type=checkbox>Clear
Reset Settings
Hack

<input id=gravity size=1 type=text value=' + settings[1] + '>Gravity
<input id=jetpack-power size=1 type=text value=' + settings[2] + '>Jetpack Power
<input id=ms-per-frame size=1 type=text value=' + settings[0] + '>ms/Frame
<input id=obstacle-frequency size=1 type=text value=' + settings[3] + '>Obstacle Frequency
<input id=obstacle-increase size=1 type=text value=' + settings[4] + '>Obstacle Increase

'
    }
}

function update_best(){
    if(frames > best){
        best = frames
    }
    if(best > 0){
        ls.setItem('jetpack_best',best)
    }else{
        ls.removeItem('jetpack_best')
    }
}

var ls = window.localStorage;

var best = ls.getItem('jetpack_best') === null ? 0 : parseInt(ls.getItem('jetpack_best'));
var best_display = 0;
var buffer = 0;
var canvas = 0;
var frames = 0;
var game_running = 0;
var height = 0;
var i = 0;
var interval = 0;
var j = 0;
var key_jetpack = 0;
var mode = 0;
var obstacles = [];
var played_explosion_sound = 0;
var player_speed = 0;
var player_y = 0;
var frames_per_obstacle = 0;
var settings = [
    ls.getItem('jetpack0') === null ? 30 : parseInt(ls.getItem('jetpack0')),/*ms/frame*/
    ls.getItem('jetpack1') === null ? 1 : parseFloat(ls.getItem('jetpack1')),/*gravity*/
    ls.getItem('jetpack2') === null ? 2 : parseFloat(ls.getItem('jetpack2')),/*jetpack power*/
    ls.getItem('jetpack3') === null ? 23 : parseInt(ls.getItem('jetpack3')),/*obstacle frequency*/
    ls.getItem('jetpack4') === null ? 115 : parseInt(ls.getItem('jetpack4')),/*obstacle increase*/
    ls.getItem('jetpack5') === null ? 1 : parseFloat(ls.getItem('jetpack5')),/*audio volume*/
    ls.getItem('jetpack6') === null ? 'W' : ls.getItem('jetpack6'),/*activate jetpack key*/
    ls.getItem('jetpack7') === null ? 'H' : ls.getItem('jetpack7'),/*restart key*/
    ls.getItem('jetpack8') === null/*clear?*/
];
var smoke = [];
var width = 0;
var x = 0;
var y = 0;

setmode(0);

window.onkeydown = function(e){
    if(mode > 0){
        i = window.event ? event : e;
        i = i.charCode ? i.charCode : i.keyCode;
        if(String.fromCharCode(i) === settings[6]){/*activate jetpack key*/
            key_jetpack = 1
        }else if(String.fromCharCode(i) === settings[7]){/*restart key*/
            best_display = best;
            frames = 0;
            frames_per_obstacle = settings[3];/*obstacle frequency*/
            game_running = 1;
            obstacles = [];
            played_explosion_sound = 0;
            player_speed = 0;
            player_y = 0;
            smoke = []
        }else if(i === 27){/*ESC*/
            setmode(0)
        }
    }
};

window.onkeyup = function(e){
    i = window.event ? event : e;
    i = i.charCode ? i.charCode : i.keyCode;
    if(String.fromCharCode(i) === settings[6]){/*activate jetpack key*/
        key_jetpack = 0
    }
};

window.onmousedown = function(e){
    if(mode > 0){
        e.preventDefault();
        key_jetpack = 1
    }
};

window.onmouseup = function(e){
    key_jetpack = 0
};

window.onresize = resize
<commit_msg>improved formatting<commit_after>function draw(){
    if(game_running){
        frames += 1;

        /*if new obstacle should be added this frame, add one*/
        if(frames % frames_per_obstacle === 0){
            i = random_number(30) + 40;
            obstacles.splice(
                0,
                0,
                [
                    x + i,
                    random_number(500) - 250,
                    i,
                    random_number(30) + 40
                ]
            )
        }

        /*if obstacle frequency increase should happen this frame, do it*/
        if(settings[4] > 0 && frames_per_obstacle > 1 && frames % settings[4] === 0){
            /*obstacle frequency increase*/
            frames_per_obstacle -= 1
        }

        /*if the player has activated jetpack, increase y speed and add smoke*/
        if(key_jetpack){
            player_speed += settings[2];/*jetpack power*/
            smoke.splice(
                0,
                0,
                [
                    -20,
                    player_y - 10
                ]
            )

        /*else apply gravity*/
        }else{
            player_speed -= settings[1]/*gravity*/
        }

        player_y += player_speed
    }

    if(settings[8]){/*clear?*/
        buffer.clearRect(
            0,
            0,
            width,
            height
        )
    }

    /*draw corridor over grey background*/
    buffer.fillStyle = '#000';
    buffer.fillRect(
        0,
        y - 250,
        width,
        500
    );

    /*draw player body*/
    buffer.fillStyle = '#fff';
    buffer.fillRect(
        x,
        y - player_y - 25,
        25,
        50
    );

    /*draw jetpack*/
    buffer.fillStyle = '#aaa';
    buffer.fillRect(
        x - 25,
        y - player_y - 15,
        25,
        20
    );

    /*draw activated jetpack fire*/
    if(game_running && key_jetpack){
        buffer.fillStyle = '#f00';
        buffer.fillRect(
            x - 22,
            y - player_y + 5,
            18,
            10
        )
    }

    /*check if player is outside of game boundaries*/
    if(player_y + 25 > 250 || player_y - 25 < -250){
        game_running = 0;
        update_best()
    }

    i = obstacles.length - 1;
    if(i >= 0){
        if(game_running){
            do{
                /*delete obstacles that are past left side of screen*/
                if(obstacles[i][0] < -x){
                    obstacles.splice(i,1)
                }else{
                    /*move obstacles left*/
                    obstacles[i][0] -= 10;

                    /*check for player collision with obstacle*/
                    if(obstacles[i][0] >= -25 - obstacles[i][2] / 2 &&
                       obstacles[i][0] <=  25 + obstacles[i][2] / 2 &&
                       obstacles[i][1] >= -player_y - 25 - obstacles[i][3] / 2 &&
                       obstacles[i][1] <= -player_y + 25 + obstacles[i][3] / 2){
                        game_running = 0;
                        update_best()
                    }
                }
            }while(i--);

            /*get new amount of obstacles, some may have been spliced*/
            i = obstacles.length - 1
        }

        /*draw obstacles*/
        if(i >= 0){
            buffer.fillStyle = '#555';
            do{
                buffer.fillRect(
                    x + obstacles[i][0] - obstacles[i][2] / 2,
                    y + obstacles[i][1] - obstacles[i][3] / 2,
                    obstacles[i][2],
                    obstacles[i][3]
                )
            }while(i--)
        }
    }

    i = smoke.length-1;
    if(i >= 0){
        if(game_running){
            /*delete smoke trails past left side of screen, else move left*/
            do{
                if(smoke[i][0] < -x){
                    smoke.splice(i,1)
                }else if(game_running){
                    smoke[i][0] -= 10
                }
            }while(i--);

            /*get new amount of smoke, some may have been spliced*/
            i = smoke.length - 1
        }

        /*draw smoke trails behind the player*/
        if(i >= 0){
            buffer.fillStyle = '#777';
            do{
                buffer.fillRect(
                    x + smoke[i][0],
                    y - smoke[i][1],
                    10,
                    10
                )
            }while(i--)
        }
    }

    /*setup text display*/
    buffer.font = '23pt sans-serif';
    buffer.textAlign = 'center';
    buffer.textBaseline = 'top';
    buffer.fillStyle = '#afa';

    /*if game is over, display game over messages*/
    if(!game_running){
        if(!played_explosion_sound){
            if(settings[5] > 0){/*audio volume*/
                /*play explode sound*/
            }
            played_explosion_sound = 1
        }

        i = y / 2;
        if(frames > best_display){
            buffer.fillText(
                'NEW BEST SCORE!',
                x,
                i - 60
            )
        }
        buffer.fillText(
            'You crashed... ☹',
            x,
            i
        );
        buffer.fillText(
            settings[7] + ' = Restart',/*restart key*/
            x,
            i + 60
        );
        buffer.fillText(
            'ESC = Main Menu',
            x,
            i+120
        )
    }

    /*top left text displays*/
    buffer.textAlign = 'left';
    buffer.fillText(
        frames,
        5,
        0
    );
    buffer.fillText(
        best_display,
        5,
        32
    );

    if(settings[8]){/*clear?*/
        canvas.clearRect(
            0,
            0,
            width,
            height
        )
    }
    canvas.drawImage(
        get('buffer'),
        0,
        0
    )
}

function get(i){
    return document.getElementById(i)
}

function random_number(i){
    return Math.floor(Math.random() * i)
}

function resize(){
    if(mode > 0){
        width = get('buffer').width = get('canvas').width = window.innerWidth;
        height = get('buffer').height = get('canvas').height = window.innerHeight;

        x = width / 2;
        y = height / 2
    }
}

function save(){
    i = 3;
    do{
        if(isNaN(get(['ms-per-frame','obstacle-frequency','obstacle-increase','audio-volume'][i]).value) || get(['ms-per-frame','obstacle-frequency','obstacle-increase','audio-volume'][i]).value < [1,1,0,0][i]){
            get('si').value = [30,23,115,1][i]
        }
    }while(i--);

    i = 5;
    do{
        j = [
            'ms-per-frame',
            'gravity',
            'jetpack-power',
            'obstacle-frequency',
            'obstacle-increase',
            'audio-volume'
        ][i];
        if(isNaN(get(j).value) || get(j).value === [30,1,2,23,115,1][i]){
            ls.removeItem('jetpack' + i);
            settings[i] = [30,1,2,23,115,1][i];
            get(j).value = settings[i]
        }else{
            settings[i] = parseFloat(get(j).value);
            ls.setItem('jetpack' + i,settings[i])
        }
    }while(i--);

    if(get('jetpack-key').value === 'W'){
        ls.removeItem('jetpack6');
        settings[6] = 'W'
    }else{
        settings[6] = get('jetpack-key').value;
        ls.setItem('jetpack6',settings[6])
    }

    if(get('restart-key').value === 'H'){
        ls.removeItem('jetpack7');
        settings[7] = 'H'
    }else{
        settings[7] = get('restart-key').value;
        ls.setItem('jetpack7',settings[7])
    }

    settings[8] = get('clear').checked;
    if(settings[8]){
        ls.removeItem('jetpack8')
    }else{
        ls.setItem('jetpack8',0)
    }
}

function setmode(newmode){
    clearInterval(interval);

    obstacles = [];
    smoke = [];
    best_display = best;
    mode = newmode;

    /*play game mode*/
    if(mode > 0){
        save();

        frames = 0;
        frames_per_obstacle = settings[3];/*obstacle frequency*/
        game_running = 1;
        played_explosion_sound = 0;
        player_speed = 0;
        player_y = 0;

        get('page').innerHTML='<canvas id=canvas></canvas>';
        buffer = get('buffer').getContext('2d');
        canvas = get('canvas').getContext('2d');

        resize();

        interval = setInterval('draw()',settings[0])/*ms/frame*/

    /*main menu mode*/
    }else{
        buffer = 0;
        canvas = 0;

        get('page').innerHTML='

Jetpack

Cave Corridor (Best: '
            + best + ')

Reset Best

<input disabled size=9 style=border:0 type=text value="Mouse Click">Activate Jetpack
<input id=jetpack-key maxlength=1 size=9 type=text value='
            + settings[6] + '>Activate Jetpack
<input disabled size=9 style=border:0 type=text value=ESC>Main Menu
<input id=restart-key maxlength=1 size=9 type=text value='
            + settings[7] + '>Restart

<input id=audio-volume max=1 min=0 step=.01 type=range value='
            + settings[5] + '>Audio
<input '
            + (settings[8] ? 'checked ' : '')+'id=clear type=checkbox>Clear
Reset Settings
Hack

<input id=gravity size=1 type=text value='
            + settings[1] + '>Gravity
<input id=jetpack-power size=1 type=text value='
            + settings[2] + '>Jetpack Power
<input id=ms-per-frame size=1 type=text value='
            + settings[0] + '>ms/Frame
<input id=obstacle-frequency size=1 type=text value='
            + settings[3] + '>Obstacle Frequency
<input id=obstacle-increase size=1 type=text value='
            + settings[4] + '>Obstacle Increase

'
    }
}

function update_best(){
    if(frames > best){
        best = frames
    }
    if(best > 0){
        ls.setItem('jetpack_best',best)
    }else{
        ls.removeItem('jetpack_best')
    }
}

var ls = window.localStorage;

var best = ls.getItem('jetpack_best') === null ? 0 : parseInt(ls.getItem('jetpack_best'));
var best_display = 0;
var buffer = 0;
var canvas = 0;
var frames = 0;
var game_running = 0;
var height = 0;
var i = 0;
var interval = 0;
var j = 0;
var key_jetpack = 0;
var mode = 0;
var obstacles = [];
var played_explosion_sound = 0;
var player_speed = 0;
var player_y = 0;
var frames_per_obstacle = 0;
var settings = [
    ls.getItem('jetpack0') === null ? 30 : parseInt(ls.getItem('jetpack0')),/*ms/frame*/
    ls.getItem('jetpack1') === null ? 1 : parseFloat(ls.getItem('jetpack1')),/*gravity*/
    ls.getItem('jetpack2') === null ? 2 : parseFloat(ls.getItem('jetpack2')),/*jetpack power*/
    ls.getItem('jetpack3') === null ? 23 : parseInt(ls.getItem('jetpack3')),/*obstacle frequency*/
    ls.getItem('jetpack4') === null ? 115 : parseInt(ls.getItem('jetpack4')),/*obstacle increase*/
    ls.getItem('jetpack5') === null ? 1 : parseFloat(ls.getItem('jetpack5')),/*audio volume*/
    ls.getItem('jetpack6') === null ? 'W' : ls.getItem('jetpack6'),/*activate jetpack key*/
    ls.getItem('jetpack7') === null ? 'H' : ls.getItem('jetpack7'),/*restart key*/
    ls.getItem('jetpack8') === null/*clear?*/
];
var smoke = [];
var width = 0;
var x = 0;
var y = 0;

setmode(0);

window.onkeydown = function(e){
    if(mode > 0){
        i = window.event ? event : e;
        i = i.charCode ? i.charCode : i.keyCode;

        if(String.fromCharCode(i) === settings[6]){/*activate jetpack key*/
            key_jetpack = 1
        }else if(String.fromCharCode(i) === settings[7]){/*restart key*/
            best_display = best;
            frames = 0;
            frames_per_obstacle = settings[3];/*obstacle frequency*/
            game_running = 1;
            obstacles = [];
            played_explosion_sound = 0;
            player_speed = 0;
            player_y = 0;
            smoke = []
        }else if(i === 27){/*ESC*/
            setmode(0)
        }
    }
};

window.onkeyup = function(e){
    i = window.event ? event : e;
    i = i.charCode ? i.charCode : i.keyCode;

    if(String.fromCharCode(i) === settings[6]){/*activate jetpack key*/
        key_jetpack = 0
    }
};

window.onmousedown = function(e){
    if(mode > 0){
        e.preventDefault();
        key_jetpack = 1
    }
};

window.onmouseup = function(e){
    key_jetpack = 0
};

window.onresize = resize
<|endoftext|>


<commit_before>const express = require('express');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const enforce = require('express-sslify');
const controller = require('./controller');
const app = express();

function enableHttps() {
	let enableScript = process.env.ENV === 'local' ? null : app.use(enforce.HTTPS({ trustProtoHeader: true }));
	return enableScript;
}

enableHttps();

// app setup
app.engine('handlebars', exphbs({ defaultLayout: 'main' }));
app.set('view engine', 'handlebars');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/public', express.static(`${__dirname}/public`));

// app controller
app.get('/', controller.index);
// 404
app.use('*', controller.notFound);

app.set('port', process.env.PORT || 5000);

module.exports = app;
<commit_msg>Fix linter-related problems<commit_after>const express = require('express');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const enforce = require('express-sslify');
const controller = require('./controller');
const app = express();

const enableHttps = () => {
    const enableScript = process.env.ENV === 'local' ? null : app.use(enforce.HTTPS({ trustProtoHeader: true }));
    return enableScript;
};

enableHttps();

// app setup
app.engine('handlebars', exphbs({ defaultLayout: 'main' }));
app.set('view engine', 'handlebars');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/public', express.static(`${__dirname}/public`));

// app controller
app.get('/', controller.index);
// 404
app.use('*', controller.notFound);

app.set('port', process.env.PORT || 5000);

module.exports = app;
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
 * Jingo, wiki engine
 * http://github.com/claudioc/jingo
 *
 * Copyright 2014 Claudio Cicali <claudio.cicali@gmail.com>
 * Released under the MIT license
 */

var express        = require("express"),
    path           = require("path"),
    components     = require("./components"),
    wikiStatic     = require("./wikistatic"),
    favicon        = require("serve-favicon"),
    session        = require("express-session"),
    bodyParser     = require("body-parser"),
    expValidator   = require("express-validator"),
    cookieParser   = require("cookie-parser"),
    logger         = require("morgan"),
    program = require('commander'),
    cookieSession  = require("cookie-session"),
    gravatar       = require("gravatar"),
    passport       = require("passport"),
    methodOverride = require("method-override"),
    flash          = require("express-flash")
;

var app;

module.exports.getInstance = function() {
  if (!app) {
    throw new Error("Cannot get an instance of an unitialized App");
  }
  return app;
};

module.exports.initialize = function(config) {

  app = express();

  app.locals.config = config;

  app.locals.baseUrl = "//" + config.get("server").hostname + ":" + config.get("server").port;

  if (config.get("server").baseUrl == "") {
    app.locals.baseUrl = "//" + config.get("server").hostname + ":" + config.get("server").port;
  } else {
    app.locals.baseUrl = config.get("server").baseUrl;
  }

  // View helpers
  app.use(function (req, res, next) {
    res.locals = {
      get user() {
        return req.user;
      },
      get appTitle() {
        return config.get("application").title;
      },
      get jingoVersion() {
        return program.version();
      },
      get authentication() {
        return config.get("authentication");
      },
      isAnonymous: function () {
        return !req.user;
      },
      canSearch: function () {
        return !!req.user || app.locals.config.get("authorization").anonRead;
      },
      gravatar: function(email) {
        return gravatar;
      }
    };
    next();
  });

  app.locals.coalesce = function(value, def) {
    return typeof value === 'undefined' ? def : value;
  };

  app.locals.pretty = true; // Pretty HTML output from Jade

  app.locals.hasSidebar = components.hasSidebar;
  app.locals.hasFooter = components.hasFooter;
  app.locals.hasCustomStyle = components.hasCustomStyle;
  app.locals.hasCustomScript = components.hasCustomScript;
  app.locals.hasFeature = function(feature) {
    return !!app.locals.config.get("features")[feature];
  };

  if (components.hasCustomStyle()) {
    console.log("Using custom style " + config.get('customizations')['style']);
  }

  if (components.hasCustomScript()) {
    console.log("Using custom script "  + config.get('customizations')['script']);
  }

  app.enable('trust proxy', 'loopback');    // Trust only proxy on loopback
  if (config.get("application").loggingMode) {
    app.use(logger(config.get("application").loggingMode == 1 ? "combined" : "dev", {skip: function() { }}));
  }
  app.use(favicon(path.join(__dirname + "/../", 'public', 'favicon.ico')))
  app.use(bodyParser.urlencoded({extended: true, limit: "500kb"}));
  app.use(methodOverride(function(req, res){
    if (req.body && typeof req.body === 'object' && '_method' in req.body) {
      // look in urlencoded POST bodies and delete it
      var method = req.body._method;
      delete req.body._method;
      return method;
    }
  }));

  app.use(express.static(path.join(__dirname + "/../", 'public')));
  app.use(cookieParser());
  app.use(cookieSession({
    name: "JingoSession",
    keys: ["jingo"],
    cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 }
  }));
  app.use(session({ name: "jingosid",
                    secret: config.get("application").secret,
                    cookie: { httpOnly: true },
                    saveUninitialized: true,
                    resave: true
                  }));
  app.use(flash());
  app.use(expValidator());

  app.set('views', __dirname + '/../views');
  app.set('view engine', 'jade');

  app.use(function (req, res, next) {

    res.locals._style  = components.customStyle();
    res.locals._script = components.customScript();

    if ( /^\/auth\//.test(req.url) ||
         /^\/misc\//.test(req.url) ||
         (/^\/login/.test(req.url) && !config.get('authorization').anonRead)
       ) {
      return next();
    }

    components.sidebarAsync().then(function(content) {
      res.locals._sidebar = content;
      return components.footerAsync();
    }).then(function(content) {
      res.locals._footer = content;
      return next();
    }).catch(function(e) {
      console.log(e);
    });
  });

  app.use(passport.initialize());
  app.use(passport.session());

  app.locals.passport = passport;

  function requireAuthentication(req, res, next) {
    if (!res.locals.user) {
      res.redirect("/login");
    } else {
      next();
    }
  }

  app.all("/pages/*", requireAuthentication);

  if (!app.locals.config.get("authorization").anonRead) {
    app.all("/wiki/*", requireAuthentication);
    app.all("/search", requireAuthentication);
  }

  app.use("/wiki", wikiStatic.configure());

  app.use(require("../routes/wiki"))
     .use(require("../routes/pages"))
     .use(require("../routes/search"))
     .use(require("../routes/auth"))
     .use(require("../routes/misc"));

  // Server error
  app.use(function(err, req, res, next) {
    res.locals.title = "500 - Internal server error";
    res.statusCode = 500;
    console.log(err);
    res.render('500.jade', {
      message: "Sorry, something went wrong and I cannot recover. If you think this might be a bug in Jingo, please file a detailed report about what you were doing here: https://github.com/claudioc/jingo/issues . Thank you!",
      error: err
    });
  });

  return app;
};
<commit_msg>* Indentation<commit_after>#!/usr/bin/env node

/*
 * Jingo, wiki engine
 * http://github.com/claudioc/jingo
 *
 * Copyright 2014 Claudio Cicali <claudio.cicali@gmail.com>
 * Released under the MIT license
 */

var express        = require("express"),
    path           = require("path"),
    components     = require("./components"),
    wikiStatic     = require("./wikistatic"),
    favicon        = require("serve-favicon"),
    session        = require("express-session"),
    bodyParser     = require("body-parser"),
    expValidator   = require("express-validator"),
    cookieParser   = require("cookie-parser"),
    logger         = require("morgan"),
    program        = require('commander'),
    cookieSession  = require("cookie-session"),
    gravatar       = require("gravatar"),
    passport       = require("passport"),
    methodOverride = require("method-override"),
    flash          = require("express-flash")
;

var app;

module.exports.getInstance = function() {
  if (!app) {
    throw new Error("Cannot get an instance of an unitialized App");
  }
  return app;
};

module.exports.initialize = function(config) {

  app = express();

  app.locals.config = config;

  app.locals.baseUrl = "//" + config.get("server").hostname + ":" + config.get("server").port;

  if (config.get("server").baseUrl == "") {
    app.locals.baseUrl = "//" + config.get("server").hostname + ":" + config.get("server").port;
  } else {
    app.locals.baseUrl = config.get("server").baseUrl;
  }

  // View helpers
  app.use(function (req, res, next) {
    res.locals = {
      get user() {
        return req.user;
      },
      get appTitle() {
        return config.get("application").title;
      },
      get jingoVersion() {
        return program.version();
      },
      get authentication() {
        return config.get("authentication");
      },
      isAnonymous: function () {
        return !req.user;
      },
      canSearch: function () {
        return !!req.user || app.locals.config.get("authorization").anonRead;
      },
      gravatar: function(email) {
        return gravatar;
      }
    };
    next();
  });

  app.locals.coalesce = function(value, def) {
    return typeof value === 'undefined' ? def : value;
  };

  app.locals.pretty = true; // Pretty HTML output from Jade

  app.locals.hasSidebar = components.hasSidebar;
  app.locals.hasFooter = components.hasFooter;
  app.locals.hasCustomStyle = components.hasCustomStyle;
  app.locals.hasCustomScript = components.hasCustomScript;
  app.locals.hasFeature = function(feature) {
    return !!app.locals.config.get("features")[feature];
  };

  if (components.hasCustomStyle()) {
    console.log("Using custom style " + config.get('customizations')['style']);
  }

  if (components.hasCustomScript()) {
    console.log("Using custom script "  + config.get('customizations')['script']);
  }

  app.enable('trust proxy', 'loopback');    // Trust only proxy on loopback
  if (config.get("application").loggingMode) {
    app.use(logger(config.get("application").loggingMode == 1 ? "combined" : "dev", {skip: function() { }}));
  }
  app.use(favicon(path.join(__dirname + "/../", 'public', 'favicon.ico')))
  app.use(bodyParser.urlencoded({extended: true, limit: "500kb"}));
  app.use(methodOverride(function(req, res){
    if (req.body && typeof req.body === 'object' && '_method' in req.body) {
      // look in urlencoded POST bodies and delete it
      var method = req.body._method;
      delete req.body._method;
      return method;
    }
  }));

  app.use(express.static(path.join(__dirname + "/../", 'public')));
  app.use(cookieParser());
  app.use(cookieSession({
    name: "JingoSession",
    keys: ["jingo"],
    cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 }
  }));
  app.use(session({ name: "jingosid",
                    secret: config.get("application").secret,
                    cookie: { httpOnly: true },
                    saveUninitialized: true,
                    resave: true
                  }));
  app.use(flash());
  app.use(expValidator());

  app.set('views', __dirname + '/../views');
  app.set('view engine', 'jade');

  app.use(function (req, res, next) {

    res.locals._style  = components.customStyle();
    res.locals._script = components.customScript();

    if ( /^\/auth\//.test(req.url) ||
         /^\/misc\//.test(req.url) ||
         (/^\/login/.test(req.url) && !config.get('authorization').anonRead)
       ) {
      return next();
    }

    components.sidebarAsync().then(function(content) {
      res.locals._sidebar = content;
      return components.footerAsync();
    }).then(function(content) {
      res.locals._footer = content;
      return next();
    }).catch(function(e) {
      console.log(e);
    });
  });

  app.use(passport.initialize());
  app.use(passport.session());

  app.locals.passport = passport;

  function requireAuthentication(req, res, next) {
    if (!res.locals.user) {
      res.redirect("/login");
    } else {
      next();
    }
  }

  app.all("/pages/*", requireAuthentication);

  if (!app.locals.config.get("authorization").anonRead) {
    app.all("/wiki/*", requireAuthentication);
    app.all("/search", requireAuthentication);
  }

  app.use("/wiki", wikiStatic.configure());

  app.use(require("../routes/wiki"))
     .use(require("../routes/pages"))
     .use(require("../routes/search"))
     .use(require("../routes/auth"))
     .use(require("../routes/misc"));

  // Server error
  app.use(function(err, req, res, next) {
    res.locals.title = "500 - Internal server error";
    res.statusCode = 500;
    console.log(err);
    res.render('500.jade', {
      message: "Sorry, something went wrong and I cannot recover. If you think this might be a bug in Jingo, please file a detailed report about what you were doing here: https://github.com/claudioc/jingo/issues . Thank you!",
      error: err
    });
  });

  return app;
};
<|endoftext|>


<commit_before>#!/usr/node/bin/node
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2014, Joyent, Inc.
 */

var lookupPath = process.env['LOOKUP_FILE'] || '../etc/lookup.json';
var lookup = require(lookupPath); // maps uuid->login
var mantaFileSave = require('manta-compute-bin').mantaFileSave;
var mod_ipaddr = require('ipaddr.js');
var mod_bunyan = require('bunyan');
var mod_carrier = require('carrier');
var mod_fs = require('fs');
var mod_manta = require('manta');
var mod_screen = require('screener');
var mod_libmanta = require('libmanta');

var files = {}; // keeps track of all the files we create
var waitingForDrain = {};
var ERROR = false;
var tmpdir = '/var/tmp';
var DELIVER_UNAPPROVED_REPORTS =
        process.env['DELIVER_UNAPPROVED_REPORTS'] === 'true';
var DROP_POSEIDON_REQUESTS = process.env['DROP_POSEIDON_REQUESTS'] === 'true';
var MALFORMED_LIMIT = process.env['MALFORMED_LIMIT'] || '0';

var LOG = require('bunyan').createLogger({
        name: 'deliver-access.js',
        stream: process.stderr,
        level: process.env['LOG_LEVEL'] || 'info'
});

/*
 * Allow all headers, then auth and x-forwarded-for headers will be removed
 * after applying this whitelist. The IP in the x-forwarded-for header will
 * be used for the top-level remoteAddress IP.
 */
var whitelist = {
        'billable_operation': 'string',
        'req': {
                'method': 'string',
                'url': 'string', // renamed 'request-uri' see RFC 2616
                'headers': true, // XXX see above
                'httpVersion': 'string',
                'caller': {
                        'login': 'string'
                }
        },
        'res': {
                'statusCode': 'number',
                'headers': true
        }
};

function shouldProcess(record) {
        return (record.audit &&
                record.req.url !== '/ping' &&
                typeof (record.req.owner) !== 'undefined' &&
                (!record.req.caller ||
                        !DROP_POSEIDON_REQUESTS ||
                        record.req.caller.login !== 'poseidon'));
}

function sanitize(record) {
        var output = mod_screen.screen(record, whitelist);
        if (output.req && output.req.headers) {
                var ip = output.req.headers['x-forwarded-for'] || '169.254.0.1';
                // MANTA-1918 if first ip is empty, use 'unknown'
                ip = ip.split(',')[0].trim() || 'unknown';

                // MANTA-1886 check for 'unknown'
                if (ip === 'unknown') {
                        output['remoteAddress'] = 'unknown';
                } else {
                        var ipaddr = mod_ipaddr.parse(ip);
                        if (ipaddr.kind() === 'ipv4') {
                                output['remoteAddress'] =
                                        ipaddr.toIPv4MappedAddress().toString();
                        } else {
                                output['remoteAddress'] = ipaddr.toString();
                        }
                }
                output.req['request-uri'] = output.req['url'];
                delete output.req.headers['x-forwarded-for'];
                delete output.req['url'];
                delete output.req.headers['authorization'];
        }
        LOG.debug({record: record, output: output}, 'record sanitized');
        return (output);
}

function write(opts, cb) {
        LOG.debug(opts, 'write start');
        var owner = opts.owner;
        var record = opts.record;
        var path = tmpdir + '/' + owner;
        var output = JSON.stringify(record) + '\n';
        var flushed;

        if (!files[owner]) {
                process.stdin.pause();
                files[owner] = mod_fs.createWriteStream(path);

                files[owner].on('drain', function (o) {
                        delete waitingForDrain[o];
                        if (Object.keys(waitingForDrain).length === 0) {
                                process.stdin.resume();
                        }
                }.bind(files[owner], owner));

                files[owner].once('open', function (o) {
                        var initialFlush = this.write(output, cb);
                        if (!initialFlush) {
                                waitingForDrain[o] = true;
                        } else {
                                process.stdin.resume();
                        }
                }.bind(files[owner], owner));
        } else {
                flushed = files[owner].write(output, cb);
                if (!flushed) {
                        waitingForDrain[owner] = true;
                        process.stdin.pause();
                }
        }
}

function saveAll(cb) {
        function save(owner, callback) {
                LOG.debug(owner, 'save start');
                var login = lookup[owner].login;
                var key = '/' + login + process.env['ACCESS_DEST'];
                var linkPath = '/' + login + process.env['ACCESS_LINK'];
                var headers = {
                        'content-type': process.env['HEADER_CONTENT_TYPE']
                };
                var filename = tmpdir + '/' + owner;

                if (!login) {
                        callback(new Error('No login found for UUID ' + owner));
                        return;
                }

                mantaFileSave({
                        client: client,
                        filename: filename,
                        key: key,
                        headers: headers,
                        log: LOG,
                        iostream: 'stderr'
                }, function saveCB(err) {
                        if (err) {
                                callback(err);
                                return;
                        }

                        LOG.info({
                                filename: filename,
                                key: key,
                                headers: headers
                        }, 'upload successful');

                        if (!process.env['ACCESS_LINK']) {
                                callback();
                                return;
                        }

                        LOG.debug({
                                key: key,
                                linkPath: linkPath
                        }, 'creating link');

                        client.ln(key, linkPath, function (err2) {
                                if (err2) {
                                        LOG.warn(err2, 'error ln ' + linkPath);
                                        return;
                                }

                                LOG.info({
                                        key: key,
                                        linkPath: linkPath
                                }, 'link created');

                                callback();
                                return;
                        });
                });
        }

        var client = mod_manta.createClient({
                sign: null,
                url: process.env['MANTA_URL']
        });

        var uploadQueue = mod_libmanta.createQueue({
                worker: save,
                limit: 25
        });

        uploadQueue.on('error', function (err) {
                LOG.error(err, 'error saving');
                ERROR = true;
        });

        uploadQueue.once('end', function () {
                client.close();
                cb();
        });

        LOG.info(Object.keys(files), 'files to upload');
        Object.keys(files).forEach(function (k) {
                uploadQueue.push(k);
        });
        uploadQueue.close();
}

function main() {
        var carry = mod_carrier.carry(process.openStdin());
        var lineCount = 0;
        var malformed = 0;

        var writeQueue = mod_libmanta.createQueue({
                worker: write,
                limit: 15
        });

        writeQueue.on('error', function (err) {
                LOG.error(err, 'write error');
        });

        writeQueue.once('end', function () {
                Object.keys(files).forEach(function (owner) {
                        files[owner].end();
                });
                saveAll(function (err) {
                        if (err) {
                                LOG.error(err, 'Error saving access logs');
                                ERROR = true;
                        }
                });
        });

        function onLine(line) {
                lineCount++;
                var record;
                //console.log(line); // re-emit each line for aggregation

                // since bunyan logs may contain lines such as
                // [ Nov 28 21:35:27 Enabled. ]
                // we need to ignore them
                if (line[0] != '{') {
                        return;
                }

                try {
                        record = JSON.parse(line);
                } catch (e) {
                        malformed++;
                        LOG.error(e, line, 'Error on line ' + lineCount);
                        return;
                }

                if (!shouldProcess(record)) {
                        return;
                }

                var login = lookup[record.req.owner];

                if (!login) {
                        LOG.error(record,
                                'No login found for UUID ' + record.req.owner);
                        ERROR = true;
                        return;
                }

                if (!DELIVER_UNAPPROVED_REPORTS && !login.approved) {
                        LOG.warn(record, record.req.owner +
                                ' not approved for provisioning. Skipping...');
                        return;
                }

                var output;
                try {
                        output = sanitize(record);
                } catch (e) {
                        LOG.error(e, 'Error sanitizing record');
                        ERROR = true;
                        return;
                }

                writeQueue.push({
                        owner: record.req.owner,
                        record: output
                });
        }

        carry.once('end', function onEnd() {
                var len = MALFORMED_LIMIT.length;
                var threshold;

                if (MALFORMED_LIMIT[len - 1] === '%') {
                        var pct = +(MALFORMED_LIMIT.substr(0, len-1));
                        threshold = pct * lineCount;
                } else {
                        threshold = +MALFORMED_LIMIT;
                }

                if (isNaN(threshold)) {
                        LOG.error('MALFORMED_LIMIT not a number');
                        ERROR = true;
                        return;
                }

                if (malformed > threshold) {
                        LOG.fatal('Too many malformed lines');
                        ERROR = true;
                        return;
                }
                writeQueue.close();
        });

        carry.on('line', onLine);
}

if (require.main === module) {
        process.on('exit', function onExit() {
                process.exit(ERROR);
        });

        main();
}
<commit_msg>MANTA-2756 metering job failed on bogus IP in request header<commit_after>#!/usr/node/bin/node
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/*
 * Copyright (c) 2014, Joyent, Inc.
 */

var lookupPath = process.env['LOOKUP_FILE'] || '../etc/lookup.json';
var lookup = require(lookupPath); // maps uuid->login
var mantaFileSave = require('manta-compute-bin').mantaFileSave;
var mod_ipaddr = require('ipaddr.js');
var mod_bunyan = require('bunyan');
var mod_carrier = require('carrier');
var mod_fs = require('fs');
var mod_manta = require('manta');
var mod_screen = require('screener');
var mod_libmanta = require('libmanta');

var files = {}; // keeps track of all the files we create
var waitingForDrain = {};
var ERROR = false;
var tmpdir = '/var/tmp';
var DELIVER_UNAPPROVED_REPORTS =
        process.env['DELIVER_UNAPPROVED_REPORTS'] === 'true';
var DROP_POSEIDON_REQUESTS = process.env['DROP_POSEIDON_REQUESTS'] === 'true';
var MALFORMED_LIMIT = process.env['MALFORMED_LIMIT'] || '0';
var ERROR_RE_BAD_IP = /the address has neither IPv6 nor IPv4 format/;

var LOG = require('bunyan').createLogger({
        name: 'deliver-access.js',
        stream: process.stderr,
        level: process.env['LOG_LEVEL'] || 'info'
});

/*
 * Allow all headers, then auth and x-forwarded-for headers will be removed
 * after applying this whitelist. The IP in the x-forwarded-for header will
 * be used for the top-level remoteAddress IP.
 */
var whitelist = {
        'billable_operation': 'string',
        'req': {
                'method': 'string',
                'url': 'string', // renamed 'request-uri' see RFC 2616
                'headers': true, // XXX see above
                'httpVersion': 'string',
                'caller': {
                        'login': 'string'
                }
        },
        'res': {
                'statusCode': 'number',
                'headers': true
        }
};

function shouldProcess(record) {
        return (record.audit &&
                record.req.url !== '/ping' &&
                typeof (record.req.owner) !== 'undefined' &&
                (!record.req.caller ||
                        !DROP_POSEIDON_REQUESTS ||
                        record.req.caller.login !== 'poseidon'));
}

function sanitize(record) {
        var output = mod_screen.screen(record, whitelist);
        if (output.req && output.req.headers) {
                var ip = output.req.headers['x-forwarded-for'] || '169.254.0.1';
                var ip_parsed = null;

                // MANTA-1918 if first ip is empty, use 'unknown'
                ip = ip.split(',')[0].trim() || 'unknown';

                // MANTA-1886 check for 'unknown'
                if (ip !== 'unknown') {
                        try {
                                ip_parsed = mod_ipaddr.parse(ip);
                        } catch (ex) {
                                if (!ERROR_RE_BAD_IP.test(ex.message))
                                        throw (ex);
                        }
                }

                if (ip_parsed === null) {
                        output['remoteAddress'] = 'unknown';
                } else {
                        if (ip_parsed.kind() === 'ipv4') {
                                output['remoteAddress'] =
                                    ip_parsed.toIPv4MappedAddress().toString();
                        } else {
                                output['remoteAddress'] = ip_parsed.toString();
                        }
                }

                output.req['request-uri'] = output.req['url'];
                delete output.req.headers['x-forwarded-for'];
                delete output.req['url'];
                delete output.req.headers['authorization'];
        }
        LOG.debug({record: record, output: output}, 'record sanitized');
        return (output);
}

function write(opts, cb) {
        LOG.debug(opts, 'write start');
        var owner = opts.owner;
        var record = opts.record;
        var path = tmpdir + '/' + owner;
        var output = JSON.stringify(record) + '\n';
        var flushed;

        if (!files[owner]) {
                process.stdin.pause();
                files[owner] = mod_fs.createWriteStream(path);

                files[owner].on('drain', function (o) {
                        delete waitingForDrain[o];
                        if (Object.keys(waitingForDrain).length === 0) {
                                process.stdin.resume();
                        }
                }.bind(files[owner], owner));

                files[owner].once('open', function (o) {
                        var initialFlush = this.write(output, cb);
                        if (!initialFlush) {
                                waitingForDrain[o] = true;
                        } else {
                                process.stdin.resume();
                        }
                }.bind(files[owner], owner));
        } else {
                flushed = files[owner].write(output, cb);
                if (!flushed) {
                        waitingForDrain[owner] = true;
                        process.stdin.pause();
                }
        }
}

function saveAll(cb) {
        function save(owner, callback) {
                LOG.debug(owner, 'save start');
                var login = lookup[owner].login;
                var key = '/' + login + process.env['ACCESS_DEST'];
                var linkPath = '/' + login + process.env['ACCESS_LINK'];
                var headers = {
                        'content-type': process.env['HEADER_CONTENT_TYPE']
                };
                var filename = tmpdir + '/' + owner;

                if (!login) {
                        callback(new Error('No login found for UUID ' + owner));
                        return;
                }

                mantaFileSave({
                        client: client,
                        filename: filename,
                        key: key,
                        headers: headers,
                        log: LOG,
                        iostream: 'stderr'
                }, function saveCB(err) {
                        if (err) {
                                callback(err);
                                return;
                        }

                        LOG.info({
                                filename: filename,
                                key: key,
                                headers: headers
                        }, 'upload successful');

                        if (!process.env['ACCESS_LINK']) {
                                callback();
                                return;
                        }

                        LOG.debug({
                                key: key,
                                linkPath: linkPath
                        }, 'creating link');

                        client.ln(key, linkPath, function (err2) {
                                if (err2) {
                                        LOG.warn(err2, 'error ln ' + linkPath);
                                        return;
                                }

                                LOG.info({
                                        key: key,
                                        linkPath: linkPath
                                }, 'link created');

                                callback();
                                return;
                        });
                });
        }

        var client = mod_manta.createClient({
                sign: null,
                url: process.env['MANTA_URL']
        });

        var uploadQueue = mod_libmanta.createQueue({
                worker: save,
                limit: 25
        });

        uploadQueue.on('error', function (err) {
                LOG.error(err, 'error saving');
                ERROR = true;
        });

        uploadQueue.once('end', function () {
                client.close();
                cb();
        });

        LOG.info(Object.keys(files), 'files to upload');
        Object.keys(files).forEach(function (k) {
                uploadQueue.push(k);
        });
        uploadQueue.close();
}

function main() {
        var carry = mod_carrier.carry(process.openStdin());
        var lineCount = 0;
        var malformed = 0;

        var writeQueue = mod_libmanta.createQueue({
                worker: write,
                limit: 15
        });

        writeQueue.on('error', function (err) {
                LOG.error(err, 'write error');
        });

        writeQueue.once('end', function () {
                Object.keys(files).forEach(function (owner) {
                        files[owner].end();
                });
                saveAll(function (err) {
                        if (err) {
                                LOG.error(err, 'Error saving access logs');
                                ERROR = true;
                        }
                });
        });

        function onLine(line) {
                lineCount++;
                var record;
                //console.log(line); // re-emit each line for aggregation

                // since bunyan logs may contain lines such as
                // [ Nov 28 21:35:27 Enabled. ]
                // we need to ignore them
                if (line[0] != '{') {
                        return;
                }

                try {
                        record = JSON.parse(line);
                } catch (e) {
                        malformed++;
                        LOG.error(e, line, 'Error on line ' + lineCount);
                        return;
                }

                if (!shouldProcess(record)) {
                        return;
                }

                var login = lookup[record.req.owner];

                if (!login) {
                        LOG.error(record,
                                'No login found for UUID ' + record.req.owner);
                        ERROR = true;
                        return;
                }

                if (!DELIVER_UNAPPROVED_REPORTS && !login.approved) {
                        LOG.warn(record, record.req.owner +
                                ' not approved for provisioning. Skipping...');
                        return;
                }

                var output;
                try {
                        output = sanitize(record);
                } catch (e) {
                        LOG.error(e, 'Error sanitizing record');
                        ERROR = true;
                        return;
                }

                writeQueue.push({
                        owner: record.req.owner,
                        record: output
                });
        }

        carry.once('end', function onEnd() {
                var len = MALFORMED_LIMIT.length;
                var threshold;

                if (MALFORMED_LIMIT[len - 1] === '%') {
                        var pct = +(MALFORMED_LIMIT.substr(0, len-1));
                        threshold = pct * lineCount;
                } else {
                        threshold = +MALFORMED_LIMIT;
                }

                if (isNaN(threshold)) {
                        LOG.error('MALFORMED_LIMIT not a number');
                        ERROR = true;
                        return;
                }

                if (malformed > threshold) {
                        LOG.fatal('Too many malformed lines');
                        ERROR = true;
                        return;
                }
                writeQueue.close();
        });

        carry.on('line', onLine);
}

if (require.main === module) {
        process.on('exit', function onExit() {
                process.exit(ERROR);
        });

        main();
}
<|endoftext|>


<commit_before>var snmp = require('net-snmp');

/**
 * Create the SNMP session
 *
 * @param   object  options
 */
function ups(options) {
  this.options = options;

  if (typeof options.host === "undefined") {
    throw "Please define a host";
  }

  this.session = snmp.createSession(this.options.host, "private", {
    version: snmp.Version1,
    timeout: 1000
  });

  // beginning of all oid's
  this.oid = "1.3.6.1.4.1.318";
}

module.exports = ups;

/**
 * Get the UPS model name (e.g. 'APC Smart-UPS 600')
 *
 * @param   function  callback
 */
ups.prototype.getModel = function(callback) {
  // Using PowerNet-MIB::upsBasicIdentModel.0
  var oid = this.oid + '.1.1.1.1.1.1.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get model number'));
      return;
    }

    callback(null, varbinds[0].value.toString());
  });
}

/**
 * Get the current internal UPS temperature expressed in Celsius.
 *
 * @param   function  callback
 */
ups.prototype.getTemperature = function(callback) {
  // Using PowerNet-MIB::upsAdvBatteryTemperature.0
  var oid = this.oid + '.1.1.1.2.2.2.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get temperature'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the current utility line voltage in VAC
 *
 * @param   function  callback
 */
ups.prototype.getInputVoltage = function(callback) {
  // Using PowerNet-MIB::upsAdvInputLineVoltage.0
  var oid = this.oid + '.1.1.1.3.2.1.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get input voltage'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the current input frequency to the UPS system in Hz.
 *
 * @param   function  callback
 */
ups.prototype.getInputFrequency = function(callback) {
  // Using PowerNet-MIB::upsAdvInputFrequency.0
  var oid = this.oid + '.1.1.1.3.2.4.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get input frequency'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the output voltage of the UPS system in VAC.
 *
 * @param   function  callback
 */
ups.prototype.getOutputVoltage = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputVoltage.0
  var oid = this.oid + '.1.1.1.4.2.1.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get output voltage'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the current output frequency to the UPS system in Hz.
 *
 * @param   function  callback
 */
ups.prototype.getOutputFrequency = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputFrequency.0
  var oid = this.oid + '.1.1.1.4.2.2.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get output frequency'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the current UPS load expressed in percent of rated capacity.
 *
 * @param   function  callback
 */
ups.prototype.getOutputLoadPercentage = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputLoad.0
  var oid = this.oid + '.1.1.1.4.2.3.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get current output load as a percentage'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the current in amperes drawn by the load on the UPS
 *
 * @param   function  callback
 */
ups.prototype.getOutputLoad = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputCurrent.0
  var oid = this.oid + '.1.1.1.4.2.4.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get current load in amps'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}

/**
 * Get the remaining battery capacity expressed in percent of full capacity.
 *
 * @param   function  callback
 */
ups.prototype.getBatteryCapacity = function(callback) {
  // Using PowerNet-MIB::upsAdvBatteryCapacity.0.0
  var oid = this.oid + '.1.1.1.2.2.1.0';

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      callback(new Error('Unable to get current battery capacity'));
      return;
    }

    callback(null, varbinds[0].value);
  });
}<commit_msg>Refactor to use getbyoid #3<commit_after>var snmp = require('net-snmp');

/**
 * Create the SNMP session
 *
 * @param   object  options
 */
function ups(options) {
  this.options = options;

  if (typeof options.host === "undefined") {
    throw "Please define a host";
  }

  this.session = snmp.createSession(this.options.host, "private", {
    version: snmp.Version1,
    timeout: 1000
  });

  // beginning of all oid's
  this.oid = "1.3.6.1.4.1.318.";
}

module.exports = ups;

/**
 * Get single parameter by oid
 *
 * @param   string    oid
 * @param   function  callback
 * @param   string    errorStr
 */
ups.prototype.getByOid = function(oid, callback, errStr) {
  oid = this.oid + oid;

  this.session.get([oid], function(err, varbinds) {
    if (err) {
      callback(err);
      return;
    }

    if (typeof varbinds[0] === "undefined") {
      if (typeof errStr === "undefined") {
        errStr = new Error('Invalid response from SNMP');
      }

      callback(errStr);
      return;
    }

    callback(null, varbinds[0].value.toString());
  });
}

/**
 * Get the UPS model name (e.g. 'APC Smart-UPS 600')
 *
 * @param   function  callback
 */
ups.prototype.getModel = function(callback) {
  // Using PowerNet-MIB::upsBasicIdentModel.0
  this.getByOid('1.1.1.1.1.1.0', callback, 'Unable to get model number');
}

/**
 * Get the current internal UPS temperature expressed in Celsius.
 *
 * @param   function  callback
 */
ups.prototype.getTemperature = function(callback) {
  // Using PowerNet-MIB::upsAdvBatteryTemperature.0
  this.getByOid('1.1.1.2.2.2.0', callback, 'Unable to get temperature');
}

/**
 * Get the current utility line voltage in VAC
 *
 * @param   function  callback
 */
ups.prototype.getInputVoltage = function(callback) {
  // Using PowerNet-MIB::upsAdvInputLineVoltage.0
  this.getByOid('1.1.1.3.2.1.0', callback, 'Unable to get input voltage');
}

/**
 * Get the current input frequency to the UPS system in Hz.
 *
 * @param   function  callback
 */
ups.prototype.getInputFrequency = function(callback) {
  // Using PowerNet-MIB::upsAdvInputFrequency.0
  this.getByOid('1.1.1.3.2.4.0', callback, 'Unable to get input frequency');
}

/**
 * Get the output voltage of the UPS system in VAC.
 *
 * @param   function  callback
 */
ups.prototype.getOutputVoltage = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputVoltage.0
  this.getByOid('1.1.1.4.2.1.0', callback, 'Unable to get output voltage');
}

/**
 * Get the current output frequency to the UPS system in Hz.
 *
 * @param   function  callback
 */
ups.prototype.getOutputFrequency = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputFrequency.0
  this.getByOid('1.1.1.4.2.2.0', callback, 'Unable to get output frequency');
}

/**
 * Get the current UPS load expressed in percent of rated capacity.
 *
 * @param   function  callback
 */
ups.prototype.getOutputLoadPercentage = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputLoad.0
  this.getByOid('1.1.1.4.2.3.0', callback, 'Unable to get current output load as a percentage');
}

/**
 * Get the current in amperes drawn by the load on the UPS
 *
 * @param   function  callback
 */
ups.prototype.getOutputLoad = function(callback) {
  // Using PowerNet-MIB::upsAdvOutputCurrent.0
  this.getByOid('1.1.1.4.2.4.0', callback, 'Unable to get current load in amps');
}

/**
 * Get the remaining battery capacity expressed in percent of full capacity.
 *
 * @param   function  callback
 */
ups.prototype.getBatteryCapacity = function(callback) {
  // Using PowerNet-MIB::upsAdvBatteryCapacity.0.0
  this.getByOid('1.1.1.2.2.1.0', callback, 'Unable to get current battery capacity');
}<|endoftext|>


<commit_before>'use strict';

function formatPretty(num) {
  let M = 1000000, K = 1000;

  if (num >= M) {
    return (num / M).toFixed(num > (M * 10) ? 1 : 2).replace(/\.0$/, '') + 'M';
  }

  if (num >= (K * 10)) {
    return (num / K).toFixed(num > (K*100) ? 0 : 1).replace(/\.0$/, '') + 'K';
  }

  return formatWithComma(num);
}

function formatWithComma(nStr) {
	nStr += '';

  if(nStr.length < 4 ) {
    return nStr;
  }

  var	x = nStr.split('.');
	var x1 = x[0];
	var x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function formatDuration(seconds) {
  seconds = Math.round(seconds);
  var date = new Date(null);
  date.setSeconds(seconds); // specify value for SECONDS here
  return date.toISOString().substr(14, 5);
}

function formatPercentage(p) {
   return Math.round(p*100) + "%";
}

export {
  formatPretty,
  formatWithComma,
  formatDuration,
  formatPercentage
}
<commit_msg>improve number format perf<commit_after>'use strict';

const M = 1000000
const K = 1000
const rx = new RegExp('\\.0$');
const commaRx = new RegExp('(\\d+)(\\d{3})');

function formatPretty(num) {
  let decimals = 0;

  if (num >= M) {
    num /= M
    decimals = 3 - ((Math.round(num) + "").length) || 0;
    return num.toFixed(decimals > -1 ? decimals : 0).replace(rx, '') + 'M';
  }

  if (num >= (K * 10)) {
    num /= K
    decimals = 3 - ((Math.round(num) + "").length) || 0;
    return num.toFixed(decimals).replace(rx, '') + 'K';
  }

  return formatWithComma(num);
}

function formatWithComma(nStr) {
	nStr += '';

  if(nStr.length < 4 ) {
    return nStr;
  }

  var	x = nStr.split('.');
	var x1 = x[0];
	var x2 = x.length > 1 ? '.' + x[1] : '';
	while (commaRx.test(x1)) {
		x1 = x1.replace(commaRx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function formatDuration(seconds) {
  seconds = Math.round(seconds);
  var date = new Date(null);
  date.setSeconds(seconds); // specify value for SECONDS here
  return date.toISOString().substr(14, 5);
}

function formatPercentage(p) {
   return Math.round(p*100) + "%";
}

export {
  formatPretty,
  formatWithComma,
  formatDuration,
  formatPercentage
}
<|endoftext|>