<commit_before>/*
    Copyright (C) 2014 Härnösands kommun

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Add layer view
 * View includes a drag/drop and collapsable layer tree
 */

Ext.define('OpenEMap.view.layer.Add' ,{
    extend: 'OpenEMap.view.layer.Tree',

    requires: [
        'OpenEMap.data.DataHandler',
        'OpenEMap.view.layer.TreeFilter',
        'OpenEMap.action.MetadataInfoColumn'
    ],

    title: 'Lägg till lager',

    width: 250,
    height: 550,

    headerPosition: 'top',
    collapsible: true,
    collapseMode: 'header',
    collapseDirection : 'right',
    titleCollapse: true,

    viewConfig: {
         plugins: {
            ptype: 'treeviewdragdrop',
            enableDrop: false
        },
        copy: true
    },

    // Layer tree filtering
    plugins: {
        ptype: 'treefilter',
        allowParentFolders: true
    },
    dockedItems: [
        {
            xtype: 'toolbar',
            dock: 'top',
            layout: 'fit',
            items: [{
                xtype: 'trigger',
                triggerCls: 'x-form-clear-trigger',
                onTriggerClick: function () {
                    this.reset();
                    this.focus();
                },
                listeners: {
                    change: function (field, newVal) {
                        var tree = field.up('treepanel');
                        tree.filter(newVal);
                    },
                    buffer: 250
                }
            }]
        }
    ],

    initComponent: function() {
        var me = this;

        this.columns = [
            {
                xtype: 'treecolumn',
                flex: 1,
                dataIndex: 'text'
            },
            me.metadataColumn
        ];

        this.store = Ext.create('OpenEMap.data.GroupedLayerTree');

        Ext.Ajax.request({
            url: OpenEMap.wmsURLs.basePath + '?service=WMS&request=GetCapabilities',
            success: this.parseCapabilities,
            scope: this
        });

        this.callParent(arguments);
    },

    parseCapabilities: function(response) {
        var format = new OpenLayers.Format.WMSCapabilities();
        var wms = format.read(response.responseText);

        var root = this.store.setRootNode({});

        var children = wms.capability.layers.map(function(layer) {

            var layerConfig = {
                'text': layer.name,
                'leaf': true,
                'checked': true,
                'title': layer.title,
                'isGroupLayer': false,
                'isSearchable': true,
                'visibility': true,
                'wms':{
                    'url': OpenEMap.wmsURLs.url,
                    'params': {
                        'layers': layer.name,
                        'format': 'image/png',
                        'transparent': true
                    },
                    'options': {
                        'isBaseLayer': false
                    }
                }
            };

            var parser = Ext.create('OpenEMap.config.Parser');
            layerConfig.layer = parser.createLayer(layerConfig);

            return layerConfig;
        });

        root.appendChild(children);
    }

});
<commit_msg>Add queryable info on added layers (#119)<commit_after>/*
    Copyright (C) 2014 Härnösands kommun

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * Add layer view
 * View includes a drag/drop and collapsable layer tree
 */

Ext.define('OpenEMap.view.layer.Add' ,{
    extend: 'OpenEMap.view.layer.Tree',

    requires: [
        'OpenEMap.data.DataHandler',
        'OpenEMap.view.layer.TreeFilter',
        'OpenEMap.action.MetadataInfoColumn'
    ],

    title: 'Lägg till lager',

    width: 250,
    height: 550,

    headerPosition: 'top',
    collapsible: true,
    collapseMode: 'header',
    collapseDirection : 'right',
    titleCollapse: true,

    viewConfig: {
         plugins: {
            ptype: 'treeviewdragdrop',
            enableDrop: false
        },
        copy: true
    },

    // Layer tree filtering
    plugins: {
        ptype: 'treefilter',
        allowParentFolders: true
    },
    dockedItems: [
        {
            xtype: 'toolbar',
            dock: 'top',
            layout: 'fit',
            items: [{
                xtype: 'trigger',
                triggerCls: 'x-form-clear-trigger',
                onTriggerClick: function () {
                    this.reset();
                    this.focus();
                },
                listeners: {
                    change: function (field, newVal) {
                        var tree = field.up('treepanel');
                        tree.filter(newVal);
                    },
                    buffer: 250
                }
            }]
        }
    ],

    initComponent: function() {
        var me = this;

        this.columns = [
            {
                xtype: 'treecolumn',
                flex: 1,
                dataIndex: 'text'
            },
            me.metadataColumn
        ];

        this.store = Ext.create('OpenEMap.data.GroupedLayerTree');

        Ext.Ajax.request({
            url: OpenEMap.wmsURLs.basePath + '?service=WMS&request=GetCapabilities',
            success: this.parseCapabilities,
            scope: this
        });

        this.callParent(arguments);
    },

    parseCapabilities: function(response) {
        var format = new OpenLayers.Format.WMSCapabilities();
        var wms = format.read(response.responseText);

        var root = this.store.setRootNode({});

        var children = wms.capability.layers.map(function(layer) {

            var layerConfig = {
                'text': layer.name,
                'leaf': true,
                'checked': true,
                'title': layer.title,
                'name': layer.title,
                'queryable': layer.queryable,
                'isGroupLayer': false,
                'isSearchable': layer.queryable,
                'visibility': true,
                'wms':{
                    'url': OpenEMap.wmsURLs.url,
                    'params': {
                        'layers': layer.name,
                        'format': 'image/png',
                        'transparent': true
                    },
                    'options': {
                        'isBaseLayer': false
                    }
                }
            };

            var parser = Ext.create('OpenEMap.config.Parser');
            layerConfig.layer = parser.createLayer(layerConfig);

            return layerConfig;
        });

        root.appendChild(children);
    }

});
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */
var Initializer = require('./initializer');

/**
 * Make `app` bootable.
 *
 * This function makes an application bootable.  Booting consists of executing
 * a sequence of phases to initialize the application.
 *
 * Examples:
 *
 *     var app = bootable(express());
 *     app.phase(bootable.initializers());
 *     app.phase(bootable.routes());
 *
 *     app.boot(function(err) {
 *       if (err) { throw err; }
 *       app.listen(3001);
 *     });
 *
 * @param {Object} app
 * @api public
 */
exports = module.exports = function(app, phases) {
  phases = [].slice.call(arguments, 1);

  /**
   * Mixin initializer.
   */
  app._initializer = new Initializer();

  /**
   * Boot application.
   *
   * @param {Function} cb
   * @param {Object} [thisArg]
   * @api public
   */
  app.boot = function(cb, thisArg) {
    this._initializer.run(cb, thisArg || this);
  };

  /**
   * Add phase to boot sequence.
   *
   * @param {Function} fn
   * @return {Object} for chaining
   * @api public
   */
  app.phase = function(fn) {
    this._initializer.phase(fn);
    return this;
  };

  for (var i = 0; i < phases.length; ++i) {
    app.phase(phases[i]);
  }
  return app;
};

/**
 * Export constructors.
 */
exports.Initializer = Initializer;

/**
 * Export phases.
 */
exports.initializers = require('./phases/initializers');
exports.routes = require('./phases/routes');

/**
 * Export phases capable of dependency injection.
 */
exports.di = require('bootable-di');
<commit_msg>Clarify comments.<commit_after>/**
 * Module dependencies.
 */
var Initializer = require('./initializer');

/**
 * Make `app` bootable.
 *
 * This function makes an application bootable.  Booting consists of executing
 * a sequence of phases to initialize the application.
 *
 * Examples:
 *
 *     var app = bootable(express());
 *     app.phase(bootable.initializers());
 *     app.phase(bootable.routes());
 *
 *     app.boot(function(err) {
 *       if (err) { throw err; }
 *       app.listen(3001);
 *     });
 *
 * @param {Object} app
 * @returns {Object} app
 * @api public
 */
exports = module.exports = function(app, phases) {
  phases = [].slice.call(arguments, 1);

  // Mixin initializer.
  app._initializer = new Initializer();

  /**
   * Boot application.
   *
   * @param {Function} cb
   * @param {Object} [thisArg]
   * @api public
   */
  app.boot = function(cb, thisArg) {
    this._initializer.run(cb, thisArg || this);
  };

  /**
   * Add phase to boot sequence.
   *
   * @param {Function} fn
   * @return {Object} for chaining
   * @api public
   */
  app.phase = function(fn) {
    this._initializer.phase(fn);
    return this;
  };

  // Register phases, if any.
  for (var i = 0; i < phases.length; ++i) {
    app.phase(phases[i]);
  }
  return app;
};

/**
 * Export constructors.
 */
exports.Initializer = Initializer;

/**
 * Export phases.
 */
exports.initializers = require('./phases/initializers');
exports.routes = require('./phases/routes');

/**
 * Export dependency injection-capable phases.
 */
exports.di = require('bootable-di');
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 10sr <8.slashes@gmail.com>
 * Licensed under the Apache License, Version 2.0
 */

var readline = require("readline");
var fs = require("fs");
var childProcess = require("child_process");
var os = require("os");

var CronJob = require("cron").CronJob;
var nodemailer = require("nodemailer");
var logger = require("log4js").getLogger();
var argparse = require("argparse");

var parseCrontabRe = new RegExp(/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$/);

var SENDER_DEFAULT = os.userInfo().username + "@" + os.hostname();

function createMailTransporter(opts){
    if (!opts.mailto) {
        return null;
    }

    logger.info("Setting up email notification");
    logger.info("Sender: " + SENDER_DEFAULT);
    logger.info("Mailto: " + opts.mailto);
    var mailDefaults = {
        from: SENDER_DEFAULT,
        to: opts.mailto
    };

    if (opts.smtpHost || opts.smtpPort ||
        opts.smtpUser || opts.smtpPass) {
        logger.info("Use SMTP to send emails");
        return nodemailer.createTransport({
            host: opts.smtpHost,
            port: opts.smtpPort,
            secure: opts.smtpSecure,
            auth: {
                user: opts.smtpUser,
                pass: opts.smtpPass
            }
        }, mailDefaults);
    } else {
        logger.info("Use sendmail to send emails");
        return nodemailer.createTransport({
            sendmail: true,
            newline: "unix"
        }, mailDefaults);
    }
}

function parseCrontab(line){
    var matched = parseCrontabRe.exec(line);
    if (!matched) {
        throw Error("Failed to parse crontab line: " + line);
    }
    return {
        cronTime: [
            matched[1], matched[2], matched[3],
            matched[4], matched[5], matched[6]
        ].join(" "),
        command: matched[7]
    }
}

var start = exports.start = function start(crontab, opts){
    var exitOnFailure = Boolean(opts.exitOnFailure);
    var timeZone = opts.timeZone || null;
    var mailTransporter = createMailTransporter(opts);

    var rl = readline.createInterface({
        input: fs.createReadStream(crontab)
    });

    rl.on("line", function(line){
        if (line.match(/^#/)) {
            return;
        }
        var parsed = parseCrontab(line);
        var cronJobOpts = {
            cronTime: parsed.cronTime,
            onTick: function(){
                var currentTime = new Date();
                // TODO: use timezone
                var dateStr = currentTime.toISOString();
                var leadingMarker = dateStr + " | " + parsed.command + " | ";
                var proc = childProcess.exec(
                    parsed.command,
                    {},
                    function(err, stdout, stderr){
                        logger.info(leadingMarker + "stdout: " + stdout.trim());
                        logger.info(leadingMarker + "stderr: " + stderr.trim());
                        if (err) {
                            logger.warn(leadingMarker + "error:  " + err.toString())
                            logger.warn(leadingMarker + "exited with code " +
                                        err.code.toString());
                        } else {
                            logger.info(leadingMarker + "exited with code 0")
                        }

                        if (mailTransporter) {
                            logger.debug(leadingMarker +
                                        "Sending email to " + opts.mailto);
                            var mailText = "stdout:\n\n" + stdout +
                                "\n\nstderr:\n\n" + stderr;
                            if (err) {
                                mailText = mailText + "\n\nerror: " + err.toString() +
                                    "\n\nExit code: " + err.code.toString();
                            }
                            var mailSubject = "Cron-JS <" + SENDER_DEFAULT +
                                "> " + parsed.command;
                            mailTransporter.sendMail({
                                // TODO: fix title
                                subject: mailSubject,
                                text: mailText
                            }, function(err, info){
                                if (err) {
                                    logger.warn(leadingMarker +
                                                "Failed to send mail: " + err.toString());
                                }
                            });
                        }

                        if (err && exitOnFailure) {
                            // TODO: Remove this: this stop sending email!
                            logger.warn("Aborting.");
                            process.exit(err.code);
                        }
                    }
                );
            },
            start: true
        };
        if (timeZone) {
            cronJobOpts.timeZone = timeZone;
        }

        var job = new CronJob(cronJobOpts);
        logger.info(parsed);
    });
};

var main = exports.main = function main(argv){
    var parser = new argparse.ArgumentParser({
        addHelp: true,
    });

    parser.addArgument("crontab", {
        help: "crontab file that defines jobs to schedule, one per line"
    });

    parser.addArgument("--exit-on-failure", {
        help: "Any of jobs ends with status code other than 0, exit with that code",
        action: "storeTrue",
        defaultValue: false
    });

    parser.addArgument("--timezone", {
        help: "Timezone of cron job definitions"
    });

    parser.addArgument("--mailto", {
        help: "Email address to send result to",
        metavar: "ADDRESS"
    });

    parser.addArgument("--smtp-host", {
        help: "SMTP host to use to send emails",
        metavar: "HOST"
    });
    parser.addArgument("--smtp-port", {
        help: "SMTP port to use to send emails",
        type: "int",
        metavar: "PORT"
    });
    parser.addArgument("--smtp-user", {
        help: "SMTP username to use to send emails",
        metavar: "USERNAME"
    });
    parser.addArgument("--smtp-pass", {
        help: "SMTP password to use to send emails",
        metavar: "PASSWORD"
    });

    var args = parser.parseArgs(argv.slice(2));

    var crontab = args.crontab;
    var exitOnFailure = args.exit_on_failure;
    var timeZone = args.timezone;

    // Mail configurations
    var mailto = args.mailto || process.env.CRON_JS_MAILTO || null;
    var smtpHost = args.smtp_host || process.env.CRON_JS_SMTP_HOST || null;
    var smtpPort = args.smtp_port || parseInt(process.env.CRON_JS_SMTP_PORT, 10) || 0;
    var smtpUser = args.smtp_user || process.env.CRON_JS_SMTP_USER || null;
    var smtpPass = args.smtp_pass || process.env.CRON_JS_SMTP_PASS || null;

    var smtpSecure = (smtpPort === 465);

    start(crontab, {
        exitOnFailure: exitOnFailure,
        timeZone: timeZone,
        mailto: mailto,
        smtpHost: smtpHost,
        smtpPort: smtpPort,
        smtpSecure: smtpSecure,
        smtpUser: smtpUser,
        smtpPass: smtpPass
    })
    return 0;
};
<commit_msg>Remove some TODOs<commit_after>/*
 * Copyright (c) 2017 10sr <8.slashes@gmail.com>
 * Licensed under the Apache License, Version 2.0
 */

var readline = require("readline");
var fs = require("fs");
var childProcess = require("child_process");
var os = require("os");

var CronJob = require("cron").CronJob;
var nodemailer = require("nodemailer");
var logger = require("log4js").getLogger();
var argparse = require("argparse");

var parseCrontabRe = new RegExp(/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$/);

var SENDER_DEFAULT = os.userInfo().username + "@" + os.hostname();

function createMailTransporter(opts){
    if (!opts.mailto) {
        return null;
    }

    logger.info("Setting up email notification");
    logger.info("Sender: " + SENDER_DEFAULT);
    logger.info("Mailto: " + opts.mailto);
    var mailDefaults = {
        from: SENDER_DEFAULT,
        to: opts.mailto
    };

    if (opts.smtpHost || opts.smtpPort ||
        opts.smtpUser || opts.smtpPass) {
        logger.info("Use SMTP to send emails");
        return nodemailer.createTransport({
            host: opts.smtpHost,
            port: opts.smtpPort,
            secure: opts.smtpSecure,
            auth: {
                user: opts.smtpUser,
                pass: opts.smtpPass
            }
        }, mailDefaults);
    } else {
        logger.info("Use sendmail to send emails");
        return nodemailer.createTransport({
            sendmail: true,
            newline: "unix"
        }, mailDefaults);
    }
}

function parseCrontab(line){
    var matched = parseCrontabRe.exec(line);
    if (!matched) {
        throw Error("Failed to parse crontab line: " + line);
    }
    return {
        cronTime: [
            matched[1], matched[2], matched[3],
            matched[4], matched[5], matched[6]
        ].join(" "),
        command: matched[7]
    }
}

var start = exports.start = function start(crontab, opts){
    var exitOnFailure = Boolean(opts.exitOnFailure);
    var timeZone = opts.timeZone || null;
    var mailTransporter = createMailTransporter(opts);

    var rl = readline.createInterface({
        input: fs.createReadStream(crontab)
    });

    rl.on("line", function(line){
        if (line.match(/^#/)) {
            return;
        }
        var parsed = parseCrontab(line);
        var cronJobOpts = {
            cronTime: parsed.cronTime,
            onTick: function(){
                var currentTime = new Date();
                // TODO: use timezone
                var dateStr = currentTime.toISOString();
                var leadingMarker = dateStr + " | " + parsed.command + " | ";
                var proc = childProcess.exec(
                    parsed.command,
                    {},
                    function(err, stdout, stderr){
                        logger.info(leadingMarker + "stdout: " + stdout.trim());
                        logger.info(leadingMarker + "stderr: " + stderr.trim());
                        if (err) {
                            logger.warn(leadingMarker + "error:  " + err.toString())
                            logger.warn(leadingMarker + "exited with code " +
                                        err.code.toString());
                        } else {
                            logger.info(leadingMarker + "exited with code 0")
                        }

                        if (mailTransporter) {
                            logger.debug(leadingMarker +
                                        "Sending email to " + opts.mailto);
                            var mailText = "stdout:\n\n" + stdout +
                                "\n\nstderr:\n\n" + stderr;
                            if (err) {
                                mailText = mailText + "\n\nerror: " + err.toString() +
                                    "\n\nExit code: " + err.code.toString();
                            }
                            var mailSubject = "Cron-JS <" + SENDER_DEFAULT +
                                "> " + parsed.command;
                            mailTransporter.sendMail({
                                subject: mailSubject,
                                text: mailText
                            }, function(err, info){
                                if (err) {
                                    logger.warn(leadingMarker +
                                                "Failed to send mail: " + err.toString());
                                }
                            });
                        }

                        if (err && exitOnFailure) {
                            logger.warn("Aborting.");
                            process.exit(err.code);
                        }
                    }
                );
            },
            start: true
        };
        if (timeZone) {
            cronJobOpts.timeZone = timeZone;
        }

        var job = new CronJob(cronJobOpts);
        logger.info(parsed);
    });
};

var main = exports.main = function main(argv){
    var parser = new argparse.ArgumentParser({
        addHelp: true,
    });

    parser.addArgument("crontab", {
        help: "crontab file that defines jobs to schedule, one per line"
    });

    parser.addArgument("--exit-on-failure", {
        help: "Any of jobs ends with status code other than 0, exit with that code",
        action: "storeTrue",
        defaultValue: false
    });

    parser.addArgument("--timezone", {
        help: "Timezone of cron job definitions"
    });

    parser.addArgument("--mailto", {
        help: "Email address to send result to",
        metavar: "ADDRESS"
    });

    parser.addArgument("--smtp-host", {
        help: "SMTP host to use to send emails",
        metavar: "HOST"
    });
    parser.addArgument("--smtp-port", {
        help: "SMTP port to use to send emails",
        type: "int",
        metavar: "PORT"
    });
    parser.addArgument("--smtp-user", {
        help: "SMTP username to use to send emails",
        metavar: "USERNAME"
    });
    parser.addArgument("--smtp-pass", {
        help: "SMTP password to use to send emails",
        metavar: "PASSWORD"
    });

    var args = parser.parseArgs(argv.slice(2));

    var crontab = args.crontab;
    var exitOnFailure = args.exit_on_failure;
    var timeZone = args.timezone;

    // Mail configurations
    var mailto = args.mailto || process.env.CRON_JS_MAILTO || null;
    var smtpHost = args.smtp_host || process.env.CRON_JS_SMTP_HOST || null;
    var smtpPort = args.smtp_port || parseInt(process.env.CRON_JS_SMTP_PORT, 10) || 0;
    var smtpUser = args.smtp_user || process.env.CRON_JS_SMTP_USER || null;
    var smtpPass = args.smtp_pass || process.env.CRON_JS_SMTP_PASS || null;

    var smtpSecure = (smtpPort === 465);

    start(crontab, {
        exitOnFailure: exitOnFailure,
        timeZone: timeZone,
        mailto: mailto,
        smtpHost: smtpHost,
        smtpPort: smtpPort,
        smtpSecure: smtpSecure,
        smtpUser: smtpUser,
        smtpPass: smtpPass
    })
    return 0;
};
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Client = require(__dirname+'/client');
var defaults =  require(__dirname + '/defaults');

//external genericPool module
var genericPool = require('generic-pool');

//cache of existing client pools
var pools = {};

var PG = function(clientConstructor) {
  EventEmitter.call(this);
  this.Client = clientConstructor;
  this.Connection = require(__dirname + '/connection');
  this.Query = clientConstructor.Query
  this.defaults = defaults;
};

util.inherits(PG, EventEmitter);

PG.prototype.end = function() {
  Object.keys(pools).forEach(function(name) {
    var pool = pools[name];
    pool.drain(function() {
      pool.destroyAllNow();
    });
  })
}

PG.prototype.connect = function(config, callback) {
  var self = this;
  var c = config;
  var cb = callback;
  //allow for no config to be passed
  if(typeof c === 'function') {
    cb = c;
    c = defaults;
  }

  //get unique pool name even if object was used as config
  var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database;
  var pool = pools[poolName];

  if(pool) return pool.acquire(cb);

  var pool = pools[poolName] = genericPool.Pool({
    name: poolName,
    create: function(callback) {
      var client = new self.Client(c);
      client.connect(function(err) {
        if(err) return callback(err);

        //handle connected client background errors by emitting event
        //via the pg object and then removing errored client from the pool
        client.on('error', function(e) {
          self.emit('error', e, client);
          pool.destroy(client);
        });

        callback(null, client);
      });

      client.on('drain', function() {
        pool.release(client);
      });
    },
    destroy: function(client) {
      client.end();
    },
    max: defaults.poolSize,
    idleTimeoutMillis: defaults.poolIdleTimeout,
    reapIntervalMillis: defaults.reapIntervalMillis,
    log: defaults.poolLog
  });
  return pool.acquire(cb);
}

// cancel the query runned by the given client
PG.prototype.cancel = function(config, client, query) {
  var c = config;
  //allow for no config to be passed
  if(typeof c === 'function')
    c = defaults;
  var cancellingClient = new this.Client(c);
  cancellingClient.cancel(client, query);
}

module.exports = new PG(Client);

//lazy require native module...the native module may not have installed
module.exports.__defineGetter__("native", function() {
  delete module.exports.native;
  return (module.exports.native = new PG(require(__dirname + '/native')));
});

module.exports.types = require('./types');
<commit_msg>fix jshint errors for lib/index.js<commit_after>var EventEmitter = require('events').EventEmitter;
var util = require('util');
var Client = require(__dirname+'/client');
var defaults =  require(__dirname + '/defaults');

//external genericPool module
var genericPool = require('generic-pool');

//cache of existing client pools
var pools = {};

var PG = function(clientConstructor) {
  EventEmitter.call(this);
  this.Client = clientConstructor;
  this.Connection = require(__dirname + '/connection');
  this.Query = clientConstructor.Query;
  this.defaults = defaults;
};

util.inherits(PG, EventEmitter);

PG.prototype.end = function() {
  Object.keys(pools).forEach(function(name) {
    var pool = pools[name];
    pool.drain(function() {
      pool.destroyAllNow();
    });
  });
};

PG.prototype.connect = function(config, callback) {
  var self = this;
  var c = config;
  var cb = callback;
  //allow for no config to be passed
  if(typeof c === 'function') {
    cb = c;
    c = defaults;
  }

  //get unique pool name even if object was used as config
  var poolName = typeof(c) === 'string' ? c : c.user+c.host+c.port+c.database;
  var pool = pools[poolName];

  if(pool) { return pool.acquire(cb); }

  pool = pools[poolName] = genericPool.Pool({
    name: poolName,
    create: function(callback) {
      var client = new self.Client(c);
      client.connect(function(err) {
        if(err) { return callback(err); }

        //handle connected client background errors by emitting event
        //via the pg object and then removing errored client from the pool
        client.on('error', function(e) {
          self.emit('error', e, client);
          pool.destroy(client);
        });

        callback(null, client);
      });

      client.on('drain', function() {
        pool.release(client);
      });
    },
    destroy: function(client) {
      client.end();
    },
    max: defaults.poolSize,
    idleTimeoutMillis: defaults.poolIdleTimeout,
    reapIntervalMillis: defaults.reapIntervalMillis,
    log: defaults.poolLog
  });
  return pool.acquire(cb);
};

// cancel the query runned by the given client
PG.prototype.cancel = function(config, client, query) {
  var c = config;
  //allow for no config to be passed
  if(typeof c === 'function') {
    c = defaults;
  }
  var cancellingClient = new this.Client(c);
  cancellingClient.cancel(client, query);
};

module.exports = new PG(Client);

//lazy require native module...the native module may not have installed
module.exports.__defineGetter__("native", function() {
  delete module.exports.native;
  return (module.exports.native = new PG(require(__dirname + '/native')));
});

module.exports.types = require('./types');
<|endoftext|>


<commit_before>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

'use strict';

// Include Gulp & tools we'll use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var merge = require('merge-stream');
var path = require('path');
var fs = require('fs');
var glob = require('glob');
var historyApiFallback = require('connect-history-api-fallback');
var packageJson = require('./package.json');
var crypto = require('crypto');
var polybuild = require('polybuild');

var AUTOPREFIXER_BROWSERS = [
  'ie >= 10',
  'ie_mob >= 10',
  'ff >= 30',
  'chrome >= 34',
  'safari >= 7',
  'opera >= 23',
  'ios >= 7',
  'android >= 4.4',
  'bb >= 10'
];

var styleTask = function (stylesPath, srcs) {
  return gulp.src(srcs.map(function(src) {
      return path.join('app', stylesPath, src);
    }))
    .pipe($.changed(stylesPath, {extension: '.css'}))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp/' + stylesPath))
    .pipe($.cssmin())
    .pipe(gulp.dest('dist/' + stylesPath))
    .pipe($.size({title: stylesPath}));
};

// Compile and automatically prefix stylesheets
gulp.task('styles', function () {
  return styleTask('styles', ['**/*.css']);
});

gulp.task('elements', function () {
  return styleTask('elements', ['**/*.css']);
});

// Lint JavaScript
gulp.task('jshint', function () {
  return gulp.src([
      'app/scripts/**/*.js',
      'app/elements/**/*.js',
      'app/elements/**/*.html'
    ])
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint.extract()) // Extract JS from .html files
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

// Optimize images
gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'images'}));
});

