if(typeof process !== "undefined")
	var define = require.define;
define(function(require, exports, module){
var Noodles;
/*--exports--
name:Plugin
description:Plugin Class implementation
@type{Noodles.Plugin}
*/
exports.Plugin = {
	/*--Coretags--
	name:getNoodles
	description:gets the noodles object
	@param{Noodles}
	*/
	getNoodles : function(_Noodles){
		Noodles = _Noodles;
	},
	/*--Coretags--
	name:willHandle
	description:array of tags that the coretags plugin will handle
	@param{Noodles.Template}
	@return {array}
	*/
	willHandle : function(Template){
		return [Template.language.tag('exit'),Template.language.tag('exitloop'),Template.language.tag('continue')];
	},
	/*--Coretags--
	name:pluginName
	@type{string}
	*/
	pluginName : 'exittag',
	/*--Coretags--
	name:browserFriendly
	description:is this plugin browser friendly?
	*/
	browserFriendly: true,
	/*--Coretags--
	name:onTemplateCreate
	description:executed on template creation
	@param{Noodles.Template}
	*/
	onTemplateCreate : function(Context,Template){},
	/*--Coretags--
	name:onTemplateExecute
	description:executed when template is run
	@param{Noodles.Context}
	@param{Noodles.Template}
	*/
	onTemplateExecute : function(Context, Template){},
	/*--Coretags--
	name:handleToken
	description:executed when any tag in "willHandle" is found
	@param{Noodles.Template}
	@param{string}
	@param{string}
	*/
	handleToken : function(Template, expression, tag){
		switch(tag){
			case Template.language.tag('exit'):
				return new Exit(Template,expression);
			case Template.language.tag('continue'):
				return new Continue(Template,expression);
			case Template.language.tag('exitloop'):
				return new Exit(Template,expression,true);
			default:
				return {skip:true};
		}
	}
};
/*--module--
name: Exit
description: Exit object
@param {Noodles.Template}
@param {string}
@param {boolean}
*/
var Exit = function(Template,expression,loop){
	this.loop = !!loop;
	this.needs = {};
	this.isAmbiguous = true;
	this.modifies = {};
};
/*--Exit--
name: execute
description: Exit execution
@param {Noodles.Template}
@param {Noodles.Context}
@param {function=}
*/
Exit.prototype.execute = function(Template,Context,Callback){
	Context.exitNow = true;
	if(this.loop){
		Context.exitLoop = true;
	}
};
/*--module--
name: Continue object
description: Continue object
@param {Noodles.Template}
@param {string}
*/
var Continue = function(Template,expression){
	this.loop = !!loop;
	this.needs = {};
	this.isAmbiguous = true;
	this.modifies = {};
};
/*--Continue--
name: execute
description: Continue execution
@param {Noodles.Template}
@param {Noodles.Context}
@param {function=}
*/
Continue.prototype.execute = function(Template,Context,Callback){
	Context.exitNow = true;
	Context.continue = true;
};
});


// Copyright (c) 2015 Patrick Dubroy <pdubroy@gmail.com>
// This software is distributed under the terms of the MIT License.

'use strict';

function startswith(haystack, needle) {
  if (Array.isArray(needle)) {
    return needle.some(function(n) { return startswith(haystack, n); });
  }
  return haystack.indexOf(needle) === 0;
}

function endswith(haystack, needle) {
  return haystack.slice(-needle.length) === needle;
}

// Returns false if `node` is a require expression where the module path
// ends with '.js'.
function checkCallExpression(node) {
  var callee = node.callee;
  if (callee.type === 'Identifier' && callee.name === 'require') {
    var pathNode = node.arguments[0];
    if (pathNode.type === 'Literal') {
      var p = pathNode.value;

      // Only check relatively-imported modules.
      if (startswith(p, ['/', './', '../'])) {
        return !endswith(p, '.js');
      }
    }
  }
  return true;
}

// Reports an AST node as a rule violation.
function report(context, node) {
  context.report(node, "require() paths should not include '.js'", {name: node.name});
}

// An ESLint rule that enforces that the path argument of a require()
// statement should not include the '.js' extension.
function noExtensionInRequire(context) {
  return {
    CallExpression: function(node) {
      if (!checkCallExpression(node)) {
        report(context, node);
      }
    }
  };
}

module.exports = {
  rules: {
    'main': noExtensionInRequire
  }
};


var _isNumber = require('./isNumber');
var _isObject = require('./isObject');
var REGEX_ENUM = require('./internal/enum/regexEnum');

/**
 * 校验参数 `val` 是否为 非正整数, 即负整数和零
 *
 * 该接口存在两种模式, 即严格模式、非严格模式;
 *
 * 默认采用 `非严格模式`
 *
 * 若参数 `val` 为 number 类型, 并且是非正整数 则返回 true, 否则返回 false
 * 若参数 `val` 为 string 类型, 并且通过验证为非正整数字符串, 则返回 true, 否则返回 false
 * 若参数 `val` 不属于以上两种类型, 则直接返回 false
 *
 * 若参数 `val` 的值为空字符串（''、'   '）, 则直接返回 false
 *
 * 若是参数 `options` 指定了严格模式, 即 options.isStrict = true, 则对于 string 类型直接返回 false
 *
 * e.g.
 *
 * 待校验参数 '-3'
 *  > 若是严格模式, 则该参数值校验后, 返回 false
 *  > 若是非严格模式, 则该参数值校验后, 返回 true
 *
 * @param   {*}       val              待校验的参数
 * @param   {Object}  options          可选参数
 * @param   {Boolean} options.isStrict 是否严格模式
 * @return  {Boolean} 返回校验结果
 * @version 0.0.5
 * @since   0.0.4
 */
function _isUnPositiveInteger(val, options) {
  var opts = _isObject(options) ? options : {};

  if (opts.isStrict === true) {
    return _isNumber(val) && REGEX_ENUM.UN_POSITIVE_INTEGER_REX.test(val);
  }

  return REGEX_ENUM.UN_POSITIVE_INTEGER_REX.test(val);
}

module.exports = _isUnPositiveInteger;


/*
* logia <https://github.com/jahnestacado/logia>
* Copyright (c) 2016 Ioannis Tzanellis
* Licensed under the MIT License (MIT).
*/
var Config = require("./config.js");
var RUNTIME_CONFIG = Config.runtime;
var EVENT_BUSLINE = Config.static.eventBusline;
var IN_SERVER_MODE = Config.static.inServerMode;
var LOGGERS = {};
var SLAVE_REMOTE = null;
var MASTER_SERVER = null;

var bus = require("hermes-bus");
var Utils = require("./utils.js");
var Logia = require("./logia.js");
var ActiveLoggerNameLengthHandler = require("./active-name-length-handler.js");
var extend = require("extend");
var ModeHandlerListener = require("./mode-handler-listener.js");

/**
* The Logia module. The returned value of require("logia").
* @namespace Logia
* @type {function}
* @param {string} name - The logger name that we want to create/retrieve
* @returns {logger} - The newly created or retrieved logger instance
*/
var LogiaFactory = function(name) {
    var logger;
    if(LOGGERS[name]){
        logger = LOGGERS[name];
    } else {
        ActiveLoggerNameLengthHandler.update(name);
        logger = new Logia(name);
        LOGGERS[name] = logger;
    }
    return logger;
};

/**
* Overwrites the configuration file on disk if the "overwritable" option is set to true.
* NOOP when executing in the browser.
* @param {object} config - An object that defines any of the {@link LogiaConfig} properties.
* @memberof Logia
*/
LogiaFactory.overwriteConfigFile = function(config) {
    if(IN_SERVER_MODE){
        if(RUNTIME_CONFIG.overwritable){
            extend(RUNTIME_CONFIG, config);
            ConfigFileHandler.writeConfigurationFile(RUNTIME_CONFIG);
        }
    } else {
        console.warn("[LOGIA] overwriteConfigFile function is a NOOP in the browser");
    }
};

/**
* Sets the date format in the logs.
* @param {string} format - {@link http://momentjs.com/docs/#/parsing/string  Moment.js} date format
* @memberof Logia
*/
LogiaFactory.setDateFormat = function (format) {
    var newDateFormat = format;
    if(typeof newDateFormat !== "string"){
        newDateFormat = "";
        console.error(("[LOGIA] Invalid 'dateFormat' value: " + format +". Using default date format...").red);
    }
    RUNTIME_CONFIG.dateFormat = newDateFormat;
};

/**
* Sets the global Logia configuration. It doesn't overwrite the configuration file on disk.
* @param {object} config - An object that defines any of the {@link LogiaConfig} properties
* @memberof Logia
*/
LogiaFactory.config = function(config) {
        extend(RUNTIME_CONFIG, config);
        bus[EVENT_BUSLINE] && bus[EVENT_BUSLINE].trigger("configurationChanged", config);
};

/**
* Enters slave mode. Logia configuration is dictated by the specified Logia master node.
* @param {object} options Logia master server location info.
* @param {string} options.host
* @param {number} options.port
* @memberof Logia
*/
LogiaFactory.enterSlaveMode = function(options) {
    LogiaFactory.exitSlaveMode();
    var url = options.host + ":" + options.port;
    SLAVE_REMOTE = Utils.createRemote({protocol: "ws", url: url, tag: "slave"});
    extend(RUNTIME_CONFIG, {
        mode: {
            type: "slave",
            host: options.host,
            port: options.port
        }
    });
    bus[EVENT_BUSLINE].trigger("enableMasterSlaveMode", {type: "slave", url: url});
    SLAVE_REMOTE.onWsMessage(function(masterConfig){
        LogiaFactory.config(masterConfig);
    });
};

/**
* Exits slave mode. Logia configuration is based on local configuration file again.
* @memberof Logia
*/
LogiaFactory.exitSlaveMode = function() {
    if(SLAVE_REMOTE){
        SLAVE_REMOTE.terminate();
        SLAVE_REMOTE = null;
        extend(RUNTIME_CONFIG, {
            mode: {
                type: null,
                host: null,
                port: null
            }
        });
        bus[EVENT_BUSLINE] && bus[EVENT_BUSLINE].trigger("configurationChanged");
        bus[EVENT_BUSLINE].trigger("disableMasterSlaveMode", {type: "slave"});
    }
};

/**
* Enters master mode. A master Logia node can command multiple slave nodes via the master node configuration mechanism.
* @param {object} options Logia master server info.
* @param {string} options.host
* @param {number} options.port
* @memberof Logia
*/
LogiaFactory.enterMasterMode = function(options) {
    if(IN_SERVER_MODE){
        var url = options.host + ":" + options.port;
        extend(RUNTIME_CONFIG, {
            mode: {
                type: "master",
                host: options.host,
                port: options.port
            }
        });
        MASTER_SERVER = Utils.setupMasterServer(MASTER_SERVER, options);
        bus[EVENT_BUSLINE].trigger("enableMasterSlaveMode", {type: "master", url: url});
    } else {
        console.warn("[LOGIA] enterMasterMode function is a NOOP in the browser");
    }
};

/**
* Exits master mode.
* @memberof Logia
*/
LogiaFactory.exitMasterMode = function() {
    if(IN_SERVER_MODE){
        if(MASTER_SERVER){
            extend(RUNTIME_CONFIG, {
                mode: {
                    type: null,
                    host: null,
                    port: null
                }
            });
            MASTER_SERVER.stop();
            MASTER_SERVER = null;
            bus[EVENT_BUSLINE].trigger("disableMasterSlaveMode", {type: "master"});
        }
    } else {
        console.warn("[LOGIA] exitMasterMode function is a NOOP in the browser");
    }
};

