<commit_before>var util = require('util');

function _has(obj, propName) {
    return Object.prototype.hasOwnProperty.call(obj, propName);
}

function _copyPlainObject(src) {
    var o = {};
    Object.keys(src).forEach(function(key) {
        o[key] = src[key];
    });
    return o;
}

/**
 * @constructor
 * @param {Number} [code=Terror.CODES.UNKNOWN_ERROR]
 * @param {String} [message]
 * @returns {Terror}
 * @example
 *      ```
 *      var MyError = Terror.create('MyError', {
 *          MY_FAULT: "It\'s my own fault, because %reason%"
 *      });
 *
 *      try {
 *          // dangerous code here
 *      } catch(err) {
 *          MyError.createError(MyError.CODES.MY_FAULT, err)
 *              .bind({ reason: 'something strange happens!' })
 *              .log();
 *      }
 *
 *      // try to use Terror#ensureError if catched error can be Terror successor or not
 *
 *      try {
 *          // dangerous code here
 *      } catch(err) {
 *          MyError.ensureError(err, MyError.CODES.MY_FAULT)
 *              .bind({ reason: 'i was sad when write code above' })
 *              .log();
 *      }
 *
 *      // or simply log and throw Terror
 *
 *      throw MyError.createError(MyError.CODES.MY_FAULT, { reason: 'i was too stupid!' })
 *          .log('warn');
 *      ```
 */
function Terror(code, message) {
    Error.apply(this);

    this.message = '$$MESSAGE$$';
    Error.captureStackTrace(this, this.constructor);
    this._stackTemplate = this.stack;

    this.code = typeof code === 'undefined' || code === null ? Terror.CODES.UNKNOWN_ERROR : code;
    this.setMessage(message || this.constructor.MESSAGES[this.code]);
    this.data = {};
}
util.inherits(Terror, Error);

Terror.prototype.name = 'Terror';

/**
 * @param {String} name Error class name
 * @param {Object} [codes] hash { ERROR_CODE: 'error message', … }
 */
Terror.create = function(name, codes) {
    var Super = this,
        Inheritor = function(code, message) {
            Super.call(this, code, message);
        };
    util.inherits(Inheritor, Super);

    Inheritor.prototype.name = name;

    // link contructors methods
    Inheritor.create = Super.create;
    Inheritor.extendCodes = Super.extendCodes;
    Inheritor.setLogger = Super.setLogger;
    Inheritor.createError = Super.createError;
    Inheritor.ensureError = Super.ensureError;
    // copy static fields
    Inheritor.CODES = _copyPlainObject(Super.CODES);
    Inheritor.MESSAGES = _copyPlainObject(Super.MESSAGES);
    Inheritor.DEFAULT_ERROR_LEVEL = Super.DEFAULT_ERROR_LEVEL;

    if (typeof codes === 'object' && codes !== null) {
        Inheritor.extendCodes(codes);
    }

    return Inheritor;
};

/**
 * Extends existing CODE and MESSAGE hashes.
 * @param {Object} codes { CODE_NAME: 'error message', … }
 * @returns {Function} constructor
 * @throws TerrorError if collisions detected.
 */
Terror.extendCodes = function(codes) {
    var ctor = this;

    Object.keys(codes).forEach(function(code) {
        if (_has(ctor.CODES, code)) {
            throw new Error('Terror codes collision detected in the ' +
                ctor.prototype.name + '.extendCodes call for code "' + code + '"');
        }

        ctor.CODES[code] = code;
        ctor.MESSAGES[code] = codes[code];
    });

    return this;
};

/**
 * Default logger writes error message to console using logMultilineError
 * @param {String} message
 * @param {String} [level=DEBUG]
 */
Terror.prototype.logger = function(message, level) {
    this.logMultilineError(message, level);
};

Terror.DEFAULT_ERROR_LEVEL = 'ERROR';

function _defaultLog(msg) {
    console.log(msg);
}

/**
 * Default multiine error formatiing for simple text loggers,
 * such as console.log or any one, which write message as line in the text file.
 * @param {String} message
 * @param {String} level
 * @param {Function} [log=console.log] (String formattedMessageRow)
 */
Terror.prototype.logMultilineError = function(message, level, log) {
    var _level = (level || this.constructor.DEFAULT_ERROR_LEVEL).toUpperCase(),
        _arrows = '\n' + _level.replace(/./ig, '>') + ' ',
        _log = log;

    if (typeof _log !== 'function') {
        _log = _defaultLog;
    }

    _log(_level + ' ' + message.replace(/\n/g, _arrows));
};

/**
 * @param {Function} logger (String message, String errorLevel)
 * @returns {Function} constructor
 */
Terror.setLogger = function(logger) {
    this.prototype.logger = logger;

    return this;
};

/**
 * @param {*} [level] – error level, any value allowed by logger
 * @returns {Terror} self
 */
Terror.prototype.log = function(level) {
    if (this._isLogged || ! this.logger) {
        return this;
    }

    this.logger(this.code + ' ' + this.stack, level);
    this._isLogged = true;

    return this;
};

/**
 * @param {Object} data
 * @returns {Terror} self
 */
Terror.prototype.bind = function(data) {
    if (this.message.indexOf('%') > -1) {
        this.setMessage(this.message.replace(/%([^%\s]+)%/g, function(match, name) {
            return _has(data, name) ? data[name] : match;
        }));
    }

    Object.keys(data)
        .forEach(function(propName) {
            this.data[propName] = data[propName];
        }, this);

    return this;
};

Terror.CODES = {
    UNKNOWN_ERROR: 'UNKNOWN_ERROR'
};

Terror.MESSAGES = {
    UNKNOWN_ERROR: 'Unknown error'
};

Terror.prototype.setMessage = function(message) {
    this.message = message;
    // patch stacktrace
    this.stack = this._stackTemplate.replace('$$MESSAGE$$', message);
    return this;
};

/**
 * @param {Number} code
 * @param {String|Error|Object} [message] error message, Error or key-value hash for binding
 * @returns {Terror} new Terror instance
 */
Terror.createError = function(code, message) {
    var Constructor = this,
        error = new Constructor(code),
        _msg = error.message;

    // patch stacktrace to avoid meaningless entry of createError call
    error.message = '$$MESSAGE$$';
    Error.captureStackTrace(error, this.createError);
    error._stackTemplate = error.stack;
    error.setMessage(_msg);

    if (message instanceof Error || typeof message === 'string') {
        error.originalError = message;
        error.setMessage(error.message + ' (' + message.toString() + ')');
    } else if (typeof message === 'object' && message !== null) {
        error.bind(message);
    }

    return error;
};

/**
 * @param {Error|Terror} error
 * @param {Number} [code]
 * @returns {Terror}
 */
Terror.ensureError = function(error, code) {
    if ( ! (error instanceof this)) {
        if (typeof code !== 'string') {
            code = this.CODES.UNKNOWN_ERROR;
        }
        error = this.createError(code, error);
    }

    return error;
};

module.exports = Terror;
<commit_msg>remove redundant "i" flag for regexp<commit_after>var util = require('util');

function _has(obj, propName) {
    return Object.prototype.hasOwnProperty.call(obj, propName);
}

function _copyPlainObject(src) {
    var o = {};
    Object.keys(src).forEach(function(key) {
        o[key] = src[key];
    });
    return o;
}

/**
 * @constructor
 * @param {Number} [code=Terror.CODES.UNKNOWN_ERROR]
 * @param {String} [message]
 * @returns {Terror}
 * @example
 *      ```
 *      var MyError = Terror.create('MyError', {
 *          MY_FAULT: "It\'s my own fault, because %reason%"
 *      });
 *
 *      try {
 *          // dangerous code here
 *      } catch(err) {
 *          MyError.createError(MyError.CODES.MY_FAULT, err)
 *              .bind({ reason: 'something strange happens!' })
 *              .log();
 *      }
 *
 *      // try to use Terror#ensureError if catched error can be Terror successor or not
 *
 *      try {
 *          // dangerous code here
 *      } catch(err) {
 *          MyError.ensureError(err, MyError.CODES.MY_FAULT)
 *              .bind({ reason: 'i was sad when write code above' })
 *              .log();
 *      }
 *
 *      // or simply log and throw Terror
 *
 *      throw MyError.createError(MyError.CODES.MY_FAULT, { reason: 'i was too stupid!' })
 *          .log('warn');
 *      ```
 */
function Terror(code, message) {
    Error.apply(this);

    this.message = '$$MESSAGE$$';
    Error.captureStackTrace(this, this.constructor);
    this._stackTemplate = this.stack;

    this.code = typeof code === 'undefined' || code === null ? Terror.CODES.UNKNOWN_ERROR : code;
    this.setMessage(message || this.constructor.MESSAGES[this.code]);
    this.data = {};
}
util.inherits(Terror, Error);

Terror.prototype.name = 'Terror';

/**
 * @param {String} name Error class name
 * @param {Object} [codes] hash { ERROR_CODE: 'error message', … }
 */
Terror.create = function(name, codes) {
    var Super = this,
        Inheritor = function(code, message) {
            Super.call(this, code, message);
        };
    util.inherits(Inheritor, Super);

    Inheritor.prototype.name = name;

    // link contructors methods
    Inheritor.create = Super.create;
    Inheritor.extendCodes = Super.extendCodes;
    Inheritor.setLogger = Super.setLogger;
    Inheritor.createError = Super.createError;
    Inheritor.ensureError = Super.ensureError;
    // copy static fields
    Inheritor.CODES = _copyPlainObject(Super.CODES);
    Inheritor.MESSAGES = _copyPlainObject(Super.MESSAGES);
    Inheritor.DEFAULT_ERROR_LEVEL = Super.DEFAULT_ERROR_LEVEL;

    if (typeof codes === 'object' && codes !== null) {
        Inheritor.extendCodes(codes);
    }

    return Inheritor;
};

/**
 * Extends existing CODE and MESSAGE hashes.
 * @param {Object} codes { CODE_NAME: 'error message', … }
 * @returns {Function} constructor
 * @throws TerrorError if collisions detected.
 */
Terror.extendCodes = function(codes) {
    var ctor = this;

    Object.keys(codes).forEach(function(code) {
        if (_has(ctor.CODES, code)) {
            throw new Error('Terror codes collision detected in the ' +
                ctor.prototype.name + '.extendCodes call for code "' + code + '"');
        }

        ctor.CODES[code] = code;
        ctor.MESSAGES[code] = codes[code];
    });

    return this;
};

/**
 * Default logger writes error message to console using logMultilineError
 * @param {String} message
 * @param {String} [level=DEBUG]
 */
Terror.prototype.logger = function(message, level) {
    this.logMultilineError(message, level);
};

Terror.DEFAULT_ERROR_LEVEL = 'ERROR';

function _defaultLog(msg) {
    console.log(msg);
}

/**
 * Default multiine error formatiing for simple text loggers,
 * such as console.log or any one, which write message as line in the text file.
 * @param {String} message
 * @param {String} level
 * @param {Function} [log=console.log] (String formattedMessageRow)
 */
Terror.prototype.logMultilineError = function(message, level, log) {
    var _level = (level || this.constructor.DEFAULT_ERROR_LEVEL).toUpperCase(),
        _arrows = '\n' + _level.replace(/./g, '>') + ' ',
        _log = log;

    if (typeof _log !== 'function') {
        _log = _defaultLog;
    }

    _log(_level + ' ' + message.replace(/\n/g, _arrows));
};

/**
 * @param {Function} logger (String message, String errorLevel)
 * @returns {Function} constructor
 */