// Copy all files at the root level (app)
gulp.task('copy', function () {
  var app = gulp.src([
    'app/*',
    '!app/test',
    '!app/cache-config.json'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));

  var bower = gulp.src([
    'bower_components/**/*'
  ]).pipe(gulp.dest('dist/bower_components'));

  var elements = gulp.src(['app/elements/**/*.html'])
    .pipe(gulp.dest('dist/elements'));

  var swBootstrap = gulp.src(['bower_components/platinum-sw/bootstrap/*.js'])
    .pipe(gulp.dest('dist/elements/bootstrap'));

  var swToolbox = gulp.src(['bower_components/sw-toolbox/*.js'])
    .pipe(gulp.dest('dist/sw-toolbox'));

  var vulcanized = gulp.src(['app/elements/elements.html'])
    .pipe($.rename('elements.vulcanized.html'))
    .pipe(gulp.dest('dist/elements'));

  return merge(app, bower, elements, vulcanized, swBootstrap, swToolbox)
    .pipe($.size({title: 'copy'}));
});

// Copy web fonts to dist
gulp.task('fonts', function () {
  return gulp.src(['app/fonts/**'])
    .pipe(gulp.dest('dist/fonts'))
    .pipe($.size({title: 'fonts'}));
});

// Scan your HTML for assets & optimize them
gulp.task('html', function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', 'dist']});

  return gulp.src(['app/**/*.html', '!app/{elements,test}/**/*.html'])
    // Replace path for vulcanized assets
    .pipe($.if('*.html', $.replace('elements/elements.html', 'elements/elements.vulcanized.html')))
    .pipe(assets)
    // Concatenate and minify JavaScript
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    // Concatenate and minify styles
    // In case you are still using useref build blocks
    .pipe($.if('*.css', $.cssmin()))
    .pipe(assets.restore())
    .pipe($.useref())
    // Minify any HTML
    .pipe($.if('*.html', $.minifyHtml({
      quotes: true,
      empty: true,
      spare: true
    })))
    // Output files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});

// Polybuild will take care of inlining HTML imports,
// scripts and CSS for you.
gulp.task('vulcanize', function () {
  return gulp.src('dist/index.html')
    .pipe(polybuild({maximumCrush: true}))
    .pipe(gulp.dest('dist/'));
});

// If you require more granular configuration of Vulcanize
// than polybuild provides, follow instructions from readme at:
// https://github.com/PolymerElements/polymer-starter-kit/#if-you-require-more-granular-configuration-of-vulcanize-than-polybuild-provides-you-an-option-by

// Rename Polybuild's index.build.html to index.html
gulp.task('rename-index', function () {
  gulp.src('dist/index.build.html')
    .pipe($.rename('index.html'))
    .pipe(gulp.dest('dist/'));
  return del(['dist/index.build.html']);
});

// Generate config data for the <sw-precache-cache> element.
// This include a list of files that should be precached, as well as a (hopefully unique) cache
// id that ensure that multiple PSK projects don't share the same Cache Storage.
// This task does not run by default, but if you are interested in using service worker caching
// in your project, please enable it within the 'default' task.
// See https://github.com/PolymerElements/polymer-starter-kit#enable-service-worker-support
// for more context.
gulp.task('cache-config', function (callback) {
  var dir = 'dist';
  var config = {
    cacheId: packageJson.name || path.basename(__dirname),
    disabled: false
  };

  glob('{elements,scripts,styles}/**/*.*', {cwd: dir}, function(error, files) {
    if (error) {
      callback(error);
    } else {
      files.push('index.html', './', 'bower_components/webcomponentsjs/webcomponents-lite.min.js');
      config.precache = files;

      var md5 = crypto.createHash('md5');
      md5.update(JSON.stringify(config.precache));
      config.precacheFingerprint = md5.digest('hex');

      var configPath = path.join(dir, 'cache-config.json');
      fs.writeFile(configPath, JSON.stringify(config), callback);
    }
  });
});

// Clean output directory
gulp.task('clean', function (cb) {
  del(['.tmp', 'dist'], cb);
});

// Watch files for changes & reload
gulp.task('serve', ['styles', 'elements', 'images'], function () {
  browserSync({
    port: 5000,
    notify: false,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: {
      baseDir: ['.tmp', 'app'],
      middleware: [ historyApiFallback() ],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch(['app/**/*.html'], reload);
  gulp.watch(['app/styles/**/*.css'], ['styles', reload]);
  gulp.watch(['app/elements/**/*.css'], ['elements', reload]);
  gulp.watch(['app/{scripts,elements}/**/{*.js,*.html}'], ['jshint']);
  gulp.watch(['app/images/**/*'], reload);
});

// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function () {
  browserSync({
    port: 5001,
    notify: false,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: 'dist',
    middleware: [ historyApiFallback() ]
  });
});

// Build production files, the default task
gulp.task('default', ['clean'], function (cb) {
  // Uncomment 'cache-config' after 'rename-index' if you are going to use service workers.
  runSequence(
    ['copy', 'styles'],
    'elements',
    ['jshint', 'images', 'fonts', 'html'],
    'vulcanize','rename-index', // 'cache-config',
    cb);
});

// Load tasks for web-component-tester
// Adds tasks for `gulp test:local` and `gulp test:remote`
require('web-component-tester').gulp.init(gulp);

// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks'); } catch (err) {}
<commit_msg>Check gulpfile.js with jshint<commit_after>/*
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/

'use strict';

// Include Gulp & tools we'll use
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var del = require('del');
var runSequence = require('run-sequence');
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var merge = require('merge-stream');
var path = require('path');
var fs = require('fs');
var glob = require('glob');
var historyApiFallback = require('connect-history-api-fallback');
var packageJson = require('./package.json');
var crypto = require('crypto');
var polybuild = require('polybuild');

var AUTOPREFIXER_BROWSERS = [
  'ie >= 10',
  'ie_mob >= 10',
  'ff >= 30',
  'chrome >= 34',
  'safari >= 7',
  'opera >= 23',
  'ios >= 7',
  'android >= 4.4',
  'bb >= 10'
];

var styleTask = function (stylesPath, srcs) {
  return gulp.src(srcs.map(function(src) {
      return path.join('app', stylesPath, src);
    }))
    .pipe($.changed(stylesPath, {extension: '.css'}))
    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
    .pipe(gulp.dest('.tmp/' + stylesPath))
    .pipe($.cssmin())
    .pipe(gulp.dest('dist/' + stylesPath))
    .pipe($.size({title: stylesPath}));
};

// Compile and automatically prefix stylesheets
gulp.task('styles', function () {
  return styleTask('styles', ['**/*.css']);
});

