<commit_before>/*
 * in
 * https://github.com/goliatone/in
 *
 * Copyright (c) 2015 goliatone
 * Licensed under the MIT license.
 */
/*jshint esversion:6*/
'use strict';

const extend = require('gextend');
const join = require('path').join;
const readdir = require('fs').readdir;
const separator = require('path').sep;
const extname = require('path').extname;
const resolve = require('path').resolve;
const util = require('util');
const exists = util.promisify(require('fs').exists);
const isAbsolute = require('path').isAbsolute;
const VError = require('verror');

const EventEmitter = require('events');
const multimatch = require('multimatch');

/**
 * This creates the bean objects.
 */
const _normalize = require('./normalizeArguments');

const _isDevelopment = require('./isDevelopment');

const _filterEmptyDir = require('./filter-empty-dir');

const logger = require('noop-console').logger();

const DEFAULTS = {
    logger,
    autoinitialize: true,
    basepath: process.cwd(),
    normalize: _normalize,
    afterMount: function() {},
    mountHandler: function _mount(bean, context, config = {}) {
        const plugin = bean.plugin;
        if (typeof bean.config === 'function') return bean.config(plugin, context, config);
        config = extend({}, bean.config, config);
        if (typeof config.mount === 'function') return config.mount(plugin, context, config);
        if (typeof plugin.init === 'function') return plugin.init(context, config);
        return context[bean.id] = plugin;
    },
    sortFilter: function _sortFilter(plugins) {
        function filter(a, b) {
            function p(i) {
                return i.plugin.priority === undefined ? 0 : i.plugin.priority;
            }
            return p(a) < p(b) ? -1 : 1;
        }
        return plugins.sort(filter);
    }
};

class PluginLoader {
    constructor(config) {
        config = extend({}, DEFAULTS, config);
        if (config.autoinitialize) this.init(config);
    }

    init(options = {}) {

        this.context = new EventEmitter();

        extend(this, options);
    }

    isPluginId(plugin) {
        return plugin.indexOf(separator) === -1;
    }

    normalizePath(path, basepath = this.basepath) {
            return resolve(join(basepath, path));
        }
        /**
         *  Public: Scans `target` for files
         *  * `target` {String} Path to scan
         *  Returns Array {Array} Array containing absolute paths to all files in target
         */
    async find(target) {
        if (!this.isPluginId(target) && !isAbsolute(target)) {
            target = this.normalizePath(target, this.basepath);
        }

        if (!await exists(target)) {
            this.logger.warn('find failed due to ENOENT: %s', target);
            return resolve([]);
        }

        return new Promise((resolve, reject) => {
            readdir(target, async(err, list) => {
                if (err) return reject(err);

                list = list.map(f => join(target, f));

                list = await _filterEmptyDir(list);

                resolve(list);
            });
        });
    }

    /**
     *  Public: Apply `minimatch` patterns against `paths`,
     *  an array of paths.
     *  The default pattern is `['**', '!node_modules', '!.git']`
     *  * `paths` {Array} Array of paths
     *  * `patterns=['**', '!node_modules', '!.git']` {Array} `minimatch` patterns
     *
     * @argument {Array} paths Array of paths.
     * @argument {Array} patterns minimatch patterns
     * @return {Promise} Array containing filtered paths.
     */
    filter(paths, patterns = ['**', '!node_modules', '!.git', '!.json']) {
        return Promise.resolve(multimatch(paths, patterns));
    }

    /**
     * exclude files that match a given pattern.
     *
     * @param  {Array} paths         List of paths
     * @param  {Array}  [patterns=[]] List of patterns
     * @return {Promise}
     */
    exclude(paths, patterns = []) {

        if (!patterns || patterns.length === 0) {
            return Promise.resolve(paths);
        }

        if (typeof patterns === 'string') {
            patterns = [patterns];
        }

        /*
         * If we have a negative pattern
         * we need to ensure the first pattern
         * is a `**` match all.
         * Check for a pattern with a !
         * If found, then ensuer index 0 is **
         */
        // if(!patterns.includes('**')) {
        //     patterns.unshift('**');
        // }

        //TODO: ensure we only have it at the start?

        let matched = [];
        let excluded = multimatch(paths, patterns);

        paths.forEach(p => {
            if (excluded.includes(p)) return;
            matched.push(p);
        });

        return Promise.resolve(matched);
    }

    /**
     * Collect all plugins into an array.
     *
     * @type {Object}
     */
    load(plugins = [], options = {}) {
        options = extend({}, DEFAULTS, options);

        if (plugins.length === 0) {
            this.logger.warn('PluginLoader: no plugins provided');
        }

        //TODO: This is not used!! If we use it things break
        let basepath = options.basepath || this.basepath;

        if (options.plugins) {
            plugins = plugins.concat(options.plugins);
        }

        plugins = this.normalize(plugins, this.basepath);

        this._paths = plugins;
        this._plugins = [];

        return new Promise(async(resolve, reject) => {

            for (let i = 0; i < plugins.length; i++) {
                let bean = plugins[i];

                if (!this.isValidBeanExtension(bean.path)) {
                    return this.logger.warn('Provided bean has invalid extension', bean.path);
                }

                bean.isLocal = true;

                try {
                    const existsModule = await exists(bean.path);
                    const existsFile = await exists(`${bean.path}.js`);

                    if (existsModule) {
                        bean.plugin = require(bean.path);
                    } else if (existsFile) {
                        bean.plugin = require(`${bean.path}.js`);
                    } else {
                        bean.plugin = require(join(this.basepath, 'node_modules', bean.path));
                        bean.isLocal = false;
                    }
                } catch (e) {
                    let msg = 'Failed to require plugin "' + bean.id + '": ' + e.message;
                    this.logger.error(msg);

                    if (_isDevelopment()) {
                        this.logger.error(e.stack);
                    }
                    reject(new VError(e, msg));
                }
                //TODO: we could have a post require hook, to add meta to each plugin?
                // bean.priority = bean.plugin.priority === undefined ? 0 : bean.plugin.priority;
                // bean.dependencies = bean.plugin.dependencies === undefined ? [] : bean.plugin.dependencies;

                this._plugins.push(bean);
            }

            this.sort(this._plugins);

            resolve(this._plugins);
        });
    }

    /**
     * Applies `sortFilter` to the passed in
     * list of plugins.
     * You can set `sortFilter` using the config
     * object.
     * The deafult value will sort plugins on a
     * `priority` property.
     *
     * ```js
     * function _sortFilter(a, b) {
     *     function p(i){
     *         return i.priority === undefined ? 0 : i.priority;
     *     }
     *     return p(a) < p(b) ? -1 : 1;
     * }
     * ```
     *
     * Syncronous.
     * @param  {Array} plugins List of plugins.
     * @return {Array} List of ordered plugins.
     */
    sort(plugins) {
        return this.sortFilter(plugins);
    }

    /**
     * Provided a list of loaded plugins it
     * will mount them in the provided `context`.
     *
     * It uses `mountHandler` which will do the
     * actual work.
     *
     * You can override `mountHandler` using the
     * config object.
     *
     * @param {Array} plugin List of loaded plugins.
     * @param {Object} config Configuration object.
     * @param {Object} context Passed as argument to
     *                         `mountHandler`
     * @type {Object}
     */
    mount(plugin, config = {}, context = this.context) {

        config = extend({}, {
            mountHandler: this.mountHandler,
            afterMount: this.afterMount
        }, config);

        let plugins = plugin;

        let { mountHandler } = config;

        if (!Array.isArray(plugins)) plugins = [plugin];

        return new Promise((resolve, reject) => {
            try {
                plugins.map((plugin) => mountHandler(plugin, context, config));
            } catch (e) {
                if (_isDevelopment()) {
                    this.logger.error(e);
                }
                reject(new VError(e, 'Error running plugin: ' + plugin.id + '\n\n' + e.message + '\n\n' + e.stack));
            }

            config.afterMount(context, config);

            resolve(context);
        });
    }

    /**
     * Mounts a directory containing plugin defintion
     * files.
     *
     * It runs the following operations:
     *
     * - find
     * - filter
     * - exclude
     * - load
     * - mount
     *
     * If `options.exclude` is an array with
     * `multimatch` patterns of files to exclude.
     *
     * @param  {String} directory              Path to directory
     * @param  {Object} [options={}]
     * @param  {Object} [context=this.context]
     * @return {Promise}
     */
    mountDirectory(directory, options = {}, context = this.context) {
        return this.find(directory)
            .then(this.filter)
            .then(plugins => this.exclude(plugins, options.exclude))
            .then(plugins => this.load(plugins, options))
            .then(plugins => this.mount(plugins, options, context));
    }

    mountList(list, options = {}, context = this.context) {
        return this.load(list, options)
            .then(plugins => this.mount(plugins, options, context));
    }

    isValidBeanExtension(path = '') {
        let ext = extname(path);
        /*
         * Allow files without extension
         */
        if (!ext) return true;

        /*
         * If file has extension only
         * allow js files.
         */
        return ext === '.js';
    }
}

PluginLoader.DEFAULTS = DEFAULTS;

PluginLoader.normalize = _normalize;

/**
 * Expose PluginLoader
 */
module.exports = PluginLoader;<commit_msg>add: Made load recursive so we can use directories with sub plugins<commit_after>/*
 * in
 * https://github.com/goliatone/in
 *
 * Copyright (c) 2015 goliatone
 * Licensed under the MIT license.
 */
/*jshint esversion:6*/
'use strict';

const extend = require('gextend');
const join = require('path').join;
const readdir = require('recursive-readdir-async');
const separator = require('path').sep;
const extname = require('path').extname;
const resolve = require('path').resolve;
const util = require('util');
const exists = util.promisify(require('fs').exists);
const isAbsolute = require('path').isAbsolute;
const VError = require('verror');

const EventEmitter = require('events');
const multimatch = require('multimatch');

const EXT_JS = '.js';

/**
 * This creates the bean objects.
 */
const _normalize = require('./normalizeArguments');

const _isDevelopment = require('./isDevelopment');

const _filterEmptyDir = require('./filter-empty-dir');

const logger = require('noop-console').logger();

const DEFAULTS = {
    logger,
    autoinitialize: true,
    basepath: process.cwd(),
    normalize: _normalize,
    afterMount: function() {},
    mountHandler: function _mount(bean, context, config = {}) {
        const plugin = bean.plugin;
        if (typeof bean.config === 'function') return bean.config(plugin, context, config);
        config = extend({}, bean.config, config);
        if (typeof config.mount === 'function') return config.mount(plugin, context, config);
        if (typeof plugin.init === 'function') return plugin.init(context, config);
        return context[bean.id] = plugin;
    },
    sortFilter: function _sortFilter(plugins) {
        function filter(a, b) {
            function p(i) {
                return i.plugin.priority === undefined ? 0 : i.plugin.priority;
            }
            return p(a) < p(b) ? -1 : 1;
        }
        return plugins.sort(filter);
    },
    readdirOpts: {
        mode: readdir.LIST,
        recursive: true,
        stats: false,
        ignoreFolders: true,
        extensions: false
    }
};

class PluginLoader {
    constructor(config) {
        config = extend({}, DEFAULTS, config);
        if (config.autoinitialize) this.init(config);
    }

    init(options = {}) {

        this.context = new EventEmitter();

        extend(this, options);
    }

    isPluginId(plugin) {
        return plugin.indexOf(separator) === -1;
    }

    normalizePath(path, basepath = this.basepath) {
        return resolve(join(basepath, path));
    }