LogiaFactory.server = {
    /**
    * Listens for certain server events.
    * Currently the only supported event is the "log" event which is triggered when Logia server receives a log.
    * @alias server.on
    * @method server.on
    * @memberof Logia
    * @param {string} event
    * @param {function} callback
    */
    on: function(event, listener){
        switch (event) {
            case "log":
                bus.subscribe(EVENT_BUSLINE, {
                    onRemoteLogReceived: function(logObj){
                        listener(logObj);
                    }
                });
                break;
            default: console.error("[LOGIA] Unknown event name: '" + event + "'");
        }
    }
};

// Attaching listener on the bus
bus.subscribe(EVENT_BUSLINE, ModeHandlerListener);

bus.subscribe(EVENT_BUSLINE, {
    afterConfigurationChanged: function () {
        // setDateFormat ensures validity of dateFormat value
        LogiaFactory.setDateFormat(RUNTIME_CONFIG.dateFormat);
    }
});

var hasModeConfigChanged = function(){
    var hasChanged = true;
    var url = RUNTIME_CONFIG.mode && RUNTIME_CONFIG.mode.host + ":" + RUNTIME_CONFIG.mode.port;
    if(SLAVE_REMOTE){
        hasChanged = RUNTIME_CONFIG.mode.type !== "slave" || url !== SLAVE_REMOTE.options.url;
    } else if(MASTER_SERVER){
        hasChanged = RUNTIME_CONFIG.mode.type !== "master" || url !== MASTER_SERVER.url;
    }
    return hasChanged;
};

var setupMasterSlaveMode = function() {
    if(hasModeConfigChanged()){
        LogiaFactory.exitMasterMode();
        LogiaFactory.exitSlaveMode();
        if(RUNTIME_CONFIG.mode){
            if(RUNTIME_CONFIG.mode.type === "master"){
                LogiaFactory.enterMasterMode(RUNTIME_CONFIG.mode);
            } else if(RUNTIME_CONFIG.mode.type === "slave"){
                LogiaFactory.enterSlaveMode(RUNTIME_CONFIG.mode);
            }
        }
    }
};

if(IN_SERVER_MODE){
    var ConfigFileHandler = require("./configuration-file-handler.js");
    setupMasterSlaveMode();

    // Attaching listener on the bus
    var FileTrimmerListener = require("./file-trimmer-listener.js");
    bus.subscribe(EVENT_BUSLINE, FileTrimmerListener);

    bus.subscribe(EVENT_BUSLINE, {
        afterConfigurationChanged: function () {
            setupMasterSlaveMode();
        }
    });
}

module.exports = LogiaFactory;


'use strict';

// Modules
const execFile = require("child_process").execFile;
const fs = require('fs');
const url = require("url");
const util = require("util");
const eventEmitter = require('events').EventEmitter;
const path = require('path');
const debuglog = util.debuglog('gitcapsule');
const gitCapsuleErrors = require("./gitcapsuleerrors.js");
const mkdirp = require("mkdirp");

var defaultRepositoryOptions = {
    "prepareBasePath": false
}

/**
 * Git repository object
 */
var GitRepository = function () {
    eventEmitter.call(this);
    var self = this;
}
util.inherits(GitRepository, eventEmitter);

function configureGitRepository(repository, basePath, options) {
    repository._basePath = path.resolve(__dirname, basePath);

    repository._childProcessOptions = {
        //encoding: 'utf8',
        //timeout: 0,
        //maxBuffer: 200 * 1024,
        //killSignal: 'SIGTERM',
        //env: null,
        cwd: repository._basePath
    }

    repository.on('newListener', function (listener) {
        debuglog('StartApp event listener: %s', listener);
        var availableListeners = ["error", "cloned", "fetched", "pulled", "gotLatestCommit", "checkedout", "gotStatus"];
    });

    if (options.prepareBasePath) {
        prepareBasePath(repository._basePath);
    }
}

/**
 * Represents the command "git clone <url> <path>"
 * @param  {string} repositoryUrl
 * @param  {(error:gitcapsuleerrors.GitCommandError,response:any)=>void} [callback]
 */
GitRepository.prototype.clone = function (repositoryUrl, callback) {
    if (typeof (repositoryUrl) === 'undefined')
        throw new TypeError("repositoryUrl cannot be " + typeof (repositoryUrl))

    validateUrl(repositoryUrl)

    var self = this;
    var args = ["clone", repositoryUrl, self._basePath];

    console.log(util.format('Cloning "%s" to "%s"', repositoryUrl, self._basePath));
    executeGitCommand(self, args, function (error, data) {
        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('clone ERROR: %s', error), data, args);
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("cloned", processCloneResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processCloneResponse(data));
    });
}

/**
 * Represents the command "git fetch"
 * @param  {(error:gitcapsuleerrors.GitCommandError,response:any)=>void} [callback]
 */
GitRepository.prototype.fetch = function (callback) {
    var self = this;
    var args = ["fetch"];

    console.log("Fetching information.");
    executeGitCommand(self, args, function (error, data) {
        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('fetch ERROR: %s', error), data, args);
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("fetched", processFetchResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processFetchResponse(data));
    });
}

/**
 * Represents the command "git pull"
 * @param  {(error:gitcapsuleerrors.GitCommandError,response:pullResponse)=>void} [callback]
 */
GitRepository.prototype.pull = function (callback) {
    var self = this;
    var args = ["pull"];

    console.log("Pulling changes.");
    executeGitCommand(self, args, function (error, data) {
        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('pull ERROR: %s', error));
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("pulled", processPullResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processPullResponse(data));
    });
}

/**
 * Represents the command  "git rev-parse --verify HEAD"
 * @param  {(error:gitcapsuleerrors.GitCommandError,response:latestCommitResponse)=>void} [callback]
 */
GitRepository.prototype.getLatestCommit = function (callback) {
    var self = this;
    var args = ["rev-parse", "--verify", "HEAD"];

    executeGitCommand(self, args, function (error, data) {
        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('rev-parse ERROR: %s', error), data, args);
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("gotLatestCommit", processRevParsedResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processRevParsedResponse(data));
    });
}

/**
 * Represents the command "git checkout <branchName>"
 * @param  {string} branchName
 * @param  {(error:gitcapsuleerrors.GitCommandError,response:checkoutResponse)=>void} [callback]
 */
GitRepository.prototype.checkout = function (branchName, callback) {
    var self = this;
    var args = ["checkout", branchName];

    console.log("Checking out branch \"%s\".", branchName);
    executeGitCommand(self, args, function (error, data) {
        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('checkout ERROR: %s', error), data, args);
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("checkedout", processCheckoutResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processCheckoutResponse(data));
    });
}

/**
 * Represents the command "git status"
 * @param {(error: gitcapsuleerrors.GitCommandError, response: statusResponse) => void} [callback]
 */
GitRepository.prototype.status = function (callback) {
    var self = this;
    var args = ["status"];

    console.log("Checking repository status.");
    executeGitCommand(self, args, function (error, data) {
        var notRepositoryError = data.indexOf("Not a git repository") >= 0;

        if (notRepositoryError)
            error = null;

        var err = null;
        if (error !== null) {
            err = gitCapsuleErrors.createGitCommandError(util.format('status ERROR: %s', error), data, args);
            debuglog(err);
            self.emit("error", err);
        } else {
            self.emit("gotStatus", processStatusResponse(data));
        }

        if (typeof (callback) !== 'undefined')
            callback(err, processStatusResponse(data));
    });
}

function processCloneResponse(data) {
    var response = processBaseResponse(data)
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    //TODO: Make que process

    return response;
}

function processRevParsedResponse(data) {
    var response = processBaseResponse(data)
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    response.commit = data.trim();

    return response;
}

function processStatusResponse(data) {
    var response = processBaseResponse(data);
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    response.isRepository = (data.indexOf("Not a git repository") < 0);

    return response;
}

function processCheckoutResponse(data) {
    var response = processBaseResponse(data);
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    //TODO: Make que process

    return response;
}

function processPullResponse(data) {
    var response = processBaseResponse(data)
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    response.alreadyUpToDate = (data.indexOf("Already up-to-date.") >= 0);

    return response;
}

function processBaseResponse(data) {
    var response = {
        "raw": null,
        "lines": []
    };

    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    response.raw = data;

    if (data.indexOf("\n") >= 0)
        response.lines = data.split("\n");
    else
        response.lines = [data];

    return response;
}

function processFetchResponse(data) {
    var response = processBaseResponse(data);
    if (typeof (data) === 'undefined' || data.length <= 0)
        return response;

    //TODO: Make que process

    return response;
}

function prepareBasePath(path) {

    try {
        if (fs.existsSync(path)) {
            console.log('Removing folder "%s"', path);
            deleteFolderRecursive(path);
            console.log('Folder "%s" removed', path);
        }

        console.log('Creating folder "%s"', path);
        mkdirp.sync(path);
        console.log('Folder "%s" created', path);

    } catch (error) {
        if (error !== null) {
            var err = new Error(util.format("Error preparing the base path: %s", error));
            console.error(err)
            throw err;
        }
    }
}

function deleteFolderRecursive(path) {
    if (fs.existsSync(path)) {
        fs.readdirSync(path).forEach(function (file, index) {
            var curPath = path + "/" + file;
            if (fs.lstatSync(curPath).isDirectory()) { // recurse
                deleteFolderRecursive(curPath);
            } else { // delete file
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(path);
    }
}

function executeGitCommand(self, args, callback) {
    if (typeof (args) === 'undefined')
        throw new TypeError("args cannot be " + typeof (args))

    if (typeof (callback) === 'undefined')
        throw new TypeError("callback cannot be " + typeof (callback))

    debuglog("EXECUTING => git " + args.join(" "));

    /**
     *
     *
     * @param {any} error
     * @param {any} stdout
     * @param {any} stderr
     */
    var child = execFile("git", args, self._childProcessOptions, function (error, stdout, stderr) {
        var err = null;

        if (error !== null) {
            err = new Error(util.format('execFile ERROR: %s', error));
            debuglog(err);
        }

        callback(err, stdout.trim() + "\n" + stderr.trim());
    });
    monitorChildProcess(child);

    return child;
}

function monitorChildProcess(child) {

    child.stdin.on('data', function (data) {
        debuglog("STDIN => %s", data);
    });

    child.stdout.on('data', function (data) {
        debuglog("STDOUT => %s", data);
    });

    child.stderr.on('data', function (data) {
        debuglog("STDERR => %s", data);
    });
}

function validateUrl(repositoryUrl) {

    try {
        var result = url.parse(repositoryUrl);
        if (typeof (result) === "undefined")
            throw new Error("Repository url is not valid.");
    } catch (error) {
        debuglog(error);
        throw new Error("Repository url is not valid.");
    }

}

/**
 * Create a instance of a GitCapsule.
 * @param  {string} basePath The path where the repository will be stored locally.
 * @param  {RepositoryOptions} options? the repository options that will be used.
 * @returns GitRepository
 */
function createGitRepository(basePath, options) {
    if (typeof (options) === "undefined")
        options = defaultRepositoryOptions;

    var gitRepository = new GitRepository();
    configureGitRepository(gitRepository, basePath, options);
    return gitRepository;
}

module.exports = {
    GitRepository: GitRepository,
    createGitRepository: createGitRepository
}


import assert from 'assert'; // from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa
import {sha256, HmacSHA256,  } from './hash';
import enforceType from './enforce_types';

import BigInteger from 'bigi';
import ECSignature from './ecsignature';

// https://tools.ietf.org/html/rfc6979#section-3.2
function deterministicGenerateK(curve, hash, d, checkSig, nonce) {

  enforceType('Buffer', hash)
  enforceType(BigInteger, d)

  if (nonce) {
    hash = sha256(Buffer.concat([hash, new Buffer(nonce)]))
  }

  // sanity check
  assert.equal(hash.length, 32, 'Hash must be 256 bit')

  var x = d.toBuffer(32)
  var k = new Buffer(32)
  var v = new Buffer(32)

  // Step B
  v.fill(1)

  // Step C
  k.fill(0)

  // Step D
  k = HmacSHA256(Buffer.concat([v, new Buffer([0]), x, hash]), k)

  // Step E
  v = HmacSHA256(v, k)

  // Step F
  k = HmacSHA256(Buffer.concat([v, new Buffer([1]), x, hash]), k)

  // Step G
  v = HmacSHA256(v, k)

  // Step H1/H2a, ignored as tlen === qlen (256 bit)
  // Step H2b
  v = HmacSHA256(v, k)

  var T = BigInteger.fromBuffer(v)

  // Step H3, repeat until T is within the interval [1, n - 1]
  while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0) || !checkSig(T)) {
    k = HmacSHA256(Buffer.concat([v, new Buffer([0])]), k)
    v = HmacSHA256(v, k)

    // Step H1/H2a, again, ignored as tlen === qlen (256 bit)
    // Step H2b again
    v = HmacSHA256(v, k)

    T = BigInteger.fromBuffer(v)
  }

  return T

}

function sign(curve, hash, d, nonce) {

  var e = BigInteger.fromBuffer(hash)
  var n = curve.n
  var G = curve.G

  var r, s
  var k = deterministicGenerateK(curve, hash, d, function (k) {
    // find canonically valid signature
    var Q = G.multiply(k)

    if (curve.isInfinity(Q)) return false

    r = Q.affineX.mod(n)
    if (r.signum() === 0) return false

    s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n)
    if (s.signum() === 0) return false

    return true
  }, nonce)

  var N_OVER_TWO = n.shiftRight(1)

  // enforce low S values, see bip62: 'low s values in signatures'
  if (s.compareTo(N_OVER_TWO) > 0) {
    s = n.subtract(s)
  }

  return new ECSignature(r, s)
}