gulp.task('elements', function () {
  return styleTask('elements', ['**/*.css']);
});

// Lint JavaScript
gulp.task('jshint', function () {
  return gulp.src([
      'app/scripts/**/*.js',
      'app/elements/**/*.js',
      'app/elements/**/*.html',
      'gulpfile.js'
    ])
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint.extract()) // Extract JS from .html files
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

// Optimize images
gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true
    })))
    .pipe(gulp.dest('dist/images'))
    .pipe($.size({title: 'images'}));
});

// Copy all files at the root level (app)
gulp.task('copy', function () {
  var app = gulp.src([
    'app/*',
    '!app/test',
    '!app/cache-config.json'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));

  var bower = gulp.src([
    'bower_components/**/*'
  ]).pipe(gulp.dest('dist/bower_components'));

  var elements = gulp.src(['app/elements/**/*.html'])
    .pipe(gulp.dest('dist/elements'));

  var swBootstrap = gulp.src(['bower_components/platinum-sw/bootstrap/*.js'])
    .pipe(gulp.dest('dist/elements/bootstrap'));

  var swToolbox = gulp.src(['bower_components/sw-toolbox/*.js'])
    .pipe(gulp.dest('dist/sw-toolbox'));

  var vulcanized = gulp.src(['app/elements/elements.html'])
    .pipe($.rename('elements.vulcanized.html'))
    .pipe(gulp.dest('dist/elements'));

  return merge(app, bower, elements, vulcanized, swBootstrap, swToolbox)
    .pipe($.size({title: 'copy'}));
});