Terror.setLogger = function(logger) {
    this.prototype.logger = logger;

    return this;
};

/**
 * @param {*} [level] – error level, any value allowed by logger
 * @returns {Terror} self
 */
Terror.prototype.log = function(level) {
    if (this._isLogged || ! this.logger) {
        return this;
    }

    this.logger(this.code + ' ' + this.stack, level);
    this._isLogged = true;

    return this;
};

/**
 * @param {Object} data
 * @returns {Terror} self
 */
Terror.prototype.bind = function(data) {
    if (this.message.indexOf('%') > -1) {
        this.setMessage(this.message.replace(/%([^%\s]+)%/g, function(match, name) {
            return _has(data, name) ? data[name] : match;
        }));
    }

    Object.keys(data)
        .forEach(function(propName) {
            this.data[propName] = data[propName];
        }, this);

    return this;
};

Terror.CODES = {
    UNKNOWN_ERROR: 'UNKNOWN_ERROR'
};

Terror.MESSAGES = {
    UNKNOWN_ERROR: 'Unknown error'
};

Terror.prototype.setMessage = function(message) {
    this.message = message;
    // patch stacktrace
    this.stack = this._stackTemplate.replace('$$MESSAGE$$', message);
    return this;
};

/**
 * @param {Number} code
 * @param {String|Error|Object} [message] error message, Error or key-value hash for binding
 * @returns {Terror} new Terror instance
 */
Terror.createError = function(code, message) {
    var Constructor = this,
        error = new Constructor(code),
        _msg = error.message;

    // patch stacktrace to avoid meaningless entry of createError call
    error.message = '$$MESSAGE$$';
    Error.captureStackTrace(error, this.createError);
    error._stackTemplate = error.stack;
    error.setMessage(_msg);

    if (message instanceof Error || typeof message === 'string') {
        error.originalError = message;
        error.setMessage(error.message + ' (' + message.toString() + ')');
    } else if (typeof message === 'object' && message !== null) {
        error.bind(message);
    }

    return error;
};

/**
 * @param {Error|Terror} error
 * @param {Number} [code]
 * @returns {Terror}
 */
Terror.ensureError = function(error, code) {
    if ( ! (error instanceof this)) {
        if (typeof code !== 'string') {
            code = this.CODES.UNKNOWN_ERROR;
        }
        error = this.createError(code, error);
    }

    return error;
};

module.exports = Terror;
<|endoftext|>


<commit_before>"use strict";

var _ = require('underscore');
var fs = require('fs');
var connect = require('connect');
var mocha = require('mocha');
var async = require('async');
var utils = require('./utils');
var winston = require('winston');
var logger = utils.getLogger();

var launchpad = require('launchpad');
var miner = require('miner');
var Server = require('./server');
var defaults = require('./defaults.json');

/**
 * Create the tunnel using Miner
 *
 * @param config
 * @param callback
 */
var createTunnel = function (config, callback) {
	var settings = { port: config.port };
	var type = config.tunnel.type || config.tunnel;
	if (_.isObject(config.tunnel)) {
		_.extend(settings, config.tunnel);
	}

	logger.debug('Setting up tunnel:', config);
	miner[type](settings, callback);
};

/**
 * Launch a browser using Launchpad
 *
 * @param url
 * @param config
 * @param callback
 */
var launch = function (url, config, callback) {
	var launcherSettings = typeof config.launch === 'string' ? {} : config.launch;
	var type = config.launch.type || config.launch;
	var browserSettings = _.isObject(config.browser) ? config.browser : utils.parseBrowser(config.browser);
	launchpad[type](launcherSettings, function (error, launcher) {
		if (error) {
			return callback(error);
		}

		logger.debug('Launching ' + url + ' on ' + type + ' with:', browserSettings);
		launcher(url, browserSettings, callback);
	});
};

var createServer = function (file, config) {
	var root = utils.getRoot(file, config.root);
	var server = Server.createServer(_.extend(_.pick(config, 'reporter', 'coverage', 'timeout'),
		config.server, { root: root }));
	server.listen(config.port);
	process.on('uncaughtException', function(err) {
		server.error(err, 'Uncaught Exception', true);
	});
	return server;
}

var test = function (file, configuration, callback) {
	var files = Array.isArray(file) ? file : [file];
	var config = _.extend({}, defaults, configuration);

	if (config.verbose) {
		logger.add(winston.transports.File, {
			filename: config.log,
			json: false
		});
	}

	var getParams = function (token, query) {
		var result = _.extend({}, query);
		result[server.config.token] = token;
		return result;
	};
	var server = createServer(file[0], config);

	server.on('serverError', function(error, critical) {
		if(critical) {
			process.exit();
		}
	});

	// logger.debug('Running test with configuration: ', config);

	server.on('listening', function () {
		// First thing: Create the tunnel
		createTunnel(_.pick(config, 'port', 'tunnel'), function (error, hostUrl, tunnel) {
			if (error) {
				server.error('Tunnel', error, true);
				return;
			}
			logger.debug('Tunnel is up at:', hostUrl);

			// Create a callback list for each test file
			var tests = files.map(function (filename) {
				return function (callback) {
					filename = utils.parseUrl(filename, true);
					// Create a new token. Make sure it's not already registered
					var token = utils.generateToken(_.keys(server.instances));
					// Based on the token, the tunnel URL and the filename we can create the actual URL
					// for launching the browser
					var url = utils.getUrl(hostUrl, filename.path, getParams(token, filename.query));
					// Launch the browser
					launch(url, _.pick(config, 'launch', 'file', 'browser'), function (error, instance) {
						if (error) {
							return callback(error);
						}

						// Register the tokens
						server.register(token, instance);
						instance.on('testing', function (remoteReporter) {
							logger.log('Got test reporter for token ' + token);
							remoteReporter.on(server.config.exitEvent, function () {
								instance.stop(function (error) {
									logger.debug('Stopped instance', url);
									callback(error);
								});
							});
						});
					});
				};
			});

			// We can only do serial testing at the moment
			async.series(tests, function (error) {
				if(error) {
					server.error(error);
				}

				server.converter.on('end', function (stats, objects) {
					callback(error, stats, objects);
				});
				server.converter.end();
				if (tunnel && tunnel.kill) {
					logger.log('Stopping tunnel process.');
					tunnel.kill();
				}
			});
		});
	});
};

module.exports = {
	Server: Server,
	createTunnel: createTunnel,
	defaults: defaults,
	launch: launch,
	test: test
};<commit_msg>Fixes #20. Typo in variable name.<commit_after>"use strict";

var _ = require('underscore');
var fs = require('fs');
var connect = require('connect');
var mocha = require('mocha');
var async = require('async');
var utils = require('./utils');
var winston = require('winston');
var logger = utils.getLogger();

var launchpad = require('launchpad');
var miner = require('miner');
var Server = require('./server');
var defaults = require('./defaults.json');

/**
 * Create the tunnel using Miner
 *
 * @param config
 * @param callback
 */
var createTunnel = function (config, callback) {
	var settings = { port: config.port };
	var type = config.tunnel.type || config.tunnel;
	if (_.isObject(config.tunnel)) {
		_.extend(settings, config.tunnel);
	}

	logger.debug('Setting up tunnel:', config);
	miner[type](settings, callback);
};

/**
 * Launch a browser using Launchpad
 *
 * @param url
 * @param config
 * @param callback
 */
var launch = function (url, config, callback) {
	var launcherSettings = typeof config.launch === 'string' ? {} : config.launch;
	var type = config.launch.type || config.launch;
	var browserSettings = _.isObject(config.browser) ? config.browser : utils.parseBrowser(config.browser);
	launchpad[type](launcherSettings, function (error, launcher) {
		if (error) {
			return callback(error);
		}

		logger.debug('Launching ' + url + ' on ' + type + ' with:', browserSettings);
		launcher(url, browserSettings, callback);
	});
};

var createServer = function (file, config) {
	var root = utils.getRoot(file, config.root);
	var server = Server.createServer(_.extend(_.pick(config, 'reporter', 'coverage', 'timeout'),
		config.server, { root: root }));
	server.listen(config.port);
	process.on('uncaughtException', function(err) {
		server.error(err, 'Uncaught Exception', true);
	});
	return server;
}

var test = function (file, configuration, callback) {
	var files = Array.isArray(file) ? file : [file];
	var config = _.extend({}, defaults, configuration);

	if (config.verbose) {
		logger.add(winston.transports.File, {
			filename: config.log,
			json: false
		});
	}

	var getParams = function (token, query) {
		var result = _.extend({}, query);
		result[server.config.token] = token;
		return result;
	};
	var server = createServer(files[0], config);

	server.on('serverError', function(error, critical) {
		if(critical) {
			process.exit();
		}
	});

	// logger.debug('Running test with configuration: ', config);

	server.on('listening', function () {
		// First thing: Create the tunnel
		createTunnel(_.pick(config, 'port', 'tunnel'), function (error, hostUrl, tunnel) {
			if (error) {
				server.error('Tunnel', error, true);
				return;
			}
			logger.debug('Tunnel is up at:', hostUrl);

			// Create a callback list for each test file
			var tests = files.map(function (filename) {
				return function (callback) {
					filename = utils.parseUrl(filename, true);
					// Create a new token. Make sure it's not already registered
					var token = utils.generateToken(_.keys(server.instances));
					// Based on the token, the tunnel URL and the filename we can create the actual URL
					// for launching the browser
					var url = utils.getUrl(hostUrl, filename.path, getParams(token, filename.query));
					// Launch the browser
					launch(url, _.pick(config, 'launch', 'file', 'browser'), function (error, instance) {
						if (error) {
							return callback(error);
						}

						// Register the tokens
						server.register(token, instance);
						instance.on('testing', function (remoteReporter) {
							logger.log('Got test reporter for token ' + token);
							remoteReporter.on(server.config.exitEvent, function () {
								instance.stop(function (error) {
									logger.debug('Stopped instance', url);
									callback(error);
								});
							});
						});
					});
				};
			});

			// We can only do serial testing at the moment
			async.series(tests, function (error) {
				if(error) {
					server.error(error);
				}

				server.converter.on('end', function (stats, objects) {
					callback(error, stats, objects);
				});
				server.converter.end();
				if (tunnel && tunnel.kill) {
					logger.log('Stopping tunnel process.');
					tunnel.kill();
				}
			});
		});
	});
};

module.exports = {
	Server: Server,
	createTunnel: createTunnel,
	defaults: defaults,
	launch: launch,
	test: test
};<|endoftext|>


<commit_before>'use strict';

const MiioApi = require('../device');

const { Mode, Children, EasyNameable } = require('abstract-things');
const { Light, Dimmable, SwitchablePower } = require('abstract-things/lights');
const { percentage } = require('abstract-things/values');

const MiioDimmable = require('./capabilities/dimmable');
const MiioPower = require('./capabilities/power');