    /**
     * Scans `target` for files
     * @public
     * @param {String} target Plugin id or path to scan
     * @param {Object} options Options for readdir
     * @returns {Array} Array containing absolute paths to all files in target
     */
    async find(target, options = {}) {
        if (!this.isPluginId(target) && !isAbsolute(target)) {
            target = this.normalizePath(target, this.basepath);
        }

        if (!await exists(target)) {
            this.logger.warn('find failed due to ENOENT: %s', target);
            return resolve([]);
        }

        options = extend({}, this.readdirOpts, options);

        let list = await readdir.list(target, options);
        list = list.map(file => file.fullname);

        return list;
    }

    /**
     *  Public: Apply `minimatch` patterns against `paths`,
     *  an array of paths.
     *  The default pattern is `['**', '!node_modules', '!.git']`
     *  * `paths` {Array} Array of paths
     *  * `patterns=['**', '!node_modules', '!.git']` {Array} `minimatch` patterns
     *
     * @argument {Array} paths Array of paths.
     * @argument {Array} patterns minimatch patterns
     * @return {Promise} Array containing filtered paths.
     */
    filter(paths, patterns = ['**', '!node_modules', '!.git', '!.json']) {
        return Promise.resolve(multimatch(paths, patterns));
    }

    /**
     * exclude files that match a given pattern.
     *
     * @param  {Array} paths         List of paths
     * @param  {Array}  [patterns=[]] List of patterns
     * @return {Promise}
     */
    exclude(paths, patterns = []) {

        if (!patterns || patterns.length === 0) {
            return Promise.resolve(paths);
        }

        if (typeof patterns === 'string') {
            patterns = [patterns];
        }

        /*
         * If we have a negative pattern
         * we need to ensure the first pattern
         * is a `**` match all.
         * Check for a pattern with a !
         * If found, then ensuer index 0 is **
         */
        // if(!patterns.includes('**')) {
        //     patterns.unshift('**');
        // }

        //TODO: ensure we only have it at the start?

        let matched = [];
        let excluded = multimatch(paths, patterns);

        paths.forEach(p => {
            if (excluded.includes(p)) return;
            matched.push(p);
        });

        return Promise.resolve(matched);
    }

    /**
     * Collect all plugins into an array.
     *
     * @param {Array} plugins list of plugin paths
     * @param {Object} options
     * @param {Object} options.directory Base directory for plugins
     */
    load(plugins = [], options = {}) {
        options = extend({}, DEFAULTS, options);

        if (plugins.length === 0) {
            this.logger.warn('PluginLoader: no plugins provided');
        }

        //TODO: This is not used!! If we use it things break
        // let basepath = options.basepath || this.basepath;

        if (options.plugins) {
            plugins = plugins.concat(options.plugins);
        }

        let baseDir = options.directory ? this.normalizePath(options.directory, this.basepath) : this.basepath;
        plugins = this.normalize(plugins, baseDir);

        this._paths = plugins;
        this._plugins = [];

        return new Promise(async(resolve, reject) => {

            for (let i = 0; i < plugins.length; i++) {
                let bean = plugins[i];

                if (!this.isValidBeanExtension(bean.path)) {
                    return this.logger.warn('Provided bean has invalid extension', bean.path);
                }

                bean.isLocal = true;

                try {

                    /**
                     * Check in order in which is more likely
                     * to be true.
                     */
                    if (await exists(bean.path)) {
                        bean.plugin = require(bean.path);
                    } else if (await exists(`${bean.path}.js`)) {
                        bean.plugin = require(`${bean.path}.js`);
                    } else {
                        bean.plugin = require(join(this.basepath, 'node_modules', bean.path));
                        bean.isLocal = false;
                    }
                } catch (e) {
                    let msg = 'Failed to require plugin "' + bean.id + '": ' + e.message;
                    this.logger.error(msg);

                    if (_isDevelopment()) {
                        this.logger.error(e.stack);
                    }
                    reject(new VError(e, msg));
                }
                //TODO: we could have a post require hook, to add meta to each plugin?
                // bean.priority = bean.plugin.priority === undefined ? 0 : bean.plugin.priority;
                // bean.dependencies = bean.plugin.dependencies === undefined ? [] : bean.plugin.dependencies;

                this._plugins.push(bean);
            }

            this.sort(this._plugins);

            resolve(this._plugins);
        });
    }

    /**
     * Applies `sortFilter` to the passed in
     * list of plugins.
     * You can set `sortFilter` using the config
     * object.
     * The deafult value will sort plugins on a
     * `priority` property.
     *
     * ```js
     * function _sortFilter(a, b) {
     *     function p(i){
     *         return i.priority === undefined ? 0 : i.priority;
     *     }
     *     return p(a) < p(b) ? -1 : 1;
     * }
     * ```
     *
     * Syncronous.
     * @param  {Array} plugins List of plugins.
     * @return {Array} List of ordered plugins.
     */
    sort(plugins) {
        return this.sortFilter(plugins);
    }

    /**
     * Provided a list of loaded plugins it
     * will mount them in the provided `context`.
     *
     * It uses `mountHandler` which will do the
     * actual work.
     *
     * You can override `mountHandler` using the
     * config object.
     *
     * @param {Array} plugin List of loaded plugins.
     * @param {Object} config Configuration object.
     * @param {Object} context Passed as argument to
     *                         `mountHandler`
     * @type {Object}
     */
    mount(plugin, config = {}, context = this.context) {

        config = extend({}, {
            mountHandler: this.mountHandler,
            afterMount: this.afterMount
        }, config);

        let plugins = plugin;

        let { mountHandler } = config;

        if (!Array.isArray(plugins)) plugins = [plugin];

        return new Promise((resolve, reject) => {
            try {
                plugins.map((plugin) => mountHandler(plugin, context, config));
            } catch (e) {
                if (_isDevelopment()) {
                    this.logger.error(e);
                }
                reject(new VError(e, 'Error running plugin: ' + plugin.id + '\n\n' + e.message + '\n\n' + e.stack));
            }

            config.afterMount(context, config);

            resolve(context);
        });
    }

    /**
     * Mounts a directory containing plugin defintion
     * files.
     *
     * It runs the following operations:
     *
     * - find
     * - filter
     * - exclude
     * - load
     * - mount
     *
     * If `options.exclude` is an array with
     * `multimatch` patterns of files to exclude.
     *
     * @param  {String} directory              Path to directory
     * @param  {Object} [options={}]
     * @param  {Object} [context=this.context]
     * @return {Promise}
     */
    mountDirectory(directory, options = {}, context = this.context) {
        if (!options.directory) options.directory = directory;
        return this.find(directory)
            .then(this.filter)
            .then(plugins => this.exclude(plugins, options.exclude))
            .then(plugins => this.load(plugins, options))
            .then(plugins => this.mount(plugins, options, context));
    }

    mountList(list, options = {}, context = this.context) {
        return this.load(list, options)
            .then(plugins => this.mount(plugins, options, context));
    }

    /**
     * Check if the path points to a valid
     * extension we can require.
     *
     * @param {String} path
     */
    isValidBeanExtension(path = '') {
        let ext = extname(path);
        /*
         * Allow files without extension
         */
        if (!ext) return true;

        /*
         * If file has extension only
         * allow js files.
         */
        return ext === EXT_JS;
    }
}

PluginLoader.DEFAULTS = DEFAULTS;

PluginLoader.normalize = _normalize;

/**
 * Expose PluginLoader
 */
module.exports = PluginLoader;<|endoftext|>


<commit_before>/**
 * Socket.IO client
 *
 * @author Guillermo Rauch <guillermo@rosepad.com>
 * @license The MIT license.
 * @copyright Copyright (c) 2009 RosePad <dev@rosepad.com>
 */

this.io = {
	version: '0.1.8',

	setPath: function(path){
		this.path = /\/$/.test(path) ? path : path + '/';

		// this is temporary until we get a fix for injecting Flash WebSocket javascript files dynamically,
		// as io.js shouldn't be aware of specific transports.
		if ('WebSocket' in window){
			WebSocket.__swfLocation = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
		}
	}
};

if ('jQuery' in this) jQuery.io = this.io;<commit_msg>Version update (0.2.0)<commit_after>/**
 * Socket.IO client
 *
 * @author Guillermo Rauch <guillermo@rosepad.com>
 * @license The MIT license.
 * @copyright Copyright (c) 2009 RosePad <dev@rosepad.com>
 */

this.io = {
	version: '0.2.0',

	setPath: function(path){
		this.path = /\/$/.test(path) ? path : path + '/';

		// this is temporary until we get a fix for injecting Flash WebSocket javascript files dynamically,
		// as io.js shouldn't be aware of specific transports.
		if ('WebSocket' in window){
			WebSocket.__swfLocation = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
		}
	}
};

if ('jQuery' in this) jQuery.io = this.io;<|endoftext|>


<commit_before>
var checkers = require('./checkers'),
    utils = require('./utils');

function parseIs(data, filters) {

	if (typeof filters == 'function')
	    return filters(data) == true;

	var
		result = false,
		isNegate = false,
		arrFilters = String(filters)
				    .split(/([a-z!]+(?:\([a-z0-9\-+\., ]+?\)|)?)/i)
				    .filter(function (element) {
					    return $.trim(element) !== '';
				    });

	arrFilters.forEach(function (v) {
		v = v.trim();
		isNegate = false;

		if (v.charAt(0) == '!') {
			isNegate = true;
			v = v.substr(1);
		}

		switch (v) {
			case 'function':
			case 'array':
			case 'object':
			case 'date':
			case 'boolean':
			case 'int':
			case 'number':
			case 'positive':
			case 'float':
			case 'alphaNum':
			case 'email':
			case 'url':
			case 'ip':
			case 'json':
				result = checkers['is' + utils.upperCaseFirst(v)](data);
				break;
			default:
				if (/^range/i.test(v) || /^length/i.test(v) || /^in/i.test(v) || /^year/i.test(v)) result=$.isYear(data,v);
				result = checkers['is' + utils.upperCaseFirst(v)](data);
				break;
		}

		if (isNegate) result = !result;

		return result === true;
	});

	return result;
};

function is(data, filters) {
    if (!(this instanceof is))
        return new is(data, filters);

    if (typeof o != 'undefined')
        return parseIs(data, filters);

    return this;
}

is.prototype = utils;

module.exports = is;
<commit_msg>Update checkers call.<commit_after>
var checkers = require('./checkers'),
    utils = require('./utils');

function parseIs(data, filters) {

	if (typeof filters == 'function')
	    return filters(data) == true;

	var
		result = false,
		isNegate = false,
		arrFilters = String(filters)
				    .split(/([a-z!]+(?:\([a-z0-9\-+\., ]+?\)|)?)/i)
				    .filter(function (element) {
					    return $.trim(element) !== '';
				    });

	arrFilters.forEach(function (v) {
		v = v.trim();
		isNegate = false;

		if (v.charAt(0) == '!') {
			isNegate = true;
			v = v.substr(1);
		}

		switch (v) {
			case 'function':
			case 'array':
			case 'object':
			case 'date':
			case 'boolean':
			case 'int':
			case 'number':
			case 'positive':
			case 'float':
			case 'alphaNum':
			case 'email':
			case 'url':
			case 'ip':
			case 'json':
				result = checkers['is' + utils.upperCaseFirst(v)](data);
				break;
			default:
				if (/^range/i.test(v) || /^length/i.test(v) || /^in/i.test(v) || /^year/i.test(v))
				    result=$.isYear(data,v);
				    result = checkers['is' + utils.upperCaseFirst(v)](data);
				break;
		}

		if (isNegate) result = !result;

		return result === true;
	});

	return result;
};

function is(data, filters) {
    if (!(this instanceof is))
        return new is(data, filters);

    if (typeof o != 'undefined')
        return parseIs(data, filters);

    return this;
}

is.prototype = utils;

module.exports = is;
<|endoftext|>