// Copy web fonts to dist
gulp.task('fonts', function () {
  return gulp.src(['app/fonts/**'])
    .pipe(gulp.dest('dist/fonts'))
    .pipe($.size({title: 'fonts'}));
});

// Scan your HTML for assets & optimize them
gulp.task('html', function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', 'dist']});

  return gulp.src(['app/**/*.html', '!app/{elements,test}/**/*.html'])
    // Replace path for vulcanized assets
    .pipe($.if('*.html', $.replace('elements/elements.html', 'elements/elements.vulcanized.html')))
    .pipe(assets)
    // Concatenate and minify JavaScript
    .pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
    // Concatenate and minify styles
    // In case you are still using useref build blocks
    .pipe($.if('*.css', $.cssmin()))
    .pipe(assets.restore())
    .pipe($.useref())
    // Minify any HTML
    .pipe($.if('*.html', $.minifyHtml({
      quotes: true,
      empty: true,
      spare: true
    })))
    // Output files
    .pipe(gulp.dest('dist'))
    .pipe($.size({title: 'html'}));
});

// Polybuild will take care of inlining HTML imports,
// scripts and CSS for you.
gulp.task('vulcanize', function () {
  return gulp.src('dist/index.html')
    .pipe(polybuild({maximumCrush: true}))
    .pipe(gulp.dest('dist/'));
});

// If you require more granular configuration of Vulcanize
// than polybuild provides, follow instructions from readme at:
// https://github.com/PolymerElements/polymer-starter-kit/#if-you-require-more-granular-configuration-of-vulcanize-than-polybuild-provides-you-an-option-by

// Rename Polybuild's index.build.html to index.html
gulp.task('rename-index', function () {
  gulp.src('dist/index.build.html')
    .pipe($.rename('index.html'))
    .pipe(gulp.dest('dist/'));
  return del(['dist/index.build.html']);
});

// Generate config data for the <sw-precache-cache> element.
// This include a list of files that should be precached, as well as a (hopefully unique) cache
// id that ensure that multiple PSK projects don't share the same Cache Storage.
// This task does not run by default, but if you are interested in using service worker caching
// in your project, please enable it within the 'default' task.
// See https://github.com/PolymerElements/polymer-starter-kit#enable-service-worker-support
// for more context.
gulp.task('cache-config', function (callback) {
  var dir = 'dist';
  var config = {
    cacheId: packageJson.name || path.basename(__dirname),
    disabled: false
  };

  glob('{elements,scripts,styles}/**/*.*', {cwd: dir}, function(error, files) {
    if (error) {
      callback(error);
    } else {
      files.push('index.html', './', 'bower_components/webcomponentsjs/webcomponents-lite.min.js');
      config.precache = files;

      var md5 = crypto.createHash('md5');
      md5.update(JSON.stringify(config.precache));
      config.precacheFingerprint = md5.digest('hex');

      var configPath = path.join(dir, 'cache-config.json');
      fs.writeFile(configPath, JSON.stringify(config), callback);
    }
  });
});

// Clean output directory
gulp.task('clean', function (cb) {
  del(['.tmp', 'dist'], cb);
});