module.exports = class EyecareLamp2 extends Light
	.with(MiioPower, MiioDimmable, Mode, Children, MiioApi, EasyNameable)
{

	constructor(options) {
		super(options);

		this.defineProperty('power', {
			name: 'power',
			mapper: v => v === 'on'
		});

		this.defineProperty('bright', {
			name: 'brightness',
			mapper: parseInt
		});

		// Get if the
		this.defineProperty('notifystatus', {
			name: 'notifyStatus',
			mapper: v => v === 'on'
		});

		// Power of the secondary light
		this.defineProperty('ambstatus', {
			name: 'ambientPower',
			mapper: v => v === 'on'
		});

		// Brightness of the secondary light
		this.defineProperty('ambvalue', {
			name: 'ambientBrightness',
			mapper: parseInt
		});

		// If the main light is on
		this.defineProperty('eyecare', {
			name: 'eyeCare',
			mapper: v => v === 'on'
		});

		// The current user-defined scene
		this.defineProperty('scene_num', {
			name: 'userScene',
			mapper: v => {
				switch (v) {
					case 1:
						return 'study';
					case 2:
						return 'reading';
					case 3:
						return 'phone';
				}
			}
		});

		this.setModes([ 'study', 'reading', 'phone' ]);

		this.defineProperty('bls', {
			name: 'bls',
			mapper: v => v === 'on'
		});

		this.defineProperty('dvalue', {
			name: 'dvalue',
			mapper: parseInt
		});

		this.ambient = new AmbientLight(this);
		this.addChild(this.ambient);
	}

	changePower(power) {
		return this.call('set_power', [power ? 'on' : 'off'], {
			refresh: true
		});
	}

	changeBrightness(brightness) {
		return this.call('set_bright', [ brightness ], {
			refresh: true
		}).then(MiioApi.checkOk);
	}

	/**
	 * Is eyeCare active?
	 */
	get eyeCare() {
		return this.property('eyeCare');
	}

	/**
	 * Enable the eyeCare
	 */
	setEyeCare(enable) {
		return this.call('set_eyecare', [enable ? 'on' : 'off'], {
				refresh: true
			})
			.then(() => null);
	}

	/**
	 * Set the current eyeCare mode
	 */
	changeMode(mode) {

		switch (mode) {
			case 'study':
				mode = 1;
				break;
			case 'reading':
				mode = 2;
				break;
			case 'phone':
				mode = 3;
				break;
			default:
				return Promise.reject(new Error('Invalid EyeCare Mode: ' + mode));
		}
		return this.call('set_user_scene', [mode], {
			refresh: true
		});
	}

	setAmbientPower(power) {
		return this.call.send('enable_amb', [ power ? 'on' : 'off' ])
			.then(MiioApi.checkOk);
	}

	setAmbientBrightness(brightness) {
		brightness = percentage(brightness, { min: 0, max: 100 });

		return this.call.send('set_amb_bright', [ brightness ])
			.then(MiioApi.checkOk);
	}

	propertyUpdated(key, value) {
		super.propertyUpdated(key, value);

		switch(key) {
			case 'ambientPower':
				this.ambient.updatePower(value);
				break;
			case 'ambientBrightness':
				this.ambient.updateBrightness(value);
				break;
		}
	}
};

class AmbientLight extends Light.with(Dimmable, SwitchablePower) {

	constructor(parent) {
		super();

		this.parent = parent;
		this.id = parent.id + ':ambient';
	}

	changePower(power) {
		return this.parent.setAmbientPower(power);
	}

	changeBrightness(brightness) {
		return this.parent.setAmbientBrightness(brightness);
	}
}
<commit_msg>Temporarily disabling mode/scenes for eye care lamp<commit_after>'use strict';

const MiioApi = require('../device');

const { Children, EasyNameable } = require('abstract-things');
const { Light, Dimmable, SwitchablePower } = require('abstract-things/lights');
const { percentage } = require('abstract-things/values');

const MiioDimmable = require('./capabilities/dimmable');
const MiioPower = require('./capabilities/power');

module.exports = class EyecareLamp2 extends Light
	.with(MiioPower, MiioDimmable, Children, MiioApi, EasyNameable)
{

	constructor(options) {
		super(options);

		this.defineProperty('power', {
			name: 'power',
			mapper: v => v === 'on'
		});

		this.defineProperty('bright', {
			name: 'brightness',
			mapper: parseInt
		});

		// Get if the
		this.defineProperty('notifystatus', {
			name: 'notifyStatus',
			mapper: v => v === 'on'
		});

		// Power of the secondary light
		this.defineProperty('ambstatus', {
			name: 'ambientPower',
			mapper: v => v === 'on'
		});

		// Brightness of the secondary light
		this.defineProperty('ambvalue', {
			name: 'ambientBrightness',
			mapper: parseInt
		});

		// If the main light is on
		this.defineProperty('eyecare', {
			name: 'eyeCare',
			mapper: v => v === 'on'
		});

		// The current user-defined scene
		this.defineProperty('scene_num', {
			name: 'userScene',
			mapper: v => {
				switch (v) {
					case 1:
						return 'study';
					case 2:
						return 'reading';
					case 3:
						return 'phone';
				}
			}
		});

		this.setModes([ 'study', 'reading', 'phone' ]);

		this.defineProperty('bls', {
			name: 'bls',
			mapper: v => v === 'on'
		});

		this.defineProperty('dvalue', {
			name: 'dvalue',
			mapper: parseInt
		});

		this.ambient = new AmbientLight(this);
		this.addChild(this.ambient);
	}

	changePower(power) {
		return this.call('set_power', [power ? 'on' : 'off'], {
			refresh: true
		});
	}

	changeBrightness(brightness) {
		return this.call('set_bright', [ brightness ], {
			refresh: true
		}).then(MiioApi.checkOk);
	}

	/**
	 * Is eyeCare active?
	 */
	eyeCare() {
		return Promise.resolve(this.property('eyeCare'));
	}

	/**
	 * Enable the eyeCare
	 */
	setEyeCare(enable) {
		return this.call('set_eyecare', [enable ? 'on' : 'off'], {
				refresh: true
			})
			.then(() => null);
	}

	/**
	 * Set the current eyeCare mode
	 *
	changeMode(mode) {

		switch (mode) {
			case 'study':
				mode = 1;
				break;
			case 'reading':
				mode = 2;
				break;
			case 'phone':
				mode = 3;
				break;
			default:
				return Promise.reject(new Error('Invalid EyeCare Mode: ' + mode));
		}
		return this.call('set_user_scene', [mode], {
			refresh: true
		});
	}
	*/

	setAmbientPower(power) {
		return this.call.send('enable_amb', [ power ? 'on' : 'off' ])
			.then(MiioApi.checkOk);
	}

	setAmbientBrightness(brightness) {
		brightness = percentage(brightness, { min: 0, max: 100 });

		return this.call.send('set_amb_bright', [ brightness ])
			.then(MiioApi.checkOk);
	}

	propertyUpdated(key, value) {
		super.propertyUpdated(key, value);

		switch(key) {
			case 'ambientPower':
				this.ambient.updatePower(value);
				break;
			case 'ambientBrightness':
				this.ambient.updateBrightness(value);
				break;
		}
	}
};

class AmbientLight extends Light.with(Dimmable, SwitchablePower) {

	constructor(parent) {
		super();

		this.parent = parent;
		this.id = parent.id + ':ambient';
	}

	changePower(power) {
		return this.parent.setAmbientPower(power);
	}

	changeBrightness(brightness) {
		return this.parent.setAmbientBrightness(brightness);
	}
}
<|endoftext|>


<commit_before>"use strict";

define([], function()
{
	var AttachmentsStore = function()
	{
        this._db = null;

        var DB_NAME = "attachments_store";
        var OBJECT_STORE_NAME = "attachments";

		this.isSupported = function()
		{
            if(!window.indexedDB){
                return false;
            }
            return true;
		};

		this.store = function(featureLayerUrl, attachmentId, objectId, attachmentFile, callback)
		{
            try
            {
                var transaction = this._db.transaction([OBJECT_STORE_NAME],"readwrite");

                transaction.oncomplete = function(event)
                {
                    callback(true);
                };

                transaction.onerror = function(event)
                {
                    callback(false,event.target.error.message);
                };

                var objectStore = transaction.objectStore(OBJECT_STORE_NAME);
                var request = objectStore.put(
                	{
                		id: attachmentId,
                		objectId: objectId,
                		featureId: featureLayerUrl + "/" + objectId,
                		contentType: attachmentFile.type,
                		name: attachmentFile.name,
                		size: attachmentFile.size,
                		url: attachmentFile.url,
                		content: attachmentFile.content
                	});
                request.onsuccess = function(event)
                {
                    //console.log("item added to db " + event.target.result);
                };
            }
            catch(err)
            {
                console.log("AttachmentsStore: " + err.stack);
                callback(false,err.stack);
            }
		};

		this.retrieve = function(attachmentId, callback)
		{
            if(this._db !== null)
            {
                var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
                var request = objectStore.get(attachmentId);
                request.onsuccess = function(event)
                {
                    var result = event.target.result;
                    if(!result){
                        callback(false,"not found");
                    }
                    else{
                        callback(true,result);
                    }
                };
                request.onerror = function(err)
                {
                    console.log(err);
                    callback(false,err);
                };
            }
		};

		this.getAttachmentsByFeatureId = function(featureLayerUrl,objectId,callback)
		{
			var featureId = featureLayerUrl + "/" + objectId;
			var attachments = [];

			var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
			var index = objectStore.index("featureId");
			var keyRange = IDBKeyRange.only(featureId);
			index.openCursor(keyRange).onsuccess = function(evt)
			{
				var cursor = evt.target.result;
				if(cursor)
				{
					attachments.push( cursor.value );
					cursor.continue();
				}
				else
				{
					callback(attachments);
				}
			};
		};

        this.getAttachmentsByFeatureLayer = function(featureLayerUrl,callback)
        {
            var attachments = [];

            var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
            var index = objectStore.index("featureId");
            var keyRange = IDBKeyRange.bound(featureLayerUrl + "/", featureLayerUrl + "/A");
            index.openCursor(keyRange).onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    attachments.push( cursor.value );
                    cursor.continue();
                }
                else
                {
                    callback(attachments);
                }
            };
        };

        this.getAllAttachments = function(callback)
        {
            var attachments = [];

            var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
            objectStore.openCursor().onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    attachments.push( cursor.value );
                    cursor.continue();
                }
                else
                {
                    callback(attachments);
                }
            };
        };

		this.deleteAttachmentsByFeatureId = function(featureLayerUrl,objectId,callback)
		{
			var featureId = featureLayerUrl + "/" + objectId;

			var objectStore = this._db.transaction([OBJECT_STORE_NAME],"readwrite").objectStore(OBJECT_STORE_NAME);
			var index = objectStore.index("featureId");
			var keyRange = IDBKeyRange.only(featureId);
			var deletedCount = 0;
			index.openKeyCursor(keyRange).onsuccess = function(evt)
			{
				var cursor = evt.target.result;
				if(cursor)
				{
					objectStore.delete(cursor.primaryKey);
					deletedCount++;
					cursor.continue();
				}
				else
				{
					callback(deletedCount);
				}
			};
		};

		this.delete = function(attachmentId, callback)
		{
            if(this._db !== null)
            {
                var request = this._db.transaction([OBJECT_STORE_NAME],"readwrite")
                    .objectStore(OBJECT_STORE_NAME)
                    .delete(attachmentId);
                request.onsuccess = function(event)
                {
                    setTimeout(function(){callback(true);},1);
                };
                request.onerror = function(err)
                {
                    callback(false,err);
                };
            }
            else
            {
                callback(false,null);
            }
		};

        this.deleteAll = function(callback)
        {
            if(this._db !== null)
            {
                var request = this._db.transaction([OBJECT_STORE_NAME],"readwrite")
                    .objectStore(OBJECT_STORE_NAME)
                    .clear();
                request.onsuccess = function(event)
                {
                    callback(true);
                };
                request.onerror = function(err)
                {
                    callback(false,err);
                };
            }
            else
            {
                callback(false,null);
            }
        };

        this.replaceFeatureId = function(featureLayerUrl, oldId, newId, callback)
        {
            var featureId = featureLayerUrl + "/" + oldId;

            var objectStore = this._db.transaction([OBJECT_STORE_NAME],"readwrite").objectStore(OBJECT_STORE_NAME);
            var index = objectStore.index("featureId");
            var keyRange = IDBKeyRange.only(featureId);
            var replacedCount = 0;
            index.openCursor(keyRange).onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    var newFeatureId = featureLayerUrl + "/" + newId;
                    var updated = cursor.value;
                    updated.featureId = newFeatureId;
                    updated.objectId = newId;
                    objectStore.put(updated);
                    replacedCount++;
                    cursor.continue();
                }
                else
                {
                    // allow time for all changes to persist...
                    setTimeout( function() { callback(replacedCount); }, 1 );
                }
            };
        };

        this.getUsage = function(callback)
        {
            if(this._db !== null){
                var usage = { sizeBytes: 0, attachmentCount: 0 };

                var transaction = this._db.transaction([OBJECT_STORE_NAME])
                    .objectStore(OBJECT_STORE_NAME)
                    .openCursor();

                console.log("dumping keys");

                transaction.onsuccess = function(event)
                {
                    var cursor = event.target.result;
                    if(cursor)
                    {
                        console.log(cursor.value.id, cursor.value.featureId, cursor.value.objectId);
                        var storedObject = cursor.value;
                        var json = JSON.stringify(storedObject);
                        usage.sizeBytes += json.length;
                        usage.attachmentCount += 1;
                        cursor.continue();
                    }
                    else
                    {
                        callback(usage,null);
                    }
                }.bind(this);
                transaction.onerror = function(err)
                {
                    callback(null,err);
                };
            }
            else
            {
                callback(null,null);
            }
        };

		this.init = function(callback)
		{
			console.log("init AttachmentStore");

            var request = indexedDB.open(DB_NAME, 11);
            callback = callback || function(success) { console.log("AttachmentsStore::init() success:", success); }.bind(this);

            request.onerror = function(event)
            {
                console.log("indexedDB error: " + event.target.errorCode);
                callback(false,event.target.errorCode);
            }.bind(this);

            request.onupgradeneeded = function(event)
            {
                var db = event.target.result;

                if( db.objectStoreNames.contains(OBJECT_STORE_NAME))
                {
                    db.deleteObjectStore(OBJECT_STORE_NAME);
                }

                var objectStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: "id" });
                objectStore.createIndex("featureId","featureId", {unique: false});
            }.bind(this);

            request.onsuccess = function(event)
            {
                this._db = event.target.result;
                console.log("database opened successfully");
                callback(true);
            }.bind(this);
        };
	};
	return AttachmentsStore;
});
<commit_msg>first step into refactoring attachmentsStore.js<commit_after>"use strict";