<commit_before>
exports.array = function sanitizeArray(array, whitelist) {
    var sanitized = [],
        whiteValue;
    array.forEach(function sanitizeArrayForEach(key) {
        whiteValue = sanitizeScalar(key, whitelist[key]);
        if (whiteValue) {
            sanitized.push(whiteValue);
        }
    });
    return sanitized;
}

exports.object = function sanitizeObject(object, whitelist) {
    var sanitized = {},
        whiteValue,
        key;
    for(key in object) {
        if (object.hasOwnProperty(key) && whitelist[key]) {
            whiteValue = sanitizeScalar(key, whitelist[key]);
            if (whiteValue) {
                sanitized[whiteValue] = object[key];
            }
        }
    }
    return sanitized;
}

exports.sort = function sanitizeSort(sort, whitelist) {
    var sanitized = [],
        whiteValue;
    sort.forEach(function sanitizeArrayForEach(sortRule) {
        whiteValue = sanitizeScalar(sortRule.attr, whitelist[sortRule.attr]);
        if (whiteValue) {
            sanitized.push({ attr: whiteValue, asc: sortRule.asc });
        }
    });
    return sanitized;
}

exports.scalar = sanitizeScalar = function sanitizeScalar(value, whiteValue) {
    if (!whiteValue) {
        return false;
    }
    var whiteType = typeof whiteValue;
    if (whiteType === 'string') {
        return whiteValue;
    }
    if (whiteType === 'function') {
        return checkWhitelist(value, whiteValue(value));
    }
    return value;
}
<commit_msg>Add sanitize.scape(str)<commit_after>
exports.escape = function escape(str) {
    // thanks:
    // https://github.com/felixge/node-mysql/blob/1d4cb893a9906890554016c398dccb4271e66808/lib/protocol/SqlString.js#L46-L56
    // Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
    // MIT License
    return str.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
        switch(s) {
            case "\0": return "\\0";
            case "\n": return "\\n";
            case "\r": return "\\r";
            case "\b": return "\\b";
            case "\t": return "\\t";
            case "\x1a": return "\\Z";
            default: return "\\" + s;
        }
    });
}

exports.array = function sanitizeArray(array, whitelist) {
    var sanitized = [],
        whiteValue;
    array.forEach(function sanitizeArrayForEach(key) {
        whiteValue = sanitizeScalar(key, whitelist[key]);
        if (whiteValue) {
            sanitized.push(whiteValue);
        }
    });
    return sanitized;
}

exports.object = function sanitizeObject(object, whitelist) {
    var sanitized = {},
        whiteValue,
        key;
    for(key in object) {
        if (object.hasOwnProperty(key) && whitelist[key]) {
            whiteValue = sanitizeScalar(key, whitelist[key]);
            if (whiteValue) {
                sanitized[whiteValue] = object[key];
            }
        }
    }
    return sanitized;
}

exports.sort = function sanitizeSort(sort, whitelist) {
    var sanitized = [],
        whiteValue;
    sort.forEach(function sanitizeArrayForEach(sortRule) {
        whiteValue = sanitizeScalar(sortRule.attr, whitelist[sortRule.attr]);
        if (whiteValue) {
            sanitized.push({ attr: whiteValue, asc: sortRule.asc });
        }
    });
    return sanitized;
}

exports.scalar = sanitizeScalar = function sanitizeScalar(value, whiteValue) {
    if (!whiteValue) {
        return false;
    }
    var whiteType = typeof whiteValue;
    if (whiteType === 'string') {
        return whiteValue;
    }
    if (whiteType === 'function') {
        return checkWhitelist(value, whiteValue(value));
    }
    return value;
}
<|endoftext|>


<commit_before>"use strict";
var inherits = require('util').inherits;
var Unit = require('units').Unit;

var Settings = function () {
	this.core = null;
};
inherits(Settings, Unit);

Settings.prototype.unitIsInitRequired = true;

Settings.prototype.unitInit = function (units) {
	this.prepare();
};

Settings.prototype.prepare = function () {
	this.init();
	this.applyLocal();
};

Settings.prototype.init = function () {
	var authMaxAge = 2 * 7 * 24 * 60 * 60 * 1000; // 2 weeks in ms

	// default values for all settings understood by apis
	this.core = {
		debug: false,

		unhandled: {
			disabled: false
		},

		daemon: {
			start: {
				exec: require.main.filename,
				args: ['daemon'],
				stdout: 'var/log/app.log',
				stderr: 'var/log/app.log'
			},
			pidFile: 'var/run/app.pid',
			exitCheckInterval: 200
		},

		cluster: {
			disabled: false,
			numberOfWorkers: null, // cpus().length
			master: {
				exec: require.main.filename,
				args: null,
				silent: null
			},
			checks : {
				lazy: {
					interval: 40 * 1000,
					maxTime: 30 * 1000
				},
				zombie: {
					interval: 40 * 1000,
					maxTime: 30 * 1000
				}
			}
		},

		logging: {
			rootLogger: 'root',

			loggers: {
				root: {
					logLevel: 'error',
					engine: {
						unit: 'core.logging.engines.console',
						settings: {}
					},
					sendTo: []
				},
				console: { // useful for testing, etc.
					logLevel: 'error',
					engine: {
						unit: 'core.logging.engines.console',
						settings: {}
					},
					sendTo: []
				},
				uncaught: {
				},
				cluster: {
				},
				ctx: {
				},
				sockjs: {
				}
			}
		},

		prefix: null, // example: '/someprefix'

		web: {
			listen: {
				port: 3000,
				address: 'localhost'
			},

			headers: {
				nameMethod: 'X-Method'
			},

			bodyMaxSize: null, // bytes, null for no limit

			crossDomainWorkaround: {
				key: 'xdomain',
				disabled: false,
				jsonp: {
					disabled: false,
					callbackKey: 'callback'
				},
				frame: {
					disabled: false
				}
			},

			cors: {
				disabled: false,
				allowCredentials: true,
				maxAge: 2 * 24 * 60 * 60, // 2 days in s

				// list of allowed origins, null to allow any
				// must contain string and/or RegExp objects
				// usefull to prevent browser-based distributed attacks
				//
				// NOTE origins are converted to lowercase before check,
				// for RegExp objects don't forget starting ^ and trailing $,
				// as well as escaping for '.', example:
				// /^http:\/\/example\.com$/
				restrictToOrigins: null
			}
		},

		handlers: {
			data: {
				needValidatorInfo: false,
				logWithData: false
			},

			result: {
				provideStackTrace: false, // true, false, 'debug'
				validateResult: 'debug', // true, false, 'debug'
				logWithData: false
			}
		},

		socket: {
			disabled: false,
			prefix: '/socket'
		},

		auth: {
			maxAge: authMaxAge,
			postRevokationTrustDelay: 5 * 60 * 1000, // 5 minites in ms
			headers: {
				name: 'X-Auth',
				nameExpected: 'X-AuthExpected'
			},
			cookies: {
				name: 'auth',
				nameLimited: 'authTwin',
				useLimited: true,
				forceNonHttp: false, // don't force exposing cookie data to JS
				secure: false,
				domain: null,
				path: '/'
			},
			renewal: {
				interval: Math.round(authMaxAge / 2),
				headers: {
					name: 'X-AuthRenewal',
					nameIssued: 'X-AuthRenewalIssued',
					nameMaxAge: 'X-AuthRenewalMaxAge'
				}
			}
		},

		stat: {
			// for mechanics/socket/stat
			socket: {
				frameSize: null, // 10000
				per: null, // 1000
				old: null // 2 * 60 * 1000
			}
		}
	};
};

Settings.prototype.getSettingsLocal = function () {
	return null;
};

Settings.prototype.applyLocal = function () {
	var settingsLocal = this.getSettingsLocal();
	if (settingsLocal) {
		settingsLocal.update(this);
	}
};

module.exports = Settings;
<commit_msg>fixed wrong uncaught settings key<commit_after>"use strict";
var inherits = require('util').inherits;
var Unit = require('units').Unit;

var Settings = function () {
	this.core = null;
};
inherits(Settings, Unit);

Settings.prototype.unitIsInitRequired = true;

Settings.prototype.unitInit = function (units) {
	this.prepare();
};

Settings.prototype.prepare = function () {
	this.init();
	this.applyLocal();
};

Settings.prototype.init = function () {
	var authMaxAge = 2 * 7 * 24 * 60 * 60 * 1000; // 2 weeks in ms

	// default values for all settings understood by apis
	this.core = {
		debug: false,

		uncaught: {
			disabled: false
		},

		daemon: {
			start: {
				exec: require.main.filename,
				args: ['daemon'],
				stdout: 'var/log/app.log',
				stderr: 'var/log/app.log'
			},
			pidFile: 'var/run/app.pid',
			exitCheckInterval: 200
		},

		cluster: {
			disabled: false,
			numberOfWorkers: null, // cpus().length
			master: {
				exec: require.main.filename,
				args: null,
				silent: null
			},
			checks : {
				lazy: {
					interval: 40 * 1000,
					maxTime: 30 * 1000
				},
				zombie: {
					interval: 40 * 1000,
					maxTime: 30 * 1000
				}
			}
		},

		logging: {
			rootLogger: 'root',

			loggers: {
				root: {
					logLevel: 'error',
					engine: {
						unit: 'core.logging.engines.console',
						settings: {}
					},
					sendTo: []
				},
				console: { // useful for testing, etc.
					logLevel: 'error',
					engine: {
						unit: 'core.logging.engines.console',
						settings: {}
					},
					sendTo: []
				},
				uncaught: {
				},
				cluster: {
				},
				ctx: {
				},
				sockjs: {
				}
			}
		},

		prefix: null, // example: '/someprefix'

		web: {
			listen: {
				port: 3000,
				address: 'localhost'
			},

			headers: {
				nameMethod: 'X-Method'
			},

			bodyMaxSize: null, // bytes, null for no limit

			crossDomainWorkaround: {
				key: 'xdomain',
				disabled: false,
				jsonp: {
					disabled: false,
					callbackKey: 'callback'
				},
				frame: {
					disabled: false
				}
			},

			cors: {
				disabled: false,
				allowCredentials: true,
				maxAge: 2 * 24 * 60 * 60, // 2 days in s

				// list of allowed origins, null to allow any
				// must contain string and/or RegExp objects
				// usefull to prevent browser-based distributed attacks
				//
				// NOTE origins are converted to lowercase before check,
				// for RegExp objects don't forget starting ^ and trailing $,
				// as well as escaping for '.', example:
				// /^http:\/\/example\.com$/
				restrictToOrigins: null
			}
		},

		handlers: {
			data: {
				needValidatorInfo: false,
				logWithData: false
			},

			result: {
				provideStackTrace: false, // true, false, 'debug'
				validateResult: 'debug', // true, false, 'debug'
				logWithData: false
			}
		},

		socket: {
			disabled: false,
			prefix: '/socket'
		},

		auth: {
			maxAge: authMaxAge,
			postRevokationTrustDelay: 5 * 60 * 1000, // 5 minites in ms
			headers: {
				name: 'X-Auth',
				nameExpected: 'X-AuthExpected'
			},
			cookies: {
				name: 'auth',
				nameLimited: 'authTwin',
				useLimited: true,
				forceNonHttp: false, // don't force exposing cookie data to JS
				secure: false,
				domain: null,
				path: '/'
			},
			renewal: {
				interval: Math.round(authMaxAge / 2),
				headers: {
					name: 'X-AuthRenewal',
					nameIssued: 'X-AuthRenewalIssued',
					nameMaxAge: 'X-AuthRenewalMaxAge'
				}
			}
		},

		stat: {
			// for mechanics/socket/stat
			socket: {
				frameSize: null, // 10000
				per: null, // 1000
				old: null // 2 * 60 * 1000
			}
		}
	};
};