// Watch files for changes & reload
gulp.task('serve', ['styles', 'elements', 'images'], function () {
  browserSync({
    port: 5000,
    notify: false,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: {
      baseDir: ['.tmp', 'app'],
      middleware: [ historyApiFallback() ],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch(['app/**/*.html'], reload);
  gulp.watch(['app/styles/**/*.css'], ['styles', reload]);
  gulp.watch(['app/elements/**/*.css'], ['elements', reload]);
  gulp.watch(['app/{scripts,elements}/**/{*.js,*.html}'], ['jshint']);
  gulp.watch(['app/images/**/*'], reload);
});

// Build and serve the output from the dist build
gulp.task('serve:dist', ['default'], function () {
  browserSync({
    port: 5001,
    notify: false,
    logPrefix: 'PSK',
    snippetOptions: {
      rule: {
        match: '',
        fn: function (snippet) {
          return snippet;
        }
      }
    },
    // Run as an https by uncommenting 'https: true'
    // Note: this uses an unsigned certificate which on first access
    //       will present a certificate warning in the browser.
    // https: true,
    server: 'dist',
    middleware: [ historyApiFallback() ]
  });
});

// Build production files, the default task
gulp.task('default', ['clean'], function (cb) {
  // Uncomment 'cache-config' after 'rename-index' if you are going to use service workers.
  runSequence(
    ['copy', 'styles'],
    'elements',
    ['jshint', 'images', 'fonts', 'html'],
    'vulcanize','rename-index', // 'cache-config',
    cb);
});

// Load tasks for web-component-tester
// Adds tasks for `gulp test:local` and `gulp test:remote`
require('web-component-tester').gulp.init(gulp);

// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks'); } catch (err) {}
<|endoftext|>


<commit_before>/*
* To use this with require.js AND the node.js module system (on server and client side).
* see https://github.com/jrburke/amdefine
*/
if (typeof define !== 'function') { var define = require('amdefine')(module); }

/**
 * @module
 * @private
 */
define(function(require, exports, module) {

	var ScreenArranger = function (session) {
		this.session = session;
		this.screens = {};
		this.width = 0;
		this.height = 0;

		this.arrange();
		session.on('playerJoined', this.onPlayerJoined.bind(this));
		session.on('playerLeft', this.onPlayerLeft.bind(this));
	};

	ScreenArranger.prototype.localToGlobal = function (player, x, y) {
		var screen = this.screens[player.id];
		var globalX = screen.left + x;
		var globalY = screen.top + y;
		return {x: globalX, y: globalY };
	};

	ScreenArranger.prototype.globalToLocal = function (x, y) {
		var player = this.getPlayerAtCoords(x, y);
		var screen = this.screens[player.id];
		var localX = x - screen.left;
		var localY = y - screen.top;
		return {player: player, x: localX, y: localY };
	};

	ScreenArranger.prototype.isScreenHit = function (screen, x, y) {
		return x >= screen.left &&
			x < screen.left + screen.player.width &&
			y >= screen.top &&
			y < screen.top + screen.player.height;
	};

	ScreenArranger.prototype.isPlayerHit = function (player, x, y) {
		return this.isScreenHit(this.screens[player.id], x, y);
	};

	ScreenArranger.prototype.getPlayerAtCoords = function (x, y) {
		for (var i in this.screens) {
			var screen = this.screens[i];
			if (this.isScreenHit(screen, x, y)) {
				return screen.player;
			}
		}
		return null;
	};

	ScreenArranger.prototype.arrange = function () {
		var screens = {};
		var height = 0;
		var xPos = 0;
		this.session.getPlayerArray().forEach(function (player) {
			screens[player.id] = {
				top: 0,
				left: xPos,
				player: player
			};
			height = Math.max(height, player.height);
			xPos += player.width;
		});

		this.screens = screens;
		this.width = xPos;
		this.height = height;
	};

	ScreenArranger.prototype.onPlayerJoined = function (event) {
		this.arrange();
	};

	ScreenArranger.prototype.onPlayerLeft = function (event) {
		this.arrange();
	};

	exports.ScreenArranger = ScreenArranger;
	return exports;

 });<commit_msg>Documented ScreenArranger<commit_after>/*
* To use this with require.js AND the node.js module system (on server and client side).
* see https://github.com/jrburke/amdefine
*/
if (typeof define !== 'function') { var define = require('amdefine')(module); }

/**
 * This module contains all classes and utils that are useful
 * for working with multiple screens. Currently that's only the
 * {@link module:shared/screen.ScreenArranger ScreenArranger}.
 * @module shared/screen
 */
define(function(require, exports, module) {

	/**
	 * @classdesc This class can be used to arrange multiple clients
	 * into one big game screen. It does rearrange every time a player
	 * joins or leaves the given session.<br>
	 * You can influence the behaviour by using this class as the base
	 * of your own Arranger class.
	 * @class
	 * @param {module:client/session~Session|module:server/session~Session}
	 *  Session that contains the players that should be arranged into
	 *  one big screen.
	 */
	exports.ScreenArranger = function (session) {
		/**
		 * Session that is getting arranged into one big game screen
		 * @type {module:client/session~Session|module:server/session~Session}
		 * @readonly
		 */
		this.session = session;
		/**
		 * Contains one screen object for every player id
		 * A screen object consists of player, x and y attributes.
		 * @type {Object.<string, object>}
		 * @private
		 */
		this.screens = {};
		/**
		 * total width of the big screen in pixel
		 * @type {integer}
		 * @readonly
		 */
		this.width = 0;
		/**
		 * total height of the big screen in pixel
		 * @type {integer}
		 * @readonly
		 */
		this.height = 0;

		this.arrange();
		session.on('playerJoined', this.onPlayerJoined.bind(this));
		session.on('playerLeft', this.onPlayerLeft.bind(this));
	};

	/**
	 * Converts local pixel coordinates to global ones.
	 * @param  {module:server/player~Player|module:client/player~Player} player
	 * player instance the local coordinates refer to
	 * @param  {integer} x  local x position in pixel
	 * @param  {integer} y  local y position in pixel
	 * @return {object}  { x: globalX, y: globalY }
	 */
	exports.ScreenArranger.prototype.localToGlobal = function (player, x, y) {
		var screen = this.screens[player.id];
		var globalX = screen.left + x;
		var globalY = screen.top + y;
		return {x: globalX, y: globalY };
	};

	/**
	 * Converts global pixel coordinates into their corresponding
	 * local ones.
	 * @param  {integer} x  global x position in pixel
	 * @param  {integer} y  global y position in pixel
	 * @return {object}  { player: localPlayer, x: localX, y: localY }
	 */
	exports.ScreenArranger.prototype.globalToLocal = function (x, y) {
		var player = this.getPlayerAtCoords(x, y);
		var screen = this.screens[player.id];
		var localX = x - screen.left;
		var localY = y - screen.top;
		return {player: player, x: localX, y: localY };
	};

	/**
	 * @param  {object}  screen  any screen object that should be tested
	 * @param  {integer}  x  global x position in pixel
	 * @param  {integer}  y  global y position in pixel
	 * @return {boolean}  true if the given global coordinates lie inside
	 * the given screen object, else false
	 * @private
	 */
	exports.ScreenArranger.prototype.isScreenHit = function (screen, x, y) {
		return x >= screen.left &&
			x < screen.left + screen.player.width &&
			y >= screen.top &&
			y < screen.top + screen.player.height;
	};

	/**
	 * @param  {module:server/player~Player|module:client/player~Player} player
	 * any player object connected to the arranged session
	 * @param  {integer}  x  global x position in pixel
	 * @param  {integer}  y  global y position in pixel
	 * @return {boolean}  true if the given coordinates lie within
	 * the screen of the given player
	 */
	exports.ScreenArranger.prototype.isPlayerHit = function (player, x, y) {
		return this.isScreenHit(this.screens[player.id], x, y);
	};

	/**
	 * @param  {integer}  x  global x position in pixel
	 * @param  {integer}  y  global y position in pixel
	 * @return {module:server/player~Player|module:client/player~Player}
	 * player object whose screen lies beneath the given coordinates
	 * or null when no player can be found at this position
	 */
	exports.ScreenArranger.prototype.getPlayerAtCoords = function (x, y) {
		for (var i in this.screens) {
			var screen = this.screens[i];
			if (this.isScreenHit(screen, x, y)) {
				return screen.player;
			}
		}
		return null;
	};

	/**
	 * Rearranges the screens of all players currently connected to
	 * the arranged session. Width, height and other attributes
	 * will be recalculated and may change.
	 * @private
	 */
	exports.ScreenArranger.prototype.arrange = function () {
		var screens = {};
		var height = 0;
		var xPos = 0;
		this.session.getPlayerArray().forEach(function (player) {
			screens[player.id] = {
				top: 0,
				left: xPos,
				player: player
			};
			height = Math.max(height, player.height);
			xPos += player.width;
		});

		this.screens = screens;
		this.width = xPos;
		this.height = height;
	};

	exports.ScreenArranger.prototype.onPlayerJoined = function (event) {
		this.arrange();
	};

	exports.ScreenArranger.prototype.onPlayerLeft = function (event) {
		this.arrange();
	};

	return exports;

 });<|endoftext|>


<commit_before><commit_msg>update jspm packages<commit_after><|endoftext|>


<commit_before>'use strict';

const path = require('path');

const async = require('async');

const merge = require(path.join(__dirname, 'merge'));

function index(env, callback) {
  if (!env.config.environments) {
    return callback(new Error('environments must be defined.'));
  }

  const environment = env.config.environments[env.mode] || {};

  merge(env.config, environment);

  async.forEachSeries(environment.plugins, (plugin, callback) => {
    env.loadPluginModule(plugin, callback);
  }, callback);
}

module.exports = index;
<commit_msg>Add logger messages<commit_after>'use strict';

const path = require('path');

const async = require('async');

const merge = require(path.join(__dirname, 'merge'));

function index(env, callback) {
  if (!env.config.environments) {
    return callback(new Error('environments must be defined.'));
  }

  const environment = env.config.environments[env.mode] || {};

  env.logger.verbose(`patching environment - mode: ${env.mode}`);
  merge(env.config, environment);
  env.logger.verbose('new config:', env.config);

  async.forEachSeries(environment.plugins, (plugin, callback) => {
    env.logger.verbose(`loading new plugin: ${plugin}`);
    env.loadPluginModule(plugin, callback);
  }, callback);
}

module.exports = index;
<|endoftext|>


<commit_before>/**
 * @jsx React.DOM
 */

var React = require('React');
var Site = require('Site');
var Prism = require('Prism');
var Marked = require('Marked');
var unindent = require('unindent');

var index = React.createClass({
  render: function() {
    return (
      <Site>

Flux

              Application Architecture for Building User Interfaces

              Flux is the application architecture that Facebook uses for building client-side web applications.  It complements React's composable view components by utilizing a unidirectional data flow.  It's more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code.

              Learn more about Flux

      </Site>
    );
  }
});

module.exports = index;
<commit_msg>translate to Korean - main page of website<commit_after>/**
 * @jsx React.DOM
 */

var React = require('React');
var Site = require('Site');
var Prism = require('Prism');
var Marked = require('Marked');
var unindent = require('unindent');

var index = React.createClass({
  render: function() {
    return (
      <Site>

Flux

              사용자 인터페이스를 만들기 위한 어플리케이션 아키텍쳐

              Flux는 Facebook에서 클라이언트-사이드 웹 어플리케이션을 만들기 위해 사용하는 어플리케이션 아키텍쳐다. 단방향 데이터 흐름을 활용하는 React의 구성형 뷰 컴포넌트를 보완한다. 이전의 프레임워크와 다르게 패턴에 가깝기 때문에, 새로운 많은 코드를 작성하는 과정 없이 Flux를 바로 사용할 수 있다.

              Flux에 대해 더 알아보기

      </Site>
    );
  }
});

module.exports = index;
<|endoftext|>


<commit_before>'use babel';

import { CompositeDisposable, Disposable } from 'atom';
import { View as RemplClientView, createElement as createRemplView } from './rempl-view';
import { View as ServerDialogView, createElement as createServerDialog } from './server-dialog-view';
import { View as StatusBarView, createElement as createStatusBar } from './status-bar';
import { EventTransport as Transport } from './transport';

const clients = new Map();
let DEFAULT_SERVER_URL = '';

atom.views.addViewProvider(RemplClientView, createRemplView);
atom.views.addViewProvider(ServerDialogView, createServerDialog);
atom.views.addViewProvider(StatusBarView, createStatusBar);

class RemplClient {
    activate() {
        let onChooseServer = () => {
            let serverUrl = this.serverInput.item.editor.getText();

            this.addClient(serverUrl);
            this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
            this.serverInput.hide();
        };
        let onCancelChoose = () => {
            if (this.serverInput.isVisible()) {
                this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
                this.serverInput.hide();
            }
        };

        this.disposable = new CompositeDisposable();
        this.disposable.add(atom.commands.add('atom-workspace', {
            'rempl:connect': () => {
                this.serverInput.show();
                this.serverInput.item.editor.element.focus();
            }
        }));

        if (!this.transport) {
            this.transport = new Transport('rempl-host', 'rempl-env');
        }

        this.transport.onConnect(api => api.send(this.getHostInfo()));

        this.disposable.add(this.transport);
        this.disposable.add(atom.config.observe('rempl-host.debug', value => this.transport.setDebug(value)));
        this.disposable.add(atom.config.observe('rempl-host.defaultHost', value => DEFAULT_SERVER_URL = value));
        this.serverInput = atom.workspace.addModalPanel({ item: new ServerDialogView(), visible: false });
        this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
        this.disposable.add(atom.commands.add(this.serverInput.item.editor.element, {
            'core:confirm': onChooseServer
        }));
        this.disposable.add(atom.commands.add(atom.views.getView(atom.workspace), {
            'core:cancel': onCancelChoose
        }));
        this.disposable.add(new Disposable(() => {
            this.serverInput.destroy();
        }));
        this.disposable.add(atom.workspace.onDidAddPaneItem(data => {
            if (data.item && data.item instanceof RemplClientView) {
                this.attachCallbacks(data.item);
            }
        }));
        this.disposable.add(atom.workspace.onDidDestroyPaneItem(data => {
            if (data.item && data.item instanceof RemplClientView) {
                this.removeClient(data.item);
            }
        }));
        this.disposable.add(atom.workspace.onDidChangeActivePaneItem(() => {
            let activePane = atom.workspace.getActivePane();
            let activeEditor = activePane.getActiveEditor();
            let activePaneItem = activePane.getActiveItem();

            if (activePaneItem) {
                let activeTitle = activePaneItem.getTitle();
                let payload = {
                    type: 'activeTabChanged',
                    tab: {
                        title: activeTitle,
                        grammar: activeEditor && activeEditor.getGrammar().name,
                        isEditor: !!activeEditor
                    }
                };

                this.broadcast(payload);
            }
        }));
    }

    getHostInfo() {
        return {
            type: 'hostInfo',
            host: {
                name: 'Atom',
                version: atom.getVersion()
            },
        };
    }

    attachCallbacks(item) {
        let view = atom.views.getView(item);

        view.addEventListener('attached', () => {
            this.transport.getEnv(view.iframe.contentWindow, api => {
                clients.set(item, api);
                api.subscribe(this.handleSubscriberMessage.bind(this, item));
                if (item.publisher.id) {
                    api.send({
                        type: 'setPublisher',
                        publisher: item.publisher
                    });
                }
            });
        });
        view.addEventListener('detached', () => this.removeClient(item));
    }

    addClient(url) {
        let clientModel = atom.workspace.getActivePane().addItem(new RemplClientView(url));

        atom.workspace.getActivePane().activateNextItem();

        return clientModel;
    }

    removeClient(model) {
        clients.delete(model);
        this.transport.cleanupTargets();
    }

    broadcast(payload) {
        clients.forEach(client => {
            client.send(payload);
        });
    }

    handleSubscriberMessage(subscriber, payload) {
        switch (payload.type) {
            case 'setStatusBarContent':
                this.statusBarTile.getItem().setContent(`Rempl: ${payload.content}`);
                break;
            case 'publisherChanged': {
                // fixme: maybe storeing pane item in clients-map is better solution
                let subscriberTab = atom.workspace.getPaneItems().filter(item => item == subscriber).pop();

                if (subscriberTab) {
                    subscriber.setPublisher(payload.publisher);
                    subscriber.updateTitle();
                }
                break;
            }
            case 'getHostInfo': {
                let api = clients.get(subscriber);

                if (api) {
                    api.send(this.getHostInfo());
                }
                break;
            }
        }
    }

    consumeStatusBar(statusBar) {
        this.statusBarTile = statusBar.addLeftTile({ item: new StatusBarView(), priority: 100 });
    }

    deactivate() {
        clients.forEach((api, client) => client.destroy());
        clients.clear();
        this.transport = null;
        this.statusBarTile.destroy();
        this.disposable.dispose();
    }

    deserializeClient(state) {
        if (!this.transport) {
            this.transport = new Transport('rempl-host', 'rempl-env');
        }

        if (state.url) {
            let clientModel = new RemplClientView(state.url, state.publisher);

            this.attachCallbacks(clientModel);

            return clientModel;
        }
    }
}

module.exports = new RemplClient();
module.exports.config = {
    defaultHost: {
        type: 'string',
        default: 'http://localhost:8177/',
        title: 'Rempl-server url by default'
    },
    debug: {
        type: 'boolean',
        default: false,
        title: 'Addition output to the devtools console'
    }
}
<commit_msg>added selectionChanged-event that sends to clients when selections in the active editor is changed some refactoring<commit_after>'use babel';

import { CompositeDisposable, Disposable } from 'atom';
import { View as RemplClientView, createElement as createRemplView } from './rempl-view';
import { View as ServerDialogView, createElement as createServerDialog } from './server-dialog-view';
import { View as StatusBarView, createElement as createStatusBar } from './status-bar';
import { EventTransport as Transport } from './transport';

const clients = new Map();
let DEFAULT_SERVER_URL = '';

atom.views.addViewProvider(RemplClientView, createRemplView);
atom.views.addViewProvider(ServerDialogView, createServerDialog);
atom.views.addViewProvider(StatusBarView, createStatusBar);

class RemplClient {
    activate() {
        let onChooseServer = () => {
            let serverUrl = this.serverInput.item.editor.getText();

            this.addClient(serverUrl);
            this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
            this.serverInput.hide();
        };
        let onCancelChoose = () => {
            if (this.serverInput.isVisible()) {
                this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
                this.serverInput.hide();
            }
        };

        this.disposable = new CompositeDisposable();
        this.disposable.add(atom.commands.add('atom-workspace', {
            'rempl:connect': () => {
                this.serverInput.show();
                this.serverInput.item.editor.element.focus();
            }
        }));

        if (!this.transport) {
            this.transport = new Transport('rempl-host', 'rempl-env');
        }

        this.transport.onConnect(api => api.send(this.getHostInfo()));

        this.disposable.add(this.transport);
        this.disposable.add(atom.config.observe('rempl-host.debug', value => this.transport.setDebug(value)));
        this.disposable.add(atom.config.observe('rempl-host.defaultHost', value => DEFAULT_SERVER_URL = value));
        this.serverInput = atom.workspace.addModalPanel({ item: new ServerDialogView(), visible: false });
        this.serverInput.item.editor.setText(DEFAULT_SERVER_URL);
        this.disposable.add(atom.commands.add(this.serverInput.item.editor.element, {
            'core:confirm': onChooseServer
        }));
        this.disposable.add(atom.commands.add(atom.views.getView(atom.workspace), {
            'core:cancel': onCancelChoose
        }));
        this.disposable.add(new Disposable(() => {
            this.serverInput.destroy();
        }));
        this.disposable.add(atom.workspace.onDidAddPaneItem(data => {
            if (data.item && data.item instanceof RemplClientView) {
                this.attachCallbacks(data.item);
            }
        }));
        this.disposable.add(atom.workspace.onDidDestroyPaneItem(data => {
            if (data.item && data.item instanceof RemplClientView) {
                this.removeClient(data.item);
            }
        }));
        this.activeEditor = {
            instance: null,
            disposable: new CompositeDisposable()
        };
        this.disposable.add(this.activeEditor.disposable);
        this.disposable.add(atom.workspace.onDidChangeActivePaneItem(item => {
            let editor = atom.workspace.getActiveTextEditor()

            this.sendPaneItemInfo(item);

            if (this.activeEditor.instance == editor) {
                return;
            }

            if (this.activeEditor.instance) {
                this.activeEditor.disposable.dispose();
                this.activeEditor.disposable = new CompositeDisposable();
            }

            this.activeEditor.instance = editor;

            if (editor) {
                // todo onDidChangeGrammar
                // todo onDidChangePath
                let selection = editor.onDidChangeSelectionRange(sr => this.sendSelectionsInfo(sr.selection.editor));

                this.activeEditor.disposable.add(selection);
            }
        }));
    }

    sendPaneItemInfo(item) {
        let editor = atom.workspace.getActiveTextEditor()

        let payload = {
            type: 'activeTabChanged',
            tab: null
        };

        if (item) {
            let activeTitle = item.getTitle();

            payload.tab = {
                title: activeTitle,
                isEditor: !!editor
            }

            if (editor) {
                payload.file = {
                    path: editor.getPath(),
                    name: editor.getFileName(),
                    grammar: editor.getGrammar().name,
                    exists: !!editor.getPath()
                };
                payload.selections = this.getEditorSelections(editor);
            }
        }

        this.broadcast(payload);

    }

    sendSelectionsInfo(editor) {
        if (editor) {
            let payload = {
                type: 'selectionChanged',
                selections: this.getEditorSelections(editor)
            };

            this.broadcast(payload);
        }
    }

    getEditorSelections(editor) {
        if (!editor) {
            return [];
        }

        return editor.getSelections()
            .map(selection => selection.getBufferRange())
            .map(range => {
                return {
                    start: {
                        line: range.start.row + 1,
                        column: range.start.column + 1
                    },
                    end: {
                        line: range.end.row + 1,
                        column: range.end.column + 1
                    }
                }
            });
    }

    getHostInfo() {
        return {
            type: 'hostInfo',
            host: {
                name: 'Atom',
                version: atom.getVersion()
            },
        };
    }

    attachCallbacks(item) {
        let view = atom.views.getView(item);

        view.addEventListener('attached', () => {
            this.transport.getEnv(view.iframe.contentWindow, api => {
                clients.set(item, api);
                api.subscribe(this.handleSubscriberMessage.bind(this, item));
                if (item.publisher.id) {
                    api.send({
                        type: 'setPublisher',
                        publisher: item.publisher
                    });
                }
            });
        });
        view.addEventListener('detached', () => this.removeClient(item));
    }

    addClient(url) {
        let clientModel = atom.workspace.getActivePane().addItem(new RemplClientView(url));

        atom.workspace.getActivePane().activateNextItem();

        return clientModel;
    }

    removeClient(model) {
        clients.delete(model);
        this.transport.cleanupTargets();
    }

    broadcast(payload) {
        clients.forEach(client => {
            client.send(payload);
        });
    }

    handleSubscriberMessage(subscriber, payload) {
        switch (payload.type) {
            case 'setStatusBarContent':
                this.statusBarTile.getItem().setContent(`Rempl: ${payload.content}`);
                break;
            case 'publisherChanged': {
                // fixme: maybe storeing pane item in clients-map is better solution
                let subscriberTab = atom.workspace.getPaneItems().filter(item => item == subscriber).pop();

                if (subscriberTab) {
                    subscriber.setPublisher(payload.publisher);
                    subscriber.updateTitle();
                }
                break;
            }
            case 'getHostInfo': {
                let api = clients.get(subscriber);

                if (api) {
                    api.send(this.getHostInfo());
                }
                break;
            }

            // todo case 'open':
        }
    }

    consumeStatusBar(statusBar) {
        this.statusBarTile = statusBar.addLeftTile({ item: new StatusBarView(), priority: 100 });
    }

    deactivate() {
        clients.forEach((api, client) => client.destroy());
        clients.clear();
        this.transport = null;
        this.activeEditor.instance = null;

        if (this.statusBarTile) {
            this.statusBarTile.destroy();
        }

        this.disposable.dispose();
    }

    deserializeClient(state) {
        if (!this.transport) {
            this.transport = new Transport('rempl-host', 'rempl-env');
        }

        if (state.url) {
            let clientModel = new RemplClientView(state.url, state.publisher);

            this.attachCallbacks(clientModel);

            return clientModel;
        }
    }
}

module.exports = new RemplClient();
module.exports.config = {
    defaultHost: {
        type: 'string',
        default: 'http://localhost:8177/',
        title: 'Rempl-server url by default'
    },
    debug: {
        type: 'boolean',
        default: false,
        title: 'Addition output to the devtools console'
    }
}
<|endoftext|>


<commit_before>/*
 * index.js: Top-level include for the smart-private-npm for serving all CouchDB traffic.
 *
 * (C) 2013, Nodejitsu Inc.
 *
 */

var createServers = require('create-servers'),
    director = require('director');

var patterns = {
  packageAnd:  /\/([_\.\(\)!\\ %@&a-zA-Z0-9-]+)\/.*/,
  packageOnly: /\/([_\.\(\)!\\ %@&a-zA-Z0-9-]+)/,
  wildcard:    /\*$/
};

//
// Export the NpmProxy.
//
exports.Proxy = require('./npm-proxy');

//
// ### function createServer (options, callback)
// #### @options {Object} Options for creating the proxy server.
// ####   - http     {Object|number} HTTP options.
// ####   - https    {Object}        HTTPS options.
// ####   - log      {function}      Logging function to use.
// ####   - proxy    {NpmProxy}      Options for the npm Proxy itself.
// ####   - rewrites {Array}         **Optional** All known rewrites to the npm registry.
//
exports.createServer = function (options, callback) {
  var router = exports.createRouter({
    rewrites: options.rewrites,
    proxy:    new exports.Proxy(options.proxy),
    log:      options.log
  });

  createServers({
    http:  options.http,
    https: options.https,
    handler: router.dispatch.bind(router)
  }, callback);
};

//
// ### function routes (options, callback)
// #### @options {Object} Options for starting the proxy
// ####   - log      {function} Logging function to use.
// ####   - rewrites {Array}    All known rewrites to the npm registry.
// ####   - proxy    {NpmProxy} Proxy for npm requests.
//
exports.createRouter = function createRouter(options, callback) {
  var router = new director.http.Router(),
      log    = options.log || console,
      proxy  = options.proxy,
      rewrites,
      server;

  //
  // Get a default set of rewrites if we weren't provided
  // with a custom set.
  //
  options.rewrites = options.rewrites || require('../config/rewrites');

  //
  // Configure director to always use async HTTP
  // stream based routing with a custom 404 handler.
  //
  router.configure({
    async: true,
    stream: true,
    notfound: function () {
      //
      // Pass along the not found notification to the proxy.
      //
      proxy.notFound(this.req, this.res);
    }
  });

  //
  // Remark: we will probably asynchronously load these things in some manner
  // but for now we just expect them
  //
  rewrites = {
    list: options.rewrites.filter(function (rr) {
      return /^_list/.test(rr.to)
        || /^\/-\/_view/.test(rr.from)
        || /^\/-\/_show/.test(rr.from);
    }),
    user: options.rewrites.filter(function (rr) {
      return /_users/.test(rr.to);
    })
  };

  //
  // `/`, `favicon.ico` and `_session` are special cases.
  // TODO: Add route for _utils to make futon hiding more seamless.
  //
  router.get('/',           function () { proxy.public(this.req, this.res);  });
  router.get('favicon.ico', function () { proxy.public(this.req, this.res); });
  ['GET', 'PUT', 'POST', 'DELETE']
    .forEach(function (method) {
      router[method.toLowerCase()]('_session', function () {
        proxy.private(this.req, this.res);
      });
    });

  //
  // All _list/* functions require a merger between
  // public and private npm database views.
  // Remark: This now defaults to private
  //
  rewrites.list.forEach(function (rr) {
    var wc     = patterns.wildcard,
        method = rr.method.toLowerCase(),
        from   = wc.test(rr.from)
          ? new RegExp(rr.from.replace(wc, '.*'))
          : rr.from;

    log.info('[route]', '%s - %s %s', 'public', method, rr.from);
    router[method](from, function () {
      proxy.private(this.req, this.res);
    });
  });

  //
  // Your private npm must manually sync whatever passwords you want
  // since the public npm _user database is the authority for all that
  // is Open Source.
  //
  // Optimizing for ONE PASSWORD EVERYWHERE, ONE .npmrc EVERYWHERE.
  //
  rewrites.user.forEach(function (rr) {
    var method = rr.method.toLowerCase(),
        from   = rr.from;

    log.info('[route]', '%s - %s %s', 'public', method, from);
    router[method](from, function () {
      proxy.public(this.req, this.res);
    });
  });

  //
  // For core `/:pkg` and `/:pkg/*` routes use the more complex, higher-level
  // proxy logic.
  //
  [patterns.packageOnly, patterns.packageAnd].forEach(function (re) {
    ['GET', 'PUT', 'DELETE'].forEach(function (method) {
      method = method.toLowerCase();

      log.info('[route]', '%s - %s %s', 'decide', method, re.source);
      router[method](re, function () {
        proxy.decide(this.req, this.res);
      });
    });
  });

  router.proxy = proxy;
  return router;
};
<commit_msg>[fix] ensure user functions still get sent to the public endpoint<commit_after>/*
 * index.js: Top-level include for the smart-private-npm for serving all CouchDB traffic.
 *
 * (C) 2013, Nodejitsu Inc.
 *
 */

var createServers = require('create-servers'),
    director = require('director');

var patterns = {
  packageAnd:  /\/([_\.\(\)!\\ %@&a-zA-Z0-9-]+)\/.*/,
  packageOnly: /\/([_\.\(\)!\\ %@&a-zA-Z0-9-]+)/,
  wildcard:    /\*$/
};

//
// Export the NpmProxy.
//
exports.Proxy = require('./npm-proxy');

//
// ### function createServer (options, callback)
// #### @options {Object} Options for creating the proxy server.
// ####   - http     {Object|number} HTTP options.
// ####   - https    {Object}        HTTPS options.
// ####   - log      {function}      Logging function to use.
// ####   - proxy    {NpmProxy}      Options for the npm Proxy itself.
// ####   - rewrites {Array}         **Optional** All known rewrites to the npm registry.
//
exports.createServer = function (options, callback) {
  var router = exports.createRouter({
    rewrites: options.rewrites,
    proxy:    new exports.Proxy(options.proxy),
    log:      options.log
  });

  createServers({
    http:  options.http,
    https: options.https,
    handler: router.dispatch.bind(router)
  }, callback);
};

//
// ### function routes (options, callback)
// #### @options {Object} Options for starting the proxy
// ####   - log      {function} Logging function to use.
// ####   - rewrites {Array}    All known rewrites to the npm registry.
// ####   - proxy    {NpmProxy} Proxy for npm requests.
//
exports.createRouter = function createRouter(options, callback) {
  var router = new director.http.Router(),
      log    = options.log || console,
      proxy  = options.proxy,
      rewrites,
      server;

  //
  // Get a default set of rewrites if we weren't provided
  // with a custom set.
  //
  options.rewrites = options.rewrites || require('../config/rewrites');

  //
  // Configure director to always use async HTTP
  // stream based routing with a custom 404 handler.
  //
  router.configure({
    async: true,
    stream: true,
    notfound: function () {
      //
      // Pass along the not found notification to the proxy.
      //
      proxy.notFound(this.req, this.res);
    }
  });

  //
  // Remark: we will probably asynchronously load these things in some manner
  // but for now we just expect them
  //
  rewrites = {
    list: options.rewrites.filter(function (rr) {
      return /^_list/.test(rr.to) && !/.byUser./.test(rr.to)
        || /^\/-\/_view/.test(rr.from)
        || /^\/-\/_show/.test(rr.from);
    }),
    usersList: options.rewrites.filter(function (rr) {
      return /^_list/.test(rr.to) && /.byUser./.test(rr.to);
    }),
    user: options.rewrites.filter(function (rr) {
      return /_users/.test(rr.to);
    })
  };

  //
  // `/`, `favicon.ico` and `_session` are special cases.
  // TODO: Add route for _utils to make futon hiding more seamless.
  //
  router.get('/',           function () { proxy.public(this.req, this.res);  });
  router.get('favicon.ico', function () { proxy.public(this.req, this.res); });
  ['GET', 'PUT', 'POST', 'DELETE']
    .forEach(function (method) {
      router[method.toLowerCase()]('_session', function () {
        proxy.private(this.req, this.res);
      });
    });

  //
  // All _list/* functions require a merger between
  // public and private npm database views.
  // Remark: This now defaults to private
  //
  rewrites.list.forEach(function (rr) {
    var wc     = patterns.wildcard,
        method = rr.method.toLowerCase(),
        from   = wc.test(rr.from)
          ? new RegExp(rr.from.replace(wc, '.*'))
          : rr.from;

    log.info('[route]', '%s - %s %s', 'private', method, rr.from);
    router[method](from, function () {
      proxy.private(this.req, this.res);
    });
  });

  //
  // These are list functions specifically relating to
  // users that will stay public
  //
  rewrites.usersList.forEach(function (rr) {
    var wc     = patterns.wildcard,
        method = rr.method.toLowerCase(),
        from   = wc.test(rr.from)
          ? new RegExp(rr.from.replace(wc, '.*'))
          : rr.from;

    log.info('[route]', '%s - %s %s', 'public', method, rr.from);
    router[method](from, function () {
      proxy.public(this.req, this.res);
    });
  });

  //
  // Your private npm must manually sync whatever passwords you want
  // since the public npm _user database is the authority for all that
  // is Open Source.
  //
  // Optimizing for ONE PASSWORD EVERYWHERE, ONE .npmrc EVERYWHERE.
  //
  rewrites.user.forEach(function (rr) {
    var method = rr.method.toLowerCase(),
        from   = rr.from;

    log.info('[route]', '%s - %s %s', 'public', method, from);
    router[method](from, function () {
      proxy.public(this.req, this.res);
    });
  });

  //
  // For core `/:pkg` and `/:pkg/*` routes use the more complex, higher-level
  // proxy logic.
  //
  [patterns.packageOnly, patterns.packageAnd].forEach(function (re) {
    ['GET', 'PUT', 'DELETE'].forEach(function (method) {
      method = method.toLowerCase();

      log.info('[route]', '%s - %s %s', 'decide', method, re.source);
      router[method](re, function () {
        proxy.decide(this.req, this.res);
      });
    });
  });

  router.proxy = proxy;
  return router;
};
<|endoftext|>


<commit_before>'use strict';

const Stream = require('stream');
const Hoek = require('hoek');
const Squeeze = require('good-squeeze').Squeeze;
const validate = require('./validate');
const formatters = require('./formatters');

/**
 * @constant {object} defaults - Default configuration
 */
const defaults = {
  levels: {
    ops: 'trace',
    response: 'trace',
    error: 'error',
    log: 'info',
    request: 'trace'
  },

  formatters
};

/**
 * GoodBunyan class.
 * @extends Stram.Transform
 */
class GoodBunyan extends Stream.Transform {
  /**
   * Create a new GoodBunyan object.
   * @param  {object} events - Good events to which subscribe to
   * @param  {object} config - Instance configuration
   * @return {GoodBunyan} A new GoodBunyan instance
   */
  constructor (events, config) {
    // Validates inputs and throws errors
    validate(events, config);

    super({ objectMode: true });

    this.settings = Hoek.applyToDefaultsWithShallow(defaults, config, ['logger']);
    this.logger = this.settings.logger; // Alias for consistency
    this._subscription = Squeeze.subscription(events);
  }

  /**
   * Gets Bunyan log level based on good event name or provided tags.
   * @param  {string} eventName - Good event name
   * @param  {array}  tags      - Array of string representing any tags associated with the event
   * @return {string} Bunyan log level
   */
  _getLevel (eventName, tags) {
    if (Array.isArray(tags)) {
      if (tags.indexOf('fatal') !== -1) {
        return 'fatal';
      } else if (tags.indexOf('error') !== -1) {
        return 'error';
      } else if (tags.indexOf('warn') !== -1) {
        return 'warn';
      } else if (tags.indexOf('info') !== -1) {
        return 'info';
      } else if (tags.indexOf('debug') !== -1) {
        return 'debug';
      } else if (tags.indexOf('trace') !== -1) {
        return 'trace';
      }
    }

    // Default level
    return this.settings.levels[eventName];
  }

  /**
   * Transforms data stream.
   * @param  {object}   data - Payload
   * @param  {string}   enc  - Encoding type (if data is string) or 'buffer' (if data is buffer)
   * @param  {Function} next - Callback function to be called after data has been processed
   * @return {undefined}
   */
  _transform (data, enc, next) {
    if (!Squeeze.filter(this._subscription, data)) {
      return next(null);
    }

    const eventName = data.event;
    const level = this._getLevel(eventName, data.tags);

    if (!level) {
      this.logger.trace(data, `[${eventName}] (unknown event)`);
      return next(null);
    }

    const formatted = this.settings.formatters[eventName](data);
    const args = Array.isArray(formatted) ? formatted : [formatted];

    this.logger[level].apply(this.logger, args);

    return next(null);
  }
}

module.exports = GoodBunyan;
<commit_msg>Changed the stream type from transform to writable.<commit_after>'use strict';

const Stream = require('stream');
const Hoek = require('hoek');
const Squeeze = require('good-squeeze').Squeeze;
const validate = require('./validate');
const formatters = require('./formatters');

/**
 * @constant {object} defaults - Default configuration
 */
const defaults = {
  levels: {
    ops: 'trace',
    response: 'trace',
    error: 'error',
    log: 'info',
    request: 'trace'
  },

  formatters
};

/**
 * GoodBunyan class.
 * @extends Stram.Writable
 */
class GoodBunyan extends Stream.Writable {
  /**
   * Create a new GoodBunyan object.
   * @param  {object} events - Good events to which subscribe to
   * @param  {object} config - Instance configuration
   * @return {GoodBunyan} A new GoodBunyan instance
   */
  constructor (events, config) {
    // Validates inputs and throws errors
    validate(events, config);

    super({ objectMode: true });

    this.settings = Hoek.applyToDefaultsWithShallow(defaults, config, ['logger']);
    this.logger = this.settings.logger; // Alias for consistency
    this._subscription = Squeeze.subscription(events);
  }

  /**
   * Gets Bunyan log level based on good event name or provided tags.
   * @param  {string} eventName - Good event name
   * @param  {array}  tags      - Array of string representing any tags associated with the event
   * @return {string} Bunyan log level
   */
  _getLevel (eventName, tags) {
    if (Array.isArray(tags)) {
      if (tags.indexOf('fatal') !== -1) {
        return 'fatal';
      } else if (tags.indexOf('error') !== -1) {
        return 'error';
      } else if (tags.indexOf('warn') !== -1) {
        return 'warn';
      } else if (tags.indexOf('info') !== -1) {
        return 'info';
      } else if (tags.indexOf('debug') !== -1) {
        return 'debug';
      } else if (tags.indexOf('trace') !== -1) {
        return 'trace';
      }
    }

    // Default level
    return this.settings.levels[eventName];
  }

  /**
   * Writes data stream.
   * @param  {object}   data - Payload
   * @param  {string}   enc  - Encoding type (if data is string) or 'buffer' (if data is buffer)
   * @param  {Function} next - Callback function to be called after data has been processed
   * @return {undefined}
   */
  _write (data, enc, next) {
    if (!Squeeze.filter(this._subscription, data)) {
      return next(null);
    }

    const eventName = data.event;
    const level = this._getLevel(eventName, data.tags);

    if (!level) {
      this.logger.trace(data, `[${eventName}] (unknown event)`);
      return next(null);
    }

    const formatted = this.settings.formatters[eventName](data);
    const args = Array.isArray(formatted) ? formatted : [formatted];

    this.logger[level].apply(this.logger, args);

    return next(null);
  }
}

module.exports = GoodBunyan;
<|endoftext|>


<commit_before>import React from "react";
import styled from "styled-components";
import Layout from "@theme/Layout";
import ChevronRight from "../assets/icons/chevron-right.svg";

const PageTitle = styled.h1`
  margin-top: 2rem;
  font-size: 3rem;
  font-weight: 800;
`;

const PageSubtitle = styled.div`
  margin-bottom: 3rem;
`;

const Page = styled.div`
  max-width: var(--ifm-container-width);
  margin: 0 auto;
  padding: 2rem var(--ifm-spacing-horizontal);
  width: 100%;
`;

function Help(props) {
  const { config: siteConfig, language = "" } = props;
  const { baseUrl, docsUrl } = siteConfig;
  const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`;
  const langPart = `${language ? `${language}/` : ""}`;
  const docUrl = (doc) => `${baseUrl}${docsPart}${langPart}${doc}`;
  return (
    <Page className="help-page">
      <PageTitle>NEED HELP?</PageTitle>
      <PageSubtitle>
        This project is maintained by a dedicated group of people.
      </PageSubtitle>

              Browse Docs

Learn more using the documentation on this site.

              Read Documents
              <ChevronRight />

              Join Community

Ask questions about the documentation and project

              GitHub
              <ChevronRight />

              Slack
              <ChevronRight />

              Twitter
              <ChevronRight />

    </Page>
  );
}

export default (props) => (
  <Layout>
    <Help {...props} />
  </Layout>
);
<commit_msg>fix: improved the description for users to join slack (#253)<commit_after>import React from "react";
import styled from "styled-components";
import Layout from "@theme/Layout";
import ChevronRight from "../assets/icons/chevron-right.svg";

const PageTitle = styled.h1`
  margin-top: 2rem;
  font-size: 3rem;
  font-weight: 800;
`;

const PageSubtitle = styled.div`
  margin-bottom: 3rem;
`;

const Page = styled.div`
  max-width: var(--ifm-container-width);
  margin: 0 auto;
  padding: 2rem var(--ifm-spacing-horizontal);
  width: 100%;
`;

function Help(props) {
  const { config: siteConfig, language = "" } = props;
  const { baseUrl, docsUrl } = siteConfig;
  const docsPart = `${docsUrl ? `${docsUrl}/` : ""}`;
  const langPart = `${language ? `${language}/` : ""}`;
  const docUrl = (doc) => `${baseUrl}${docsPart}${langPart}${doc}`;
  return (
    <Page className="help-page">
      <PageTitle>NEED HELP?</PageTitle>
      <PageSubtitle>
        This project is maintained by a dedicated group of people.
      </PageSubtitle>

              Browse Docs

Learn more using the documentation on this site.

              Read Documents
              <ChevronRight />

              Join Community

Ask questions about the documentation and project

              GitHub
              <ChevronRight />

              Slack
              <ChevronRight />

              Twitter
              <ChevronRight />

    </Page>
  );
}

export default (props) => (
  <Layout>
    <Help {...props} />
  </Layout>
);
<|endoftext|>


<commit_before>/*
*  Interceptor.js
*
*  Manages all things related to requests and re-routing them
*
*/

$(document).on('FWExtrasOptionsLoaded',function(){

    if(_globalOptions.chat_base === true) {

        //Blocks out the sites JavaScript chat refresher so we can use our own chat refresh code
        chrome.webRequest.onBeforeRequest.addListener(
            function(details) {
                if(details.url.indexOf("://108.197.28.233/scripts/auto_refresh_home.js") != -1) {
                    console.log('Blocking /scripts/auto_refresh_home.js');
                }
                return {cancel: details.url.indexOf("://108.197.28.233/scripts/auto_refresh_home.js") != -1};
            },
            {urls: ["*://108.197.28.233/*"]},
            ["blocking"]
        );
    }

    if(_globalOptions.interceptor_localassets === true) {

        //Redirects asset requests to local copies for speed
        chrome.webRequest.onBeforeRequest.addListener(
            function(details) {
                if(details.type !== 'xmlhttprequest'){
                    //console.log(details.type+'  ('+details.url+')');
                    var requestedAsset = details.url.substring('http://108.197.28.233'.length);
                    //console.log('requestedAsset:',requestedAsset)
                    if(requestedAsset.indexOf('/loteria/') !== -1) {
                        //likely a loteria image
                        //console.log('/loteria/ file?');
                        console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)));
                        return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length))}
                    }
                    if(requestedAsset.indexOf('/cards/') !== -1) {
                        //likely a blackjack card
                        //console.log('/cards/ file?');
                        //console.log(chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)))
                        console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)));
                        return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length))}
                    }
                    /*if(requestedAsset.indexOf('/media/') !== -1) {
                    //console.log('/media/ file?');
                    console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset));
                    return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset)};
                }*/
            }
            return {redirectUrl: details.url};
        },
        {urls: ["*://108.197.28.233/*"]},
        ["blocking"]
    );
}

});
<commit_msg>Fixed interceptor to work with options.js<commit_after>/*
*  Interceptor.js
*
*  Manages all things related to requests and re-routing them
*
*/

var _globalOptions = {};

chrome.storage.local.get({
    chat_base: true,
    nicknames_base: true,
    interceptor_localassets: false,
    mentions_pane: false,
    mentions_highlighter: false,
    blackjack_base: false,
    loteria_suggestions: false,
    loteria_bot: false
}, function(items) {
    _globalOptions = items;
    console.log(_globalOptions);

    if(_globalOptions.chat_base === true) {

        //Blocks out the sites JavaScript chat refresher so we can use our own chat refresh code
        chrome.webRequest.onBeforeRequest.addListener(
            function(details) {
                if(details.url.indexOf("://108.197.28.233/scripts/auto_refresh_home.js") != -1) {
                    console.log('Blocking /scripts/auto_refresh_home.js');
                }
                return {cancel: details.url.indexOf("://108.197.28.233/scripts/auto_refresh_home.js") != -1};
            },
            {urls: ["*://108.197.28.233/*"]},
            ["blocking"]
        );
    }

    if(_globalOptions.interceptor_localassets === true) {

        //Redirects asset requests to local copies for speed
        chrome.webRequest.onBeforeRequest.addListener(function(details) {
            if(details.type !== 'xmlhttprequest'){
                //console.log(details.type+'  ('+details.url+')');
                var requestedAsset = details.url.substring('http://108.197.28.233'.length);
                //console.log('requestedAsset:',requestedAsset)
                if(requestedAsset.indexOf('/loteria/') !== -1) {
                    //likely a loteria image
                    //console.log('/loteria/ file?');
                    console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)));
                    return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length))}
                }
                if(requestedAsset.indexOf('/cards/') !== -1) {
                    //likely a blackjack card
                    //console.log('/cards/ file?');
                    //console.log(chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)))
                    console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length)));
                    return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset.substring('/img'.length))}
                }
                /*if(requestedAsset.indexOf('/media/') !== -1) {
                //console.log('/media/ file?');
                console.log('Intercepted '+requestedAsset+' to '+chrome.extension.getURL('../assets'+requestedAsset));
                return {redirectUrl: chrome.extension.getURL('../assets'+requestedAsset)};
            }*/
        }
        return {redirectUrl: details.url};
    }, {urls: ["*://108.197.28.233/*"]},["blocking"]);
}

});
<|endoftext|>