define([], function()
{
	var AttachmentsStore = function()
	{
        this._db = null;

        var DB_NAME = "attachments_store";
        var OBJECT_STORE_NAME = "attachments";

		this.isSupported = function()
		{
            if(!window.indexedDB){
                return false;
            }
            return true;
		};

		this.store = function(featureLayerUrl, attachmentId, objectId, attachmentFile, callback)
		{
            try
            {
                var transaction = this._db.transaction([OBJECT_STORE_NAME],"readwrite");

                transaction.oncomplete = function(event)
                {
                    callback(true);
                };

                transaction.onerror = function(event)
                {
                    callback(false,event.target.error.message);
                };

                var objectStore = transaction.objectStore(OBJECT_STORE_NAME);
                var request = objectStore.put(
                	{
                		id: attachmentId,
                		objectId: objectId,
                		featureId: featureLayerUrl + "/" + objectId,
                		contentType: attachmentFile.type,
                		name: attachmentFile.name,
                		size: attachmentFile.size,
                		url: attachmentFile.url,
                		content: attachmentFile.content
                	});
                request.onsuccess = function(event)
                {
                    //console.log("item added to db " + event.target.result);
                };
            }
            catch(err)
            {
                console.log("AttachmentsStore: " + err.stack);
                callback(false,err.stack);
            }
		};

		this.retrieve = function(attachmentId, callback)
		{
            console.assert(this._db !== null, "indexeddb not initialized");

            var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
            var request = objectStore.get(attachmentId);
            request.onsuccess = function(event)
            {
                var result = event.target.result;
                if(!result){
                    callback(false,"not found");
                }
                else{
                    callback(true,result);
                }
            };
            request.onerror = function(err)
            {
                console.log(err);
                callback(false,err);
            };
		};

		this.getAttachmentsByFeatureId = function(featureLayerUrl,objectId,callback)
		{
            console.assert(this._db !== null, "indexeddb not initialized");

			var featureId = featureLayerUrl + "/" + objectId;
			var attachments = [];

			var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
			var index = objectStore.index("featureId");
			var keyRange = IDBKeyRange.only(featureId);
			index.openCursor(keyRange).onsuccess = function(evt)
			{
				var cursor = evt.target.result;
				if(cursor)
				{
					attachments.push( cursor.value );
					cursor.continue();
				}
				else
				{
					callback(attachments);
				}
			};
		};

        this.getAttachmentsByFeatureLayer = function(featureLayerUrl,callback)
        {
            console.assert(this._db !== null, "indexeddb not initialized");

            var attachments = [];

            var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
            var index = objectStore.index("featureId");
            var keyRange = IDBKeyRange.bound(featureLayerUrl + "/", featureLayerUrl + "/A");
            index.openCursor(keyRange).onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    attachments.push( cursor.value );
                    cursor.continue();
                }
                else
                {
                    callback(attachments);
                }
            };
        };

        this.getAllAttachments = function(callback)
        {
            console.assert(this._db !== null, "indexeddb not initialized");

            var attachments = [];

            var objectStore = this._db.transaction([OBJECT_STORE_NAME]).objectStore(OBJECT_STORE_NAME);
            objectStore.openCursor().onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    attachments.push( cursor.value );
                    cursor.continue();
                }
                else
                {
                    callback(attachments);
                }
            };
        };

		this.deleteAttachmentsByFeatureId = function(featureLayerUrl,objectId,callback)
		{
            console.assert(this._db !== null, "indexeddb not initialized");

			var featureId = featureLayerUrl + "/" + objectId;

			var objectStore = this._db.transaction([OBJECT_STORE_NAME],"readwrite").objectStore(OBJECT_STORE_NAME);
			var index = objectStore.index("featureId");
			var keyRange = IDBKeyRange.only(featureId);
			var deletedCount = 0;
			index.openKeyCursor(keyRange).onsuccess = function(evt)
			{
				var cursor = evt.target.result;
				if(cursor)
				{
					objectStore.delete(cursor.primaryKey);
					deletedCount++;
					cursor.continue();
				}
				else
				{
					callback(deletedCount);
				}
			};
		};

		this.delete = function(attachmentId, callback)
		{
            console.assert(this._db !== null, "indexeddb not initialized");

            var request = this._db.transaction([OBJECT_STORE_NAME],"readwrite")
                .objectStore(OBJECT_STORE_NAME)
                .delete(attachmentId);
            request.onsuccess = function(event)
            {
                setTimeout(function(){callback(true);},1);
            };
            request.onerror = function(err)
            {
                callback(false,err);
            };
		};

        this.deleteAll = function(callback)
        {
            console.assert(this._db !== null, "indexeddb not initialized");

            var request = this._db.transaction([OBJECT_STORE_NAME],"readwrite")
                .objectStore(OBJECT_STORE_NAME)
                .clear();
            request.onsuccess = function(event)
            {
                callback(true);
            };
            request.onerror = function(err)
            {
                callback(false,err);
            };
        };

        this.replaceFeatureId = function(featureLayerUrl, oldId, newId, callback)
        {
            console.assert(this._db !== null, "indexeddb not initialized");

            var featureId = featureLayerUrl + "/" + oldId;

            var objectStore = this._db.transaction([OBJECT_STORE_NAME],"readwrite").objectStore(OBJECT_STORE_NAME);
            var index = objectStore.index("featureId");
            var keyRange = IDBKeyRange.only(featureId);
            var replacedCount = 0;
            index.openCursor(keyRange).onsuccess = function(evt)
            {
                var cursor = evt.target.result;
                if(cursor)
                {
                    var newFeatureId = featureLayerUrl + "/" + newId;
                    var updated = cursor.value;
                    updated.featureId = newFeatureId;
                    updated.objectId = newId;
                    objectStore.put(updated);
                    replacedCount++;
                    cursor.continue();
                }
                else
                {
                    // allow time for all changes to persist...
                    setTimeout( function() { callback(replacedCount); }, 1 );
                }
            };
        };

        this.getUsage = function(callback)
        {
            console.assert(this._db !== null, "indexeddb not initialized");

            var usage = { sizeBytes: 0, attachmentCount: 0 };

            var transaction = this._db.transaction([OBJECT_STORE_NAME])
                .objectStore(OBJECT_STORE_NAME)
                .openCursor();

            console.log("dumping keys");

            transaction.onsuccess = function(event)
            {
                var cursor = event.target.result;
                if(cursor)
                {
                    console.log(cursor.value.id, cursor.value.featureId, cursor.value.objectId);
                    var storedObject = cursor.value;
                    var json = JSON.stringify(storedObject);
                    usage.sizeBytes += json.length;
                    usage.attachmentCount += 1;
                    cursor.continue();
                }
                else
                {
                    callback(usage,null);
                }
            }.bind(this);
            transaction.onerror = function(err)
            {
                callback(null,err);
            };
        };

		this.init = function(callback)
		{
			console.log("init AttachmentStore");

            var request = indexedDB.open(DB_NAME, 11);
            callback = callback || function(success) { console.log("AttachmentsStore::init() success:", success); }.bind(this);

            request.onerror = function(event)
            {
                console.log("indexedDB error: " + event.target.errorCode);
                callback(false,event.target.errorCode);
            }.bind(this);

            request.onupgradeneeded = function(event)
            {
                var db = event.target.result;

                if( db.objectStoreNames.contains(OBJECT_STORE_NAME))
                {
                    db.deleteObjectStore(OBJECT_STORE_NAME);
                }

                var objectStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: "id" });
                objectStore.createIndex("featureId","featureId", {unique: false});
            }.bind(this);

            request.onsuccess = function(event)
            {
                this._db = event.target.result;
                console.log("database opened successfully");
                callback(true);
            }.bind(this);
        };
	};
	return AttachmentsStore;
});
<|endoftext|>


<commit_before>/**
 * Created by rulkens on 29/04/15.
 */
var Scheduler     = require('./scheduler');

module.exports = function (api) {
    var s = new Scheduler({api : api});

    //s.add('binary-clock');
    //s.add('blink');
    //s.add('pong.color');
    //s.add('off');
    //s.add('pong.color');
    s.add('light.color');
    /*s.add('blink', {
        startIn: '10s',
        endsIn: '20s'
    });*/

    s.start();
    return s;
};
<commit_msg>setting leap motion to default!<commit_after>/**
 * Created by rulkens on 29/04/15.
 */
var Scheduler     = require('./scheduler');

module.exports = function (api) {
    var s = new Scheduler({api : api, frameRate : 40});

    //s.add('binary-clock');
    //s.add('blink');
    //s.add('binary-clock');
    //s.add('analogue-clock');
    //s.add('analogue-clock.color');
    //s.add('off');
    //s.add('pong.color');
    //s.add('light.color');
    //s.add('rainbow');
    //s.add('blink');
    s.add('leap-motion.color');
    /*s.add('blink', {
        startIn: '10s',
        endsIn: '20s'
    });*/

    s.start();
    return s;
};
<|endoftext|>