Settings.prototype.getSettingsLocal = function () {
	return null;
};

Settings.prototype.applyLocal = function () {
	var settingsLocal = this.getSettingsLocal();
	if (settingsLocal) {
		settingsLocal.update(this);
	}
};

module.exports = Settings;
<|endoftext|>


<commit_before>import { clamp, is_nil } from './utils/index';
import calc from './utils/calc';

const { cos, sin, sqrt, pow, PI } = Math;
const DEG = PI / 180;

function polygon(option, fn) {
  if (typeof arguments[0] == 'function') {
    fn = option;
    option = {};
  }

  if (!fn) {
    fn = t => [ cos(t), sin(t) ];
  }

  let split = option.split || 120;
  let scale = option.scale || 1;
  let start = DEG * (option.start || 0);
  let deg = option.deg ? (option.deg * DEG) : (PI / (split / 2));
  let points = [];

  for (let i = 0; i < split; ++i) {
    let t = start + deg * i;
    let [x, y] = fn(t);
    points.push(
      ((x * 50 * scale) + 50 + '% ') +
      ((y * 50 * scale) + 50 + '%')
    );
  }

  option.type = option['fill-rule'] || option.type;

  return option.type
    ? `polygon(${ option.type }, ${ points.join(',') })`
    : `polygon(${ points.join(',') })`;
}

function rotate(x, y, deg) {
  let rad = DEG * deg;
  return [
    x * cos(rad) - y * sin(rad),
    y * cos(rad) + x * sin(rad)
  ];
}

const shapes =  {

  circle() {
    return 'circle(49%)';
  },

  triangle() {
    return polygon({ split: 3, start: -90 }, t => [
      cos(t) * 1.1,
      sin(t) * 1.1 + .2
    ]);
  },

  rhombus() {
    return polygon({ split: 4 });
  },

  pentagon() {
    return polygon({ split: 5, start: 54 });
  },

  hexgon() {
    return polygon({ split: 6, start: 30 });
  },

  hexagon() {
    return polygon({ split: 6, start: 30 });
  },

  heptagon() {
    return polygon({ split: 7, start: -90 });
  },

  octagon() {
    return polygon({ split: 8, start: 22.5 });
  },

  star() {
    return polygon({ split: 5, start: 54, deg: 144 });
  },

  diamond() {
    return 'polygon(50% 5%, 80% 50%, 50% 95%, 20% 50%)';
  },

  cross() {
    return `polygon(
      5% 35%,  35% 35%, 35% 5%,  65% 5%,
      65% 35%, 95% 35%, 95% 65%, 65% 65%,
      65% 95%, 35% 95%, 35% 65%, 5% 65%
    )`;
  },

  clover(k = 3) {
    k = clamp(k, 3, 5);
    if (k == 4) k = 2;
    return polygon({ split: 240 }, t => {
      let x = cos(k * t) * cos(t);
      let y = cos(k * t) * sin(t);
      if (k == 3) x -= .2;
      if (k == 2) {
        x /= 1.1;
        y /= 1.1;
      }
      return [x, y];
    });
  },

  hypocycloid(k = 3) {
    k = clamp(k, 3, 6);
    let m = 1 - k;
    return polygon({ scale: 1 / k  }, t => {
      let x = m * cos(t) + cos(m * (t - PI));
      let y = m * sin(t) + sin(m * (t - PI));
      if (k == 3) {
        x = x * 1.1 - .6;
        y = y * 1.1
      }
      return [x, y];
    });
  },

  astroid() {
    return shapes.hypocycloid(4);
  },

  infinity() {
    return polygon(t => {
      let a = .7 * sqrt(2) * cos(t);
      let b = (pow(sin(t), 2) + 1);
      return [
        a / b,
        a * sin(t) / b
      ]
    });
  },

  heart() {
    return polygon(t => {
      let x = .75 * pow(sin(t), 3);
      let y =
          cos(1 * t) * (13 / 18)
        - cos(2 * t) * (5 / 18)
        - cos(3 * t) / 18
        - cos(4 * t) / 18;
      return rotate(
        x * 1.2,
        (y + .2) * 1.1,
        180
      );
    });
  },

  bean() {
    return polygon(t => {
      let [a, b] = [pow(sin(t), 3), pow(cos(t), 3)];
      return rotate(
        (a + b) * cos(t) * 1.3 - .45,
        (a + b) * sin(t) * 1.3 - .45,
        -90
      );
    });
  },

  bicorn() {
    return polygon(t => rotate(
      cos(t),
      pow(sin(t), 2) / (2 + sin(t)) - .5,
      180
    ));
  },

  drop() {
    return polygon(t => rotate(
      sin(t),
      (1 + sin(t)) * cos(t) / 1.4,
      90
    ));
  },

  pear() {
    return polygon(t => [
      sin(t),
      (1 + sin(t)) * cos(t) / 1.4
    ]);
  },

  fish() {
    return polygon(t => [
      cos(t) - pow(sin(t), 2) / sqrt(2),
      sin(2 * t) / 2
    ]);
  },

  whale() {
    return polygon({ split: 240 }, t => {
      let r = 3.4 * (pow(sin(t), 2) - .5) * cos(t);
      return rotate(
        cos(t) * r + .75,
        sin(t) * r * 1.2,
        180
      );
    });
  },

  bud(n = 3) {
    n = clamp(n, 3, 10);
    return polygon({ split: 240 }, t => [
      ((1 + .2 * cos(n * t)) * cos(t)) * .8,
      ((1 + .2 * cos(n * t)) * sin(t)) * .8
    ]);
  },

  alien(...args) {
    let [a = 1, b = 1, c = 1, d = 1, e = 1]
      = args.map(n => clamp(n, 1, 9));
    return polygon({ split: 480, type: 'evenodd' }, t => [
      (cos(t * a) + cos(t * c) + cos(t * e)) * .31,
      (sin(t * b) + sin(t * d) + sin(t)) * .31
    ]);
  }
}

function is_empty(value) {
  return is_nil(value) || value === '';
}

function custom_shape(props) {
  let option = Object.assign({}, props, {
    split: clamp(parseInt(props.split) || 0, 3, 2400),
    start: 0
  });

  let px = is_empty(props.x) ? 'cos(t)' : props.x;
  let py = is_empty(props.y) ? 'sin(t)' : props.y;
  let pr = is_empty(props.r) ? ''       : props.r;

  return polygon(option, t => {
    let context = Object.assign({}, props, { t });
    let x = calc(px, context);
    let y = calc(py, context);
    if (pr) {
      let r = calc(pr, context);
      x = r * Math.cos(t);
      y = -r * Math.sin(t);
    }
    if (props.rotate) {
      return rotate(x, y, parseInt(props.rotate) || 0);
    }
    return [x, y];
  });
}

export {
  shapes,
  custom_shape
}
<commit_msg>Validate user input fill-rule value<commit_after>import { clamp, is_nil } from './utils/index';
import calc from './utils/calc';

const { cos, sin, sqrt, pow, PI } = Math;
const DEG = PI / 180;

function polygon(option, fn) {
  if (typeof arguments[0] == 'function') {
    fn = option;
    option = {};
  }

  if (!fn) {
    fn = t => [ cos(t), sin(t) ];
  }

  let split = option.split || 120;
  let scale = option.scale || 1;
  let start = DEG * (option.start || 0);
  let deg = option.deg ? (option.deg * DEG) : (PI / (split / 2));
  let points = [];

  for (let i = 0; i < split; ++i) {
    let t = start + deg * i;
    let [x, y] = fn(t);
    points.push(
      ((x * 50 * scale) + 50 + '% ') +
      ((y * 50 * scale) + 50 + '%')
    );
  }

  option.type = read_fillrule(option['fill-rule']);

  return option.type
    ? `polygon(${ option.type }, ${ points.join(',') })`
    : `polygon(${ points.join(',') })`;
}

function read_fillrule(value) {
  let enum = ['nonzero', 'evenodd'];
  if (!enum.includes(value)) return '';
  return value;
}

function rotate(x, y, deg) {
  let rad = DEG * deg;
  return [
    x * cos(rad) - y * sin(rad),
    y * cos(rad) + x * sin(rad)
  ];
}

const shapes =  {

  circle() {
    return 'circle(49%)';
  },

  triangle() {
    return polygon({ split: 3, start: -90 }, t => [
      cos(t) * 1.1,
      sin(t) * 1.1 + .2
    ]);
  },

  rhombus() {
    return polygon({ split: 4 });
  },

  pentagon() {
    return polygon({ split: 5, start: 54 });
  },

  hexgon() {
    return polygon({ split: 6, start: 30 });
  },

  hexagon() {
    return polygon({ split: 6, start: 30 });
  },

  heptagon() {
    return polygon({ split: 7, start: -90 });
  },

  octagon() {
    return polygon({ split: 8, start: 22.5 });
  },

  star() {
    return polygon({ split: 5, start: 54, deg: 144 });
  },

  diamond() {
    return 'polygon(50% 5%, 80% 50%, 50% 95%, 20% 50%)';
  },

  cross() {
    return `polygon(
      5% 35%,  35% 35%, 35% 5%,  65% 5%,
      65% 35%, 95% 35%, 95% 65%, 65% 65%,
      65% 95%, 35% 95%, 35% 65%, 5% 65%
    )`;
  },

  clover(k = 3) {
    k = clamp(k, 3, 5);
    if (k == 4) k = 2;
    return polygon({ split: 240 }, t => {
      let x = cos(k * t) * cos(t);
      let y = cos(k * t) * sin(t);
      if (k == 3) x -= .2;
      if (k == 2) {
        x /= 1.1;
        y /= 1.1;
      }
      return [x, y];
    });
  },

  hypocycloid(k = 3) {
    k = clamp(k, 3, 6);
    let m = 1 - k;
    return polygon({ scale: 1 / k  }, t => {
      let x = m * cos(t) + cos(m * (t - PI));
      let y = m * sin(t) + sin(m * (t - PI));
      if (k == 3) {
        x = x * 1.1 - .6;
        y = y * 1.1
      }
      return [x, y];
    });
  },

  astroid() {
    return shapes.hypocycloid(4);
  },

  infinity() {
    return polygon(t => {
      let a = .7 * sqrt(2) * cos(t);
      let b = (pow(sin(t), 2) + 1);
      return [
        a / b,
        a * sin(t) / b
      ]
    });
  },

  heart() {
    return polygon(t => {
      let x = .75 * pow(sin(t), 3);
      let y =
          cos(1 * t) * (13 / 18)
        - cos(2 * t) * (5 / 18)
        - cos(3 * t) / 18
        - cos(4 * t) / 18;
      return rotate(
        x * 1.2,
        (y + .2) * 1.1,
        180
      );
    });
  },

  bean() {
    return polygon(t => {
      let [a, b] = [pow(sin(t), 3), pow(cos(t), 3)];
      return rotate(
        (a + b) * cos(t) * 1.3 - .45,
        (a + b) * sin(t) * 1.3 - .45,
        -90
      );
    });
  },

  bicorn() {
    return polygon(t => rotate(
      cos(t),
      pow(sin(t), 2) / (2 + sin(t)) - .5,
      180
    ));
  },

  drop() {
    return polygon(t => rotate(
      sin(t),
      (1 + sin(t)) * cos(t) / 1.4,
      90
    ));
  },

  pear() {
    return polygon(t => [
      sin(t),
      (1 + sin(t)) * cos(t) / 1.4
    ]);
  },

  fish() {
    return polygon(t => [
      cos(t) - pow(sin(t), 2) / sqrt(2),
      sin(2 * t) / 2
    ]);
  },

  whale() {
    return polygon({ split: 240 }, t => {
      let r = 3.4 * (pow(sin(t), 2) - .5) * cos(t);
      return rotate(
        cos(t) * r + .75,
        sin(t) * r * 1.2,
        180
      );
    });
  },

  bud(n = 3) {
    n = clamp(n, 3, 10);
    return polygon({ split: 240 }, t => [
      ((1 + .2 * cos(n * t)) * cos(t)) * .8,
      ((1 + .2 * cos(n * t)) * sin(t)) * .8
    ]);
  },

  alien(...args) {
    let [a = 1, b = 1, c = 1, d = 1, e = 1]
      = args.map(n => clamp(n, 1, 9));
    return polygon({ split: 480, type: 'evenodd' }, t => [
      (cos(t * a) + cos(t * c) + cos(t * e)) * .31,
      (sin(t * b) + sin(t * d) + sin(t)) * .31
    ]);
  }
}