function verifyRaw(curve, e, signature, Q) {
  var n = curve.n
  var G = curve.G

  var r = signature.r
  var s = signature.s

  // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1]
  if (r.signum() <= 0 || r.compareTo(n) >= 0) return false
  if (s.signum() <= 0 || s.compareTo(n) >= 0) return false

  // c = s^-1 mod n
  var c = s.modInverse(n)

  // 1.4.4 Compute u1 = es^−1 mod n
  //               u2 = rs^−1 mod n
  var u1 = e.multiply(c).mod(n)
  var u2 = r.multiply(c).mod(n)

  // 1.4.5 Compute R = (xR, yR) = u1G + u2Q
  var R = G.multiplyTwo(u1, Q, u2)

  // 1.4.5 (cont.) Enforce R is not at infinity
  if (curve.isInfinity(R)) return false

  // 1.4.6 Convert the field element R.x to an integer
  var xR = R.affineX

  // 1.4.7 Set v = xR mod n
  var v = xR.mod(n)

  // 1.4.8 If v = r, output "valid", and if v != r, output "invalid"
  return v.equals(r)
}

function verify(curve, hash, signature, Q) {
  // 1.4.2 H = Hash(M), already done by the user
  // 1.4.3 e = H
  var e = BigInteger.fromBuffer(hash)
  return verifyRaw(curve, e, signature, Q)
}

/**
  * Recover a public key from a signature.
  *
  * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
  * Key Recovery Operation".
  *
  * http://www.secg.org/download/aid-780/sec1-v2.pdf
  */