<commit_before>import {
  objectOrFunction,
  isFunction
} from './utils';

import asap from './asap';

function noop() {}

var PENDING   = void 0;
var FULFILLED = 1;
var REJECTED  = 2;

var GET_THEN_ERROR = new ErrorObject();

function selfFullfillment() {
  return new TypeError("You cannot resolve a promise with itself");
}
function getThen(promise) {
  try {
    return promise.then;
  } catch(error) {
    GET_THEN_ERROR.error = error;
    return GET_THEN_ERROR;
  }
}

function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
  try {
    then.call(value, fulfillmentHandler, rejectionHandler);
  } catch(e) {
    return e;
  }
}

function handleForeignThenable(promise, thenable, then) {
   asap(function(promise) {
    var sealed = false;
    var error = tryThen(then, thenable, function(value) {
      if (sealed) { return; }
      sealed = true;
      if (thenable !== value) {
        resolve(promise, value);
      } else {
        fulfill(promise, value);
      }
    }, function(reason) {
      if (sealed) { return; }
      sealed = true;

      reject(promise, reason);
    }, 'Settle: ' + (promise._label || ' unknown promise'));

    if (!sealed && error) {
      sealed = true;
      reject(promise, error);
    }
  }, promise);
}

function handleOwnThenable(promise, thenable) {
  if (thenable._state === FULFILLED) {
    fulfill(promise, thenable._result);
  } else if (promise._state === REJECTED) {
    reject(promise, thenable._result);
  } else {
    subscribe(thenable, undefined, function(value) {
      resolve(promise, value);
    }, function(reason) {
      reject(promise, reason);
    });
  }
}

function handleMaybeThenable(promise, maybeThenable) {
  if (maybeThenable.constructor === promise.constructor) {
    handleOwnThenable(promise, maybeThenable);
  } else {
    var then = getThen(maybeThenable);

    if (then === GET_THEN_ERROR) {
      reject(promise, GET_THEN_ERROR.error);
    } else if (then === undefined) {
      fulfill(promise, maybeThenable);
    } else if (isFunction(then)) {
      handleForeignThenable(promise, maybeThenable, then);
    } else {
      fulfill(promise, maybeThenable);
    }
  }
}

function resolve(promise, value) {
  if (promise === value) {
    reject(promise, selfFullfillment());
  } else if (objectOrFunction(value)) {
    handleMaybeThenable(promise, value);
  } else {
    fulfill(promise, value);
  }
}

function publishRejection(promise) {
  if (promise._onerror) {
    promise._onerror(promise._result);
  }

  publish(promise);
}

function fulfill(promise, value) {
  if (promise._state !== PENDING) { return; }

  promise._result = value;
  promise._state = FULFILLED;

  if (promise._subscribers.length === 0) {
  } else {
    asap(publish, promise);
  }
}

function reject(promise, reason) {
  if (promise._state !== PENDING) { return; }
  promise._state = REJECTED;
  promise._result = reason;

  asap(publishRejection, promise);
}

function subscribe(parent, child, onFulfillment, onRejection) {
  var subscribers = parent._subscribers;
  var length = subscribers.length;

  parent._onerror = null;

  subscribers[length] = child;
  subscribers[length + FULFILLED] = onFulfillment;
  subscribers[length + REJECTED]  = onRejection;

  if (length === 0 && parent._state) {
    asap(publish, parent);
  }
}

function publish(promise) {
  var subscribers = promise._subscribers;
  var settled = promise._state;

  if (subscribers.length === 0) { return; }

  var child, callback, detail = promise._result;

  for (var i = 0; i < subscribers.length; i += 3) {
    child = subscribers[i];
    callback = subscribers[i + settled];

    if (child) {
      invokeCallback(settled, child, callback, detail);
    } else {
      callback(detail);
    }
  }

  promise._subscribers.length = 0;
}

function ErrorObject() {
  this.error = null;
}

var TRY_CATCH_ERROR = new ErrorObject();

function tryCatch(callback, detail) {
  try {
    return callback(detail);
  } catch(e) {
    TRY_CATCH_ERROR.error = e;
    return TRY_CATCH_ERROR;
  }
}

function invokeCallback(settled, promise, callback, detail) {
  var hasCallback = isFunction(callback),
      value, error, succeeded, failed;

  if (hasCallback) {
    value = tryCatch(callback, detail);

    if (value === TRY_CATCH_ERROR) {
      failed = true;
      error = value.error;
      value = null;
    } else {
      succeeded = true;
    }

    if (promise === value) {
      reject(promise, new TypeError('A promises callback cannot return that same promise.'));
      return;
    }

  } else {
    value = detail;
    succeeded = true;
  }

  if (promise._state !== PENDING) {
    // noop
  } else if (hasCallback && succeeded) {
    resolve(promise, value);
  } else if (failed) {
    reject(promise, error);
  } else if (settled === FULFILLED) {
    fulfill(promise, value);
  } else if (settled === REJECTED) {
    reject(promise, value);
  }
}

function initializePromise(promise, resolver) {
  try {
    resolver(function resolvePromise(value){
      resolve(promise, value);
    }, function rejectPromise(reason) {
      reject(promise, reason);
    });
  } catch(e) {
    reject(promise, e);
  }
}

export {
  noop,
  resolve,
  reject,
  fulfill,
  subscribe,
  publish,
  publishRejection,
  initializePromise,
  invokeCallback,
  FULFILLED,
  REJECTED,
  PENDING
};
<commit_msg>keep AST size down<commit_after>import {
  objectOrFunction,
  isFunction
} from './utils';

import asap from './asap';

function noop() {}

var PENDING   = void 0;
var FULFILLED = 1;
var REJECTED  = 2;

var GET_THEN_ERROR = new ErrorObject();

function selfFullfillment() {
  return new TypeError("You cannot resolve a promise with itself");
}

function cannotReturnOwn() {
  return new TypeError('A promises callback cannot return that same promise.')
}

function getThen(promise) {
  try {
    return promise.then;
  } catch(error) {
    GET_THEN_ERROR.error = error;
    return GET_THEN_ERROR;
  }
}

function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
  try {
    then.call(value, fulfillmentHandler, rejectionHandler);
  } catch(e) {
    return e;
  }
}

function handleForeignThenable(promise, thenable, then) {
   asap(function(promise) {
    var sealed = false;
    var error = tryThen(then, thenable, function(value) {
      if (sealed) { return; }
      sealed = true;
      if (thenable !== value) {
        resolve(promise, value);
      } else {
        fulfill(promise, value);
      }
    }, function(reason) {
      if (sealed) { return; }
      sealed = true;

      reject(promise, reason);
    }, 'Settle: ' + (promise._label || ' unknown promise'));

    if (!sealed && error) {
      sealed = true;
      reject(promise, error);
    }
  }, promise);
}

function handleOwnThenable(promise, thenable) {
  if (thenable._state === FULFILLED) {
    fulfill(promise, thenable._result);
  } else if (promise._state === REJECTED) {
    reject(promise, thenable._result);
  } else {
    subscribe(thenable, undefined, function(value) {
      resolve(promise, value);
    }, function(reason) {
      reject(promise, reason);
    });
  }
}

function handleMaybeThenable(promise, maybeThenable) {
  if (maybeThenable.constructor === promise.constructor) {
    handleOwnThenable(promise, maybeThenable);
  } else {
    var then = getThen(maybeThenable);

    if (then === GET_THEN_ERROR) {
      reject(promise, GET_THEN_ERROR.error);
    } else if (then === undefined) {
      fulfill(promise, maybeThenable);
    } else if (isFunction(then)) {
      handleForeignThenable(promise, maybeThenable, then);
    } else {
      fulfill(promise, maybeThenable);
    }
  }
}

function resolve(promise, value) {
  if (promise === value) {
    reject(promise, selfFullfillment());
  } else if (objectOrFunction(value)) {
    handleMaybeThenable(promise, value);
  } else {
    fulfill(promise, value);
  }
}

function publishRejection(promise) {
  if (promise._onerror) {
    promise._onerror(promise._result);
  }

  publish(promise);
}

function fulfill(promise, value) {
  if (promise._state !== PENDING) { return; }

  promise._result = value;
  promise._state = FULFILLED;

  if (promise._subscribers.length === 0) {
  } else {
    asap(publish, promise);
  }
}

function reject(promise, reason) {
  if (promise._state !== PENDING) { return; }
  promise._state = REJECTED;
  promise._result = reason;

  asap(publishRejection, promise);
}

function subscribe(parent, child, onFulfillment, onRejection) {
  var subscribers = parent._subscribers;
  var length = subscribers.length;

  parent._onerror = null;

  subscribers[length] = child;
  subscribers[length + FULFILLED] = onFulfillment;
  subscribers[length + REJECTED]  = onRejection;

  if (length === 0 && parent._state) {
    asap(publish, parent);
  }
}

function publish(promise) {
  var subscribers = promise._subscribers;
  var settled = promise._state;

  if (subscribers.length === 0) { return; }

  var child, callback, detail = promise._result;

  for (var i = 0; i < subscribers.length; i += 3) {
    child = subscribers[i];
    callback = subscribers[i + settled];

    if (child) {
      invokeCallback(settled, child, callback, detail);
    } else {
      callback(detail);
    }
  }

  promise._subscribers.length = 0;
}

function ErrorObject() {
  this.error = null;
}

var TRY_CATCH_ERROR = new ErrorObject();

function tryCatch(callback, detail) {
  try {
    return callback(detail);
  } catch(e) {
    TRY_CATCH_ERROR.error = e;
    return TRY_CATCH_ERROR;
  }
}

function invokeCallback(settled, promise, callback, detail) {
  var hasCallback = isFunction(callback),
      value, error, succeeded, failed;

  if (hasCallback) {
    value = tryCatch(callback, detail);

    if (value === TRY_CATCH_ERROR) {
      failed = true;
      error = value.error;
      value = null;
    } else {
      succeeded = true;
    }

    if (promise === value) {
      reject(promise, cannotReturnOwn());
      return;
    }

  } else {
    value = detail;
    succeeded = true;
  }

  if (promise._state !== PENDING) {
    // noop
  } else if (hasCallback && succeeded) {
    resolve(promise, value);
  } else if (failed) {
    reject(promise, error);
  } else if (settled === FULFILLED) {
    fulfill(promise, value);
  } else if (settled === REJECTED) {
    reject(promise, value);
  }
}

function initializePromise(promise, resolver) {
  try {
    resolver(function resolvePromise(value){
      resolve(promise, value);
    }, function rejectPromise(reason) {
      reject(promise, reason);
    });
  } catch(e) {
    reject(promise, e);
  }
}

export {
  noop,
  resolve,
  reject,
  fulfill,
  subscribe,
  publish,
  publishRejection,
  initializePromise,
  invokeCallback,
  FULFILLED,
  REJECTED,
  PENDING
};
<|endoftext|>


<commit_before>'use strict';
const log = require('intel').getLogger('browsertime.firefox');
const geckoProfilerDefaults = require('./settings/geckoProfilerDefaults');
const { isAndroidConfigured, Android } = require('../android');
const path = require('path');
const pathToFolder = require('../support/pathToFolder');
const { BrowserError } = require('../support/errors');
const delay = ms => new Promise(res => setTimeout(res, ms));