function is_empty(value) {
  return is_nil(value) || value === '';
}

function custom_shape(props) {
  let option = Object.assign({}, props, {
    split: clamp(parseInt(props.split) || 0, 3, 2400),
    start: 0
  });

  let px = is_empty(props.x) ? 'cos(t)' : props.x;
  let py = is_empty(props.y) ? 'sin(t)' : props.y;
  let pr = is_empty(props.r) ? ''       : props.r;

  return polygon(option, t => {
    let context = Object.assign({}, props, { t });
    let x = calc(px, context);
    let y = calc(py, context);
    if (pr) {
      let r = calc(pr, context);
      x = r * Math.cos(t);
      y = -r * Math.sin(t);
    }
    if (props.rotate) {
      return rotate(x, y, parseInt(props.rotate) || 0);
    }
    return [x, y];
  });
}

export {
  shapes,
  custom_shape
}
<|endoftext|>


<commit_before>require('colors')
const str = require('./strings')
const config = require('../bbpr.config')
const hg = require('./hg')
const open = require('open')
const shell = require('shelljs')

function sendPullRequest (postRequest) => {
  console.log('\nSending pull request to BitBucket remote repository...'.bold)
  shell.exec(postRequest, (code, stdout) => {
    const statusCode = stdout

    // on success
    if (/201/.test(statusCode)) {
      console.log('\nPull request created successfully. Redirecting to BitBucket...'.bold)
      setTimeout(() => {
        open(`https://bitbucket.org/${config.organization.name}/${hg.getRepositoryName()}/pull-requests/`)
      }, 2000)
    }

    // on fail
    else {
      console.log(`\nSomething wrong happened with your request to BitBucket. You received a ${statusCode.trim()}.\n`.red)
    }
  })
}

function buildPullRequest (pullRequestTitle, pullRequestDescription, destinationBranch, allReviewers, usernameBitBucket, passwordBitBucket) => {
  const pullRequestJSON = getPullRequestJSON(pullRequestTitle, pullRequestDescription, destinationBranch, allReviewers)
  const userNamePassword = `${usernameBitBucket}:${passwordBitBucket}`
  const postRequestUrl = `${str.bitBucketAPIUrl}/${config.organization.name}/${hg.getRepositoryName()}/pullrequests`
  const postRequest = `${str.curlOptions} '${str.contentTypeJSON}' --user ${userNamePassword} ${postRequestUrl} -d '${pullRequestJSON}'`

  return postRequest
}

function getPullRequestJSON (title, description, destinationBranch, allReviewers) {
  return JSON.stringify({
    'title': title || '',
    'description': description || '',
    'source': {
      'branch': {
        'name': hg.getCurrentBranchName()
      },
      'repository': {
        'full_name': `${config.organization.name}/${hg.getRepositoryName()}`
      }
    },
    'destination': {
      'branch': {
        'name': destinationBranch || 'default'
      }
    },
    'reviewers': allReviewers,
    'close_source_branch': config.branches.source.close
  })
}

module.exports = {
  buildPullRequest,
  sendPullRequest
}
<commit_msg>fix function<commit_after>require('colors')
const str = require('./strings')
const config = require('../bbpr.config')
const hg = require('./hg')
const open = require('open')
const shell = require('shelljs')

function sendPullRequest (postRequest) {
  console.log('\nSending pull request to BitBucket remote repository...'.bold)
  shell.exec(postRequest, (code, stdout) => {
    const statusCode = stdout

    // on success
    if (/201/.test(statusCode)) {
      console.log('\nPull request created successfully. Redirecting to BitBucket...'.bold)
      setTimeout(() => {
        open(`https://bitbucket.org/${config.organization.name}/${hg.getRepositoryName()}/pull-requests/`)
      }, 2000)
    }

    // on fail
    else {
      console.log(`\nSomething wrong happened with your request to BitBucket. You received a ${statusCode.trim()}.\n`.red)
    }
  })
}

function buildPullRequest (pullRequestTitle, pullRequestDescription, destinationBranch, allReviewers, usernameBitBucket, passwordBitBucket) => {
  const pullRequestJSON = getPullRequestJSON(pullRequestTitle, pullRequestDescription, destinationBranch, allReviewers)
  const userNamePassword = `${usernameBitBucket}:${passwordBitBucket}`
  const postRequestUrl = `${str.bitBucketAPIUrl}/${config.organization.name}/${hg.getRepositoryName()}/pullrequests`
  const postRequest = `${str.curlOptions} '${str.contentTypeJSON}' --user ${userNamePassword} ${postRequestUrl} -d '${pullRequestJSON}'`

  return postRequest
}

function getPullRequestJSON (title, description, destinationBranch, allReviewers) {
  return JSON.stringify({
    'title': title || '',
    'description': description || '',
    'source': {
      'branch': {
        'name': hg.getCurrentBranchName()
      },
      'repository': {
        'full_name': `${config.organization.name}/${hg.getRepositoryName()}`
      }
    },
    'destination': {
      'branch': {
        'name': destinationBranch || 'default'
      }
    },
    'reviewers': allReviewers,
    'close_source_branch': config.branches.source.close
  })
}

module.exports = {
  buildPullRequest,
  sendPullRequest
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var getObject = require('getobject');
var base = require('./base');

var sub = base.sub;

var RULES = {
	REGEX_ARRAY_INTERNAL_SPACE: /[^,]*?,((?! )| {2,})[^,]+?/g,
	REGEX_ARRAY_SURROUNDING_SPACE: /\[\s|\s\]/g,

	REGEX_AUI_SCRIPT: /<(aui:)?script(.*?)>([\s\S]*?)<\/\1script>/,

	REGEX_BRACE_CLOSING: /\}\s*?$/,
	REGEX_BRACE_OPENING: /\{\s*?$/,

	REGEX_COMMA_LEADING: /^((?:\[|\{)\s*),/,
	REGEX_COMMA_TRAILING: /,(\s*(?:\]|\}))$/,

	REGEX_COMMENT: /\/(\/|\*).*/g,

	REGEX_CSS_COMMA_END: /,\s*?$/,

	REGEX_DIGITS: /\d+/,

	REGEX_EXT_CSS: /\.(s)?css$/,
	REGEX_EXT_HTML: /\.(jsp.?|html|vm|ftl|tpl|tmpl)$/,
	REGEX_EXT_JS: /\.js$/,

	REGEX_HEX: /#[0-9A-Fa-f]{3,6}\b/,
	REGEX_HEX_REDUNDANT: /#([0-9A-Fa-f])\1([0-9A-Fa-f])\2([0-9A-Fa-f])\3/,

	REGEX_LANG_EMPTYFN: /(^|(A\.)?(Lang\.)?)emptyFn(True|False)?/,

	REGEX_LEADING_INCLUDE: /^@include /,
	REGEX_LEADING_SPACE: /^\s+/,

	REGEX_PROP_KEY: /^\s*(?:@include\s)?([^:]+)(?:)/,
	REGEX_PROPERTY: /^\t*([^:]+:|@include\s)[^;]+;$/,

	REGEX_REGEX: /\/.*\/([gim]{1,3})?/g,

	REGEX_SCRIPTLET_STUB: new RegExp('^\\s*' + base.jspLintStubs.scriptlet + '$'),

	REGEX_SERVICE_PROPS: /(^@)|((.*?) = (.*?))/,
	REGEX_SINGLE_QUOTES: /'[^']*'/g,

	REGEX_STUBS: new RegExp('^_*(' + Object.keys(base.stubs).join('|') + ')_*'),

	REGEX_VAR_IS: /^_?is[A-Z]/,

	REPLACE_REGEX_REDUNDANT: '#$1$2$3',

	common: require('./engine_rules/common'),
	css: require('./engine_rules/css'),

	html: {},

	htmlJS: require('./engine_rules/html_js'),
	js: require('./engine_rules/js')
};

var re = function(rules) {
	_.defaults(this, rules);
};

re.prototype.getValue = getObject.get;

re.prototype.getWarning = function(lineNum, item, result, rule, context) {
	var warning;

	var message = rule.message || this.message;

	if (rule.message === false) {
		message = false;
	}

	if (_.isString(message)) {
		warning = this.message(message, lineNum, item, result, rule, context);
	}
	else if (_.isFunction(message)) {
		warning = message.call(this, lineNum, item, result, rule, context);
	}

	return warning;
};

re.prototype.hasExtraNewLines = function(item, index, collection, logger) {
	var extraNewLines = false;

	if (item === '') {
		extraNewLines = (index === 0 && collection.length > 1) || collection[index - 1] === '';
	}

	if (extraNewLines && logger) {
		logger(index + 1, 'Extra new line');
	}

	return extraNewLines;
};

re.prototype.hasHex = function(item) {
	var match = item.match(this.REGEX_HEX);

	return match && match[0];
};

re.prototype.hasProperty = function(item) {
	return this.REGEX_PROPERTY.test(item);
};

re.prototype.isValidRule = function(ruleName, rule, context) {
	return (ruleName !== 'IGNORE' && ruleName.indexOf('_') !== 0) &&
			(rule.ignore !== 'node' || !context.hasSheBang);
};

re.prototype.isValidRuleSet = function(rules, fullItem, context) {
	var validRuleSet = false;

	if (_.isObject(rules)) {
		var ignore = rules.IGNORE;
		var customIgnore = context.customIgnore;

		validRuleSet = (!ignore || (ignore && !ignore.test(fullItem))) &&
				(!customIgnore || (customIgnore && !customIgnore.test(fullItem)));
	}

	return validRuleSet;
};

re.prototype.iterateRules = function(rules, fullItem, context) {
	var instance = this;

	if (_.isString(rules)) {
		rules = instance.getValue(instance, rules);
	}

	var item = context.item;
	var lineNum = context.lineNum;
	var logger = context.logger;

	if (instance.isValidRuleSet(rules, fullItem, context)) {
		_.forEach(
			rules,
			function(rule, ruleName) {
				if (instance.isValidRule(ruleName, rule, context)) {
					var result = instance.testLine(rule, fullItem, context);

					if (result) {
						var warning = instance.getWarning(lineNum, item, result, rule, context);

						if (warning && logger) {
							logger(lineNum, warning);
						}

						fullItem = instance.replaceItem(lineNum, fullItem, result, rule, context);
					}
				}
			}
		);
	}

	return fullItem;
};

re.prototype.match = function(item, re) {
	return item.match(re);
};

re.prototype.message = function(message, lineNum, item, result, rule) {
	return sub(message, lineNum, item);
};

re.prototype.replaceItem = function(lineNum, fullItem, result, rule, context) {
	var replacer = rule.replacer;

	if (replacer) {
		fullItem = this._callReplacer(fullItem, result, rule, context);
		fullItem = this._callFormatItem(fullItem, context);
	}

	return fullItem;
};

re.prototype.test = function(item, regex) {
	return regex.test(item);
};