function recoverPubKey(curve, e, signature, i) {
  assert.strictEqual(i & 3, i, 'Recovery param is more than two bits')

  var n = curve.n
  var G = curve.G

  var r = signature.r
  var s = signature.s

  assert(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value')
  assert(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value')

  // A set LSB signifies that the y-coordinate is odd
  var isYOdd = i & 1

  // The more significant bit specifies whether we should use the
  // first or second candidate key.
  var isSecondKey = i >> 1

  // 1.1 Let x = r + jn
  var x = isSecondKey ? r.add(n) : r
  var R = curve.pointFromX(isYOdd, x)

  // 1.4 Check that nR is at infinity
  var nR = R.multiply(n)
  assert(curve.isInfinity(nR), 'nR is not a valid curve point')

  // Compute -e from e
  var eNeg = e.negate().mod(n)

  // 1.6.1 Compute Q = r^-1 (sR -  eG)
  //               Q = r^-1 (sR + -eG)
  var rInv = r.modInverse(n)

  var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv)
  curve.validate(Q)

  return Q
}

/**
  * Calculate pubkey extraction parameter.
  *
  * When extracting a pubkey from a signature, we have to
  * distinguish four different cases. Rather than putting this
  * burden on the verifier, Bitcoin includes a 2-bit value with the
  * signature.
  *
  * This function simply tries all four cases and returns the value
  * that resulted in a successful pubkey recovery.
  */
function calcPubKeyRecoveryParam(curve, e, signature, Q) {
  for (var i = 0; i < 4; i++) {
    var Qprime = recoverPubKey(curve, e, signature, i)

    // 1.6.2 Verify Q
    if (Qprime.equals(Q)) {
      return i
    }
  }

  throw new Error('Unable to find valid recovery factor')
}

export { calcPubKeyRecoveryParam, deterministicGenerateK, recoverPubKey, sign,
  verify, verifyRaw };


"use strict"
var Url = require('url')
var _ = require('underscore')

module.exports = function(ngin) {
  var SportsModel = ngin.SportsModel
  var Super = SportsModel.prototype
  var config = ngin.config

  /**
   * Scopes the url to the tournament or flight
   *
   * @param {Object} options
   * @returns {String}
   * @api public
   */

  function scopeUrl(options, inst) {
    options = _.extend(_.clone(options || {}), inst)
    if (typeof options !== 'object' && (!options.tournament_id || !options.flight_id || !options.league_id))
      throw new Error('tournament_id required to make StandingsDefault api calls')

    return options.tournament_id ? tournamentUrl(options.tournament_id) : leagueUrl(options.league_id, options.game_type)
  }

  function tournamentUrl(tournament_id) {
    return ngin.Tournament.urlRoot() + '/' + tournament_id + StandingsDefault.urlRoot()
  }

  function leagueUrl(league_id, game_type) {
    return ngin.League.urlRoot() + '/' + league_id + StandingsDefault.urlRoot() + '/' + game_type
  }

  /**
   * StandingsDefault Class
   *
   * @param {Object} attr
   * @param {Object} options
   * @api public
   */

  var StandingsDefault = SportsModel.extend({

    fetch: function(options, callback) {
      var url = scopeUrl(options, this)
      return Super.fetch.call(this, url, options, callback)
    },

    save: function(options, callback) {
      if (typeof options == 'function') {
        callback = options
        options = {}
      }
      var url = scopeUrl(options, this)
      options.method = options.method || 'PUT'
      return Super.save.call(this, url, options, callback)
    }

  }, {

    list: function(options, callback) {
      var url = ngin.League.urlRoot() + '/' + options.id + this.urlRoot() + '/' + options.gameType
      return SportsModel.list.call(this, url, options, callback)
    },

    urlRoot: function(options) {
      return '/standings_defaults'
    }

  })

  return StandingsDefault

}


var _ = require('lodash');

/**
 * Serverbone ACL
 *
 * Serverbone ACL provides a simple inline RBAC that can be easily extented to be used with normal user/pass
 * authentication or token based authentication.
 *
 * Roles can be granted several ways,
 *
 * - Directly to a model (like User model instance) via .grant(roles)
 * - Based on schema relations, grant 'owner, user' to user model that has its id in this.get('user_id') as seen below.
 * - via overriding getRoles(model) in ACLModel subclass, like seen also below.
 *
 * var MyModel = BaseModel.extend({
 *   schema: {
 *     permissions: {
 *       "*": ["read","create"],
 *       owner: ["update","delete"],
 *       admin: ["*"]
 *     },
 *     properties: {
 *       hidden_id: {
 *         type: "integer",
 *         permissions: {
 *           "*": [], owner:[]
 *         }
 *       },
 *       hiddent_text: {
 *         type: "string",
 *         permissions: {
 *           "*": [],
 *           "hidden": ["read","update"]
 *         }
 *       },
 *       user_id: {"type":"integer"},
 *       user: {
 *         "type": "relation",
 *         "roles": ["owner"],
 *         "references": {
 *           id: 'user_id'
 *         }
 *       }
 *     }
 *   },
 *   getRoles: function(model) {
 *     // returns function that matches model type against 'user'
 *     var isUser = acl.type('user');
 *     // returns function that matches this.get('hidden_id') against model.get('hidden_id')
 *     var isIdMatch = acl.property('hidden_id', 'hidden_id');
 *     var roles = [];
 *     if(isUser(model) && isIdMatch(this, model)) {
 *       // grant model 'hidden' role against this model to allow access to hidden_text
 *       roles.push('hidden');
 *     }
 *     return roles;
 *   }
 * });
 *
 */

// Default role permission sets that are implicit
var Permissions = {
  owner: ['read', 'update'],
  admin: ['*'],
  '*': ['create', 'read']
};

/**
 * Create new ACL with passed in roles and attached permissions.
 *
 * permissions are in the form of {"role":["action1","action2"]}
 *
 * @param {Object} permissions
 */
exports.ACL = function (permissions) {
  // Permissions map roles to array of actions: {"user":["read"],"admin":["write"]}
  this.permissions = _.extend({}, Permissions, permissions);
};

_.extend(exports.ACL.prototype, {
  /**
   * allows additional permissions for this acl
   *
   * @param  {Object} permissions
   *
   */
  grant: function (permissions) {
    _.merge(this.permissions, permissions, function (a, b) {
      return _.isArray(a) ? a.concat(b) : undefined;
    });
    return this;
  },
  /**
   * Revoke a role
   *
   * @param  {String|Array} roles a role or roles to revoke
   * @api public
   *
   * @return {ACL}      this for chaining
   */
  revoke: function (roles) {
    if (!Array.isArray(roles)) {
      roles = [roles];
    }
    this.permissions = _.reduce(this.permissions, function (result, actions, key) {
      if (roles.indexOf(key) === -1) {
        result[key] = actions;
      }
      return result;
    }, {});
    return this;
  },
  /**
   * Assert access to this acl's 'action' with role(s)
   *
   * Can I write here with these roles?
   *
   *
   * @param  {String|Array} roles
   * @param  {String} action
   *
   * @example
   *
   * var ownerReading = acl.assert(['*','owner'], 'read')
   * var someoneWriting = acl.assert(['*']‚ 'write')
   *
   * @return {Boolean}
   */
  assert: function (roles, action) {
    var self = this;
    if (!action) {
      action = roles;
      roles = ['*'];
    }
    if (!Array.isArray(roles)) {
      roles = [roles];
    }
    roles.push('*');
    var matches = _.filter(roles, function (role) {
      var actions = self.permissions[role] || self.permissions['*'];
      return actions.indexOf(action) !== -1 || actions.indexOf('*') !== -1;
    });
    return matches.length > 0;
  },

  /**
   * Returns a list of actions given role(s) have access to
   * @param  {String|Array} roles
   * @return {Array} list of actions
   */
  allowedActions: function(roles) {
    roles = roles || ['*'];
    if (!Array.isArray(roles)) {
      roles = [roles];
    }
    if (roles.indexOf('*') === -1) roles.push('*');
    var actions = [];
    _.each(roles, function(role) {
      if (_.has(this.permissions, role)) {
        actions = actions.concat(this.permissions[role]);
      }
    }, this);
    return _.uniq(actions);
  }
});

/**
 * Asserts actorModel.type == type || actorModel.get('type') == type
 *
 * @param  {[type]} type
 * @return {[type]}
 */
exports.type = function (type) {
  return function (actor) {
    if (!actor) return false;
    return actor.has('type') ? actor.get('type') === type : actor.type === type;
  };
};

/**
 * Asserts actorModel.has(key) && actorModel.get(key) === value
 *
 * @param  {String} attr
 * @param  {Object} value
 * @api public
 * @return {Boolean}
 */
exports.attribute = function (attr, value) {
  return function (model, actor) {
    return actor.has(attr) && actor.get(attr) === value;
  };
};

/**
 * Asserts model.has(key) && actorModel.has(key) && actorModel.get(key) === model.get(key)
 *
 * @param  {String} key
 * @param  {Object} actorKey
 * @api public
 * @return {Boolean}
 */
exports.property = function (key, actorKey) {
  return function (model, actor) {
    return actor.has(actorKey) && model.has(key) && model.get(key) === actor.get(actorKey);
  };
};


// eslint-disable-next-line max-params
(function main(DEFAULT_STRATEGY) {
    class Uri_query {
        constructor(...args) {
            return construct_uri_query.call(this, ...args);
        }
    }
    Uri_query.is_encoded = is_encoded;
    return module.exports = Object.freeze(Uri_query);

    // -----------

    function construct_uri_query(parsee, alter_params) {
        const this_uri_query = this;
        const strategy = DEFAULT_STRATEGY;
        Object.defineProperty(this_uri_query, 'toString', { value: to_string });
        if (undefined !== parsee && null !== parsee) {
            Object.assign(
                this_uri_query,
                parse_parsee(parsee, strategy, alter_params),
                ); // eslint-disable-line indent
        }
        return this_uri_query;

        // -----------

        function to_string() {
            return compose_query_string(this_uri_query, strategy, alter_params);
        }
    }
    function parse_parsee(parsee, strategy, alter_params) {
        let parsed_query_object;
        switch (true) {
            case 'string' === typeof parsee:
            case 'number' === typeof parsee:
            case 'boolean' === typeof parsee:
            case 'symbol' === typeof parsee:
                parsed_query_object
                    = parse_query_string(String(parsee), strategy)
                    ; // eslint-disable-line indent
                break;
            case 'object' === typeof parsee:
                parsed_query_object = parse_query_params(parsee, strategy);
                break;
        }
        if (parsed_query_object) {
            parsed_query_object = protect_proto(parsed_query_object);
            return alter_params
                ? alter_query_object('parse', parsed_query_object, alter_params)
                : parsed_query_object
                ; // eslint-disable-line indent
        }
        throw new TypeError([
            'URI queries must be constructed with a primitive value',
            'or an object',
            ].join(' ')); // eslint-disable-line indent
    }

    // -----------

    function parse_query_string(raw_query_string, strategy) {
        const trimmed_raw_query_string = raw_query_string.trim();
        if ([ '', '?', '#', '?#' ].includes(trimmed_raw_query_string)) {
            return {};
        }
        const hash_index = trimmed_raw_query_string.indexOf('#');
        /* eslint-disable indent */
        const query_string = trimmed_raw_query_string
            .substring(
                '?' === trimmed_raw_query_string.substring(0, 1) ? 1 : 0,
                -1 === hash_index ? undefined : hash_index,
                )
            .replace(/(?:^[&\s]+|[&\s]+$)/g, '') // trim white space and &'s
            .replace(/[&\s]*&[&\s]*/g, '&')
            ;
        /* eslint-enable indent */
        if ('' === query_string) {
            return {};
        }
        return strategy.parse_query_string(query_string);
    }

    function parse_query_params(raw_object, strategy) {
        const flattened_proto_object = {};
        // eslint-disable-next-line guard-for-in
        for (const key in raw_object) {
            const value = raw_object[key];
            switch (true) {
                case undefined === value:
                case null === value:
                case 'string' === typeof value:
                case 'number' === typeof value:
                case 'boolean' === typeof value:
                case 'symbol' === typeof value:
                case 'object' === typeof value:
                    flattened_proto_object[key] = value;
            }
        }
        return strategy.parse_query_params(flattened_proto_object);
    }

    function compose_query_string(query_object, strategy, alter_params) {
        const unsafe_query_object = unprotect_proto(query_object);
        const altered_object = alter_params
            ? alter_query_object('compose', unsafe_query_object, alter_params)
            : unsafe_query_object
            ; // eslint-disable-line indent
        return strategy.compose_query_string(altered_object);
    }

    // -----------

    function protect_proto(parsed_query_object) {
        const unsafe_keys = Object.getOwnPropertyNames(Object.prototype);
        const safe_query_object = Object.assign({}, parsed_query_object);
        for (const key of unsafe_keys) {
            '__proto__' !== key // __proto__ is ignored by javascript
                && undefined !== safe_query_object[key]
                && safe_query_object[key] !== Object.prototype[key]
                && protect_prop(key)
                ; // eslint-disable-line indent
        }
        return safe_query_object;

        // -----------

        function protect_prop(key) {
            safe_query_object[ `$$$${ key }` ] = safe_query_object[key];
            delete safe_query_object[key];
            return true;
        }
    }

    function unprotect_proto(parsed_query_object) {
        const unsafe_keys = Object.getOwnPropertyNames(Object.prototype);
        const unsafe_query_object = Object.assign({}, parsed_query_object);
        for (const unsafe_key of unsafe_keys) {
            const safe_key = `$$$${ unsafe_key }`;
            '__proto__' !== unsafe_key // __proto__ is ignored by javascript
                && undefined !== unsafe_query_object[safe_key]
                && unprotect_prop(unsafe_key, safe_key)
                ; // eslint-disable-line indent
        }
        return unsafe_query_object;

        // -----------

        function unprotect_prop(unsafe_key, safe_key) {
            unsafe_query_object[ unsafe_key ] = unsafe_query_object[safe_key];
            delete unsafe_query_object[safe_key];
            return true;
        }
    }

    // -----------

    function alter_query_object(mode, query_object, alter_params) {
        const altered_object = Object.assign({}, query_object);
        const query_keys = Object.keys(query_object);
        const alter_keys = Object.keys(alter_params);
        for (const key of alter_keys) {
            if (query_keys.includes(key)) {
                const alter_value = alter_params[key];
                /* eslint-disable indent */
                const perform_alteration
                    = 'parse' === mode ? 'function' === typeof alter_value
                        ? alter_value
                        : 'function' === typeof alter_value.parse
                            ? alter_value.parse
                            : dont_alter
                    : 'compose' === mode
                        ? 'function' === typeof alter_value.compose
                            ? alter_value.compose
                            : dont_alter
                    : dont_alter
                    ;
                /* eslint-ensable indent */
                altered_object[key] = perform_alteration(altered_object[key]);
            }
        }
        return altered_object;
    }

    function dont_alter(value) {
        return value;
    }

    // -----------

    function is_encoded(raw_uri_query) {
        return /^\??(?:[A-Za-z0-9-._~!$&'()*+,;=:@/?]|%[0-9A-F]{2})*(?:#.*)?$/
            .test(raw_uri_query)
            ; // eslint-disable-line indent
    }
}(
    require('./strategies/default'),
));


function isNumber(n) {
  return typeof n === 'number' && n % 1 === 0;
}

/*
 * Receiver stream
 */
var InStream = function (options) {
  options = options || {};
  this.maxLen = options.maxLen || 20; //how many packets can be buffered before stopping acknowledging new packets
  this.ops = [];
  this.seq = 0;
  this.drained = true;
  this._send = function (op) {
  };
};

InStream.prototype.isReadable = function () {
  return this.ops.length && this.ops[0].seq == (this.seq + 1);
};

InStream.prototype.pop = function () {

  if (!this.isReadable()) {
    return null;
  }

  var op = this.ops.shift();

  this.seq++;

  this._send({ack: this.seq});

  if (!this.isReadable()) {
    this.drained = true;
  }

  return op.data;
};

InStream.prototype.insert = function (op) {

  if (this.ops.length >= this.maxLen) {
    return; //packet buffer lenght exceeded, dropping packets
  }

  if (op.seq <= this.seq) {
    //already processed this op, acknowledge with the last seq we have have
    this._send({ack: this.seq});
    return;
  }

  if ((op.seq - this.seq - 1) > this.maxLen) {
    return; //if op.seq is i.e. 1000000, then algorithm will block itself because of this.maxLen
  }

  var pos = 0;

  for (var i = 0; i < this.ops.length; i++) {
    var opi = this.ops[i];
    if (opi.seq == op.seq) {
      return; //drop, this packet already is in ops - waiting for pop OR previous packets
    } else if (opi.seq < op.seq) {
      pos = i + 1; //most of the time it will be the end of array
    }
  }

  this.ops.splice(pos, 0, op);

  if (this.drained && this.onReadable && this.isReadable()) {
    this.drained = false;
    setTimeout(this.onReadable, 0);
  }
};

/*
 * Sender stream
 */
var OutStream = function (options) {
  options = options || {};
  this.retryTimeout = options.retryTimeout || 10000;
  this.maxNotAck = options.maxNotAck || 10; //how many unacknowledged packets can be in fly
  this.ops = [];
  this.seq = 0;
  this.sentSeq = 0; //the last packet which was sent, but still not acknowledged
  this.lastSend = 0;
  this._send = function (op) {
  };
};

OutStream.prototype.triggerSend = function () {

  if (this.isWaitingAck() && (Date.now() - this.lastSend) > this.retryTimeout) {
    this.sentSeq = this.ops[0].seq - 1;
  }

  if (this.ops.length) {
    if (this.sentSeq < (this.ops[0].seq + this.maxNotAck)) {
      for (var i = 0; i < this.ops.length; i++) {
        var opi = this.ops[i];
        if (opi.seq > this.sentSeq) {
          this._send(opi);
          this.sentSeq = opi.seq;
          this.lastSend = Date.now();
        }

        if ((i + 1) >= this.maxNotAck) {
          break;
        }
      }
    }
  }
};

OutStream.prototype.isWaitingAck = function () {
  return this.ops.length && this.sentSeq >= this.ops[0].seq; //it can be that there are ops, but we still haven't sent them, so trigger should them first
};

OutStream.prototype.retry = function () {
  if (this.ops.length) {
    this.sentSeq = this.ops[0].seq - 1;
    this.triggerSend();
  }
};

OutStream.prototype.push = function (data) {
  this.seq++;

  var op = {
    seq: this.seq,
    data: data
  };
  this.ops.push(op);
  this.triggerSend();
};

//find index of the acknowledged packet and remove every packet below
OutStream.prototype.acknowledge = function (seq) {
  var n = 0;
  for (var i = 0; i < this.ops.length; i++) {
    var opi = this.ops[i];
    if (opi.seq <= seq) {
      n = i + 1;
    }
  }

  if (n) {
    this.ops.splice(0, n);
    this.triggerSend();
  }
};

/*
 * OpStream
 */

var OpStream = function (options) {
  var opStream = this;

  options = options || {};

  this.pingIntervalMs = options.pingIntervalMs || 5000;
  this.pingTimeoutMs = options.pingTimeoutMs || 3000;

  this.inStream = new InStream({
    maxLen: options.inMaxLen
  });

  this.outStream = new OutStream({
    retryTimeout: options.outRetryTimeout,
    maxNotAck: options.outMaxNotAck
  });

  this.inStream._send = this._send.bind(this);
  this.outStream._send = this._send.bind(this);

  this.inStream.onReadable = function () {
    if (opStream.onReadable) opStream.onReadable();
  };

  this.onReadable = null;
  this.onOnline = null;
  this.onOffline = null;

  this.lastPing = 0;

  this.connectionStatus = 'online';
  this.paused = false;

  this.timerInterval = null;
  this.pingTimeout = null;

  this.initTimer();
};

OpStream.prototype.initTimer = function () {
  var opStream = this;
  this.timerInterval = setInterval(function () {
    opStream.outStream.triggerSend();
    opStream.triggerPing();
  }, 300);
};

OpStream.prototype.destroy = function() {
  clearInterval(this.timerInterval);
  if (this.pingTimeout) {
    clearTimeout(this.pingTimeout);
    this.pingTimeout = null;
  }
  this.onReadable = null;
  this.onOnline = null;
  this.onOffline = null;
};

OpStream.prototype.setPaused = function (pause) {
  if (pause) {
    this.paused = true;
  } else {
    if (this.paused) {
      this.paused = false;
      this.outStream.triggerSend();
    }
  }
};

OpStream.prototype.pingTimeouted = function () {
  if (this.connectionStatus == 'online') {
    this.connectionStatus = 'offline';
    if (this.onOffline) {
      this.onOffline();
    }
  }
};

OpStream.prototype.triggerPing = function () {
  if ((Date.now() - this.lastPing) > this.pingIntervalMs) {
    this._send({ping: Date.now()});
    this.pingTimeout = setTimeout(this.pingTimeouted.bind(this), this.pingTimeoutMs);
    this.lastPing = Date.now();
  }
};

OpStream.prototype.ponged = function (packet) {
  var time = Date.now() - packet.pong;
  if (this.pingTimeout) {
    clearTimeout(this.pingTimeout);
    this.pingTimeout = null;
  }
  if (this.connectionStatus == 'offline') {
    this.connectionStatus = 'online';
    if (this.onOnline) {
      this.onOnline();
    }
  }
};

OpStream.prototype.push = function (data) {
  this.outStream.push(data);
};

OpStream.prototype.pop = function () {
  return this.inStream.pop();
};

OpStream.prototype._send = function (op) {
  if (!this.paused && this.send) {
    this.send(op);
  }
};

OpStream.prototype.recv = function (packet) {
  if (packet.seq) {
    if (isNumber(packet.seq)) {
      this.inStream.insert(packet);
    }
  } else if (packet.ack) {
    if (isNumber(packet.ack)) {
      this.outStream.acknowledge(packet.ack);
    }
  } else if (packet.ping) {
    if (isNumber(packet.ping)) {
      this._send({pong: packet.ping});
    }
  } else if (packet.pong) {
    if (isNumber(packet.pong)) {
      this.ponged(packet);
    }
  }
};

module.exports = OpStream;


const DataStore = require('nedb');
const memFs = require('mem-fs');
const editor = require('mem-fs-editor');
const store = memFs.create();
const fs = editor.create(store);
const appRoot = require("app-root-path");
const path = require("path");
const tv4 = require("tv4");

/**
 * DAO implementation.
 * @constructor
 * @implements {DAOInterface}
 * @param {Object} config - Configuration.
 * @param {string} config.collectionName - Collection name.
 * @param {Object} config.schema - Collection schema.
 * @param {Object} config.basePath - Base path to collection data folder.
 * @param {string} [config.filename] - Path to the
 * file where the data is persisted. If left blank,
 * the datastore is automatically considered in-memory
 * only. It cannot end with a ~ which is used in the
 * temporary files NeDB uses to perform crash-safe writes.
 * @param {boolean} [config.inMemoryOnly] - Defaults
 * to false, as the name implies.
 * @param {boolean} [config.timestampData] - Defaults to
 * false. Timestamp the insertion and last update of all documents,
 * with the fields createdAt and updatedAt. User-specified
 * values override automatic generation, usually useful
 * for testing.
 * @param {boolean} [config.autoload] - Defaults to false.
 * If used, the database will automatically be loaded from
 * the datafile upon creation (you don't need to call
 * loadDatabase. Any command issued before load is finished
 * is buffered and will be executed when load is done.
 * @param {Object} [config.onload] - If you use autoloading,
 * this is the handler called after the loadDatabase.
 * It takes one error argument. If you use autoloading without
 * specifying this handler, and an error happens during load,
 * an error will be thrown.
 * @param {Object} [config.afterSerialization] - Hook you can use
 * to transform data after it was serialized and before it is
 * written to disk. Can be used for example to encrypt data
 * before writing database to disk. This function takes a
 * string as parameter (one line of an NeDB data file) and
 * outputs the transformed string, which must absolutely not
 * contain a \n character (or data will be lost).
 * @param {Object} [config.beforeDeserialization] - Inverse of
 * afterSerialization. Make sure to include both and not just
 * one or you risk data loss. For the same reason, make sure
 * both functions are inverses of one another. Some failsafe
 * mechanisms are in place to prevent data loss if you misuse
 * the serialization hooks: NeDB checks that never one is
 * declared without the other, and checks that they are reverse
 * of one another by testing on random strings of various lengths.
 * In addition, if too much data is detected as corrupt, NeDB will
 * refuse to start as it could mean you're not using the
 * deserialization hook corresponding to the serialization hook
 * used before (see below).
 * @param {number} [config.corruptAlertThreshold] -
 * between 0 and 1,
 * defaults to 10%. NeDB will refuse to start if more than this
 * percentage of the datafile is corrupt. 0 means you don't tolerate
 * any corruption, 1 means you don't care.
 * @param {Object} [config.compareStrings] - function
 * compareStrings(a, b)
 * compares strings a and b and return -1, 0 or 1. If specified,
 * it overrides default string comparison which is not well adapted
 * to non-US characters in particular accented letters. Native
 * localCompare will most of the time be the right choice.
 */
function DAOImplementation(config) {
  let basePath = config.basePath || 'backend/persistence/catalog/';
  let isDBloaded = true;
  if (config.filename) {
    config.filename = basePath + config.filename;
  }
  if (config.schema) {
    this.schema = fs.readJSON(path.join(appRoot.toString(),
      basePath, config.schema));
  } else {
    this.schema = {};
  }
  let db = new DataStore(config);
  if (config.filename && !config.autoload) {
    isDBloaded = false;
  }
  this.collection = db;
  this.isDBloaded = isDBloaded;
}

DAOImplementation.prototype.find = function(query, options) {
  return loadDB(this)
    .then(db => find(db, query, options));
};

DAOImplementation.prototype.findOne = function(query) {
  if (typeof query === 'string') {
    query = {_id: query};
  }
  return loadDB(this)
    .then(db => findOne(db, query));
};

DAOImplementation.prototype.insert = function(data) {
  let dao = this;
  return loadDB(this)
    .then(() => insert(dao, data));
};

DAOImplementation.prototype.update = function(query, data, options) {
  let dao = this;
  if (typeof query === 'string') {
    query = {_id: query};
  }
  return loadDB(this)
    .then(() => update(dao, query, data, options));
};

DAOImplementation.prototype.patch = function(query, change) {
  let dao = this;
  // update['$set'] = change; // we could use set to make a patch

  return this.findOne(query)
    .then(function(result) {
      let update = Object.keys(change)
        .reduce(function(doc, prop) {
          doc[prop] = change[prop];
          return doc;
        }, result);
      return dao.update(query, update);
    });
};

DAOImplementation.prototype.remove = function(query, options) {
  let dao = this;
  return loadDB(this)
    .then(() => remove(dao, query, options));
};

DAOImplementation.prototype.getSchema = function() {
  return Promise.resolve(this.schema);
};

function find(db, query, options) { // eslint-disable-line require-jsdoc
  options = options || {};
  query = query || {};
  var search = db.find(query);
  if (options.sort) {
    search.sort(options.sort);
  }
  if (options.skip) {
    search.skip(options.skip);
  }
  if (options.limit) {
    search.limit(options.limit);
  }
  return new Promise(function(fulfill, reject) {
    search.exec(function(err, docs) {
      if (err) {
        reject(err);
      } else {
        fulfill(docs);
      }
    });
  });
}

function findOne(db, query) { // eslint-disable-line require-jsdoc
  return new Promise(function(fulfill, reject) {
    db.findOne(query, function(err, doc) {
      if (err) {
        reject(err);
      } else {
        fulfill(doc);
      }
    });
  });
}

function insert(dao, data) { // eslint-disable-line require-jsdoc
  let db = dao.collection;
  let schema = dao.schema;
  let isValid = true;

  if (Array.isArray(data)) {
    data.some(function(item) {
      isValid = tv4.validate(item, schema);
      return !isValid;
    });
  } else {
    isValid = tv4.validate(data, schema);
  }

  return new Promise(function(fulfill, reject) {
    if (!isValid) {
      reject(new Error("422"));
    }
    db.insert(data, function(err, doc) {
      if (err) {
        reject(err);
      } else {
        fulfill(doc);
      }
    });
  });
}

function update(dao, query, data, options) { // eslint-disable-line require-jsdoc
  query = query || {};
  options = options || {};
  let db = dao.collection;
  let schema = dao.schema;
  return new Promise(function(fulfill, reject) {
    if (!tv4.validate(data, schema)) {
      reject(new Error("422"));
    }
    db.update(query, data, options,
      function(err, numAffected) { // callback params: err, numAffected, affectedDocuments
        if (err) {
          reject(err);
        } else {
          fulfill(numAffected);
        }
      });
  });
}

function remove(dao, query, options) { // eslint-disable-line require-jsdoc
  query = query || {};
  options = options || {};
  let db = dao.collection;
  return new Promise(function(fulfill, reject) {
    db.remove(query, options,
      function(err, numAffected) {
        if (err) {
          reject(err);
        } else {
          fulfill(numAffected);
        }
      });
  });
}

function loadDB(dao) { // eslint-disable-line require-jsdoc
  let result;
  let db = dao.collection;
  let isDBloaded = dao.isDBloaded;
  if (isDBloaded) {
    result = Promise.resolve(db);
  } else {
    result = new Promise(function(fulfill, reject) {
      db.loadDatabase(function(err) {
        if (err) {
          reject(err);
        } else {
          dao.isDBloaded = true;
          fulfill(db);
        }
      });
    });
  }
  return result;
}

module.exports = DAOImplementation;


var util         = require('util');
var _            = require('underscore');
var EventEmitter = require('events').EventEmitter;

// Find the Proxy Constructor to use
var ProxyCtor;
try {
    ProxyCtor = Proxy;
}
catch (error) {
    try {
        ProxyCtor = require('node-proxy');
    }
    catch(error) {
        console.error('You need to run node with --harmony_proxies enabled or have the node-proxy module installed');
        process.exit(1);
    }
}

// Quick reference to Object.prototype
var ObjProto = Object.prototype;

/**
 * Model implementation based on Backbone.js' Model implementation.
 *
 * The Model object uses an internal hash to store it's values and
 * emits events on Model attribute changes.
 *
 * @param {Object} attributes   Initial attributes for the Model
 */
function Model(attributes) {
    // Set events hash now to prevent proxy trap
    this._events = {};

    // Call super constructor
    EventEmitter.call(this);
    attributes = attributes || {};

    // Separator for change events
    this._separator = ':';

    // Internal Object for storing attributes
    this.attributes = {};

    // Attributes that have changed since the last `change` was called.
    this._changed = {};
    // Hash of attributes that have changed silently since the last `change`
    // was called.
    this._silent  = {};
    // Hash of changed attributes that have changed since the last `change`
    // call began.
    this._pending = {};

    // Set initial attributes silently
    this.set(attributes, { silent: true });

    // Reset changes
    this._changes = {};
    this._silent  = {};
    this._pending = {};

    // Keep track of previous values (before the previous change call)
    this._previous = _.clone(this.attributes);

    // Call initialize logic
    this.initialize.apply(this, arguments);
}
util.inherits(Model, EventEmitter);

/**
 * Initialize logic for the Model. Override this method to implement your
 * own initialize logic.
 */
Model.prototype.initialize = function() {};

/**
 * Clone the Model. This will transfer all Model attributes to a new Model
 * instance.
 * @return Model
 */
Model.prototype.clone = function() {
    return new Model(this.attributes);
};

/**
 * Get the JSON representation of the Model
 * @return Object
 */
Model.prototype.toJSON = function() {
    return this.attributes;
};

/**
 * Check if the Model has an attribute specified by `name`.
 * @param {String} name
 * @return Boolean
 */
Model.prototype.has = function(name) {
    return ObjProto.hasOwnProperty.call(this.attributes, name);
};

/**
 * Get a value from the Model
 * @param {String} name
 * @return mixed            The value for the attribute or undefined
 */
Model.prototype.get = function(name) {
    if (this.has(name)) {
        return this.attributes[name];
    }
};

/**
 * Set a value on the Model
 * @param {Sting} name
 * @param Mixed value
 */
Model.prototype.set = function(name, value, options) {
    var attrs, attr, val;

    // Handle both `"key", value` and `{key: value}` -style arguments.
    if (_.isObject(name) || name == null) {
        attrs = name;
        options = value;
    } else {
        attrs = {};
        attrs[name] = value;
    }

    // Extract attributes and options.
    options || (options = {});
    if (!attrs) return this;
    if (options.unset) for (attr in attrs) attrs[attr] = void 0;

    var changes  = options.changes = {};
    var current  = this.attributes;
    var previous = this._previous || {};

    // For each `set` attribute...
    for (attr in attrs) {
        val = attrs[attr];

        // If the new and current value differ, record the change.
        if (!_.isEqual(current[attr], val) || (options.unset && _.has(now, attr))) {
            (options.silent ? this._silent : changes)[attr] = true;
        }

        // Update or delete the current value.
        options.unset ? delete current[attr] : current[attr] = val;

        // If the new and previous value differ, record the change. If not,
        // then remove changes for this attribute.
        if (!_.isEqual(previous[attr], val) || (_.has(current, attr) != _.has(previous, attr))) {
            this._changed[attr] = val;
            if (!options.silent) this._pending[attr] = true;
        } else {
            delete this._changed[attr];
            delete this._pending[attr];
        }
    }

    // Fire the `"change"` events.
    if (!options.silent) this.change(options);
    return this;
};

/**
 * Call this method to manually fire a `"change"` event for this model and
 * a `"change:attribute"` event for each changed attribute.
 * Calling this will cause all objects observing the model to update.
 * @param {Object} options
 */
Model.prototype.change = function(options) {
    options || (options = {});
    var changing = this._changing;
    this._changing = true;

    // Silent changes become pending changes.
    for (var attr in this._silent) this._pending[attr] = true;

    // Silent changes are triggered.
    var changes = _.extend({}, options.changes, this._silent);
    this._silent = {};
    for (var attr in changes) {
        this.emit('change' + this._separator + attr, this, this.get(attr), options);
    }
    if (changing) return this;

      // Continue firing `"change"` events while there are pending changes.
    while (!_.isEmpty(this._pending)) {
        this._pending = {};
        this.emit('change', this, options);
        // Pending and silent changes still remain.
        for (var attr in this.changed) {
            if (this._pending[attr] || this._silent[attr]) continue;
            delete this._changed[attr];
        }
        this._previousAttributes = _.clone(this.attributes);
    }

    this._changing = false;
    return this;
};

/**
 * Unset an attribute on the Model
 * @param {String} name
 * @param {Object} options
 * @return Boolean
 */
Model.prototype.unset = function(name, options) {
    options = _.extend({}, options, { unset: true });
    return this.set(name, null, options);
};

/**
 * Link attributes from a foreign object to the Model. Linked values set
 * on the Model will be transfered directly to the foreign Object.
 * @param {Object} linkMap
 * @param {Object} foreignObject
 * @param {Object} options
 */
Model.prototype.link = function(linkMap, foreignObject, options) {
    throw new Error('Not implemented');
};

/**
 * ProxiedModel constructor. This will return a ProxyHandle to act as a Proxy for
 * the created model.
 */
function ProxiedModel(attributes) {
    var model;
    if (attributes instanceof Model) {
        // Use existing model
        model = attributes;
    }
    else {
        // Create a new Model
        model = new Model(attributes);
    }

    // Return the Proxy handler
    return createModelProxy(model);
}

/**
 * Create a Proxy for a Model. This function will return a new Proxy handle for the given Model.
 * @param {Model} model
 * @return Object
 */
function createModelProxy(model) {

    // Create a Proxy handle
    var handle = {
        getOwnPropertyDescriptor: function(target, name) {
            return ObjProto.getOwnPropertyDescriptor.call(model.attributes, name);
        },
        getOwnPropertyNames: function(target) {
            return ObjProto.getOwnPropertyNames.call(model.attributes);
        },
        defineProperty: function(name, propertyDescriptor) {
            return Object.defineProperty(model.attributes, name, propertyDescriptor);
        },
        // Get an attribute from the Model. This will first check for Model properties before
        // checking the Model's internal attributes map.
        get: function(target, name, reciever) {
            // Check for direct properties to satisfy internal attribute and function calls
            if (model[name]) {
                return model[name];
            }

            // It's not a property, check for internal attribute value
            return model.get(name);
        },
        set: function(target, name, value, receiver) {
            return model.set(name, value);
        },
        delete: function(name) {
            model.unset(name);
        },
        has: function(target, name) {
            return model.has('name');
        },
        hasOwn: function(target, name) {
            return this.has(target, name);
        },
        enumerate: function(target) {
            return model.attributes;
        },
        keys: function(target) {
            return Object.keys(model.attributes);
        }
        //protect: function(operation, target) -> boolean
        //stopTrapping: function(target) -> boolean
        //iterate: not implemented yet
    };

    return ProxyCtor.create(handle, Model);
}

// our awesome export products
exports = module.exports = {
    Model:        Model,
    ProxiedModel: ProxiedModel,
    proxyModel:   createModelProxy
};


/*
 * grunt-contrib-copy
 * http://gruntjs.com/
 *
 * Copyright (c) 2014 Chris Talkington, contributors
 * Licensed under the MIT license.
 * https://github.com/gruntjs/grunt-contrib-copy/blob/master/LICENSE-MIT
 */

/*
 * grunt-json5-to-json
 * https://github.com/leader22/grunt-json5-to-json
 *
 * Copyright (c) 2014 leader22
 * Licensed under the MIT license.
 */

module.exports = function(grunt) {
    'use strict';

    var path = require('path');
    var fs = require('fs');
    var chalk = require('chalk');
    var JSON5 = require('json5');
    var cnst = {
        windows:   'win32',
        file:      'file',
        directory: 'directory'
    };

    grunt.registerMultiTask('json5_to_json', 'Convert json5 to json.', function() {
        var kindOf = grunt.util.kindOf;

        var options = this.options({
            encoding: grunt.file.defaultEncoding,
            replacer: null,
            space: 2
        });

        var dest;
        var isExpandedPair;
        var tally = {
            dirs: 0,
            files: 0
        };
        var obj;
        var json;
        var json5;

        this.files.forEach(function(filePair) {
            isExpandedPair = filePair.orig.expand || false;

            filePair.src.forEach(function(src) {
                if (detectDestType(filePair.dest) === cnst.directory) {
                    dest = (isExpandedPair) ? filePair.dest : unixifyPath(path.join(filePair.dest, src));
                } else {
                    dest = filePair.dest;
                }

                if (grunt.file.isDir(src)) {
                    grunt.verbose.writeln('Creating ' + chalk.cyan(dest));
                    grunt.file.mkdir(dest);

                    tally.dirs++;
                } else {
                    grunt.verbose.writeln('Converting ' + chalk.cyan(src) + ' -> ' + chalk.cyan(dest));
                    json5 = grunt.file.read(src, options);
                    try {
                      obj = JSON5.parse(json5);
                      json = JSON.stringify(obj, options.replacer, options.space);
                    } catch(e) {
                      grunt.log.error(e + ' in ' + src);
                      return;
                    }

                    dest = dest.split(path.extname(dest))[0] + '.json';
                    grunt.file.write(dest, json, options);

                    tally.files++;
                }
            });
        });

        if (tally.dirs) {
            grunt.log.write('Created ' + chalk.cyan(tally.dirs.toString()) + ' directories');
        }

        if (tally.files) {
            grunt.log.write((tally.dirs ? ', converted ' : 'Converted ') + chalk.cyan(tally.files.toString()) + (tally.files === 1 ? ' file' : ' files'));
        }

        grunt.log.writeln();
    });

    // Private functions.
    function detectDestType(dest) {
        if (grunt.util._.endsWith(dest, '/')) {
            return cnst.directory;
        } else {
            return cnst.file;
        }
    }

    function unixifyPath(filepath) {
        if (process.platform === cnst.windows) {
            return filepath.replace(/\\/g, '/');
        } else {
            return filepath;
        }
    }
};


'use strict';

// MODULES //

var partial = require( './partial.js' );

// RANDOM //

/**
* FUNCTION: random( len, mu, sigma[, rand] )
*	Creates an array of normally distributed random numbers.
*
* @param {Number} len - array length
* @param {Number} mu - mean parameter
* @param {Number} sigma - standard deviation
* @param {Function} [rand=Math.random] - random number generator
* @returns {Number[]} array filled with normal random numbers
*/
function random( len, mu, sigma, rand ) {
	var out;
	var draw;
	var i;

	draw = partial( mu, sigma, rand );
	// Ensure fast elements...
	if ( len < 64000 ) {
		out = new Array( len );
		for ( i = 0; i < len; i++ ) {
			out[ i ] = draw();
		}
	} else {
		out = [];
		for ( i = 0; i < len; i++ ) {
			out.push( draw() );
		}
	}
	return out;
} // end FUNCTION random()

// EXPORTS //

module.exports = random;


/**
*
*	COMPUTE: roundn
*
*
*	DESCRIPTION:
*		- Round values to the nearest multiple of 10^n.
*
*
*	NOTES:
*		[1]
*
*
*	TODO:
*		[1]
*
*
*	LICENSE:
*		MIT
*
*	Copyright (c) 2014. Athan Reines.
*
*
*	AUTHOR:
*		Athan Reines. kgryte@gmail.com. 2014.
*
*/

'use strict';

/**
* FUNCTION: roundn( x, n )
*	Rounds values to the nearest multiple of 10^n. Notes: if provided an array, mutates the array.
*
* @param {Array|Number} x - value(s) to be rounded
* @param {Number} n - power of 10; should be an integer value
* @returns {Array|Number|Null} rounded value(s). If `x` is an empty array, returns `null`.
*/
function roundn( x, n ) {
	var isArray = Array.isArray( x ),
		scalar,
		len;
	if ( !isArray && ( typeof x !== 'number' || x !== x ) ) {
		throw new TypeError( 'roundn()::invalid input argument. Must provide either a single numeric value or a numeric array.' );
	}
	if ( typeof n !== 'number' || n !== n || n !== ( n | 0) ) {
		throw new TypeError( 'roundn()::invalid input argument. Power of 10 must be an integer value.' );
	}
	n = -n;
	scalar = Math.pow( 10, n );
	if ( !isArray ) {
		return Math.round( x*scalar ) / scalar;
	}
	len = x.length;
	if ( !len ) {
		return null;
	}
	for ( var i = 0; i < len; i++ ) {
		x[ i ] = Math.round( x[i]*scalar ) / scalar;
	}
	return x;
} // end FUNCTION roundn()

// EXPORTS //

module.exports = roundn;


/**
 * pingy: PNG creation and manipulation helper
 * https://github.com/gavinhungry/pingy
 *
 * Released under the terms of the MIT license
 */

(function() {
  'use strict';

  var PNG = require('pngjs').PNG;
  var Stream = require('stream');

  var is_num = function(v) { return !isNaN(v); };
  var to_int = function(v) { return Math.floor(+v) || 0; };
  var to_rgba_int = function(v) { return clamp(to_int(v), 0, 255); };

  var clamp = function(val, min, max) {
    val = is_num(val) ? val: 0;
    min = is_num(min) ? min : Number.NEGATIVE_INFINITY;
    max = is_num(max) ? max : Number.POSITIVE_INFINITY;

    return Math.min(Math.max(val, min), max);
  };

  /**
   * Get an image buffer for a given width and height
   *
   * @param {Number} width - image width
   * @param {Number} height - image height
   * @return {Buffer}
   */
  var buffer = function(width, height) {
    return new Buffer(width * height * 4); // RGBA
  };

  /**
   * Get the buffer index of a coordinate
   *
   * @param {Number} width - image width
   * @param {Number} x - x coordinate
   * @param {Number} y - y coordinate
   * @return {Number} index of coordinate in an image buffer
   */
  var get_index = function(width, x, y) {
    return (width * y + x) << 2;
  };

  /**
   * Get a random color
   *
   * @return {Object} RGBA value
   */
  var random_rgba = function() {
    return {
      r: Math.floor(Math.random() * 256),
      g: Math.floor(Math.random() * 256),
      b: Math.floor(Math.random() * 256),
      a: 255
    };
  };

  /**
   * Pingy constructor
   *
   * @param {Number} [width] - image width
   * @param {Number} [height] - image height
   * @return {Pingy}
   */
  var Pingy = function(width, height) {
    width = clamp(width, 1);
    height = clamp(height, 1);

    this._png = new PNG();
    this._png.width = width;
    this._png.height = height;

    this._png.data = buffer(width, height);

    this.forEachPoint(function(x, y, rgba) {
      return { r:0, g:0, b:0, a:255 };
    });
  };

  /**
   * Create a Pingy object from an existing pngjs object
   *
   * @param {PNG} png - pngjs object
   * @return {Pingy}
   */
  Pingy.fromPNG = function(png) {
    var self = new Pingy();
    self._png = png;
    return self;
  };

  /**
   * Create a Pingy object from an array of points
   *
   * @param {PNG} arr - 2-dimensional array of RGBA values
   * @return {Pingy}
   */
  Pingy.fromArray = function(arr) {
    var self = new Pingy(arr[0].length, arr.length);

    return self.forEachPoint(function(x, y, rgba) {
      return arr[y][x];
    });
  };

  /**
   * Create a Pingy object from ASCII art
   *
   * Unmapped colors are assigned a random color (per character)
   *
   * @param {String} art - ASCII art
   * @param {Object} map - map of characters to RGBA values
   * @return {Pingy}
   */
  Pingy.fromAsciiArt = function(art, map) {
    map = map || {};

    var arr = art.split('\n').map(function(row) {
      return row.split('').map(function(c) {
        if (!map[c]) { map[c] = random_rgba(); }
        return map[c];
      });
    });

    return Pingy.fromArray(arr);
  };

  Pingy.prototype = {

    /**
     * Get the buffer index of a coordinate
     *
     * @private
     * @param {Number} x - x coordinate
     * @param {Number} y - y coordinate
     * @return {Number} index of coordinate in image buffer
     */
    _getIndex: function(x, y) {
      return get_index(this._png.width, x, y);
    },

    /**
     * Execute a function on each point in an image
     *
     * The rgba object passed to the callback will be saved back to the image,
     * so no need to call `set_rgba` there
     *
     * If the callback returns an object, it will be used as the new rgba value
     *
     * @param {Function} fn - Function(x, y, rgba) to execute
     * @return {Pingy} self
     */
    forEachPoint: function(fn) {
      for (var y = 0; y < this.getHeight(); y++) {
        for (var x = 0; x < this.getWidth(); x++) {

          var rgba = this.getColor(x, y);
          var out = fn.call(this, x, y, rgba);

          this.setColor(x, y, (out || rgba));
        }
      }

      return this;
    },

    /**
     * Get the RGBA value of a coordinate
     *
     * @param {Number} x - x coordinate
     * @param {Number} y - y coordinate
     * @return {Object} RGBA value
     */
    getColor: function(x, y) {
      var i = this._getIndex(x, y);

      return {
        r: this._png.data[i + 0],
        g: this._png.data[i + 1],
        b: this._png.data[i + 2],
        a: this._png.data[i + 3]
      };
    },

    /**
     * Set the RGBA value of a coordinate
     *
     * @param {Number} x - x coordinate
     * @param {Number} y - y coordinate
     * @param {Object} rgba - RGBA value
     * @return {Object} RGBA value
     */
    setColor: function(x, y, rgba) {
      var i = this._getIndex(x, y);
      var prev = this.getColor(x, y);

      this._png.data[i + 0] = is_num(rgba.r) ? to_rgba_int(rgba.r): prev.r;
      this._png.data[i + 1] = is_num(rgba.g) ? to_rgba_int(rgba.g): prev.g;
      this._png.data[i + 2] = is_num(rgba.b) ? to_rgba_int(rgba.b): prev.b;
      this._png.data[i + 3] = is_num(rgba.a) ? to_rgba_int(rgba.a): prev.a;

      return this.getColor(x, y);
    },

    /**
     * Get the image width
     *
     * @return {Number} image width
     */
    getWidth: function() {
      return this._png.width;
    },

    /**
     * Get the image height
     *
     * @return {Number} image height
     */
    getHeight: function() {
      return this._png.height;
    },

    /**
     * Enlarge by some integer factor
     *
     * @param {Number} factor
     * @return {Pingy} self
     */
    scale: function(factor) {
      factor = clamp(to_int(factor), 1);

      var width = this.getWidth() * factor;
      var height = this.getHeight() * factor;

      var buf = new buffer(width, height);

      for (var y = 0; y < height; y++) {
        for (var x = 0; x < width; x++) {

          var i = get_index(width, x, y);
          var rgba = this.getColor(to_int(x / factor), to_int(y / factor));

          buf[i + 0] = rgba.r;
          buf[i + 1] = rgba.g;
          buf[i + 2] = rgba.b;
          buf[i + 3] = rgba.a;
        }
      }

      this._png.width = width;
      this._png.height = height;
      this._png.data = buf;

      return this;
    },

    /**
     * Get the base64 encoding
     *
     * @param {Function} [fn] - callback, defaults to console.log
     */
    toBase64: function(fn) {
      fn = fn || console.log.bind(console);

      var buffers = [];

      var base64 = new Stream();
      base64.readable = base64.writable = true;
      base64.write = function(data) {
        buffers.push(data);
      };

      base64.end = function() {
        fn(Buffer.concat(buffers).toString('base64'));
      }

      this._png.pack().pipe(base64);
    },

    /**
     * Get the base64 encoding as a data URI
     *
     * @param {Function} [fn] - callback, defaults to console.log
     */
    toBase64Uri: function(fn) {
      fn = fn || console.log.bind(console);

      return this.toBase64(function(str) {
        fn('data:image/png;base64,' + str);
      });
    }
  };

  module.exports = Pingy;

})();


'use strict';

function isArguments(object) {
  return Object.prototype.toString.call(object) === '[object Arguments]';
}

var fastEqual;
try {
  require('buffertools');
  fastEqual = Buffer.equals;
}
catch (e) {
  // whoops, weren't able to install node-buffertools o well
}

/**
 * This is a node-specific version of an anal structural equality test, modeled
 * on bits and pieces of many other versions of this check, most notably
 * deeper, which is in turn based on the Node.js source's assert.deepEqual and
 * the Underscore library. It doesn't throw and handles cycles.
 *
 * Everybody who writes one of these functions puts the documentation
 * inline, which makes it incredibly hard to follow. Here's what this version
 * of the algorithm does, in order:
 *
 * 1. === only tests objects and and functions by reference. Null is an object.
 *    Any pairs of identical entities failing this test are therefore objects
 *    (including null), which need to be recursed into and compared attribute by
 *    attribute.
 * 2. Since the only matching entities to get to this test must be objects, if
 *    a or b is not an object, they're clearly not the same. All unfiltered a
 *    and b getting are objects (including null).
 * 3. null is an object, but null === null. All unfiltered a and b are non-null
 *    objects.
 * 4. Buffers need to be special-cased because they live partially on the wrong
 *    side of the C++ / JavaScript barrier. Still, calling this on structures
 *    that can contain Buffers is a bad idea, because they can contain
 *    multiple megabytes of data and comparing them byte-by-byte is hella
 *    expensive.
 * 5. It's much faster to compare dates by numeric value than by lexical value.
 * 6. Same goes for Regexps.
 * 7. The parts of an arguments list most people care about are the arguments
 *    themselves, not the callee, which you shouldn't be looking at anyway.
 * 8. Objects are more complex:
 *    a. ensure that a and b are on the same constructor chain
 *    b. ensure that a and b have the same number of own properties, *ignoring
 *       whether they're enumerable or not*.
 *    c. ensure that cyclical references don't blow up the stack.
 *    d. ensure that all the property names match (faster).
 *    e. fetch each property's descriptor, and ensure all the regular descriptor
 *       values match.
 *    f. recursively call deepest on any property values found through the
 *       descriptor.
 *
 * (SOMEWHAT UNTESTED) ASSUMPTIONS:
 *
 * o Functions are only considered identical if they unify to the same
 *   reference. To anything else is to invite the wrath of the halting problem.
 * o V8 is smart enough to optimize treating an Array like any other kind of
 *   object.
 * o Users of this function are cool with mutually recursive data structures
 *   that are otherwise identical being treated as the same.
 */
function deepest(a, b, ca, cb) {
  if (a === b) {
    return true;
  }
  else if (typeof a !== 'object' || typeof b !== 'object') {
    return false;
  }
  else if (a === null || b === null) {
    return false;
  }
  else if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {
    if (fastEqual) {
      return fastEqual.call(a, b);
    }
    else {
      if (a.length !== b.length) return false;

      for (var i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;

      return true;
    }
  }
  else if (a instanceof Date && b instanceof Date) {
    return a.getTime() === b.getTime();
  }
  else if (isArguments(a) || isArguments(b)) {
    if (!(isArguments(a) && isArguments(b))) return false;

    var slice = Array.prototype.slice;
    return deepest(slice.call(a), slice.call(b), ca, cb);
  }
  else {
    if (a.constructor !== b.constructor) return false;

    var pa = Object.getOwnPropertyNames(a);
    var pb = Object.getOwnPropertyNames(b);
    if (pa.length !== pb.length) return false;

    var cal = ca.length;
    while (cal--) if (ca[cal] === a) return cb[cal] === b;
    ca.push(a); cb.push(b);

    pa.sort(); pb.sort();
    for (var j = pa.length - 1; j >= 0; j--) if (pa[j] !== pb[j]) return false;

    var name, da, db;
    for (var k = pa.length - 1; k >= 0; k--) {
      name = pa[k];
      da = Object.getOwnPropertyDescriptor(a, name);
      db = Object.getOwnPropertyDescriptor(b, name);
      if (da.enumerable   !== db.enumerable   ||
          da.writable     !== db.writable     ||
          da.configurable !== db.configurable ||
          da.get          !== db.get          ||
          da.set          !== db.set) {
        return false;
      }
      if (!deepest(da.value, db.value, ca, cb)) return false;
    }

    ca.pop(); cb.pop();

    return true;
  }
}

function wrapper(a, b) {
  return deepest(a, b, [], []);
}

wrapper.patchAssert = function () {
  var assert = require('assert');
  assert.deepEqual = function deepEqual(actual, expected, message) {
    if (!wrapper(actual, expected)) {
      assert.fail(actual, expected, message, 'deepEqual', assert.deepEqual);
    }
  };
};

wrapper.patchChai = function () {
  var chai = require('chai');
  chai.Assertion.overwriteMethod('eql', function () {
    return function eql(obj, msg) {
      this.assert(wrapper(this._obj, obj),
                  "expected #{this} to deeply equal #{exp}",
                  "expected #{this} to not deeply equal #{exp}",
                  obj,
                  this._obj,
                  true);
    };
  });
};

/**
 * Isaac and James, I thought you were my friends. :(
 *
 * This is some super-burly monkeypatching here, done more out of determination
 * to figure out how to do it than good sense. Still, it works and is only as
 * fragile as node-tap is mutable.
 */
wrapper.patchTap = function () {
  var tap      = require('tap')
    , inherits = require('inherits')
    ;

  // copied straight from tap-test.js
  function assertParasite(fn) {
    return function _deeperAssert() {
      if (this._bailedOut) return;

      var res = fn.apply(tap.assert, arguments);
      this.result(res);
      return res;
    };
  }

  // methods and synonyms that will use deepest under the covers
  var omg = [
    "equivalent",
    "isEquivalent",
    "looseEqual",
    "looseEquals",
    "isDeeply",
    "same",
    "deepEqual",
    "deepEquals",
    "notEquivalent",
    "notDeepEqual",
    "notDeeply",
    "notSame",
    "isNotDeepEqual",
    "isNotDeeply",
    "isNotEquivalent",
    "isInequivalent",
    "inequivalent"
  ];

  var oldAssert = tap.assert;
  // ditch assert's properties by hiding them behind a proxy
  tap.assert = oldAssert.bind(null);
  tap.assert.ok = tap.assert;
  Object.getOwnPropertyNames(oldAssert).forEach(function (name) {
    if (tap.assert.hasOwnProperty(name) || name === 'prototype') return;

    if (omg.indexOf(name) >= 0) return;

    var descriptor = Object.getOwnPropertyDescriptor(oldAssert, name);
    Object.defineProperty(tap.assert, name, descriptor);
  });

  var newTestProto = {};
  Object.getOwnPropertyNames(tap.Test.prototype).forEach(function (name) {
    if (omg.indexOf(name) >= 0) return;

    var descriptor = Object.getOwnPropertyDescriptor(tap.Test.prototype, name);
    Object.defineProperty(newTestProto, name, descriptor);
  });
  tap.Test.prototype = newTestProto;
  // have to reset the prototype after wantonly abusing it
  inherits(tap.Test, tap.Test.super);

  function equivalent(a, b, message, extra) {
    if (extra && extra.skip) return tap.assert.skip(message, extra);

    extra        = extra   || {};
    message      = message || "should be equivalent";
    extra.found  = a;
    extra.wanted = b;

    return tap.assert(wrapper(a, b), message, extra);
  }
  tap.assert.equivalent = equivalent;
  tap.Test.prototype.equivalent = equivalent;

  [
    "isEquivalent",
    "looseEqual",
    "looseEquals",
    "isDeeply",
    "same",
    "deepEqual",
    "deepEquals"
  ].forEach(function (alias) {
    Object.defineProperty(tap.assert, alias, {
      value      : equivalent,
      enumerable : false
    });

    var descriptor = Object.getOwnPropertyDescriptor(tap.assert, alias)
      , value = descriptor.value
      ;

    if (!value) return;

    descriptor.value = assertParasite(value);
    Object.defineProperty(tap.Test.prototype, alias, descriptor);
  });

  function inequivalent(a, b, message, extra) {
    if (extra && extra.skip) return tap.assert.skip(message, extra);

    extra           = extra   || {};
    message         = message || "should not be equivalent";
    extra.found     = a;
    extra.doNotWant = b;

    return tap.assert(!wrapper(a, b), message, extra);
  }
  tap.assert.inequivalent = inequivalent;
  tap.Test.prototype.inequivalent = inequivalent;

  [
    "notEquivalent",
    "notDeepEqual",
    "notDeeply",
    "notSame",
    "isNotDeepEqual",
    "isNotDeeply",
    "isNotEquivalent",
    "isInequivalent"
  ].forEach(function (alias) {
    Object.defineProperty(tap.assert, alias, {
      value      : inequivalent,
      enumerable : false
    });

    var descriptor = Object.getOwnPropertyDescriptor(tap.assert, alias)
      , value      = descriptor.value
      ;

    if (!value) return;

    descriptor.value = assertParasite(value);
    Object.defineProperty(tap.Test.prototype, alias, descriptor);
  });
};

module.exports = wrapper;


var uglify = require('uglify-js');

/**
 * Generates an immediately-invoked function expression to be placed inside
 * <script> tags.
 * @param  {String} email
 * @param  {String} text
 * @return {String}
 */
module.exports.generate = function (email, text) {
  /* rot13 encode the email address */
  email = rot13(email);

  /* rot13 encode the text (it may contain email) */
  text = rot13(text);

  /* Start building the js string. */
  /* Assign the rot13 email to a var */
  var js = 'var email = \'' + email + '\';';

  /* Assign the link text to a var */
  js += 'var text = \'' + text + '\';';

  /* Call the swapTags function */
  js += 'swapTags(rot13(email), rot13(text));';

  /* Include the swapTags function */
  js += swapTags.toString();

  /* Include the rot13 function */
  js += rot13.toString();

  /* Wrap everything in an immediately-invoked function expression */
  js = '(function(){' + js + '})();';

  /* Minify */
  js = uglify.minify(js, {fromString: true});

  /* Return minified code */
  return js.code;
};

/**
 * Performs rot13 encoding/decoding
 * @param  {String} str
 * @return {String}
 */
function rot13(str) {
  return str.replace(/[a-zA-Z]/g , function(c) {
    return String.fromCharCode(
      (c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13 ) ? c : c - 26);
  });
}

/**
 * Swaps all tags with a class of "obfuscemail" with an <a> mailto link
 * @param  {String} email
 * @param  {String} text
 */
function swapTags(email, text) {
  document.querySelectorAll('.obfuscemail').forEach(function(a) {
    var newA = document.createElement('a');
    newA.href = 'mailto:' + email;
    newA.innerHTML = text;
    a.parentNode.replaceChild(newA, a);
  });
}

/* Expose functions to Node.js require(). Also helps with testing. */
module.exports.rot13 = rot13;
module.exports.swapTags = swapTags;


'use strict';

// MODULES //

var matrix = require( 'dstructs-matrix' );
var partial = require( './partial.js' );

// RANDOM //

/**
* FUNCTION: random( dims, dt, mu, sigma[, rand] )
*	Creates a matrix of normally distributed random numbers.
*
* @param {Number[]} dims - dimensions
* @param {String} dt - data type
* @param {Number} mu - mean parameter
* @param {Number} sigma - standard deviation
* @param {Function} [rand=Math.random] - random number generator
* @returns {Matrix} matrix filled with normal random numbers
*/
function random( dims, dt, mu, sigma, rand ) {
	var out;
	var draw;
	var i;

	draw = partial( mu, sigma, rand );
	out = matrix( dims, dt );
	for ( i = 0; i < out.length; i++ ) {
		out.data[ i ] = draw();
	}
	return out;
} // end FUNCTION random()

// EXPORTS //

module.exports = random;


/*
 * grunt-publish
 * https://github.com/maxleiko/grunt-publish
 *
 * Copyright (c) 2014 Maxime Tricoire
 * Licensed under the MIT license.
 */

'use strict';
var path = require('path'),
  async = require('async'),
  npmPublisher = require('./lib/npm-publisher');

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('publish', 'Automatically publish to NPM registry one or more modules', function() {
    var done = this.async(), tasks = [];

    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
      ignore: ['node_modules'],
      registry: null,
      exitOnFailure: false
    });

    /**
     * Validates "ignore" option for given path
     * @param filepath
     * @returns {*}
     */
    function getIgnored(filepath) {
      for (var i in options.ignore) {
        if (filepath.indexOf(options.ignore[i]) !== -1) {
          return options.ignore[i];
        }
      }
      return null;
    }

    /**
     * Tells whether or not, the given path is a valid directory (directory which contains a package.json)
     * @param filepath
     * @returns {*}
     */
    function isValidDir(filepath) {
      if (grunt.file.isDir(filepath)) {
        return grunt.file.exists(path.resolve(filepath, 'package.json'));
      }
      return false;
    }

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      f.src.forEach(function(filepath) {
        var ignored = getIgnored(filepath);
        if (!ignored && isValidDir(filepath)) {
          var moduleName = grunt.file.readJSON(path.resolve(filepath, 'package.json')).name;
          tasks.push(function(cb) {
            grunt.log.ok('Publishing ' + moduleName + ' (' + filepath + ') ...');
            npmPublisher(filepath, options, function(err) {
              if (err) {
                if (options.exitOnFailure) {
                  cb(err);
                } else {
                  cb(null, { name: moduleName, err: err });
                }
              } else {
                grunt.log.ok(moduleName + ' published successfully');
                cb(null, { name: moduleName });
              }
            });
          });
        }
      });
    });

    async[options.exitOnFailure ? 'series':'parallel'](tasks, function(err, results) {
      if (err) {
        done(err);
      } else {
        var success = [], error = [];
        for (var i in results) {
          if (results[i].err) {
            error.push(results[i]);
          } else {
            success.push(results[i]);
          }
        }

        if (success.length > 0) {
          grunt.log.subhead('Successfully published:');
        }
        success.forEach(function (item) {
          grunt.log.ok(path.basename(item.name));
        });

        if (error.length > 0) {
          grunt.log.subhead('Unable to publish:');
        }
        error.forEach(function (item) {
          grunt.log.error(path.basename(item.err));
        });

        done();
      }
    });
  });

};