/**
 * Timeout a promise after ms. Use promise.race to compete
 * about the timeout and the promise.
 * @param {promise} promise - The promise to wait for
 * @param {int} ms - how long in ms to wait for the promise to fininsh
 * @param {string} errorMessage - the error message in the Error if we timeouts
 */
async function timeout(promise, ms, errorMessage) {
  let timer = null;

  return Promise.race([
    new Promise((resolve, reject) => {
      timer = setTimeout(reject, ms, new BrowserError(errorMessage));
      return timer;
    }),
    promise.then(value => {
      clearTimeout(timer);
      return value;
    })
  ]);
}
class GeckoProfiler {
  constructor(runner, storageManager, firefoxConfig, options) {
    this.runner = runner;
    this.storageManager = storageManager;
    this.firefoxConfig = firefoxConfig;
    this.options = options;
  }

  async start() {
    const runner = this.runner;
    const firefoxConfig = this.firefoxConfig;
    const options = this.options;
    const chosenFeatures =
      firefoxConfig.geckoProfilerParams.features.split(',');
    const featureString = '["' + chosenFeatures.join('","') + '"]';

    const chosenThreads = firefoxConfig.geckoProfilerParams.threads.split(',');
    const threadString = '["' + chosenThreads.join('","') + '"]';

    let interval = firefoxConfig.geckoProfilerParams.interval;

    // Set platform specific sampling intervals if not explicitly specified.
    if (
      firefoxConfig.geckoProfiler &&
      !firefoxConfig.geckoProfilerParams.interval
    ) {
      interval = isAndroidConfigured(options)
        ? geckoProfilerDefaults.android_sampling_interval
        : geckoProfilerDefaults.desktop_sampling_interval;
    }

    const bufferSize = firefoxConfig.geckoProfilerParams.bufferSize;

    // Firefox 69 and above has a slightly different API for StartProfiler
    // See nsIProfiler::StartProfiler in tools/profiler/gecko/nsIProfiler.idl
    const parameterLength = await runner.runPrivilegedScript(
      'return Services.profiler.StartProfiler.length;',
      'Get StartProfiler.length'
    );

    let script;
    if (parameterLength === 7) {
      script = `Services.profiler.StartProfiler(${bufferSize},${interval},${featureString},
        ${chosenFeatures.length},${threadString},${chosenThreads.length});`;
    } else if (parameterLength === 5 || parameterLength === 6) {
      script = `Services.profiler.StartProfiler(${bufferSize},${interval},${featureString},${threadString});`;
    } else {
      log.error('Unknown Gecko Profiler API');
      throw new Error('Unknown Gecko Profiler API');
    }

    log.info(
      'Start GeckoProfiler with features: %s and threads: %s',
      featureString,
      threadString
    );

    await runner.runPrivilegedScript(script, 'Start GeckoProfiler');
    return delay(firefoxConfig.geckoProfilerSettleTime || 3000);
  }

  async stop(index, url) {
    const runner = this.runner;
    const storageManager = this.storageManager;
    const options = this.options;
    let profileDir = await storageManager.createSubDataDir(
      path.join(pathToFolder(url, options))
    );
    let destinationFilename = path.join(
      profileDir,
      `geckoProfile-${index}.json`
    );

    let deviceProfileFilename = destinationFilename;
    if (isAndroidConfigured(options)) {
      deviceProfileFilename = `/sdcard/Android/data/${this.firefoxConfig.android.package}/files/geckoProfile-${index}.json`;
    }

    // Must use String.raw or else the backslashes on Windows will be escapes.
    log.info(
      `Collecting Gecko profile from ${deviceProfileFilename} to ${destinationFilename}`
    );
    const script = `
      var callback = arguments[arguments.length - 1];
       Services.profiler.dumpProfileToFileAsync(String.raw\`${deviceProfileFilename}\`)
        .then(callback)
        .catch((e) => callback({'error' : e}));
       `;
    try {
      await timeout(
        runner.runPrivilegedAsyncScript(script, 'Collect GeckoProfiler'),
        1200000,
        'Could not get the Geckoprofiler log'
      );
      log.info('Stop GeckoProfiler.');
      await runner.runPrivilegedScript(
        'Services.profiler.StopProfiler();',
        'Stop GeckoProfiler'
      );

      if (isAndroidConfigured(options)) {
        const android = new Android(options);
        await android._downloadFile(deviceProfileFilename, destinationFilename);
      }

      // GZIP the profile and remove the old file
      return storageManager.gzip(
        destinationFilename,
        path.join(profileDir, `geckoProfile-${index}.json.gz`),
        true
      );
    } catch (e) {
      log.error(e.message);
    }
  }

  addMetaData() {}
}

module.exports = GeckoProfiler;
<commit_msg>Fallback to Firefox name https://github.com/sitespeedio/browsertime/issues/1711 (#1712)<commit_after>'use strict';
const log = require('intel').getLogger('browsertime.firefox');
const geckoProfilerDefaults = require('./settings/geckoProfilerDefaults');
const { isAndroidConfigured, Android } = require('../android');
const path = require('path');
const get = require('lodash.get');
const pathToFolder = require('../support/pathToFolder');
const { BrowserError } = require('../support/errors');
const delay = ms => new Promise(res => setTimeout(res, ms));

/**
 * Timeout a promise after ms. Use promise.race to compete
 * about the timeout and the promise.
 * @param {promise} promise - The promise to wait for
 * @param {int} ms - how long in ms to wait for the promise to fininsh
 * @param {string} errorMessage - the error message in the Error if we timeouts
 */
async function timeout(promise, ms, errorMessage) {
  let timer = null;

  return Promise.race([
    new Promise((resolve, reject) => {
      timer = setTimeout(reject, ms, new BrowserError(errorMessage));
      return timer;
    }),
    promise.then(value => {
      clearTimeout(timer);
      return value;
    })
  ]);
}
class GeckoProfiler {
  constructor(runner, storageManager, firefoxConfig, options) {
    this.runner = runner;
    this.storageManager = storageManager;
    this.firefoxConfig = firefoxConfig;
    this.options = options;
  }

  async start() {
    const runner = this.runner;
    const firefoxConfig = this.firefoxConfig;
    const options = this.options;
    const chosenFeatures =
      firefoxConfig.geckoProfilerParams.features.split(',');
    const featureString = '["' + chosenFeatures.join('","') + '"]';

    const chosenThreads = firefoxConfig.geckoProfilerParams.threads.split(',');
    const threadString = '["' + chosenThreads.join('","') + '"]';

    let interval = firefoxConfig.geckoProfilerParams.interval;

    // Set platform specific sampling intervals if not explicitly specified.
    if (
      firefoxConfig.geckoProfiler &&
      !firefoxConfig.geckoProfilerParams.interval
    ) {
      interval = isAndroidConfigured(options)
        ? geckoProfilerDefaults.android_sampling_interval
        : geckoProfilerDefaults.desktop_sampling_interval;
    }

    const bufferSize = firefoxConfig.geckoProfilerParams.bufferSize;

    // Firefox 69 and above has a slightly different API for StartProfiler
    // See nsIProfiler::StartProfiler in tools/profiler/gecko/nsIProfiler.idl
    const parameterLength = await runner.runPrivilegedScript(
      'return Services.profiler.StartProfiler.length;',
      'Get StartProfiler.length'
    );

    let script;
    if (parameterLength === 7) {
      script = `Services.profiler.StartProfiler(${bufferSize},${interval},${featureString},
        ${chosenFeatures.length},${threadString},${chosenThreads.length});`;
    } else if (parameterLength === 5 || parameterLength === 6) {
      script = `Services.profiler.StartProfiler(${bufferSize},${interval},${featureString},${threadString});`;
    } else {
      log.error('Unknown Gecko Profiler API');
      throw new Error('Unknown Gecko Profiler API');
    }

    log.info(
      'Start GeckoProfiler with features: %s and threads: %s',
      featureString,
      threadString
    );

    await runner.runPrivilegedScript(script, 'Start GeckoProfiler');
    return delay(firefoxConfig.geckoProfilerSettleTime || 3000);
  }

  async stop(index, url) {
    const runner = this.runner;
    const storageManager = this.storageManager;
    const options = this.options;
    let profileDir = await storageManager.createSubDataDir(
      path.join(pathToFolder(url, options))
    );
    let destinationFilename = path.join(
      profileDir,
      `geckoProfile-${index}.json`
    );

    let deviceProfileFilename = destinationFilename;
    if (isAndroidConfigured(options)) {
      deviceProfileFilename = `/sdcard/Android/data/${get(
        this.firefoxConfig,
        'android.package',
        'org.mozilla.firefox'
      )}/files/geckoProfile-${index}.json`;
    }

    // Must use String.raw or else the backslashes on Windows will be escapes.
    log.info(
      `Collecting Gecko profile from ${deviceProfileFilename} to ${destinationFilename}`
    );
    const script = `
      var callback = arguments[arguments.length - 1];
       Services.profiler.dumpProfileToFileAsync(String.raw\`${deviceProfileFilename}\`)
        .then(callback)
        .catch((e) => callback({'error' : e}));
       `;
    try {
      await timeout(
        runner.runPrivilegedAsyncScript(script, 'Collect GeckoProfiler'),
        1200000,
        'Could not get the Geckoprofiler log'
      );
      log.info('Stop GeckoProfiler.');
      await runner.runPrivilegedScript(
        'Services.profiler.StopProfiler();',
        'Stop GeckoProfiler'
      );

      if (isAndroidConfigured(options)) {
        const android = new Android(options);
        await android._downloadFile(deviceProfileFilename, destinationFilename);
      }

      // GZIP the profile and remove the old file
      return storageManager.gzip(
        destinationFilename,
        path.join(profileDir, `geckoProfile-${index}.json.gz`),
        true
      );
    } catch (e) {
      log.error(e.message);
    }
  }

  addMetaData() {}
}

module.exports = GeckoProfiler;
<|endoftext|>


<commit_before>// Function that provides map of rules found in ignorefiles for given ignorefile
// type. Additinally it invokes event on changes in map which are results of
// changes in ignorefiles.

'use strict';

var getNull   = require('es5-ext/lib/Function/k')(null)
  , extend    = require('es5-ext/lib/Object/extend')
  , deferred  = require('deferred')
  , readFile  = deferred.promisify(require('fs').readFile)
  , dirname   = require('path').dirname
  , sep       = require('../path/sep')
  , FindRoot  = require('./find-root').FindRoot
  , watchPath = require('./watch-path')

  , Map, readRules, readRulesWatch, paths, getMap;

paths = function (root, path2) {
	if (root === path2) {
		return [root];
	}
	return [root].concat(path2.slice(root.length + 1).split(sep)
		.map(function (path) {
			return root += sep + path;
		}));
};

readRules = function (path) {
	return readFile(path + sep + this.filename)(String, getNull);
};
readRulesWatch = function (path) {
	var watcher, promise, current = null;
	promise = readRules.call(this, path);
	watcher = watchPath(path + sep + this.filename);

	promise.end(function (data) {
		current = data;
	}, null);
	watcher.on('change', function (event) {
		if (event.type === 'remove') {
			if (current != null) {
				current = promise.value = null;
				promise.emit('change', current, path);
			}
		} else {
			readRules.call(this, path, this.filename).end(function (data) {
				if (data !== current) {
					current = promise.value = data;
					promise.emit('change', current, path);
				}
			}, null);
		}
	}.bind(this));
	return promise;
};