re.prototype.testLine = function(rule, fullItem, context) {
	var regex = rule.regex;
	var test = rule.test || this.test;

	if (test === 'match') {
		test = this.match;
	}

	var testItem = context.item;

	if (rule.testFullItem) {
		testItem = fullItem;
	}

	return test.call(this, testItem, regex, rule, context);
};

re.prototype._callReplacer = function(fullItem, result, rule, context) {
	var replacer = rule.replacer;

	if (_.isString(replacer)) {
		fullItem = fullItem.replace(rule.regex, replacer);
	}
	else if (_.isFunction(replacer)) {
		fullItem = replacer.call(this, fullItem, result, rule, context);
	}

	return fullItem;
};

re.prototype._callFormatItem = function(fullItem, context) {
	var formatItem = context.formatItem;

	if (formatItem) {
		fullItem = formatItem.call(this, fullItem, context);
	}

	return fullItem;
};

var rulesInstance = new re(RULES);

rulesInstance.re = re;

re.RULES = RULES;

module.exports = rulesInstance;<commit_msg>Removing unused regexes<commit_after>var _ = require('lodash');
var getObject = require('getobject');
var base = require('./base');

var sub = base.sub;

var RULES = {
	REGEX_ARRAY_INTERNAL_SPACE: /[^,]*?,((?! )| {2,})[^,]+?/g,
	REGEX_ARRAY_SURROUNDING_SPACE: /\[\s|\s\]/g,

	REGEX_AUI_SCRIPT: /<(aui:)?script(.*?)>([\s\S]*?)<\/\1script>/,

	REGEX_BRACE_CLOSING: /\}\s*?$/,
	REGEX_BRACE_OPENING: /\{\s*?$/,

	REGEX_CSS_COMMA_END: /,\s*?$/,

	REGEX_DIGITS: /\d+/,

	REGEX_HEX: /#[0-9A-Fa-f]{3,6}\b/,
	REGEX_HEX_REDUNDANT: /#([0-9A-Fa-f])\1([0-9A-Fa-f])\2([0-9A-Fa-f])\3/,

	REGEX_LANG_EMPTYFN: /(^|(A\.)?(Lang\.)?)emptyFn(True|False)?/,

	REGEX_LEADING_INCLUDE: /^@include /,
	REGEX_LEADING_SPACE: /^\s+/,

	REGEX_PROP_KEY: /^\s*(?:@include\s)?([^:]+)(?:)/,
	REGEX_PROPERTY: /^\t*([^:]+:|@include\s)[^;]+;$/,

	REGEX_REGEX: /\/.*\/([gim]{1,3})?/g,

	REGEX_SCRIPTLET_STUB: new RegExp('^\\s*' + base.jspLintStubs.scriptlet + '$'),

	REGEX_SERVICE_PROPS: /(^@)|((.*?) = (.*?))/,

	REGEX_STUBS: new RegExp('^_*(' + Object.keys(base.stubs).join('|') + ')_*'),

	REGEX_VAR_IS: /^_?is[A-Z]/,

	REPLACE_REGEX_REDUNDANT: '#$1$2$3',

	common: require('./engine_rules/common'),
	css: require('./engine_rules/css'),

	html: {},

	htmlJS: require('./engine_rules/html_js'),
	js: require('./engine_rules/js')
};

var re = function(rules) {
	_.defaults(this, rules);
};

re.prototype.getValue = getObject.get;

re.prototype.getWarning = function(lineNum, item, result, rule, context) {
	var warning;

	var message = rule.message || this.message;

	if (rule.message === false) {
		message = false;
	}

	if (_.isString(message)) {
		warning = this.message(message, lineNum, item, result, rule, context);
	}
	else if (_.isFunction(message)) {
		warning = message.call(this, lineNum, item, result, rule, context);
	}

	return warning;
};

re.prototype.hasExtraNewLines = function(item, index, collection, logger) {
	var extraNewLines = false;

	if (item === '') {
		extraNewLines = (index === 0 && collection.length > 1) || collection[index - 1] === '';
	}

	if (extraNewLines && logger) {
		logger(index + 1, 'Extra new line');
	}

	return extraNewLines;
};

re.prototype.hasHex = function(item) {
	var match = item.match(this.REGEX_HEX);

	return match && match[0];
};

re.prototype.hasProperty = function(item) {
	return this.REGEX_PROPERTY.test(item);
};

re.prototype.isValidRule = function(ruleName, rule, context) {
	return (ruleName !== 'IGNORE' && ruleName.indexOf('_') !== 0) &&
			(rule.ignore !== 'node' || !context.hasSheBang);
};

re.prototype.isValidRuleSet = function(rules, fullItem, context) {
	var validRuleSet = false;

	if (_.isObject(rules)) {
		var ignore = rules.IGNORE;
		var customIgnore = context.customIgnore;

		validRuleSet = (!ignore || (ignore && !ignore.test(fullItem))) &&
				(!customIgnore || (customIgnore && !customIgnore.test(fullItem)));
	}

	return validRuleSet;
};

re.prototype.iterateRules = function(rules, fullItem, context) {
	var instance = this;

	if (_.isString(rules)) {
		rules = instance.getValue(instance, rules);
	}

	var item = context.item;
	var lineNum = context.lineNum;
	var logger = context.logger;

	if (instance.isValidRuleSet(rules, fullItem, context)) {
		_.forEach(
			rules,
			function(rule, ruleName) {
				if (instance.isValidRule(ruleName, rule, context)) {
					var result = instance.testLine(rule, fullItem, context);

					if (result) {
						var warning = instance.getWarning(lineNum, item, result, rule, context);

						if (warning && logger) {
							logger(lineNum, warning);
						}

						fullItem = instance.replaceItem(lineNum, fullItem, result, rule, context);
					}
				}
			}
		);
	}

	return fullItem;
};

re.prototype.match = function(item, re) {
	return item.match(re);
};

re.prototype.message = function(message, lineNum, item, result, rule) {
	return sub(message, lineNum, item);
};

re.prototype.replaceItem = function(lineNum, fullItem, result, rule, context) {
	var replacer = rule.replacer;

	if (replacer) {
		fullItem = this._callReplacer(fullItem, result, rule, context);
		fullItem = this._callFormatItem(fullItem, context);
	}

	return fullItem;
};

re.prototype.test = function(item, regex) {
	return regex.test(item);
};

re.prototype.testLine = function(rule, fullItem, context) {
	var regex = rule.regex;
	var test = rule.test || this.test;

	if (test === 'match') {
		test = this.match;
	}

	var testItem = context.item;

	if (rule.testFullItem) {
		testItem = fullItem;
	}

	return test.call(this, testItem, regex, rule, context);
};

re.prototype._callReplacer = function(fullItem, result, rule, context) {
	var replacer = rule.replacer;

	if (_.isString(replacer)) {
		fullItem = fullItem.replace(rule.regex, replacer);
	}
	else if (_.isFunction(replacer)) {
		fullItem = replacer.call(this, fullItem, result, rule, context);
	}

	return fullItem;
};

re.prototype._callFormatItem = function(fullItem, context) {
	var formatItem = context.formatItem;

	if (formatItem) {
		fullItem = formatItem.call(this, fullItem, context);
	}

	return fullItem;
};

var rulesInstance = new re(RULES);

rulesInstance.re = re;

re.RULES = RULES;

module.exports = rulesInstance;<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global require, exports, console */
'use strict';

const self = require("sdk/self");
const data = self.data;
const tabs = require('sdk/tabs');
const {
  isPrivate
} = require("sdk/private-browsing");
const {
  ContentPolicy
} = require('shared/policy');
const ss = require('sdk/simple-storage');
const {
  on, once, off, emit
} = require("sdk/event/core");
const prefs = require("sdk/simple-prefs").prefs;

const persist = require("./persist");
const {
  Connection, getAllConnections
} = require("./connection");

const xulapp = require("sdk/system/xul-app");
const usingAustralis = xulapp.satisfiesVersion(">=29");
if (usingAustralis) {
  const {
    ActionButton
  } = require("sdk/ui/button/action");
} else {
  const {
    Widget
  } = require("sdk/widget");
}
exports.usingAustralis = usingAustralis;

const mainPage = data.url("index.html");
var uiworker = null;

exports.mainPage = mainPage;
exports.attachToLightbeamPage = attachToLightbeamPage;
// These attach page workers to new tabs.
exports.onForWorker = function (eventname, handler) {
  if (uiworker) {
    uiworker.port.on(eventname, handler);
  } else {
    console.log('no uiworker to subscript to order');
  }
};

exports.emitForWorker = function (eventname, obj) {
  if (uiworker) {
    uiworker.port.emit(eventname, obj);
  }
};

// Begin tab handlers. These are for sidebar functionality, which is not
// present yet.
// FIXME: Move tab handlers into a tab component
// And specify what we're trying to do with it

function lightbeamTabClosed(tab) {
  menuitem.label = "Show Lightbeam";
  button.tooltip = "Show Lightbeam";
}

function lightbeamTabReady(tab) {
  menuitem.label = "Close Lightbeam";
  button.tooltip = "Close Lightbeam";
}

function lightbeamTabDeactivate(tab) {
  menuitem.label = "Switch to Lightbeam Tab";
  button.tooltip = "Switch to Lightbeam Tab";
}

const blockmap = ss.storage.blockmap;
var blocksites = Object.keys(blockmap);
console.log("blocking " + blocksites.length + ' sites');

// This is the heart of the Lightbeam blocking functionality.
ContentPolicy({
  description: "Blocks user-defined blocklist from Lightbeam UI",
  shouldLoad: function ({
    location: location,
    origin: origin
  }) {
    // ignore URIs with no host
    var topLevelDomain;
    try {
      topLevelDomain = Connection.getDomain(location.host);
    } catch (e) {
      // See Issue 374: https://github.com/mozilla/lightbeam/issues/374
      // if there is no host, like in about:what, then the host getter throws
      return true;
    }

    if (blockmap[topLevelDomain]) {
      return false;
    }
    return true;
  }
});

function handlePrivateTab(tab) {
  if (isPrivate(tab) && uiworker) {
    // console.error('tab is private and uiworker exists');
    uiworker.port.emit("private-browsing");
    // console.error('sent message');
    return true;
  }
}

// if there is a private tab opened while the lightbeam tab is open,
// then alert the user about it.
tabs.on('open', handlePrivateTab);

// Notify the user in case they open a private window. Connections are
// visualized but never stored.
function hasPrivateTab() {
  // console.error('hasPrivateTab: %s tabs to test', tabs.length);
  for (var i = 0; i < tabs.length; i++) {
    if (handlePrivateTab(tabs[i])) {
      break; // the presence of a Private Window has been detected
    }
  }
}