/*!
 * benz <https://github.com/tunnckoCore/benz>
 *
 * Copyright (c) 2015 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk)
 * Released under the MIT license.
 */

/* jshint asi:true, esnext:true */

'use strict'

var kindOf = require('kind-of')
var extend = require('extend-shallow')
var isGenFn = require('is-es6-generator-function')
var isObject = require('is-extendable')
var isPromise = require('is-promise')
var asyncDone = require('async-done')
var nowAndLater = require('now-and-later')
var handleArguments = require('handle-arguments')
var manageArguments = require('manage-arguments')

module.exports = function factory (self, method) {
  method = method === 'series' ? 'mapSeries' : method
  method = method === 'parallel' ? 'map' : method

  return function _factory_ (fns, exts) {
    if (kindOf(fns) === 'function') {
      fns = [fns]
    }
    if (kindOf(fns) !== 'array' && kindOf(fns) !== 'object') {
      throw new TypeError('benz: expect `fns` to be array, object or function')
    }
    exts = kindOf(exts) === 'object' ? exts : {}

    var _ctx = self.option('context')
    var _ext = self.option('extensions')
    var context = isObject(_ctx) ? _ctx : {}
    var extensions = extend(isObject(_ext) ? _ext : {}, exts)

    self.option('context', context)
    self.option('extensions', extensions)

    function complete () {
      var argz = handleArguments(arguments)
      var results = []

      nowAndLater[method](fns, iterator, extensions, lastCallback(context, argz.callback))

      function iterator (fn, next) {
        var params = results.length ? results.shift() : argz.args
        fn = isPromise(fn) ? wrapify(fn) : fn
        fn = isGenFn(fn) ? self.option('generatorify')(fn) : fn
        fn = bindify(fn, context, params)

        asyncDone(fn, function (err) {
          if (err) { return next(err) }

          var args = manageArguments(arguments).slice(1)
          results.push(args)

          if (args.length === 0) {
            return next(null)
          }
          if (args.length === 1) {
            return next(null, args[0])
          }

          next(null, args)
        })
      }

      function lastCallback (ctx, done) {
        done = kindOf(done) === 'function' ? done : self.option('done')

        return function lastCb () {
          var args = manageArguments(arguments)
          var err = args[0]
          var res = args.slice(1).shift()
          var last = res[res.length - 1]
          res = kindOf(res) === 'array' ? res.filter(Boolean) : res

          if (self.enabled('flatten') && fns.length === 1) {
            self.disable('flatten')
          }
          if (self.enabled('onlylast')) {
            return done.call(ctx, err, last)
          }
          if (self.disabled('flatten')) {
            return done.apply(ctx, [err].concat(res))
          }

          return done.call(ctx, err, res)
        }
      }
    }

    if (self.enabled('promise')) {
      return self.option('promisify')(complete)
    }

    return complete
  }
}

/**
 * utils
 */

function bindify (fn, thisArg, args) {
  return fn.bind.apply(fn, [thisArg].concat(args))
}

function wrapify (promise) {
  return function () {
    return promise
  }
}