Map = function (path, watch) {
	var def, root;
	this.path = path;
	this.watch = watch;
	this.data = { root: null, map: {} };
	extend(this, deferred());
	if (this.watch) {
		this.onRulesChange = this.onRulesChange.bind(this);
		this.rulePromises = {};
	}
};
Map.prototype = {
	init: function (root) {
		if (this.watch) {
			root.on('change', this.updateRoot.bind(this));
		}
		root.end(function (root) {
			if (root) {
				this.data.root = root;
				this.addPaths(root, this.path).end(function () {
					this.resolve(this.data);
				}.bind(this), this.resolve);
			} else {
				this.resolve(this.data);
			}
		}.bind(this), this.resolve);
		return this.promise;
	},
	onRulesChange: function (rules, path) {
		if (rules == null) {
			delete this.data.map[path];
		} else {
			this.data.map[path] = rules;
		}
		this.promise.emit('change', this.data);
	},
	addPaths: function (root, path) {
		return deferred.map(paths(root, path), function (path) {
			var rules = this.readRules(path);
			if (this.watch) {
				this.rulePromises[path] = rules;
				rules.on('change', this.onRulesChange);
			}
			return rules.aside(function (rules) {
				if (rules != null) {
					this[path] = rules;
				}
			}.bind(this.data.map));
		}, this);
	},
	removePaths: function (root, path) {
		paths(root, path).forEach(function (path) {
			this.rulePromises[path].off('change', this.onRulesChange);
			delete this.rulePromises[path];
			delete this.data.map[path];
		}, this);
	},
	updateRoot: function (root) {
		if (!root) {
			this.removePaths(this.data.root, this.path);
			this.data.root = null;
			this.promise.emit('change', this.data);
		} else if (!this.data.root) {
			this.data.root = root;
			this.addPaths(root, this.path)
				.end(this.promise.emit.bind(this.promise, 'change', this.data), null);
		} else if (this.data.root < root) {
			this.removePaths(this.data.root, dirname(root));
			this.data.root = root;
			this.promise.emit('change', this.data);
		} else {
			this.addPaths(root, dirname(this.data.root))
				.end(this.promise.emit.bind(this.promise, 'change', this.data), null);
			this.data.root = root;
		}
	}
};

getMap = module.exports = function (path, mode, watch) {
	var map = new Map(path, watch), finder, isRoot;
	map.filename = mode.filename;
	map.readRules = watch ? readRulesWatch : readRules;
	finder = new FindRoot(path, watch);
	finder.isRoot = watch ? mode.isRootWatch : mode.isRoot;
	finder.next();
	return map.init(finder.promise);
};
getMap.Map = Map;
getMap.readRules = readRules;
getMap.readRulesWatch = readRulesWatch;
<commit_msg>Internal: Customizable parse function for readRules<commit_after>// Function that provides map of rules found in ignorefiles for given ignorefile
// type. Additinally it invokes event on changes in map which are results of
// changes in ignorefiles.

'use strict';

var getNull   = require('es5-ext/lib/Function/k')(null)
  , extend    = require('es5-ext/lib/Object/extend')
  , isCopy    = require('es5-ext/lib/Object/is-copy')
  , deferred  = require('deferred')
  , readFile  = deferred.promisify(require('fs').readFile)
  , dirname   = require('path').dirname
  , sep       = require('../path/sep')
  , FindRoot  = require('./find-root').FindRoot
  , watchPath = require('./watch-path')

  , Map, readRules, readRulesWatch, paths, getMap;

paths = function (root, path2) {
	if (root === path2) {
		return [root];
	}
	return [root].concat(path2.slice(root.length + 1).split(sep)
		.map(function (path) {
			return root += sep + path;
		}));
};

readRules = function (path) {
	return readFile(path + sep + this.filename)(this.parse, getNull);
};
readRulesWatch = function (path) {
	var watcher, promise, current = null;
	promise = readRules.call(this, path);
	watcher = watchPath(path + sep + this.filename);

	promise.end(function (data) {
		current = data;
	}, null);
	watcher.on('change', function (event) {
		if (event.type === 'remove') {
			if (current != null) {
				current = promise.value = null;
				promise.emit('change', current, path);
			}
		} else {
			readRules.call(this, path, this.filename).end(function (data) {
				if (!isCopy(current, data)) {
					current = promise.value = data;
					promise.emit('change', current, path);
				}
			}, null);
		}
	}.bind(this));
	return promise;
};

Map = function (path, watch) {
	var def, root;
	this.path = path;
	this.watch = watch;
	this.data = { root: null, map: {} };
	extend(this, deferred());
	if (this.watch) {
		this.onRulesChange = this.onRulesChange.bind(this);
		this.rulePromises = {};
	}
};
Map.prototype = {
	init: function (root) {
		if (this.watch) {
			root.on('change', this.updateRoot.bind(this));
		}
		root.end(function (root) {
			if (root) {
				this.data.root = root;
				this.addPaths(root, this.path).end(function () {
					this.resolve(this.data);
				}.bind(this), this.resolve);
			} else {
				this.resolve(this.data);
			}
		}.bind(this), this.resolve);
		return this.promise;
	},
	parse: String,
	onRulesChange: function (rules, path) {
		if (rules == null) {
			delete this.data.map[path];
		} else {
			this.data.map[path] = rules;
		}
		this.promise.emit('change', this.data);
	},
	addPaths: function (root, path) {
		return deferred.map(paths(root, path), function (path) {
			var rules = this.readRules(path);
			if (this.watch) {
				this.rulePromises[path] = rules;
				rules.on('change', this.onRulesChange);
			}
			return rules.aside(function (rules) {
				if (rules != null) {
					this[path] = rules;
				}
			}.bind(this.data.map));
		}, this);
	},
	removePaths: function (root, path) {
		paths(root, path).forEach(function (path) {
			this.rulePromises[path].off('change', this.onRulesChange);
			delete this.rulePromises[path];
			delete this.data.map[path];
		}, this);
	},
	updateRoot: function (root) {
		if (!root) {
			this.removePaths(this.data.root, this.path);
			this.data.root = null;
			this.promise.emit('change', this.data);
		} else if (!this.data.root) {
			this.data.root = root;
			this.addPaths(root, this.path)
				.end(this.promise.emit.bind(this.promise, 'change', this.data), null);
		} else if (this.data.root < root) {
			this.removePaths(this.data.root, dirname(root));
			this.data.root = root;
			this.promise.emit('change', this.data);
		} else {
			this.addPaths(root, dirname(this.data.root))
				.end(this.promise.emit.bind(this.promise, 'change', this.data), null);
			this.data.root = root;
		}
	}
};

getMap = module.exports = function (path, mode, watch, parse) {
	var map = new Map(path, watch), finder, isRoot;
	map.filename = mode.filename;
	map.readRules = watch ? readRulesWatch : readRules;
	if (parse) {
		map.parse = parse;
	}
	finder = new FindRoot(path, watch);
	finder.isRoot = watch ? mode.isRootWatch : mode.isRoot;
	finder.next();
	return map.init(finder.promise);
};
getMap.Map = Map;
getMap.readRules = readRules;
getMap.readRulesWatch = readRulesWatch;
<|endoftext|>


<commit_before>import React from 'react';

import './styles.css';

export default class About extends React.Component {
  render() {
    return (

Um verkefnið

Um vefinn

Á þessum vef finnur þú upplýsingar og tölfræði um þingmenn og þingflokka fyrir kjörtímabilið 2013-2016.

Markmið vefsins er að sækja gögn sem finna má á vef Alþingis, vinna úr þeim og setja fram á skemmtilegan, fræðandi og helst af öllu hlutlausan máta.

Hvaðan koma gögnin?

Öll gögn eru sótt af vef Alþingis og skiptast þau niður í tvo meginflokka: atkvæðaskrá og ræður eftir þingum.

Gögnin eru sótt sjálfkrafa, hver einasta undirsíða fyrir alla þingmenn er skoðuð og gögnum breytt yfir á form sem þægilegt er fyrir tölvu að vinna úr þeim.

Því næst er byrjað að vinna úr gögnunum, þau flokkuð og skoðuð fyrir hvern þingmann. Eftir að hafa unnið úr þeim fyrir hvern þingmann eru upplýsingum safnað saman til þess að fá gögn fyrir þingflokkana.

Verkefnið

Þetta er verkefni eftir Bæring Gunnar Steinþórsson.

Sérstakar þakkir fá samstarfsfélagar mínir hjá Aranja;
 Davíð Bachmann Jóhannesson, Sebastian Helms og Ægir Giraldo Þorsteinsson fyrir hjálp við útfærslu og hönnun á vefnum.

Ábendingar og hugmyndir eru vel þegnar á thingmenn@aranja.com.

    );
  }
}
<commit_msg>Update about page<commit_after>import React from 'react';

import './styles.css';

export default class About extends React.Component {
  render() {
    return (

Um verkefnið

Um vefinn

Á þessum vef finnur þú upplýsingar og tölfræði um þingmenn og þingflokka fyrir árin 2007 til 2017.

Markmið vefsins er að sækja gögn sem finna má á vef Alþingis, vinna úr þeim og setja fram á skemmtilegan, fræðandi og helst af öllu hlutlausan máta.

Hvaðan koma gögnin?

Öll gögn eru sótt af vef Alþingis og skiptast þau niður í þrjá meginflokka: atkvæðaskrár, ræðuskrár og þingskjalalista.

Gögnin eru sótt sjálfkrafa, hver einasta undirsíða fyrir alla þingmenn er skoðuð, þau flokkuð og skoðuð fyrir hvern þingmann.

Eftir að hafa unnið úr þeim fyrir hvern þingmann eru upplýsingum safnað saman til þess að fá gögn fyrir þingflokkana.

Verkefnið

Þetta er verkefni eftir Bæring Gunnar Steinþórsson.

Sérstakar þakkir fá samstarfsfélagar mínir hjá Aranja;
 Davíð Bachmann Jóhannesson, Sebastian Helms og Ægir Giraldo Þorsteinsson fyrir hjálp við útfærslu og hönnun á vefnum.

Ábendingar og hugmyndir eru vel þegnar á thingmenn@aranja.com.

    );
  }
}
<|endoftext|>