// Connect the tab to the content script of the UI page. There may only ever be
// one UI page.
function attachToLightbeamPage(worker) {
  console.debug("Attaching to lightbeam page");
  uiworker = worker;

  // The blocklist is maintained on both sides to reduce latency. However,
  // this may cause sync errors.
  function onWorkerUpdateBlocklist(site, blockFlag) {
    if (blockFlag) {
      if (!blockmap[site]) {
        blockmap[site] = true;
      }
    } else {
      if (blockmap[site]) {
        delete blockmap[site];
      }
    }

    uiworker.port.emit('update-blocklist', {
      domain: site,
      flag: blockFlag
    });
  }

  function onPrefChanged(event) {
    console.debug("Received updated prefs", JSON.stringify(event));
    if ("contributeData" in event) {
      prefs.contributeData = event.contributeData;
    }
    if ("defaultVisualization" in event) {
      prefs.defaultVisualization = event.defaultVisualization;
    }
    if ("defaultFilter" in event) {
      prefs.defaultFilter = event.defaultFilter;
    }
  }

  // Send over the the blocklist initially so we can use it.
  worker.port.emit('update-blocklist-all',
    Object.keys(blockmap).map(
      function (site) {
        return {
          domain: site,
          flag: blockmap[site]
        };
      }));

  function onWorkerReset() {
    // Reset buffered state
    Connection.reset();
    // And stored state, including prefs
    persist.reset();
  }

  function onUIReady() {
    worker.port.emit("updateUIFromMetadata", { version: self.version });
    worker.port.emit("updateUIFromPrefs", prefs);
    worker.port.emit("passStoredConnections", getAllConnections());
  }

  function onWorkerDetach() {
    // console.error('detaching lightbeam view');
    this.port.removeListener('reset', onWorkerReset);
    this.port.removeListener('uiready', onUIReady);
    this.port.removeListener('updateBlocklist', onWorkerUpdateBlocklist);
    this.port.removeListener("prefChanged", onPrefChanged);
    uiworker = null;
    this.destroy();
  }

  worker.on("detach", onWorkerDetach);
  worker.port.on("reset", onWorkerReset);
  worker.port.on('uiready', onUIReady);
  worker.port.on('updateBlocklist', onWorkerUpdateBlocklist);
  worker.port.on("prefChanged", onPrefChanged);
  worker.port.emit('init');

  // if there is a private window open, then alert the user about it.
  try {
    hasPrivateTab();
  } catch (e) {
    console.error('Error testing with hasPrivateTab(): %o', e);
  }
}

// This lets us toggle between the 3 states (no lightbeam tab open, lightbeam
// tab open but it's not the tab you're on, you're on the lightbeam tab)
function getLightbeamTab() {
  for each(let tab in tabs) {
    if (tab.url.slice(0, mainPage.length) === mainPage) {
      return tab;
    }
  }
}
exports.getLightbeamTab = getLightbeamTab;

// Set up the menu item to open the main UI page:
var menuitem = require("shared/menuitems").Menuitem({
  id: "lightbeam_openUITab",
  menuid: "menu_ToolsPopup",
  label: "Show Lightbeam",
  onCommand: function () {
    openOrSwitchToOrClose();
  },
  insertbefore: "sanitizeItem",
  image: data.url("icons/lightbeam_logo-only_32x32.png")
});

function openOrSwitchToOrClose() {
  // Open the Lightbeam tab, if it doesn't exist.
  var tab = getLightbeamTab();
  if (!tab) {
    return tabs.open({
      url: mainPage,
      onOpen: lightbeamTabReady,
      onClose: lightbeamTabClosed,
      onReady: lightbeamTabReady,
      onActivate: lightbeamTabReady,
      onDeactivate: lightbeamTabDeactivate
    });
  }
  // Close it if it's active.
  if (tab === tabs.activeTab) {
    tab.close();
  } else {
    // Otherwise, switch to the Lightbeam tab
    tab.activate();
    tab.window.activate();
  }
}
exports.openOrSwitchToOrClose = openOrSwitchToOrClose;

// Set up the status bar button to open the main UI page:
var button;
if (usingAustralis) {
  console.debug("Using australis");
  button = ActionButton({
    id: "lightbeam_Widget",
    label: "Lightbeam",
    tooltip: "Show Lightbeam",
    // Relative to the data directory
    icon: {
      "16": "./icons/lightbeam_logo-only_16x16.png",
      "32": "./icons/lightbeam_logo-only_32x32.png",
      "48": "./icons/lightbeam_logo-only_48x48.png",
    },
    onClick: function () {
      openOrSwitchToOrClose();
    }
  });
} else {
  console.debug("Not using australis");
  button = Widget({
    id: "lightbeam_Widget",
    label: "Lightbeam",
    tooltip: "Show Lightbeam",
    contentURL: data.url("icons/lightbeam_logo-only_32x32.png"),
    onClick: function () {
      openOrSwitchToOrClose();
    }
  });
}
<commit_msg>Turn off warning about a possible strict violation<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* global require, exports, console */
'use strict';

const self = require("sdk/self");
const data = self.data;
const tabs = require('sdk/tabs');
const {
  isPrivate
} = require("sdk/private-browsing");
const {
  ContentPolicy
} = require('shared/policy');
const ss = require('sdk/simple-storage');
const {
  on, once, off, emit
} = require("sdk/event/core");
const prefs = require("sdk/simple-prefs").prefs;

const persist = require("./persist");
const {
  Connection, getAllConnections
} = require("./connection");

const xulapp = require("sdk/system/xul-app");
const usingAustralis = xulapp.satisfiesVersion(">=29");
if (usingAustralis) {
  const {
    ActionButton
  } = require("sdk/ui/button/action");
} else {
  const {
    Widget
  } = require("sdk/widget");
}
exports.usingAustralis = usingAustralis;

const mainPage = data.url("index.html");
var uiworker = null;

exports.mainPage = mainPage;
exports.attachToLightbeamPage = attachToLightbeamPage;
// These attach page workers to new tabs.
exports.onForWorker = function (eventname, handler) {
  if (uiworker) {
    uiworker.port.on(eventname, handler);
  } else {
    console.log('no uiworker to subscript to order');
  }
};

exports.emitForWorker = function (eventname, obj) {
  if (uiworker) {
    uiworker.port.emit(eventname, obj);
  }
};

// Begin tab handlers. These are for sidebar functionality, which is not
// present yet.
// FIXME: Move tab handlers into a tab component
// And specify what we're trying to do with it

function lightbeamTabClosed(tab) {
  menuitem.label = "Show Lightbeam";
  button.tooltip = "Show Lightbeam";
}

function lightbeamTabReady(tab) {
  menuitem.label = "Close Lightbeam";
  button.tooltip = "Close Lightbeam";
}

function lightbeamTabDeactivate(tab) {
  menuitem.label = "Switch to Lightbeam Tab";
  button.tooltip = "Switch to Lightbeam Tab";
}

const blockmap = ss.storage.blockmap;
var blocksites = Object.keys(blockmap);
console.log("blocking " + blocksites.length + ' sites');

// This is the heart of the Lightbeam blocking functionality.
ContentPolicy({
  description: "Blocks user-defined blocklist from Lightbeam UI",
  shouldLoad: function ({
    location: location,
    origin: origin
  }) {
    // ignore URIs with no host
    var topLevelDomain;
    try {
      topLevelDomain = Connection.getDomain(location.host);
    } catch (e) {
      // See Issue 374: https://github.com/mozilla/lightbeam/issues/374
      // if there is no host, like in about:what, then the host getter throws
      return true;
    }

    if (blockmap[topLevelDomain]) {
      return false;
    }
    return true;
  }
});

function handlePrivateTab(tab) {
  if (isPrivate(tab) && uiworker) {
    // console.error('tab is private and uiworker exists');
    uiworker.port.emit("private-browsing");
    // console.error('sent message');
    return true;
  }
}

// if there is a private tab opened while the lightbeam tab is open,
// then alert the user about it.
tabs.on('open', handlePrivateTab);

// Notify the user in case they open a private window. Connections are
// visualized but never stored.
function hasPrivateTab() {
  // console.error('hasPrivateTab: %s tabs to test', tabs.length);
  for (var i = 0; i < tabs.length; i++) {
    if (handlePrivateTab(tabs[i])) {
      break; // the presence of a Private Window has been detected
    }
  }
}

// Connect the tab to the content script of the UI page. There may only ever be
// one UI page.
function attachToLightbeamPage(worker) {
  console.debug("Attaching to lightbeam page");
  uiworker = worker;

  // The blocklist is maintained on both sides to reduce latency. However,
  // this may cause sync errors.
  function onWorkerUpdateBlocklist(site, blockFlag) {
    if (blockFlag) {
      if (!blockmap[site]) {
        blockmap[site] = true;
      }
    } else {
      if (blockmap[site]) {
        delete blockmap[site];
      }
    }

    uiworker.port.emit('update-blocklist', {
      domain: site,
      flag: blockFlag
    });
  }

  function onPrefChanged(event) {
    console.debug("Received updated prefs", JSON.stringify(event));
    if ("contributeData" in event) {
      prefs.contributeData = event.contributeData;
    }
    if ("defaultVisualization" in event) {
      prefs.defaultVisualization = event.defaultVisualization;
    }
    if ("defaultFilter" in event) {
      prefs.defaultFilter = event.defaultFilter;
    }
  }

  // Send over the the blocklist initially so we can use it.
  worker.port.emit('update-blocklist-all',
    Object.keys(blockmap).map(
      function (site) {
        return {
          domain: site,
          flag: blockmap[site]
        };
      }));

  function onWorkerReset() {
    // Reset buffered state
    Connection.reset();
    // And stored state, including prefs
    persist.reset();
  }

  function onUIReady() {
    worker.port.emit("updateUIFromMetadata", { version: self.version });
    worker.port.emit("updateUIFromPrefs", prefs);
    worker.port.emit("passStoredConnections", getAllConnections());
  }

  function onWorkerDetach() {
    // console.error('detaching lightbeam view');
    /* jshint validthis:true */
    this.port.removeListener('reset', onWorkerReset);
    this.port.removeListener('uiready', onUIReady);
    this.port.removeListener('updateBlocklist', onWorkerUpdateBlocklist);
    this.port.removeListener("prefChanged", onPrefChanged);
    uiworker = null;
    this.destroy();
  }

  worker.on("detach", onWorkerDetach);
  worker.port.on("reset", onWorkerReset);
  worker.port.on('uiready', onUIReady);
  worker.port.on('updateBlocklist', onWorkerUpdateBlocklist);
  worker.port.on("prefChanged", onPrefChanged);
  worker.port.emit('init');

  // if there is a private window open, then alert the user about it.
  try {
    hasPrivateTab();
  } catch (e) {
    console.error('Error testing with hasPrivateTab(): %o', e);
  }
}

// This lets us toggle between the 3 states (no lightbeam tab open, lightbeam
// tab open but it's not the tab you're on, you're on the lightbeam tab)
function getLightbeamTab() {
  for each(let tab in tabs) {
    if (tab.url.slice(0, mainPage.length) === mainPage) {
      return tab;
    }
  }
}
exports.getLightbeamTab = getLightbeamTab;

// Set up the menu item to open the main UI page:
var menuitem = require("shared/menuitems").Menuitem({
  id: "lightbeam_openUITab",
  menuid: "menu_ToolsPopup",
  label: "Show Lightbeam",
  onCommand: function () {
    openOrSwitchToOrClose();
  },
  insertbefore: "sanitizeItem",
  image: data.url("icons/lightbeam_logo-only_32x32.png")
});

function openOrSwitchToOrClose() {
  // Open the Lightbeam tab, if it doesn't exist.
  var tab = getLightbeamTab();
  if (!tab) {
    return tabs.open({
      url: mainPage,
      onOpen: lightbeamTabReady,
      onClose: lightbeamTabClosed,
      onReady: lightbeamTabReady,
      onActivate: lightbeamTabReady,
      onDeactivate: lightbeamTabDeactivate
    });
  }
  // Close it if it's active.
  if (tab === tabs.activeTab) {
    tab.close();
  } else {
    // Otherwise, switch to the Lightbeam tab
    tab.activate();
    tab.window.activate();
  }
}
exports.openOrSwitchToOrClose = openOrSwitchToOrClose;

// Set up the status bar button to open the main UI page:
var button;
if (usingAustralis) {
  console.debug("Using australis");
  button = ActionButton({
    id: "lightbeam_Widget",
    label: "Lightbeam",
    tooltip: "Show Lightbeam",
    // Relative to the data directory
    icon: {
      "16": "./icons/lightbeam_logo-only_16x16.png",
      "32": "./icons/lightbeam_logo-only_32x32.png",
      "48": "./icons/lightbeam_logo-only_48x48.png",
    },
    onClick: function () {
      openOrSwitchToOrClose();
    }
  });
} else {
  console.debug("Not using australis");
  button = Widget({
    id: "lightbeam_Widget",
    label: "Lightbeam",
    tooltip: "Show Lightbeam",
    contentURL: data.url("icons/lightbeam_logo-only_32x32.png"),
    onClick: function () {
      openOrSwitchToOrClose();
    }
  });
}
<|endoftext|>


<commit_before>/*
 *   Copyright 2014 Guy Bedford (http://guybedford.com)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

var Promise = require('rsvp').Promise;

// if storing any logs, dump them on exit
process.on('exit', function() {
  if (logBuffer && !apiResolver)
    console.log(logBuffer);
})

var cli = module.exports;

var apiResolver;
exports.setResolver = function(resolver) {
  apiResolver = resolver;
}

// use the default option in all prompts
// throws an error for prompts that don't take a default
var useDefaults;
exports.useDefaults = function() {
  useDefaults = true;
}

var logging = true;
var logBuffer = '';
var logged = false;
var log = exports.log = function(type, msg) {
  if (apiResolver)
    return apiResolver.emit('log', type, msg);

  if (logged == false)
    console.log('');
  logged = true;
  if (arguments.length == 1) {
    msg = type;
    type = null;
  }

  if (typeof(msg) !== 'string')
    msg = String(msg);

  if (type)
    msg = format[type](msg);

  if (logging)
    return console.log(msg);
  logBuffer += msg + '\n';
}

function moduleMsg(msg, color) {
  return (color || '\033[0m')
    + msg
      .replace(/(\s|\`|^)%([^%\n]+)%/g, '$1\033[1m\033[90m$2\033[0m' + color || '')
      .replace(/(\s|^)\`([^\`\n]+)\`/g, '$1\033[36m$2\033[0m' + color || '')
      .replace(/\n\r?( {0,4}\w)/g, '\n     $1')
    + '\033[0m';
}
var format = exports.format = {
  q: function(msg, opt) {
    return moduleMsg(msg, '') + '\033[90m' + (opt ? ' [' + opt + ']' : '') + '\033[39m:\033[0m ';
  },
  err: function(msg) {
    return '\n\033[31m\033[1merr  \033[0m' + moduleMsg(msg, '\033[0m');
  },
  info: function(msg) {
    return '     ' + moduleMsg(msg, '\033[0m');
  },
  warn: function(msg) {
    return '\n\033[33m\033[1mwarn \033[0m' + moduleMsg(msg, '\033[0m');
  },
  ok: function(msg) {
    return '\033[32m\033[1mok   \033[0m' + moduleMsg(msg, '\033[0m');
  }
};

var inputQueue = [];
var confirm = exports.confirm = function(msg, def) {
  if (useDefaults) {
    if (def !== true && def !== false)
      def = true;
    process.stdout.write(format.q(msg) + (def ? 'Yes' : 'No') + '\n');
    return Promise.resolve(def);
  }

  if (apiResolver)
    return new Promise(function(resolve, reject) {
      apiResolver.emit('prompt', {
        type: 'confirm',
        message: msg,
        default: def
      }, function(answer) {
        resolve(answer);
      });
    });

  var defText = 'y/n';
  if (def === true)
    defText = 'yes';
  else if (def === false)
    defText = 'no';
  else
    def = undefined;

  var p = cli.input(msg, defText);
  return p.then(function(reply) {
    if (reply.match(/^\b(no|n)\b$/i))
      return false;
    else if (reply.match(/^\b(yes|y\b)$/i))
      return true;
    else if (def !== undefined)
      return def;
    else
      return confirm(msg, def);
  });
}

exports.input = function(msg, def, disableOutput, queue) {
  if (useDefaults) {
    process.stdout.write(format.q(msg) + def + '\n');
    return Promise.resolve(def);
  }

  if (apiResolver)
    return new Promise(function(resolve, reject) {
      apiResolver.emit('prompt', {
        type: 'input',
        message: msg,
        default: def
      }, function(answer) {
        resolve(answer.input);
      });
    });

  if (arguments.length == 2)
    disableOutput = false;

  return new Promise(function(resolve, reject) {
    if (!logging && !queue)
      return inputQueue.push({
        args: [msg, def, disableOutput, true],
        resolve: resolve,
        reject: reject
      });

    if (logging && logged)
      process.stdout.write('\n');
    logging = false;
    process.stdout.write(format.q(msg, def));
    process.stdin.resume();
    process.stdin.setEncoding('utf8');
    process.stdin.setRawMode(disableOutput);
    var inputVal = '';
    process.stdin.on('data', function(chunk) {
      var lastChar = chunk.substr(chunk.length - 1, 1);
      if (lastChar == '\n' || lastChar == '\r' || lastChar == '\u0004') {
        process.stdin.setRawMode(false);
        process.stdin.pause();
        process.stdin.removeAllListeners('data');
        inputVal += chunk.substr(0, chunk.length - 1);

        // bump the input queue
        var next = inputQueue.shift();
        if (next)
          cli.input.apply(null, next.args).then(next.resolve, next.reject);
        else {
          process.stdout.write(logBuffer);
          logBuffer = '';
          logging = true;
          logged = false;
        }

        resolve(inputVal.trim() || def);
      }
      inputVal += chunk;
    });

  });
}<commit_msg>remove use of grey<commit_after>/*
 *   Copyright 2014 Guy Bedford (http://guybedford.com)
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

var Promise = require('rsvp').Promise;

// if storing any logs, dump them on exit
process.on('exit', function() {
  if (logBuffer && !apiResolver)
    console.log(logBuffer);
})

var cli = module.exports;

var apiResolver;
exports.setResolver = function(resolver) {
  apiResolver = resolver;
}

// use the default option in all prompts
// throws an error for prompts that don't take a default
var useDefaults;
exports.useDefaults = function() {
  useDefaults = true;
}

var logging = true;
var logBuffer = '';
var logged = false;
var log = exports.log = function(type, msg) {
  if (apiResolver)
    return apiResolver.emit('log', type, msg);

  if (logged == false)
    console.log('');
  logged = true;
  if (arguments.length == 1) {
    msg = type;
    type = null;
  }

  if (typeof(msg) !== 'string')
    msg = String(msg);

  if (type)
    msg = format[type](msg);

  if (logging)
    return console.log(msg);
  logBuffer += msg + '\n';
}

function moduleMsg(msg, color) {
  return (color || '\033[0m')
    + msg
      .replace(/(\s|\`|^)%([^%\n]+)%/g, '$1\033[1m$2\033[0m' + color || '')
      .replace(/(\s|^)\`([^\`\n]+)\`/g, '$1\033[36m$2\033[0m' + color || '')
      .replace(/\n\r?( {0,4}\w)/g, '\n     $1')
    + '\033[0m';
}
var format = exports.format = {
  q: function(msg, opt) {
    return moduleMsg(msg, '') + '' + (opt ? ' [' + opt + ']' : '') + '\033[39m:\033[0m ';
  },
  err: function(msg) {
    return '\n\033[31m\033[1merr  \033[0m' + moduleMsg(msg, '\033[0m');
  },
  info: function(msg) {
    return '     ' + moduleMsg(msg, '\033[0m');
  },
  warn: function(msg) {
    return '\n\033[33m\033[1mwarn \033[0m' + moduleMsg(msg, '\033[0m');
  },
  ok: function(msg) {
    return '\033[32m\033[1mok   \033[0m' + moduleMsg(msg, '\033[0m');
  }
};

var inputQueue = [];
var confirm = exports.confirm = function(msg, def) {
  if (useDefaults) {
    if (def !== true && def !== false)
      def = true;
    process.stdout.write(format.q(msg) + (def ? 'Yes' : 'No') + '\n');
    return Promise.resolve(def);
  }

  if (apiResolver)
    return new Promise(function(resolve, reject) {
      apiResolver.emit('prompt', {
        type: 'confirm',
        message: msg,
        default: def
      }, function(answer) {
        resolve(answer);
      });
    });

  var defText = 'y/n';
  if (def === true)
    defText = 'yes';
  else if (def === false)
    defText = 'no';
  else
    def = undefined;

  var p = cli.input(msg, defText);
  return p.then(function(reply) {
    if (reply.match(/^\b(no|n)\b$/i))
      return false;
    else if (reply.match(/^\b(yes|y\b)$/i))
      return true;
    else if (def !== undefined)
      return def;
    else
      return confirm(msg, def);
  });
}

exports.input = function(msg, def, disableOutput, queue) {
  if (useDefaults) {
    process.stdout.write(format.q(msg) + def + '\n');
    return Promise.resolve(def);
  }

  if (apiResolver)
    return new Promise(function(resolve, reject) {
      apiResolver.emit('prompt', {
        type: 'input',
        message: msg,
        default: def
      }, function(answer) {
        resolve(answer.input);
      });
    });

  if (arguments.length == 2)
    disableOutput = false;

  return new Promise(function(resolve, reject) {
    if (!logging && !queue)
      return inputQueue.push({
        args: [msg, def, disableOutput, true],
        resolve: resolve,
        reject: reject
      });

    if (logging && logged)
      process.stdout.write('\n');
    logging = false;
    process.stdout.write(format.q(msg, def));
    process.stdin.resume();
    process.stdin.setEncoding('utf8');
    process.stdin.setRawMode(disableOutput);
    var inputVal = '';
    process.stdin.on('data', function(chunk) {
      var lastChar = chunk.substr(chunk.length - 1, 1);
      if (lastChar == '\n' || lastChar == '\r' || lastChar == '\u0004') {
        process.stdin.setRawMode(false);
        process.stdin.pause();
        process.stdin.removeAllListeners('data');
        inputVal += chunk.substr(0, chunk.length - 1);

        // bump the input queue
        var next = inputQueue.shift();
        if (next)
          cli.input.apply(null, next.args).then(next.resolve, next.reject);
        else {
          process.stdout.write(logBuffer);
          logBuffer = '';
          logging = true;
          logged = false;
        }

        resolve(inputVal.trim() || def);
      }
      inputVal += chunk;
    });

  });
}<|endoftext|>


<commit_before>Comments.ui = (function () {
  Avatar.options = {
    defaultImageUrl: 'http://s3.amazonaws.com/37assets/svn/765-default-avatar.png'
  };

  Tracker.autorun(function () {
    var userId = Meteor.userId();

    if (userId) {
      Comments.session.set('loginAction', '');
    }
  });

  var config = {
    template: 'semantic-ui',
    limit: 2,
    loadMoreCount: 1
  };

  return {
    config: function (newConfig) {
      if (!newConfig) {
        return config;
      }

      config = _.extend(config, newConfig);
    },
    callIfLoggedIn: function (action, cb) {
      if (!Meteor.userId()) {
        Comments.session.set('loginAction', action);
      } else {
        return cb();
      }
    }
  };
})();<commit_msg>Change default loadMore and limit configuration<commit_after>Comments.ui = (function () {
  Avatar.options = {
    defaultImageUrl: 'http://s3.amazonaws.com/37assets/svn/765-default-avatar.png'
  };

  Tracker.autorun(function () {
    var userId = Meteor.userId();

    if (userId) {
      Comments.session.set('loginAction', '');
    }
  });

  var config = {
    template: 'semantic-ui',
    limit: 30,
    loadMoreCount: 20
  };

  return {
    config: function (newConfig) {
      if (!newConfig) {
        return config;
      }

      config = _.extend(config, newConfig);
    },
    callIfLoggedIn: function (action, cb) {
      if (!Meteor.userId()) {
        Comments.session.set('loginAction', action);
      } else {
        return cb();
      }
    }
  };
})();<|endoftext|>