<commit_before>var logsView = Backbone.View.extend({
  el: '#content',
  offset: 0,
  size: 10,
  page: 1,
  table: 'logTableID',
  totalAmount: 0,
  totalPages: 0,

  initialize: function () {
    this.totalAmount = this.collection.models[0].attributes.totalAmount;
    this.totalPages = Math.ceil(this.totalAmount / this.size);
  },

  events: {
    "click #all-switch" : "all",
    "click #error-switch" : "error",
    "click #warning-switch" : "warning",
    "click #debug-switch" : "debug",
    "click #info-switch" : "info",
    "click #logTableID_first" : "firstTable",
    "click #logTableID_last"  : "lastTable",
    "click #logTableID_prev"  : "prevTable",
    "click #logTableID_next"  : "nextTable",
  },
  firstTable: function () {
    if (this.offset == 0) {
    }
    else {
      this.offset = 0;
      this.page = 1;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  lastTable: function () {
    if (this.page == this.totalPages) {
    }
    else {
      this.totalPages = Math.ceil(this.totalAmount / this.size);
      this.page = this.totalPages;
      this.offset = (this.totalPages * this.size) - this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  prevTable: function () {
    if (this.offset == 0) {
    }
    else {
      this.offset = this.offset - this.size;
      this.page = this.page - 1;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  nextTable: function () {
    if (this.page == this.totalPages) {
    }
    else {
      this.page = this.page + 1;
      this.offset = this.offset + this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  jumpToTable: function (toPage) {
      this.page = toPage;
      this.offset = toPage * this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  all: function () {
    this.resetState();
    this.table = "logTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  error: function() {
    this.resetState();
    this.table = "critTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  warning: function() {
    this.resetState();
    this.table = "warnTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  debug: function() {
    this.resetState();
    this.table = "debugTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, 0, this.size);
  },
  info: function() {
    this.resetState();
    this.table = "infoTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, 0, this.size);
  },
  resetState: function () {
    this.offset = 0;
    this.size = 10;
    this.page = 1;
  },

  tabs: function () {
  },

  template: new EJS({url: '/_admin/html/js/templates/logsView.ejs'}),
  initLogTables: function () {
    var self = this;
    $.each(this.collection.tables, function(key, table) {
      table = $('#'+table).dataTable({
        "bFilter": false,
        "bPaginate": false,
        "bLengthChange": false,
        "bDeferRender": true,
        "bProcessing": true,
        "bAutoWidth": false,
        "iDisplayLength": -1,
        "bJQueryUI": false,
        "aoColumns": [
          { "sClass":"center firstcol", "bSortable":false},
          { "sClass":"center seccol", "bSortable":false},
          { "bSortable": false, "sClass":"logContent thirdcol"}
        ],
        "oLanguage": {"sEmptyTable": "No logfiles available"}
      });
    });

  },
  render: function() {
    $(this.el).html(this.template.text);
    return this;
  },
  renderPagination: function (totalPages, currentPage) {
    var self = this;
    var target = $('#logtestdiv'),
    options = {
      left: 1,
      right: 1,
      page: currentPage,
      lastPage: totalPages,
      click: function(i) {
        if (i === 1 && i !== currentPage) {
          self.firstTable();
        }
        if (i === totalPages && i !== currentPage) {
          self.lastTable();
        }
        else {
          console.log("Number: " + i);
          self.jumpToTable(i);
        }
        options.page = i;
        target.pagination(options);
      }
    };
    target.pagination(options);
  },
  drawTable: function () {
    var self = this;

    function format (dt) {
      var pad = function (n) {
        return n < 10 ? '0' + n : n
      };

      return dt.getUTCFullYear() + '-'
      + pad(dt.getUTCMonth() + 1) + '-'
      + pad(dt.getUTCDate()) + ' '
      + pad(dt.getUTCHours()) + ':'
      + pad(dt.getUTCMinutes()) + ':'
      + pad(dt.getUTCSeconds());
    }

    $.each(window.arangoLogsStore.models, function(key, value) {
      var convertedLog = self.convertLogStatus(value.attributes.level);
      var dt = new Date(value.attributes.timestamp * 1000);
      $('#'+self.table).dataTable().fnAddData([convertedLog, format(dt), value.attributes.text]);
    });
    try {
      this.totalAmount = this.collection.models[0].attributes.totalAmount;
      this.totalPages = Math.ceil(this.totalAmount / this.size);
      this.renderPagination(this.totalPages, this.page);
    }
    catch (e) {
      //  $('#logPages').html('No logfiles available');
    }
  },
  clearTable: function () {
    $('#'+this.table).dataTable().fnClearTable();
  },
  convertLogStatus: function (status) {
    if (status === 1) { return "Error" ;}
    else if (status === 2) { return "Warning" ;}
    else if (status === 3) { return "Info" ;}
    else if (status === 4) { return "Debug" ;}
    else { return "Unknown";}
  }
});
<commit_msg>log bugfix<commit_after>var logsView = Backbone.View.extend({
  el: '#content',
  offset: 0,
  size: 10,
  page: 1,
  table: 'logTableID',
  totalAmount: 0,
  totalPages: 0,

  initialize: function () {
    this.totalAmount = this.collection.models[0].attributes.totalAmount;
    this.totalPages = Math.ceil(this.totalAmount / this.size);
  },

  events: {
    "click #all-switch" : "all",
    "click #error-switch" : "error",
    "click #warning-switch" : "warning",
    "click #debug-switch" : "debug",
    "click #info-switch" : "info",
    "click #logTableID_first" : "firstTable",
    "click #logTableID_last"  : "lastTable",
    "click #logTableID_prev"  : "prevTable",
    "click #logTableID_next"  : "nextTable",
  },
  firstTable: function () {
    if (this.offset == 0) {
    }
    else {
      this.offset = 0;
      this.page = 1;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  lastTable: function () {
    if (this.page == this.totalPages) {
    }
    else {
      this.totalPages = Math.ceil(this.totalAmount / this.size);
      this.page = this.totalPages;
      this.offset = (this.totalPages * this.size) - this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  prevTable: function () {
    if (this.offset == 0) {
    }
    else {
      this.offset = this.offset - this.size;
      this.page = this.page - 1;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  nextTable: function () {
    if (this.page == this.totalPages) {
    }
    else {
      this.page = this.page + 1;
      this.offset = this.offset + this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
    }
  },
  jumpToTable: function (toPage) {
      this.page = toPage;
      this.offset = toPage * this.size;
      this.clearTable();
      this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  all: function () {
    this.resetState();
    this.table = "logTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  error: function() {
    this.resetState();
    this.table = "critTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  warning: function() {
    this.resetState();
    this.table = "warnTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, this.offset, this.size);
  },
  debug: function() {
    this.resetState();
    this.table = "debugTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, 0, this.size);
  },
  info: function() {
    this.resetState();
    this.table = "infoTableID";
    this.clearTable();
    this.collection.fillLocalStorage(this.table, 0, this.size);
  },
  resetState: function () {
    this.offset = 0;
    this.size = 10;
    this.page = 1;
  },

  tabs: function () {
  },

  template: new EJS({url: '/_admin/html/js/templates/logsView.ejs'}),
  initLogTables: function () {
    var self = this;
    $.each(this.collection.tables, function(key, table) {
      table = $('#'+table).dataTable({
        "bFilter": false,
        "bPaginate": false,
        "bLengthChange": false,
        "bDeferRender": true,
        "bProcessing": true,
        "bAutoWidth": false,
        "iDisplayLength": -1,
        "bJQueryUI": false,
        "aoColumns": [
          { "sClass":"center firstcol", "bSortable":false},
          { "sClass":"center seccol", "bSortable":false},
          { "bSortable": false, "sClass":"logContent thirdcol"}
        ],
        "oLanguage": {"sEmptyTable": "No logfiles available"}
      });
    });

  },
  render: function() {
    $(this.el).html(this.template.text);
    return this;
  },
  renderPagination: function (totalPages, currentPage) {
    var self = this;
    var target = $('#logtestdiv'),
    options = {
      left: 1,
      right: 1,
      page: currentPage,
      lastPage: totalPages,
      click: function(i) {
        if (i === 1 && i !== currentPage) {
          self.firstTable();
        }
        else if (i === totalPages && i !== currentPage) {
          self.lastTable();
        }
        else {
          console.log("Number: " + i);
          self.jumpToTable(i);
        }
        options.page = i;
        target.pagination(options);
      }
    };
    target.pagination(options);
  },
  drawTable: function () {
    var self = this;

    function format (dt) {
      var pad = function (n) {
        return n < 10 ? '0' + n : n
      };

      return dt.getUTCFullYear() + '-'
      + pad(dt.getUTCMonth() + 1) + '-'
      + pad(dt.getUTCDate()) + ' '
      + pad(dt.getUTCHours()) + ':'
      + pad(dt.getUTCMinutes()) + ':'
      + pad(dt.getUTCSeconds());
    }

    $.each(window.arangoLogsStore.models, function(key, value) {
      var convertedLog = self.convertLogStatus(value.attributes.level);
      var dt = new Date(value.attributes.timestamp * 1000);
      $('#'+self.table).dataTable().fnAddData([convertedLog, format(dt), value.attributes.text]);
    });
    try {
      this.totalAmount = this.collection.models[0].attributes.totalAmount;
      this.totalPages = Math.ceil(this.totalAmount / this.size);
      this.renderPagination(this.totalPages, this.page);
    }
    catch (e) {
      //  $('#logPages').html('No logfiles available');
    }
  },
  clearTable: function () {
    $('#'+this.table).dataTable().fnClearTable();
  },
  convertLogStatus: function (status) {
    if (status === 1) { return "Error" ;}
    else if (status === 2) { return "Warning" ;}
    else if (status === 3) { return "Info" ;}
    else if (status === 4) { return "Debug" ;}
    else { return "Unknown";}
  }
});
<|endoftext|>


<commit_before><commit_msg>js client: fix long polling<commit_after><|endoftext|>


<commit_before>// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import 'babel-polyfill'
import Vue from 'vue'
import Vuex from 'vuex'
// import BootstrapVue from 'bootstrap-vue'
import App from './App'
// import App from './AppBS4'
import router from './router'
import { store } from './store'
// import 'bootstrap/dist/css/bootstrap.min.css'
// import 'bootstrap-vue/dist/bootstrap-vue.css'

// GWELLS js API library (helper methods for working with API)
import ApiService from '@/common/services/gwells'

Vue.use(Vuex)
Vue.config.productionTip = false

// set baseURL and default headers
ApiService.init()

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
<commit_msg>clean up main app entry<commit_after>// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import 'babel-polyfill'
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App'
import router from './router'
import { store } from './store'

// GWELLS js API library (helper methods for working with API)
import ApiService from '@/common/services/gwells'

Vue.use(Vuex)
Vue.config.productionTip = false

// set baseURL and default headers
ApiService.init()

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var appRoot = path.join(__dirname, '../../..');
var fs = require('fs');
var hbs = require('hbs');

var utils = require(path.join(appRoot, './lib/utils'));
var resource = require('./resource');

const invocationKey = 'node_0_12';

function generate (service) {
  // console.log(service);
  var resources = service.resources;
  var clients = [];

  resources.forEach(function (rSource) {
    clients.push(resource.createResource(rSource, service.imports));
  });

  var hbsFilePath = path.join(appRoot, 'public/templates', invocationKey, 'client.hbs');
  var hbsFileContents = fs.readFileSync(hbsFilePath).toString('utf-8');
  var template = hbs.handlebars.compile(hbsFileContents);

  var model = {
    constructorName: utils.alphaNumOnly(utils.capitalizeFirstLetter(service.name)),
    clients: clients
  };

  return [{
    name: service.name + '.js',
    dir: 'app/api/' + service.name,
    contents: template(model)
  }];
}

module.exports = {
  generate: generate
};
<commit_msg>Update node_0_12 client to use Promises<commit_after>'use strict';

var path = require('path');
var appRoot = path.join(__dirname, '../../..');
var fs = require('fs');
var hbs = require('hbs');

var utils = require(path.join(appRoot, './lib/utils'));
var resource = require('./resource');

const invocationKey = 'node_0_12';

function generate (service) {
  var resources = service.resources;
  var clients = [];

  resources.forEach(function (rSource) {
    clients.push(resource.createResource(rSource, service.imports));
  });

  var hbsFilePath = path.join(appRoot, 'public/templates', invocationKey, 'client.hbs');
  var hbsFileContents = fs.readFileSync(hbsFilePath).toString('utf-8');
  var template = hbs.handlebars.compile(hbsFileContents);

  var model = {
    constructorName: utils.alphaNumOnly(utils.capitalizeFirstLetter(service.name)),
    clients: clients
  };

  return new Promise(function (resolve) {
    resolve([{
      name: service.name + '.js',
      dir: 'app/api/' + service.name,
      contents: template(model)
    }]);
  });

}

module.exports = {
  generate: generate
};
<|endoftext|>